@productbrain/mcp 0.0.1-beta.4721 → 0.0.1-beta.4732

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/tools/entries.ts","../src/envelope.ts","../src/errors.ts","../src/tools/knowledge-helpers.ts","../src/gap-store.ts","../src/compound-tool.ts","../src/tools/knowledge.ts","../src/tools/smart-capture.ts","../src/lib/captureTimeoutOutcome.ts","../src/lib/scopedCache.ts","../src/tools/coherency-refusal.ts","../src/lib/resolveCollection.ts","../src/lib/fieldTypes.ts","../src/lib/formatFieldGuidance.ts","../src/lib/inferSourceDate.ts","../src/lib/collectionCache.ts","../src/lib/textMatch.ts","../src/lib/batchCaptureOutput.ts","../src/lib/batchTimeoutCohort.ts","../src/lib/createEntryPreviewResult.ts","../src/lib/entryDataNormalization.ts","../src/lib/batchInlineRelations.ts","../src/lib/captureForRealAction.ts","../src/lib/rubricFormatting.ts","../src/lib/captureSinglePreviewOutput.ts","../src/lib/batchPreviewDuplicates.ts","../src/tools/conflict-preflight.ts","../src/tools/knowledge/getHistory.ts","../src/tools/verify.ts","../src/lib/resolve-project-root.ts","../src/tools/entry-move.ts","../src/tools/relations.ts","../src/tools/graph.ts","../src/tools/context.ts","../src/tools/documents.ts","../src/tools/collections.ts","../src/tools/labels.ts","../src/tools/orient.ts","../src/tools/planned-work.ts","../src/lib/coherence/data.ts","../src/lib/coherence/resolver.ts","../src/lib/coherence/git-detection.ts","../src/lib/coherence/index.ts","../src/lib/coherence/doc-completeness.ts","../src/tools/orient-shared.ts","../src/tools/orient-rituals.ts","../src/tools/orient-metrics.ts","../src/tools/orientDegradation.ts","../src/lib/gapToPrompt.ts","../src/lib/canonicalRefs.ts","../src/tools/start_pb.ts","../src/tools/skills.ts","../src/lib/sessionNotices.ts","../src/tools/record_activation.ts","../src/tools/workflows.ts","../src/workflows/descriptor.ts","../src/workflows/definitions.ts","../src/lib/workflowRun.ts","../src/tools/quality.ts","../src/tools/audit.ts","../src/tools/spine-check.ts","../src/tools/session.ts","../src/tools/wrapup.ts","../src/lib/compose-wrapup-view.ts","../src/tools/facilitate.ts","../src/tools/gitchain.ts","../src/lib/versionDisplay.ts","../src/tools/workspace.ts","../src/tools/health.ts","../src/lib/auditView.ts","../src/tools/usage.ts","../src/tools/governance.ts","../src/tools/feedback.ts","../src/lib/productFeedbackConstants.ts","../src/tools/shape.ts","../src/tools/question.ts","../src/lib/strip.ts","../src/resources/index.ts","../src/resources/agentCheatsheet.ts","../src/prompts/index.ts","../src/flags.ts","../src/featureFlags.ts"],"sourcesContent":["/**\n * McpServer factory — shared between stdio (index.ts) and HTTP (http.ts) entry points.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nimport { registerEntriesTools } from \"./tools/entries.js\";\nimport { registerRelationsTools } from \"./tools/relations.js\";\nimport { registerContextTools } from \"./tools/context.js\";\nimport { registerCollectionsTools } from \"./tools/collections.js\";\nimport { registerOrientTool } from \"./tools/orient.js\";\nimport { registerSmartCaptureTools } from \"./tools/smart-capture.js\";\nimport { registerWorkflowTools } from \"./tools/workflows.js\";\nimport { registerQualityTools } from \"./tools/quality.js\";\nimport { registerSessionTools } from \"./tools/session.js\";\nimport { registerGitChainTools } from \"./tools/gitchain.js\";\nimport { registerWorkspaceTools } from \"./tools/workspace.js\";\nimport { registerFeedbackTool } from './tools/feedback.js';\nimport { registerShapeTools } from './tools/shape.js';\nimport { registerQuestionTools } from './tools/question.js';\nimport { registerResources } from \"./resources/index.js\";\nimport { registerPrompts } from \"./prompts/index.js\";\n\nexport const SERVER_VERSION = \"0.7.2\";\n\nconst INSTRUCTIONS = [\n \"Product Brain — the single source of truth for product knowledge.\",\n \"Terminology, standards, and core data all live here — no need to check external docs.\",\n \"\",\n \"## About Product Brain (PB)\",\n \"\",\n \"PB is a knowledge management system used by many product teams.\",\n \"These describe how PB works — not your product.\",\n \"\",\n \"### How PB Organizes Its Tools\",\n \"- **Tools** are for actions with side-effects or dynamic computation (capture, accept, search).\",\n \"- **Resources** are for stable, read-only data (orientation, terminology, collection schemas).\",\n \"- **Prompts** are for multi-step choreography (workflows, guided capture, deep dives).\",\n \"- Every tool, resource, and prompt works for ANY workspace — no bespoke logic.\",\n \"- Resource templates (URI params) provide workspace-specific data through generic patterns.\",\n \"- Tool count stays minimal: compound tools with `action` enums over many single-purpose tools.\",\n \"\",\n \"### How PB Handles Your Data\",\n \"- **Draft-first**: all writes create drafts. Nothing reaches SSOT without explicit user confirmation.\",\n \"- **Empty-workspace safe**: every tool and resource handles zero entries, zero collections, and fresh workspaces.\",\n \"- **Advisory, not blocking**: quality scores, contradiction checks, and coaching are informational. They never prevent an operation.\",\n \"- **Workspace-agnostic**: PB is a product used by many teams. No workspace-specific logic in server code.\",\n \"- **Self-documenting**: orient and server instructions teach agents how PB works. Cursor rules supplement but don't replace.\",\n \"\",\n \"### Tool Rename Notice (WP-484 S3, one release)\",\n \"Serves 13 default compound tools (WP-559 adds `shape` — review/disposition for write-shape advisories; WP-638 S3 adds `question` — routed-question routing/ownership/lifecycle); 2 more (chain, chain-review) behind PB_MODULES=gitchain.\",\n \"Old standalone names are gone — no alias window (ASM-43: zero external consumers). Map: \" +\n \"`start_pb`→`orient action=start`, `record_activation`→`orient action=record-activation`, \" +\n \"`session-wrapup`→`session action=wrapup-review|wrapup-commit`, `facilitate`→`session action=resume|commit-constellation`, \" +\n \"`update-entry`→`entries action=update`, `commit-entry`→`entries action=commit`, `get-history`→`entries action=history`, \" +\n \"`move-entry`→`entries action=move`, `verify-entry`→`entries action=verify`, `graph`→`relations action=find|suggest`, \" +\n \"`documents`→`context action=last-verified-brief`, `labels`→`collections action=label-*`, \" +\n \"`verify`→`quality action=verify-chain`, `audit`→`quality action=audit`, `health`→`workspace action=check|whoami|status|self-test`, \" +\n \"`get-usage-summary`→`workspace action=usage`, `governance-proposals`→`workspace action=proposals-*`, \" +\n \"`skills`→`workflows action=load-skill`, `chain-version`→`chain action=version.*`, `chain-branch`→`chain-review action=branch.*`.\",\n \"\",\n \"## Your Workspace Principles\",\n \"\",\n \"When you orient or start, PB surfaces active entries from your `principles`, `standards`,\",\n \"and `business-rules` collections. These are YOUR team's guardrails — respect them during implementation.\",\n \"If no principles exist yet, PB will tell you and suggest how to add them.\",\n \"\",\n \"The three governance collections:\",\n \"- **Principles** (`principles`) — beliefs that guide decisions. 'We believe X.' You reason from a principle.\",\n \"- **Standards** (`standards`) — conventions about how work is done. 'We do X this way.' You lint for a standard.\",\n \"- **Business Rules** (`business-rules`) — system constraints. 'The system must do X.' You test for a rule.\",\n \"\",\n \"## Workflow\",\n \"\",\n \" 1. Start: call `session action=start` to open a tracked write session, then `orient action=start` — it detects your workspace stage and returns the right guidance. Fresh workspaces get the pb-setup skill body; active workspaces get a standup briefing. (`orient` orients the session; only `session action=start` creates one.)\",\n \" 2. Re-orient: call `orient action=task` mid-session for task-scoped context or a compact status refresh.\",\n \" 3. Discover: use `entries action=search` to find entries, or `entries action=list` to browse.\",\n \" 4. Drill in: use `entries action=get entryId=\\\"...\\\"` for full details — data, labels, relations, history.\",\n \" 5. Context: use `context action=gather` with an entryId or a task description.\",\n \" 6. Capture: use `capture` to create entries — auto-links and scores in one call.\",\n \" 7. Accept: use `entries action=commit` to promote drafts to SSOT — only when the user confirms.\",\n \" 8. Connect: use `relations action=suggest` then `relations action=create` to build the graph.\",\n \" 9. Wrapup: call `session action=wrapup-review` before closing — reviews drafts, coaches quality, suggests links.\",\n \" 10. Close: call `session action=close` when done — records session activity. Auto-nudges if wrapup was skipped.\",\n \"\",\n \"Write tools (capture, entries action=update, relations, entries action=commit) require:\",\n \" - An active agent session — call `session action=start` first, then `orient action=start` for context. Call `orient action=task` mid-session for a refresh.\",\n \" - A readwrite API key scope\",\n \"\",\n \"Accept-on-confirm: always capture as draft first and show the user what was captured.\",\n \"Only call `entries action=commit` when the user explicitly confirms (e.g. 'accept', 'looks good', 'yes').\",\n \"This builds trust — the Chain (main) is SSOT; nothing goes there without user consent.\",\n \"\",\n \"Alignment-first: before proposing or building anything, check orient's Workspace Governance\",\n \"and Active work packages sections. These are constraints, not reference material.\",\n \"If the proposal conflicts with a principle, standard, or business rule — stop, flag the conflict,\",\n \"and get explicit user confirmation before proceeding. Do not design around governance.\",\n \"If the work is outside the scope of active work packages — stop, name the gap, and ask the user\",\n \"to confirm before designing. Do not propose implementation for out-of-scope work without a go-ahead.\",\n \"\",\n \"Workspace setup: use `collections action=create` and `collections action=update` to shape the workspace\",\n \"structure with the user. Ask what they need to track; presets are starting points, not fixed.\",\n \"\",\n \"Personalization: if you have context about the user from memory (prior work, recent\",\n \"conversations, team context), use it to personalize recommendations. For example,\",\n \"'Based on your recent pitch reviews, the gap most likely to matter is X.'\",\n \"The orient/start output gives you the workspace state; your memory fills in the human context.\",\n].join(\"\\n\");\n\nexport function createProductBrainServer(): McpServer {\n const server = new McpServer(\n { name: \"Product Brain\", version: SERVER_VERSION },\n { capabilities: { logging: {} }, instructions: INSTRUCTIONS },\n );\n\n // WP-484 S3 (DEC-1466): default flipped from \"core,gitchain\" to \"core\".\n // DEC-1473 adds universal feedback as a governed exception; WP-559 adds a second,\n // `shape` (the disposition ledger); WP-638 S3 adds a third, `question` (routed\n // questions — a genuinely new noun, per-noun ceiling breach if folded into `workspace`,\n // §4.3 of the design spec). The fixed budgets are 13 default tools and 15 with gitchain\n // opted in.\n const enabledModules = new Set(\n (process.env.PB_MODULES ?? \"core\")\n .split(\",\").map((m) => m.trim().toLowerCase()),\n );\n\n // Core surface — always registered. Exactly 13 tools (WP-638 S3 raises the\n // DEC-1466/DEC-1473/WP-559 ceiling from 12 to 13, deliberately: the ten knowledge\n // resources, universal product feedback, shape (WP-559 disposition ledger), and\n // question (WP-638 routed questions) — the tool-count-gate test is the CI enforcement,\n // updated in the SAME PR as this registration).\n registerSessionTools(server);\n registerEntriesTools(server);\n registerRelationsTools(server);\n registerContextTools(server);\n registerCollectionsTools(server);\n registerOrientTool(server);\n registerSmartCaptureTools(server);\n registerQualityTools(server);\n registerWorkflowTools(server);\n registerWorkspaceTools(server);\n registerFeedbackTool(server);\n registerShapeTools(server);\n registerQuestionTools(server);\n\n // Module-gated — opt-in via PB_MODULES=core,gitchain (2 more tools: chain,\n // chain-review). Off the public default (DEC-1466).\n if (enabledModules.has(\"gitchain\")) registerGitChainTools(server);\n\n registerResources(server);\n registerPrompts(server);\n\n // 13 tools visible by default (16 with PB_MODULES=core,gitchain — feedback\n // S3, TEN-2157; shape, WP-559; question, WP-638 S3). Write tools are guarded at handler level\n // (requireWriteAccess checks session + orient + key scope). Hiding tools\n // via disable() broke Claude's lazy tool indexing — it never re-indexed\n // after list_changed notifications.\n\n return server;\n}\n","/**\n * Entries compound tool — the WP-484 \"entries family\": list, get, batch,\n * search, update, commit, history, move, verify. Consolidates list-entries,\n * get-entry, batch-get, search (original) plus update-entry, commit-entry,\n * get-history, move-entry, verify-entry (WP-484 S1) into one tool, per the\n * two-layer shape (§3/§4). BR-72: Compound Tool Standard.\n *\n * The legacy standalone tools (update-entry, commit-entry, get-history,\n * move-entry, verify-entry) stay registered alongside `entries` until S3\n * deletes them (§7's \"alongside\" mechanic) — both call the SAME handler\n * functions (exported from knowledge.ts / verify.ts), so there is exactly\n * one business-logic path per action, not two to keep in sync.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, runWithToolContext, getWorkspaceId } from \"../client.js\";\nimport { success, failure, thinWrapper, parseOrFail, notFoundResult, type ToolResult } from \"../envelope.js\";\nimport { extractPreview, deriveEpistemicStatus, formatEpistemicLine, toEpistemicInput } from \"./knowledge-helpers.js\";\nimport { trackKnowledgeGap } from \"../analytics.js\";\nimport { recordGap } from \"../gap-store.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { updateEntrySchema, commitEntrySchema, getHistorySchema, handleUpdateEntry, handleCommitEntry, handleGetHistory } from \"./knowledge.js\";\nimport { verifyEntrySchema, handleVerifyEntry } from \"./verify.js\";\nimport { handleMoveEntry, moveEntrySchema } from \"./entry-move.js\";\nexport { moveEntrySchema } from \"./entry-move.js\";\n\nfunction sanitizeEntryData(data: unknown): Record<string, unknown> | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n const filtered = Object.fromEntries(\n Object.entries(data as Record<string, unknown>).filter(([key]) => !key.startsWith(\"_\")),\n );\n return Object.keys(filtered).length > 0 ? filtered : undefined;\n}\n\n/**\n * TEN-2191 (honesty patch): build the self-announcing WHY line for a `get` result.\n *\n * whyQuality is rationale-only (the kernel dropped the description fallback), so a\n * missing or restated rationale is surfaced rather than masked:\n * - 'missing' → \"**Why:** — (no rationale captured)\" (no `why` text exists)\n * - 'restated' → \"**Why:** <text> (restated)\"\n * - else (real rationale, or legacy entry carrying only `why`) → \"**Why:** <text>\"\n *\n * Returns the line (or null when there is nothing to render), the `why` text\n * (normalized to a string, \"\" when absent) for reuse in the structured payload,\n * and the data key whose value is now surfaced as Why so the caller can suppress\n * it from both the text and structured data blocks (STD-218 parity, Codex finding).\n *\n * whySourceKey reflects the kernel-resolved WHY field (rationale or description):\n * - Prefers `e.whyField` ('rationale' | 'description') when present AND the\n * corresponding data field is a non-empty string — uses it directly as the\n * source key. Threaded from the kernel so arch-note `description` is recognized.\n * - Falls back to rationale-only detection when `whyField` is absent (older\n * kernels / non-governance entries) so behaviour is unchanged for those entries.\n *\n * Pure — mirrors the CLI `pb get` render. Exported for testing.\n */\nexport function renderWhyLine(e: Record<string, unknown>): {\n line: string | null;\n why: string;\n whySourceKey: string | null;\n} {\n const why = typeof e.why === \"string\" ? e.why : \"\";\n if (e.whyQuality === \"missing\") {\n return { line: `**Why:** — (no rationale captured)`, why, whySourceKey: null };\n }\n if (why.length > 0) {\n const suffix = e.whyQuality === \"restated\" ? \" (restated)\" : \"\";\n const d = (e.data ?? {}) as Record<string, unknown>;\n // Prefer the kernel-threaded whyField (covers 'description' for arch notes).\n // Fall back to rationale-detection for older kernels that don't thread it.\n let whySourceKey: string | null = null;\n const kf = e.whyField;\n if ((kf === \"rationale\" || kf === \"description\") && typeof d[kf] === \"string\" && (d[kf] as string).trim().length > 0) {\n whySourceKey = kf;\n } else if (typeof d.rationale === \"string\" && d.rationale.trim().length > 0) {\n whySourceKey = \"rationale\";\n }\n return { line: `**Why:** ${why}${suffix}`, why, whySourceKey };\n }\n return { line: null, why, whySourceKey: null };\n}\n\n/**\n * Attestation-model finding (PR #341 review): render the honest `**Verification:**`\n * line the same way packages/cli/src/formatters/entry.ts renders it — connectors NEVER\n * re-derive strength (spec §5), they only display what chain.getEntry ships\n * (`verifiedBy` + `attestation.{strength,basis}`). A non-'attested' basis (the\n * pre-branch legacy corpus) is a legacy-honest label rendered as a bare qualifier\n * `(<verifiedBy>)`, never `— by <legacy string>`. Pure — exported for testing.\n */\nexport function renderVerificationLine(e: Record<string, unknown>): string | null {\n if (!e.verificationStatus) return null;\n const verifiedBy = typeof e.verifiedBy === \"string\" ? e.verifiedBy : undefined;\n const attestation = e.attestation && typeof e.attestation === \"object\"\n ? (e.attestation as { strength?: unknown; basis?: unknown })\n : undefined;\n const strength = attestation && typeof attestation.strength === \"string\" ? attestation.strength : undefined;\n const basis = attestation && typeof attestation.basis === \"string\" ? attestation.basis : undefined;\n\n let who: string;\n if (basis && basis !== \"attested\") {\n who = verifiedBy ? ` (${verifiedBy})` : \"\";\n } else {\n who = verifiedBy ? ` — by ${verifiedBy}${strength ? ` (${strength})` : \"\"}` : \"\";\n }\n return `**Verification:** ${String(e.verificationStatus)}${who}`;\n}\n\n// WP-484 S1 (§3/§4): the \"entries family\" — entries absorbs update-entry,\n// commit-entry, get-history, move-entry, verify-entry as actions. The legacy\n// standalone tools stay registered too (the \"alongside until S3\" mechanic,\n// §7) — registerEntriesTools below only ADDS the new actions to `entries`.\nconst ENTRIES_ACTIONS = [\n \"list\", \"get\", \"batch\", \"search\", \"update\", \"commit\", \"history\", \"move\", \"verify\",\n] as const;\ntype EntriesAction = (typeof ENTRIES_ACTIONS)[number];\n\nconst entriesStatusFilterSchema = z.union([z.string().max(200), z.array(z.enum([\"draft\", \"active\", \"accepted\", \"deprecated\", \"archived\"])).max(5)]); // PR #660 R1 Zqh1K/O: mirrors convex's max-5 + vocab bound, rejected before the round-trip.\nconst coherencyAcknowledgementFlatSchema = z.object({\n response: z.enum(['linked', 'accepted-fix', 'diverged']).describe(\"Explicit response to an acknowledge-required coherency challenge.\"),\n entryId: z.string().max(200).optional().describe(\"Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix').\"),\n reason: z.string().max(2000).optional().describe(\"Divergence rationale (required for 'diverged', ≥12 chars).\"),\n});\n\n/**\n * §3a — the REGISTERED layer: a flat ZodObject, action enum + the superset of\n * every absorbed action's optional params. Every param whose consuming\n * actions changed with this migration carries a description naming them\n * (§4 division of labor / §4 entries-merge worked example: `status` is a\n * `list`/`search` FILTER string here — the strict lifecycle union only\n * applies inside the `update` branch of the handler-layer discriminatedUnion,\n * §3b, below). TEN-1146 string length caps applied per-noun as each noun\n * migrates — entries is first, so free-text fields get caps here.\n */\nexport const entriesSchema = z.object({\n action: z.enum(ENTRIES_ACTIONS).describe(\n \"'list': browse entries with filters. 'get': fetch one entry by ID. 'batch': fetch multiple entries. \" +\n \"'search': full-text search. 'update': change fields on an existing entry (draft by default). \" +\n \"'commit': accept a draft entry onto the Chain. 'history': audit trail for an entry. \" +\n \"'move': reclassify an entry to a different collection. 'verify': mark an entry as verified \" +\n \"(lightweight — no codebase scan; see `quality action=verify-chain` for the codebase-scanning check).\",\n ),\n entryId: z.string().max(200).optional().describe(\n \"Entry ID, e.g. '<PREFIX>-<n>'. Required for: get, update, commit, history, move, verify.\",\n ),\n entryIds: z.array(z.string().max(200)).min(1).max(20).optional()\n .describe(\"Entry IDs for 'batch', e.g. ['TYPE-strategy', 'STR-jljeg7']\"),\n collection: z.string().max(200).optional()\n .describe(\"Collection slug — for 'list'/'search': scope filter, e.g. 'glossary', 'tracking-events'.\"),\n status: entriesStatusFilterSchema.optional() // 'active'/'accepted' are the same trust level (DEC-1575) — both enumerated, never one substituted for the other.\n .describe(\n \"For 'list': one lifecycle value (draft|active|accepted|deprecated|archived; active/accepted are the same trust level). \" +\n \"For 'search': one value OR an array of up to 5 (e.g. ['active','accepted']). For 'update': draft|active|deprecated|archived \" +\n \"ONLY — 'accepted' is set via 'commit', never 'update'. Workflow values use `workflowStatus` instead.\"),\n tag: z.string().max(200).optional().describe(\"For 'list': filter by internal tag.\"),\n label: z.string().max(200).optional().describe(\"For 'list': filter by label slug — matches entries across all collections.\"),\n query: z.string().min(2).max(500).optional().describe(\"For 'search': search text (min 2 characters).\"),\n name: z.string().max(500).optional().describe(\"For 'update': new display name.\"),\n workflowStatus: z.string().max(200).optional().describe(\n \"For 'update': collection workflow state. Valid values are collection-specific and server-owned — \" +\n \"discover via `collections action=describe`. Invalid values are rejected with the valid set.\",\n ),\n data: z.record(z.unknown()).optional().describe(\"For 'update': fields to update (merged with existing data).\"),\n order: z.number().optional().describe(\"For 'update': new sort order.\"),\n canonicalKey: z.string().max(200).optional().describe(\n \"For 'update': semantic type (e.g. 'decision', 'tension'). Only changeable on draft/uncommitted entries.\",\n ),\n autoPublish: z.boolean().optional().default(false).describe(\n \"For 'update': only true when the user explicitly asks to publish. Default false = draft.\",\n ),\n changeNote: z.string().max(2000).optional().describe(\n \"For 'update': short human-readable rationale for WHY this change was made. Surfaces in activity feed.\",\n ),\n sourceRef: z.string().max(2000).optional().describe(\n \"For 'update': URI or path of the source document backing this entry. Write-once.\",\n ),\n sourceExcerpt: z.string().max(5000).optional().describe(\n \"For 'update': verbatim excerpt from the source backing this entry's claims. Write-once.\",\n ),\n steeringOverrideReason: z.string().max(2000).optional().describe(\n \"For 'update'/'commit': typed override (≥12 chars) that clears a steering coherency block.\",\n ),\n coherencyAcknowledgement: coherencyAcknowledgementFlatSchema.optional().describe(\n \"For 'update'/'commit': explicit response to a coherency challenge (standard/strict workspace modes).\",\n ),\n preview: z.boolean().optional().describe(\n \"For 'commit': if true, validates the accept without writing — returns what would happen.\",\n ),\n toCollection: z.string().max(200).optional().describe(\"For 'move': target collection slug, e.g. 'decisions', 'architecture'.\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion, built by reusing the\n// existing single-purpose schemas (Code Integrity — the system already knows\n// these shapes; `.extend()` adds only the discriminant). This is what actually\n// enforces per-action semantics (e.g. `update`'s strict status union vs.\n// `list`'s free-text filter) — the flat schema above never does.\nconst entriesListVariant = z.object({\n action: z.literal(\"list\"),\n collection: z.string().max(200).optional(),\n status: z.string().max(200).optional(),\n tag: z.string().max(200).optional(),\n label: z.string().max(200).optional(),\n});\nconst entriesGetVariant = z.object({\n action: z.literal(\"get\"),\n entryId: z.string().max(200),\n});\nconst entriesBatchVariant = z.object({\n action: z.literal(\"batch\"),\n entryIds: z.array(z.string().max(200)).min(1).max(20),\n});\nconst entriesSearchVariant = z.object({\n action: z.literal(\"search\"),\n query: z.string().min(2).max(500),\n collection: z.string().max(200).optional(),\n status: entriesStatusFilterSchema.optional(), // PR #660 R1 Zqh1K: string|array.\n});\nconst entriesUpdateVariant = updateEntrySchema.extend({ action: z.literal(\"update\") });\nconst entriesCommitVariant = commitEntrySchema.extend({ action: z.literal(\"commit\") });\nconst entriesHistoryVariant = getHistorySchema.extend({ action: z.literal(\"history\") });\nconst entriesMoveVariant = z.object({\n action: z.literal(\"move\"),\n entryId: z.string().max(200),\n toCollection: z.string().max(200),\n});\nconst entriesVerifyVariant = verifyEntrySchema.extend({ action: z.literal(\"verify\") });\n\nexport const entriesActionUnion = z.discriminatedUnion(\"action\", [\n entriesListVariant,\n entriesGetVariant,\n entriesBatchVariant,\n entriesSearchVariant,\n entriesUpdateVariant,\n entriesCommitVariant,\n entriesHistoryVariant,\n entriesMoveVariant,\n entriesVerifyVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const ENTRIES_ACTION_SPECS: Record<EntriesAction, ActionParamSpec> = {\n list: { params: [\"collection\", \"status\", \"tag\", \"label\"], description: \"Browse entries; all params optional.\" },\n get: { params: [\"entryId\"], description: \"Fetch one entry by ID.\" },\n batch: { params: [\"entryIds\"], description: \"Fetch up to 20 entries by ID.\" },\n search: { params: [\"query\", \"collection\", \"status\"], description: \"Full-text search; query is required (min 2 chars).\" },\n update: { params: [\"entryId\", \"name\", \"status\", \"workflowStatus\", \"data\", \"order\", \"canonicalKey\", \"autoPublish\", \"changeNote\", \"sourceRef\", \"sourceExcerpt\", \"steeringOverrideReason\", \"coherencyAcknowledgement\"], description: \"entryId is required; every other field is optional.\" },\n commit: { params: [\"entryId\", \"preview\", \"steeringOverrideReason\", \"coherencyAcknowledgement\"], description: \"entryId is required.\" },\n history: { params: [\"entryId\"], description: \"entryId is required.\" },\n move: { params: [\"entryId\", \"toCollection\"], description: \"Both entryId and toCollection are required.\" },\n verify: { params: [\"entryId\"], description: \"entryId is required.\" },\n};\n\nexport const entriesGetOutputSchema = z.object({\n entryId: z.string(),\n name: z.string(),\n collection: z.string(),\n status: z.string(),\n capturedAt: z.number().optional(),\n origin: z.string().optional(),\n originDetail: z.string().optional(),\n verificationStatus: z.string().optional(),\n // Attestation-model finding (PR #341 review): the server's honest verifier label and\n // derived attestation strength/basis — connectors NEVER re-derive strength (spec §5),\n // they only render what chain.getEntry ships. Mirrors packages/cli EntryFromApi.\n //\n // The literal set below is a hand-kept WIRE-SHAPE mirror of kernel/quality/\n // attestation.ts's AttestationStrength SSOT (allowlisted in Check D —\n // scripts/check-collection-ssot.mjs's CHECK_D_ALLOWLIST — with the full\n // reasoning for why this can't just import that module). Update both together.\n verifiedBy: z.string().optional(),\n attestation: z.object({\n strength: z.enum([\"human-direct\", \"delegated\", \"system\", \"unattested\"]),\n basis: z.string().optional(),\n }).optional(),\n sourceRef: z.string().optional(),\n sourceExcerpt: z.string().optional(),\n why: z.string().optional(),\n // TEN-2191: quality of the captured WHY — 'rationale' | 'missing' | 'restated'.\n whyQuality: z.enum([\"rationale\", \"missing\", \"restated\"]).optional(),\n data: z.record(z.unknown()).optional(),\n relations: z.array(z.object({\n entryId: z.string().optional(),\n name: z.string(),\n type: z.string(),\n direction: z.string(),\n })).optional(),\n labels: z.array(z.string()).optional(),\n}).passthrough();\n\nexport const entriesListOutputSchema = z.object({\n entries: z.array(z.object({\n entryId: z.string(),\n name: z.string(),\n collection: z.string(),\n status: z.string(),\n })),\n total: z.number(),\n});\n\nexport const entriesSearchOutputSchema = z.object({\n results: z.array(z.object({\n entryId: z.string(),\n name: z.string(),\n collection: z.string(),\n status: z.string(),\n score: z.number().optional(),\n })),\n total: z.number(),\n query: z.string(),\n});\n\nexport const entriesBatchOutputSchema = z.object({\n entries: z.array(z.object({\n entryId: z.string(),\n name: z.string(),\n collection: z.string(),\n status: z.string(),\n capturedAt: z.number().optional(),\n origin: z.string().optional(),\n originDetail: z.string().optional(),\n verificationStatus: z.string().optional(),\n // Attestation-model finding (PR #341 review): mirror entriesGetOutputSchema — batch\n // entries now carry the same honest verifiedBy/attestation fields. Literal set is\n // the same hand-kept SSOT mirror — see entriesGetOutputSchema's attestation\n // comment above for the full Check D / kernel-import reasoning.\n verifiedBy: z.string().optional(),\n attestation: z.object({\n strength: z.enum([\"human-direct\", \"delegated\", \"system\", \"unattested\"]),\n basis: z.string().optional(),\n }).optional(),\n sourceRef: z.string().optional(),\n sourceExcerpt: z.string().optional(),\n // TEN-2191: mirror entriesGetOutputSchema — batch entries now carry why/whyQuality.\n why: z.string().optional(),\n whyQuality: z.enum([\"rationale\", \"missing\", \"restated\"]).optional(),\n data: z.record(z.unknown()).optional(),\n }).passthrough()),\n total: z.number(),\n});\n\nexport function registerEntriesTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched by dispatchDiscriminated\n // via entriesActionUnion. A discriminatedUnion failure at this point is\n // ALWAYS \"valid action, wrong param combination or per-action enum\n // violation\" (§4 division of labor) — the registered flat layer already\n // rejected an unknown action or a wrong param TYPE before the handler runs.\n const entriesHandlers: Record<EntriesAction, (data: any) => Promise<ToolResult>> = {\n list: (data) => handleList(data.collection, data.status, data.tag, data.label),\n get: (data) => handleGet(data.entryId),\n batch: (data) => handleBatch(data.entryIds),\n search: (data) => handleSearch(server, data.query, data.collection, data.status),\n // update/commit reuse knowledge.ts's extracted handlers — \"entries\" routes\n // `next` at itself (toolName=\"entries\") instead of the legacy tool names.\n update: (data) => handleUpdateEntry(data, \"entries\"),\n commit: (data) => handleCommitEntry(data, \"entries\"),\n history: (data) => handleGetHistory(data),\n move: (data) => handleMoveEntry(data.entryId, data.toCollection),\n verify: (data) => handleVerifyEntry(data),\n };\n\n server.registerTool(\n \"entries\",\n {\n title: \"Entries\",\n description:\n \"Read and manage entries on the Chain. One tool for the entry lifecycle.\\n\\n\" +\n \"- **list**: Browse entries with optional filters (collection, status, tag, label). Use collections action=list first to discover slugs.\\n\" +\n \"- **get**: Fetch a single entry by ID — full record with data, labels, relations, history.\\n\" +\n \"- **batch**: Fetch multiple entries (max 20) in one call. Same shape as get per entry.\\n\" +\n \"- **search**: Full-text search across entries. Scope by collection or filter by status.\\n\" +\n \"- **update**: Change fields on an existing entry (draft by default — never autoPublish without explicit user confirmation).\\n\" +\n \"- **commit**: Accept a draft entry onto the Chain (SSOT). Runs the contradiction preflight first.\\n\" +\n \"- **history**: Audit trail for an entry.\\n\" +\n \"- **move**: Reclassify an entry to a different collection.\\n\" +\n \"- **verify**: Mark an entry as verified (lightweight, no codebase scan — see `quality action=verify-chain` for that).\\n\\n\" +\n \"Use `entries action=get entryId=\\\"...\\\"` to fetch one. Use `entries action=search query=\\\"...\\\"` to discover.\",\n inputSchema: entriesSchema,\n // Mixed read/write noun (§3 R3): can't be marked read-only once update/commit/move\n // live here too — accepted for the 11-tool default (§9 R3).\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(entriesSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"entries\", action }, () =>\n dispatchDiscriminated(\"entries\", entriesActionUnion, parsed.data, ENTRIES_ACTION_SPECS, entriesHandlers),\n );\n }),\n );\n}\n\nasync function handleGet(entryId: string) {\n const entry = await kernelQuery<unknown>(\"chain.getEntry\", { entryId });\n\n if (!entry) {\n return notFoundResult(entryId, `Entry '${entryId}' not found. Try search to find the right ID.`);\n }\n\n const e = entry as Record<string, unknown>;\n const epistemic = deriveEpistemicStatus(toEpistemicInput(e));\n\n const lines: string[] = [\n `## Get Result`,\n \"\",\n `# ${e.entryId ? `${e.entryId}: ` : \"\"}${e.name}`,\n \"\",\n `**Status:** ${e.status}${e.workflowStatus ? ` / ${e.workflowStatus}` : \"\"}`,\n `**Type:** ${e.canonicalKey ?? \"untyped\"}`,\n ];\n\n // BET-240 S6: surface trust/provenance fields when present\n if (typeof e.capturedAt === \"number\") lines.push(`**Captured at:** ${new Date(e.capturedAt).toISOString()}`);\n if (e.origin) {\n const detail = e.originDetail ? ` (${e.originDetail})` : \"\";\n lines.push(`**Origin:** ${e.origin}${detail}`);\n }\n const verificationLine = renderVerificationLine(e);\n if (verificationLine) lines.push(verificationLine);\n if (e.sourceRef) lines.push(`**Source ref:** ${e.sourceRef}`);\n if (e.sourceExcerpt) lines.push(`**Source excerpt:** ${e.sourceExcerpt}`);\n\n if (epistemic) {\n lines.push(formatEpistemicLine(epistemic));\n }\n\n // TEN-2191 (honesty patch): self-announcing WHY-quality line for active governance\n // entries. whyQuality is rationale-only (no description fallback) so a missing or\n // restated rationale is surfaced rather than masked. Mirrors the CLI `pb get` render.\n const { line: whyLine, why, whySourceKey } = renderWhyLine(e);\n if (whyLine !== null) lines.push(whyLine);\n\n const visibleData = sanitizeEntryData(e.data);\n // Suppress whySourceKey (the field now surfaced as top-level `why`) from BOTH the\n // text Data block and the structured payload — this is lossless because `why`\n // carries the full untruncated value from extractWhy (get never caps it), so\n // removing the source field from `data` loses no information. Omitting it from\n // both surfaces restores true STD-218 text/structured parity and removes the\n // bloat that commit 8f3b1664 left in the structured payload. The whySourceKey is\n // the kernel-resolved field ('rationale' for most governance, 'description' for\n // architecture notes) — see renderWhyLine for derivation. (Codex finding, TEN-2191.)\n const filteredData = visibleData && whySourceKey\n ? (Object.keys(visibleData).filter((k) => k !== whySourceKey).length > 0\n ? Object.fromEntries(Object.entries(visibleData).filter(([k]) => k !== whySourceKey))\n : undefined)\n : visibleData;\n if (filteredData) {\n lines.push(\"\");\n for (const [key, val] of Object.entries(filteredData)) {\n const display = typeof val === \"string\" ? val : JSON.stringify(val);\n lines.push(`**${key}:** ${display}`);\n }\n }\n\n if (Array.isArray(e.tags) && e.tags.length > 0) {\n lines.push(\"\", `**Tags:** ${(e.tags as string[]).join(\", \")}`);\n }\n\n if (Array.isArray(e.labels) && (e.labels as unknown[]).length > 0) {\n const labels = e.labels as { slug?: string; name?: string }[];\n lines.push(\"\", `**Labels:** ${labels.map((l) => `\\`${l.slug ?? l.name}\\``).join(\", \")}`);\n }\n\n if (Array.isArray(e.relations) && (e.relations as unknown[]).length > 0) {\n lines.push(\"\", \"## Relations\");\n for (const r of e.relations as { direction?: string; type?: string; otherEntryId?: string; otherName?: string }[]) {\n const arrow = r.direction === \"outgoing\" ? \"\\u2192\" : \"\\u2190\";\n const other = r.otherEntryId ? `${r.otherEntryId}: ${r.otherName}` : (r.otherName ?? \"unknown\");\n lines.push(`- ${arrow} **${r.type}** ${other}`);\n }\n }\n\n if (Array.isArray(e.history) && (e.history as unknown[]).length > 0) {\n lines.push(\"\", \"## History (last 10)\");\n // WP-D (attestation spec §7.2): legacyQualifier is server-derived — it renders beside a\n // legacy 'verified' event so the append-only ledger sentence stops lying. Never re-derived here.\n for (const h of (e.history as { timestamp: string; event: string; changedBy?: string; legacyQualifier?: string }[]).slice(-10)) {\n const date = new Date(h.timestamp).toISOString().split(\"T\")[0];\n const qualifier = h.legacyQualifier ? ` [${h.legacyQualifier}]` : \"\";\n lines.push(`- ${date}: ${h.event}${h.changedBy ? ` _(${h.changedBy})_` : \"\"}${qualifier}`);\n }\n }\n\n const entryData = {\n entryId: String(e.entryId ?? \"\"),\n name: String(e.name ?? \"\"),\n collection: String(e.canonicalKey ?? \"\"),\n status: String(e.status ?? \"\"),\n ...(typeof e.capturedAt === \"number\" ? { capturedAt: e.capturedAt } : {}),\n ...(e.workflowStatus ? { workflowStatus: String(e.workflowStatus) } : {}),\n ...(epistemic ? { epistemicStatus: epistemic } : {}),\n // BET-240 S6: trust/provenance fields\n ...(e.origin ? { origin: String(e.origin) } : {}),\n ...(e.originDetail ? { originDetail: String(e.originDetail) } : {}),\n ...(e.verificationStatus ? { verificationStatus: String(e.verificationStatus) } : {}),\n // Attestation-model finding (PR #341 review): forward the server's honest verifier\n // label + derived attestation strength/basis on the structured payload too — the\n // agent surface must see the same fields the text render displays (spec §5).\n ...(typeof e.verifiedBy === \"string\" ? { verifiedBy: e.verifiedBy } : {}),\n ...(e.attestation && typeof e.attestation === \"object\" ? { attestation: e.attestation as { strength: string; basis?: string } } : {}),\n ...(e.sourceRef ? { sourceRef: String(e.sourceRef) } : {}),\n ...(e.sourceExcerpt ? { sourceExcerpt: String(e.sourceExcerpt) } : {}),\n // TEN-2191: surface the WHY and its quality in the structured payload too.\n ...(why.length > 0 ? { why } : {}),\n ...(e.whyQuality ? { whyQuality: String(e.whyQuality) } : {}),\n entries: [{ entryId: e.entryId, name: e.name, status: e.status, ...(e.workflowStatus ? { workflowStatus: e.workflowStatus } : {}), collectionName: String((e as { collectionName?: string }).collectionName ?? e.canonicalKey ?? \"—\") }],\n // Structured payload uses the same filteredData as the text render — the\n // WHY-source field (rationale or description) is intentionally omitted from\n // `data` because its full value is carried in the top-level `why` field\n // (no information loss; `why` is the complete untruncated extractWhy result).\n // This restores true STD-218 text/structured parity and removes the duplication\n // that commit 8f3b1664 left in the structured payload. (Codex finding, TEN-2191.)\n ...(filteredData ? { data: filteredData } : {}),\n ...(Array.isArray(e.relations) && (e.relations as unknown[]).length > 0\n ? {\n relations: (e.relations as { direction?: string; type?: string; otherEntryId?: string; otherName?: string }[]).map((r) => ({\n ...(r.otherEntryId ? { entryId: r.otherEntryId } : {}),\n name: r.otherName ?? \"unknown\",\n type: r.type ?? \"unknown\",\n direction: r.direction ?? \"unknown\",\n })),\n }\n : {}),\n ...(Array.isArray(e.labels) && (e.labels as unknown[]).length > 0\n ? { labels: (e.labels as { slug?: string; name?: string }[]).map((l) => l.slug ?? l.name ?? \"\") }\n : {}),\n };\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Found ${entryId}: ${String(e.name)} [${String(e.canonicalKey ?? \"\")}].`,\n entryData,\n [\n { tool: \"relations\", description: \"Explore connections\", parameters: { action: \"suggest\", entryId } },\n { tool: \"context\", description: \"Gather related context\", parameters: { action: \"gather\", entryId } },\n ],\n ),\n };\n}\n\nasync function handleBatch(entryIds: string[]) {\n const results = await kernelQuery<GatewayRouteReturnByName<\"chain.batchGetEntries\">>(\"chain.batchGetEntries\", { entryIds });\n\n const lines: string[] = [`## Batch Result`, \"\", `# Batch Get (${results.length} requested)`, \"\"];\n\n for (let i = 0; i < results.length; i++) {\n const r = results[i];\n const requestedId = entryIds[i];\n if (r.error) {\n lines.push(`## ${requestedId}\\n\\n**Error:** ${r.error}\\n`);\n continue;\n }\n const entry = r.entry as Record<string, unknown>;\n lines.push(`## ${entry.entryId ? `${entry.entryId}: ` : \"\"}${entry.name}`);\n lines.push(\"\");\n lines.push(`**Status:** ${entry.status}${entry.workflowStatus ? ` / ${entry.workflowStatus}` : \"\"}`);\n lines.push(`**Type:** ${entry.canonicalKey ?? \"untyped\"}`);\n if (typeof entry.capturedAt === \"number\") {\n lines.push(`**Captured at:** ${new Date(entry.capturedAt).toISOString()}`);\n }\n if (entry.origin) {\n const detail = entry.originDetail ? ` (${entry.originDetail})` : \"\";\n lines.push(`**Origin:** ${entry.origin}${detail}`);\n }\n const entryVerificationLine = renderVerificationLine(entry);\n if (entryVerificationLine) lines.push(entryVerificationLine);\n if (entry.sourceRef) {\n lines.push(`**Source ref:** ${entry.sourceRef}`);\n }\n if (entry.sourceExcerpt) {\n lines.push(`**Source excerpt:** ${entry.sourceExcerpt}`);\n }\n\n // TEN-2191 (STD-218 parity): mirror handleGet's WHY line + source-key suppression.\n // renderWhyLine returns the self-announcing line, the canonical `why` text, and the\n // data key whose value is now surfaced as Why (so we can suppress it from the Data\n // block — lossless because `why` carries the full value). Mirrors handleGet exactly.\n const { line: whyLine, whySourceKey } = renderWhyLine(entry);\n if (whyLine !== null) lines.push(whyLine);\n\n const visibleData = sanitizeEntryData(entry.data);\n // Build filteredData: exclude the why-source key from both text and structured output.\n // Same inline logic as handleGet (~lines 278-282) — see there for the rationale.\n const filteredData = visibleData && whySourceKey\n ? (Object.keys(visibleData).filter((k) => k !== whySourceKey).length > 0\n ? Object.fromEntries(Object.entries(visibleData).filter(([k]) => k !== whySourceKey))\n : undefined)\n : visibleData;\n if (filteredData) {\n lines.push(\"\");\n for (const [key, val] of Object.entries(filteredData)) {\n const display = typeof val === \"string\" ? val : JSON.stringify(val);\n lines.push(`**${key}:** ${display}`);\n }\n }\n\n if (Array.isArray(entry.tags) && entry.tags.length > 0) {\n lines.push(\"\", `**Tags:** ${(entry.tags as string[]).join(\", \")}`);\n }\n\n if (Array.isArray(entry.labels) && (entry.labels as unknown[]).length > 0) {\n const labels = entry.labels as { slug?: string; name?: string }[];\n lines.push(\"\", `**Labels:** ${labels.map((l) => `\\`${l.slug ?? l.name}\\``).join(\", \")}`);\n }\n\n if (Array.isArray(entry.relations) && (entry.relations as unknown[]).length > 0) {\n lines.push(\"\", \"**Relations:**\");\n for (const rel of entry.relations as { direction?: string; type?: string; otherEntryId?: string; otherName?: string }[]) {\n const dir = rel.direction === \"outgoing\" ? \"→\" : \"←\";\n const other = rel.otherEntryId ?? rel.otherName ?? \"?\";\n lines.push(`- ${dir} [${rel.type}] ${other}`);\n }\n }\n\n if (Array.isArray(entry.history) && (entry.history as unknown[]).length > 0) {\n lines.push(\"\", \"**History (last 5):**\");\n for (const h of (entry.history as { timestamp: string; event: string }[]).slice(-5)) {\n const date = new Date(h.timestamp).toISOString().split(\"T\")[0];\n lines.push(`- ${date}: ${h.event}`);\n }\n }\n\n lines.push(\"\");\n }\n\n const structuredEntries = results\n .filter((r) => !r.error && r.entry)\n .map((r) => {\n const entry = r.entry as Record<string, unknown>;\n // TEN-2191 (STD-218 parity): same conditional-spread as handleGet structured payload.\n // renderWhyLine is pure so re-calling it here is safe (no side-effects).\n const { why: entryWhy, whySourceKey: entryWhySourceKey } = renderWhyLine(entry);\n const entryVisibleData = sanitizeEntryData(entry.data);\n const entryFilteredData = entryVisibleData && entryWhySourceKey\n ? (Object.keys(entryVisibleData).filter((k) => k !== entryWhySourceKey).length > 0\n ? Object.fromEntries(Object.entries(entryVisibleData).filter(([k]) => k !== entryWhySourceKey))\n : undefined)\n : entryVisibleData;\n return {\n entryId: String(entry.entryId ?? \"\"),\n name: String(entry.name ?? \"\"),\n collection: String(entry.canonicalKey ?? \"\"),\n status: String(entry.status ?? \"\"),\n ...(typeof entry.capturedAt === \"number\" ? { capturedAt: entry.capturedAt } : {}),\n ...(entry.origin ? { origin: String(entry.origin) } : {}),\n ...(entry.originDetail ? { originDetail: String(entry.originDetail) } : {}),\n ...(entry.verificationStatus ? { verificationStatus: String(entry.verificationStatus) } : {}),\n // Attestation-model finding (PR #341 review): mirror handleGet — forward the\n // honest verifier label + derived attestation on batch's structured payload too.\n ...(typeof entry.verifiedBy === \"string\" ? { verifiedBy: entry.verifiedBy } : {}),\n ...(entry.attestation && typeof entry.attestation === \"object\" ? { attestation: entry.attestation as { strength: string; basis?: string } } : {}),\n ...(entry.sourceRef ? { sourceRef: String(entry.sourceRef) } : {}),\n ...(entry.sourceExcerpt ? { sourceExcerpt: String(entry.sourceExcerpt) } : {}),\n ...(entry.workflowStatus ? { workflowStatus: String(entry.workflowStatus) } : {}),\n // TEN-2191: surface why/whyQuality in structured payload — mirrors handleGet.\n ...(entryWhy.length > 0 ? { why: entryWhy } : {}),\n ...(entry.whyQuality ? { whyQuality: String(entry.whyQuality) } : {}),\n ...(entryFilteredData ? { data: entryFilteredData } : {}),\n };\n });\n\n const total = structuredEntries.length;\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(`Fetched ${total} entries in batch.`, { entries: structuredEntries, total }),\n };\n}\n\nasync function handleList(collection?: string, status?: string, tag?: string, label?: string) {\n let entries: unknown[];\n\n if (label) {\n entries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntriesByLabel\">>(\"chain.listEntriesByLabel\", { labelSlug: label });\n if (status) {\n entries = (entries as { status?: string }[]).filter((e) => e.status === status);\n }\n } else {\n entries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", {\n collectionSlug: collection,\n status,\n tag,\n });\n }\n\n if (entries.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: \"No entries match the given filters.\" }],\n structuredContent: success(\n \"No entries match the given filters.\",\n { entries: [], total: 0 },\n [{ tool: \"collections\", description: \"List collections\", parameters: { action: \"list\" } }],\n ),\n };\n }\n\n const formatted = (entries as { entryId?: string; name?: string; status?: string; workflowStatus?: string; data?: unknown }[])\n .map((e) => {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const statusDisplay = e.workflowStatus ? `${e.status} / ${e.workflowStatus}` : e.status;\n const visibleData = sanitizeEntryData(e.data);\n const dataPreview = visibleData\n ? Object.entries(visibleData)\n .slice(0, 4)\n .map(([k, v]) => ` ${k}: ${typeof v === \"string\" ? v.substring(0, 120) : JSON.stringify(v)}`)\n .join(\"\\n\")\n : \"\";\n return `- ${id}${e.name} \\`${statusDisplay}\\`${dataPreview ? `\\n${dataPreview}` : \"\"}`;\n })\n .join(\"\\n\\n\");\n\n const scope = collection ? ` in \\`${collection}\\`` : \"\";\n\n const structuredEntries = (entries as { entryId?: string; name?: string; status?: string; workflowStatus?: string; canonicalKey?: string }[]).map((e) => ({\n entryId: String(e.entryId ?? \"\"),\n name: String(e.name ?? \"\"),\n collection: String(e.canonicalKey ?? collection ?? \"\"),\n status: String(e.status ?? \"\"),\n ...(e.workflowStatus ? { workflowStatus: e.workflowStatus } : {}),\n }));\n\n const total = structuredEntries.length;\n return {\n content: [{ type: \"text\" as const, text: `## List Result\\n\\n# Entries${scope} (${entries.length})\\n\\n${formatted}` }],\n structuredContent: success(`Found ${total} entries${scope}.`, { entries: structuredEntries, total }),\n };\n}\n\nasync function handleSearch(\n server: McpServer,\n query: string,\n collection?: string,\n status?: string | string[],\n) {\n const scope = collection ? ` in \\`${collection}\\`` : \"\";\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Searching${scope} for \"${query}\"...`,\n logger: \"product-os\",\n });\n\n const [results, collections] = await Promise.all([\n kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query, collectionSlug: collection, status }),\n kernelQuery<unknown[]>(\"chain.listCollections\"),\n ]);\n\n if (results.length === 0) {\n const recorded = recordGap({ query, tool: \"entries\", action: \"search\", gapType: \"search_zero\", collectionScope: collection });\n if (recorded) {\n getWorkspaceId()\n .then((wsId) => trackKnowledgeGap(wsId, { query, tool: \"entries\", action: \"search\", gap_type: \"search_zero\", collection_scope: collection }))\n .catch(() => {});\n }\n\n return {\n content: [{\n type: \"text\" as const,\n text: `\"${query}\" is not yet on the Chain${scope}. Try a broader search or use \\`collections action=list\\` to browse available knowledge.`,\n }],\n structuredContent: success(\n `'${query}' is not yet on the Chain${scope}.`,\n { entries: [], total: 0, query },\n [\n { tool: \"entries\", description: \"Try a broader search\", parameters: { action: \"search\", query: query.split(\" \")[0] } },\n { tool: \"collections\", description: \"Browse available collections\", parameters: { action: \"list\" } },\n ],\n ),\n };\n }\n\n const collMap = new Map<string, { name: string; slug: string }>();\n for (const c of collections as { _id: string; name: string; slug: string }[]) {\n collMap.set(c._id, { name: c.name, slug: c.slug });\n }\n\n const countsBySlug = new Map<string, number>();\n for (const e of results as { collectionId: string }[]) {\n const col = collMap.get(e.collectionId);\n const slug = col?.slug ?? \"unknown\";\n countsBySlug.set(slug, (countsBySlug.get(slug) ?? 0) + 1);\n }\n const collSummary = [...countsBySlug.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([slug, count]) => `${count} ${slug}`)\n .join(\", \");\n\n const formatted = (results as {\n entryId?: string;\n name?: string;\n status?: string;\n workflowStatus?: string;\n collectionId?: string;\n canonicalKey?: string;\n data?: unknown;\n }[])\n .map((e) => {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const statusDisplay = e.workflowStatus ? `${e.status} / ${e.workflowStatus}` : e.status;\n const col = collMap.get(e.collectionId ?? \"\");\n const colTag = col ? ` [${col.slug}]` : \"\";\n const typeTag = e.canonicalKey ? ` (${e.canonicalKey})` : \"\";\n const desc = extractPreview(e.data, 150);\n const preview = desc ? `\\n ${desc}` : \"\";\n return `- ${id}${e.name} \\`${statusDisplay}\\`${colTag}${typeTag}${preview}`;\n })\n .join(\"\\n\");\n\n const header = `## Search Result\\n\\n# Search Results for \"${query}\"${scope} (${results.length} match${results.length === 1 ? \"\" : \"es\"})\\n\\n**By collection:** ${collSummary}`;\n const footer = `_Tip: Use \\`collection\\` param to scope search. Use entries action=get with an entry ID for full details._`;\n\n const structuredResults = (results as {\n entryId?: string;\n name?: string;\n status?: string;\n workflowStatus?: string;\n collectionId?: string;\n score?: number;\n }[]).map((e) => ({\n entryId: String(e.entryId ?? \"\"),\n name: String(e.name ?? \"\"),\n collection: collMap.get(e.collectionId ?? \"\")?.slug ?? \"unknown\",\n status: String(e.status ?? \"\"),\n ...(e.workflowStatus ? { workflowStatus: e.workflowStatus } : {}),\n ...(e.score != null ? { score: e.score } : {}),\n }));\n\n const entriesForView = structuredResults.map((e) => ({\n entryId: e.entryId,\n name: e.name,\n status: e.status,\n collectionName: e.collection,\n }));\n\n const total = structuredResults.length;\n return {\n content: [{ type: \"text\" as const, text: `${header}\\n\\n${formatted}\\n\\n${footer}` }],\n structuredContent: success(`Found ${total} entries matching '${query}'.`, {\n results: structuredResults,\n entries: entriesForView,\n total,\n query,\n }),\n };\n}\n","/**\n * Response Envelope — Agent-Native MCP Contract (BET-78)\n *\n * Universal response shape for all MCP tool responses.\n * Lives in structuredContent — zero breaking changes to content[0].text.\n *\n * Design: envelope IS structuredContent, not nested inside it.\n * Discriminated on `ok` for O(1) agent parsing.\n */\n\nimport { z, type ZodTypeAny } from \"zod/v3\";\nimport { classifyError } from \"./errors.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────\n\nexport interface NextAction {\n tool: string;\n description: string;\n parameters: Record<string, unknown>;\n}\n\n/**\n * Describes the schema contract for a single collection's capture tool.\n * Returned in EnvelopeSuccess.contract for write tools so agents can\n * self-describe required fields without a separate round-trip.\n * WP-316 S0 — downstream slices populate this field on capture responses.\n */\nexport interface CaptureContractField {\n key: string;\n required: boolean;\n type: string;\n helpText?: string;\n}\n\nexport interface CaptureContract {\n requiredFields: string[];\n allFields: CaptureContractField[];\n captureExpectation?: string;\n}\n\n/** Per-step timing for capture pipeline (BET-105, TEN-359). */\nexport interface CaptureTiming {\n classifyMs: number;\n createMs: number;\n autoLinkMs: number;\n userLinksMs: number;\n qualityMs: number;\n totalMs: number;\n}\n\n/** Batch capture timing: wall-clock total and per-entry average. */\nexport interface BatchCaptureTiming {\n totalMs: number;\n perEntryAvgMs: number;\n}\n\nexport interface EnvelopeMeta {\n durationMs?: number;\n /** Per-step timing (single capture) or batch timing (capture action=batch). */\n timing?: CaptureTiming | BatchCaptureTiming;\n /**\n * WP-484 S1 (§4): self-correction hint for the handler-layer backpressure\n * channel. Written against param ABSENCE only, never misspelling — the SDK\n * silently strips undeclared/typo'd params before the handler ever sees\n * them, so a typo surfaces as \"missing `<param>`,\" never \"did you mean.\"\n */\n tip?: string;\n /**\n * WP-484 S1 (§4): structured wrong-call backpressure payload — the\n * handler-layer's answer for a call that passed the registered flat\n * schema's action-enum + type checks but violates the per-action\n * discriminated shape (a valid action with a wrong param combination).\n */\n advisory?: Record<string, unknown>;\n}\n\n// Declared as type ALIASES, not interfaces, on purpose: the envelope is assigned to\n// `ToolResult.structuredContent?: Record<string, unknown>` (:139), and TypeScript grants an\n// implicit index signature to an object type alias but NOT to an interface. As interfaces these\n// were unassignable — 18 TS2322s that nothing could see, because this package was typechecked by\n// nothing until DEC-1447. Keep them as `type`.\nexport type EnvelopeSuccess<T = Record<string, unknown>> = {\n ok: true;\n summary: string;\n data: T;\n next?: NextAction[];\n /** WP-316 S0: Optional capture contract — populated by write tools on create/update responses. */\n contract?: CaptureContract;\n _meta?: EnvelopeMeta;\n};\n\nexport type EnvelopeError = {\n ok: false;\n code: string;\n message: string;\n recovery?: string;\n availableActions?: NextAction[];\n diagnostics?: Record<string, unknown>;\n _meta?: EnvelopeMeta;\n};\n\nexport type Envelope<T = Record<string, unknown>> =\n | EnvelopeSuccess<T>\n | EnvelopeError;\n\n// ─── Builders ────────────────────────────────────────────────────────────\n\nexport function success<T>(\n summary: string,\n data: T,\n next?: NextAction[],\n): EnvelopeSuccess<T> {\n return {\n ok: true,\n summary: summary || \"Operation completed.\",\n data,\n ...(next?.length ? { next } : {}),\n };\n}\n\nexport function failure(\n code: string,\n message: string,\n recovery?: string,\n availableActions?: NextAction[],\n diagnostics?: Record<string, unknown>,\n): EnvelopeError {\n return {\n ok: false,\n code,\n message,\n ...(recovery ? { recovery } : {}),\n ...(availableActions?.length ? { availableActions } : {}),\n ...(diagnostics ? { diagnostics } : {}),\n };\n}\n\n/** Shorthand for NOT_FOUND failures — the most common soft-failure pattern. */\nexport function notFound(id: string, hint?: string): EnvelopeError {\n return failure(\n \"NOT_FOUND\",\n `Entry '${id}' not found.`,\n hint ?? \"Use entries action=search to find the correct ID.\",\n [{ tool: \"entries\", description: \"Search entries\", parameters: { action: \"search\", query: id } }],\n );\n}\n\n/** Shorthand for VALIDATION_ERROR failures. */\nexport function validationError(message: string): EnvelopeError {\n return failure(\"VALIDATION_ERROR\", message);\n}\n\n// ─── Tool Response Helpers ───────────────────────────────────────────────\n\ntype TextContent = { type: \"text\"; text: string };\n// `structuredContent` is REQUIRED, not optional. Every builder below sets it, and the envelope\n// contract is that every tool response carries one — so `?` was a lie the typechecker could never\n// catch (this package was typechecked by nothing until DEC-1447). Left optional, every read of\n// `result.structuredContent.*` is \"possibly undefined\": ~112 TS18048s across the tests, not one of\n// them real. The MCP SDK's own wire type keeps it optional; ours is the narrower internal contract,\n// and it is assignable to the SDK's.\n//\n// It is deliberately `Record<string, unknown>` and NOT `Envelope`. That looks like the obvious\n// improvement — it would restore discriminated-union narrowing at every call site — and it does not\n// work: `successResult<T>` builds an `EnvelopeSuccess<T>` for arbitrary `T`, which is not assignable\n// to `Envelope` (= `Envelope<Record<string, unknown>>`) unless `T extends Record<string, unknown>`,\n// and plenty of handlers return arrays and scalars. MEASURED: it takes the package from 23 errors to\n// 42. Two independent reviewers proposed it; it is wrong. Narrow on the READ side instead — the\n// tests use small runtime-checked accessors that assert `ok` and return the right arm.\nexport type ToolResult = {\n content: TextContent[];\n structuredContent: Record<string, unknown>;\n isError?: boolean;\n};\n\n/** Build a `content` array from a single text string. */\nexport function textContent(text: string): TextContent[] {\n return [{ type: \"text\" as const, text }];\n}\n\n/**\n * Parse args against a Zod schema and return a typed result or a ready-to-return\n * validation error ToolResult. Eliminates the 5-line parse+check+format boilerplate.\n */\nexport function parseOrFail<T extends z.ZodTypeAny>(\n schema: T,\n args: unknown,\n): { ok: true; data: z.infer<T> } | { ok: false; result: ToolResult } {\n const parsed = schema.safeParse(args);\n if (parsed.success) return { ok: true, data: parsed.data };\n const issues = parsed.error.issues\n .map((i: z.ZodIssue) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \");\n const msg = `Invalid arguments: ${issues}`;\n return {\n ok: false,\n result: { content: textContent(msg), structuredContent: validationError(msg) },\n };\n}\n\n/** Standard response for unknown compound-tool actions. */\nexport function unknownAction(action: string, valid: readonly string[]): ToolResult {\n const msg = `Unknown action '${action}'. Valid actions: ${valid.join(\", \")}.`;\n return { content: textContent(msg), structuredContent: validationError(msg) };\n}\n\n// ─── Compound Result Builders ─────────────────────────────────────────\n// Eliminate the { content: [...], structuredContent: ... } boilerplate.\n\n/** Success result with human-readable text + structured envelope in one call. */\nexport function successResult<T>(\n text: string,\n summary: string,\n data: T,\n next?: NextAction[],\n): ToolResult {\n return { content: textContent(text), structuredContent: success(summary, data, next) };\n}\n\n/** Failure result with human-readable text + structured error envelope. */\nexport function failureResult(\n text: string,\n code: string,\n message: string,\n recovery?: string,\n availableActions?: NextAction[],\n diagnostics?: Record<string, unknown>,\n): ToolResult {\n return { content: textContent(text), structuredContent: failure(code, message, recovery, availableActions, diagnostics) };\n}\n\n/** Not-found result — the most common soft failure pattern. */\nexport function notFoundResult(id: string, text?: string, hint?: string): ToolResult {\n return { content: textContent(text ?? `Entry '${id}' not found.`), structuredContent: notFound(id, hint) };\n}\n\n/** Validation error result where the text and error message are the same. */\nexport function validationResult(message: string): ToolResult {\n return { content: textContent(message), structuredContent: validationError(message) };\n}\n\n// ─── Zod Schema Helper ──────────────────────────────────────────────────\n\nconst nextActionSchema = z.object({\n tool: z.string(),\n description: z.string(),\n parameters: z.record(z.unknown()),\n});\n\nconst metaSchema = z\n .object({\n durationMs: z.number().optional(),\n timing: z\n .object({\n classifyMs: z.number().optional(),\n createMs: z.number().optional(),\n autoLinkMs: z.number().optional(),\n userLinksMs: z.number().optional(),\n qualityMs: z.number().optional(),\n totalMs: z.number(),\n perEntryAvgMs: z.number().optional(),\n })\n .passthrough()\n .optional(),\n // WP-484 S1 (§4): backpressure channel — see EnvelopeMeta for the contract.\n tip: z.string().optional(),\n advisory: z.record(z.unknown()).optional(),\n })\n .optional();\n\n/**\n * Wraps any data schema into a discriminated-union envelope schema.\n * Use for contract tests: `envelopeSchema(captureOutputSchema).safeParse(result)`.\n */\nexport function envelopeSchema<T extends ZodTypeAny>(dataSchema: T) {\n return z.discriminatedUnion(\"ok\", [\n z.object({\n ok: z.literal(true),\n summary: z.string().min(1),\n data: dataSchema,\n next: z.array(nextActionSchema).optional(),\n /** WP-316 S1a: capture contract for write tools — optional for backward compat. */\n contract: z.object({\n requiredFields: z.array(z.string()),\n allFields: z.array(z.object({\n key: z.string(),\n required: z.boolean(),\n type: z.string(),\n helpText: z.string().optional(),\n })),\n captureExpectation: z.string().optional(),\n }).optional(),\n _meta: metaSchema,\n }),\n z.object({\n ok: z.literal(false),\n code: z.string().min(1),\n message: z.string().min(1),\n recovery: z.string().optional(),\n availableActions: z.array(nextActionSchema).optional(),\n diagnostics: z.record(z.unknown()).optional(),\n _meta: metaSchema,\n // DEC-798\n class: z.enum(['transient','permanent','auth','notfound','payload','rate_limited']).optional(),\n retryAdvised: z.boolean().optional(),\n }),\n ]);\n}\n\n// ─── withEnvelope HOF ───────────────────────────────────────────────────\n\n/**\n * Wraps a tool handler to guarantee an Envelope in structuredContent.\n *\n * - Catches thrown errors (gates, backend) and classifies them.\n * - If the handler already returns an envelope (ok field present), passes through.\n * - Adds _meta.durationMs to every response.\n * - Owns isError: sets true iff ok===false (RH1 mitigation — TEN-206).\n *\n * @deprecated Use `thinWrapper` for new and migrated tools. `withEnvelope` retains\n * the safety net that auto-wraps non-envelope responses; `thinWrapper` throws instead,\n * making incomplete migrations visible immediately.\n */\nexport function withEnvelope<Args>(\n handler: (args: Args) => Promise<ToolResult>,\n): (args: Args) => Promise<ToolResult> {\n return async (args: Args): Promise<ToolResult> => {\n const start = Date.now();\n try {\n const result = await handler(args);\n const durationMs = Date.now() - start;\n\n const sc = result.structuredContent as Envelope | undefined;\n if (sc && typeof sc === \"object\" && \"ok\" in sc) {\n sc._meta = { ...sc._meta, durationMs };\n return {\n content: result.content ?? [],\n structuredContent: sc,\n ...(sc.ok === false ? { isError: true } : {}),\n };\n }\n\n // Safety net: all tools should be migrated. If this executes, a handler\n // is returning without an envelope — log so it surfaces during development.\n console.warn(`[withEnvelope] Handler returned without envelope shape. Wrapping automatically. Content preview: \"${result.content?.[0]?.text?.slice(0, 60) ?? \"(empty)\"}\"`);\n return {\n content: result.content ?? [],\n structuredContent: {\n ...success(\n result.content?.[0]?.text?.slice(0, 100) ?? \"\",\n sc ?? {},\n ),\n _meta: { durationMs },\n },\n };\n } catch (err) {\n const durationMs = Date.now() - start;\n const classified = classifyError(err);\n const envelope: EnvelopeError = {\n ...failure(\n classified.code,\n classified.message,\n classified.recovery,\n classified.availableActions,\n // WP-316 S1a: pass structured diagnostics (e.g. missingRequiredFields, fieldErrors)\n classified.diagnostics as Record<string, unknown> | undefined,\n ),\n _meta: { durationMs },\n };\n return {\n content: [{\n type: \"text\" as const,\n text: classified.fn\n ? `[${classified.code}/${classified.fn}] ${classified.message}`\n : `[${classified.code}] ${classified.message}`\n }],\n structuredContent: envelope,\n isError: true,\n };\n }\n };\n}\n\n// ─── thinWrapper HOF ────────────────────────────────────────────────────\n\n/**\n * Strict variant of `withEnvelope` for fully-migrated tools (WP-321 E3).\n *\n * Identical to `withEnvelope` EXCEPT the safety net is replaced with a hard\n * throw. If a handler returns without an envelope shape, this surfaces\n * immediately as an error rather than silently wrapping the response.\n *\n * Use this for all new tools and all tools that have been migrated to return\n * envelope-shaped responses directly.\n */\nexport function thinWrapper<Args>(\n handler: (args: Args) => Promise<ToolResult>,\n): (args: Args) => Promise<ToolResult> {\n return async (args: Args): Promise<ToolResult> => {\n const start = Date.now();\n try {\n const result = await handler(args);\n const durationMs = Date.now() - start;\n\n const sc = result.structuredContent as Envelope | undefined;\n if (sc && typeof sc === \"object\" && \"ok\" in sc) {\n sc._meta = { ...sc._meta, durationMs };\n return {\n content: result.content ?? [],\n structuredContent: sc,\n ...(sc.ok === false ? { isError: true } : {}),\n };\n }\n\n throw new Error(`[thinWrapper] Handler '${handler.name || \"<anonymous>\"}' returned without envelope shape — migration incomplete.`);\n } catch (err) {\n const durationMs = Date.now() - start;\n const classified = classifyError(err);\n const envelope: EnvelopeError = {\n ...failure(\n classified.code,\n classified.message,\n classified.recovery,\n classified.availableActions,\n // WP-316 S1a: pass structured diagnostics (e.g. missingRequiredFields, fieldErrors)\n classified.diagnostics as Record<string, unknown> | undefined,\n ),\n _meta: { durationMs },\n };\n return {\n content: [{\n type: \"text\" as const,\n text: classified.fn\n ? `[${classified.code}/${classified.fn}] ${classified.message}`\n : `[${classified.code}] ${classified.message}`\n }],\n structuredContent: envelope,\n isError: true,\n };\n }\n };\n}\n","/**\n * Structured error classification for the Response Envelope (BET-78, FEAT-121).\n *\n * Typed error classes + classifyError pattern-matching.\n * classifyError handles both typed classes (new code) and plain Error\n * messages from client.ts gates (existing code — no modifications needed).\n *\n * BET-191 (FEAT-573): KernelCallError carries a .code from the Convex HTTP gateway\n * (classifyMcpGatewayError). VALIDATION_FAILED errors must surface the clean\n * validation message — not the HTTP wrapper prefix — so agents receive actionable\n * \"Field X must be one of: ...\" text without noise.\n *\n * WP-321 E3a: Output codes emitted by classifyError are registered as the unified\n * error code SSOT in convex/lib/errors.ts::ErrorCodes. The MCP server cannot\n * import from convex/ (monorepo boundary: ARCH-55, BR-154), so the string values\n * are maintained as inline constants here — but they MUST match the corresponding\n * entries in ErrorCodes exactly. Verified output codes:\n * SESSION_REQUIRED, SESSION_CLOSED, ORIENTATION_REQUIRED, READONLY_SCOPE,\n * BACKEND_UNAVAILABLE, BACKEND_ERROR, INTERNAL_ERROR, DUPLICATE,\n * PERMISSION_DENIED, VALIDATION_ERROR, NOT_FOUND\n * The canonical registry lives in convex/lib/errors.ts — update there first\n * if a code name ever needs to change, then update the strings here to match.\n */\n\nimport type { NextAction } from \"./envelope.js\";\n\n// ─── KernelCallError duck-type helpers ──────────────────────────────────────────\n// KernelCallError is defined in client.ts and carries the structured code from the\n// Convex HTTP gateway. We use duck typing to avoid a circular import.\n\n/**\n * Matches `MCP call \"fn\" failed (STATUS): <clean message>` — the KernelCallError\n * message format from client.ts. Group 1 = fn scope, group 2 = clean backend message.\n */\n// DEC-798: group 1 = fn scope, group 2 = clean message\nconst MCP_CALL_ERROR_RE = /^MCP call \"([^\"]+)\" failed \\(\\d+\\): (.+)$/s;\n\n/**\n * If err is a KernelCallError (duck typed via .code and MCP_CALL_ERROR_RE message),\n * extract the structured code, fn scope, clean message, and WP-316 S1a diagnostics.\n * Returns undefined if not a match.\n */\nfunction asKernelCallError(\n err: unknown,\n): {\n code: string;\n fn: string;\n cleanMessage: string;\n missingRequiredFields?: string[];\n fieldErrors?: string[];\n} | undefined {\n if (!(err instanceof Error)) return undefined;\n const e = err as Error & {\n code?: unknown;\n missingRequiredFields?: unknown;\n fieldErrors?: unknown;\n };\n if (typeof e.code !== \"string\") return undefined;\n const match = MCP_CALL_ERROR_RE.exec(e.message);\n if (!match) return undefined;\n return {\n code: e.code,\n fn: match[1],\n cleanMessage: match[2], // NOTE: match[2] not match[1] — group 1 is now fn scope (DEC-798)\n missingRequiredFields: Array.isArray(e.missingRequiredFields) ? e.missingRequiredFields : undefined,\n fieldErrors: Array.isArray(e.fieldErrors) ? e.fieldErrors : undefined,\n };\n}\n\n// ─── Typed Error Classes ─────────────────────────────────────────────────\n\nexport class GateError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"GateError\";\n }\n}\n\nexport class BackendError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BackendError\";\n }\n}\n\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\n// ─── Classification Result ───────────────────────────────────────────────\n\nexport interface ClassifiedError {\n code: string;\n message: string;\n fn?: string; // DEC-798: Convex function scope from KernelCallError\n recovery?: string;\n availableActions?: NextAction[];\n /** WP-316 S1a: Structured commit validation diagnostics when code=VALIDATION_ERROR. */\n diagnostics?: {\n missingRequiredFields?: string[];\n fieldErrors?: string[];\n };\n}\n\n// ─── Gate Patterns (from client.ts requireWriteAccess / requireActiveSession) ─\n\ninterface GatePattern {\n pattern: RegExp;\n code: string;\n recovery: string;\n action: NextAction;\n}\n\nconst GATE_PATTERNS: GatePattern[] = [\n {\n pattern: /session required|no active.*session|call.*session.*start/i,\n code: \"SESSION_REQUIRED\",\n recovery: \"Start an agent session first.\",\n action: { tool: \"session\", description: \"Start session\", parameters: { action: \"start\" } },\n },\n {\n pattern: /session.*closed/i,\n code: \"SESSION_CLOSED\",\n recovery: \"Start a new session.\",\n action: { tool: \"session\", description: \"Start new session\", parameters: { action: \"start\" } },\n },\n {\n pattern: /orientation required|call.*orient/i,\n code: \"ORIENTATION_REQUIRED\",\n recovery: \"Orient before writing.\",\n action: { tool: \"orient\", description: \"Orient session\", parameters: {} },\n },\n {\n pattern: /read.?only.*scope/i,\n code: \"READONLY_SCOPE\",\n recovery: \"This API key cannot write. Use a readwrite key.\",\n action: { tool: \"workspace\", description: \"Check key scope\", parameters: { action: \"whoami\" } },\n },\n];\n\n// ─── Classification ──────────────────────────────────────────────────────\n\n/**\n * Classify an error into a structured code + recovery path.\n * Handles:\n * 1. Gate errors (from requireWriteAccess / requireActiveSession)\n * 2. KernelCallError with structured Convex codes (VALIDATION_FAILED, NOT_FOUND, DUPLICATE)\n * 3. Backend errors (network/connectivity)\n * 4. Pattern-matched validation / not-found / duplicate messages\n * 5. Fallback to INTERNAL_ERROR\n */\nexport function classifyError(err: unknown): ClassifiedError {\n const message = err instanceof Error ? err.message : String(err);\n\n if (err instanceof GateError) {\n return {\n code: \"PERMISSION_DENIED\",\n message,\n recovery: \"Check permissions or use a readwrite API key.\",\n availableActions: [{ tool: \"workspace\", description: \"Check key scope\", parameters: { action: \"whoami\" } }],\n };\n }\n\n if (err instanceof BackendError) {\n return { code: \"BACKEND_ERROR\", message, recovery: \"Retry the operation or check backend health.\" };\n }\n\n if (err instanceof ValidationError) {\n return { code: \"VALIDATION_ERROR\", message };\n }\n\n // BET-191 (FEAT-573): KernelCallError carries the structured Convex error code from\n // classifyMcpGatewayError. Use it for clean classification before falling through\n // to regex matching, so agents receive the clean backend message without the\n // \"MCP call ... failed (400):\" HTTP wrapper prefix.\n const mcpErr = asKernelCallError(err);\n if (mcpErr) {\n const { code: convexCode, fn, cleanMessage, missingRequiredFields, fieldErrors } = mcpErr;\n if (convexCode === \"VALIDATION_FAILED\") {\n const hasDiagnostics = missingRequiredFields?.length || fieldErrors?.length;\n return {\n code: \"VALIDATION_ERROR\",\n fn,\n message: cleanMessage,\n ...(hasDiagnostics ? {\n diagnostics: {\n ...(missingRequiredFields?.length ? { missingRequiredFields } : {}),\n ...(fieldErrors?.length ? { fieldErrors } : {}),\n },\n } : {}),\n };\n }\n if (convexCode === \"NOT_FOUND\") {\n return {\n code: \"NOT_FOUND\",\n fn,\n message: cleanMessage,\n recovery: \"Use entries action=search to find the correct ID.\",\n availableActions: [{ tool: \"entries\", description: \"Search entries\", parameters: { action: \"search\" } }],\n };\n }\n // BR-227 (WP-584 S4): an active-but-wrong-role session is an AUTHORIZATION failure, not a\n // session failure — convex/http.ts's vendor-route gate (and any other AUTHZ_* refusal that\n // reaches the gateway) must classify to PERMISSION_DENIED, never fall through to a raw,\n // un-mapped code or (worse, pre-fix) get misread by the GATE_PATTERNS regex below as a\n // session problem. Mirrors the header comment's documented (but previously unimplemented)\n // \"PERMISSION_DENIED... Maps from AUTHZ_PERMISSION_DENIED + GateError\" contract — a real\n // family match (review round 1, P2-4), not three hand-picked literals: a fixed list drifts\n // the moment the gateway emits a fourth AUTHZ_* code this file never learns about.\n if (convexCode?.startsWith(\"AUTHZ_\")) {\n return {\n code: \"PERMISSION_DENIED\",\n fn,\n message: cleanMessage,\n recovery: \"Check permissions or use a readwrite API key.\",\n availableActions: [{ tool: \"workspace\", description: \"Check key scope\", parameters: { action: \"whoami\" } }],\n };\n }\n if (convexCode === \"WORKSPACE_SLUG_TAKEN\" || convexCode === \"PERSON_ALREADY_EXISTS\") {\n return {\n code: \"DUPLICATE\",\n fn,\n message: cleanMessage,\n recovery: \"Use entries action=get to inspect the existing entry.\",\n availableActions: [{ tool: \"entries\", description: \"Get entry\", parameters: { action: \"get\" } }],\n };\n }\n // TEN-656: per-key API quota (HTTP 429, code 'rate-limited' — registered in\n // convex/lib/errors.ts ErrorCodes.RATE_LIMITED). The refusal must be agent-legible\n // (TEN-2655): say exactly what to do — wait, then retry the same call unchanged.\n if (convexCode === \"rate-limited\") {\n return {\n code: \"rate-limited\",\n fn,\n message: cleanMessage,\n recovery:\n \"Rate limit hit for this API key. Wait the number of seconds in the message (Retry-After), then retry the same call unchanged — it is safe to retry.\",\n };\n }\n // Fallthrough for any other convexCode: preserve fn for the prefix format\n return { code: convexCode, fn, message: cleanMessage };\n }\n\n for (const { pattern, code, recovery, action } of GATE_PATTERNS) {\n if (pattern.test(message)) {\n return { code, message, recovery, availableActions: [action] };\n }\n }\n\n // WP-575 / PR #533 review (Codex P2). A gateway budget abort must be classified as itself.\n // Before this branch existed it fell through to INTERNAL_ERROR — strictly worse than the\n // pre-WP-575 behavior, where the old `MCP call \"X\" network error: …` text matched the\n // regex below and at least produced BACKEND_UNAVAILABLE. Only the capture path special-\n // cases the typed error; EVERY other MCP tool reaches classifyError, so without this the\n // \"the write may have landed\" fact — the entire point of the type — was dropped on the\n // floor for all of them. Matched on `name`, not `instanceof`: same reason as\n // lib/captureTimeoutOutcome.ts's guard (mocked modules, bundler duplication).\n if ((err as { name?: string } | null | undefined)?.name === \"GatewayTimeoutError\") {\n const mayHaveLanded = (err as { mayHaveLanded?: boolean }).mayHaveLanded === true;\n return {\n code: \"GATEWAY_TIMEOUT\",\n message,\n recovery: mayHaveLanded\n ? \"The server was reachable and may have completed this write — verify before retrying, since a blind retry can duplicate it.\"\n : \"The server was reachable but did not answer in time. Nothing was written — safe to retry.\",\n };\n }\n\n if (/network error|fetch failed|ECONNREFUSED|ETIMEDOUT/i.test(message)) {\n return { code: \"BACKEND_UNAVAILABLE\", message, recovery: \"Retry in a few seconds.\" };\n }\n\n return { code: \"INTERNAL_ERROR\", message: message || \"An unexpected error occurred.\" };\n}\n","/**\n * Shared helpers for knowledge tools. Extracted from knowledge.ts for reuse\n * across entries, relations, graph, context, and collections compound tools.\n */\n\n// ─── Epistemic Status ─────────────────────────────────────────────────\n// Pure derivation of confidence level for claim-carrying entries (BR-85).\n// Used by entries/get, commit-entry, and context/gather to surface trust signals.\n\n// BET-281: Epistemic collections have fundamentally different validation logic\n// (assumptions use untested→testing→validated/invalidated; insights use hypothesis→evidenced→validated).\n// This is intentionally collection-specific (Tier 3 pattern per STD-20).\n// When governanceRole is available, replace with governanceRole === 'epistemic' filter.\nconst EPISTEMIC_COLLECTIONS = new Set([\"insights\", \"assumptions\"]);\n\nexport interface EpistemicStatus {\n level: \"validated\" | \"evidenced\" | \"hypothesis\" | \"untested\" | \"testing\" | \"invalidated\";\n reason: string;\n action?: string;\n}\n\n/**\n * Derives epistemic confidence from entry data + relations.\n * Returns null for non-epistemic entry types.\n */\nexport function deriveEpistemicStatus(entry: {\n collectionName?: string;\n workflowStatus?: string;\n relations?: Array<{ type?: string; direction?: string }>;\n}): EpistemicStatus | null {\n const coll = entry.collectionName?.toLowerCase();\n if (!coll || !EPISTEMIC_COLLECTIONS.has(coll)) return null;\n\n const relations = entry.relations ?? [];\n const hasValidates = relations.some(\n (r) => r.type === \"validates\" && r.direction === \"incoming\",\n );\n const hasInvalidates = relations.some(\n (r) => r.type === \"invalidates\" && r.direction === \"incoming\",\n );\n const evidenceCount = relations.filter(\n (r) => (r.type === \"validates\" || r.type === \"invalidates\") && r.direction === \"incoming\",\n ).length;\n\n if (coll === \"assumptions\") {\n const ws = entry.workflowStatus;\n if (ws === \"invalidated\" || hasInvalidates) {\n return { level: \"invalidated\", reason: \"Disproved by linked counter-evidence\" };\n }\n if (ws === \"validated\" || (hasValidates && ws !== \"untested\")) {\n return { level: \"validated\", reason: `${evidenceCount} evidence link${evidenceCount !== 1 ? \"s\" : \"\"}` };\n }\n if (ws === \"testing\") {\n return { level: \"testing\", reason: \"Experiment in progress\" };\n }\n return { level: \"untested\", reason: \"No evidence linked\", action: \"Link evidence via `relations action=create type=\\\"validates\\\"`\" };\n }\n\n // Insights: derive from workflowStatus first, then from relations (BR-85).\n // Deliberate AND: workflowStatus alone isn't enough — linked evidence is required.\n // Setting ws=\"validated\" without evidence still returns \"hypothesis\" per BR-85.\n const ws = entry.workflowStatus;\n if (ws === \"validated\" && hasValidates) {\n return { level: \"validated\", reason: `${evidenceCount} evidence link${evidenceCount !== 1 ? \"s\" : \"\"}` };\n }\n if (ws === \"evidenced\" || hasValidates) {\n return { level: \"evidenced\", reason: `${evidenceCount} evidence link${evidenceCount !== 1 ? \"s\" : \"\"}` };\n }\n // BR-85: insight without linked evidence defaults to hypothesis\n return {\n level: \"hypothesis\",\n reason: \"No linked evidence\",\n action: \"Link proof via `relations action=create type=\\\"validates\\\"`\",\n };\n}\n\n/** Format epistemic status as a single markdown line for MCP text responses. */\nexport function formatEpistemicLine(es: EpistemicStatus): string {\n const icon = es.level === \"validated\" ? \"✓\"\n : es.level === \"evidenced\" ? \"◎\"\n : es.level === \"hypothesis\" ? \"△\"\n : es.level === \"untested\" ? \"?\"\n : es.level === \"testing\" ? \"◎\"\n : \"✕\";\n const suffix = es.action ? ` ${es.action}` : \"\";\n return `**Confidence:** ${icon} ${es.level} — ${es.reason}.${suffix}`;\n}\n\n/** Adapts a raw entry record into the shape deriveEpistemicStatus expects. */\nexport function toEpistemicInput(entry: Record<string, unknown>) {\n return {\n collectionName: typeof entry.collectionName === \"string\" ? entry.collectionName : undefined,\n workflowStatus: typeof entry.workflowStatus === \"string\" ? entry.workflowStatus : undefined,\n relations: Array.isArray(entry.relations)\n ? (entry.relations as Array<{ direction?: string; type?: string }>).map((r) => ({ type: r.type, direction: r.direction }))\n : undefined,\n };\n}\n\n/** Compact suffix for list/context views. Only emits for low-confidence entries. */\nexport function epistemicSuffix(es: EpistemicStatus | null): string {\n if (!es) return \"\";\n if (es.level === \"validated\") return \"\";\n if (es.level === \"evidenced\") return \"\";\n if (es.level === \"hypothesis\") return \" `△ hypothesis`\";\n if (es.level === \"untested\") return \" `? untested`\";\n if (es.level === \"testing\") return \" `◎ testing`\";\n if (es.level === \"invalidated\") return \" `✕ invalidated`\";\n return \"\";\n}\n\n// ─── General helpers ──────────────────────────────────────────────────\n\nexport function extractPreview(data: unknown, maxLen: number): string {\n if (!data || typeof data !== \"object\") return \"\";\n const d = data as Record<string, unknown>;\n const raw = d.description ?? d.canonical ?? d.detail ?? d.rule ?? \"\";\n if (typeof raw !== \"string\" || !raw) return \"\";\n return raw.length > maxLen ? raw.substring(0, maxLen) + \"...\" : raw;\n}\n\n/**\n * Canonical tool-name translation map.\n * Maps deprecated atomic tool names to their consolidated compound equivalents.\n * Used by context/orient to annotate stale references in historical content\n * (plans, docs, prototypes) without bulk-editing those files.\n *\n * WP-484 S3 (clean break, TEN-2157): retargeted + extended. Two changes:\n * (1) pre-WP-484 entries whose RHS pointed at a name that ALSO retired in S3\n * (`graph`, `health`, `session-wrapup`) are retargeted to the new noun so the\n * coach never routes an agent toward a second dead name; (2) the 25 tool\n * names that retired in S3 (37 total − 12 reused: the 9 core nouns plus\n * `chain` and `chain-review` — `chain-review` was REUSED as a compound name\n * in S2, a ruled deviation from the original 11-reused/26-retiring count) are\n * added as new entries, so a stale reference to any pre-S3 name gets coached\n * to current syntax.\n */\nexport const TOOL_NAME_MIGRATIONS: ReadonlyMap<string, string> = new Map([\n // ─── Pre-WP-484 atomic names (retargeted where the old RHS also retired) ──\n [\"list-entries\", 'entries action=\"list\"'],\n [\"get-entry\", 'entries action=\"get\"'],\n [\"batch-get\", 'entries action=\"batch\"'],\n [\"search\", 'entries action=\"search\"'],\n [\"relate-entries\", 'relations action=\"create\"'],\n [\"batch-relate\", 'relations action=\"batch-create\"'],\n [\"find-related\", 'relations action=\"find\"'],\n [\"suggest-links\", 'relations action=\"suggest\"'],\n [\"gather-context\", 'context action=\"gather\"'],\n [\"get-build-context\", 'context action=\"build\"'],\n [\"list-collections\", 'collections action=\"list\"'],\n [\"create-collection\", 'collections action=\"create\"'],\n [\"update-collection\", 'collections action=\"update\"'],\n [\"agent-start\", 'session action=\"start\"'],\n [\"agent-close\", 'session action=\"close\"'],\n [\"agent-status\", 'session action=\"status\"'],\n [\"workspace-status\", 'workspace action=\"status\"'],\n [\"mcp-audit\", 'workspace action=\"audit\"'],\n [\"quality-check\", 'quality action=\"check\"'],\n [\"re-evaluate\", 'quality action=\"re-evaluate\"'],\n [\"list-workflows\", 'workflows action=\"list\"'],\n [\"workflow-checkpoint\", 'workflows action=\"checkpoint\"'],\n [\"wrapup\", 'session action=\"wrapup-review\"'],\n [\"finish\", 'session action=\"wrapup-review\"'],\n // ─── WP-484 S3 clean break: the 21 retiring standalone tool names ────────\n // (WP-687 S2 retired the map tool and its 4 migration rows below.)\n // Multi-action retired tools map to the FULL action menu (pipe / wildcard\n // form), never a single default action: the coach only matches the retired\n // NAME, so historical text like `facilitate action=commit-constellation`\n // would otherwise be annotated with the wrong action (e.g. → resume) and\n // send the agent down the wrong path (PR #362 review finding).\n [\"update-entry\", 'entries action=\"update\"'],\n [\"get-history\", 'entries action=\"history\"'],\n [\"commit-entry\", 'entries action=\"commit\"'],\n [\"move-entry\", 'entries action=\"move\"'],\n [\"session-wrapup\", 'session action=\"wrapup-review|wrapup-commit\" (review → wrapup-review, commit-all → wrapup-commit)'],\n [\"facilitate\", 'session action=\"resume|commit-constellation\" (same action names)'],\n [\"graph\", 'relations action=\"find|suggest\" (same action names)'],\n [\"documents\", 'context action=\"last-verified-brief\"'],\n [\"labels\", 'collections action=\"label-*\" (list/create/update/delete/apply/remove → label-<same>)'],\n [\"health\", 'workspace action=\"check|whoami|status|audit|self-test\" (same action names)'],\n [\"verify\", 'quality action=\"verify-chain\"'],\n [\"verify-entry\", 'entries action=\"verify\"'],\n [\"batch-capture\", 'capture action=\"batch\" (entries[] → items[])'],\n [\"skills\", 'workflows action=\"load-skill\"'],\n [\"start_pb\", 'orient action=\"start\"'],\n [\"record_activation\", 'orient action=\"record-activation\"'],\n [\"get-usage-summary\", 'workspace action=\"usage\"'],\n [\"audit\", 'quality action=\"audit\"'],\n [\"governance-proposals\", 'workspace action=\"proposals-list|proposals-respond|proposals-count\" (list/respond/count → proposals-<same>)'],\n [\"chain-version\", 'chain action=\"version.*\" (commit/list/diff/revert/history → version.<same>)'],\n [\"chain-branch\", 'chain-review action=\"branch.*\" (create/list/merge/conflicts → branch.<same>)'],\n]);\n\n/**\n * Translates any deprecated tool names found in text to their current equivalents.\n * Returns null if no translations were needed, or a footnote string listing them.\n */\nexport function translateStaleToolNames(text: string): string | null {\n const found: string[] = [];\n for (const [old, current] of TOOL_NAME_MIGRATIONS) {\n const pattern = new RegExp(`\\\\b${old.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\b`, \"g\");\n if (pattern.test(text)) {\n found.push(`\\`${old}\\` → \\`${current}\\``);\n }\n }\n if (found.length === 0) return null;\n return `\\n\\n---\\n_Tool name translations (these references use deprecated names):_\\n${found.map(f => `- ${f}`).join(\"\\n\")}`;\n}\n","/**\n * Knowledge gap store — tracks what agents searched for and couldn't find.\n * BET-89: Knowledge Gap Sensing.\n *\n * Dual layer:\n * In-memory — session-scoped, fast, used for wrapup/start surfacing.\n * Persistent — fire-and-forget writes to Convex via `gaps.record`.\n * Cross-session, admin-only reads. Survives restarts.\n *\n * Gaps are keyed by agent session ID so concurrent sessions don't leak\n * state across each other. Sessionless callers (e.g. stdio transport)\n * use a fallback \"__sessionless__\" key.\n *\n * Deduplicates within a 60s window to avoid noise from confused agents\n * retrying the same query.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelMutation, getAgentSessionId } from \"./client.js\";\n\nexport type GapType =\n | \"search_zero\"\n | \"context_task_empty\"\n | \"context_entry_isolated\"\n | \"context_graph_empty\";\n\nexport interface KnowledgeGap {\n query: string;\n tool: string;\n action: string;\n gapType: GapType;\n collectionScope?: string;\n timestamp: number;\n}\n\nconst SESSIONLESS_KEY = \"__sessionless__\";\nconst sessionGaps = new Map<string, KnowledgeGap[]>();\nconst DEDUP_WINDOW_MS = 60_000;\n\nfunction currentSessionKey(): string {\n return getAgentSessionId() ?? SESSIONLESS_KEY;\n}\n\nfunction getGapsForSession(sessionKey: string): KnowledgeGap[] {\n let gaps = sessionGaps.get(sessionKey);\n if (!gaps) {\n gaps = [];\n sessionGaps.set(sessionKey, gaps);\n }\n return gaps;\n}\n\nfunction isDuplicate(gaps: KnowledgeGap[], gap: KnowledgeGap): boolean {\n const cutoff = gap.timestamp - DEDUP_WINDOW_MS;\n return gaps.some(\n (existing) =>\n existing.query === gap.query &&\n existing.tool === gap.tool &&\n existing.action === gap.action &&\n existing.timestamp >= cutoff,\n );\n}\n\n/**\n * Record a gap in-memory and persist to Convex (fire-and-forget).\n * Returns true if the gap was new (not deduplicated).\n */\nexport function recordGap(gap: Omit<KnowledgeGap, \"timestamp\">): boolean {\n const timestamped: KnowledgeGap = { ...gap, timestamp: Date.now() };\n const sessionKey = currentSessionKey();\n const gaps = getGapsForSession(sessionKey);\n if (isDuplicate(gaps, timestamped)) return false;\n gaps.push(timestamped);\n\n persistGap(gap);\n return true;\n}\n\nfunction persistGap(gap: Omit<KnowledgeGap, \"timestamp\">): void {\n const sessionId = getAgentSessionId();\n kernelMutation(\"gaps.record\", {\n sessionId: sessionId ?? undefined,\n query: gap.query,\n tool: gap.tool,\n action: gap.action,\n gapType: gap.gapType,\n collectionScope: gap.collectionScope,\n }).catch(() => {\n // Persistence is best-effort; in-memory store is the primary path.\n });\n}\n\nexport function getSessionGaps(): readonly KnowledgeGap[] {\n return getGapsForSession(currentSessionKey());\n}\n\n/** Top gaps by frequency — returns unique queries ranked by how often they appeared. */\nexport function getTopGaps(limit = 5): Array<{ query: string; count: number; gapType: GapType }> {\n const gaps = getGapsForSession(currentSessionKey());\n const counts = new Map<string, { count: number; gapType: GapType }>();\n for (const gap of gaps) {\n const key = gap.query.toLowerCase().trim();\n const existing = counts.get(key);\n if (existing) {\n existing.count++;\n } else {\n counts.set(key, { count: 1, gapType: gap.gapType });\n }\n }\n return [...counts.entries()]\n .map(([query, { count, gapType }]) => ({ query, count, gapType }))\n .sort((a, b) => b.count - a.count)\n .slice(0, limit);\n}\n\nexport function clearSessionGaps(): void {\n const sessionKey = currentSessionKey();\n sessionGaps.delete(sessionKey);\n}\n\n/**\n * Remove all gaps for a specific session ID.\n * Called during session teardown to prevent unbounded memory growth.\n */\nexport function cleanupSessionGaps(sessionId: string): void {\n sessionGaps.delete(sessionId);\n}\n\n/**\n * Resolve persistent gaps matching a newly captured entry.\n * Fire-and-forget — called from smart-capture after successful create.\n */\nexport function resolveGapsForEntry(entryName: string, entryId: string): void {\n kernelMutation<GatewayRouteReturnByName<\"gaps.resolve\">>(\"gaps.resolve\", { entryName, entryId }).catch(() => {\n // Best-effort decay; failure doesn't affect capture flow.\n });\n}\n","/**\n * Shared two-layer compound-tool dispatch scaffolding (WP-484 S1, §3/§4).\n *\n * ── The mechanism (empirically proven, S1 SDK spike) ─────────────────────\n *\n * Layer (a) — REGISTERED: every compound tool registers a FLAT ZodObject\n * (`{ action: z.enum([...]), ...allParams }`) as its `inputSchema`. This is\n * mandatory, never a top-level `z.discriminatedUnion` — on SDK 1.27.1 (the\n * pinned dependency) `tools/list` serialization\n * (`normalizeObjectSchema` in `@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js`)\n * only recognizes schemas exposing `.shape` (zod v3) or `def.type === 'object'`\n * (zod v4) — a union has neither, so it silently falls back to\n * `EMPTY_OBJECT_JSON_SCHEMA` and the client sees a parameterless tool while\n * call-time validation keeps working (a silent, tests-green failure).\n *\n * **S1 SPIKE (§3c) — re-verified against the newest published SDK (1.29.0,\n * fetched via `npm pack` for inspection, not installed): the SAME\n * `normalizeObjectSchema` gate ships unchanged in 1.29.0 — it still only\n * recognizes `.shape` / `def.type === 'object'`, so a `discriminatedUnion`\n * still erases to `EMPTY_OBJECT_JSON_SCHEMA` there too.** Outcome: DO NOT\n * upgrade — the two-layer shape is not a workaround for a fixed-in-newer-SDK\n * bug, it is the correct shape for every SDK version available today. This\n * spike is re-run (and this comment re-verified) before any future SDK bump.\n *\n * Layer (b) — HANDLER: an internal per-action `z.discriminatedUnion(\"action\", [...])`\n * validates the call once past the registered layer. Call-time validation of\n * unions is the half that's proven to work.\n *\n * ── Division of labor (§4, Pass-1 Domain D4, amended v3.1) ────────────────\n *\n * The SDK's registered-layer validation PREEMPTS the handler for two of three\n * wrong-call classes — (i) an unknown `action` and (ii) a wrong param TYPE —\n * both return the registered layer's raw zod error in-band before the handler\n * ever runs. That is accepted, not fought: zod's enum error already carries\n * the valid-options list, so agents self-correct on it (`action` is\n * deliberately NOT loosened to `z.string()` — the served enum's\n * discoverability is the point). Everything the deliberately-loose flat layer\n * passes through — a valid action with a wrong param COMBINATION, or a\n * per-action-enum violation — reaches `dispatchDiscriminated` below, which\n * answers with the structured backpressure `backpressureResult()` builds:\n * never raw zod text on this path.\n */\n\nimport { z, type ZodDiscriminatedUnion } from \"zod/v3\";\nimport { textContent, validationError, type ToolResult } from \"./envelope.js\";\n\n/**\n * One entry per action — a human-readable param spec used ONLY to build the\n * backpressure message, never for registration (the registered schema is the\n * flat ZodObject built separately per §3a, in each tool's own schema file).\n */\nexport interface ActionParamSpec {\n /**\n * Declared param names this action accepts. Absence-only (§4 probe note):\n * the SDK silently strips undeclared/typo'd params before the handler ever\n * sees them, so the tip can only ever say a declared param is \"missing\" —\n * never suggest a misspelling correction.\n */\n readonly params: readonly string[];\n /** One-line description of what this action does / requires. */\n readonly description: string;\n}\n\n/**\n * Structured wrong-call backpressure (§4) — the handler-layer's answer for a\n * call that passed the registered layer's action-enum + type checks but\n * violates the per-action discriminated shape. Never raw zod text.\n */\nexport function backpressureResult(\n toolName: string,\n action: string,\n spec: ActionParamSpec,\n detail: string,\n): ToolResult {\n const paramList = spec.params.length > 0 ? spec.params.join(\", \") : \"(no params)\";\n const tip = `action '${action}' needs: ${paramList}. ${spec.description}`;\n const message = `${toolName} action='${action}': ${detail}`;\n return {\n content: textContent(message),\n structuredContent: {\n ...validationError(message),\n _meta: { tip, advisory: { action, expectedParams: spec.params, reason: detail } },\n },\n };\n}\n\n/**\n * Handler-layer dispatch (§3b): validates `flatData` (the already-registered-layer-\n * parsed args) against the internal discriminatedUnion, then routes to the\n * matching handler. A discriminatedUnion failure here is, by construction,\n * ALWAYS the \"valid action, wrong param combination\" case (the flat layer\n * already rejected unknown actions and wrong param types) — so it always\n * answers via `backpressureResult`, never raw zod text.\n */\nexport async function dispatchDiscriminated<\n Union extends ZodDiscriminatedUnion<\"action\", readonly [z.ZodObject<any>, ...z.ZodObject<any>[]]>,\n>(\n toolName: string,\n union: Union,\n flatData: Record<string, unknown>,\n actionSpecs: Record<string, ActionParamSpec>,\n handlers: Record<string, (data: any) => Promise<ToolResult>>,\n): Promise<ToolResult> {\n const action = String(flatData.action ?? \"\");\n const parsed = union.safeParse(flatData);\n if (!parsed.success) {\n const spec = actionSpecs[action];\n const detail = parsed.error.issues\n .map((i) => `${i.path.join(\".\") || action}: ${i.message}`)\n .join(\"; \");\n if (!spec) {\n // Should be unreachable — the registered flat layer already validated the\n // action enum — but fail closed rather than throw.\n return backpressureResult(toolName, action, { params: [], description: \"unknown action\" }, detail);\n }\n return backpressureResult(toolName, action, spec, detail);\n }\n const handler = handlers[action];\n if (!handler) {\n const spec = actionSpecs[action] ?? { params: [], description: \"unknown action\" };\n return backpressureResult(toolName, action, spec, `no handler registered for action '${action}'`);\n }\n return handler(parsed.data);\n}\n\n// ─── Batch validate-all-then-apply (§4, PAT-268 item 1) ───────────────────\n// Scaffolding for S2's `capture items[]` / `relations batch-create` — not\n// consumed by any S1 noun (entries has no batch-WRITE action), built now so\n// every noun that migrates a batch-write action reuses one implementation.\n\nexport interface BatchApplyResult<T> {\n ok: true;\n results: T[];\n}\n\nexport interface BatchValidationFailure {\n ok: false;\n errors: { index: number; message: string }[];\n}\n\n/**\n * Validates every item against `itemSchema` BEFORE applying any — a batch\n * either fully validates or nothing is written (PAT-268 item 1). `apply` runs\n * only after every item parses; failures short-circuit with per-index detail.\n */\nexport async function validateAllThenApply<Item, Out>(\n items: readonly unknown[],\n itemSchema: z.ZodType<Item>,\n apply: (validItems: Item[]) => Promise<Out[]>,\n): Promise<BatchApplyResult<Out> | BatchValidationFailure> {\n const errors: { index: number; message: string }[] = [];\n const validated: Item[] = [];\n items.forEach((item, index) => {\n const parsed = itemSchema.safeParse(item);\n if (!parsed.success) {\n errors.push({\n index,\n message: parsed.error.issues.map((i) => `${i.path.join(\".\")}: ${i.message}`).join(\"; \"),\n });\n } else {\n validated.push(parsed.data as Item);\n }\n });\n if (errors.length > 0) return { ok: false, errors };\n const results = await apply(validated);\n return { ok: true, results };\n}\n","import type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, getWorkspaceContext, requireWriteAccess, recordSessionActivity, getAgentSessionId } from \"../client.js\";\nimport { formatRubricCoaching } from \"./smart-capture.js\";\nimport { runConflictPreflight } from \"./conflict-preflight.js\";\nimport { trackQualityVerdict, trackQualityCheck, trackChainEntryCommitted, trackFieldQualityWarning, trackCommitErrorByCode } from \"../analytics.js\";\nimport { extractPreview, deriveEpistemicStatus, formatEpistemicLine, toEpistemicInput } from \"./knowledge-helpers.js\";\nimport { success, notFoundResult, successResult, type NextAction, type CaptureContract, type ToolResult } from \"../envelope.js\";\n// WP-465 surface parity (TEN-2458): extracted to coherency-refusal.ts to break the circular dep with smart-capture.ts.\nimport { coherencyRefusedResult, type CoherencyRefusalPayload } from \"./coherency-refusal.js\";\nexport { coherencyRefusedResult, type CoherencyRefusalPayload } from \"./coherency-refusal.js\";\n\n// WP-640 S2 (TASK-63): BET-68's legacy `status`→`workflowStatus` shim RETIRED EARLY, per\n// ASM-43 (zero external consumers) — not date-locked to its originally-promised ~2026-09-03\n// sunset. The WORKFLOW_STATUS_VALUES frozen literal, the WorkflowStatus type, and\n// LEGACY_WORKFLOW_STATUSES routing that used to live here are gone; `status` now accepts ONLY\n// the lifecycle enum, hard, with no auto-routing or deprecation warning. This is a distinct\n// workstream from the WP-640 era-collapse rename (TEN-3079) — coincidentally the frozen literal\n// used to carry a stray `'bet'` value in its \"Chains (bet type) lifecycle\" comment block, but that\n// was BET-68's OWN historical artifact, not this slice's canonicalKey era shim.\n\ntype LifecycleStatus = 'draft' | 'active' | 'deprecated' | 'archived';\n\nexport const updateEntrySchema = z.object({\n entryId: z.string().describe(\"Entry ID to update, e.g. 'T-SUPPLIER', '<PREFIX>-<n>'\"),\n name: z.string().optional().describe(\"New display name\"),\n // Chain-ID-leak guard (check:chain-id-leaks): the retired legacy-shim ticket number stays in\n // the code comment above, never in this user-visible describe() string.\n status: z.enum(['draft', 'active', 'deprecated', 'archived']).optional().describe(\"Lifecycle status: draft | active | deprecated | archived. Use `workflowStatus` for collection-specific workflow values — those are no longer accepted via `status`.\"),\n workflowStatus: z.string().optional().describe(\"Collection workflow state. Valid values are collection-specific and server-owned — discover them via `collections action=describe` for the target collection. The server rejects invalid values and returns the valid set in the error.\"),\n data: z.record(z.unknown()).optional().describe(\"Fields to update (merged with existing data)\"),\n order: z.number().optional().describe(\"New sort order\"),\n canonicalKey: z.string().optional().describe(\"Semantic type (e.g. 'decision', 'tension'). Only changeable on draft/uncommitted entries.\"),\n autoPublish: z.boolean().optional().default(false).describe(\"Only true when user explicitly asks to publish. Default false = draft. Never auto-publish without user confirmation.\"),\n changeNote: z.string().optional().describe(\"Strongly recommended: short human-readable rationale for WHY this change was made (e.g. 'Aligned description with F1-themed copy'). Surfaces in activity feed and pb get. If omitted, falls back to session purpose or auto-generated field summary.\"),\n sourceRef: z.string().optional().describe(\"URI or path of the source document backing this entry. Write-once: can only be set if currently empty.\"),\n sourceExcerpt: z.string().optional().describe(\"Verbatim excerpt from the source that backs this entry's claims. Write-once: can only be set if currently empty.\"),\n // WP-465 slice ⑤ — relay-only (TEN-2233): validation/min-length/recording live in Convex.\n steeringOverrideReason: z.string().optional().describe(\"Typed override (≥12 chars) that clears a steering coherency block on a misaligned governance write — always recorded with author attribution.\"),\n coherencyAcknowledgement: z.object({\n response: z.enum(['linked', 'accepted-fix', 'diverged']).describe(\"Explicit response to an acknowledge-required coherency challenge.\"),\n entryId: z.string().optional().describe(\"Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix').\"),\n reason: z.string().optional().describe(\"Divergence rationale (required for 'diverged', ≥12 chars).\"),\n }).optional().describe(\"Explicit response to a coherency challenge (standard/strict workspace modes). One acknowledgement per challenge per entry per session.\"),\n});\n\n\n// getHistorySchema/handleGetHistory moved to ./knowledge/getHistory.ts (STD-2/DEC-1504\n// shrink-only offset, WP-582 B1) — re-exported here so existing importers of \"./knowledge.js\"\n// are unaffected.\nexport { getHistorySchema, handleGetHistory } from \"./knowledge/getHistory.js\";\n\nexport const commitEntrySchema = z.object({\n entryId: z.string().describe(\"Entry ID to accept, e.g. 'TEN-abc123', '<PREFIX>-<n>'\"),\n // WP-316 S3: Preview gate — dry-run mode. Returns would-succeed result, no DB writes.\n preview: z.boolean().optional().describe(\"If true, validates the accept without writing. Returns what would happen. Default false.\"),\n // WP-465 slice ⑤ — relay-only (TEN-2233): validation/recording live in Convex.\n steeringOverrideReason: z.string().optional().describe(\"Typed override (≥12 chars) that clears a steering coherency block at the publish chokepoint — always recorded with author attribution.\"),\n coherencyAcknowledgement: z.object({\n response: z.enum(['linked', 'accepted-fix', 'diverged']).describe(\"Explicit response to an acknowledge-required coherency challenge.\"),\n entryId: z.string().optional().describe(\"Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix').\"),\n reason: z.string().optional().describe(\"Divergence rationale (required for 'diverged', ≥12 chars).\"),\n }).optional().describe(\"Explicit response to a coherency challenge (standard/strict workspace modes).\"),\n});\n\n/**\n * WP-484 S1 (§3/§4 entries-family migration): update-entry's handler body,\n * extracted so BOTH the legacy `update-entry` tool AND the new\n * `entries action=\"update\"` variant call the SAME implementation — one\n * business-logic path. WP-484 S3 (clean break, TEN-2157): the standalone\n * `update-entry` tool retired — `entries` (action=update) is the only\n * remaining caller, so `toolName` is always \"entries\" now. The parameter\n * stays (rather than hardcoding the literal inline) so a future caller with\n * a different self-reference doesn't have to plumb a new argument through.\n */\nexport async function handleUpdateEntry(\n { entryId, name, status: rawStatus, workflowStatus: rawWorkflowStatus, data, order, canonicalKey, autoPublish, changeNote, sourceRef, sourceExcerpt, steeringOverrideReason, coherencyAcknowledgement }: z.infer<typeof updateEntrySchema>,\n toolName: \"entries\" = \"entries\",\n): Promise<ToolResult> {\n requireWriteAccess();\n\n const fieldsProvided: string[] = [];\n if (name !== undefined) fieldsProvided.push('name');\n if (rawStatus !== undefined) fieldsProvided.push('status');\n if (rawWorkflowStatus !== undefined) fieldsProvided.push('workflowStatus');\n if (data !== undefined) fieldsProvided.push('data');\n if (order !== undefined) fieldsProvided.push('order');\n if (canonicalKey !== undefined) fieldsProvided.push('canonicalKey');\n\n // WP-640 S2 (TASK-63): BET-68's legacy status→workflowStatus auto-routing (and its\n // deprecation-warning response line, below) retired — `status` is validated hard by the\n // schema above to the lifecycle enum, so no runtime routing/coercion is needed here.\n const status: LifecycleStatus | undefined = rawStatus;\n const workflowStatus: string | undefined = rawWorkflowStatus;\n\n // BET-192 / FEAT-575: chain.updateEntry now returns warnings + normalization breakdown\n const updateResult = await kernelMutation<GatewayRouteReturnByName<\"chain.updateEntry\">>(\"chain.updateEntry\", {\n entryId,\n name,\n status,\n workflowStatus,\n data,\n order,\n canonicalKey,\n autoPublish,\n changeNote,\n changedBy: getAgentSessionId() ? `agent:${getAgentSessionId()}` : undefined,\n ...(sourceRef ? { sourceRef } : {}),\n ...(sourceExcerpt ? { sourceExcerpt } : {}),\n ...(steeringOverrideReason ? { steeringOverrideReason } : {}),\n ...(coherencyAcknowledgement ? { coherencyAcknowledgement } : {}),\n });\n\n // WP-465 slice ⑤ (Option B): a refused write RETURNS the structured payload —\n // render it as a failure with the routes; never as a silent success.\n const maybeRefused = updateResult as unknown as { outcome?: string; refusal?: CoherencyRefusalPayload };\n if (maybeRefused.outcome === 'refused' && maybeRefused.refusal) {\n return coherencyRefusedResult(`${toolName} action=update`, entryId, maybeRefused.refusal);\n }\n\n const id = updateResult.id;\n await recordSessionActivity({ entryModified: id });\n\n const wsCtx = await getWorkspaceContext();\n const updated = await kernelQuery<any>(\"chain.getEntry\", { entryId });\n const entryStatus: LifecycleStatus = (updated?.status ?? 'draft') as LifecycleStatus;\n const versionMode = entryStatus === 'active' ? 'published' : `saved as ${entryStatus}`;\n const responseLines = [\n `# Entry Updated`,\n ``,\n `**${entryId}** — ${versionMode}.`,\n ``,\n `Internal ID: ${id}`,\n `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`,\n ];\n\n if (fieldsProvided.length > 0) {\n responseLines.push(`**Fields provided:** ${fieldsProvided.join(', ')}`);\n } else {\n responseLines.push('');\n responseLines.push('⚠️ No fields to update were provided — only `entryId` was set.');\n }\n\n // BET-192 / FEAT-575: Surface normalization warnings (fields silently dropped by normalizeEntryData)\n if ((updateResult.normalizationWarnings ?? []).length > 0) {\n responseLines.push('');\n responseLines.push('⚠️ **Normalization warnings:**');\n for (const warning of updateResult.normalizationWarnings ?? []) {\n responseLines.push(` - ${warning}`);\n }\n }\n\n // BET-192 / FEAT-575: Surface validation warnings (missing required fields, etc.)\n if ((updateResult.validationWarnings ?? []).length > 0) {\n responseLines.push('');\n responseLines.push('⚠️ **Validation warnings:**');\n for (const warning of updateResult.validationWarnings ?? []) {\n responseLines.push(` - ${warning}`);\n }\n }\n\n const summary = `Updated ${entryId} — ${versionMode}. Fields: ${fieldsProvided.join(', ') || 'none'}.`;\n const next: NextAction[] = [\n { tool: toolName, description: \"View updated entry\", parameters: { action: \"get\", entryId } },\n { tool: toolName, description: \"Accept onto Chain\", parameters: { action: \"commit\", entryId } },\n ];\n\n return {\n content: [{ type: \"text\" as const, text: responseLines.join(\"\\n\") }],\n structuredContent: success(summary, {\n entryId: id,\n versionMode,\n fieldsProvided,\n // BET-192: normalization breakdown in structuredContent — symmetric with capture tool\n ...(updateResult.normalization && (Object.keys(updateResult.normalization.remapped).length > 0 || updateResult.normalization.rejected.length > 0) && {\n normalization: {\n remapped: updateResult.normalization.remapped,\n rejected: updateResult.normalization.rejected,\n },\n }),\n ...((updateResult.normalizationWarnings ?? []).length > 0 && {\n normalizationWarnings: updateResult.normalizationWarnings,\n }),\n ...((updateResult.validationWarnings ?? []).length > 0 && {\n validationWarnings: updateResult.validationWarnings,\n }),\n }, next),\n };\n}\n\n/**\n * WP-484 S1/S3: commit-entry's handler body. WP-484 S3 (clean break,\n * TEN-2157): the standalone `commit-entry` tool retired — `entries`\n * (action=commit) is the only remaining caller, same `toolName` convention\n * as `handleUpdateEntry`.\n */\nexport async function handleCommitEntry(\n { entryId, preview, steeringOverrideReason, coherencyAcknowledgement }: z.infer<typeof commitEntrySchema>,\n toolName: \"entries\" = \"entries\",\n): Promise<ToolResult> {\n requireWriteAccess();\n\n const entry = await kernelQuery<any>(\"chain.getEntry\", { entryId });\n if (!entry) {\n return notFoundResult(entryId, `Entry '${entryId}' not found. Try search to find the right ID.`);\n }\n\n const descField = entry.data?.description ?? entry.data?.canonical ?? entry.data?.rationale ?? \"\";\n const preflight = await runConflictPreflight(\n entry.name,\n descField,\n entry.collectionSlug ?? entry.collection?.slug ?? entry.collection?.name,\n );\n // WP-485 Slice 2b (R2, FEAT-1370): every discovered conflict is now shown as visible\n // advisory text — no local \"blocking\" filter. The old branch below this comment used to\n // hard-block on `preflight.blockingContradictions.length > 0` via a client-side\n // BLOCKING_CONTRADICTION_THRESHOLD comparison (deleted from conflict-preflight.ts); that\n // enforcement decision now happens ONE place, server-side, inside commitEntry's gate\n // (Slice 2a) — this tool no longer decides, it only discovers and displays.\n const advisoryWarnings = preflight.source === \"semantic\"\n ? preflight.conflicts.map((conflict) => ({\n kind: \"semantic\" as const,\n entryId: conflict.chainEntryId,\n name: conflict.chainEntryName,\n explanation: conflict.explanation,\n }))\n : preflight.advisoryWarnings.map((warning) => ({\n kind: \"heuristic\" as const,\n entryId: warning.entryId,\n name: warning.name,\n collection: warning.collection,\n governsCount: warning.governsCount,\n }));\n\n if (advisoryWarnings.length > 0) {\n await recordSessionActivity({ contradictionWarning: true });\n }\n\n // WP-485 Slice 2b round 2 (Codex P1, FEAT-1370): forward the discovered semantic\n // conflicts to commitEntry as evidence — `resolveContradictionVerdict` reads ONLY\n // caller-fed conflicts (mutations can't call the LLM-backed detector themselves), so\n // without this the server gate always evaluates an empty set on this path, no matter\n // how genuine the discovered contradiction is. Heuristic-source `advisoryWarnings` are a\n // different shape (`ContradictionWarning`, not `SemanticConflictArg`) and are never\n // forwarded. Whitelist only the validator-accepted fields — `chain.detectSemanticConflicts`\n // also returns an internal `chainEntryDocId` that fails commitEntry's `conflicts` arg\n // validator (live-proof finding, Slice 2b round 1).\n const conflictEvidence = preflight.source === \"semantic\"\n ? preflight.conflicts.map((c) => ({\n chainEntryId: c.chainEntryId,\n chainEntryName: c.chainEntryName,\n ...(c.chainEntryDescription ? { chainEntryDescription: c.chainEntryDescription } : {}),\n type: c.type,\n confidence: c.confidence,\n explanation: c.explanation,\n }))\n : [];\n\n let coachingResult: any = null;\n // A REAL commit re-evaluates here so the gate (inside chain.commitEntry) reads a\n // fresh verdict for the current content — otherwise a stale passing row lets the\n // commit through on content that changed.\n //\n // Codex P1 (PR #291): a PREVIEW must NOT run this — it used to insert a throwaway\n // verdict row (so the preview probe would read a fresh judgment), but that row\n // polluted usage stats and became the entry's latest verdict, leaving it\n // un-promotable after a mere dry run. The preview now gets parity a different way:\n // chain.commitEntry's dry-run path computes the same verdict in memory and classifies\n // it (buildCommitPreviewVerdictRow → simulatedVerdictRow), writing nothing. So skip\n // the re-evaluate entirely on preview.\n if (!preview) {\n try {\n coachingResult = await kernelMutation<GatewayRouteReturnByName<\"quality.evaluateHeuristicAndSchedule\">>(\"quality.evaluateHeuristicAndSchedule\", {\n entryId,\n context: \"commit\",\n });\n } catch {\n // Quality coaching is advisory\n }\n }\n\n let result: any;\n try {\n result = await kernelMutation<GatewayRouteReturnByName<\"chain.commitEntry\">>(\"chain.commitEntry\", {\n entryId,\n author: getAgentSessionId() ? `agent:${getAgentSessionId()}` : undefined,\n sessionId: getAgentSessionId() ?? undefined,\n ...(preview ? { preview: true } : {}),\n ...(steeringOverrideReason ? { steeringOverrideReason } : {}),\n ...(coherencyAcknowledgement ? { coherencyAcknowledgement } : {}),\n ...(conflictEvidence.length > 0 ? { conflicts: conflictEvidence } : {}),\n });\n } catch (commitErr: unknown) {\n // WP-316 S1a: Fire PostHog event on structured validation failure before re-throwing.\n // The thinWrapper HOF will catch and format the error into diagnostics.\n const errCode = (commitErr as { code?: string })?.code;\n if (errCode === \"VALIDATION_FAILED\") {\n try {\n const wsCtx = await getWorkspaceContext();\n const e = commitErr as { missingRequiredFields?: string[]; fieldErrors?: string[] };\n trackCommitErrorByCode(wsCtx.workspaceId, {\n error_code: errCode,\n missing_field_count: e.missingRequiredFields?.length ?? 0,\n field_error_count: e.fieldErrors?.length ?? 0,\n entry_id: entryId,\n });\n } catch { /* tracking must not break commit error path */ }\n }\n throw commitErr;\n }\n\n // WP-465 slice ⑤ (Option B): a refused accept RETURNS the structured payload —\n // render it as a failure with the routes; never as a silent success.\n if (result?.status === 'coherency_refused' && result?.refusal) {\n return coherencyRefusedResult(`${toolName} action=commit`, entryId, result.refusal as CoherencyRefusalPayload);\n }\n\n // WP-316 S3: Preview gate — return dry-run result without recording activity.\n if (result?.preview) {\n const wouldBlock = result.wouldBlock === true;\n // WP-485 Slice 2b round 3 (Codex P1, FEAT-1370): commitEntry's preview path attaches\n // `contradictionAdvisory` for parity with a real commit (Slice 2a) — this early return\n // sits BEFORE the contradictionAdvisory rendering further down, so preview silently\n // dropped it. Mirror it here so `preview:true` and a real commit report the same\n // advisory for identical `conflicts` evidence.\n const previewContradictionAdvisory = result?.contradictionAdvisory as\n | { reason: string; blockingCount: number; conflictDetails: Array<{ chainEntryId: string; chainEntryName: string; explanation: string }> }\n | undefined;\n const previewEnvelope = success(\n `Preview: ${wouldBlock ? \"would BLOCK accept\" : \"would accept\"} ${entryId} — no DB writes`,\n {\n entryId,\n name: entry.name,\n outcome: wouldBlock ? (\"blocked\" as const) : (\"preview\" as const),\n currentStatus: result.currentStatus,\n wouldSetStatus: result.wouldSetStatus,\n wouldBlock,\n ...(wouldBlock && result.blockingReason ? { blockingReason: result.blockingReason } : {}),\n ...(previewContradictionAdvisory ? { contradictionAdvisory: previewContradictionAdvisory } : {}),\n },\n [{ tool: toolName, description: \"Accept for real\", parameters: { action: \"commit\", entryId } }],\n );\n if (result.contract) {\n previewEnvelope.contract = result.contract;\n }\n const blockingNote = wouldBlock && result.blockingReason\n ? `\\n\\n**Would be blocked:** ${result.blockingReason}`\n : wouldBlock\n ? `\\n\\n**Would be blocked** by the coherency/grounding gate.`\n : \"\";\n const advisoryNote = previewContradictionAdvisory\n ? `\\n\\n⚠ Contradiction advisory (would be attached on real commit): ${previewContradictionAdvisory.reason}\\n${previewContradictionAdvisory.conflictDetails.map((c) => `- \\`${c.chainEntryId}\\` ${c.chainEntryName}: ${c.explanation}`).join(\"\\n\")}`\n : \"\";\n return {\n content: [{ type: \"text\" as const, text: `# Preview: would ${wouldBlock ? \"BLOCK accept\" : \"accept\"} ${entryId}\\n\\nCurrent status: \\`${result.currentStatus}\\` → would become \\`${result.wouldSetStatus}\\`.${blockingNote}${advisoryNote}\\n\\nNo DB writes — call without \\`preview:true\\` to accept for real.` }],\n structuredContent: previewEnvelope,\n };\n }\n\n const docId = result?._id ?? entry._id;\n const wsCtx = await getWorkspaceContext();\n const isProposal = result?.status === \"proposal_created\";\n if (!isProposal) {\n await recordSessionActivity({ entryModified: docId });\n const coll =\n (entry.collectionSlug as string | undefined) ??\n (entry.collection?.slug as string | undefined);\n trackChainEntryCommitted(wsCtx.workspaceId, {\n entry_id: entry.entryId ?? entryId,\n collection: coll,\n commit_method: \"manual\",\n surface: \"mcp_commit_tool\",\n });\n }\n let lines: string[];\n\n if (isProposal) {\n lines = [\n `# Proposal created: ${result.entryId ?? entryId}`,\n `**${result.name ?? entry.name}** — accepting requires consent. A proposal was created instead of accepting directly.`,\n `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`,\n \"\",\n result.existing\n ? \"An open proposal for this entry already exists.\"\n : \"Affected owners will be notified. The entry will be accepted when the consent window expires with no objections, or when all owners approve.\",\n ];\n } else {\n lines = [\n `# Accepted: ${entryId}`,\n `**${entry.name}** promoted to SSOT on the Chain.`,\n `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`,\n ];\n // WP-B (attestation spec §4.3): THE RECEIPT SAYS SO — the server attested this\n // entry as part of the promote (promote-gate context). Rendered, never re-derived.\n const autoVerified = result?.autoVerified as { strength?: string; verifiedBy?: string } | undefined;\n if (autoVerified?.strength) {\n const who = autoVerified.verifiedBy ? ` (${autoVerified.verifiedBy})` : \"\";\n lines.push(\"\");\n lines.push(`_Auto-verified as part of promote — ${autoVerified.strength}${who}._`);\n }\n }\n\n if (advisoryWarnings.length > 0) {\n lines.push(\"\");\n lines.push(preflight.source === \"semantic\"\n ? \"⚠ Semantic conflict preflight: advisory conflict(s) found.\"\n : \"⚠ Contradiction check: proposed entry matched existing governance entries:\");\n for (const w of advisoryWarnings) {\n lines.push(w.kind === \"semantic\"\n ? `- ${w.name} (${w.entryId}) — ${w.explanation}`\n : `- ${w.name} (${w.collection}, ${w.entryId}) — has 'governs' relation to ${w.governsCount} entries`);\n }\n // WP-485 Slice 2b round 4 (Codex P2, FEAT-1370): this block renders AFTER the entry\n // has already been accepted (R2 deleted the client-side block that used to make\n // \"before accepting\" true) — the recovery instruction must be a post-commit action,\n // not an impossible-to-follow \"before\" instruction for an accept that already happened.\n lines.push(preflight.source === \"semantic\"\n ? \"Run context action=gather on the conflicting entries to review; use entries action=update to reconcile the two, or to mark this entry status='deprecated' if it's actually superseded.\"\n : \"Run context action=gather on these entries to review; use entries action=update to reconcile the two, or to mark this entry status='deprecated' if it's actually superseded.\");\n }\n\n if (coachingResult?.verdict) {\n try {\n const v = coachingResult.verdict;\n const failedCount = (v.criteria ?? []).filter((c: any) => !c.passed).length;\n trackQualityVerdict(wsCtx.workspaceId, {\n entry_id: entryId,\n entry_type: v.canonicalKey ?? entry.canonicalKey ?? \"\",\n tier: v.tier,\n context: \"commit\",\n passed: v.passed,\n source: coachingResult.source ?? \"heuristic\",\n criteria_total: v.criteria?.length ?? 0,\n criteria_failed: failedCount,\n llm_scheduled: v.tier !== \"passive\",\n methodology_version: v.methodologyVersion,\n });\n } catch { /* tracking is advisory */ }\n }\n\n if (coachingResult?.verdict && coachingResult.verdict.tier !== \"passive\" && coachingResult.verdict.criteria.length > 0) {\n const coaching = formatRubricCoaching(coachingResult);\n if (coaching) {\n lines.push(\"\");\n lines.push(coaching);\n if (!coachingResult.verdict.passed && coachingResult.verdict.tier === \"assertive\") {\n lines.push(\"\");\n lines.push(\"_This entry was accepted despite quality concerns. The override has been recorded._\");\n }\n }\n }\n\n // BET-289 S5: Surface advisory guidance warnings from commit result + track\n const guidanceWarnings = result?.guidanceWarnings as Array<{ field: string; message: string; warningType: string }> | undefined;\n if (guidanceWarnings && guidanceWarnings.length > 0) {\n lines.push(\"\");\n lines.push(\"## Field Guidance Warnings (advisory)\");\n for (const w of guidanceWarnings) {\n lines.push(`- **${w.field}:** ${w.message}`);\n }\n lines.push(`_These are advisory — the entry was accepted. Use \\`entries action=update entryId=\"${entryId}\"\\` to address them._`);\n\n const uniqueTypes = [...new Set(guidanceWarnings.map((w) => w.warningType))];\n trackFieldQualityWarning(wsCtx.workspaceId, {\n warning_count: guidanceWarnings.length,\n warning_types: uniqueTypes,\n });\n }\n\n // WP-465 slice ⑤ (Light-mode row-11): a non-blocking coherency advisory raised\n // when a misaligned governance draft is accepted. The accept proceeds; the\n // misalignment is surfaced alongside the other commit warnings, never enforced.\n const steeringAdvisory =\n typeof result?.steeringAdvisory === \"string\" && result.steeringAdvisory.trim()\n ? (result.steeringAdvisory as string)\n : undefined;\n if (steeringAdvisory) {\n lines.push(\"\");\n lines.push(`⚠ Coherency advisory (entry accepted): ${steeringAdvisory}`);\n }\n\n // WP-485 Slice 2b round 2 (Codex P1, FEAT-1370): the server's own contradiction\n // verdict (DEC-1321 — advisory only, never blocking), distinct from the broader\n // discovery list rendered above — this is the gate's authoritative high-confidence\n // read of the conflicts forwarded as evidence, not every candidate found.\n const contradictionAdvisory = result?.contradictionAdvisory as\n | { reason: string; blockingCount: number; conflictDetails: Array<{ chainEntryId: string; chainEntryName: string; explanation: string }> }\n | undefined;\n if (contradictionAdvisory) {\n lines.push(\"\");\n lines.push(`⚠ Contradiction advisory (entry committed): ${contradictionAdvisory.reason}`);\n for (const c of contradictionAdvisory.conflictDetails) {\n lines.push(`- \\`${c.chainEntryId}\\` ${c.chainEntryName}: ${c.explanation}`);\n }\n }\n\n // WP-582 B1 (FEAT-1403): direction-trace promote-time advisory (publishSeam accumulator).\n const publishAdvisories = Array.isArray(result?.publishAdvisories)\n ? (result.publishAdvisories as unknown[]).filter((a): a is string => typeof a === \"string\")\n : undefined;\n if (publishAdvisories && publishAdvisories.length > 0) {\n lines.push(\"\");\n lines.push(\"⚠ Direction advisory (entry committed):\");\n for (const advisory of publishAdvisories) {\n lines.push(`- ${advisory}`);\n }\n }\n\n // Epistemic advisory for insights without evidence (BR-85)\n const epistemic = deriveEpistemicStatus(toEpistemicInput(entry as Record<string, unknown>));\n\n if (epistemic && (epistemic.level === \"hypothesis\" || epistemic.level === \"untested\")) {\n lines.push(\"\");\n lines.push(`⚠ ${formatEpistemicLine(epistemic)}`);\n if (epistemic.action) {\n lines.push(` → ${epistemic.action}`);\n }\n }\n\n // WP-316 S1a: Fetch capture contract so agents know required fields after commit.\n // Advisory — failure must not block the commit response.\n let captureContract: CaptureContract | undefined;\n try {\n const collSlug =\n (entry.collectionSlug as string | undefined) ??\n (entry.collection?.slug as string | undefined);\n if (collSlug) {\n captureContract = await kernelQuery<GatewayRouteReturnByName<\"chain.getCaptureContract\">>(\n \"chain.getCaptureContract\",\n { collectionSlug: collSlug },\n ) ?? undefined;\n }\n } catch { /* contract fetch is advisory */ }\n\n // Context-sensitive next: proposal vs. direct commit have different follow-ups\n const next: NextAction[] = isProposal\n ? [\n { tool: \"entries\", description: \"View entry\", parameters: { action: \"get\", entryId } },\n ]\n : [\n { tool: \"relations\", description: \"Discover connections\", parameters: { action: \"suggest\", entryId } },\n { tool: \"entries\", description: \"View accepted entry\", parameters: { action: \"get\", entryId } },\n ];\n\n const summary = isProposal\n ? `Proposal created for ${entryId} (${entry.name}). Awaiting consent.`\n : `Accepted ${entryId} (${entry.name}) onto the Chain.`;\n\n const commitSuccessEnvelope = success(\n summary,\n {\n entryId,\n name: entry.name,\n outcome: isProposal ? \"proposal_created\" as const : \"committed\" as const,\n qualityVerdict: coachingResult?.verdict ?? undefined,\n source: coachingResult?.source ?? undefined,\n contradictions: advisoryWarnings.length,\n ...(epistemic ? { epistemicStatus: epistemic } : {}),\n ...(steeringAdvisory ? { steeringAdvisory } : {}),\n // WP-485 Slice 2b round 2 (Codex P1, FEAT-1370): mirror the server's contradiction\n // advisory into the structured payload so --json/agent consumers see it too.\n ...(contradictionAdvisory ? { contradictionAdvisory } : {}),\n // WP-582 B1 (FEAT-1403): mirror the direction-trace advisory into the structured payload.\n ...(publishAdvisories && publishAdvisories.length > 0 ? { publishAdvisories } : {}),\n // WP-B (attestation spec §4.3): mirror the auto-verify receipt into the\n // structured payload so --json/agent consumers see it too.\n ...(result?.autoVerified ? { autoVerified: result.autoVerified } : {}),\n },\n next,\n );\n // WP-316 S1a: Attach capture contract so agents know required fields for next capture.\n if (captureContract) {\n commitSuccessEnvelope.contract = captureContract;\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: commitSuccessEnvelope,\n };\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `update-entry` /\n// `get-history` / `commit-entry` tool registrations retired here.\n// handleUpdateEntry / handleGetHistory / handleCommitEntry stay live —\n// entries.ts (the `entries` compound) is their only remaining caller.\n\n","/**\n * Smart capture — ARCH-node-mcp (Core layer)\n * Chain: FEAT-MCP-001 (MCP Server), ARCH-flow-smart-capture\n * Rules: SOS-016 (governed draft-first), SOS-015 (unique IDs within scope)\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, kernelCall, getWorkspaceContext, refreshWorkspaceGovernanceMode, requireWriteAccess, recordSessionActivity, getAgentSessionId, cacheScope, runWithToolContext } from \"../client.js\";\nimport { isGatewayTimeout, buildCaptureOutcomeUnknownResult } from \"../lib/captureTimeoutOutcome.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { ScopedCache, COLLECTION_CACHE_TTL_MS } from \"../lib/scopedCache.js\";\nimport {\n trackCaptureClassifierAutoRouted,\n trackCaptureClassifierEvaluated,\n trackCaptureClassifierFallback,\n trackCaptureQualityHints,\n trackCaptureRelationSuggestions,\n trackQualityVerdict,\n trackChainEntryCommitted,\n trackCollectionClassified,\n trackFieldGuidanceApplied,\n trackClassifierDivergence,\n type ClassifierReasonCategory,\n} from \"../analytics.js\";\nimport { extractPreview } from \"./knowledge-helpers.js\";\n// WP-465 surface parity (TEN-2458): import from coherency-refusal.ts (not knowledge.ts) to avoid circular dep.\nimport { coherencyRefusedResult } from \"./coherency-refusal.js\";\nimport { resolveGapsForEntry } from \"../gap-store.js\";\nimport {\n CLASSIFIABLE_COLLECTIONS,\n type ClassifiableCollectionSlug,\n} from \"./smart-capture-routing.js\";\nimport { resolveCollection, type ResolvedCollection } from \"../lib/resolveCollection.js\";\nimport { thinWrapper, success, failure, parseOrFail, type NextAction, type EnvelopeError, type CaptureContract, type ToolResult } from \"../envelope.js\";\nimport { FIELD_TYPE_DEFAULTS, type FieldType } from \"../lib/fieldTypes.js\";\nimport { formatFieldGuidance } from \"../lib/formatFieldGuidance.js\";\nimport { inferSourceDate } from \"../lib/inferSourceDate.js\";\nimport {\n getCollections,\n getCollectionBySlug,\n isGoverned,\n isHubCollection,\n type CollectionDoc,\n} from \"../lib/collectionCache.js\";\nimport { STOP_WORDS, tokenizeText } from \"../lib/textMatch.js\";\nimport { buildBatchPreviewFromResults, buildBatchEntryFailure, describeBatchEntryOutcome, splitBatchNotOk, unknownOutcomeSummaryNote, renderOutcomeUnknownSection, type BatchTimeoutOutcome } from \"../lib/batchCaptureOutput.js\"; // WP-575 review (P1, TEN-1126) — outcome-unknown cohort re-exported from lib/batchTimeoutCohort.ts.\nimport { isPreviewCreateEntryResult, extractPreviewWouldBlock, resolveEffectiveCollection } from \"../lib/createEntryPreviewResult.js\";\nimport { isEmptyValue, isNonEmptyValue, canonicalizeSelects } from \"../lib/entryDataNormalization.js\";\nimport { applyBatchInlineRelations } from \"../lib/batchInlineRelations.js\";\nimport { buildCaptureForRealNextAction } from \"../lib/captureForRealAction.js\";\nimport { verdictQualityPhrase, formatRubricCoaching, formatRubricVerdictSection } from \"../lib/rubricFormatting.js\";\nimport { captureSinglePreviewOutputSchema } from \"../lib/captureSinglePreviewOutput.js\";\nimport { createBatchPreviewDuplicateTracker, checkBatchPreviewDuplicate, reconcileBatchPreviewDuplicate } from \"../lib/batchPreviewDuplicates.js\";\n\nexport {\n CLASSIFIER_AUTO_ROUTE_THRESHOLD,\n CLASSIFIABLE_COLLECTIONS,\n isClassificationAmbiguous,\n type ClassifiableCollectionSlug,\n type ClassificationResult,\n} from \"./smart-capture-routing.js\";\n\n// ── Collection Workflow Profiles ────────────────────────────────────────────\n\ninterface FieldDefault {\n key: string;\n value: unknown | \"today\" | \"infer\";\n}\n\ninterface CollectionProfile {\n governedDraft: boolean;\n defaults: FieldDefault[];\n descriptionField: string;\n recommendedRelationTypes: string[];\n inferField?: (ctx: CaptureContext) => Record<string, unknown>;\n}\n\ninterface CaptureContext {\n collection: string;\n name: string;\n description: string;\n context?: string;\n data: Record<string, unknown>;\n entryId: string;\n canonicalKey?: string;\n linksCreated: LinkResult[];\n linksSuggested: LinkSuggestion[];\n collectionFields: Array<{ key: string; type: string; required?: boolean; options?: string[]; label?: string; writingGuidance?: string; writingExamples?: string[]; minLength?: number; maxLength?: number }>;\n}\n\ninterface LinkResult {\n targetEntryId: string;\n targetName: string;\n targetCollection: string;\n relationType: string;\n linkReason?: string;\n}\n\ninterface LinkSuggestion {\n entryId?: string;\n name: string;\n collection: string;\n reason: string;\n preview: string;\n}\n\n// normalizeMatchText/tokenizeMatchText/scoreOptionMatch/inferFieldOption were dead\n// private helpers with zero callers anywhere in this file — deleted (STD-2 / DEC-1504\n// module-health cleanup), not moved.\n\n// ── Strategy Category Inference (FEAT-128) ──────────────────────────────────\n// WP-488 Slice 4 (FEAT-1378, TEN-2733): moved to kernel/strategy/inferCategory.ts,\n// served over the gateway as `chain.classifyStrategyCategory` — no connector-local\n// copy. This function had zero production callers in this file at the time of the\n// move (re-grounded finding, not assumed from the WP-D spec's original pointers); see\n// kernel/strategy/inferCategory.ts's header and the PR body for the full note. A\n// future caller reaches the verdict via\n// `kernelQuery<GatewayRouteReturnByName<'chain.classifyStrategyCategory'>>\n// ('chain.classifyStrategyCategory', { name, description })`.\n\n// ── Collection Profiles ─────────────────────────────────────────────────────\n// BR-183 / E4.2: Runtime profiles are derived from collection documents. The\n// generic fallback intentionally avoids slug-specific defaults, relation\n// policies, and inference because collection docs do not expose those sources.\n\nconst GENERIC_PROFILE: CollectionProfile = {\n governedDraft: false,\n descriptionField: \"description\",\n defaults: [],\n recommendedRelationTypes: [\"related_to\", \"references\"],\n};\n\n/**\n * E4.2: Build a runtime profile from collection metadata. Do not infer\n * relation policies, default values, or field-population policies from slug.\n *\n * WP-480 S1 (FEAT-1358): quality is judged ONCE, server-side (STD-101 / DEC-32\n * thin wrapper), so this profile carries no client scorecard — it keeps only\n * description-field resolution and relation defaults.\n */\nasync function buildRuntimeProfile(slug: string): Promise<CollectionProfile> {\n const col = await getCollectionBySlug(slug);\n if (!col) return GENERIC_PROFILE;\n\n const fields = col.fields ?? [];\n const layoutDescriptionField = fields.find(\n (field) => field.zone === \"body\" || field.displayHint === \"textarea\" || field.displayHint === \"section\",\n )?.key;\n const descriptionField = col.descriptionFieldKey || layoutDescriptionField || \"description\";\n\n return {\n governedDraft: col.governed === true,\n descriptionField,\n defaults: [],\n recommendedRelationTypes: GENERIC_PROFILE.recommendedRelationTypes,\n };\n}\n\n/**\n * Per-scope profile cache (keyed by collection slug within a scope).\n * Note: TTL is stamped when a scope's Map is first created; later map.set adds\n * entries without refreshing it, so all profiles in a scope expire ≤TTL after the\n * first one. Fail-safe toward freshness (can only expire sooner); staleness\n * ceiling stays COLLECTION_CACHE_TTL_MS.\n */\nconst profileCache = new ScopedCache<Map<string, CollectionProfile>>(COLLECTION_CACHE_TTL_MS);\n\n/**\n * Get a collection's profile for the current scope, cached with a short TTL.\n */\nexport async function getProfile(slug: string): Promise<CollectionProfile> {\n const scope = cacheScope();\n let map = profileCache.get(scope);\n if (!map) {\n map = new Map();\n profileCache.set(scope, map);\n }\n const cached = map.get(slug);\n if (cached) return cached;\n const profile = await buildRuntimeProfile(slug);\n map.set(slug, profile);\n return profile;\n}\n\n/** Reset all profile caches — test hook + full flush. */\nexport function resetProfileCache(): void {\n profileCache.clear();\n}\n\n/**\n * Drop the current scope's profile cache. Profiles derive their descriptionField and\n * quality criteria from collection fields, so a collection write in this scope must drop\n * them too — otherwise the next capture uses the pre-write profile until the TTL expires.\n */\nexport function invalidateProfileCacheForScope(): void {\n profileCache.delete(cacheScope());\n}\n\n// ── Auto-Linking Logic ──────────────────────────────────────────────────────\n\nfunction extractSearchTerms(name: string, description: string): string {\n const text = `${name} ${description}`;\n return text\n .replace(/[^\\w\\s]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 3)\n .slice(0, 8)\n .join(\" \");\n}\n\n/**\n * Positional result + jobs-request shape for `chain.scoreLinkCandidates` (Lane C S4).\n * Mirror the served route's request/response shape (convex/agentKnowledge/relations.ts).\n * Hand-declared here rather than imported from kernel/ (mcp-server cannot import kernel/\n * directly — no build edge, same reasoning as chain-classifier.ts's hand-declared\n * GovernanceFunction/GovernanceRelationEdge pre-S3a) and not (yet) re-exported from\n * @productbrain/kernel-client either — this route's types are net-new to that package's\n * surface, out of S4's scope (S3a's precedent is the addition path if a future slice\n * wants type-only re-export here instead of a hand-declared mirror).\n *\n * PR #392 round 1 (Copilot + Codex, confirmed): candidates carry ONLY {name,\n * collectionId} on the wire — `data`/`entryId` were never read by the scoring formula\n * and risked tripping convex/http.ts's validateArgLengths (10KB-per-string, recursive)\n * for a large entry payload, failing the whole scoring call. Callers keep their own full\n * candidate objects locally and re-associate via the positional `index` — nothing lost.\n *\n * PR #392 round 2 (Codex, confirmed): `collMap`/`hubSlugs` are HOISTED out of\n * `LinkScoreJob` — they're the SAME workspace-wide caches for every job in one capture\n * flow, so sending them per-job (round 1's shape) meant an N-job batch request repeated\n * the identical collMap/hubSlugs JSON N times. Now sent once, at the request's top\n * level (see `scoreEntryJobsChunk` below).\n */\ninterface LinkScoreResult {\n index: number;\n score: number;\n reason: string;\n}\n\n/** One unit of scoring work — see kernel/relations/scoreLinkCandidates.ts's LinkScoreJob.\n * `collMap`/`hubSlugs` are NOT here — hoisted to the request's top level (round 2). */\ninterface LinkScoreJob {\n candidates: Array<{ name: string; collectionId: string }>;\n sourceName: string;\n sourceDescription: string;\n sourceCollection: string;\n}\n\n// BET-281: hub slugs get higher link-confidence. Per-scope + TTL (TEN-2415).\nconst hubCache = new ScopedCache<Set<string>>(COLLECTION_CACHE_TTL_MS);\n\n/** Resolve (and cache) the current scope's hub-collection slug set. */\nexport async function populateHubCache(): Promise<Set<string>> {\n const scope = cacheScope();\n const hit = hubCache.get(scope);\n if (hit) return hit;\n const cols = await getCollections();\n const set = new Set(\n cols\n .filter((c) => c.governanceRole === \"steering\" || c.thinkingLayer === \"strategy\")\n .map((c) => c.slug),\n );\n hubCache.set(scope, set);\n return set;\n}\n\n/** Reset all hub caches — test hook + full flush. */\nexport function resetHubCache(): void {\n hubCache.clear();\n}\n\n/**\n * Drop the current scope's hub-slug set. The set derives from collection governanceRole /\n * thinkingLayer, so a collection write in this scope must drop it too — otherwise link\n * confidence keeps scoring against the pre-write hub set until the TTL expires.\n */\nexport function invalidateHubCacheForScope(): void {\n hubCache.delete(cacheScope());\n}\n\n/**\n * Lane C S4 (TEN-2733 pattern extension): builds ONE scoring job for the batched\n * served-kernel-verdict call that replaced this file's former local link-scoring\n * function (a connector-resident scorer with no kernel/convex counterpart — the same\n * architectural gap the classifier migrations already closed elsewhere). Deliberately\n * does NOT call `kernelQuery` itself — each call site below invokes the gateway route\n * directly (not through a shared wrapper) so the route-name string literal appears at\n * the real call site(s), never hidden behind a single shared indirection point (grep-\n * based doneWhen — see PR body). Candidates are trimmed to `{name, collectionId}` here\n * — see the `LinkScoreJob` doc comment above for why `data`/`entryId` never travel over\n * the wire. `collMap`/`hubSlugs` are NOT built here (round 2) — they're THIS connector's\n * own already-fetched/cached data, hoisted to the request's top level by each call site.\n */\nfunction buildScoreLinkCandidatesJob(\n candidates: ReadonlyArray<{ name: string; collectionId: string }>,\n sourceName: string,\n sourceDescription: string,\n sourceCollection: string,\n): LinkScoreJob {\n return {\n candidates: candidates.map((c) => ({ name: c.name, collectionId: c.collectionId })),\n sourceName,\n sourceDescription,\n sourceCollection,\n };\n}\n\n/**\n * PR #392 round 2 (Codex, confirmed): batch-capture's scoring jobs are processed in\n * CHUNKS, not one call for the WHOLE batch. Two independent bounds, whichever hits\n * first closes the current chunk:\n * - COUNT: at most this many entries' jobs per `chain.scoreLinkCandidates` call — keeps\n * a 50-entry batch at ≤5 scoring calls (was: 1 unbounded call before this fix, 50\n * calls before round 1's batching fix).\n * - BYTES: a conservative `JSON.stringify` length estimate of the accumulated chunk's\n * jobs, so a chunk of entries with unusually large candidate names/counts still stays\n * safely under Convex's ~1MB per-call argument ceiling (this margin, not the ceiling\n * itself — leaves room for the request's other fields and the wire envelope).\n * CHUNKING ALSO RESTORES WRITE INTERLEAVING: each chunk's relation writes (`finish`)\n * run to completion BEFORE the next chunk's entries even start their `createEntry` —\n * see the batch-capture loop below — so auto-links for early entries are never starved\n * behind dozens of queued creates in a large batch.\n */\nconst LINK_SCORE_CHUNK_MAX_ENTRIES = 10;\nconst LINK_SCORE_CHUNK_MAX_BYTES = 700_000;\n\n/** Conservative byte estimate for one scoring job — used only to decide chunk\n * boundaries (see LINK_SCORE_CHUNK_MAX_BYTES above), never sent anywhere itself.\n * `Buffer.byteLength(..., 'utf8')`, NOT `.length` (v2-review sweep, PR #392\n * unresolved thread, Codex, P2, posted twice/same finding): `.length` on a JS\n * string counts UTF-16 code units, undercounting multibyte (e.g. CJK) candidate\n * names relative to their real UTF-8 wire size — a chunk could exceed Convex's\n * sub-1MB argument ceiling despite passing this estimate, and the caught failure\n * silently dropped auto-links for the whole chunk. */\nfunction estimateJobBytes(job: LinkScoreJob): number {\n return Buffer.byteLength(JSON.stringify(job), \"utf8\");\n}\n\ninterface RelationTypeResult {\n type: string;\n reason: string;\n}\n\nfunction inferRelationType(\n _sourceCollection: string,\n _targetCollection: string,\n profile: CollectionProfile,\n): RelationTypeResult {\n const type = profile.recommendedRelationTypes[0] ?? \"related_to\";\n const reason = `profile default (${type})`;\n return { type, reason };\n}\n\n\n// ── Tool Registration ───────────────────────────────────────────────────────\n\n// BET-281: GOVERNED_COLLECTIONS replaced by runtime isGoverned() from collectionCache.\n// The `governed` field on each collection doc is the SSOT.\n\nconst AUTO_LINK_CONFIDENCE_THRESHOLD = 35;\nconst MAX_AUTO_LINKS = 5;\nconst MAX_SUGGESTIONS = 5;\n\n/** BR-111: entryId only for business-rules and standards; format BR-NNN or STD-NNN. All other collections use auto-generated IDs. */\nconst BR_STD_ENTRY_ID_REGEX = /^(BR|STD)-\\d+$/;\nconst entryIdSchema = z.string().regex(BR_STD_ENTRY_ID_REGEX).optional().describe(\"Only for business-rules and standards. Must match BR-NNN or STD-NNN. Omit for all other collections — IDs are auto-generated.\");\n\nexport const captureSchema = z.object({\n collection: z.string().optional().describe(\"Collection slug, e.g. 'tensions', 'business-rules', 'glossary', 'decisions'. Optional — classifier auto-routes when omitted.\"),\n name: z.string().describe(\"Display name — be specific (e.g. 'Convex adjacency list won't scale for graph traversal')\"),\n description: z.string().describe(\"Full context — what's happening, why it matters, what you observed\"),\n context: z.string().optional().describe(\"Optional additional context (e.g. 'Observed during context gather calls taking 700ms+')\"),\n entryId: entryIdSchema,\n canonicalKey: z.string().optional().describe(\"Semantic type (e.g. 'decision', 'tension', 'vision'). Auto-assigned from collection if omitted.\"),\n data: z.record(z.unknown()).optional().describe(\"Explicit field values when you know the schema (e.g. canonical_key, cardinality_rule, required_fields). Merged with inferred values; user-provided wins.\"),\n links: z.array(z.object({\n to: z.string().describe(\"Target entry ID (e.g. '<PREFIX>-<n>')\"),\n type: z.string().describe(\"Relation type (e.g. 'governs', 'related_to', 'informs')\"),\n })).optional().describe(\"Relations to create after capture. Skips auto-link discovery when provided.\"),\n autoCommit: z.boolean().optional().describe(\"If true, commits the entry immediately after capture + linking. If omitted, Open mode workspaces auto-commit by default and consensus/role modes stay draft-first.\"),\n sourceRef: z.string().optional().describe(\"URI or path of the source document backing this entry (e.g. 'meeting-2026-03-28.md', 'import://batch-5'). Stored as top-level entry field, not in data.\"),\n sourceExcerpt: z.string().optional().describe(\"Verbatim excerpt from the source that backs this entry's claims. Stored as top-level entry field, not in data.\"),\n // WP-316 S3: Preview gate — dry-run mode. Returns what would happen, no DB writes.\n preview: z.boolean().optional().describe(\"If true, validates the capture without writing. Returns what would happen. Default false.\"),\n // WP-318 S2: Pre-write grounding — run link suggestion before creating entry.\n suggestOnly: z.boolean().optional().describe(\"If true, runs pre-write grounding (suggestLinksForCapture) and returns a groundingReport WITHOUT creating any entry. Use to preview graph participation before accepting. Default false.\"),\n // WP-318 S2: Format for groundingReport in response.\n format: z.enum([\"agent\", \"human\"]).optional().describe(\"Response format for grounding data. 'agent' (default): full JSON groundingReport. 'human': compressed summary string appended to the capture summary.\"),\n // WP-513: team+role to create AS OWNER of (rung 2 only); no-op pre-rung-2.\n ownerTeamEntryId: z.string().max(200).optional().describe(\"Owning team entry ID/ref (rung 2).\"),\n ownerRoleEntryId: z.string().max(200).optional().describe(\"Owning role entry ID/ref (rung 2).\"),\n});\n\n// WP-484 S2 (§3/§7 TEN-957): inline per-item relations — each batch entry can\n// name relations to EXISTING Chain entries to create right after it is\n// captured, resolving TEN-957 (\"batch-capture lacks inline relations\").\n// Sibling-item (intra-batch) references are out of scope for this slice —\n// `to` must be an existing entryId already on the Chain.\nconst batchCaptureRelationSchema = z.object({\n to: z.string().max(200).describe(\"Target entry ID already on the Chain, e.g. '<PREFIX>-<n>'.\"),\n type: z.string().max(200).describe(\"Relation type, e.g. 'related_to', 'informed_by', 'governs'.\"),\n});\n\nexport const batchCaptureSchema = z.object({\n entries: z.array(z.object({\n // FEAT-160\n collection: z.string().max(200).optional().describe(\"Collection slug. Optional — auto-classified via LLM when omitted.\"),\n name: z.string().max(500).describe(\"Display name\"),\n description: z.string().max(20000).describe(\"Full context / definition\"),\n entryId: entryIdSchema,\n data: z.record(z.unknown()).optional().describe(\"Explicit field values (e.g. urgency, status, assignee). Merged with inferred values; user-provided wins.\"),\n canonicalKey: z.string().max(200).optional().describe(\"Semantic type (e.g. 'decision', 'tension', 'work_package'). Enables work-package redirect in createEntry when collection is 'chains'.\"),\n sourceRef: z.string().max(2000).optional().describe(\"URI or path of the source document backing this entry (e.g. 'meeting-2026-03-28.md', 'import://batch-5'). Stored as top-level entry field, not in data.\"),\n sourceExcerpt: z.string().max(5000).optional().describe(\"Verbatim excerpt from the source that backs this entry's claims. Stored as top-level entry field, not in data.\"),\n // TEN-957 (WP-484 S2): relations to create right after this entry is captured.\n relations: z.array(batchCaptureRelationSchema).max(10).optional().describe(\"Relations to create right after this entry is captured — each {to, type} links the NEW entry to an existing Chain entry.\"),\n // WP-513: team+role to create THIS entry AS OWNER of (rung 2 only).\n ownerTeamEntryId: z.string().max(200).optional().describe(\"Owning team entry ID/ref (rung 2).\"),\n ownerRoleEntryId: z.string().max(200).optional().describe(\"Owning role entry ID/ref (rung 2).\"),\n })).min(1).max(50).describe(\"Array of entries to capture\"),\n autoCommit: z\n .boolean()\n .optional()\n .describe(\n \"If true, commits created entries immediately after linking. \" +\n \"If omitted, Open mode workspaces commit by default and consensus/role modes stay draft-first.\"\n ),\n // WP-316 S3: Preview gate — dry-run mode. Returns what would happen, no DB writes.\n preview: z.boolean().optional().describe(\"If true, validates all captures without writing. Returns what would happen. Default false.\"),\n});\n\nexport const captureClassifierSchema = z.object({\n enabled: z.boolean(),\n autoRouted: z.boolean(),\n agrees: z.boolean(),\n abstained: z.boolean(),\n topConfidence: z.number(),\n confidence: z.number(),\n reasons: z.array(z.string()),\n candidates: z.array(\n z.object({\n collection: z.string(),\n signalScore: z.number().optional(),\n confidence: z.number(),\n /** WP-316 S2: required-field cost — how many fields the agent must supply for this collection. */\n requiredFieldCount: z.number().optional(),\n }),\n ),\n agentProvidedCollection: z.string().optional(),\n overrideCommand: z.string().optional(),\n classifiedBy: z.enum([\"llm\", \"heuristic\", \"explicit\"]).optional(),\n confidenceTier: z.enum([\"high\", \"medium\", \"low\"]).optional(),\n reasoning: z.string().optional(),\n});\n\nexport type CaptureClassifierMetadata = z.infer<typeof captureClassifierSchema>;\n\ntype CaptureToolResult = {\n content: Array<{ type: \"text\"; text: string }>;\n // Required (not optional) to mirror envelope.ts's ToolResult contract (DEC-1447): every\n // response this tool returns always sets structuredContent.\n structuredContent: z.infer<typeof captureOutputSchema> | EnvelopeError;\n};\n\ntype CollectionResolution = {\n resolvedCollection?: string;\n classifierMeta?: CaptureClassifierMetadata;\n earlyResult?: CaptureToolResult;\n};\n\nfunction trackClassifierTelemetry(params: {\n workspaceId: string;\n predictedCollection: string;\n confidence: number;\n autoRouted: boolean;\n reasonCategory: ClassifierReasonCategory;\n explicitCollectionProvided: boolean;\n outcome: \"auto-routed\" | \"fallback\";\n}): void {\n const telemetry = {\n predicted_collection: params.predictedCollection,\n confidence: params.confidence,\n auto_routed: params.autoRouted,\n reason_category: params.reasonCategory,\n explicit_collection_provided: params.explicitCollectionProvided,\n };\n\n trackCaptureClassifierEvaluated(params.workspaceId, telemetry);\n if (params.outcome === \"auto-routed\") {\n trackCaptureClassifierAutoRouted(params.workspaceId, telemetry);\n return;\n }\n trackCaptureClassifierFallback(params.workspaceId, telemetry);\n}\n\nfunction buildClassifierUnknownResult(): CaptureToolResult {\n return {\n content: [{\n type: \"text\" as const,\n text:\n \"I could not infer a collection confidently from this input.\\n\\n\" +\n \"Please provide `collection`, or rewrite with clearer intent (decision/problem/definition/insight/work-package).\",\n }],\n structuredContent: failure(\n \"VALIDATION_ERROR\",\n \"Could not infer collection from input.\",\n \"Provide collection explicitly, or rewrite with clearer intent.\",\n [{ tool: \"collections\", description: \"List available collections\", parameters: { action: \"list\" } }],\n { classifier: { enabled: true, autoRouted: false, agrees: false, abstained: true, topConfidence: 0, confidence: 0, reasons: [], candidates: [] } },\n ),\n };\n}\n\nfunction buildProvisionedCollectionSuggestions(\n candidates: Array<{ collection: string; signalScore?: number; confidence: number }>,\n): string {\n return candidates.length\n ? candidates\n .map((c) => `- \\`${c.collection}\\` (${c.signalScore ?? c.confidence}% confidence)`)\n .join(\"\\n\")\n : \"- No collection candidates were inferred confidently.\";\n}\n\nfunction buildLowConfidenceResult(\n resolved: ResolvedCollection,\n classifierMeta: CaptureClassifierMetadata,\n): CaptureToolResult {\n const allCandidates = [\n { collection: resolved.collection, confidence: resolved.confidence },\n ...resolved.alternatives,\n ];\n // WP-316 S2: enrich suggestions with requiredFieldCount from classifierMeta.candidates\n const candidateFieldCounts = new Map<string, number>();\n for (const c of classifierMeta.candidates) {\n if (c.requiredFieldCount !== undefined) {\n candidateFieldCounts.set(c.collection, c.requiredFieldCount);\n }\n }\n const suggestions = allCandidates\n .map((c) => {\n const fieldCost = candidateFieldCounts.get(c.collection);\n const fieldNote = fieldCost !== undefined ? `, ${fieldCost} required field${fieldCost === 1 ? \"\" : \"s\"}` : \"\";\n return `- \\`${c.collection}\\` (${c.confidence}% confidence${fieldNote})`;\n })\n .join(\"\\n\");\n const textBody =\n `Low confidence classification (${resolved.confidence}%, classified by ${resolved.classifiedBy}).\\n\\n` +\n `Predicted: \\`${resolved.collection}\\`\\n` +\n `Reason: ${resolved.reasoning || \"low signal\"}\\n\\n` +\n \"Choose one of these and retry with `collection`:\\n\" +\n `${suggestions}\\n\\n` +\n \"Correction path: rerun with your chosen `collection`, or capture and use `entries action=move` later.\";\n return {\n content: [{ type: \"text\" as const, text: textBody }],\n structuredContent: failure(\n \"VALIDATION_ERROR\",\n `Low confidence routing to '${resolved.collection}' (${resolved.confidence}%, ${resolved.classifiedBy}).`,\n \"Rerun with explicit collection.\",\n allCandidates.map((c) => ({\n tool: \"capture\",\n description: `Capture to ${c.collection}`,\n parameters: { collection: c.collection },\n })),\n { classifier: classifierMeta },\n ),\n };\n}\n\n\nfunction buildClassifierMeta(\n resolved: ResolvedCollection,\n overrides: Partial<CaptureClassifierMetadata> = {},\n): CaptureClassifierMetadata {\n return {\n enabled: true,\n autoRouted: false,\n agrees: true,\n abstained: false,\n topConfidence: resolved.confidence,\n confidence: resolved.confidence,\n reasons: resolved.reasoning ? [resolved.reasoning] : [],\n candidates: [\n { collection: resolved.collection, confidence: resolved.confidence },\n ...resolved.alternatives.map((a) => ({ collection: a.collection, confidence: a.confidence })),\n ].slice(0, 3),\n classifiedBy: resolved.classifiedBy,\n confidenceTier: resolved.tier,\n reasoning: resolved.reasoning,\n ...overrides,\n };\n}\n\n/**\n * WP-316 S3 gap fix: enrich classifier candidates with requiredFieldCount from collection schema.\n * This gives agents a cost signal when choosing between low-confidence candidates.\n * Advisory — never throws, falls back to unmodified candidates.\n */\nasync function enrichCandidatesWithFieldCounts(meta: CaptureClassifierMetadata): Promise<void> {\n try {\n const cols = await getCollections();\n const reqBySlug = new Map(\n cols.map((c) => [c.slug, (c.fields ?? []).filter((f: { required?: boolean }) => f.required === true).length]),\n );\n meta.candidates = meta.candidates.map((c) => ({\n ...c,\n requiredFieldCount: reqBySlug.get(c.collection) ?? 0,\n }));\n } catch {\n // enrichment is advisory; never fail capture for this\n }\n}\n\n/**\n * BET-288 S0: Fire confusion-matrix telemetry on every classification.\n * Called from every code path that produces a ResolvedCollection.\n */\nfunction emitClassificationTelemetry(\n resolved: ResolvedCollection,\n workspaceId: string,\n opts: { explicitCollectionProvided: boolean; autoRouted: boolean },\n): void {\n const topAlt = resolved.alternatives?.[0] ?? null;\n trackCollectionClassified(workspaceId, {\n collection_slug: resolved.collection,\n thinking_layer: resolved.thinkingLayer ?? null,\n confidence: resolved.confidence,\n classified_by: resolved.classifiedBy,\n confidence_tier: resolved.tier,\n alternative_slug: topAlt?.collection ?? null,\n alternative_confidence: topAlt?.confidence ?? null,\n explicit_collection_provided: opts.explicitCollectionProvided,\n auto_routed: opts.autoRouted,\n });\n}\n\nasync function resolveCaptureCollection(params: {\n collection?: string;\n name: string;\n description: string;\n workspaceId: string;\n explicitCollectionProvided: boolean;\n}): Promise<CollectionResolution> {\n const {\n collection,\n name,\n description,\n workspaceId,\n explicitCollectionProvided,\n } = params;\n\n if (collection) {\n const resolved = await resolveCollection({ name, description });\n if (resolved) {\n const agrees = resolved.collection === collection;\n const classifierMeta = buildClassifierMeta(resolved, {\n autoRouted: false,\n agrees,\n agentProvidedCollection: collection,\n ...(!agrees && {\n overrideCommand: `capture collection=\"${resolved.collection}\"`,\n }),\n });\n await enrichCandidatesWithFieldCounts(classifierMeta);\n // BET-288 S0: Fire confusion telemetry on every classification (explicit path)\n emitClassificationTelemetry(resolved, workspaceId, {\n explicitCollectionProvided: true,\n autoRouted: false,\n });\n if (!agrees) {\n trackClassifierTelemetry({\n workspaceId,\n predictedCollection: resolved.collection,\n confidence: resolved.confidence,\n autoRouted: false,\n reasonCategory: \"low-confidence\",\n explicitCollectionProvided: true,\n outcome: \"fallback\",\n });\n // WP-316 S2: track divergence — agent overrode classifier suggestion\n const agentInCandidates =\n resolved.alternatives.some((a) => a.collection === collection) ||\n resolved.collection === collection;\n trackClassifierDivergence(workspaceId, {\n classifier_collection: resolved.collection,\n agent_collection: collection,\n classifier_confidence: resolved.confidence,\n classifier_tier: resolved.tier,\n agent_in_candidates: agentInCandidates,\n });\n }\n return { resolvedCollection: collection, classifierMeta };\n }\n return {\n resolvedCollection: collection,\n classifierMeta: {\n enabled: true,\n autoRouted: false,\n agrees: false,\n abstained: true,\n topConfidence: 0,\n confidence: 0,\n reasons: [],\n candidates: [],\n agentProvidedCollection: collection,\n },\n };\n }\n\n const resolved = await resolveCollection({ name, description });\n if (!resolved) {\n trackClassifierTelemetry({\n workspaceId,\n predictedCollection: \"unknown\",\n confidence: 0,\n autoRouted: false,\n reasonCategory: \"low-confidence\",\n explicitCollectionProvided,\n outcome: \"fallback\",\n });\n return { earlyResult: buildClassifierUnknownResult() };\n }\n\n // FEAT-159: Tier-based routing replaces shouldAutoRouteClassification/isClassificationAmbiguous.\n // High+medium auto-route; low rejects and asks for explicit collection.\n const autoRoute = resolved.tier !== \"low\";\n const classifierMeta = buildClassifierMeta(resolved, { autoRouted: autoRoute });\n await enrichCandidatesWithFieldCounts(classifierMeta);\n\n // BET-288 S0: Fire confusion telemetry on every classification (classifier path)\n emitClassificationTelemetry(resolved, workspaceId, {\n explicitCollectionProvided,\n autoRouted: autoRoute,\n });\n\n if (!autoRoute) {\n trackClassifierTelemetry({\n workspaceId,\n predictedCollection: resolved.collection,\n confidence: resolved.confidence,\n autoRouted: false,\n reasonCategory: \"low-confidence\",\n explicitCollectionProvided,\n outcome: \"fallback\",\n });\n return {\n classifierMeta,\n earlyResult: buildLowConfidenceResult(resolved, classifierMeta),\n };\n }\n\n trackClassifierTelemetry({\n workspaceId,\n predictedCollection: resolved.collection,\n confidence: resolved.confidence,\n autoRouted: true,\n reasonCategory: \"auto-routed\",\n explicitCollectionProvided,\n outcome: \"auto-routed\",\n });\n\n return {\n resolvedCollection: resolved.collection,\n classifierMeta,\n };\n}\n\nconst captureSuccessOutputSchema = z.object({\n entryId: z.string(),\n collection: z.string(),\n name: z.string(),\n // \"draft_on_failure\" is the status emitted when an auto-commit is REFUSED/failed (the entry\n // stays a draft) — the same path that now also emits coherencyRefusal. The strict schema must\n // accept it or a refused response fails to validate on `status` (codex review, completing the\n // coherencyRefusal contract fix).\n status: z.enum([\"draft\", \"committed\", \"proposed\", \"draft_on_failure\"]),\n // WP-480 S1: `qualityScore` (required, client N/10) deleted — a named, accepted\n // breaking output-contract change. The server verdict stays as `qualityVerdict`.\n qualityVerdict: z.record(z.unknown()).optional(),\n classifier: captureClassifierSchema.optional(),\n studioUrl: z.string().optional(),\n warnings: z.array(z.string()).optional(),\n normalization: z.object({\n remapped: z.record(z.string()).optional(),\n rejected: z.array(z.string()).optional(),\n }).optional(),\n expectedFields: z.array(z.object({\n key: z.string(),\n type: z.string(),\n required: z.boolean().optional(),\n })).optional(),\n // TEN-2365: capture-time authority-domain proposal (PENDING ratification), when one was filed.\n authorityDomain: z.object({\n slug: z.string(),\n status: z.literal(\"proposal-pending\"),\n }).optional(),\n // WP-465 surface parity: structured coherency refusal when an auto-commit is gate-refused.\n // Loose record (matching the qualityVerdict convention above) — the CoherencyRefusal contract\n // is authored in convex/lib/gates/coherencyControls.ts; re-declaring its shape here would create\n // a second source of truth. Required because the schema is `.strict()` (an undeclared key throws).\n coherencyRefusal: z.record(z.unknown()).optional(),\n // WP-485 Slice 2b round 4 (Codex P2, FEAT-1370): the server's contradiction advisory\n // (ContradictionAdvisory, declared below) is emitted into structuredContent at line ~2203\n // but was missing here — since this schema is `.strict()`, any real capture response\n // carrying the advisory failed validation outright with `unrecognized_keys`. Loose record,\n // same single-source-of-truth rationale as coherencyRefusal above.\n contradictionAdvisory: z.record(z.unknown()).optional(),\n}).strict();\n\nconst captureClassifierOnlyOutputSchema = z.object({\n classifier: captureClassifierSchema,\n}).strict();\n\n// Fix 2 (WP-577 review round 3, TEN-2918 follow-up): captureSinglePreviewOutputSchema\n// (lib/captureSinglePreviewOutput.ts) is the third union member — the single `preview: true`\n// branch's own honest shape, distinct from both the real-create success shape below and the\n// classifier-only fallback. See that module's doc comment for why it's declared there.\nexport const captureOutputSchema = z.union([\n captureSuccessOutputSchema,\n captureSinglePreviewOutputSchema,\n captureClassifierOnlyOutputSchema,\n]);\n\n// STD-2 / DEC-1504: the batch output contract (real + preview branches) and the preview\n// envelope builder live in ../lib/batchCaptureOutput.js. `batchCaptureOutputSchema`\n// re-exported here because __tests__/tool-harness.test.ts imports it from this module;\n// its two branch schemas have no importer of this module and are not re-exported.\nexport {\n batchCaptureOutputSchema,\n} from \"../lib/batchCaptureOutput.js\";\n\n/**\n * TEN-194: Auto-commit only in Open mode. In consensus/role, draft-first always —\n * ignore autoCommit: true to prevent governance bypass.\n */\nfunction shouldAutoCommitCapture(\n autoCommit: boolean | undefined,\n governanceMode: string | undefined,\n): boolean {\n if (governanceMode !== \"open\") return false;\n return autoCommit === true || autoCommit === undefined;\n}\n\n/**\n * Build initial entry data from collection field definitions using type-aware defaults.\n * Single source of truth: FIELD_TYPE_DEFAULTS from fieldTypes.ts (BET-106, DEC-174).\n * Deduplicates logic previously inlined in both capture and batch-capture (TEN-305).\n */\nfunction buildDataFromFields(\n fields: Array<{ key: string; type: string; [k: string]: unknown }>,\n descriptionField: string,\n descriptionValue: string,\n): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n for (const field of fields) {\n if (field.key === descriptionField) {\n data[field.key] = descriptionValue;\n } else {\n data[field.key] = FIELD_TYPE_DEFAULTS[field.type as FieldType] ?? null;\n }\n }\n return data;\n}\n\n// WP-484 S2 (§3): `capture` absorbs `batch-capture` → action=batch, `items[]`\n// (each item may carry inline `relations` — TEN-957). Legacy `batch-capture`\n// tool stays registered alongside (§7 \"alongside\" mechanic) — both call the\n// SAME handleCapture/handleBatchCapture functions, one business-logic path.\nconst CAPTURE_ACTIONS = [\"capture\", \"batch\"] as const;\ntype CaptureAction = (typeof CAPTURE_ACTIONS)[number];\n\nconst captureItemSchema = batchCaptureSchema.shape.entries.element;\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of every\n// absorbed action's params (single-capture fields relaxed to optional; batch\n// adds `items`). `action` defaults to 'capture' — `capture`'s name is REUSED\n// (not \"alongside\"-eligible), and its pre-S2 behavior took no `action` param,\n// so a default preserves every existing bare single-entry capture call site\n// until the DEC-283 sweep (S3).\nexport const captureCompoundSchema = z.object({\n action: z.enum(CAPTURE_ACTIONS).optional().default(\"capture\").describe(\"'capture': create a single knowledge entry (the original capture behavior). 'batch': create multiple entries in one call via `items[]` (absorbs batch-capture; each item may carry inline `relations`).\"),\n // For 'capture' — mirrors captureSchema, relaxed to optional (batch omits these).\n collection: z.string().max(200).optional().describe(\"For 'capture': collection slug, e.g. 'tensions', 'business-rules', 'glossary', 'decisions'. Optional — classifier auto-routes when omitted.\"),\n name: z.string().max(500).optional().describe(\"For 'capture': display name — required for this action.\"),\n description: z.string().max(20000).optional().describe(\"For 'capture': full context — required for this action.\"),\n context: z.string().max(5000).optional().describe(\"For 'capture': optional additional context.\"),\n entryId: entryIdSchema,\n canonicalKey: z.string().max(200).optional().describe(\"For 'capture': semantic type (e.g. 'decision', 'tension', 'vision'). Auto-assigned from collection if omitted.\"),\n data: z.record(z.unknown()).optional().describe(\"For 'capture': explicit field values. Merged with inferred values; user-provided wins.\"),\n links: z.array(z.object({\n to: z.string().max(200).describe(\"Target entry ID (e.g. '<PREFIX>-<n>')\"),\n type: z.string().max(200).describe(\"Relation type (e.g. 'governs', 'related_to', 'informs')\"),\n })).max(20).optional().describe(\"For 'capture': relations to create after capture. Skips auto-link discovery when provided.\"),\n autoCommit: z.boolean().optional().describe(\"For 'capture'/'batch': if true, commits immediately after capture + linking.\"),\n sourceRef: z.string().max(2000).optional().describe(\"For 'capture': URI or path of the source document backing this entry.\"),\n sourceExcerpt: z.string().max(5000).optional().describe(\"For 'capture': verbatim excerpt from the source backing this entry's claims.\"),\n preview: z.boolean().optional().describe(\"For 'capture'/'batch': if true, validates without writing.\"),\n suggestOnly: z.boolean().optional().describe(\"For 'capture': if true, runs pre-write grounding and returns a groundingReport WITHOUT creating any entry.\"),\n format: z.enum([\"agent\", \"human\"]).optional().describe(\"For 'capture': response format for grounding data.\"),\n // For 'batch' — mirrors batchCaptureSchema's `entries`, renamed `items` per §3.\n items: z.array(captureItemSchema).min(1).max(50).optional().describe(\"For 'batch': array of entries to capture, each may carry inline `relations`.\"),\n // WP-513: team+role to create AS OWNER of (rung 2 only).\n ownerTeamEntryId: z.string().max(200).optional().describe(\"For 'capture': owning team (rung-2).\"),\n ownerRoleEntryId: z.string().max(200).optional().describe(\"For 'capture': owning role (rung-2).\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion, reusing the\n// existing single-purpose schemas (Code Integrity — captureSchema/\n// batchCaptureSchema already know these shapes).\nconst captureSingleVariant = captureSchema.extend({ action: z.literal(\"capture\") });\nconst captureBatchVariant = z.object({\n action: z.literal(\"batch\"),\n items: z.array(captureItemSchema).min(1).max(50),\n autoCommit: z.boolean().optional(),\n preview: z.boolean().optional(),\n});\n\nexport const captureActionUnion = z.discriminatedUnion(\"action\", [\n captureSingleVariant,\n captureBatchVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const CAPTURE_ACTION_SPECS: Record<CaptureAction, ActionParamSpec> = {\n capture: {\n params: [\"collection\", \"name\", \"description\", \"context\", \"entryId\", \"canonicalKey\", \"data\", \"links\", \"autoCommit\", \"sourceRef\", \"sourceExcerpt\", \"preview\", \"suggestOnly\", \"format\"],\n description: \"name and description are required.\",\n },\n batch: { params: [\"items\", \"autoCommit\", \"preview\"], description: \"items (1-50, each may carry inline relations) is required.\" },\n};\n\nexport function registerSmartCaptureTools(server: McpServer) {\n // §3b handler map — dispatched via dispatchDiscriminated.\n const captureHandlers: Record<CaptureAction, (data: any) => Promise<ToolResult>> = {\n capture: (data) => handleCapture(server, data),\n batch: (data) => handleBatchCapture(server, { entries: data.items, autoCommit: data.autoCommit, preview: data.preview }),\n };\n\n server.registerTool(\n \"capture\",\n {\n title: \"Capture\",\n description:\n \"The tool for creating knowledge entries — single or batch. Two actions:\\n\\n\" +\n \"- **capture**: Create a single entry. Creates an entry, auto-links related entries, and returns a quality \" +\n \"scorecard — all in one call. Provide a name and description; `collection` is optional — the classifier \" +\n \"auto-routes when omitted.\\n\" +\n \"- **batch**: Create multiple entries in one call via `items[]` (absorbs batch-capture). Each item may carry \" +\n \"inline `relations` created right after that entry is captured.\\n\\n\" +\n \"**action=capture details:**\\n\" +\n \"Supported collections with smart profiles: tensions, business-rules, glossary, decisions, features, \" +\n \"audiences, strategy, standards, maps, chains, insights, assumptions, principles, tracking-events.\\n\" +\n \"All other collections get an ENT-{random} ID and sensible defaults.\\n\\n\" +\n \"**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. \" +\n \"Top-level `name` and `description` always win for those fields. `data` wins over inference for all other fields.\\n\\n\" +\n \"**Compound capture:** Pass `links` to create relations in the same call (skips auto-link discovery). \" +\n \"In Open mode, entries commit by default when `autoCommit` is omitted. \" +\n \"Pass `autoCommit: true` to promote the entry from draft to SSOT immediately after linking when you want to be explicit. \" +\n \"Governed collections (glossary, business-rules, principles, standards, strategy, features, architecture) \" +\n \"will warn but still commit — use only when you're certain.\\n\\n\" +\n \"Entries are created as `draft` first, then may publish immediately depending on governance and `autoCommit`. Use `entries action=update` for post-creation adjustments.\",\n inputSchema: captureCompoundSchema,\n annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(captureCompoundSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"capture\", action }, () =>\n dispatchDiscriminated(\"capture\", captureActionUnion, parsed.data, CAPTURE_ACTION_SPECS, captureHandlers),\n );\n }),\n );\n\n // WP-484 S3 (clean break, TEN-2157): the standalone `batch-capture` tool\n // registration retired here (registerBatchCaptureTool deleted below).\n // handleBatchCapture stays live via `capture action=batch`.\n}\n\n/**\n * WP-484 S2 (§3): extracted single-item capture handler — reused by the\n * legacy `capture` standalone tool AND the new `capture action=capture`\n * (unchanged shape; the noun itself absorbs `batch-capture` as `action=batch`,\n * §3 core-nouns table). One business-logic path.\n */\nexport async function handleCapture(\n server: McpServer,\n { collection, name, description, context, entryId, canonicalKey, data: userData, links, autoCommit, sourceRef, sourceExcerpt, preview, suggestOnly, format, ownerTeamEntryId, ownerRoleEntryId }: z.infer<typeof captureSchema>,\n) {\n requireWriteAccess();\n\n const timingStart = Date.now();\n\n const wsCtx = await getWorkspaceContext();\n const explicitCollectionProvided = typeof collection === \"string\" && collection.trim().length > 0;\n\n const resolution = await resolveCaptureCollection({\n collection,\n name,\n description,\n workspaceId: wsCtx.workspaceId,\n explicitCollectionProvided,\n });\n if (resolution.earlyResult) {\n return resolution.earlyResult;\n }\n let resolvedCollection = resolution.resolvedCollection;\n const classifierMeta = resolution.classifierMeta;\n if (!resolvedCollection) {\n return buildClassifierUnknownResult();\n }\n\n // DEC-313 GAP 1: When classifier auto-routes to 'chains' and candidates\n // include 'work-packages', inject canonicalKey='work_package' so createEntry's isBetSignal\n // guard can redirect chains→work-packages. Only fires for classifier-driven routing\n // (not explicit agent choice) and when no canonicalKey was already provided.\n if (\n resolvedCollection === 'chains' &&\n !canonicalKey &&\n !explicitCollectionProvided &&\n classifierMeta?.candidates?.some(\n (c: { collection: string }) => c.collection === 'work-packages'\n )\n ) {\n canonicalKey = 'work_package';\n }\n\n const tAfterClassify = Date.now();\n\n // BR-111: entryId only allowed for business-rules and standards\n if (entryId && resolvedCollection !== \"business-rules\" && resolvedCollection !== \"standards\") {\n return {\n content: [{\n type: \"text\" as const,\n // BR-111\n text: `# entryId Not Allowed\\n\\n\\`entryId\\` is only valid for \\`business-rules\\` and \\`standards\\` collections. For \\`${resolvedCollection}\\`, omit \\`entryId\\` — IDs are auto-generated.`,\n }],\n structuredContent: failure(\n \"INVALID_ENTRY_ID\",\n `entryId is only allowed for business-rules and standards. Omit for ${resolvedCollection}.`,\n \"Remove entryId from your capture call.\",\n [],\n ),\n };\n }\n\n const profile = await getProfile(resolvedCollection);\n\n const col = await kernelQuery<CollectionDoc | null>(\"chain.getCollection\", { slug: resolvedCollection });\n if (!col) {\n const displayName = resolvedCollection.split(\"-\").map((w: string) => w.charAt(0).toUpperCase() + w.slice(1)).join(\" \");\n return {\n content: [{\n type: \"text\" as const,\n text:\n `Collection \\`${resolvedCollection}\\` not found.\\n\\n` +\n `**To create it**, run:\\n` +\n `\\`\\`\\`\\ncollections action=create slug=\"${resolvedCollection}\" name=\"${displayName}\" description=\"...\"\\n\\`\\`\\`\\n\\n` +\n `Or use \\`collections action=list\\` to see available collections.`,\n }],\n structuredContent: failure(\n \"NOT_FOUND\",\n `Collection '${resolvedCollection}' not found.`,\n \"Create the collection first, or use collections action=list to see available ones.\",\n [\n { tool: \"collections\", description: \"Create collection\", parameters: { action: \"create\", slug: resolvedCollection, name: displayName } },\n { tool: \"collections\", description: \"List collections\", parameters: { action: \"list\" } },\n ],\n ),\n };\n }\n\n // WP-318 S2 E1: Pre-write grounding — call suggestLinksForCapture in parallel with collection fetch.\n // Graceful degradation: grounding NEVER blocks capture. Any error → null.\n // Only runs when there's searchable content and auto-discovery is not skipped.\n const skipAutoDiscoveryEarly = links && links.length > 0;\n const groundingStart = Date.now();\n const groundingPromise = (!skipAutoDiscoveryEarly && (name || description))\n ? kernelQuery<GatewayRouteReturnByName<\"chain.suggestLinksForCapture\">>(\"chain.suggestLinksForCapture\", {\n entries: [{ name, description: description ?? \"\", collectionHint: resolvedCollection }],\n limit: 5,\n threshold: 2,\n }).catch(() => null)\n : Promise.resolve(null);\n\n // WP-318 S2 E1: Await grounding result — capped at 500ms to preserve fail-open on latency.\n const groundingRaw = await Promise.race([\n groundingPromise,\n new Promise<null>((r) => setTimeout(() => r(null), 500)),\n ]);\n const groundingElapsedMs = Date.now() - groundingStart;\n const groundingEntry = (groundingRaw as any)?.[0] ?? null;\n const groundingRelated: Array<{\n entryId: string; name: string; collectionSlug: string;\n overlapRatio: number; recommendedRelationType: string; reasoning: string;\n }> = groundingEntry?.related ?? [];\n const groundingDuplicates: Array<{\n entryId: string; name: string; collectionSlug: string;\n matchType: \"related\" | \"possible_duplicate\"; overlapRatio: number;\n }> = groundingEntry?.duplicates ?? [];\n\n // WP-319 S2: Consume governance[] from query response (moved from local isGoverned loop).\n // governance[] is pre-computed by suggestLinksForCapture (WP-319 S1) — no async round trips needed.\n // Severity field from the query is ignored here; MCP banner display does not distinguish severity yet.\n const groundingGovernance: Array<{ entryId: string; name: string; collectionSlug: string }> =\n (groundingEntry?.governance ?? []).map((g: any) => ({\n entryId: g.entryId,\n name: g.name,\n collectionSlug: g.collectionSlug,\n }));\n\n const groundingReport = {\n related: groundingRelated.map((r) => ({\n entryId: r.entryId,\n name: r.name,\n collectionSlug: r.collectionSlug,\n overlapRatio: r.overlapRatio,\n recommendedRelationType: r.recommendedRelationType,\n reasoning: r.reasoning,\n })),\n duplicates: groundingDuplicates.map((d) => ({\n entryId: d.entryId,\n name: d.name,\n collectionSlug: d.collectionSlug,\n matchType: d.matchType,\n overlapRatio: d.overlapRatio,\n })),\n governance: groundingGovernance,\n };\n\n // WP-318 S2 E3: suggestOnly — return grounding preview without creating entry\n if (suggestOnly) {\n const hasSuggestions = groundingReport.related.length > 0 || groundingReport.duplicates.length > 0;\n const summaryText = hasSuggestions\n ? `Grounding preview for \"${name}\": ${groundingReport.related.length} related, ${groundingReport.duplicates.length} possible duplicates. No entry created.`\n : `Grounding preview for \"${name}\": no similar entries found. Safe to capture.`;\n return {\n content: [{\n type: \"text\" as const,\n text: `# Grounding Preview — No Entry Created\\n\\n${summaryText}\\n\\n` +\n (groundingReport.related.length > 0\n ? `## Related entries\\n${groundingReport.related.map((r) => `- **${r.entryId}** ${r.name} [${r.collectionSlug}] — ${r.reasoning}`).join(\"\\n\")}\\n\\n`\n : \"\") +\n (groundingReport.duplicates.length > 0\n ? `## Possible duplicates\\n${groundingReport.duplicates.map((d) => `- **${d.entryId}** ${d.name} [${d.collectionSlug}] (${d.matchType}, overlap: ${d.overlapRatio})`).join(\"\\n\")}\\n\\n`\n : \"\") +\n (groundingReport.governance.length > 0\n ? `## Governance entries to review\\n${groundingReport.governance.map((g) => `- **${g.entryId}** ${g.name} [${g.collectionSlug}]`).join(\"\\n\")}\\n\\n`\n : \"\") +\n `_Call \\`capture\\` without \\`suggestOnly\\` to proceed with entry creation._`,\n }],\n structuredContent: {\n ...success(\n summaryText,\n { groundingReport, outcome: \"suggest_only\" as const },\n // Fix 3 sibling (TEN-2918 follow-up): thread the caller's full original payload —\n // see lib/captureForRealAction.ts's doc comment.\n buildCaptureForRealNextAction({\n collection: resolvedCollection, name, description, context, entryId, canonicalKey,\n data: userData, links, autoCommit, sourceRef, sourceExcerpt, ownerTeamEntryId, ownerRoleEntryId,\n }),\n ),\n },\n };\n }\n\n // 2. Build data with profile defaults + inference\n const data = buildDataFromFields(col.fields ?? [], profile.descriptionField, description);\n\n for (const def of profile.defaults) {\n if (def.value !== \"infer\" && def.value !== \"today\") {\n data[def.key] = def.value;\n }\n }\n\n if (profile.inferField) {\n const inferred = profile.inferField({\n collection: resolvedCollection, name, description, context, data, entryId: \"\",\n linksCreated: [], linksSuggested: [], collectionFields: col.fields ?? [],\n });\n for (const [key, val] of Object.entries(inferred)) {\n if (val !== undefined && val !== \"\") {\n data[key] = val;\n }\n }\n }\n\n if (isEmptyValue(data.date)) {\n const inferredSourceDate = inferSourceDate(name, description, context, sourceRef, sourceExcerpt);\n if (inferredSourceDate && (col.fields ?? []).some((field) => field.key === \"date\")) {\n data.date = inferredSourceDate;\n }\n }\n\n // Merge user-provided data (wins over inference). WP-574/TEN-2916: NO key is filtered — a\n // `key !== \"name\"` strip discarded explicitly supplied mirror values while the batch path\n // never filtered. The write gate owns mirror semantics (blank coalesces from entry.name).\n if (userData && typeof userData === \"object\") Object.assign(data, userData);\n\n // Top-level description always wins\n data[profile.descriptionField || \"description\"] = description;\n\n // BET-281/WP-640 S2 (TASK-63): Identify work_package captures via canonicalKey (primary) or defaultCanonicalKey — isBetCapture renamed isWorkPackageCapture (mechanical).\n const colMeta = await getCollectionBySlug(resolvedCollection);\n const isWorkPackageCapture = canonicalKey === \"work_package\" || colMeta?.defaultCanonicalKey === \"work_package\";\n\n // BET-125: decomposeContent (strategy goals/rationale/scope; bet problem/elements/doneWhen) + canonicalizeSelects\n let entryWarnings: string[] = [];\n // BET-288: derive strategy check from thinkingLayer instead of hardcoded slug\n const isStrategyCapture = colMeta?.thinkingLayer === \"strategy\";\n const shouldDecompose =\n (isStrategyCapture || isWorkPackageCapture) &&\n description.trim().length > 0;\n if (shouldDecompose) {\n try {\n const decomposed = await kernelCall<GatewayRouteReturnByName<\"chain.decomposeContent\">>(\n \"chain.decomposeContent\",\n {\n collectionSlug: resolvedCollection,\n entryName: name,\n description,\n existingData: data,\n ...(isWorkPackageCapture ? { canonicalKey: \"work_package\" } : {}),\n ...(colMeta?.thinkingLayer ? { thinkingLayer: colMeta.thinkingLayer } : {}),\n },\n );\n if (decomposed?.decomposed) {\n for (const [key, val] of Object.entries(decomposed.decomposed)) {\n if (isEmptyValue(data[key]) && isNonEmptyValue(val)) {\n data[key] = val;\n }\n }\n }\n } catch {\n // Non-blocking: capture proceeds without decomposition (BET-125 contract)\n entryWarnings.push(\"Content decomposition skipped (transient error). Entry saved with description only.\");\n }\n }\n canonicalizeSelects(data, col.fields ?? [], isWorkPackageCapture);\n\n // BET-132: bet captures keep flat fields (problem, appetite, etc.) — no data.links wrapping\n\n // 3b. Status is now resolved server-side (DEC-896 / BR-76): Open mode → 'active', else 'draft'.\n // Do NOT pass explicit status here so governance mode governs. Callers that need draft can pass it.\n const agentId = getAgentSessionId();\n\n // 4. Create entry (Convex generates sequential ID when entryId not provided)\n let finalEntryId: string;\n let internalId: string;\n let normalizationMeta: { remapped: Record<string, string>; rejected: string[]; accepted: string[] } | undefined;\n // BET-272 S3: Formative quality hints — populated from createEntryWithClassification result (STD-101)\n let formativeHints: Array<{ field: string; hint: string; severity: \"advisory\" }> = [];\n // BET-272 S5: Advisory relation suggestions from graph (BR-144, STD-147)\n let relationSuggestionsFromCreate: Array<{ targetEntryId: string; targetName: string; relationType: string; confidence: number; reasoning: string }> = [];\n // TEN-2365: capture-time authority-domain proposal echo (PENDING ratification), when filed.\n let authorityDomainFromCreate: { slug: string; status: \"proposal-pending\" } | undefined;\n // WP-475 E1: heuristic coaching verdict delivered in the createEntry response.\n // `undefined` = field absent (older deploy) → fall back to the explicit call below.\n let coachingFromCreate: CoachingResultSubset | null | undefined;\n // DEC-896 / BR-76 S3: server returned 'active' — skip post-write commitEntry call.\n let wasAutoCommittedServerSide = false;\n try {\n // WP-577 / TEN-2918: the server's declared return type for this route now honestly\n // includes its preview-mode branch (convex/agentKnowledge/entries.ts,\n // CreateEntryWithClassificationPreviewResult) — GatewayRouteReturnByName picks it up\n // directly, no client-local widening type needed anymore.\n const result = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntry\">>(\"chain.createEntry\", {\n collectionSlug: resolvedCollection,\n entryId: entryId ?? undefined,\n name,\n // DEC-896 / BR-76: omit status — server resolves from governanceMode (Open→active, else draft).\n data,\n canonicalKey,\n createdBy: agentId ? `agent:${agentId}` : \"capture\",\n sessionId: agentId ?? undefined,\n ...(sourceRef ? { sourceRef } : {}),\n ...(sourceExcerpt ? { sourceExcerpt } : {}),\n ...(preview ? { preview: true } : {}),\n // WP-513 review round 3 (P1): rung-2 owner — no-op pre-rung-2.\n ...(ownerTeamEntryId ? { ownerTeamEntryId } : {}),\n ...(ownerRoleEntryId ? { ownerRoleEntryId } : {}),\n // WP-475 E1 (Codex P2 — CLI parity): user links are known UPFRONT, so the\n // post-relations re-evaluation below owns the single LLM run — defer the\n // create-time LLM schedule (deterministic, mirrors `pb capture --link`).\n // Auto-discovered links are unknown here: zero-user-link captures do NOT\n // defer (a link-less capture must keep its LLM run); the supersession\n // guard bounds the auto-link double-run race when timing allows.\n // Fail-safe: if the relations batch then creates nothing, the deferred row\n // keeps its delivered heuristic verdict with llmStatus 'skipped' (same\n // accepted shape as the CLI dying between create and re-eval).\n ...(links && links.length > 0 ? { deferLLMSchedule: true } : {}),\n });\n\n // WP-316 S3: Preview gate — return dry-run result without recording session activity.\n if (result && isPreviewCreateEntryResult(result)) {\n const hasGrounding = groundingReport.related.length > 0 || groundingReport.duplicates.length > 0 || groundingReport.governance.length > 0;\n const groundingSummary = hasGrounding\n ? `\\n\\n**Grounding:** ${[\n groundingReport.duplicates.length > 0 && `${groundingReport.duplicates.length} possible duplicate${groundingReport.duplicates.length > 1 ? \"s\" : \"\"}`,\n groundingReport.related.length > 0 && `${groundingReport.related.length} related entr${groundingReport.related.length > 1 ? \"ies\" : \"y\"}`,\n groundingReport.governance.length > 0 && `${groundingReport.governance[0]?.entryId} may govern this`,\n ].filter(Boolean).join(\", \")}.`\n : \"\";\n // Phase 2 (D1): when the server predicts the governance WHY hard-gate would\n // reject this capture, the preview must say \"would be BLOCKED\" — not \"would\n // capture\" — so the dry-run contract stays honest for the newly gated inputs.\n const wouldBlock = result.wouldBlock === true;\n const headline = wouldBlock\n ? `Preview: would be BLOCKED — \"${name}\" [${resolvedCollection}]`\n : `Preview: would capture \"${name}\" [${resolvedCollection}]`;\n const previewEnvelope = success(\n wouldBlock\n ? `Preview: would be BLOCKED — \"${name}\" — no DB writes`\n : `Preview: would capture \"${name}\" — no DB writes`,\n {\n entryId: result.entryId,\n name,\n // P0 round 4 (fix 1/3, root): see resolveEffectiveCollection's doc comment\n // (lib/createEntryPreviewResult.ts) for why this must be the server's EFFECTIVE\n // post-routing collection, never the caller's pre-routing `resolvedCollection`.\n collection: resolveEffectiveCollection(result, preview, resolvedCollection),\n outcome: wouldBlock ? (\"blocked\" as const) : (\"preview\" as const),\n ...(wouldBlock && result.blockingReason ? { blockingReason: result.blockingReason } : {}),\n warnings: result.warnings ?? [],\n groundingReport,\n // TEN-2458: thread task-alignment verdict when kernel computed it for this preview.\n ...(result.taskAlignment ? { taskAlignment: result.taskAlignment } : {}),\n },\n // Fix 3 (WP-577 review re-review, TEN-2918 follow-up): thread the caller's full\n // original payload so a follow-up \"capture for real\" creates the SAME entry the\n // preview described — see lib/captureForRealAction.ts's doc comment for the bug\n // this closes (a bare {collection,name,description} dropped `data`/`links`/etc.,\n // so a required WHY supplied via `data` silently vanished on retry).\n buildCaptureForRealNextAction({\n collection: resolvedCollection, name, description, context, entryId, canonicalKey,\n data: userData, links, autoCommit, sourceRef, sourceExcerpt, ownerTeamEntryId, ownerRoleEntryId,\n }),\n );\n if (result.contract) {\n previewEnvelope.contract = result.contract;\n }\n const taskAlignmentNote = result.taskAlignment\n ? `\\n\\n**Task alignment:** ${result.taskAlignment.wording}`\n : \"\";\n return {\n content: [{ type: \"text\" as const, text: `# ${headline}\\n\\nNo DB writes — call without \\`preview:true\\` to capture for real.${result.warnings?.length ? `\\n\\n**Warnings:** ${result.warnings.join(\"; \")}` : \"\"}${groundingSummary}${taskAlignmentNote}` }],\n structuredContent: previewEnvelope,\n };\n }\n // Past this point `result` is provably the real-create branch (the preview branch\n // returned above) — TS's control-flow narrowing doesn't propagate through the\n // `\"preview\" in result` guard above for this union shape, so re-assert explicitly\n // rather than relying on it (PR #395, Lane C S3b annotation pass; still true after\n // WP-577's server-type fix — the discriminant check is the same shape, just against\n // the now-honest generated union instead of the old client-local widening type).\n const created = result as Exclude<typeof result, { preview: true }>;\n internalId = created.docId;\n finalEntryId = created.entryId;\n entryWarnings.push(...(created.warnings ?? []));\n // Server declares `normalization: Record<string, unknown> | null` (looser than this\n // file's own consumption shape) — the real convention (remapped/rejected/accepted) is\n // documented at the construction sites (convex/agentKnowledge/entries.ts) but not\n // statically typed there either (PR #395, Lane C S3b annotation pass).\n normalizationMeta = created.normalization as\n | { remapped: Record<string, string>; rejected: string[]; accepted: string[] }\n | undefined;\n // BET-272 S5: Advisory relation suggestions from graph (BR-144, STD-147)\n relationSuggestionsFromCreate = created.relationSuggestions ?? [];\n // BET-272 S3: Quality hints from createEntryWithClassification (STD-101: single source)\n formativeHints = created.qualityHints ?? [];\n // TEN-2365: capture-time authority-domain proposal echo.\n authorityDomainFromCreate = created.authorityDomain;\n // WP-475 E1: consume the inline coaching verdict (undefined = older deploy).\n coachingFromCreate = (created as typeof created & { coaching?: typeof coachingFromCreate }).coaching;\n resolveGapsForEntry(name, created.entryId);\n // DEC-896 / BR-76 S3: server already committed (Open mode auto-commit). Mark and skip commitEntry.\n if ((created as typeof created & { status?: string }).status === \"active\") {\n wasAutoCommittedServerSide = true;\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n // WP-575: a budget abort is an UNKNOWN capture, not a failed one (see the module).\n if (isGatewayTimeout(error)) return buildCaptureOutcomeUnknownResult(error, name, msg);\n if (msg.includes(\"Duplicate\") || msg.includes(\"already exists\")) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Cannot Capture — Duplicate Detected\\n\\n${msg}\\n\\nUse \\`entries action=get\\` to inspect the existing entry, or \\`entries action=update\\` to modify it.`,\n }],\n structuredContent: failure(\n \"DUPLICATE\",\n msg,\n \"Use entries action=get to inspect the existing entry.\",\n [\n { tool: \"entries\", description: \"Get existing entry\", parameters: { action: \"get\", entryId: entryId ?? name } },\n { tool: \"entries\", description: \"Update existing entry\", parameters: { action: \"update\", entryId: entryId ?? \"\" } },\n ],\n ),\n };\n }\n throw error;\n }\n\n const tAfterCreate = Date.now();\n\n // WP-319 S2: Record grounding outcome for observability (STD-155).\n // Fire-and-forget — never block capture on observability failure.\n void kernelMutation<GatewayRouteReturnByName<\"chain.recordGroundingOutcome\">>(\"chain.recordGroundingOutcome\", {\n surface: \"mcp\",\n promptShown: groundingReport.governance.length > 0,\n highestRatio: Math.max(\n ...groundingReport.duplicates.map((d: any) => d.overlapRatio),\n ...groundingReport.related.map((r: any) => r.overlapRatio),\n 0,\n ),\n hadGovernance: groundingReport.governance.length > 0,\n grounding_ms: groundingElapsedMs,\n }).catch(() => undefined);\n\n // 6. Discover candidates + build batch relations array (BET-105 E4)\n const linksCreated: LinkResult[] = [];\n const linksSuggested: LinkSuggestion[] = [];\n const userLinkResults: Array<{ label: string; ok: boolean }> = [];\n // WP-474 E5: auto-links the server judge advised but did NOT write (untypeable) — surfaced, never silently dropped.\n const advisedLinks: Array<{ targetName: string; targetCollection: string; relationType: string }> = [];\n // BET-167: Conflict candidates for pre-commit advisory (populated from search results)\n let conflictCandidates: Array<{ entryId: string; name: string; collection: string }> = [];\n\n type PendingRelation = {\n fromEntryId: string; toEntryId: string; type: string;\n // WP-474 E4-REWIRE: provenance marker + carried confidence threaded structurally\n // (not just as a string in meta.linkReason) so createEntryRelations persists them.\n proposedBy?: string; confidence?: number;\n meta: { source: \"auto\" | \"user\"; targetName: string; targetCollection: string; linkReason?: string };\n };\n const pendingRelations: PendingRelation[] = [];\n\n const skipAutoDiscovery = links && links.length > 0;\n const searchQuery = extractSearchTerms(name, description);\n if (searchQuery && !skipAutoDiscovery) {\n // BET-281: Populate hub cache before scoring; uses collectionCache (no extra DB call).\n const hubSlugs = await populateHubCache();\n const [searchResults, allCollections] = await Promise.all([\n kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: searchQuery }),\n getCollections(),\n ]);\n\n const collMap = new Map<string, string>();\n for (const c of allCollections) collMap.set(c._id, c.slug);\n\n // PR #392 round 2 (Codex, finding 5 — memory): project each search-result\n // candidate to the MINIMAL shape actually needed downstream immediately — never\n // retain the full raw doc (which can carry an arbitrarily large `data` blob)\n // past this line. `preview` is computed HERE (not deferred) so the one\n // downstream consumer that used to read `c.data` (linksSuggested's preview\n // text, extractPreview) still works off a small, already-bounded (<=80 char)\n // string instead of the full original `data` object.\n const candidatesFiltered = (searchResults ?? [])\n .filter((r) => r.entryId !== finalEntryId && r._id !== internalId)\n .map((r) => ({\n name: r.name as string,\n entryId: r.entryId as string | undefined,\n collectionId: r.collectionId as string,\n preview: extractPreview(r.data, 80),\n }));\n\n // Lane C S4: ONE batched chain.scoreLinkCandidates call for every filtered\n // candidate — never a per-candidate call inside this .map(). Single-entry\n // capture sends exactly one job (this flow scores one entry's candidates); the\n // response is one result array per job. Server returns results already sorted\n // by score descending (positional `index`, immune to an undefined entryId);\n // re-associate via candidatesFiltered[result.index].\n //\n // PR #392 round 2 (Codex, finding 1): the served scoring call can genuinely\n // fail (network, rate limit, transient gateway error) — the deleted pre-migration\n // in-process local scorer could never throw. Fail OPEN, matching that property:\n // on failure, treat this entry as having zero auto-link candidates rather than\n // letting the whole capture fail. The entry is already created by this point;\n // only the auto-link/suggestion ADVISORY features degrade.\n let scores: LinkScoreResult[] = [];\n if (candidatesFiltered.length > 0) {\n try {\n const scoreJobResults = await kernelQuery<GatewayRouteReturnByName<\"chain.scoreLinkCandidates\">>(\"chain.scoreLinkCandidates\", {\n collMap: Object.fromEntries(collMap),\n hubSlugs: [...hubSlugs],\n jobs: [\n buildScoreLinkCandidatesJob(\n candidatesFiltered.map((r) => ({ name: r.name, collectionId: r.collectionId })),\n name,\n description,\n resolvedCollection,\n ),\n ],\n });\n scores = scoreJobResults[0] ?? [];\n } catch { /* scoring failed; entry still created, zero auto-links this round */ }\n }\n const candidates = scores.map((s) => {\n const r = candidatesFiltered[s.index];\n return {\n ...r,\n collSlug: collMap.get(r.collectionId) ?? \"unknown\",\n confidence: s.score,\n confidenceReason: s.reason,\n };\n });\n\n let autoCount = 0;\n for (const c of candidates) {\n if (autoCount >= MAX_AUTO_LINKS) break;\n if (c.confidence < AUTO_LINK_CONFIDENCE_THRESHOLD) break;\n if (!c.entryId || !finalEntryId) continue;\n\n const { type: relationType, reason: relationReason } = inferRelationType(resolvedCollection, c.collSlug, profile);\n pendingRelations.push({\n fromEntryId: finalEntryId, toEntryId: c.entryId, type: relationType,\n // WP-474 E4-REWIRE: auto-defaulted relation (no one chose the type) — mark it\n // as auto-link and carry the numeric confidence structurally.\n proposedBy: \"auto-link\", confidence: c.confidence,\n meta: { source: \"auto\", targetName: c.name, targetCollection: c.collSlug,\n linkReason: `confidence ${c.confidence} (${c.confidenceReason}) + ${relationReason}` },\n });\n autoCount++;\n }\n\n const autoTargetIds = new Set(pendingRelations.map(r => r.toEntryId));\n for (const c of candidates) {\n if (linksSuggested.length >= MAX_SUGGESTIONS) break;\n if (c.entryId !== undefined && autoTargetIds.has(c.entryId)) continue;\n if (c.confidence < 10) continue;\n\n // PR #392 round 2 (finding 5): `c.preview` was already computed at projection\n // time (right after search), off the full `data` — never retained here.\n const reason = c.confidence >= AUTO_LINK_CONFIDENCE_THRESHOLD\n ? \"high relevance (already linked)\"\n : `\"${c.name.toLowerCase().split(/\\s+/).filter((w: string) => `${name} ${description}`.toLowerCase().includes(w) && w.length > 3).slice(0, 2).join('\", \"')}\" appears in content`;\n\n linksSuggested.push({ entryId: c.entryId, name: c.name, collection: c.collSlug, reason, preview: c.preview });\n }\n\n // BET-167: Collect conflict candidates from auto-link search results for pre-commit advisory.\n // Reuses the search already done — no extra query needed.\n conflictCandidates = candidates\n .filter((c) => c.entryId && c.entryId !== finalEntryId)\n .slice(0, 3)\n .map((c) => ({ entryId: c.entryId as string, name: c.name as string, collection: c.collSlug as string }));\n }\n\n // 6b. Add user-specified links to batch\n if (links && links.length > 0 && finalEntryId) {\n for (const link of links) {\n pendingRelations.push({\n fromEntryId: finalEntryId, toEntryId: link.to, type: link.type,\n // WP-474 E4-REWIRE: user-chosen type — mark provenance, NO confidence (human-chosen).\n proposedBy: \"user\",\n meta: { source: \"user\", targetName: link.to, targetCollection: \"unknown\" },\n });\n }\n }\n\n // 7. Parallel post-create: batch relations + cardinality + contradiction + coaching\n const resolvedCK = canonicalKey;\n\n const batchRelationsPromise = pendingRelations.length > 0\n ? kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelations\">>(\n \"chain.createEntryRelations\", {\n // WP-474 E4-REWIRE: carry provenance + confidence through to the server seam.\n relations: pendingRelations.slice(0, 25).map(r => ({\n fromEntryId: r.fromEntryId, toEntryId: r.toEntryId, type: r.type,\n ...(r.proposedBy !== undefined ? { proposedBy: r.proposedBy } : {}),\n ...(r.confidence !== undefined ? { confidence: r.confidence } : {}),\n })),\n sessionId: agentId ?? undefined,\n },\n ).catch((err) => {\n entryWarnings.push(`Auto-linking partially failed: ${err instanceof Error ? err.message : \"unknown error\"}`);\n return null;\n })\n : Promise.resolve(null);\n\n const cardinalityPromise = resolvedCK\n ? kernelQuery<GatewayRouteReturnByName<\"chain.checkCardinalityWarning\">>(\"chain.checkCardinalityWarning\", { canonicalKey: resolvedCK }).catch(() => null)\n : Promise.resolve(null);\n\n const contradictionPromise = runContradictionCheck(name, description);\n\n // WP-475 E1: chain.createEntry now delivers the heuristic coaching verdict in its\n // response — consume it instead of re-running the evaluation (the second call\n // inserted a duplicate qualityVerdicts row and scheduled the background LLM judge\n // twice). The explicit kernelMutation survives ONLY as a fallback for older\n // deploys whose createEntry response lacks the coaching field (deploy skew).\n const coachingPromise = coachingFromCreate !== undefined\n ? Promise.resolve(coachingFromCreate)\n : kernelMutation<GatewayRouteReturnByName<\"quality.evaluateHeuristicAndSchedule\">>(\"quality.evaluateHeuristicAndSchedule\", {\n entryId: finalEntryId, context: \"capture\",\n }).catch(() => null);\n\n const [batchResult, cardinalityCheck, contradictionWarnings, coachingAtCreate] = await Promise.all([\n batchRelationsPromise, cardinalityPromise, contradictionPromise, coachingPromise,\n ]);\n\n // WP-475 E1 (Codex P2 — CLI parity): the relations batch landed AFTER the\n // create-time verdict, so relation-dependent rubric criteria would render\n // falsely failed. When ANY relation was created (user links and/or\n // auto-discovered), re-evaluate and render THAT verdict — the re-eval also\n // schedules the LLM run that user-link captures deferred at create.\n // Fail-open: a re-eval failure keeps the create-time verdict.\n let verdictResult = coachingAtCreate;\n if ((batchResult?.created ?? 0) > 0) {\n const reEval = await kernelMutation<GatewayRouteReturnByName<\"quality.evaluateHeuristicAndSchedule\">>(\"quality.evaluateHeuristicAndSchedule\", {\n entryId: finalEntryId, context: \"capture\",\n }).catch(() => null);\n if (reEval?.verdict) verdictResult = reEval;\n }\n\n const tAfterRelations = Date.now();\n\n // Map batch results back to linksCreated / userLinkResults\n if (batchResult) {\n for (let i = 0; i < pendingRelations.length; i++) {\n const pending = pendingRelations[i];\n const result = batchResult.results[i];\n if (!result) continue;\n\n if (pending.meta.source === \"auto\") {\n if (result.ok) {\n linksCreated.push({\n targetEntryId: pending.toEntryId, targetName: pending.meta.targetName,\n targetCollection: pending.meta.targetCollection, relationType: pending.type,\n linkReason: pending.meta.linkReason,\n });\n } else if (result.status === 'advised') {\n advisedLinks.push({\n targetName: pending.meta.targetName, targetCollection: pending.meta.targetCollection,\n relationType: pending.type,\n });\n }\n } else {\n if (result.ok) {\n userLinkResults.push({ label: `✓ ${pending.type} → ${pending.toEntryId}`, ok: true });\n linksCreated.push({\n targetEntryId: pending.toEntryId, targetName: pending.meta.targetName,\n targetCollection: pending.meta.targetCollection, relationType: pending.type,\n });\n } else {\n userLinkResults.push({ label: `✗ ${pending.type} → ${pending.toEntryId}: ${result.error ?? \"failed\"}`, ok: false });\n }\n }\n }\n }\n\n // WP-474 E5: surface auto-links the judge advised but did not write — never silently dropped.\n if (advisedLinks.length > 0) {\n entryWarnings.push(`${advisedLinks.length} auto-link(s) advised, not written (untypeable) — accept with \\`relations action=create\\` to promote.`);\n }\n\n // 8. WP-480 S1: the in-process client scorecard was deleted — quality is\n // judged ONCE server-side. The verdict rides `verdictResult` (rubric coaching\n // below) and the advisory `formativeHints`; the connector only renders them.\n const tAfterQuality = Date.now();\n\n const cardinalityWarning: string | null = cardinalityCheck?.warning ?? null;\n\n if (contradictionWarnings.length > 0) {\n await recordSessionActivity({ contradictionWarning: true });\n }\n\n let coachingSection = \"\";\n if (verdictResult?.verdict && verdictResult.verdict.tier !== \"passive\" && verdictResult.verdict.criteria.length > 0) {\n coachingSection = formatRubricCoaching(verdictResult);\n }\n\n // 11. Track quality verdict\n if (verdictResult?.verdict) {\n try {\n const wsForTracking = await getWorkspaceContext();\n const v = verdictResult.verdict;\n const failedCount = (v.criteria ?? []).filter((c: any) => !c.passed).length;\n trackQualityVerdict(wsForTracking.workspaceId, {\n entry_id: finalEntryId,\n entry_type: v.canonicalKey ?? resolvedCollection,\n tier: v.tier,\n context: \"capture\",\n passed: v.passed,\n source: verdictResult.source ?? \"heuristic\",\n criteria_total: v.criteria?.length ?? 0,\n criteria_failed: failedCount,\n llm_scheduled: v.tier !== \"passive\",\n methodology_version: v.methodologyVersion,\n });\n } catch { /* tracking is advisory */ }\n }\n\n // 12. Auto-commit if requested (or defaulted via Open governance mode).\n // BET-76 FEAT-111: When autoCommit is not explicitly set, default to true for\n // Open mode workspaces. Consensus/role modes retain draft-first behavior.\n // TEN-1810: Refresh governanceMode in case workspace flipped to Open after session start.\n const freshGovernanceMode = await refreshWorkspaceGovernanceMode();\n const shouldAutoCommit = shouldAutoCommitCapture(autoCommit, freshGovernanceMode);\n\n // BET-167 doneWhen #4: Conflict pre-check before auto-commit (advisory, never blocking).\n // When auto-link discovery was skipped (user provided explicit links), run a lightweight\n // search now so conflict candidates are populated before the commit.\n if (shouldAutoCommit && finalEntryId && conflictCandidates.length === 0) {\n try {\n const conflictResults = await kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: name });\n conflictCandidates = (conflictResults ?? [])\n .filter((r: any) => r.entryId && r.entryId !== finalEntryId && r._id !== internalId)\n .slice(0, 3)\n .map((r: any) => ({ entryId: r.entryId as string, name: r.name as string, collection: r.collectionSlug ?? \"unknown\" }));\n } catch {\n // Advisory only — proceed without conflict check on failure\n }\n }\n\n let finalStatus: \"draft\" | \"committed\" | \"proposed\" | \"draft_on_failure\" = \"draft\";\n let commitError: string | null = null;\n // WP-465 surface parity: full refusal payload (routes + mode) for the coherency refused path.\n let commitRefusal: Record<string, unknown> | null = null;\n // WP-485 Slice 2b (R2, FEAT-1370): the server's typed advisory, when commitEntry's\n // contradiction gate found a high-confidence match (DEC-1321 — advisory only).\n let contradictionAdvisory: ContradictionAdvisory | null = null;\n // DEC-896 / BR-76 S3: server already committed in Open mode — skip commitEntry entirely.\n //\n // KNOWN GAP (WP-485 Slice 2b round 4, Codex P1, FEAT-1370 — DEFERRED, not silently\n // resolved, flagged as the MOST IMPACTFUL open item from this review loop). This branch\n // is the MAIN, common auto-commit path — chain.createEntry itself sets status:'active'\n // for the default Open-governance case (createEntryPreparation.ts's rung 5) — and it\n // never discovers or forwards conflicts, so the contradiction gate this whole slice wired\n // up is DEAD CODE for ordinary captures; only entries forced/clamped to draft (the `else`\n // branch below) exercise it. Not fixed here because the honest root-fix is materially\n // bigger than everything else in this round: `chain.createEntry` has no `conflicts` arg,\n // and adding one means wiring the contradiction evaluate() gate into\n // createEntryPreparation.ts's status-resolution ladder — a piece of logic with a\n // documented history of subtle defects (PRI-24/DEC-173, \"Capture-Path Integrity Defect\n // A\") across 5 already-audited rungs (deprecated / forceDraft / explicit status /\n // coherency-mode floor / governance default). Inserting a 6th rung there under review-fix\n // time pressure is a worse risk than shipping this gap named and tracked. Follow-up:\n // give `createEntry` its own `conflicts` arg + contradiction gate + `contradictionAdvisory`\n // on its success response (mirroring commitEntry's Slice 2a shape), and discover conflicts\n // BEFORE calling createEntry on this path (both single- and batch-capture) so they can be\n // forwarded.\n if (wasAutoCommittedServerSide) {\n finalStatus = \"committed\";\n await recordSessionActivity({ entryModified: internalId });\n trackChainEntryCommitted(wsCtx.workspaceId, {\n entry_id: finalEntryId,\n collection: resolvedCollection,\n commit_method: \"auto\",\n surface: \"mcp_capture\",\n });\n } else if (shouldAutoCommit && finalEntryId) {\n try {\n // WP-485 Slice 2b (R2, FEAT-1370): discover, never decide — the enforcement decision\n // (was: a local BLOCKING_CONTRADICTION_THRESHOLD comparison, thrown before commitEntry\n // was ever called) now happens ONE place, server-side, inside commitEntry's\n // evaluate()/assessContradiction gate. Discovered conflicts are handed to the server\n // as evidence; the server computes contradictionAdvisory (DEC-1321: advisory only).\n const semanticConflicts = await discoverSemanticConflicts(name, description, resolvedCollection);\n const commitResult = await kernelMutation<GatewayRouteReturnByName<\"chain.commitEntry\">>(\"chain.commitEntry\", {\n entryId: finalEntryId,\n author: agentId ? `agent:${agentId}` : undefined,\n sessionId: agentId ?? undefined,\n ...(semanticConflicts.length > 0 ? { conflicts: semanticConflicts } : {}),\n });\n const refusalReason = coherencyRefusalReason(commitResult);\n if (refusalReason) {\n // WP-465 slice ⑤ (Option B): the entry stays a draft — never accepted/tracked.\n commitError = `coherency gate refused this accept — ${refusalReason}`;\n // WP-465 surface parity: thread full refusal payload so routes + mode reach the caller.\n commitRefusal = commitResultField<Record<string, unknown>>(commitResult, \"refusal\") ?? null;\n finalStatus = \"draft_on_failure\";\n } else {\n finalStatus = commitResultField<string>(commitResult, \"status\") === \"proposal_created\" ? \"proposed\" : \"committed\";\n contradictionAdvisory = commitResultField<ContradictionAdvisory>(commitResult, \"contradictionAdvisory\") ?? null;\n if (finalStatus === \"committed\") {\n await recordSessionActivity({ entryModified: internalId });\n trackChainEntryCommitted(wsCtx.workspaceId, {\n entry_id: finalEntryId,\n collection: resolvedCollection,\n commit_method: \"auto\",\n surface: \"mcp_capture\",\n });\n }\n }\n } catch (e: unknown) {\n // BR-76 S2 — DEC-888: Surface failures via log + payload + session TEN. Never silent.\n commitError = e instanceof Error ? e.message : \"unknown error\";\n finalStatus = \"draft_on_failure\";\n await recordCommitFailure({ entryId: finalEntryId, error: e, sessionId: agentId, server });\n }\n }\n\n // 13. Format response\n const lines: string[] = [\n `# Captured: ${finalEntryId || name}`,\n `**${name}** added to \\`${resolvedCollection}\\` as \\`${finalStatus}\\``,\n `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`,\n ];\n\n if (classifierMeta) {\n lines.push(\"\");\n lines.push(\"## Classification\");\n if (classifierMeta.abstained) {\n lines.push(`No classifier coverage for \\`${resolvedCollection}\\` — entry accepted as-is.`);\n } else if (classifierMeta.autoRouted) {\n lines.push(`Auto-routed to \\`${resolvedCollection}\\` (${classifierMeta.topConfidence}% confidence).`);\n if (classifierMeta.reasons.length > 0) {\n lines.push(`Reason: ${classifierMeta.reasons.join(\"; \")}.`);\n }\n lines.push(`Override: rerun with explicit \\`collection\\` if wrong.`);\n } else if (classifierMeta.agrees) {\n lines.push(`Classifier confirms \\`${resolvedCollection}\\` (${classifierMeta.topConfidence}% confidence).`);\n } else {\n const suggested = classifierMeta.candidates[0]?.collection ?? \"unknown\";\n lines.push(`Classifier suggests \\`${suggested}\\` (${classifierMeta.topConfidence}% confidence) — review classification.`);\n if (classifierMeta.reasons.length > 0) {\n lines.push(`Reason: ${classifierMeta.reasons.join(\"; \")}.`);\n }\n if (classifierMeta.overrideCommand) {\n lines.push(`Override: \\`${classifierMeta.overrideCommand}\\``);\n }\n }\n }\n\n // DEC-70: Cortex link for chain entries (e.g. bets) — structuredContent studioUrl\n const appUrl = process.env.PRODUCTBRAIN_APP_URL ?? \"https://work.productbrain.io\";\n const studioUrl =\n resolvedCollection === \"chains\"\n ? `${appUrl.replace(/\\/$/, \"\")}/w/${wsCtx.workspaceSlug}/legacy/${internalId}`\n : undefined;\n if (studioUrl) {\n lines.push(\"\");\n lines.push(`**View in Cortex:** ${studioUrl}`);\n }\n\n if (linksCreated.length > 0) {\n lines.push(\"\");\n lines.push(`## Auto-linked (${linksCreated.length})`);\n for (const link of linksCreated) {\n const reason = (link as any).linkReason ? ` — because ${(link as any).linkReason}` : \"\";\n lines.push(`- -> **${link.relationType}** ${link.targetEntryId}: ${link.targetName} [${link.targetCollection}]${reason}`);\n }\n }\n\n if (userLinkResults.length > 0) {\n lines.push(\"\");\n lines.push(\"## Requested links\");\n for (const r of userLinkResults) lines.push(`- ${r.label}`);\n }\n\n if (finalStatus === \"committed\") {\n const wasAutoCommitted = autoCommit === undefined && freshGovernanceMode === \"open\";\n lines.push(\"\");\n lines.push(`## Accepted: ${finalEntryId}`);\n if (wasAutoCommitted) {\n lines.push(`**${name}** added to your knowledge base.`);\n } else {\n lines.push(`**${name}** promoted to SSOT on the Chain.`);\n }\n if (await isGoverned(resolvedCollection)) {\n lines.push(`_Note: \\`${resolvedCollection}\\` is a governed collection — ensure this entry has been reviewed._`);\n }\n // WP-485 Slice 2b (R2, FEAT-1370): a high-confidence contradiction never blocks\n // (DEC-1321) but must stay VISIBLE — never a silent success.\n if (contradictionAdvisory) {\n lines.push(\"\");\n lines.push(\"## Contradiction advisory\");\n lines.push(contradictionAdvisory.reason);\n for (const c of contradictionAdvisory.conflictDetails) {\n lines.push(`- \\`${c.chainEntryId}\\` ${c.chainEntryName}: ${c.explanation}`);\n }\n }\n } else if (finalStatus === \"proposed\") {\n lines.push(\"\");\n lines.push(`## Proposal created: ${finalEntryId}`);\n lines.push(`**${name}** requires consent before it can be accepted, so a proposal was created instead of accepting directly.`);\n } else if (commitError) {\n lines.push(\"\");\n lines.push(\"## Accept failed\");\n if (commitRefusal) {\n // WP-465 surface parity: render routes + mode from the structured coherency refusal.\n // MINOR 4: demote to H3 so the embedded refusal sits correctly under the H2 \"## Accept failed\".\n const refusalText = coherencyRefusedResult(\"capture\", finalEntryId, commitRefusal, { headingLevel: 3 }).content[0].text;\n lines.push(...refusalText.split(\"\\n\"));\n lines.push(`Entry saved as draft — use \\`entries action=commit entryId=\"${finalEntryId}\"\\` to promote when ready.`);\n } else {\n lines.push(`Error: ${commitError}. Entry saved as draft — use \\`entries action=commit entryId=\"${finalEntryId}\"\\` to promote when ready.`);\n }\n }\n\n // BET-167: Advisory conflict notice — shown after commit status, never blocking\n if (shouldAutoCommit && conflictCandidates.length > 0) {\n lines.push(\"\");\n lines.push(\"## Potential Overlaps\");\n lines.push(`Auto-accepted with advisory: ${conflictCandidates.length} similar ${conflictCandidates.length === 1 ? \"entry\" : \"entries\"} found.`);\n for (const c of conflictCandidates) {\n lines.push(`- \\`${c.entryId}\\`: ${c.name} [${c.collection}]`);\n }\n lines.push(\"Consider reviewing for duplicates.\");\n }\n\n if (linksSuggested.length > 0) {\n lines.push(\"\");\n lines.push(\"## Suggested links (review and use `relations action=create`)\");\n for (let i = 0; i < linksSuggested.length; i++) {\n const s = linksSuggested[i];\n const preview = s.preview ? ` — ${s.preview}` : \"\";\n lines.push(`${i + 1}. **${s.entryId ?? \"(no ID)\"}**: ${s.name} [${s.collection}]${preview}`);\n }\n }\n\n // WP-318 S2 E4: Grounding report — format:human renders compact summary; format:agent exposes via structuredContent only\n if (format === \"human\") {\n const hasDuplicates = groundingReport.duplicates.length > 0;\n const hasRelated = groundingReport.related.length > 0;\n const hasGov = groundingReport.governance.length > 0;\n if (hasDuplicates || hasRelated || hasGov) {\n lines.push(\"\");\n const parts: string[] = [];\n if (hasDuplicates) parts.push(`${groundingReport.duplicates.length} possible duplicate${groundingReport.duplicates.length > 1 ? \"s\" : \"\"}`);\n if (hasRelated) parts.push(`${groundingReport.related.length} related entr${groundingReport.related.length > 1 ? \"ies\" : \"y\"}`);\n if (hasGov) parts.push(`${groundingReport.governance[0]?.entryId} may govern this`);\n lines.push(`_Grounding: ${parts.join(\", \")}. Review and link if relevant._`);\n }\n }\n\n // BET-289 S2: Field-level writing guidance — shown when collection fields have guidance\n const fieldGuidanceSection = formatFieldGuidance(col.fields ?? []);\n if (fieldGuidanceSection) {\n lines.push(\"\");\n lines.push(fieldGuidanceSection);\n\n // BET-289 S5: Track guidance application for observability (STD-155)\n const guidedFieldCount = (col.fields ?? []).filter((f: { writingGuidance?: string }) => f.writingGuidance).length;\n trackFieldGuidanceApplied(wsCtx.workspaceId, {\n collection: resolvedCollection,\n guided_field_count: guidedFieldCount,\n });\n }\n\n // BET-272 S3: Formative quality hints — advisory, never blocking (BR-144)\n if (formativeHints.length > 0) {\n lines.push(\"\");\n lines.push(\"## Quality Hints (advisory)\");\n for (const hint of formativeHints) {\n lines.push(`- **${hint.field}:** ${hint.hint}`);\n }\n lines.push(`_These hints are advisory — your entry was captured. Use \\`entries action=update entryId=\"${finalEntryId}\"\\` to address them._`);\n }\n\n // BET-272 S5: Advisory relation suggestions from graph (BR-144, STD-147)\n if (relationSuggestionsFromCreate.length > 0) {\n lines.push(\"\");\n lines.push(\"## Suggested Relations (advisory)\");\n for (const rs of relationSuggestionsFromCreate) {\n lines.push(`- **${rs.relationType}** → ${rs.targetEntryId} \"${rs.targetName}\" (confidence: ${rs.confidence})`);\n }\n lines.push(`_Create with: \\`relations action=create fromId=\"${finalEntryId}\" toId=\"TARGET-ID\" type=\"TYPE\"\\`_`);\n }\n\n // TEN-2365: capture-time authority-domain filing — PENDING proposal, never auto-ratified (PAT-251)\n if (authorityDomainFromCreate) {\n lines.push(\"\");\n lines.push(`domain: ${authorityDomainFromCreate.slug} (proposal pending — ratify at session close)`);\n }\n\n // STD-155: Track capture intelligence observability\n if (formativeHints.length > 0) {\n trackCaptureQualityHints(wsCtx.workspaceId, {\n collection: resolvedCollection,\n hint_count: formativeHints.length,\n hint_fields: formativeHints.map((h) => h.field),\n });\n }\n if (relationSuggestionsFromCreate.length > 0) {\n trackCaptureRelationSuggestions(wsCtx.workspaceId, {\n collection: resolvedCollection,\n suggestion_count: relationSuggestionsFromCreate.length,\n relation_types: relationSuggestionsFromCreate.map((rs) => rs.relationType),\n avg_confidence: Math.round(\n relationSuggestionsFromCreate.reduce((sum, rs) => sum + rs.confidence, 0) /\n relationSuggestionsFromCreate.length,\n ),\n });\n }\n\n // Strategy-link warning for bet/goal (ENT-ldomlr: Intelligence Surface)\n const isBetOrGoal =\n isWorkPackageCapture ||\n resolvedCK === \"bet\" ||\n resolvedCK === \"goal\";\n const hasStrategyLink = linksCreated.some((l) => l.targetCollection === \"strategy\");\n if (isBetOrGoal && !hasStrategyLink) {\n lines.push(\"\");\n lines.push(\n `**Strategy link:** This ${isWorkPackageCapture ? \"work package\" : \"goal\"} doesn't connect to any strategy entry. Consider linking before accepting. Use \\`relations action=suggest entryId=\"${finalEntryId}\"\\` to find strategy entries to connect to.`\n );\n await recordSessionActivity({ strategyLinkWarnedForEntryId: internalId });\n }\n\n // Cardinality warning for singleton types (DEC-zcuhvb)\n if (cardinalityWarning) {\n lines.push(\"\");\n lines.push(`**Cardinality warning:** ${cardinalityWarning}`);\n }\n\n // Contradiction warnings — exact format per spec\n if (contradictionWarnings.length > 0) {\n lines.push(\"\");\n lines.push(\"⚠ Contradiction check: proposed entry matched existing governance entries:\");\n for (const w of contradictionWarnings) {\n lines.push(`- ${w.name} (${w.collection}, ${w.entryId}) — has 'governs' relation to ${w.governsCount} entries`);\n }\n lines.push(\"Run `context action=gather` on these entries before accepting.\");\n }\n\n // Validation warnings from createEntry (FEAT-188: MCP Envelope Warnings)\n if (entryWarnings.length > 0) {\n lines.push(\"\");\n lines.push(\"## Validation Warnings\");\n for (const w of entryWarnings) {\n lines.push(`- ${w}`);\n }\n }\n\n // Rubric coaching (assertive/nudge only)\n if (coachingSection) {\n lines.push(\"\");\n lines.push(coachingSection);\n }\n\n // Next steps: adapt based on what was already done\n // WP-480 S1: \"has quality gaps\" is now sourced from the SERVER verdict +\n // advisory formative hints (the deleted client scorecard used to drive this).\n const hasQualityGaps =\n (verdictResult?.verdict != null && verdictResult.verdict.passed === false) ||\n formativeHints.length > 0;\n lines.push(\"\");\n lines.push(\"## Next Steps\");\n const eid = finalEntryId || \"(check entry ID)\";\n if (finalStatus === \"committed\") {\n lines.push(`1. **Connect it:** \\`relations action=suggest entryId=\"${eid}\"\\` — discover additional links`);\n if (hasQualityGaps) {\n lines.push(`2. **Improve quality:** \\`entries action=update entryId=\"${eid}\"\\` — fill missing fields`);\n }\n } else if (finalStatus === \"proposed\") {\n lines.push(`1. **Connect it:** \\`relations action=suggest entryId=\"${eid}\"\\` — discover additional links to support the proposal`);\n if (hasQualityGaps) {\n lines.push(`2. **Improve quality:** \\`entries action=update entryId=\"${eid}\"\\` — strengthen the entry before approval`);\n }\n } else {\n if (userLinkResults.length === 0) {\n lines.push(`1. **Connect it:** \\`relations action=suggest entryId=\"${eid}\"\\` — discover what this should link to`);\n }\n lines.push(`${userLinkResults.length === 0 ? \"2\" : \"1\"}. **Accept it:** \\`entries action=commit entryId=\"${eid}\"\\` — promote from draft to SSOT on the Chain`);\n if (hasQualityGaps) {\n lines.push(`${userLinkResults.length === 0 ? \"3\" : \"2\"}. **Improve quality:** \\`entries action=update entryId=\"${eid}\"\\` — fill missing fields`);\n }\n }\n\n // Advisory: workspace readiness hints (never blocking)\n try {\n const readiness = await kernelQuery<GatewayRouteReturnByName<\"chain.workspaceReadiness\">>(\"chain.workspaceReadiness\");\n if (readiness && readiness.gaps && readiness.gaps.length > 0) {\n const topGaps = readiness.gaps.slice(0, 2);\n lines.push(\"\");\n lines.push(`## Workspace Readiness: ${readiness.score}%`);\n for (const gap of topGaps) {\n lines.push(`- _${gap.label}:_ ${gap.guidance}`);\n }\n }\n } catch {\n // Readiness check is advisory — capture works without it\n }\n\n // Context-sensitive next: adapt based on what was already done\n const next: NextAction[] = [];\n if (finalStatus === \"committed\") {\n next.push({ tool: \"relations\", description: \"Discover connections\", parameters: { action: \"suggest\", entryId: finalEntryId } });\n } else if (finalStatus === \"proposed\") {\n next.push({ tool: \"relations\", description: \"Discover connections\", parameters: { action: \"suggest\", entryId: finalEntryId } });\n } else {\n if (userLinkResults.length === 0) {\n next.push({ tool: \"relations\", description: \"Discover links\", parameters: { action: \"suggest\", entryId: finalEntryId } });\n }\n next.push({ tool: \"entries\", description: \"Accept onto Chain\", parameters: { action: \"commit\", entryId: finalEntryId } });\n }\n\n // WP-480 S1: quality wording comes from the server rubric verdict (single\n // scorer, DEC-1418), not a client N/10 recompute.\n const qualityPhrase = verdictQualityPhrase(verdictResult);\n const summary = finalStatus === \"committed\"\n ? `Captured and accepted ${finalEntryId} (${name}) onto ${resolvedCollection}. ${qualityPhrase}`\n : finalStatus === \"proposed\"\n ? `Captured ${finalEntryId} (${name}) in ${resolvedCollection} and created a proposal for acceptance. ${qualityPhrase}`\n : `Captured ${finalEntryId} (${name}) as draft in ${resolvedCollection}. ${qualityPhrase}`;\n\n const expectedFields = (col.fields ?? []).map((f: any) => ({\n key: f.key, type: f.type, ...(f.required && { required: true }),\n }));\n\n // WP-316 S1a: Build CaptureContract for the EnvelopeSuccess.contract field.\n // Agents can read required fields upfront without a separate round-trip.\n const captureContractForEnvelope = {\n requiredFields: (col.fields ?? []).filter((f) => f.required === true).map((f) => f.key),\n allFields: (col.fields ?? []).map((f) => ({\n key: f.key,\n required: f.required === true,\n type: f.type,\n ...(f.helpText ? { helpText: f.helpText } : {}),\n })),\n ...(col.captureExpectation ? { captureExpectation: col.captureExpectation } : {}),\n };\n\n const totalMs = Date.now() - timingStart;\n const timing = {\n classifyMs: tAfterClassify - timingStart,\n createMs: tAfterCreate - tAfterClassify,\n autoLinkMs: tAfterRelations - tAfterCreate,\n qualityMs: tAfterQuality - tAfterRelations,\n totalMs,\n };\n\n const toolResult = {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: {\n ...success(\n summary,\n {\n entryId: finalEntryId,\n collection: resolvedCollection,\n name,\n status: finalStatus,\n // WP-465 surface parity: thread full refusal (routes + mode) for coherency-refused auto-commits.\n ...(commitRefusal ? { coherencyRefusal: commitRefusal } : {}),\n // WP-485 Slice 2b round 3 (Codex P2, FEAT-1370): mirror the server's contradiction\n // advisory into the structured payload — it was rendered in the human text (the\n // \"## Contradiction advisory\" section above) but silently absent from\n // structuredContent, so a structured-only MCP consumer saw a committed capture\n // with no warning even though the text response carried one.\n ...(contradictionAdvisory ? { contradictionAdvisory } : {}),\n // WP-480 S1: the server verdict rides `qualityVerdict` (named breaking\n // output-contract change, pre-launch).\n qualityVerdict: verdictResult?.verdict\n ? { ...verdictResult.verdict, source: verdictResult.source ?? \"heuristic\" }\n : undefined,\n ...(classifierMeta && { classifier: classifierMeta }),\n ...(studioUrl && { studioUrl }),\n ...(entryWarnings.length > 0 && { warnings: entryWarnings }),\n ...(normalizationMeta && (Object.keys(normalizationMeta.remapped).length > 0 || normalizationMeta.rejected.length > 0) && {\n normalization: {\n remapped: normalizationMeta.remapped,\n rejected: normalizationMeta.rejected,\n },\n }),\n expectedFields,\n // BET-272 S3: Advisory quality hints — always included (empty array when all criteria pass)\n qualityHints: formativeHints,\n // BET-272 S5: Advisory relation suggestions from graph (BR-144, STD-147)\n relationSuggestions: relationSuggestionsFromCreate,\n // TEN-2365: capture-time authority-domain proposal (PENDING ratification), when filed.\n ...(authorityDomainFromCreate && { authorityDomain: authorityDomainFromCreate }),\n // WP-318 S2: Pre-write grounding report — always included (empty arrays when no suggestions)\n groundingReport,\n },\n next,\n ),\n // WP-316 S1a: Populate contract field so agents know required fields upfront.\n contract: captureContractForEnvelope,\n _meta: { timing },\n },\n };\n\n return toolResult;\n}\n\n/**\n * WP-484 S2 (§3): extracted batch-capture handler — reused by the legacy\n * `batch-capture` standalone tool AND the new `capture action=batch`\n * (absorbed per §3 core-nouns table). One business-logic path. TEN-957:\n * each entry may carry inline `relations` created right after capture.\n */\nexport async function handleBatchCapture(\n server: McpServer,\n { entries, autoCommit, preview }: z.infer<typeof batchCaptureSchema>,\n) {\n requireWriteAccess();\n\n const batchTimingStart = Date.now();\n\n const agentId = getAgentSessionId();\n const createdBy = agentId ? `agent:${agentId}` : \"capture\";\n const wsCtx = await getWorkspaceContext();\n // TEN-1810: Refresh governanceMode in case workspace flipped to Open after session start.\n const freshGovernanceModeForBatch = await refreshWorkspaceGovernanceMode();\n const autoCommitApplied = shouldAutoCommitCapture(autoCommit, freshGovernanceModeForBatch);\n\n // ── FEAT-160: Parallel classification for entries without explicit collection ──\n const needsClassification = entries\n .map((e, i) => ({ ...e, index: i }))\n .filter((e) => !e.collection);\n\n let classificationMap = new Map<number, ResolvedCollection | null>();\n if (needsClassification.length > 0) {\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Classifying ${needsClassification.length}/${entries.length} entries via LLM...`,\n logger: \"product-brain\",\n });\n const classifications = await Promise.all(\n needsClassification.map((e) =>\n resolveCollection({ name: e.name, description: e.description }).catch(() => null),\n ),\n );\n for (let i = 0; i < needsClassification.length; i++) {\n classificationMap.set(needsClassification[i].index, classifications[i]);\n }\n }\n\n type BatchEntryResult = {\n // PR #392 round 2 (Codex, finding 2): the ORIGINAL input position, carried\n // explicitly on every result (success or failure) from the moment it's known.\n // NEVER derive an entry's input position via `results.indexOf(...)` later — the\n // chunked pipeline below pushes phase-1 failures and phase-2 (chunk-flush)\n // results in an order that does NOT match `entries`' original order (phase-1\n // failures land immediately, in loop order; phase-2 results land per-chunk,\n // after that chunk's scoring call resolves) — `results.indexOf` on that\n // reordered array silently reports the WRONG input index.\n entryIdx: number;\n name: string;\n collection: string;\n entryId: string;\n ok: boolean;\n autoLinks: number;\n // WP-474 E5: auto-links the judge advised but did NOT write (untypeable).\n advisedLinks: number;\n status: \"draft\" | \"committed\" | \"proposed\" | \"draft_on_failure\";\n classifiedBy?: \"llm\" | \"heuristic\" | \"explicit\";\n confidence?: number;\n confidenceTier?: \"high\" | \"medium\" | \"low\";\n error?: string;\n commitError?: string;\n // WP-465 surface parity: full coherency refusal payload for batch-path refused auto-commits.\n commitRefusal?: Record<string, unknown>;\n warnings?: string[];\n normalization?: { remapped: Record<string, string>; rejected: string[] };\n // BET-167: Number of similar entries found during conflict pre-check\n overlapCount?: number;\n // TEN-2365: capture-time authority-domain proposal (PENDING ratification), when filed.\n authorityDomain?: { slug: string; status: \"proposal-pending\" };\n // TEN-957 (WP-484 S2): inline relations created right after this entry.\n relationsCreated?: number;\n // Finding #14: inline relations that filed an agent proposal instead of writing.\n relationsProposed?: number;\n // WP-577 review follow-up (P2, TEN-2918): the preview branch's own would-block verdict\n // for THIS entry (createEntryPreview.ts's `wouldBlock`/`blockingReason`) — undefined on\n // the real-create path. Lets the batch-preview response separate a would-be-blocked\n // item from the honest `wouldCapture` cohort instead of reporting it as would-succeed.\n wouldBlock?: boolean;\n blockingReason?: string;\n // Fix 1 (WP-577 review re-review, TEN-2918 follow-up): true when this entry's ID was\n // auto-allocated (no caller-supplied `entryId`) rather than exact. Consumed only by the\n // preview projection (lib/batchCaptureOutput.ts) — see that module's WouldCaptureEntry\n // doc comment for why a batch preview cannot report a concrete auto-ID.\n entryIdAssignedAtCapture?: boolean;\n // WP-485 Slice 2b round 2 (Codex P1): the server's per-entry contradiction advisory\n // (DEC-1321 — advisory only, never blocking). Was reaching the intermediate `results`\n // item but silently dropped from the final `captured` projection and had no text\n // rendering — a high-confidence contradiction could commit in a batch with a\n // completely silent response. Declared on the type so both the structured `captured`\n // mapping and the text section below can read it.\n contradictionAdvisory?: ContradictionAdvisory;\n timeoutOutcome?: BatchTimeoutOutcome; }; // WP-575 review (P1, TEN-1126) — gateway timeout, see lib/batchTimeoutCohort.ts.\n const results: BatchEntryResult[] = [];\n // Fix 3 (WP-577 review round 3) + Fix 2/3 (P0 round 4, TEN-2918 follow-up): catches\n // batch-LOCAL duplicate collection+name AND entryId — see lib/batchPreviewDuplicates.ts.\n const previewDupTracker = createBatchPreviewDuplicateTracker();\n type SkippedEntry = {\n index: number;\n name: string;\n suggestedCollection?: string;\n confidence?: number;\n alternatives?: Array<{ collection: string; confidence: number }>;\n };\n const skippedLowConfidence: SkippedEntry[] = [];\n\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Batch capturing ${entries.length} entries...`,\n logger: \"product-brain\",\n });\n\n // BET-281: Use collectionCache instead of direct listCollections call.\n const allCollections = await getCollections();\n const hubSlugs = await populateHubCache();\n const collCache = new Map<string, CollectionDoc>();\n for (const c of allCollections) collCache.set(c.slug, c);\n const collIdToSlug = new Map<string, string>();\n for (const c of allCollections) collIdToSlug.set(c._id, c.slug);\n\n // Lane C S4 + PR #392 rounds 1-2: each entry that reaches search defers its\n // score-dependent work (auto-links, TEN-957 relations, commit, results.push) into\n // `finish`, invoked once its CHUNK (not the whole batch — round 2) has been\n // scored in one chain.scoreLinkCandidates call. `entryIdx`/`entry`/`resolvedSlug`/\n // `classifiedBy`/`confidence`/`confidenceTier` are carried alongside `finish` (not\n // just captured inside its closure) so a chunk-flush catch can build the same\n // failure result shape the original single-phase try/catch used.\n type PendingFinish = {\n // PR #392 round 2, finding 2 — see BatchEntryResult.entryIdx's comment.\n entryIdx: number;\n entry: (typeof entries)[number];\n // By construction, every entry reaching pendingFinish.push() below already\n // passed the `if (!col) { ...; continue; }` collection-resolution guard, so\n // resolvedSlug is always a defined string here (narrowed non-optional\n // deliberately — matches the string the original single-phase catch's\n // `collection: resolvedSlug` field already relied on via control-flow narrowing).\n resolvedSlug: string;\n classifiedBy: \"llm\" | \"heuristic\" | \"explicit\" | undefined;\n confidence: number | undefined;\n confidenceTier: \"high\" | \"medium\" | \"low\" | undefined;\n job: LinkScoreJob | null;\n finish: (scores: LinkScoreResult[]) => Promise<void>;\n };\n\n /**\n * PR #392 round 2 (Codex, findings 3+4 — chunked pipeline): scores and finishes\n * exactly ONE chunk. Called synchronously (awaited) from inside the main entries\n * loop below, so the NEXT chunk's entries never start their `createEntry` until\n * THIS chunk's relation writes (`finish`) have completed — restores write\n * interleaving (a large batch no longer queues 100 creates before the first\n * relation write) while keeping scoring calls bounded (~5 per 50-entry batch at\n * the default chunk size, vs. 50 before round 1's fix and 1 unbounded-payload call\n * before this round's chunking).\n */\n async function flushPendingChunk(chunk: PendingFinish[]): Promise<void> {\n if (chunk.length === 0) return;\n const jobsToScore = chunk.filter((p) => p.job !== null).map((p) => p.job as LinkScoreJob);\n let scoreResultsByJob: LinkScoreResult[][] = [];\n if (jobsToScore.length > 0) {\n try {\n scoreResultsByJob = await kernelQuery<GatewayRouteReturnByName<\"chain.scoreLinkCandidates\">>(\"chain.scoreLinkCandidates\", {\n collMap: Object.fromEntries(collIdToSlug),\n hubSlugs: [...hubSlugs],\n jobs: jobsToScore,\n });\n } catch {\n // Whole-CHUNK scoring call failed — every entry in this chunk was already\n // created; none of them get auto-links this round (same \"entry still\n // created\" fail-open semantics the original per-entry try/catch had).\n scoreResultsByJob = jobsToScore.map(() => []);\n }\n }\n let scoreCursor = 0;\n for (const pending of chunk) {\n const scores = pending.job !== null ? (scoreResultsByJob[scoreCursor++] ?? []) : [];\n try {\n await pending.finish(scores);\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n results.push(buildBatchEntryFailure({\n entryIdx: pending.entryIdx, name: pending.entry.name, collection: pending.resolvedSlug,\n classifiedBy: pending.classifiedBy, confidence: pending.confidence, confidenceTier: pending.confidenceTier,\n error: msg,\n }));\n }\n }\n }\n\n let pendingFinish: PendingFinish[] = [];\n let chunkBytes = 0;\n\n for (let entryIdx = 0; entryIdx < entries.length; entryIdx++) {\n const entry = entries[entryIdx];\n\n if (entryIdx > 0 && entryIdx % 5 === 0) {\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Captured ${entryIdx}/${entries.length} entries...`,\n logger: \"product-brain\",\n });\n }\n\n // ── Resolve collection: explicit or classified ──\n let resolvedSlug: string | undefined = entry.collection;\n let classifiedBy: \"llm\" | \"heuristic\" | \"explicit\" | undefined;\n let confidence: number | undefined;\n let confidenceTier: \"high\" | \"medium\" | \"low\" | undefined;\n\n if (resolvedSlug) {\n classifiedBy = \"explicit\";\n } else {\n const resolved = classificationMap.get(entryIdx);\n // BET-288 S0: Fire confusion telemetry for batch classifications\n if (resolved) {\n emitClassificationTelemetry(resolved, wsCtx.workspaceId, {\n explicitCollectionProvided: false,\n autoRouted: resolved.tier !== \"low\",\n });\n }\n if (!resolved || resolved.tier === \"low\") {\n skippedLowConfidence.push({\n index: entryIdx,\n name: entry.name,\n suggestedCollection: resolved?.collection,\n confidence: resolved?.confidence,\n alternatives: resolved?.alternatives.slice(0, 3),\n });\n continue;\n }\n resolvedSlug = resolved.collection;\n classifiedBy = resolved.classifiedBy;\n confidence = resolved.confidence;\n confidenceTier = resolved.tier;\n }\n\n const profile = await getProfile(resolvedSlug);\n const col = collCache.get(resolvedSlug);\n\n if (!col) {\n results.push(buildBatchEntryFailure({\n entryIdx, name: entry.name, collection: resolvedSlug, classifiedBy, confidence, confidenceTier,\n error: `Collection \"${resolvedSlug}\" not found`,\n }));\n continue;\n }\n\n // BR-111: entryId only allowed for business-rules and standards\n if (entry.entryId && resolvedSlug !== \"business-rules\" && resolvedSlug !== \"standards\") {\n results.push(buildBatchEntryFailure({\n entryIdx, name: entry.name, collection: resolvedSlug, classifiedBy, confidence, confidenceTier,\n // BR-111\n error: `entryId only allowed for business-rules and standards. Omit for ${resolvedSlug}.`,\n }));\n continue;\n }\n\n const data = buildDataFromFields(col.fields ?? [], profile.descriptionField, entry.description);\n\n for (const def of profile.defaults) {\n if (def.value !== \"infer\" && def.value !== \"today\") data[def.key] = def.value;\n }\n\n if (profile.inferField) {\n const inferred = profile.inferField({\n collection: resolvedSlug, name: entry.name, description: entry.description,\n data, entryId: \"\", linksCreated: [], linksSuggested: [], collectionFields: col.fields ?? [],\n });\n for (const [key, val] of Object.entries(inferred)) {\n if (val !== undefined && val !== \"\") data[key] = val;\n }\n }\n\n if (isEmptyValue(data.date)) {\n const inferredSourceDate = inferSourceDate(entry.name, entry.description);\n if (inferredSourceDate && (col.fields ?? []).some((field) => field.key === \"date\")) {\n data.date = inferredSourceDate;\n }\n }\n\n if (!data[profile.descriptionField] && !data.description && !data.canonical) {\n data[profile.descriptionField || \"description\"] = entry.description;\n }\n\n if (entry.data && typeof entry.data === \"object\") {\n for (const [k, v] of Object.entries(entry.data)) {\n if (v !== undefined && v !== null && v !== \"\") data[k] = v;\n }\n }\n\n // DEC-231: work-packages collection is canonical — collection slug is the sole discriminator\n // DEC-313 GAP 2: also detect work package via canonicalKey from batch input\n const batchIsBet = resolvedSlug === \"work-packages\" || entry.canonicalKey === \"work_package\";\n // BET-288: derive strategy check from thinkingLayer instead of hardcoded slug\n const batchIsStrategy = col?.thinkingLayer === \"strategy\";\n const shouldDecomposeBatch =\n (batchIsStrategy || batchIsBet) && entry.description?.trim();\n let batchDecomposeWarning: string | undefined;\n if (shouldDecomposeBatch) {\n try {\n const decomposed = await kernelCall<GatewayRouteReturnByName<\"chain.decomposeContent\">>(\n \"chain.decomposeContent\",\n {\n collectionSlug: resolvedSlug,\n entryName: entry.name,\n description: entry.description,\n existingData: data,\n ...(batchIsBet ? { canonicalKey: \"work_package\" } : {}),\n ...(col?.thinkingLayer ? { thinkingLayer: col.thinkingLayer } : {}),\n },\n );\n if (decomposed?.decomposed) {\n for (const [key, val] of Object.entries(decomposed.decomposed)) {\n if (isEmptyValue(data[key]) && isNonEmptyValue(val)) {\n data[key] = val;\n }\n }\n }\n } catch {\n batchDecomposeWarning = \"Content decomposition skipped (transient error). Entry saved with description only.\";\n }\n }\n canonicalizeSelects(data, col.fields ?? [], batchIsBet);\n\n // BET-132: bet captures keep flat fields — no data.links wrapping\n\n // Fix 2/3 (P0 round 4, TEN-2918 follow-up): batch-local entryId + name duplicate checks.\n const previewDuplicate = checkBatchPreviewDuplicate(previewDupTracker, {\n preview, entryIdx, name: entry.name, collection: resolvedSlug,\n callerEntryId: entry.entryId, classifiedBy, confidence, confidenceTier,\n });\n if (previewDuplicate) { results.push(previewDuplicate); continue; }\n\n try {\n const rawResult = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntry\">>(\"chain.createEntry\", {\n collectionSlug: resolvedSlug,\n entryId: entry.entryId ?? undefined,\n name: entry.name,\n // DEC-896 / BR-76: omit status — server resolves from governanceMode (Open→active, else draft).\n data,\n createdBy,\n sessionId: agentId ?? undefined,\n canonicalKey: entry.canonicalKey ?? undefined,\n // BR-76 S2: Distinguish batch provenance in retrospective metrics (path a).\n originDetailOverride: \"mcp-batch-capture\",\n ...(entry.sourceRef ? { sourceRef: entry.sourceRef } : {}),\n ...(entry.sourceExcerpt ? { sourceExcerpt: entry.sourceExcerpt } : {}),\n ...(preview ? { preview: true } : {}),\n // WP-513 review round 3 (P1): rung-2 owner — no-op pre-rung-2.\n ...(entry.ownerTeamEntryId ? { ownerTeamEntryId: entry.ownerTeamEntryId } : {}),\n ...(entry.ownerRoleEntryId ? { ownerRoleEntryId: entry.ownerRoleEntryId } : {}),\n });\n\n // WP-577 / TEN-2918: `preview` now genuinely reaches this route — before this fix\n // every batch `preview: true` call threw ArgumentValidationError before this point,\n // so the code below always ran against a real create. It was ALREADY written to\n // tolerate a preview create for the parts that matter (inline relations forward\n // `preview` themselves ~2 screens down, and `batchWasAutoCommittedServerSide` reads\n // `result.status`, which is simply absent — hence `false` — on a preview result,\n // so the auto-commit block's condition already excluded it structurally EXCEPT for\n // one gap: `autoCommitApplied` on its own doesn't know about `preview`, so it would\n // fire a REAL `chain.commitEntry` against an entry that was never actually created —\n // fixed below at the `!preview` guard, ~2 screens down (Codex-shape bug this fix\n // would otherwise have introduced, since preview batch capture always errored before\n // reaching here). `result.docId`/`result.status` are read as if always present below\n // (pre-existing, unchanged) — safe because `docId` is only consumed inside the\n // `batchWasAutoCommittedServerSide` guard (false for preview) and `status` itself is\n // simply undefined (not a crash) on this route's preview branch.\n //\n // WP-577 review follow-up (P2, TEN-2918): read the preview union's wouldBlock/\n // blockingReason BEFORE the cast below discards that member — see\n // extractPreviewWouldBlock in lib/createEntryPreviewResult.ts for the full reasoning.\n const previewWouldBlock = extractPreviewWouldBlock(rawResult, preview);\n // P0 round 4 (fix 1/3, root): see resolveEffectiveCollection's doc comment\n // (lib/createEntryPreviewResult.ts) — reported in this entry's own result below, and\n // fed to reconcileBatchPreviewDuplicate (fix 2/3, lib/batchPreviewDuplicates.ts).\n const effectiveCollection = resolveEffectiveCollection(rawResult, preview, resolvedSlug);\n const result = rawResult as Exclude<typeof rawResult, { preview: true }>;\n\n const postRoutingDuplicate = reconcileBatchPreviewDuplicate(previewDupTracker, {\n wouldCapture: Boolean(preview && previewWouldBlock && !previewWouldBlock.wouldBlock),\n effectiveCollection, entryIdx, name: entry.name, callerEntryId: entry.entryId,\n classifiedBy, confidence, confidenceTier,\n });\n if (postRoutingDuplicate) { results.push(postRoutingDuplicate); continue; }\n\n const internalId = result.docId;\n const finalEntryId = result.entryId;\n const batchEntryWarnings = [\n ...(batchDecomposeWarning ? [batchDecomposeWarning] : []),\n ...(result.warnings ?? []),\n ];\n // WP-577 / TEN-2918 follow-up (P1): a preview never wrote `result.entryId` — resolving\n // gaps against it would mark a real knowledge gap resolved via a `gaps.resolve`\n // mutation against an entryId that doesn't exist in the DB. Matches the `!preview`\n // guard on the auto-commit block below.\n if (!preview) resolveGapsForEntry(entry.name, result.entryId);\n // DEC-896 / BR-76 S3: server already committed (Open mode auto-commit). Skip commitEntry.\n // KNOWN GAP (WP-485 Slice 2b round 4, Codex P1, FEAT-1370 — DEFERRED): same gap as the\n // single-capture path above (~line 1813) — this is the main auto-commit case and it\n // never discovers/forwards conflicts. See that comment for the full reasoning.\n const batchWasAutoCommittedServerSide = result.status === \"active\";\n let finalStatus: \"draft\" | \"committed\" | \"proposed\" | \"draft_on_failure\" = batchWasAutoCommittedServerSide ? \"committed\" : \"draft\";\n let commitError: string | undefined;\n // WP-465 surface parity: full refusal payload for coherency-refused batch auto-commits.\n let commitRefusal: Record<string, unknown> | undefined;\n // WP-485 Slice 2b (R2, FEAT-1370): the server's typed advisory, when commitEntry's\n // contradiction gate found a high-confidence match (DEC-1321 — advisory only).\n let contradictionAdvisory: ContradictionAdvisory | undefined;\n if (batchWasAutoCommittedServerSide) {\n await recordSessionActivity({ entryModified: internalId });\n trackChainEntryCommitted(wsCtx.workspaceId, {\n entry_id: finalEntryId,\n collection: resolvedSlug ?? undefined,\n commit_method: \"auto\",\n surface: \"mcp_capture\",\n });\n }\n\n // Lane C S4 + PR #392 rounds 1-2: search stays PER-ENTRY (it needs\n // finalEntryId, only known here) but SCORING is deferred — this entry's job\n // (if it has candidates) is collected into `pendingFinish` below and scored\n // once its CHUNK is flushed (see flushPendingChunk above), never one call per\n // entry.\n //\n // PR #392 round 2 (finding 5 — memory): project each search-result candidate\n // to the MINIMAL shape needed downstream IMMEDIATELY — the batch flow never\n // consumes a candidate's `data` (no preview text built here, unlike the\n // single-capture flow), so the raw search-result docs (which can carry large\n // `data` blobs) are never retained past this block, not even across the\n // deferred `finish` closure below.\n let candidatesFiltered: Array<{ name: string; entryId?: string; collectionId: string }> = [];\n let job: LinkScoreJob | null = null;\n const searchQuery = extractSearchTerms(entry.name, entry.description);\n if (searchQuery) {\n try {\n const searchResults = await kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: searchQuery });\n candidatesFiltered = (searchResults ?? [])\n .filter((r) => r.entryId !== finalEntryId)\n .map((r) => ({\n name: r.name as string,\n entryId: r.entryId as string | undefined,\n collectionId: r.collectionId as string,\n }));\n if (candidatesFiltered.length > 0) {\n job = buildScoreLinkCandidatesJob(\n candidatesFiltered.map((r) => ({ name: r.name, collectionId: r.collectionId })),\n entry.name,\n entry.description,\n resolvedSlug!,\n );\n }\n } catch { /* search failed; entry still created, candidatesFiltered stays empty */ }\n }\n\n // PR #392 round 3 (Codex P2): check BEFORE appending this entry to the\n // current chunk, not after. Checking after (the round-2 shape) let a chunk\n // SHIP over the byte bound: a chunk sitting just under LINK_SCORE_CHUNK_MAX_BYTES\n // plus one more large job's bytes still got flushed as ONE oversized request —\n // the check only ever caught the NEXT entry, one job too late. Flush the\n // EXISTING chunk first (without this entry) when either bound would be\n // exceeded, then start a fresh chunk with this entry.\n //\n // A single job that ALONE exceeds LINK_SCORE_CHUNK_MAX_BYTES still ships as\n // its own one-job chunk — `pendingFinish.length > 0` guards the flush-first\n // branch below, so an EMPTY pending chunk never flushes itself just to stay\n // under budget (there is no way to split candidates WITHIN one job without\n // breaking that entry's scoring as a unit). The gateway's own per-string 10KB\n // `validateArgLengths` check is the backstop for this specific edge case (an\n // entry whose search returns enough long candidate names to itself approach\n // ~700KB is not something this chunk boundary can prevent — LINK_SCORE_CHUNK_MAX_BYTES\n // bounds the chunk, not any single job).\n const prospectiveJobBytes = job ? estimateJobBytes(job) : 0;\n if (\n pendingFinish.length > 0 &&\n (pendingFinish.length >= LINK_SCORE_CHUNK_MAX_ENTRIES ||\n chunkBytes + prospectiveJobBytes > LINK_SCORE_CHUNK_MAX_BYTES)\n ) {\n await flushPendingChunk(pendingFinish);\n pendingFinish = [];\n chunkBytes = 0;\n }\n\n // Everything below depends on this entry's scores (not known until this\n // entry's CHUNK is flushed) — deferred as a closure that captures every local\n // variable it needs (finalEntryId, resolvedSlug, batchEntryWarnings, etc.) by\n // normal lexical scoping, invoked from flushPendingChunk.\n pendingFinish.push({\n entryIdx, entry, resolvedSlug, classifiedBy, confidence, confidenceTier,\n job,\n finish: async (scores: LinkScoreResult[]) => {\n let autoLinkCount = 0;\n // WP-474 E5: auto-links the judge advised but did NOT write (untypeable) — per-entry tally.\n let advisedLinkCount = 0;\n // BET-167: Track overlaps from search results for conflict advisory\n let entryOverlapCount = 0;\n\n if (candidatesFiltered.length > 0) {\n try {\n // Server returns results already sorted by score descending; the\n // `reason` field is a superset this call site simply doesn't consume\n // (it never carried confidenceReason pre-migration either — no-op for it).\n const candidates = scores.map((s) => {\n const r = candidatesFiltered[s.index];\n return { ...r, collSlug: collIdToSlug.get(r.collectionId) ?? \"unknown\", confidence: s.score };\n });\n\n // BET-167: Count similar entries for conflict pre-check (reuses search, no extra query)\n entryOverlapCount = candidates.filter((c) => c.entryId).length;\n\n // WP-474 E4-REWIRE: batch auto-links carry provenance + confidence like the single path.\n const batchAutoLinks: Array<{ fromEntryId: string; toEntryId: string; type: string; proposedBy: string; confidence: number }> = [];\n for (const c of candidates) {\n if (batchAutoLinks.length >= MAX_AUTO_LINKS) break;\n if (c.confidence < AUTO_LINK_CONFIDENCE_THRESHOLD) break;\n if (!c.entryId) continue;\n const { type: relationType } = inferRelationType(resolvedSlug!, c.collSlug, profile);\n batchAutoLinks.push({ fromEntryId: finalEntryId, toEntryId: c.entryId, type: relationType, proposedBy: \"auto-link\", confidence: c.confidence });\n }\n\n if (batchAutoLinks.length > 0 && preview) {\n // Finding #13: chain.createEntryRelations (the batch/plural mutation) has\n // NO preview arg — unlike the singular chain.createEntryRelation used just\n // below. A previewed createEntry (preview:true, no DB write) was still\n // followed by a REAL relation write here whenever matching targets existed.\n // Skip the write entirely in preview mode; report what would happen instead.\n batchEntryWarnings.push(`${batchAutoLinks.length} auto-link(s) would be created (preview — no DB writes).`);\n } else if (batchAutoLinks.length > 0) {\n const batchRes = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelations\">>(\"chain.createEntryRelations\", {\n relations: batchAutoLinks, sessionId: agentId ?? undefined,\n });\n autoLinkCount = batchRes.created;\n // WP-474 E5: surface auto-links the judge advised but did not write — never silently dropped.\n advisedLinkCount = batchRes.advised ?? 0;\n if (advisedLinkCount > 0) {\n batchEntryWarnings.push(`${advisedLinkCount} auto-link(s) advised, not written (untypeable) — accept with \\`relations action=create\\` to promote.`);\n }\n }\n } catch { /* batch link failed; entry still created */ }\n }\n\n // TEN-957 (WP-484 S2): inline per-item relations — validate-all-then-apply\n // (PAT-268 item 1) against the ALREADY-VALIDATED batchCaptureRelationSchema\n // shape (zod validated every item's {to, type} before this handler ran);\n // apply here means \"create against the kernel,\" not \"shape validation.\"\n // Fix 2 (WP-577 review re-review, TEN-2918 follow-up): extracted to\n // lib/batchInlineRelations.ts — a preview batch's source entry was never\n // persisted, so `chain.createEntryRelation` unconditionally threw NOT_FOUND on\n // `fromEntryId` (relations.ts:69-80 resolves it BEFORE any preview branch). See\n // that module's doc comment for the full reasoning.\n const {\n relationsCreatedCount, relationsProposedCount, relationsNotValidatedCount, relationsFailedList,\n } = await applyBatchInlineRelations(entry.relations, finalEntryId, preview, agentId);\n if (relationsFailedList.length > 0) {\n batchEntryWarnings.push(`${relationsFailedList.length} inline relation(s) failed: ${relationsFailedList.join(\"; \")}`);\n }\n // Fix 4 (WP-577 review round 3, TEN-2918 follow-up): never promise these would be\n // created — target existence and relation policy (`governs` authorization,\n // `guardRelation`) are only checked at real capture, not here.\n if (relationsNotValidatedCount > 0) {\n batchEntryWarnings.push(`${relationsNotValidatedCount} inline relation(s) not validated in preview (target existence and relation policy are checked at capture).`);\n }\n if (relationsProposedCount > 0) {\n batchEntryWarnings.push(`${relationsProposedCount} inline relation(s) converted to an agent proposal (misuse pattern) — review in Cortex UI.`);\n }\n\n // DEC-896 / BR-76 S3: skip commitEntry when server already returned active.\n // WP-577 / TEN-2918: also skip on `preview` — `autoCommitApplied` doesn't know\n // about preview mode on its own, and without this guard a preview batch capture\n // would fire a REAL `chain.commitEntry` mutation against an entry that was never\n // actually created (createEntry's own preview branch never wrote a doc). This\n // path was unreachable before this slice (preview batch calls always threw\n // ArgumentValidationError before getting this far), so it's a latent bug this\n // fix would otherwise have newly exposed, not a regression in existing behavior.\n if (!preview && autoCommitApplied && !batchWasAutoCommittedServerSide) {\n try {\n // WP-485 Slice 2b (R2, FEAT-1370): discover, never decide — see the single-entry\n // auto-commit path above for the full rationale. The enforcement decision now\n // happens ONE place, server-side, inside commitEntry's gate.\n const semanticConflicts = await discoverSemanticConflicts(entry.name, entry.description, resolvedSlug);\n const commitResult = await kernelMutation<GatewayRouteReturnByName<\"chain.commitEntry\">>(\"chain.commitEntry\", {\n entryId: finalEntryId,\n author: agentId ? `agent:${agentId}` : undefined,\n sessionId: agentId ?? undefined,\n ...(semanticConflicts.length > 0 ? { conflicts: semanticConflicts } : {}),\n });\n const refusalReason = coherencyRefusalReason(commitResult);\n if (refusalReason) {\n // WP-465 slice ⑤ (Option B): the entry stays a draft — never accepted/tracked.\n commitError = `coherency gate refused this accept — ${refusalReason}`;\n // WP-465 surface parity: thread full refusal payload so routes + mode reach the caller.\n commitRefusal = commitResultField<Record<string, unknown>>(commitResult, \"refusal\") ?? undefined;\n finalStatus = \"draft_on_failure\";\n } else {\n finalStatus = commitResultField<string>(commitResult, \"status\") === \"proposal_created\" ? \"proposed\" : \"committed\";\n contradictionAdvisory = commitResultField<ContradictionAdvisory>(commitResult, \"contradictionAdvisory\") ?? undefined;\n if (finalStatus === \"committed\") {\n await recordSessionActivity({ entryModified: internalId });\n trackChainEntryCommitted(wsCtx.workspaceId, {\n entry_id: finalEntryId,\n collection: resolvedSlug ?? undefined,\n commit_method: \"auto\",\n surface: \"mcp_capture\",\n });\n }\n }\n } catch (error: unknown) {\n // BR-76 S2 — DEC-888: Surface failures via log + payload + session TEN. Never silent.\n commitError = error instanceof Error ? error.message : String(error);\n finalStatus = \"draft_on_failure\";\n await recordCommitFailure({ entryId: finalEntryId, error, sessionId: agentId, server });\n }\n }\n\n // Server declares `normalization: Record<string, unknown> | null` (looser than\n // this file's own consumption shape) — same documented convention as the\n // single-capture path above (PR #395, Lane C S3b annotation pass).\n const entryNorm = result.normalization as\n | { remapped: Record<string, string>; rejected: string[] }\n | null\n | undefined;\n results.push({\n entryIdx,\n name: entry.name,\n // P0 round 4 (fix 1/3, root): EFFECTIVE (post-routing) collection — see\n // `effectiveCollection`'s declaration above, ~2 screens up.\n collection: effectiveCollection,\n entryId: finalEntryId,\n ok: true,\n autoLinks: autoLinkCount,\n advisedLinks: advisedLinkCount,\n status: finalStatus,\n classifiedBy,\n confidence,\n confidenceTier,\n ...(previewWouldBlock ? { wouldBlock: previewWouldBlock.wouldBlock } : {}),\n ...(previewWouldBlock?.blockingReason ? { blockingReason: previewWouldBlock.blockingReason } : {}),\n // Fix 1 (TEN-2918 follow-up): not caller-supplied — the preview projection\n // must not report this predicted-but-duplicable ID as concrete.\n ...(!entry.entryId ? { entryIdAssignedAtCapture: true } : {}),\n ...(commitError ? { commitError } : {}),\n // WP-465 surface parity: thread full refusal payload for coherency-refused batch entries.\n ...(commitRefusal ? { commitRefusal } : {}),\n // WP-485 Slice 2b (R2, FEAT-1370): the server's contradiction advisory (DEC-1321 —\n // advisory only, never blocking) — visible, never a silent success.\n ...(contradictionAdvisory ? { contradictionAdvisory } : {}),\n ...(batchEntryWarnings.length > 0 ? { warnings: batchEntryWarnings } : {}),\n ...(entryNorm && (Object.keys(entryNorm.remapped).length > 0 || entryNorm.rejected.length > 0) && {\n normalization: { remapped: entryNorm.remapped, rejected: entryNorm.rejected },\n }),\n // BET-167: Track overlap count for conflict advisory\n ...(entryOverlapCount > 0 ? { overlapCount: entryOverlapCount } : {}),\n // TEN-2365: capture-time authority-domain proposal echo.\n ...(result.authorityDomain ? { authorityDomain: result.authorityDomain } : {}),\n // TEN-957 (WP-484 S2): inline relations created for this entry.\n ...(relationsCreatedCount > 0 ? { relationsCreated: relationsCreatedCount } : {}),\n // Finding #14: distinct from relationsCreated — never counted as a write.\n ...(relationsProposedCount > 0 ? { relationsProposed: relationsProposedCount } : {}),\n });\n },\n });\n\n // This entry's job is now part of the (possibly just-flushed-and-fresh)\n // current chunk — track its bytes for the NEXT entry's before-append check\n // above. Flushing happens inside the loop (the check above, before push), so\n // chunk N+1's `createEntry` always waits for chunk N's `finish` (relation\n // writes) to complete first — the for-loop is sequential and that flush call\n // is awaited.\n if (job) chunkBytes += prospectiveJobBytes;\n } catch (error: unknown) {\n results.push(buildBatchEntryFailure({\n entryIdx, name: entry.name, collection: resolvedSlug, classifiedBy, confidence, confidenceTier,\n ...describeBatchEntryOutcome(error, entry.name), // WP-575 review (P1, TEN-1126) — see lib/batchTimeoutCohort.ts.\n }));\n }\n }\n\n // Flush any remaining partial chunk (fewer than LINK_SCORE_CHUNK_MAX_ENTRIES\n // entries, under the byte bound) once the loop finishes.\n await flushPendingChunk(pendingFinish);\n\n const created = results.filter((r) => r.ok);\n const { failed, unknownOutcome: unknownOutcomeEntries } = splitBatchNotOk(results.filter((r) => !r.ok)); // WP-575 review (P1, TEN-1126) — see lib/batchTimeoutCohort.ts.\n const committed = created.filter((r) => r.status === \"committed\");\n const proposed = created.filter((r) => r.status === \"proposed\");\n const drafts = created.filter((r) => r.status === \"draft\");\n const commitFailed = created.filter((r) => r.status === \"draft_on_failure\");\n const classifiedCount = created.filter((r) => r.classifiedBy && r.classifiedBy !== \"explicit\").length;\n\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Batch complete. ${created.length} succeeded, ${failed.length} failed, ${skippedLowConfidence.length} skipped (low confidence).`,\n logger: \"product-brain\",\n });\n\n // WP-577 / TEN-2918 follow-up: everything below builds the REAL-create surface —\n // \"# Batch Capture Complete\", per-entry `status: \"draft\"`, and a `next` offering\n // `entries action=commit` on an entryId a preview never wrote. handleCapture's\n // single path returns a dedicated preview envelope for exactly this reason; batch\n // had none, so a preview batch reported itself as a successful capture. Return the\n // honest envelope here, before any of that shaping. See lib/batchCaptureOutput.ts.\n // WP-577 review follow-up (P2, TEN-2918): cohort-splitting + mapping (wouldCapture vs.\n // wouldBlock, failed, skipped) now lives in buildBatchPreviewFromResults, alongside the\n // preview contract it feeds (lib/batchCaptureOutput.ts) — STD-2 / DEC-1504 shrink-only.\n if (preview) {\n return buildBatchPreviewFromResults(created, failed, skippedLowConfidence, entries.length, entries, autoCommit);\n }\n\n const totalAutoLinks = created.reduce((sum, r) => sum + r.autoLinks, 0);\n // WP-474 E5: aggregate advised-not-written cohort across the batch — never silently dropped.\n const totalAdvisedLinks = created.reduce((sum, r) => sum + r.advisedLinks, 0);\n\n const byCollection = new Map<string, number>();\n for (const r of created) {\n byCollection.set(r.collection, (byCollection.get(r.collection) ?? 0) + 1);\n }\n\n const lines: string[] = [\n `# Batch Capture Complete`,\n `**${created.length}** created, **${failed.length}** failed, **${skippedLowConfidence.length}** skipped out of ${entries.length} total.`,\n `**Auto-links created:** ${totalAutoLinks}${totalAdvisedLinks > 0 ? `, ${totalAdvisedLinks} advised` : \"\"}`,\n \"\",\n ];\n\n if (classifiedCount > 0) {\n lines.push(`**Auto-classified:** ${classifiedCount} entries routed by LLM/heuristic.`);\n lines.push(\"\");\n }\n\n if (created.length > 0) {\n const commitFailedSegment = commitFailed.length > 0 ? `, ${commitFailed.length} commit-failed` : \"\";\n lines.push(\n `**Statuses:** ${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft${commitFailedSegment}.`,\n );\n lines.push(\"\");\n }\n\n if (byCollection.size > 0) {\n lines.push(\"## By Collection\");\n for (const [col, count] of byCollection) {\n lines.push(`- \\`${col}\\`: ${count} entries`);\n }\n lines.push(\"\");\n }\n\n if (created.length > 0) {\n const highConfidence = created.filter((r) => r.confidenceTier === \"high\" || r.classifiedBy === \"explicit\");\n const mediumConfidence = created.filter((r) => r.confidenceTier === \"medium\");\n\n if (highConfidence.length > 0) {\n lines.push(\"## Created — High Confidence / Explicit\");\n for (const r of highConfidence) {\n const linkNote = r.autoLinks > 0 ? `, ${r.autoLinks} auto-links` : \"\";\n const classNote = r.classifiedBy !== \"explicit\" ? ` (${r.classifiedBy} ${r.confidence}%)` : \"\";\n lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] — \\`${r.status}\\`${classNote}${linkNote}`);\n }\n }\n\n if (mediumConfidence.length > 0) {\n lines.push(\"\");\n lines.push(\"## Created — Medium Confidence (review recommended)\");\n for (const r of mediumConfidence) {\n const linkNote = r.autoLinks > 0 ? `, ${r.autoLinks} auto-links` : \"\";\n lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] — \\`${r.status}\\` (${r.classifiedBy} ${r.confidence}%)${linkNote}`);\n }\n lines.push(`\\n_Use \\`entries action=move\\` to correct any misclassified entries._`);\n }\n }\n\n if (skippedLowConfidence.length > 0) {\n lines.push(\"\");\n lines.push(\"## Skipped — Low Confidence (needs explicit collection)\");\n for (const s of skippedLowConfidence) {\n const suggestion = s.suggestedCollection\n ? ` — best guess: \\`${s.suggestedCollection}\\` (${s.confidence}%)`\n : \" — no classification available\";\n const alts = s.alternatives?.length\n ? ` | alternatives: ${s.alternatives.map((a) => `\\`${a.collection}\\` (${a.confidence}%)`).join(\", \")}`\n : \"\";\n lines.push(`- **[${s.index}]** ${s.name}${suggestion}${alts}`);\n }\n lines.push(\"\");\n lines.push(\"_Re-capture these with an explicit `collection` or use the suggested collection._\");\n }\n\n if (commitFailed.length > 0) {\n lines.push(\"\");\n lines.push(\"## Saved as draft\");\n for (const r of commitFailed) {\n if (r.commitRefusal) {\n // WP-465 surface parity: mirror the single path — the refusal block already leads with\n // the reason, so DROP commitError from the bullet (it embeds the same reason → no double\n // print). Render the block at top level (NOT indented — indenting turns the `##`/`###`\n // headings into a code block) and demote the leading heading to H3.\n lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}]`);\n const refusalText = coherencyRefusedResult(\"batch-capture\", r.entryId ?? \"\", r.commitRefusal, { headingLevel: 3 }).content[0].text;\n lines.push(...refusalText.split(\"\\n\"));\n } else {\n lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] — ${r.commitError}`);\n }\n }\n }\n\n // WP-485 Slice 2b round 2 (Codex P1, FEAT-1370): surface the server's per-entry\n // contradiction advisory in the batch response text — a high-confidence contradiction\n // committing with no visible trace is exactly the silent-success failure R2 exists to\n // prevent (mirrors the single-entry \"## Contradiction advisory\" section above).\n const entriesWithContradictionAdvisory = created.filter((r) => r.contradictionAdvisory);\n if (entriesWithContradictionAdvisory.length > 0) {\n lines.push(\"\");\n lines.push(\"## Contradiction Advisories\");\n for (const r of entriesWithContradictionAdvisory) {\n lines.push(`- **${r.entryId}**: ${r.name} — ${r.contradictionAdvisory!.reason}`);\n for (const c of r.contradictionAdvisory!.conflictDetails) {\n lines.push(` - \\`${c.chainEntryId}\\` ${c.chainEntryName}: ${c.explanation}`);\n }\n }\n }\n\n // BET-167: Advisory overlap notice for batch entries with potential duplicates\n if (autoCommitApplied) {\n const entriesWithOverlaps = created.filter((r) => r.overlapCount && r.overlapCount > 0);\n if (entriesWithOverlaps.length > 0) {\n lines.push(\"\");\n lines.push(\"## Potential Overlaps\");\n lines.push(`${entriesWithOverlaps.length} ${entriesWithOverlaps.length === 1 ? \"entry has\" : \"entries have\"} similar existing entries. Consider reviewing for duplicates:`);\n for (const r of entriesWithOverlaps) {\n lines.push(`- **${r.entryId}**: ${r.name} — ${r.overlapCount} similar ${r.overlapCount === 1 ? \"entry\" : \"entries\"}`);\n }\n }\n }\n\n const entriesWithWarnings = created.filter((r) => r.warnings && r.warnings.length > 0);\n if (entriesWithWarnings.length > 0) {\n lines.push(\"\");\n lines.push(\"## Validation Warnings\");\n for (const r of entriesWithWarnings) {\n lines.push(`- **${r.entryId}** (${r.name}): ${r.warnings!.join(\"; \")}`);\n }\n }\n\n if (failed.length > 0) {\n lines.push(\"\");\n lines.push(\"## Failed\");\n for (const r of failed) {\n lines.push(`- ${r.name} [${r.collection}]: _${r.error}_`);\n }\n lines.push(\"\");\n lines.push(`_If failed > 0, inspect \\`failedEntries\\` in the structured response and retry individually._`);\n }\n lines.push(...renderOutcomeUnknownSection(unknownOutcomeEntries)); // WP-575 review (P1, TEN-1126) — see lib/batchTimeoutCohort.ts.\n const entryIds = created.map((r) => r.entryId);\n if (entryIds.length > 0 || skippedLowConfidence.length > 0) {\n lines.push(\"\");\n lines.push(\"## Next Steps\");\n if (entryIds.length > 0) {\n lines.push(`- **Connect:** Run \\`relations action=suggest\\` on key entries to build the knowledge graph`);\n }\n if (drafts.length > 0) {\n lines.push(`- **Accept:** Use \\`entries action=commit\\` to promote remaining drafts to SSOT`);\n }\n if (skippedLowConfidence.length > 0) {\n lines.push(`- **Classify:** Re-capture ${skippedLowConfidence.length} skipped entries with explicit collections`);\n }\n if (entryIds.length > 0) {\n lines.push(`- **Quality:** Run \\`quality action=check\\` on individual entries to assess completeness`);\n }\n }\n\n const skippedNote = skippedLowConfidence.length > 0 ? `, ${skippedLowConfidence.length} skipped (low confidence)` : \"\";\n const classifiedNote = classifiedCount > 0 ? `, ${classifiedCount} auto-classified` : \"\";\n const commitFailedNote = commitFailed.length > 0 ? `, ${commitFailed.length} commit-failed` : \"\";\n const summary =\n failed.length > 0 || unknownOutcomeEntries.length > 0 || skippedLowConfidence.length > 0 || commitFailed.length > 0\n ? `Batch captured ${created.length}/${entries.length} entries (${failed.length} failed${unknownOutcomeSummaryNote(unknownOutcomeEntries)}${skippedNote}, ${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft${commitFailedNote}${classifiedNote}).`\n : `Batch captured ${created.length} entries successfully (${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft${classifiedNote}).`;\n\n const firstDraft = drafts[0];\n\n const next: NextAction[] = [];\n if (created.length > 0) {\n next.push({ tool: \"relations\", description: \"Discover connections\", parameters: { action: \"suggest\", entryId: created[0].entryId } });\n }\n if (firstDraft) {\n next.push({ tool: \"entries\" as const, description: \"Accept first draft\", parameters: { action: \"commit\", entryId: firstDraft.entryId } });\n }\n if (skippedLowConfidence.length > 0) {\n next.push({ tool: \"capture\", description: `Capture skipped entry with explicit collection`, parameters: { name: skippedLowConfidence[0].name, collection: skippedLowConfidence[0].suggestedCollection ?? \"\" } });\n }\n\n const batchTotalMs = Date.now() - batchTimingStart;\n const batchTiming = {\n totalMs: batchTotalMs,\n perEntryAvgMs: created.length > 0 ? Math.round(batchTotalMs / created.length) : 0,\n };\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: {\n ...success(\n summary,\n {\n captured: created.map((r) => ({\n entryId: r.entryId,\n collection: r.collection,\n name: r.name,\n status: r.status,\n ...(r.classifiedBy ? { classifiedBy: r.classifiedBy } : {}),\n ...(r.confidence != null ? { confidence: r.confidence } : {}),\n ...(r.confidenceTier ? { confidenceTier: r.confidenceTier } : {}),\n ...(r.warnings?.length ? { warnings: r.warnings } : {}),\n ...(r.normalization ? { normalization: r.normalization } : {}),\n ...(r.commitError ? { commitError: r.commitError } : {}),\n // WP-465 surface parity: thread full refusal payload into batch structured output.\n ...(r.commitRefusal ? { coherencyRefusal: r.commitRefusal } : {}),\n ...(r.authorityDomain ? { domain: r.authorityDomain.slug } : {}),\n // TEN-957 (WP-484 S2): inline relations created for this entry.\n ...(r.relationsCreated ? { relationsCreated: r.relationsCreated } : {}),\n // Finding #14: proposal outcomes are distinct from writes — never folded in.\n ...(r.relationsProposed ? { relationsProposed: r.relationsProposed } : {}),\n // WP-485 Slice 2b round 2 (Codex P1): the server's per-entry contradiction\n // advisory — was reaching `results` but dropped here, the final projection the\n // caller actually receives. Visible, never a silent success.\n ...(r.contradictionAdvisory ? { contradictionAdvisory: r.contradictionAdvisory } : {}),\n })),\n total: created.length,\n failed: failed.length,\n committed: committed.length,\n proposed: proposed.length,\n drafts: drafts.length,\n ...(commitFailed.length > 0 ? { commitFailed: commitFailed.length } : {}),\n ...(classifiedCount > 0 ? { classified: classifiedCount } : {}),\n autoCommitApplied,\n ...(skippedLowConfidence.length > 0 && {\n skippedLowConfidence: skippedLowConfidence.map((s) => ({\n index: s.index,\n name: s.name,\n ...(s.suggestedCollection ? { suggestedCollection: s.suggestedCollection } : {}),\n ...(s.confidence != null ? { confidence: s.confidence } : {}),\n ...(s.alternatives?.length ? { alternatives: s.alternatives } : {}),\n })),\n }),\n ...(failed.length > 0 && {\n // PR #392 round 2 (Codex, finding 2): `r.entryIdx` is the ORIGINAL input\n // position, carried explicitly since the moment each result was built —\n // NEVER `results.indexOf(r)` (the chunked pipeline pushes results in a\n // different order than `entries`' input order, so that would silently\n // report the wrong index for a batch with a mix of early/late failures).\n failedEntries: failed.map((r) => ({\n index: r.entryIdx,\n collection: r.collection,\n name: r.name,\n error: r.error ?? \"unknown error\",\n })),\n }), ...(unknownOutcomeEntries.length > 0 && { unknownOutcomeEntries }), // WP-575 review (P1, TEN-1126) — kept OUT of failedEntries.\n },\n next,\n ),\n _meta: { timing: batchTiming },\n },\n };\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\n/**\n * WP-465 slice ⑤ (Option B): `chain.commitEntry` RETURNS a structured coherency refusal\n * instead of throwing. Detect it so an auto-commit refusal is surfaced as a non-committed\n * draft (mirrors the thrown-failure path) and is NEVER reported or tracked as accepted.\n * Returns the refusal reason when refused, otherwise null.\n */\nfunction coherencyRefusalReason(commitResult: unknown): string | null {\n // `chain.commitEntry`'s real return is a discriminated union whose plain-success branch\n // has NO `status` field at all (not even `status: undefined`) — accepting `unknown` and\n // narrowing with `in` here (PR #395, Lane C S3b annotation pass) matches every branch\n // shape without a hand-written parameter type drifting from the server's real union.\n if (\n !commitResult ||\n typeof commitResult !== \"object\" ||\n !(\"status\" in commitResult) ||\n (commitResult as { status?: unknown }).status !== \"coherency_refused\"\n ) {\n return null;\n }\n const refusal =\n \"refusal\" in commitResult ? (commitResult as { refusal?: { reason?: string } }).refusal : undefined;\n return refusal?.reason ?? \"refused by the coherency gate\";\n}\n\n/**\n * Safe field reads across `chain.commitEntry`'s discriminated union (see\n * `coherencyRefusalReason` above for why the plain-success branch has no shared fields\n * with the others) — used at both call sites below (PR #395, Lane C S3b annotation pass).\n */\nfunction commitResultField<T>(commitResult: unknown, field: string): T | undefined {\n if (!commitResult || typeof commitResult !== \"object\" || !(field in commitResult)) return undefined;\n return (commitResult as Record<string, unknown>)[field] as T | undefined;\n}\n\n/**\n * BR-76 S2 — DEC-888: Surface commitEntry failures so they are never silent.\n * Fire-and-forget: each fan-out step has its own try/catch so a failure in one\n * does NOT block the others and does NOT change the caller's finalStatus.\n *\n * Steps:\n * 1. server.sendLoggingMessage (level \"error\") — visible in MCP transcript stream.\n * 2. Session-bound TEN emit via chain.createEntry — persisted to Chain when an\n * active write session (agentId) exists.\n *\n * Persistence to a queryable DB field is deferred (TEN-1811 follow-on).\n */\nasync function recordCommitFailure({\n entryId,\n error,\n sessionId,\n server,\n}: {\n entryId: string;\n error: unknown;\n sessionId: string | null | undefined;\n server: McpServer;\n}): Promise<void> {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const logLine = `commitEntry failed for ${entryId}: ${errorMessage}${sessionId ? ` (session: ${sessionId})` : \"\"}`;\n\n // Step 1: MCP transcript log — level \"error\"\n try {\n await server.sendLoggingMessage({ level: \"error\", data: logLine, logger: \"product-brain\" });\n } catch {\n // Logging must never break the caller\n }\n\n // Step 2: Session-bound TEN emit — only when an active write session exists\n if (sessionId) {\n try {\n const tenName = `commitEntry failed for ${entryId} — ${errorMessage}`.slice(0, 250);\n await kernelMutation<GatewayRouteReturnByName<\"chain.createEntry\">>(\"chain.createEntry\", {\n collectionSlug: \"tensions\",\n name: tenName,\n // Failure audit TENs intentionally stay draft — they need explicit human review,\n // not auto-commit, even in Open mode.\n status: \"draft\",\n data: {},\n createdBy: `agent:${sessionId}`,\n sessionId,\n });\n } catch {\n // TEN emit is advisory — never propagates\n }\n }\n}\n\n// STOP_WORDS/tokenizeText moved to ../lib/textMatch.ts (STD-2 / DEC-1504 module-health\n// extraction) — imported above; behavior unchanged.\n\n/**\n * Keyword contradiction check against governance entries.\n * Extracts terms 4+ chars, searches architecture and business-rules,\n * checks for 'governs' relations, returns formatted warnings.\n * Non-blocking — never throws, never prevents the operation.\n */\nexport interface ContradictionWarning {\n entryId: string;\n name: string;\n collection: string;\n governsCount: number;\n}\n\nexport async function runContradictionCheck(\n name: string,\n description: string,\n): Promise<ContradictionWarning[]> {\n const warnings: ContradictionWarning[] = [];\n try {\n const keyTerms = tokenizeText(`${name} ${description}`)\n .filter((w) => w.length >= 4 && !STOP_WORDS.has(w))\n .slice(0, 8);\n\n if (keyTerms.length === 0) return warnings;\n\n const searchQuery = keyTerms.slice(0, 5).join(\" \");\n const [govResults, archResults] = await Promise.all([\n kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: searchQuery, collectionSlug: \"business-rules\" }),\n kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: searchQuery, collectionSlug: \"architecture\" }),\n ]);\n\n const allGov = [...(govResults ?? []), ...(archResults ?? [])].slice(0, 5);\n\n for (const entry of allGov) {\n const entryTokens = new Set(tokenizeText(`${entry.name} ${entry.data?.description ?? \"\"}`));\n const matched = keyTerms.filter((t) => entryTokens.has(t));\n if (matched.length < 3) continue;\n\n // Check for 'governs' relations\n let governsCount = 0;\n try {\n const relations = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntryRelations\">>(\"chain.listEntryRelations\", {\n entryId: entry.entryId,\n });\n governsCount = (relations ?? []).filter((r: any) => r.type === \"governs\").length;\n } catch { /* non-critical */ }\n\n warnings.push({\n entryId: entry.entryId ?? \"\",\n name: entry.name,\n collection: entry.collectionSlug ?? \"\",\n governsCount,\n });\n }\n } catch {\n // Contradiction check is advisory — never blocks the operation\n }\n return warnings;\n}\n\ninterface SemanticConflictResult {\n chainEntryId: string;\n chainEntryName: string;\n chainEntryDescription?: string;\n type: \"contradiction\" | \"supersession\" | \"duplicate\" | \"overlap\";\n confidence: number;\n explanation: string;\n}\n\n/**\n * WP-485 Slice 2b (R2, FEAT-1370): the typed advisory chain.commitEntry's contradiction gate\n * attaches to a success response when the caller-supplied `conflicts` include a high-confidence\n * contradiction (DEC-1321 — advisory only, never blocking). Mirrors the shape\n * convex/agentKnowledge/entries.ts's `commitEntry` returns.\n */\ninterface ContradictionAdvisory {\n reason: string;\n blockingCount: number;\n conflictDetails: SemanticConflictResult[];\n}\n\n/**\n * WP-485 Slice 2b (R2, FEAT-1370): discover semantic conflicts to hand to chain.commitEntry's\n * CALLER-FED `conflicts` arg. Previously this file ran its own private\n * BLOCKING_CONTRADICTION_THRESHOLD comparison and threw a local `commitError` before ever\n * calling commitEntry — a THIRD independent copy of the enforcement decision, distinct from\n * conflict-preflight.ts's own copy. Deleted: the enforcement decision is now made ONE place,\n * server-side, by commitEntry's evaluate()/assessContradiction gate (Slice 2a). This helper only\n * DISCOVERS candidates — it never decides whether to block.\n */\nasync function discoverSemanticConflicts(\n name: string,\n description: string,\n collectionHint?: string,\n): Promise<SemanticConflictResult[]> {\n try {\n const conflicts = await kernelQuery<GatewayRouteReturnByName<\"chain.detectSemanticConflicts\">>(\"chain.detectSemanticConflicts\", {\n name,\n description,\n ...(collectionHint ? { collectionHint } : {}),\n });\n // WP-485 Slice 2b (live-proof finding): `chain.detectSemanticConflicts` also returns\n // `chainEntryDocId` (convex/intelligence/conflictDetection.ts DetectResult) — an internal\n // doc id NOT declared on `semanticConflictValidator` (convex/lib/conflictPolicy.ts), the\n // validator for commitEntry's `conflicts` arg. Passing the raw result straight through as\n // `conflicts` fails Convex's strict argument validation (caught live: a real detected\n // contradiction threw ArgumentValidationError). Whitelist only the accepted fields — both\n // call sites below hand this return value straight to chain.commitEntry.\n return (conflicts ?? []).map((c) => ({\n chainEntryId: c.chainEntryId,\n chainEntryName: c.chainEntryName,\n ...(c.chainEntryDescription ? { chainEntryDescription: c.chainEntryDescription } : {}),\n type: c.type,\n confidence: c.confidence,\n explanation: c.explanation,\n }));\n } catch {\n return [];\n }\n}\n\n// ── Quality Coaching Helpers ──────────────────────────────────────────────\n\n// WP-475 E1 (Copilot review): typed structural subset of the kernel QualityVerdict\n// (kernel/quality/types.ts) — exactly the fields this tool consumes (render via\n// formatRubricCoaching, telemetry via trackQualityVerdict, envelope qualityVerdict).\n// Precedent: the CLI's local mirror in packages/cli/src/formatters/coaching.ts.\n// The runtime value may carry more fields; they pass through the envelope spread\n// untouched.\ninterface CoachingCriterionSubset {\n id: string;\n passed: boolean;\n hint: string;\n questionTemplate: string;\n}\n\ninterface CoachingVerdictSubset {\n canonicalKey: string;\n tier: string;\n passed: boolean;\n criteria: CoachingCriterionSubset[];\n weakest: { criterion: string; hint: string; questionTemplate: string } | null;\n /** WP-475 E3: rubric methodology that produced the verdict (v1-vs-v2 seam). */\n methodologyVersion?: string;\n}\n\ninterface CoachingResultSubset {\n verdict: CoachingVerdictSubset;\n source: string;\n}\n\n// Round-3 review (TEN-2918 follow-up): moved to lib/rubricFormatting.ts — genuine cohesive\n// extraction that pays for this round's additions elsewhere in this shrink-only file (STD-2 /\n// DEC-1504). Imported (not just re-exported) because formatRubricCoaching/verdictQualityPhrase\n// are also called from within this file; re-exported so knowledge.ts/quality.ts/tests importing\n// them from \"../tools/smart-capture.js\" keep working unmodified.\nexport { verdictQualityPhrase, formatRubricCoaching, formatRubricVerdictSection };\n","/**\n * Capture-path timeout outcomes — WP-575 (TEN-2917, TEN-1126).\n *\n * A gateway budget abort on `chain.createEntry` is NOT a failed capture — it is an UNKNOWN\n * one, and that difference is the whole reason this module exists. The client stopped\n * waiting; the server may have written the entry. Before this, `tools/smart-capture.ts`\n * rethrew bare, so the agent was told the capture failed and would helpfully retry —\n * duplicating a write that had actually succeeded. TEN-1126 names the same thing on the\n * batch path: \"ghost entries, no partial-result feedback or reconciliation path.\"\n *\n * Split out of smart-capture.ts rather than inlined (STD-2 / DEC-1504 shrink-only ratchet):\n * \"what do we tell the caller when the outcome is unknowable\" is a self-contained decision\n * with its own reason to change, and smart-capture.ts is already 3.4k lines of orchestration.\n */\nimport { failure, type ToolResult } from \"../envelope.js\";\nimport type { GatewayTimeoutError } from \"../client.js\";\n\n/**\n * Did this throw come from a gateway latency-budget abort?\n *\n * Discriminates on `name`, NOT `instanceof`, and takes the class in as a TYPE only — so this\n * module never holds a runtime reference to `../client.js`'s class object. Two real reasons,\n * both of which bit before this shape was chosen:\n * 1. Class identity does not survive a mocked module. Every smart-capture test mocks\n * `../client.js` with an explicit factory listing the exports it needs; an `instanceof`\n * against a class such a factory doesn't re-export evaluates against `undefined` and\n * throws \"Right-hand side of 'instanceof' is not callable\" — surfacing three layers away\n * as an unrelated assertion failure. That is a trap for every future test that mocks the\n * client, not a one-time fix.\n * 2. Class identity does not survive module duplication in general (a bundler emitting the\n * module twice, an ESM/CJS split). `name` does.\n * This is the same technique `../client.js` itself uses one layer down to recognize\n * `AbortSignal.timeout`'s DOMException, which is likewise not an importable class. The `name`\n * value depended on here is pinned by `../__tests__/route-latency-budget.test.ts`.\n */\nexport function isGatewayTimeout(error: unknown): error is GatewayTimeoutError {\n return (error as { name?: string } | null | undefined)?.name === \"GatewayTimeoutError\";\n}\n\n/**\n * The single-capture answer: report what is actually known instead of a bare failure.\n *\n * WP-575 review round (P1): this used to assert `didNotRun: [\"relations\", \"commit\",\n * \"coaching\"]` — wrong for two of the three. `commit` and `coaching` both run INSIDE\n * `chain.createEntry` before it returns (convex/agentKnowledge/entries.ts: coaching at\n * ~683-692/715, Open-mode auto-commit exposed via `insertResult.status` at ~706), so if the\n * server finished after this client gave up waiting, they already ran — same as the entry\n * itself. Only relation linking (`chain.createEntryRelations`) is a genuinely SEPARATE\n * mutation issued later by this file and never reached when create throws. Asserting\n * \"definitely did not run\" for commit/coaching told the agent it was safe to assume no\n * server-side side effect existed, which is exactly backwards for the Open-mode default.\n */\nexport function buildCaptureOutcomeUnknownResult(\n error: GatewayTimeoutError,\n name: string,\n msg: string,\n): ToolResult {\n if (!error.mayHaveLanded) return buildDryRunTimeoutResult(error, msg);\n const recovery =\n `Search for \"${name}\" before retrying — a retry will duplicate it if the write landed. ` +\n `If found, read back its commit status and coaching output before assuming either is missing.`;\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Capture Outcome Unknown — Not Failed\\n\\n${msg}\\n\\n` +\n `**What is known:** the request reached the server and this client gave up waiting ` +\n `after ${error.elapsedMs}ms. The entry **may or may not** have been written.\\n\\n` +\n `**What definitely did NOT run:** relation linking — a separate mutation issued ` +\n `after the create returns, so it is never reached when create itself times out.\\n\\n` +\n `**What may also have run — outcome unknown, same reason as the entry itself:** ` +\n `auto-commit and quality coaching. Both execute INSIDE the create call, before it ` +\n `returns, so if the server finished after this client stopped waiting, they ran too. ` +\n `Do not assume either is absent — read the entry back to find out.\\n\\n` +\n `**Do this next:** ${recovery}`,\n }],\n structuredContent: failure(\n \"CAPTURE_OUTCOME_UNKNOWN\",\n msg,\n recovery,\n [{ tool: \"entries\", description: \"Search for the entry before retrying\", parameters: { action: \"search\", query: name } }],\n {\n // Structured so a caller can branch on this without parsing prose — the\n // reconciliation signal TEN-1126 says the capture path never had.\n partialSuccess: true,\n mayHaveLanded: error.mayHaveLanded,\n budgetMs: error.budgetMs,\n elapsedMs: error.elapsedMs,\n completedBeforeTimeout: [] as string[],\n // WP-575 review (P1): genuinely definite — relation linking is a separate mutation\n // never reached when create throws. See the doc comment above for why `commit` and\n // `coaching` were removed from this list.\n didNotRun: [\"relations\"],\n // WP-575 review (P1): distinct from `didNotRun` on purpose — these ran INSIDE the\n // same server call as the create, so their outcome is exactly as unknown as the\n // entry's. A caller must read the entry back, never assume either ran or didn't.\n mayHaveRun: [\"commit\", \"coaching\"],\n },\n ),\n };\n}\n\n/**\n * The DRY-RUN answer (PR #533 review, Codex P2).\n *\n * A `preview: true` capture that times out is the one case where \"did the write land\" has a\n * definite answer: no. The server's preview branch returns before any insert\n * (convex/agentKnowledge/entries.ts:498-599, first write at :601), so nothing — entry,\n * auto-commit, coaching, or relation linking — can have happened. The generic path above\n * would tell the agent its write \"may or may not\" have been written and to search before\n * retrying, which is not merely unhelpful on a dry run: the batch-preview surface renders that\n * warning directly beside its own \"no DB writes\" line, so one response asserted both.\n *\n * The code stays `CAPTURE_OUTCOME_UNKNOWN` because something genuinely IS unknown — the\n * validation VERDICT the preview existed to produce. What is now known is that nothing landed,\n * which is what makes it plainly safe to re-run.\n */\nfunction buildDryRunTimeoutResult(error: GatewayTimeoutError, msg: string): ToolResult {\n const recovery = \"Re-run the preview — nothing was written, so there is nothing to search for and nothing to duplicate.\";\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Preview Outcome Unknown — Nothing Was Written\\n\\n${msg}\\n\\n` +\n `**What is known:** the request reached the server and this client gave up waiting ` +\n `after ${error.elapsedMs}ms. This was a **preview**, and the server returns its ` +\n `validation result before performing any write — so no entry, auto-commit, quality ` +\n `coaching, or relation linking happened.\\n\\n` +\n `**What is unknown:** the validation verdict this preview was asked for.\\n\\n` +\n `**Do this next:** ${recovery}`,\n }],\n structuredContent: failure(\n \"CAPTURE_OUTCOME_UNKNOWN\",\n msg,\n recovery,\n [],\n {\n // No partial success to reconcile: a dry run has no server-side state to converge on.\n partialSuccess: false,\n mayHaveLanded: false,\n budgetMs: error.budgetMs,\n elapsedMs: error.elapsedMs,\n completedBeforeTimeout: [] as string[],\n didNotRun: [\"entry\", \"relations\", \"commit\", \"coaching\"],\n mayHaveRun: [] as string[],\n },\n ),\n };\n}\n\n/**\n * The batch answer (TEN-1126). The entry is still reported failed so the batch summary stays\n * honest about what it can PROVE, but the message now says the write may have landed and\n * names the one action that resolves it — instead of a bare transport error the caller could\n * only read as \"didn't happen\", which is exactly how a ghost entry gets made.\n */\nexport function describeBatchEntryError(error: unknown, entryName: string): string {\n const msg = error instanceof Error ? error.message : String(error);\n if (!isGatewayTimeout(error)) return msg;\n // A dry run cannot have been captured, so \"it may be captured twice\" would be false — and\n // the preview surface prints this line beside its own \"no DB writes\" note (PR #533 review).\n return error.mayHaveLanded\n ? `${msg} Outcome unknown for this entry — search for \"${entryName}\" before re-running the batch, or it may be captured twice.`\n : `${msg} This was a preview, so nothing was written for this entry — safe to re-run the batch.`;\n}\n","/**\n * Per-scope, TTL-bounded cache.\n *\n * Each MCP server process can hold state for many workspaces at once (HTTP mode:\n * one process, many API keys — see auth.ts). Caches must therefore be partitioned\n * by request scope, never stored as a single module global, or one workspace's\n * data leaks to another (TEN-2415). The TTL bounds staleness so a mid-session\n * structure change becomes visible without a process restart (TEN-2398).\n *\n * Bounded by maxScopes with TTL-first eviction, mirroring auth.ts keyStateMap\n * (evictStale + MAX_KEYS). Without this, a long-lived multi-tenant process would\n * accumulate one entry per API key that ever connected — the in-process per-key\n * Map scale ceiling called out in TEN-2229.\n */\ninterface Entry<T> {\n value: T;\n expiresAt: number;\n}\n\nexport class ScopedCache<T> {\n private store = new Map<string, Entry<T>>();\n constructor(\n private readonly ttlMs: number,\n private readonly maxScopes = 100, // matches auth.ts MAX_KEYS — can't have more live scopes than live keys\n ) {}\n\n get(scope: string): T | undefined {\n const e = this.store.get(scope);\n if (!e) return undefined;\n if (Date.now() > e.expiresAt) {\n this.store.delete(scope);\n return undefined;\n }\n return e.value;\n }\n\n set(scope: string, value: T): void {\n this.store.set(scope, { value, expiresAt: Date.now() + this.ttlMs });\n if (this.store.size > this.maxScopes) this.evict();\n }\n\n delete(scope: string): void {\n this.store.delete(scope);\n }\n\n clear(): void {\n this.store.clear();\n }\n\n size(): number {\n return this.store.size;\n }\n\n /** Drop expired entries first; if still over budget, drop the oldest-expiring. */\n private evict(): void {\n const now = Date.now();\n for (const [k, e] of this.store) {\n if (now > e.expiresAt) this.store.delete(k);\n }\n if (this.store.size > this.maxScopes) {\n const sorted = [...this.store.entries()].sort((a, b) => a[1].expiresAt - b[1].expiresAt);\n const overBy = sorted.length - this.maxScopes; // capture once — store mutates in the loop\n for (let i = 0; i < overBy; i++) {\n this.store.delete(sorted[i][0]);\n }\n }\n }\n}\n\n/** Collection-structure caches share this window. Matches the readCache TTL in client.ts. */\nexport const COLLECTION_CACHE_TTL_MS = 60_000;\n","/**\n * Coherency refusal rendering — shared between knowledge.ts and smart-capture.ts.\n * Extracted to break the knowledge ↔ smart-capture circular dependency (WP-465 TEN-2458).\n *\n * Display-lane only: never interprets the refusal, only renders it.\n * The contract lives in convex/lib/gates/coherencyControls.ts (CoherencyRefusal).\n */\n\nimport { failureResult } from \"../envelope.js\";\n\n/** Structured coherency refusal (WP-465 slice ⑤ Option B) — rendered, never interpreted here. */\nexport type CoherencyRefusalPayload = {\n reason?: string;\n disposition?: string;\n overridable?: boolean;\n mode?: string;\n subject?: { entryId?: string | null; name?: string };\n routes?: Record<string, unknown>;\n};\n\n/** Options controlling how the refusal is rendered (vs. interpreted — interpretation never happens here). */\nexport type CoherencyRefusalRenderOptions = {\n /**\n * Markdown heading level for the leading \"Write refused…\" line. Defaults to 1 (H1) for the\n * standalone failure result; embedding callers (e.g. under an H2 `## Accept failed`) pass 3\n * so the hierarchy stays correct (no H1 nested under an H2).\n */\n headingLevel?: 1 | 2 | 3;\n};\n\n/** Coerce a possibly-non-string description to a clean string, or undefined if not renderable. */\nfunction asDescription(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nconst GENERIC_RECOVERY_LINE =\n \"Respond and retry: link the entry to the strategic spine, pass `coherencyAcknowledgement`, or supply a typed `steeringOverrideReason`.\";\n\n/**\n * Build a failure ToolResult from a structured coherency refusal, rendering the actual\n * routes (link / acknowledge / override) and mode from the payload.\n *\n * Degrades gracefully when routes are absent OR present-but-empty (no recognized route yields a\n * bullet) — falls back to a generic \"use one of the routes\" sentence so the agent never hits a\n * dead end. The fallback is keyed on whether ≥1 route bullet was actually emitted, not on the\n * raw key count, so `{ link: null }` or unknown-only keys still leave a way forward.\n */\nexport function coherencyRefusedResult(\n toolName: string,\n entryId: string,\n refusal: CoherencyRefusalPayload,\n options?: CoherencyRefusalRenderOptions,\n) {\n const headingLevel = options?.headingLevel ?? 1;\n const heading = \"#\".repeat(headingLevel);\n const lines: string[] = [\n `${heading} Write refused by the coherency gate`,\n \"\",\n refusal.reason ?? `The coherency gate refused this write on ${entryId}.`,\n ];\n\n if (refusal.subject?.name) {\n lines.push(`On: ${refusal.subject.name}`);\n }\n\n if (refusal.mode) {\n lines.push(\"\", `Mode: ${refusal.mode}`);\n }\n\n const routes = refusal.routes as Record<string, unknown> | undefined;\n const routeKeys = routes ? Object.keys(routes) : [];\n if (routeKeys.length > 0) {\n // Subheading stays exactly one level below the leading heading so an embedded caller\n // (headingLevel: 3) renders `### Write refused…` / `#### Recovery routes`, never an\n // inverted `## Recovery routes` nested under an `###` (codex/self review).\n lines.push(\"\", `${\"#\".repeat(headingLevel + 1)} Recovery routes`);\n // MINOR 3: track whether any route actually rendered a bullet — the no-dead-end guarantee\n // must hold even when routes is present but yields nothing renderable.\n const beforeRoutes = lines.length;\n if (routes && typeof routes.link === \"object\" && routes.link !== null) {\n const link = routes.link as { description?: unknown };\n lines.push(`- **link:** ${asDescription(link.description) ?? \"Link the entry to the strategic spine.\"}`);\n }\n if (routes && typeof routes.acknowledge === \"object\" && routes.acknowledge !== null) {\n const ack = routes.acknowledge as { param?: string; responses?: ReadonlyArray<string>; minReasonChars?: number; description?: unknown };\n const responses = ack.responses?.join(\" | \") ?? \"linked | accepted-fix | diverged\";\n lines.push(\n `- **acknowledge** (\\`${ack.param ?? \"coherencyAcknowledgement\"}\\`): ${responses}${ack.minReasonChars ? ` (≥${ack.minReasonChars} chars for diverged)` : \"\"}. ${asDescription(ack.description) ?? \"\"}`.trim(),\n );\n }\n if (routes && typeof routes.override === \"object\" && routes.override !== null) {\n const ov = routes.override as { param?: string; minChars?: number; description?: unknown };\n lines.push(\n `- **override** (\\`${ov.param ?? \"steeringOverrideReason\"}\\`): ≥${ov.minChars ?? 12} chars. ${asDescription(ov.description) ?? \"\"}`.trim(),\n );\n }\n if (lines.length === beforeRoutes) {\n // Header printed but no bullet followed → append the generic fallback so the section\n // never dead-ends under a bare \"## Recovery routes\".\n lines.push(GENERIC_RECOVERY_LINE);\n }\n } else {\n lines.push(\"\", GENERIC_RECOVERY_LINE);\n }\n\n return failureResult(\n lines.join(\"\\n\"),\n \"COHERENCY_REFUSED\",\n `Coherency gate refused ${toolName} on ${entryId}.`,\n \"Use one of the refusal's routes (link / coherencyAcknowledgement / steeringOverrideReason), then retry.\",\n undefined,\n { entryId, refusal },\n );\n}\n","/**\n * Unified Collection Routing — FEAT-157 (BET-105 Slice 0)\n *\n * Thin client: delegates to Convex chain.resolveCollection (L5 orchestration).\n * All entry-creation surfaces call this; Convex runs LLM → heuristic → typeHint.\n *\n * Chain: DEC-163 (L5 placement), FEAT-157, FEAT-159 (confidence gating)\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelCall, getAgentSessionId } from \"../client.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────\n// PR #395 (Lane C S3b annotation pass): `ResolvedCollection` used to be a\n// hand-copied mirror of `convex/agentKnowledge/resolveCollection.ts`'s own\n// exported interface. Annotating this call site with the generic\n// `GatewayRouteReturnByName<'chain.resolveCollection'>` alias surfaced a real\n// drift: the hand copy was missing the `candidates` field entirely and had a\n// narrower `thinkingLayer?: string` (server reality: `string | null`). Now\n// DERIVED from the server type directly — a future server-side shape change\n// is a compile error here, not a silent, unnoticed divergence.\n\nexport type ResolvedCollection = NonNullable<GatewayRouteReturnByName<\"chain.resolveCollection\">>;\n\n// ── Main entry point (thin client) ───────────────────────────────────────\n\nexport async function resolveCollection(params: {\n name: string;\n description: string;\n typeHint?: string;\n allowReviewRouting?: boolean;\n}): Promise<ResolvedCollection | null> {\n const { name, description, typeHint, allowReviewRouting } = params;\n\n const sessionId = getAgentSessionId();\n const result = await kernelCall<GatewayRouteReturnByName<\"chain.resolveCollection\">>(\"chain.resolveCollection\", {\n entryName: name,\n entryDescription: description,\n ...(typeHint ? { typeHint } : {}),\n ...(allowReviewRouting ? { allowReviewRouting } : {}),\n ...(sessionId ? { agentSessionId: sessionId } : {}),\n });\n\n return result ?? null;\n}\n","/**\n * Synced from convex/lib/fieldTypes.ts (BET-106: closed field type system, BR-108: MCP import boundary).\n */\n\n/**\n * Closed field type system — single source of truth for collection field types.\n * BET-106: Makes the collection contract self-enforcing.\n *\n * Adding a new field type requires updating:\n * 1. VALID_FIELD_TYPES + FIELD_TYPE_DEFAULTS + isValidValueForType (this file)\n * 2. validateEntryData switch in convex/lib/guards.ts\n * 3. fieldDefValidator in convex/agentKnowledge/_helpers.ts\n * 4. Run: node scripts/sync-convex-lib-to-mcp.mjs\n * 5. packages/mcp-server/src/lib/fieldTypes.ts (mirror — must stay in sync)\n */\n\nexport const VALID_FIELD_TYPES = [\n\t'string',\n\t'text',\n\t'rich-text',\n\t'number',\n\t'boolean',\n\t'select',\n\t'multi-select',\n\t'array',\n\t'json',\n\t'date',\n\t/** Convex Id<'people'> as string — BR-130 */\n\t'person',\n] as const;\n\nexport type FieldType = (typeof VALID_FIELD_TYPES)[number];\n\n/** Type-aware defaults for smart-capture and entry creation. */\nexport const FIELD_TYPE_DEFAULTS: Record<FieldType, unknown> = {\n\t'string': '',\n\t'text': '',\n\t'rich-text': '',\n\t'number': null,\n\t'boolean': false,\n\t'select': null,\n\t'multi-select': [],\n\t'array': [],\n\t'json': null,\n\t'date': null,\n\t'person': null,\n};\n\nexport function isValidFieldType(type: string): type is FieldType {\n\treturn (VALID_FIELD_TYPES as readonly string[]).includes(type);\n}\n\nexport function isValidValueForType(value: unknown, type: FieldType): boolean {\n\tswitch (type) {\n\t\tcase 'string':\n\t\tcase 'text':\n\t\tcase 'rich-text':\n\t\t\treturn typeof value === 'string';\n\t\tcase 'number':\n\t\t\treturn value === null || typeof value === 'number';\n\t\tcase 'boolean':\n\t\t\treturn typeof value === 'boolean';\n\t\tcase 'select':\n\t\t\treturn value === null || typeof value === 'string';\n\t\tcase 'multi-select':\n\t\tcase 'array':\n\t\t\treturn Array.isArray(value);\n\t\tcase 'json':\n\t\t\treturn true;\n\t\tcase 'date':\n\t\t\treturn value === null || (typeof value === 'string' && /^\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])$/.test(value));\n\t\tcase 'person':\n\t\t\t// WP-630 (TEN-3042): deliberately NOT tightened to an id-shape regex. This\n\t\t\t// function returns a plain boolean with no separate advisory/blocking channel —\n\t\t\t// unlike kernel/entries/guards.ts's validateEntryData (warn vs error split), a\n\t\t\t// tightened `false` here would be indistinguishable from \"reject.\" The write\n\t\t\t// gate's runtime Step-1.5 (convex/lib/personPlaceholder.ts) is the actual\n\t\t\t// guarantee (resolves-or-creates before validation ever sees a write-set value);\n\t\t\t// this predicate stays permissive so it can never disagree with that outcome —\n\t\t\t// see the shaping doc's \"preview and gate must never disagree\" disposition.\n\t\t\treturn value === null || typeof value === 'string';\n\t}\n}\n","/**\n * BET-289 S2: Format field-level writing guidance into a prompt section.\n * Replicated from convex/lib/formatFieldGuidance.ts due to monorepo import boundary (BR-170).\n * Must produce identical output to the convex/ version.\n *\n * Pure function (STD-148). No side effects, no imports beyond types.\n */\n\nexport interface FieldWithGuidance {\n\tkey: string;\n\tlabel?: string;\n\twritingGuidance?: string;\n\twritingExamples?: string[];\n}\n\n/**\n * Format field-level writing guidance into a prompt-injectable section.\n *\n * @param fields - Array of field definitions, potentially with writingGuidance/writingExamples.\n * @returns Formatted string for prompt injection, or empty string if no fields have guidance.\n */\nexport function formatFieldGuidance(fields: FieldWithGuidance[]): string {\n\tconst guidedFields = fields.filter((f) => f.writingGuidance);\n\tif (guidedFields.length === 0) return '';\n\n\tconst lines: string[] = ['## Writing Guidance'];\n\tfor (const field of guidedFields) {\n\t\tconst displayName = field.label || field.key;\n\t\tlines.push(`- ${displayName}: ${field.writingGuidance}`);\n\t\tif (field.writingExamples && field.writingExamples.length > 0) {\n\t\t\tlines.push(` Examples: ${field.writingExamples.join(' | ')}`);\n\t\t}\n\t}\n\n\treturn lines.join('\\n');\n}\n","/**\n * Synced from convex/lib/inferSourceDate.ts (FEAT-885: shared date inference, BR-108: MCP import boundary).\n */\n\n/**\n * Infer an ISO date (YYYY-MM-DD) from free-text values.\n *\n * Canonical source for MCP (packages/mcp-server/src/lib/inferSourceDate.ts)\n * and CLI (packages/cli/src/lib/inferSourceDate.ts) — both are synced copies\n * maintained by scripts/sync-convex-lib-to-mcp.mjs (FEAT-885, BR-108).\n */\n\nexport function inferSourceDate(...values: Array<string | undefined>): string | undefined {\n\tconst combined = values\n\t\t.filter((value): value is string => typeof value === 'string' && value.trim().length > 0)\n\t\t.join('\\n');\n\n\tif (!combined) return undefined;\n\n\tconst isoMatch = combined.match(/\\b(20\\d{2}-\\d{2}-\\d{2})\\b/);\n\tif (isoMatch) return isoMatch[1];\n\n\tconst monthMatch = combined.match(\n\t\t/\\b(january|february|march|april|may|june|july|august|september|october|november|december)\\s+(\\d{1,2})(?:st|nd|rd|th)?(?:,?\\s+(20\\d{2}))?\\b/i,\n\t);\n\tif (!monthMatch) return undefined;\n\n\tconst monthIndex = [\n\t\t'january',\n\t\t'february',\n\t\t'march',\n\t\t'april',\n\t\t'may',\n\t\t'june',\n\t\t'july',\n\t\t'august',\n\t\t'september',\n\t\t'october',\n\t\t'november',\n\t\t'december',\n\t].indexOf(monthMatch[1].toLowerCase());\n\tif (monthIndex < 0) return undefined;\n\n\tconst inferredYear = monthMatch[3] ?? combined.match(/\\b(20\\d{2})\\b/)?.[1] ?? String(new Date().getUTCFullYear());\n\tconst month = String(monthIndex + 1).padStart(2, '0');\n\tconst day = monthMatch[2].padStart(2, '0');\n\treturn `${inferredYear}-${month}-${day}`;\n}\n","/**\n * Per-scope collection metadata cache — BET-281 Slice 2, TEN-2398/TEN-2415.\n *\n * Wraps chain.listCollections() with a per-workspace, TTL-bounded cache\n * (see lib/scopedCache.ts). In HTTP/SSE mode one process serves many workspaces,\n * so the cache is partitioned by request scope (hashed API key) — never a single\n * module global — and each entry expires after COLLECTION_CACHE_TTL_MS so a\n * mid-session collection add/rename is visible without a process restart. A\n * collection write also invalidates the current scope for immediate visibility\n * (see invalidateCollectionCacheForScope, wired in tools/collections.ts).\n *\n * Helpers derive runtime behavior from DB fields so consumers never hardcode slugs.\n *\n * Chain: BET-281, STD-101 (derive, don't declare), TEN-2398, TEN-2415.\n */\n\nimport { kernelQuery, cacheScope } from \"../client.js\";\nimport { ScopedCache, COLLECTION_CACHE_TTL_MS } from \"./scopedCache.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface CollectionDoc {\n _id: string;\n slug: string;\n name: string;\n description?: string;\n purpose?: string;\n icon?: string;\n navGroup?: \"daily\" | \"strategic\" | \"governance\" | \"reference\" | \"collections\";\n fields: Array<{\n key: string;\n label: string;\n type: string;\n required?: boolean;\n options?: string[];\n relatesTo?: string;\n searchable?: boolean;\n displayHint?: string;\n zone?: string;\n colorMap?: unknown;\n accentSource?: boolean;\n iconMap?: Record<string, string>;\n helpText?: string;\n /** BET-289: Natural language instruction for how to write this field value. */\n writingGuidance?: string;\n /** BET-289: Example strings showing good/bad field values. */\n writingExamples?: string[];\n optionDescriptions?: unknown;\n semanticRole?: string;\n maxLength?: number;\n minLength?: number;\n requiredContext?: string;\n /**\n * WP-328/WP-574: this field mirrors the entry name. The server owns the semantics\n * (writeGate coalesces entry.name into a blank value, an explicit non-blank value\n * wins and warns on divergence) — declared here so the wire type matches what\n * chain.listCollections actually returns (schema.ts:398) rather than silently\n * dropping the flag before any client can reason about it.\n */\n mirrorsEntryName?: boolean;\n }>;\n stratum: \"system\" | \"domain\" | \"working\";\n defaultCanonicalKey?: string;\n defaultWorkflowStatus?: string;\n governed?: boolean;\n idPrefix?: string;\n validWorkflowStatuses?: string[];\n classificationCheck?: string;\n classificationPriority?: number;\n qualityCriteria?: Array<{\n field: string;\n rule: \"required\" | \"min_length\" | \"pattern\";\n value?: string;\n active?: boolean;\n }>;\n thinkingLayer?: string;\n timelineRole?: string;\n color?: string;\n governanceRole?: string;\n governanceFunction?: string;\n layoutTemplate?: string;\n usageGuidance?: string;\n examples?: Array<{ name: string; description: string }>;\n crossReferences?: Array<{ slug: string; relationship: string; guidance: string }>;\n descriptionFieldKey?: string;\n /** WP-316: agent-facing guidance on what a well-formed capture for this collection looks like. */\n captureExpectation?: string;\n}\n\n// ── Cache State (per-scope, TTL-bounded) ─────────────────────────────────────\n\ninterface CollectionCacheValue {\n collections: CollectionDoc[];\n bySlug: Map<string, CollectionDoc>;\n}\n\nconst collectionCache = new ScopedCache<CollectionCacheValue>(COLLECTION_CACHE_TTL_MS);\n\n// ── Core ─────────────────────────────────────────────────────────────────────\n\n/**\n * Get all workspace collections for the current request scope, cached with a\n * short TTL. First call within the window hits Convex; subsequent calls return\n * cached data. Keyed per workspace so one tenant never sees another's structure.\n */\nexport async function getCollections(): Promise<CollectionDoc[]> {\n const scope = cacheScope();\n const hit = collectionCache.get(scope);\n if (hit) return hit.collections;\n const result = (await kernelQuery<CollectionDoc[]>(\"chain.listCollections\")) ?? [];\n const bySlug = new Map(result.map((c) => [c.slug, c]));\n collectionCache.set(scope, { collections: result, bySlug });\n return result;\n}\n\n/**\n * Get collection by slug from the current scope's cache.\n */\nexport async function getCollectionBySlug(slug: string): Promise<CollectionDoc | undefined> {\n await getCollections();\n return collectionCache.get(cacheScope())?.bySlug.get(slug);\n}\n\n/** Clear ALL scopes — test hook + full flush. */\nexport function resetCollectionCache(): void {\n collectionCache.clear();\n}\n\n/** Invalidate only the current request scope — call after a collection write. */\nexport function invalidateCollectionCacheForScope(): void {\n collectionCache.delete(cacheScope());\n}\n\n// ── Derived Queries ────────────────────────────────────────────────────────\n\n/**\n * Check if a collection supports classification (has non-empty classificationCheck).\n * Runtime equivalent of the old CLASSIFIABLE_COLLECTIONS constant.\n */\nexport async function isClassifiable(slug: string): Promise<boolean> {\n const col = await getCollectionBySlug(slug);\n return !!col?.classificationCheck;\n}\n\n/**\n * Get all classifiable collection slugs.\n */\nexport async function getClassifiableSlugs(): Promise<string[]> {\n const cols = await getCollections();\n return cols\n .filter((c) => !!c.classificationCheck)\n .map((c) => c.slug);\n}\n\n/**\n * Check if a collection uses governed draft workflow.\n * Runtime replacement for the GOVERNED_COLLECTIONS set.\n */\nexport async function isGoverned(slug: string): Promise<boolean> {\n const col = await getCollectionBySlug(slug);\n return !!col?.governed;\n}\n\n/**\n * Get collections by navGroup (e.g. 'governance', 'strategic', 'daily').\n */\nexport async function getByNavGroup(navGroup: string): Promise<CollectionDoc[]> {\n const cols = await getCollections();\n return cols.filter((c) => c.navGroup === navGroup);\n}\n\n/**\n * Get collections by thinkingLayer.\n */\nexport async function getByThinkingLayer(layer: string): Promise<CollectionDoc[]> {\n const cols = await getCollections();\n return cols.filter((c) => c.thinkingLayer === layer);\n}\n\n/**\n * Check if a collection is a \"hub\" collection — strategic collections that\n * get higher link confidence scores. Original HUB_COLLECTIONS was strategy + features.\n * Primary: governanceRole === 'steering' (captures both strategy + features).\n * Fallback: thinkingLayer === 'strategy' for workspaces not yet backfilled.\n */\nexport async function isHubCollection(slug: string): Promise<boolean> {\n const col = await getCollectionBySlug(slug);\n if (!col) return false;\n return col.governanceRole === \"steering\" || col.thinkingLayer === \"strategy\";\n}\n\n/**\n * Get the description field key for a collection.\n * Most collections use \"description\"; some use \"rationale\", \"belief\", \"canonical\", etc.\n * Falls back to \"description\" if not specified in the collection's field metadata.\n */\nexport async function getDescriptionFieldKey(slug: string): Promise<string> {\n const col = await getCollectionBySlug(slug);\n if (!col) return \"description\";\n\n // Check for fields with specific semantic roles or known description-like keys\n const descriptionLikeKeys = [\"description\", \"rationale\", \"belief\", \"canonical\"];\n for (const key of descriptionLikeKeys) {\n const field = col.fields.find((f) => f.key === key);\n if (field && (field.displayHint === \"hero\" || field.displayHint === \"textarea\" || field.zone === \"body\")) {\n return key;\n }\n }\n\n // Fallback: check for first field in body zone with textarea hint\n const bodyTextField = col.fields.find(\n (f) => f.zone === \"body\" || f.displayHint === \"textarea\",\n );\n if (bodyTextField) return bodyTextField.key;\n\n return \"description\";\n}\n\n/**\n * Check if collection's navGroup is 'governance' — used for binding governance\n * collections (principles, standards, business-rules).\n */\nexport async function isGovernanceNavGroup(slug: string): Promise<boolean> {\n const col = await getCollectionBySlug(slug);\n return col?.navGroup === \"governance\";\n}\n\n/**\n * Check if a collection belongs to the work planning domain\n * (thinkingLayer is delivery-container, delivery-grouping, or delivery-work).\n * Runtime replacement for checking slug === \"chains\" || slug === \"work-packages\".\n */\nexport async function isWorkPlanningCollection(slug: string): Promise<boolean> {\n const col = await getCollectionBySlug(slug);\n const layer = col?.thinkingLayer;\n return layer === \"delivery-container\" || layer === \"delivery-grouping\" || layer === \"delivery-work\";\n}\n\n/**\n * Check if a collection has a specific defaultCanonicalKey.\n */\nexport async function hasCanonicalKey(slug: string, key: string): Promise<boolean> {\n const col = await getCollectionBySlug(slug);\n return col?.defaultCanonicalKey === key;\n}\n","/**\n * Text tokenization utilities shared across smart-capture's contradiction-check\n * keyword extraction. Pure — no MCP/kernel dependencies. Extracted from\n * tools/smart-capture.ts (STD-2 / DEC-1504 module-health ratchet); the call site\n * stays unchanged, only the implementation moved.\n */\n\n// Stop words excluded from noun phrase / keyword extraction.\nexport const STOP_WORDS = new Set([\n \"the\", \"and\", \"for\", \"are\", \"but\", \"not\", \"you\", \"all\", \"can\", \"has\", \"her\",\n \"was\", \"one\", \"our\", \"out\", \"day\", \"had\", \"hot\", \"how\", \"its\", \"may\", \"new\",\n \"now\", \"old\", \"see\", \"way\", \"who\", \"did\", \"get\", \"let\", \"say\", \"she\", \"too\",\n \"use\", \"from\", \"have\", \"been\", \"each\", \"that\", \"this\", \"with\", \"will\", \"they\",\n \"what\", \"when\", \"make\", \"like\", \"long\", \"look\", \"many\", \"some\", \"them\", \"than\",\n \"most\", \"only\", \"over\", \"such\", \"into\", \"also\", \"back\", \"just\", \"much\", \"must\",\n \"name\", \"very\", \"your\", \"after\", \"which\", \"their\", \"about\", \"would\", \"there\",\n \"should\", \"could\", \"other\", \"these\", \"first\", \"being\", \"those\", \"still\", \"where\",\n]);\n\nexport function tokenizeText(input: string): string[] {\n return input\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]+/gu, \" \")\n .split(/\\s+/)\n .filter(Boolean);\n}\n","/**\n * WP-577 / TEN-2918 follow-up: the honest response shape for `capture action=batch`\n * run with `preview: true`.\n *\n * Why this exists. `handleCapture`'s single path has always had a dedicated preview\n * branch that returns \"Preview: would capture … — no DB writes\" with\n * `outcome: \"preview\"`. `handleBatchCapture` had no equivalent: its response shaping\n * is unconditional, so a preview batch returned the REAL-create surface —\n * \"# Batch Capture Complete\", \"**N** created\", per-entry `status: \"draft\"`, and a\n * `next` offering `entries action=commit` on an entryId that was never written.\n *\n * That was invisible until now because batch preview threw `ArgumentValidationError`\n * at the gateway before reaching this code (the parity gap this PR closes). Making\n * `preview` forward correctly is what turned the dishonest report into a LIVE agent\n * surface — the same \"the fix exposed a latent bug\" shape as the auto-commit block\n * guarded in `handleBatchCapture`, found by driving the real MCP connector process\n * against a seeded preview.\n *\n * Extracted rather than inlined: `smart-capture.ts` is grandfathered shrink-only\n * under STD-2 / DEC-1504, so the additions are paid for here (same reasoning as\n * `lib/textMatch.ts` in this PR) instead of widening that file's baseline.\n */\n// zod/v3 — must match smart-capture.ts's specifier exactly; a bare \"zod\" import resolves\n// to v4 here and the two instances' types are not assignable across a z.union().\nimport { z } from \"zod/v3\";\nimport { success, type NextAction } from \"../envelope.js\";\n// WP-575 review round (P1, TEN-1126): the outcome-unknown cohort (type, split, structured\n// mapping, zod shape, rendering) is ONE responsibility shared with smart-capture.ts's\n// real-create batch path — see that module's doc comment for the full reasoning.\nimport {\n splitBatchNotOk,\n unknownOutcomeEntrySchema,\n unknownOutcomeSummaryNote,\n renderOutcomeUnknownSection,\n type BatchTimeoutOutcome,\n type UnknownOutcomeEntry,\n} from \"./batchTimeoutCohort.js\";\n\n// Re-exported so smart-capture.ts's real-create batch path can pull the whole outcome-unknown\n// cohort API (used identically on both batch surfaces) from ONE import specifier.\nexport { splitBatchNotOk, describeBatchEntryOutcome, unknownOutcomeSummaryNote, renderOutcomeUnknownSection, type BatchTimeoutOutcome, type UnknownOutcomeEntry } from \"./batchTimeoutCohort.js\";\n\n/**\n * The real-create branch of the `capture action=batch` output contract. Moved here from\n * smart-capture.ts (STD-2 / DEC-1504 shrink-only) so both branches of the batch contract\n * and the builder that produces the preview one live in a single cohesive module —\n * re-exported from smart-capture.ts for existing importers.\n */\nexport const batchCaptureRealOutputSchema = z.object({\n captured: z.array(z.object({\n entryId: z.string(),\n collection: z.string(),\n name: z.string(),\n // \"draft_on_failure\" is the status emitted when an auto-commit is REFUSED/failed (the entry\n // stays a draft) — the same path that now also emits coherencyRefusal. The strict schema must\n // accept it or a refused response fails to validate on `status` (codex review, completing the\n // coherencyRefusal contract fix).\n status: z.enum([\"draft\", \"committed\", \"proposed\", \"draft_on_failure\"]),\n classifiedBy: z.enum([\"llm\", \"heuristic\", \"explicit\"]).optional(),\n confidence: z.number().optional(),\n confidenceTier: z.enum([\"high\", \"medium\", \"low\"]).optional(),\n warnings: z.array(z.string()).optional(),\n normalization: z.object({\n remapped: z.record(z.string()).optional(),\n rejected: z.array(z.string()).optional(),\n }).optional(),\n // TEN-2365: capture-time authority-domain proposal slug (PENDING ratification), when filed.\n domain: z.string().optional(),\n // WP-465 surface parity: structured coherency refusal for a gate-refused auto-commit (batch\n // shape). Loose record — same single-source rationale as captureSuccessOutputSchema.\n coherencyRefusal: z.record(z.unknown()).optional(),\n // WP-485 Slice 2b round 4 (Codex P2, FEAT-1370): per-entry contradiction advisory, emitted\n // into structuredContent but previously undeclared here. Not `.strict()` so this one was\n // silently stripped rather than rejected — declared anyway so batch consumers actually see it.\n contradictionAdvisory: z.record(z.unknown()).optional(),\n })),\n total: z.number(),\n failed: z.number(),\n committed: z.number(),\n proposed: z.number(),\n drafts: z.number(),\n classified: z.number().optional(),\n autoCommitApplied: z.boolean(),\n skippedLowConfidence: z.array(z.object({\n index: z.number(),\n name: z.string(),\n suggestedCollection: z.string().optional(),\n confidence: z.number().optional(),\n alternatives: z.array(z.object({\n collection: z.string(),\n confidence: z.number(),\n })).optional(),\n })).optional(),\n failedEntries: z.array(z.object({\n index: z.number(),\n collection: z.string(),\n name: z.string(),\n error: z.string(),\n })).optional(),\n // WP-575 review round (P1, TEN-1126): a DISTINCT cohort from `failedEntries` — additive,\n // never removes or retypes an existing field (repo's schema rule). See\n // lib/batchTimeoutCohort.ts's doc comment for why this must stay separate.\n unknownOutcomeEntries: z.array(unknownOutcomeEntrySchema).optional(),\n});\n\n/**\n * The batch-preview branch of the `capture` output contract — a DIFFERENT shape from a\n * real batch: no `captured`/`drafts`/`committed` (nothing was written, so reporting\n * draft counts would lie), and `wouldCapture` entries carry no `status` for the same\n * reason. Lives beside its builder so the two cannot drift.\n */\nexport const batchCapturePreviewOutputSchema = z.object({\n outcome: z.literal(\"preview\"),\n wouldCapture: z.array(z.object({\n // Fix 1 (WP-577 review re-review, TEN-2918 follow-up): optional, not required — see\n // WouldCaptureEntry's doc comment. Absent exactly when `entryIdAssignedAtCapture` is true.\n entryId: z.string().optional(),\n entryIdAssignedAtCapture: z.literal(true).optional(),\n collection: z.string(),\n name: z.string(),\n classifiedBy: z.string().optional(),\n confidence: z.number().optional(),\n warnings: z.array(z.string()).optional(),\n })),\n // WP-577 review follow-up (P2, TEN-2918): entries the server's WHY/glossary gate says would\n // be BLOCKED on a real (non-preview) create — a distinct cohort from `wouldCapture` so the\n // structured response never claims a governance-refused capture would succeed. Optional/\n // additive: absent (or empty) on every response this route produced before this fix.\n wouldBlock: z.array(z.object({\n entryId: z.string().optional(),\n entryIdAssignedAtCapture: z.literal(true).optional(),\n collection: z.string(),\n name: z.string(),\n blockingReason: z.string().optional(),\n warnings: z.array(z.string()).optional(),\n })).optional(),\n requested: z.number(),\n total: z.number(),\n failed: z.number(),\n skippedLowConfidence: z.array(z.object({\n index: z.number(),\n name: z.string(),\n suggestedCollection: z.string().optional(),\n confidence: z.number().optional(),\n })).optional(),\n failedEntries: z.array(z.object({\n index: z.number(),\n collection: z.string(),\n name: z.string(),\n error: z.string(),\n })).optional(),\n // WP-575 review round (P1, TEN-1126): sibling of the same field on\n // batchCaptureRealOutputSchema — preview batches reach the SAME unconditional\n // `chain.createEntry` catch a real batch does, so the discriminator exists here too.\n unknownOutcomeEntries: z.array(unknownOutcomeEntrySchema).optional(),\n});\n\n/** The full batch output contract: a real create, or a preview. Mirrors captureOutputSchema's union shape on the single path. */\nexport const batchCaptureOutputSchema = z.union([\n batchCaptureRealOutputSchema,\n batchCapturePreviewOutputSchema,\n]);\n\n/**\n * One entry the batch WOULD have created. Deliberately never carries `status` — there is no\n * persisted entry to have one.\n *\n * Fix 1 (WP-577 review re-review, TEN-2918 follow-up): `entryId` is present ONLY when the\n * caller supplied it explicitly for that item. A batch preview cannot predict an auto-allocated\n * ID: each `createEntry` call is independent and stateless (`peekNextEntryId` reads the same\n * counter row without advancing it — TEN-2918's original fix), and IDs are allocated\n * per-collection-prefix server-side, so two auto-ID entries sharing a prefix within ONE preview\n * batch would both `peekNextEntryId` the SAME next value. A real (non-preview) batch instead\n * allocates them consecutively, advancing the counter after each write — the two paths cannot\n * agree, so reporting the predicted value here would silently duplicate it across every\n * auto-ID item and mislead a caller planning links off the receipt. `entryIdAssignedAtCapture`\n * is set instead whenever `entryId` is omitted for this reason.\n */\nexport type WouldCaptureEntry = {\n entryId?: string;\n entryIdAssignedAtCapture?: boolean;\n collection: string;\n name: string;\n classifiedBy?: string;\n confidence?: number;\n warnings?: string[];\n};\n\n/**\n * One entry the batch WOULD have had BLOCKED on a real (non-preview) create — e.g. a governed\n * capture missing its required WHY, or a glossary insert-block (createEntryPreview.ts's\n * `wouldBlock`/`blockingReason`). Kept distinct from `WouldCaptureEntry` so the preview surface\n * never reports a would-be-refused capture as would-succeed (WP-577 review follow-up, P2,\n * TEN-2918).\n */\nexport type WouldBlockEntry = {\n // Fix 1 (TEN-2918 follow-up): same caller-supplied-only rule as WouldCaptureEntry.entryId —\n // a would-block verdict is still keyed off a predicted ID, subject to the same collision.\n entryId?: string;\n entryIdAssignedAtCapture?: boolean;\n collection: string;\n name: string;\n blockingReason?: string;\n warnings?: string[];\n};\n\nexport type BatchPreviewInput = {\n /** Entries the batch would have written, in result order. */\n wouldCapture: WouldCaptureEntry[];\n /** Entries the server says would be BLOCKED on a real create (governance/glossary gates). */\n wouldBlock?: WouldBlockEntry[];\n /** Entries that failed before any write would have happened. */\n failed: Array<{ index: number; collection: string; name: string; error: string }>;\n /**\n * WP-575 review round (P1, TEN-1126): entries whose `chain.createEntry` gateway-timed-out —\n * outcome unknown, NOT proven failed. Kept out of `failed` on purpose (see\n * `UnknownOutcomeEntry`'s doc comment).\n */\n unknownOutcome?: UnknownOutcomeEntry[];\n /** Entries skipped because classification confidence was too low. */\n skipped: Array<{ index: number; name: string; suggestedCollection?: string; confidence?: number }>;\n /** Size of the caller's original `items[]`. */\n requested: number;\n /**\n * The caller's original batch payload (one entry per `items[]` element), threaded through so\n * the \"Capture for real\" next-action can supply a schema-valid, non-empty `items` array\n * instead of the unusable `{ action: \"batch\" }` alone (WP-577 review follow-up, P2, TEN-2918).\n * Omitted (or empty) callers get no \"Capture for real\" next-action rather than a broken one.\n */\n originalItems?: unknown[];\n /**\n * Fix 1 (WP-577 review round 3, TEN-2918 follow-up): the batch's own top-level `autoCommit`,\n * threaded into the \"Capture for real\" next-action so a caller who previewed with\n * `autoCommit: false` doesn't silently get the DEFAULT auto-commit behavior on retry — the\n * exact `buildCaptureForRealNextAction`/`captureForRealAction.ts` trap on the single path,\n * mirrored here. `undefined` (never supplied) is omitted so the server's own default still\n * governs; `false` is an explicit caller choice and MUST survive — never dropped as falsy.\n */\n originalAutoCommit?: boolean;\n};\n\n/**\n * Builds the summary line. Mirrors the single path's \"— no DB writes\" suffix so both\n * capture surfaces read the same way, and never uses the word \"captured\" (past tense\n * on a dry run is precisely the lie this module exists to prevent).\n */\nexport function buildBatchPreviewSummary({ wouldCapture, wouldBlock = [], failed, unknownOutcome = [], skipped, requested }: BatchPreviewInput): string {\n const noun = requested === 1 ? \"entry\" : \"entries\";\n const blockedNote = wouldBlock.length > 0 ? `, ${wouldBlock.length} would be BLOCKED` : \"\";\n const failedNote = failed.length > 0 ? `, ${failed.length} would fail` : \"\";\n const unknownNote = unknownOutcomeSummaryNote(unknownOutcome);\n const skippedNote = skipped.length > 0 ? `, ${skipped.length} skipped (low confidence)` : \"\";\n return `Preview: would capture ${wouldCapture.length} of ${requested} ${noun}${blockedNote}${failedNote}${unknownNote}${skippedNote} — no DB writes.`;\n}\n\n/**\n * The full batch-preview tool result — markdown body + structured envelope.\n *\n * `next` offers ONLY \"capture for real\", and only when `originalItems` was supplied —\n * `capture action=batch` requires a non-empty `items[]` (batchCaptureSchema `.min(1)`), so a\n * next-action with no items would fail argument validation the instant an agent followed it\n * (WP-577 review follow-up, P2, TEN-2918). It otherwise deliberately omits both actions the\n * real-create path offers: `entries action=commit` (would target an entry that does not exist)\n * and `relations action=suggest` (same). An agent following a `next` hint into a 404 — or a\n * validation error — is worse than no hint.\n */\n/** One `created` entry as seen by the preview-cohort split — the fields `buildBatchPreviewFromResults` reads off `handleBatchCapture`'s per-entry result, never the full internal result shape. */\nexport type BatchCreatedForPreview = {\n entryId: string;\n collection: string;\n name: string;\n classifiedBy?: string;\n confidence?: number;\n warnings?: string[];\n // WP-577 review follow-up (P2, TEN-2918): this entry's own would-block verdict\n // (createEntryPreview.ts's `wouldBlock`/`blockingReason`), undefined on the real-create path.\n wouldBlock?: boolean;\n blockingReason?: string;\n // Fix 1 (TEN-2918 follow-up): true when `entryId` was auto-allocated (no caller-supplied\n // `entryId` for this item) — see WouldCaptureEntry's doc comment.\n entryIdAssignedAtCapture?: boolean;\n};\n\nexport type BatchFailedForPreview = {\n entryIdx: number;\n collection: string;\n name: string;\n error?: string;\n // WP-575 review round (P1, TEN-1126): set only when this failure came from a\n // `chain.createEntry` gateway timeout — see `BatchTimeoutOutcome`'s doc comment. Presence\n // (not the boolean fields inside it) is the discriminator `buildBatchPreviewFromResults`\n // filters on to route this entry to `unknownOutcome` instead of `failed`.\n timeoutOutcome?: BatchTimeoutOutcome;\n};\n\nexport type BatchSkippedForPreview = { index: number; name: string; suggestedCollection?: string; confidence?: number };\n\n/**\n * The shared shape of a batch entry's early/mid-loop failure result — `handleBatchCapture`'s\n * \"collection not found\", \"entryId not allowed\" (BR-111), chunk-flush-catch, and outer-catch\n * sites all built this exact literal by hand (`entryId: \"\"`, `ok: false`, `autoLinks: 0`,\n * `advisedLinks: 0`, `status: \"draft\"`) with only `entryIdx`/`name`/`collection`/classification/\n * `error` varying. Extracted here (STD-2 / DEC-1504 shrink-only — `smart-capture.ts` is\n * grandfathered over budget, so new call sites pay their cost here, never by widening it) so the\n * four call sites read as one line each instead of repeating the same 10-field literal.\n */\nexport function buildBatchEntryFailure(args: {\n entryIdx: number;\n name: string;\n collection: string;\n classifiedBy: \"llm\" | \"heuristic\" | \"explicit\" | undefined;\n confidence: number | undefined;\n confidenceTier: \"high\" | \"medium\" | \"low\" | undefined;\n error: string;\n // WP-575 review round (P1, TEN-1126/TEN-2917): set by the ONE call site\n // (smart-capture.ts's outer per-entry catch) that can observe a `chain.createEntry`\n // gateway timeout — see `BatchTimeoutOutcome`'s doc comment. Every other caller of this\n // builder (\"collection not found\", BR-111 entryId rejection, chunk-flush-catch) fails\n // before or independent of that mutation, so they never pass this.\n timeoutOutcome?: BatchTimeoutOutcome;\n}) {\n return {\n entryIdx: args.entryIdx,\n name: args.name,\n collection: args.collection,\n entryId: \"\",\n ok: false as const,\n autoLinks: 0,\n advisedLinks: 0,\n status: \"draft\" as const,\n classifiedBy: args.classifiedBy,\n confidence: args.confidence,\n confidenceTier: args.confidenceTier,\n error: args.error,\n ...(args.timeoutOutcome ? { timeoutOutcome: args.timeoutOutcome } : {}),\n };\n}\n\n/**\n * Splits a batch's `created` cohort into wouldCapture/wouldBlock, maps `failed`/`skipped`\n * into the preview shapes, and builds the full preview result. Moved out of\n * `handleBatchCapture` (STD-2 / DEC-1504 shrink-only, smart-capture.ts is grandfathered\n * over-budget) — this module already owns the preview output contract, so the\n * cohort-splitting + mapping that feeds it belongs beside it, not in the tool handler.\n */\nexport function buildBatchPreviewFromResults(\n created: BatchCreatedForPreview[],\n failed: BatchFailedForPreview[],\n skipped: BatchSkippedForPreview[],\n requested: number,\n originalItems: unknown[],\n // Fix 1 (TEN-2918 follow-up): the batch's own `autoCommit` — see BatchPreviewInput's\n // `originalAutoCommit` doc comment for why `false` must survive this parameter untouched.\n originalAutoCommit?: boolean,\n) {\n // WP-577 review follow-up (P2, TEN-2918): split `created` into the entries the server\n // says would actually be written vs. the ones it says would be BLOCKED (governance WHY\n // gate, glossary insert-block, etc.) — reporting a would-block item under `wouldCapture`\n // told the caller a governed capture would succeed when the real (non-preview) call\n // would be rejected at the same gate.\n const wouldCaptureEntries = created.filter((r) => !r.wouldBlock);\n const wouldBlockEntries = created.filter((r) => r.wouldBlock);\n const { failed: genuinelyFailed, unknownOutcome: timedOut } = splitBatchNotOk(failed);\n return buildBatchPreviewResult({\n // Fix 1 (TEN-2918 follow-up): report the concrete `entryId` only when it was NOT\n // auto-allocated (i.e. the caller supplied it for this item) — see WouldCaptureEntry's\n // doc comment for why an auto-ID cannot be predicted per-item within a preview batch.\n wouldCapture: wouldCaptureEntries.map((r) => ({\n ...(r.entryIdAssignedAtCapture ? { entryIdAssignedAtCapture: true as const } : { entryId: r.entryId }),\n collection: r.collection,\n name: r.name,\n ...(r.classifiedBy ? { classifiedBy: r.classifiedBy } : {}),\n ...(r.confidence != null ? { confidence: r.confidence } : {}),\n ...(r.warnings?.length ? { warnings: r.warnings } : {}),\n })),\n wouldBlock: wouldBlockEntries.map((r) => ({\n ...(r.entryIdAssignedAtCapture ? { entryIdAssignedAtCapture: true as const } : { entryId: r.entryId }),\n collection: r.collection,\n name: r.name,\n ...(r.blockingReason ? { blockingReason: r.blockingReason } : {}),\n ...(r.warnings?.length ? { warnings: r.warnings } : {}),\n })),\n failed: genuinelyFailed.map((r) => ({ index: r.entryIdx, collection: r.collection, name: r.name, error: r.error ?? \"unknown error\" })),\n unknownOutcome: timedOut, // WP-575 review (P1, TEN-1126) — see lib/batchTimeoutCohort.ts.\n skipped: skipped.map((s) => ({ index: s.index, name: s.name, ...(s.suggestedCollection ? { suggestedCollection: s.suggestedCollection } : {}), ...(s.confidence != null ? { confidence: s.confidence } : {}) })),\n requested,\n // WP-577 review follow-up (P2, TEN-2918): thread the caller's original batch payload\n // through so the \"Capture for real\" next-action can supply a non-empty `items` array —\n // omitting it left the suggestion advertising `{ action: \"batch\" }` alone, which fails\n // batchCaptureSchema's `.min(1)` items requirement the instant an agent follows it.\n originalItems,\n // Fix 1 (TEN-2918 follow-up): thread the batch's own autoCommit through unchanged.\n originalAutoCommit,\n });\n}\n\nexport function buildBatchPreviewResult(input: BatchPreviewInput) {\n const { wouldCapture, wouldBlock = [], failed, unknownOutcome = [], skipped, requested, originalItems, originalAutoCommit } = input;\n const summary = buildBatchPreviewSummary(input);\n\n const lines: string[] = [`# Batch Preview — No Entries Created`, summary, \"\"];\n\n if (wouldCapture.length > 0) {\n lines.push(\"## Would capture\");\n for (const r of wouldCapture) {\n const classNote = r.classifiedBy && r.classifiedBy !== \"explicit\" ? ` (${r.classifiedBy}${r.confidence != null ? ` ${r.confidence}%` : \"\"})` : \"\";\n const warnNote = r.warnings?.length ? ` — ${r.warnings.join(\"; \")}` : \"\";\n // Fix 1 (TEN-2918 follow-up): only render a concrete ID; an auto-allocated one is never\n // predictable per-item within a preview batch (see WouldCaptureEntry's doc comment).\n const idNote = r.entryId ? `**${r.entryId}**: ` : \"\";\n const assignedNote = r.entryIdAssignedAtCapture ? \" (ID assigned at capture)\" : \"\";\n lines.push(`- ${idNote}**${r.name}** [${r.collection}]${classNote}${warnNote}${assignedNote}`);\n }\n lines.push(\"\");\n }\n\n if (wouldBlock.length > 0) {\n lines.push(\"## Would be BLOCKED\");\n for (const b of wouldBlock) {\n const reasonNote = b.blockingReason ? ` — ${b.blockingReason}` : \"\";\n const idNote = b.entryId ? `**${b.entryId}**: ` : \"\";\n const assignedNote = b.entryIdAssignedAtCapture ? \" (ID assigned at capture)\" : \"\";\n lines.push(`- ${idNote}**${b.name}** [${b.collection}]${reasonNote}${assignedNote}`);\n }\n lines.push(\"\");\n }\n\n if (skipped.length > 0) {\n lines.push(\"## Would be skipped — low confidence\");\n for (const s of skipped) {\n const suggestion = s.suggestedCollection ? ` — best guess: \\`${s.suggestedCollection}\\`${s.confidence != null ? ` (${s.confidence}%)` : \"\"}` : \" — no classification available\";\n lines.push(`- **[${s.index}]** ${s.name}${suggestion}`);\n }\n lines.push(\"\");\n }\n\n if (failed.length > 0) {\n lines.push(\"## Would fail\");\n for (const f of failed) {\n lines.push(`- **[${f.index}]** ${f.name} [${f.collection}]: _${f.error}_`);\n }\n lines.push(\"\");\n }\n\n // WP-575 review round (P1, TEN-1126): see lib/batchTimeoutCohort.ts — shared with the\n // real-create batch path so this section can never drift out of sync with it.\n lines.push(...renderOutcomeUnknownSection(unknownOutcome));\n\n lines.push(\"_No DB writes — call `capture action=batch` without `preview:true` to capture for real._\");\n\n const next: NextAction[] =\n originalItems && originalItems.length > 0\n ? [{\n tool: \"capture\",\n description: \"Capture for real\",\n parameters: {\n action: \"batch\",\n items: originalItems,\n // Fix 1 (WP-577 review round 3, TEN-2918 follow-up): preserve the batch's own\n // autoCommit explicitly — `false` must survive (never dropped as falsy), and\n // `undefined` (never supplied) is omitted so the server default still governs.\n ...(originalAutoCommit !== undefined ? { autoCommit: originalAutoCommit } : {}),\n },\n }]\n : [];\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: {\n ...success(\n summary,\n {\n outcome: \"preview\" as const,\n wouldCapture,\n ...(wouldBlock.length > 0 ? { wouldBlock } : {}),\n requested,\n total: wouldCapture.length,\n failed: failed.length,\n ...(skipped.length > 0 ? { skippedLowConfidence: skipped } : {}),\n ...(failed.length > 0 ? { failedEntries: failed } : {}),\n // WP-575 review round (P1, TEN-1126): structured sibling of `failedEntries` — see\n // `UnknownOutcomeEntry`'s doc comment for why these are never merged into it.\n ...(unknownOutcome.length > 0 ? { unknownOutcomeEntries: unknownOutcome } : {}),\n },\n next,\n ),\n },\n };\n}\n","/**\n * batchTimeoutCohort.ts — WP-575 review round (P1, TEN-1126/TEN-2917).\n *\n * One self-contained responsibility: recognizing a batch entry whose `chain.createEntry`\n * gateway-timed-out, and keeping it in its own \"outcome unknown\" cohort everywhere a batch\n * result is reported — the split, the structured `unknownOutcomeEntries` mapping, the zod\n * shape, the \"## Outcome Unknown — Not Failed\" markdown section, and the summary note. It\n * must never be folded into `failed`/`failedEntries`, which every batch surface already\n * treats as \"safe to retry individually\" — that is the exact ghost-entry duplication\n * TEN-1126 exists to prevent.\n *\n * Shared by BOTH `tools/smart-capture.ts` (the real-create batch path) and\n * `lib/batchCaptureOutput.ts` (the preview batch path) — the preview path hits the SAME\n * unconditional try/catch a real batch does, so this cohort exists on both branches.\n * Extracted (STD-2 / DEC-1504 shrink-only) rather than duplicated in each: this\n * responsibility, written out twice, is what pushed both call sites over their\n * module-health budget — one module, one job, imported by both.\n */\nimport { z } from \"zod/v3\";\nimport { isGatewayTimeout, describeBatchEntryError } from \"./captureTimeoutOutcome.js\";\n\nexport type BatchTimeoutOutcome = {\n mayHaveLanded: boolean;\n budgetMs: number;\n elapsedMs: number;\n};\n\n/** The structured shape both batch surfaces emit under `unknownOutcomeEntries`. */\nexport type UnknownOutcomeEntry = {\n index: number;\n collection: string;\n name: string;\n error: string;\n mayHaveLanded: boolean;\n budgetMs: number;\n elapsedMs: number;\n};\n\n/**\n * Shared zod fragment — `batchCaptureRealOutputSchema` and `batchCapturePreviewOutputSchema`\n * both wrap this the same way (`z.array(unknownOutcomeEntrySchema).optional()`), so the\n * shape lives once instead of twice.\n */\nexport const unknownOutcomeEntrySchema = z.object({\n index: z.number(),\n collection: z.string(),\n name: z.string(),\n error: z.string(),\n mayHaveLanded: z.boolean(),\n budgetMs: z.number(),\n elapsedMs: z.number(),\n});\n\n/**\n * Did this catch observe a `chain.createEntry` gateway timeout? Carries the same\n * `mayHaveLanded`/`budgetMs`/`elapsedMs` signal the single-capture path already surfaces\n * (`captureTimeoutOutcome.ts`'s `buildCaptureOutcomeUnknownResult`) onto one batch entry.\n */\nexport function deriveTimeoutOutcome(error: unknown): BatchTimeoutOutcome | undefined {\n return isGatewayTimeout(error)\n ? { mayHaveLanded: error.mayHaveLanded, budgetMs: error.budgetMs, elapsedMs: error.elapsedMs }\n : undefined;\n}\n\n/** One call for a batch entry's catch: the error message plus its timeout signal, spread straight into `buildBatchEntryFailure`. */\nexport function describeBatchEntryOutcome(error: unknown, entryName: string): { error: string; timeoutOutcome?: BatchTimeoutOutcome } {\n return { error: describeBatchEntryError(error, entryName), timeoutOutcome: deriveTimeoutOutcome(error) };\n}\n\n/**\n * Splits a batch's not-ok cohort into genuinely-failed (untouched, caller's own shape) vs.\n * outcome-unknown (already mapped to the structured `unknownOutcomeEntries` shape) — one\n * call replaces a filter-by-`timeoutOutcome` plus a separate map at every call site.\n */\nexport function splitBatchNotOk<\n T extends { entryIdx: number; collection: string; name: string; error?: string; timeoutOutcome?: BatchTimeoutOutcome },\n>(notOk: readonly T[]): { failed: T[]; unknownOutcome: UnknownOutcomeEntry[] } {\n return {\n failed: notOk.filter((r) => !r.timeoutOutcome),\n unknownOutcome: notOk.filter((r) => r.timeoutOutcome).map((r) => ({\n index: r.entryIdx,\n collection: r.collection,\n name: r.name,\n error: r.error ?? \"unknown error\",\n mayHaveLanded: r.timeoutOutcome!.mayHaveLanded,\n budgetMs: r.timeoutOutcome!.budgetMs,\n elapsedMs: r.timeoutOutcome!.elapsedMs,\n })),\n };\n}\n\n/** \", N outcome unknown\" summary-line note — \"\" when the cohort is empty. Named distinctly from a \"failed\" note so a caller can never fold the two together. */\nexport function unknownOutcomeSummaryNote(entries: readonly unknown[]): string {\n return entries.length > 0 ? `, ${entries.length} outcome unknown` : \"\";\n}\n\n/**\n * The \"## Outcome Unknown — Not Failed\" markdown block both batch surfaces render — `[]`\n * when the cohort is empty, so a caller can always `lines.push(...renderOutcomeUnknownSection(...))`\n * unconditionally, no `if` needed. Distinct from \"## Failed\"/\"## Would fail\" on purpose:\n * these entries' writes may have landed, so they are never presented as safe to retry.\n */\nexport function renderOutcomeUnknownSection(entries: readonly UnknownOutcomeEntry[]): string[] {\n if (entries.length === 0) return [];\n // The footer follows the cohort's own `mayHaveLanded`, not the section's name (PR #533\n // review, Codex P2). On the PREVIEW batch path nothing can have landed, and this block is\n // rendered a few lines above that surface's own \"_No DB writes_\" note — so a fixed\n // duplicate-warning made one response state both. `some`, not `every`: a single entry that\n // may have landed is enough to owe the caller the search.\n const anyMayHaveLanded = entries.some((e) => e.mayHaveLanded);\n return [\n \"\",\n \"## Outcome Unknown — Not Failed\",\n ...entries.map((e) => `- ${e.name} [${e.collection}]: _${e.error}_`),\n \"\",\n anyMayHaveLanded\n ? \"_Do NOT retry these individually — search for each name first (see `unknownOutcomeEntries` in the structured response); a retry may duplicate an entry that already landed._\"\n : \"_Nothing was written for these — the preview returns before any write, so re-running is safe. Only the validation verdict is missing._\",\n ];\n}\n","/**\n * Narrowing helper for the `chain.createEntry` gateway route's return type.\n *\n * WP-577 / TEN-2918: the route's declared return type is an honest union that includes\n * the preview branch (convex/agentKnowledge/entries.ts + createEntryPreview.ts).\n * tools/smart-capture.ts has two call sites that need this discriminant —\n * `handleCapture`'s single-entry path and `handleBatchCapture`'s per-entry loop — this\n * is the one shared predicate both use, instead of each hand-rolling its own inline\n * `\"preview\" in result && result.preview` copy.\n *\n * `packages/mcp-server` may not import from `convex/` (scripts/check-mcp-boundaries.mjs),\n * so this is a local structural copy of convex/agentKnowledge/createEntryPreview.ts's\n * `isCreateEntryPreview` — the same duplication packages/cli/src/lib/createEntryResult.ts\n * carries for the same reason. Deliberately tiny and behaviour-free so the duplication\n * cannot drift meaningfully — the discriminant is the presence (and truthiness) of the\n * `preview` key, which is part of the route's public response contract.\n *\n * A plain inline `'preview' in result` check does not reliably narrow the ELSE branch\n * for this generated union shape — an explicit predicate function does (the same\n * limitation is documented in convex/agentKnowledge/createEntryPreview.ts and\n * packages/cli/src/lib/createEntryResult.ts).\n */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\n\nexport type CreateEntryRouteResult = GatewayRouteReturnByName<\"chain.createEntry\">;\n\nexport type CreateEntryPreviewRouteResult = Extract<CreateEntryRouteResult, { preview: true }>;\n\n/** True when the `chain.createEntry` route returned its preview branch. */\nexport function isPreviewCreateEntryResult(\n result: CreateEntryRouteResult,\n): result is CreateEntryPreviewRouteResult {\n return \"preview\" in result && result.preview === true;\n}\n\n/**\n * WP-577 review follow-up (P2, TEN-2918): the preview union member carries\n * `wouldBlock`/`blockingReason` (CreateEntryPreviewMutationResult,\n * convex/agentKnowledge/createEntryPreview.ts:63-80). Callers must read this BEFORE\n * casting the union down to its real-create member (which discards the preview member\n * entirely) — otherwise a batch preview item the server says would be BLOCKED (e.g. a\n * governed capture missing its required WHY) gets silently folded into `wouldCapture`\n * instead of reported honestly. Returns undefined outside a preview call, or when the\n * route didn't return its preview branch (a real create — nothing to extract).\n */\nexport function extractPreviewWouldBlock(\n result: CreateEntryRouteResult | undefined,\n preview: boolean | undefined,\n): { wouldBlock: boolean; blockingReason?: string } | undefined {\n return preview && result && isPreviewCreateEntryResult(result)\n ? { wouldBlock: result.wouldBlock === true, blockingReason: result.blockingReason }\n : undefined;\n}\n\n/**\n * P0 review round 4 (fix 1/3, root): resolves the EFFECTIVE (post-routing) collection a\n * `chain.createEntry` preview call reports — `createEntryPreview.ts`'s `collection` field on\n * `CreateEntryPreviewMutationResult`, which `prepareCreateEntry` sets to the collectionSlug\n * AFTER `resolveCreateEntryRouting`'s redirect (e.g. a caller-supplied `collectionSlug: \"chains\"`\n * for a bet-shaped payload routes to \"work-packages\"). Both of `smart-capture.ts`'s preview call\n * sites — `handleCapture`'s single path and `handleBatchCapture`'s per-entry loop — need this\n * instead of echoing the caller's pre-routing `collectionSlug` in their preview receipts; the\n * batch loop additionally feeds it to `reconcileBatchPreviewDuplicate`\n * (lib/batchPreviewDuplicates.ts, fix 2/3) to catch a later item routing into an earlier item's\n * destination. Falls back to `fallbackCollection` outside a preview call, when the route didn't\n * return its preview branch, or (older/absent field) when the preview branch itself somehow\n * lacks `collection` — additive, never re-derives routing client-side.\n */\nexport function resolveEffectiveCollection(\n result: CreateEntryRouteResult | undefined,\n preview: boolean | undefined,\n fallbackCollection: string,\n): string {\n return preview && result && isPreviewCreateEntryResult(result)\n ? result.collection ?? fallbackCollection\n : fallbackCollection;\n}\n","/**\n * Shared entry-data normalization helpers used by both `handleCapture` (single) and\n * `handleBatchCapture` (batch) in tools/smart-capture.ts, right before the\n * `chain.createEntry` call: value-emptiness checks (used to decide whether a\n * decomposed-content field should overwrite a user-supplied one) and select-field\n * canonicalization (fuzzy-match a supplied select value against the collection's\n * declared options). Extracted rather than inlined: smart-capture.ts is grandfathered\n * shrink-only under STD-2 / DEC-1504, so these additions are paid for here instead of\n * widening that file's baseline. Pure and self-contained — no dependency on the tool's\n * request/response shapes.\n */\n\n/** Returns true if a value should be considered empty (null, empty array, or blank string). */\nexport function isEmptyValue(v: unknown): boolean {\n return v == null || (Array.isArray(v) ? v.length === 0 : String(v).trim() === \"\");\n}\n\n/** Returns true if a value should be considered non-empty (opposite of isEmptyValue). */\nexport function isNonEmptyValue(v: unknown): boolean {\n return v != null && (Array.isArray(v) ? v.length > 0 : String(v).trim() !== \"\");\n}\n\n/** Levenshtein distance for fuzzy select matching. DEC-173: fix when possible, never silently accept. */\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array(m + 1)\n .fill(null)\n .map(() => Array(n + 1).fill(0));\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost);\n }\n }\n return dp[m][n];\n}\n\nconst APPETITE_OPTIONS = [\"small\", \"medium\", \"large\"] as const;\n\nfunction findClosestOption(value: string, options: readonly string[]): { opt: string; dist: number } {\n const lower = value.toLowerCase();\n const exact = options.find((o) => o.toLowerCase() === lower);\n if (exact) return { opt: exact, dist: 0 };\n return options.reduce(\n (acc, opt) => {\n const d = levenshtein(lower, opt.toLowerCase());\n return d < acc.dist ? { opt, dist: d } : acc;\n },\n { opt: options[0], dist: Infinity },\n );\n}\n\n/**\n * Canonicalize select fields: if current value is not in options, find closest match.\n * Case-insensitive exact first, then Levenshtein distance. DEC-173: fix when possible.\n * BET-125 Slice 1: appetite (top-level before bet move), horizon, severity, priority from col.fields.\n */\nexport function canonicalizeSelects(\n data: Record<string, unknown>,\n fields: Array<{ key: string; type: string; options?: string[] }>,\n isBet: boolean,\n): void {\n if (isBet && data.appetite != null && typeof data.appetite === \"string\") {\n const val = data.appetite.trim();\n if (val) {\n const { opt, dist } = findClosestOption(val, APPETITE_OPTIONS);\n if (dist <= 4) data.appetite = opt;\n }\n }\n\n for (const field of fields) {\n if (field.type !== \"select\" || !field.options?.length) continue;\n if (field.key === \"appetite\" && isBet) continue;\n const val = data[field.key];\n if (val == null || typeof val !== \"string\") continue;\n const trimmed = val.trim();\n if (!trimmed) continue;\n const { opt, dist } = findClosestOption(trimmed, field.options);\n if (dist <= 4) data[field.key] = opt;\n }\n}\n","/**\n * TEN-957 (WP-484 S2) inline per-item relations for `capture action=batch` — extracted out of\n * `handleBatchCapture` (STD-2 / DEC-1504 shrink-only, smart-capture.ts is grandfathered\n * over-budget) so the preview-vs-real branch added here doesn't widen that file's baseline.\n *\n * Fix 2 (WP-577 review re-review, TEN-2918 follow-up): a preview batch's inline relations\n * always reported themselves as FAILED. `chain.createEntryRelation`\n * (convex/agentKnowledge/relations.ts:69-80) resolves `fromEntry` from the `entries` table and\n * throws `notFound` BEFORE any preview branch in that mutation runs. In a preview batch the\n * source entry (`finalEntryId`) was never persisted — `createEntry`'s own preview branch never\n * writes a doc — so every inline relation call was GUARANTEED to hit that NOT_FOUND, even\n * though the real (non-preview) capture creates the source first and links successfully\n * afterward. Reporting that as a failure told the caller a relation that WOULD succeed on a\n * real capture is broken.\n *\n * The fix (as first shipped): never call `chain.createEntryRelation` for a preview batch's\n * inline relations at all — count them as would-be-created instead, mirroring the\n * `batchAutoLinks` preview handling already in `handleBatchCapture` for the same underlying\n * reason.\n *\n * Fix 4 (WP-577 review round 3, TEN-2918 follow-up): that first fix replaced one lie with the\n * opposite lie. Counting every schema-valid `{to, type}` pair as \"would be created\" PROMISES an\n * edge with no target-existence check, no `governs` authorization check, and no `guardRelation`\n * policy check — the real (non-preview) path performs all three\n * (convex/agentKnowledge/relations.ts), so a missing target or a forbidden relation type can\n * fail, or resolve to an agent proposal instead of a write, even though the preview said it would\n * simply be created. This module deliberately does NOT attempt to reimplement target/policy\n * validation client-side (that is kernel logic — STD-2's connector boundary forbids it here, and\n * TEN-2278 already establishes connectors cannot import kernel/convex logic). The honest fix is\n * to under-promise: report this cohort as NOT VALIDATED in preview, never as would-succeed.\n */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelMutation } from \"../client.js\";\n\nexport type BatchInlineRelation = { to: string; type: string };\n\nexport type BatchInlineRelationsResult = {\n relationsCreatedCount: number;\n relationsProposedCount: number;\n // Fix 4 (TEN-2918 follow-up): named for what preview honestly knows — NOT for a predicted\n // outcome. Renamed from `relationsPreviewedCount`, which the caller-facing warning text read\n // as a promise (\"would be created\"). No target-existence check, no `governs` authorization\n // check, and no `guardRelation` policy check has run against this cohort — those are the real\n // path's kernel-side checks (convex/agentKnowledge/relations.ts), never reproduced here.\n relationsNotValidatedCount: number;\n relationsFailedList: string[];\n};\n\n/**\n * Applies (or, under `preview`, merely counts) one batch entry's inline relations.\n * `finalEntryId` is the entry these relations attach FROM — real on a non-preview create,\n * predicted-only (never persisted) on a preview one.\n */\nexport async function applyBatchInlineRelations(\n relations: BatchInlineRelation[] | undefined,\n finalEntryId: string,\n preview: boolean | undefined,\n agentId: string | null,\n): Promise<BatchInlineRelationsResult> {\n const result: BatchInlineRelationsResult = {\n relationsCreatedCount: 0,\n relationsProposedCount: 0,\n relationsNotValidatedCount: 0,\n relationsFailedList: [],\n };\n if (!relations || relations.length === 0) return result;\n\n if (preview) {\n // No write, no mutation call — see module doc comment for why this cohort can never\n // resolve `fromEntry` on a preview batch. Fix 4: NOT a promise these would be created —\n // target existence and relation policy are unchecked here; see the type's doc comment.\n result.relationsNotValidatedCount = relations.length;\n return result;\n }\n\n for (const rel of relations) {\n try {\n // Finding #14 (pre-existing): forward the returned status instead of discarding it — a\n // discarded result treated every non-throwing call as \"created\", including misuse-pattern\n // interceptions that only file an agent proposal (no edge written).\n const relResult = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelation\">>(\n \"chain.createEntryRelation\",\n {\n fromEntryId: finalEntryId,\n toEntryId: rel.to,\n type: rel.type,\n proposedBy: \"user\",\n sessionId: agentId ?? undefined,\n },\n );\n if (relResult?.status === \"agent_proposal_created\") {\n result.relationsProposedCount++;\n } else {\n result.relationsCreatedCount++;\n }\n } catch (relErr: unknown) {\n const relMsg = relErr instanceof Error ? relErr.message : String(relErr);\n result.relationsFailedList.push(`${rel.to} (${rel.type}): ${relMsg}`);\n }\n }\n return result;\n}\n","/**\n * Fix 3 (WP-577 review re-review, TEN-2918 follow-up, sibling of the batch-preview\n * `originalItems` fix in `lib/batchCaptureOutput.ts`): the single-capture preview's\n * \"Capture for real\" next-action used to advertise only\n * `{ collection, name, description }` — dropping `data`, `entryId`, `canonicalKey`, `links`,\n * `sourceRef`, `sourceExcerpt`, `autoCommit`, `ownerTeamEntryId`, `ownerRoleEntryId`. An agent\n * that followed the hint literally created a MATERIALLY DIFFERENT entry than the one the\n * preview said would succeed — e.g. a required WHY supplied via `data` disappeared and the\n * retry hit a governance block the preview never predicted.\n *\n * Extracted (rather than inlined at both call sites) so `smart-capture.ts` — grandfathered\n * shrink-only under STD-2 / DEC-1504 — pays for the extra fields here instead of widening its\n * own baseline, and so the single-capture preview branch and the `suggestOnly` grounding\n * preview (same underlying defect) share one source of truth instead of drifting.\n */\nimport type { NextAction } from \"../envelope.js\";\n\nexport type CaptureForRealPayload = {\n collection: string;\n name: string;\n description: string;\n context?: string;\n entryId?: string;\n canonicalKey?: string;\n data?: Record<string, unknown>;\n links?: Array<{ to: string; type: string }>;\n autoCommit?: boolean;\n sourceRef?: string;\n sourceExcerpt?: string;\n ownerTeamEntryId?: string;\n ownerRoleEntryId?: string;\n};\n\n/**\n * Builds the single \"Capture for real\" next-action, including every field the caller actually\n * supplied (omitting undefined/empty ones so the suggestion stays clean and additive-safe).\n */\nexport function buildCaptureForRealNextAction(payload: CaptureForRealPayload): NextAction[] {\n const {\n collection, name, description, context, entryId, canonicalKey, data, links,\n autoCommit, sourceRef, sourceExcerpt, ownerTeamEntryId, ownerRoleEntryId,\n } = payload;\n return [{\n tool: \"capture\",\n description: \"Capture for real\",\n parameters: {\n collection,\n name,\n description,\n ...(context ? { context } : {}),\n ...(entryId ? { entryId } : {}),\n ...(canonicalKey ? { canonicalKey } : {}),\n ...(data && Object.keys(data).length > 0 ? { data } : {}),\n ...(links && links.length > 0 ? { links } : {}),\n ...(autoCommit !== undefined ? { autoCommit } : {}),\n ...(sourceRef ? { sourceRef } : {}),\n ...(sourceExcerpt ? { sourceExcerpt } : {}),\n ...(ownerTeamEntryId ? { ownerTeamEntryId } : {}),\n ...(ownerRoleEntryId ? { ownerRoleEntryId } : {}),\n },\n }];\n}\n","/**\n * Rubric/coaching formatting helpers — extracted verbatim out of `tools/smart-capture.ts`\n * (STD-2 / DEC-1504 shrink-only: that file is grandfathered over-budget and may not grow) to\n * pay for this review round's additions elsewhere in that file (the round-3 fixes: threading\n * `autoCommit` through the batch preview next-action, the single-preview output schema member,\n * and the batch-local duplicate-name check).\n *\n * Pure, self-contained, and behaviour-unchanged by the move — re-exported from\n * smart-capture.ts (and imported there for its own internal call sites) so every existing\n * importer (`tools/knowledge.ts`, `tools/quality.ts`, test files importing from\n * `../tools/smart-capture.js`) keeps working unmodified, the same pattern already used for\n * `batchCaptureOutputSchema` (lib/batchCaptureOutput.ts).\n *\n * `withTimeout` has no remaining call site anywhere in this repo (verified by grep before the\n * move) — moved rather than deleted so this extraction stays a pure relocation with zero\n * behavioral risk; a follow-up cleanup can remove it separately if still dead.\n */\n\nexport function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return Promise.race([\n promise,\n new Promise<T>((_, reject) =>\n setTimeout(() => reject(new Error(\"quality coaching timeout\")), ms),\n ),\n ]);\n}\n\n/**\n * WP-480 S1 (FEAT-1358): a short capture-confirmation phrase derived from the\n * SERVER rubric verdict — replaces the deleted client `Quality N/10` recompute\n * (single scorer; DEC-1418 the connector owns the sentence). Passive/absent\n * verdicts (no rubric criteria) read as \"not evaluated\"; otherwise it reports the\n * rubric criteria pass count and points at the coaching already in the response.\n */\nexport function verdictQualityPhrase(\n result: { verdict?: { tier?: string; passed?: boolean; criteria?: Array<{ passed: boolean }> } } | null | undefined,\n): string {\n const v = result?.verdict;\n const criteria = v?.criteria ?? [];\n // \"No rubric\" is decided by whether the verdict HAS criteria — never by its tier.\n // Passive-tier types (tension, glossary) carry real rubric criteria, and for them the\n // heuristic IS the full judgment (the background LLM pass deliberately never runs).\n // Short-circuiting on tier === 'passive' therefore threw away a real verdict and told\n // the agent \"not evaluated\" while qualityVerdict recorded failing criteria.\n if (!v || criteria.length === 0) {\n return \"Quality: not evaluated (no rubric for this type).\";\n }\n const total = criteria.length;\n const passed = criteria.filter((c) => c.passed).length;\n return v.passed\n ? `Quality: all ${total} rubric criteria pass.`\n : `Quality: ${passed}/${total} rubric criteria pass — see the coaching above.`;\n}\n\n/**\n * Format a full quality coaching result (from evaluateAtCapture / evaluateAtCommit)\n * for inclusion in MCP capture/commit responses.\n */\nexport function formatRubricCoaching(result: any): string {\n const { verdict, rogerMartin } = result;\n if (!verdict || verdict.criteria.length === 0) return \"\";\n\n const lines: string[] = [\"## Semantic Quality\"];\n const failed = (verdict.criteria ?? []).filter((c: any) => !c.passed);\n const total = verdict.criteria?.length ?? 0;\n const passedCount = total - failed.length;\n\n if (verdict.passed) {\n lines.push(`All ${total} rubric criteria pass for \\`${verdict.canonicalKey}\\` (${verdict.tier} tier).`);\n } else {\n lines.push(`${passedCount}/${total} criteria pass for \\`${verdict.canonicalKey}\\` (${verdict.tier} tier)`);\n lines.push(\"\");\n for (const c of verdict.criteria) {\n const icon = c.passed ? \"[x]\" : \"[ ]\";\n const extra = c.passed ? \"\" : ` — ${c.hint}`;\n lines.push(`${icon} ${c.id}${extra}`);\n }\n\n if (verdict.weakest) {\n lines.push(\"\");\n lines.push(`**Coaching hint:** ${verdict.weakest.hint}`);\n lines.push(`_Question to consider:_ ${verdict.weakest.questionTemplate}`);\n }\n }\n\n if (rogerMartin) {\n lines.push(\"\");\n lines.push(\"### Roger Martin Test\");\n if (rogerMartin.isStrategicChoice) {\n lines.push(\"This principle passes — the opposite is a reasonable strategic choice.\");\n } else {\n lines.push(`This principle may not be a strategic choice. ${rogerMartin.reasoning}`);\n if (rogerMartin.suggestion) {\n lines.push(`_Suggestion:_ ${rogerMartin.suggestion}`);\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format a cached rubric verdict section for quality check responses.\n * SOS-e4r5cn: capability and visibility must ship together.\n */\nexport function formatRubricVerdictSection(verdict: any): string {\n if (!verdict || !verdict.criteria || verdict.criteria.length === 0) return \"\";\n\n const lines: string[] = [\"## Semantic Quality\"];\n const failed = verdict.criteria.filter((c: any) => !c.passed);\n const total = verdict.criteria.length;\n const passedCount = total - failed.length;\n\n const durationSuffix = verdict.llmDurationMs ? ` in ${(verdict.llmDurationMs / 1000).toFixed(1)}s` : '';\n const statusNote = verdict.llmStatus === 'pending'\n ? ' — LLM evaluation in progress...'\n : verdict.llmStatus === 'failed'\n ? ` — LLM evaluation failed${verdict.llmError ? `: ${verdict.llmError}` : ''}, showing heuristic results`\n : verdict.source === 'llm' && durationSuffix\n ? ` — evaluated${durationSuffix}`\n : '';\n\n if (failed.length === 0) {\n lines.push(`All ${total} rubric criteria pass for \\`${verdict.canonicalKey}\\` (${verdict.tier} tier, ${verdict.source} evaluation).${statusNote}`);\n } else {\n lines.push(`${passedCount}/${total} criteria pass for \\`${verdict.canonicalKey}\\` (${verdict.tier} tier, ${verdict.source} evaluation)${statusNote}`);\n lines.push(\"\");\n for (const c of verdict.criteria) {\n const icon = c.passed ? \"[x]\" : \"[ ]\";\n const extra = c.passed ? \"\" : ` — ${c.hint}`;\n lines.push(`${icon} ${c.id}${extra}`);\n }\n\n if (verdict.weakest) {\n lines.push(\"\");\n lines.push(`**Top improvement:** ${verdict.weakest.hint}`);\n }\n }\n\n if (verdict.rogerMartin) {\n const rm = verdict.rogerMartin;\n lines.push(\"\");\n lines.push(\"### Roger Martin Test\");\n if (rm.isStrategicChoice) {\n lines.push(`This is a real strategic choice — the opposite is reasonable. ${rm.reasoning}`);\n } else {\n lines.push(`This may not be a strategic choice. ${rm.reasoning}`);\n if (rm.suggestion) {\n lines.push(`_Suggestion:_ ${rm.suggestion}`);\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Fix 2 (WP-577 review round 3, TEN-2918 follow-up): the single-capture `preview: true` branch\n * (tools/smart-capture.ts, the `isPreviewCreateEntryResult(result)` branch inside `handleCapture`)\n * has returned structured data — `entryId`, `name`, `collection`, `outcome`, `blockingReason`,\n * `warnings`, `groundingReport`, `taskAlignment` — since WP-316 S3 / TEN-2458. That branch was\n * only reachable in practice once PR #523 closed the action/mutation validator parity gap for\n * `preview: true` (before that, a preview call threw at the gateway before reaching this code).\n * `captureOutputSchema` (tools/smart-capture.ts) was a union of only the strict real-capture\n * shape (`status` required) and the classifier-only fallback shape — neither accepts this\n * branch's object, so any consumer validating a successful single-capture preview response\n * against the documented `envelopeSchema(captureOutputSchema)` contract rejected it outright.\n *\n * This schema is derived directly from the object the branch actually builds (smart-capture.ts,\n * the `success(...)` call inside the preview branch) — not guessed. `contract` is deliberately\n * NOT declared here: it rides the envelope's own top-level `contract` field\n * (envelope.ts's `envelopeSchema`), never `data`.\n *\n * Extracted to lib/ (rather than declared inline in smart-capture.ts) for the same STD-2 /\n * DEC-1504 shrink-only reason as `batchCaptureOutputSchema` (lib/batchCaptureOutput.ts) — that\n * file is grandfathered over-budget and may not grow.\n */\n// zod/v3 — must match smart-capture.ts's specifier exactly; a bare \"zod\" import resolves to v4\n// here and the two instances' types are not assignable across a z.union() (same note as\n// lib/batchCaptureOutput.ts).\nimport { z } from \"zod/v3\";\n\n/** One `groundingReport.related` entry (smart-capture.ts's `groundingRelated` mapping). */\nconst groundingRelatedEntrySchema = z.object({\n entryId: z.string(),\n name: z.string(),\n collectionSlug: z.string(),\n overlapRatio: z.number(),\n recommendedRelationType: z.string(),\n reasoning: z.string(),\n});\n\n/** One `groundingReport.duplicates` entry (smart-capture.ts's `groundingDuplicates` mapping). */\nconst groundingDuplicateEntrySchema = z.object({\n entryId: z.string(),\n name: z.string(),\n collectionSlug: z.string(),\n matchType: z.enum([\"related\", \"possible_duplicate\"]),\n overlapRatio: z.number(),\n});\n\n/** One `groundingReport.governance` entry (smart-capture.ts's `groundingGovernance`). */\nconst groundingGovernanceEntrySchema = z.object({\n entryId: z.string(),\n name: z.string(),\n collectionSlug: z.string(),\n});\n\n/**\n * The pre-write grounding report always included on a capture response (WP-318 S2) — every\n * array is required (present, possibly empty), matching how smart-capture.ts always spreads\n * `groundingReport` unconditionally rather than gating it on any of the three cohorts being\n * non-empty.\n */\nconst groundingReportSchema = z.object({\n related: z.array(groundingRelatedEntrySchema),\n duplicates: z.array(groundingDuplicateEntrySchema),\n governance: z.array(groundingGovernanceEntrySchema),\n});\n\n/**\n * The kernel's librarian task-alignment verdict (convex/lib/gates/taskAlignmentPolicy.ts's\n * `OrientTaskAlignment`) — loose record, same single-source-of-truth rationale already used for\n * `coherencyRefusal`/`contradictionAdvisory`/`qualityVerdict` in `captureSuccessOutputSchema`\n * (tools/smart-capture.ts): the kernel owns this shape, re-declaring it field-for-field here\n * would create a second source of truth that silently drifts.\n */\nconst taskAlignmentSchema = z.record(z.unknown());\n\n/**\n * The single `capture` tool's `preview: true` response data — a THIRD member of the output\n * union, distinct from both the real-create success shape (`status` required) and the\n * classifier-only fallback shape (`classifier` only). No DB write happens on this branch, so it\n * carries no `status` at all — reporting one would be the same \"preview claims a write occurred\"\n * lie `lib/batchCaptureOutput.ts`'s doc comment describes for the batch path.\n */\nexport const captureSinglePreviewOutputSchema = z.object({\n entryId: z.string(),\n name: z.string(),\n collection: z.string(),\n outcome: z.enum([\"preview\", \"blocked\"]),\n // Present only when `outcome: \"blocked\"` AND the server supplied a reason.\n blockingReason: z.string().optional(),\n // Always present — `result.warnings ?? []`, never omitted.\n warnings: z.array(z.string()),\n groundingReport: groundingReportSchema,\n // TEN-2458: only present when the kernel computed a librarian verdict for this preview.\n taskAlignment: taskAlignmentSchema.optional(),\n}).strict();\n","/**\n * Fix 3 (WP-577 review round 3, TEN-2918 follow-up) + Fix 2/3 (P0 review round 4 follow-up):\n * a batch preview's per-item `chain.createEntry` preview call reads the database independently\n * of every OTHER item in the same preview batch — nothing is ever written — so a real (non-preview)\n * run's ordering effects go unpredicted unless this connector-side tracker reproduces them:\n *\n * - **Name collision** (original Fix 3): two items sharing a (collection, name) both come back\n * `wouldCapture`, while a real run writes the first and rejects the second via\n * `assertNoDuplicateEntryName` (convex/agentKnowledge/createEntryDuplicates.ts) — an EXACT\n * string match on `name`, no case-folding, no whitespace trimming, scoped PER COLLECTION.\n * - **entryId collision** (round 4, Fix 2): two items with DIFFERENT names but the SAME\n * caller-supplied `entryId` both come back `wouldCapture`, while a real run rejects the\n * second via `assertNoDuplicateEntryId` — a check that is **workspace-wide**, not scoped to\n * any collection. This tracker mirrors that scope exactly: `isDuplicateEntryId`/\n * `recordEntryId` take no collection argument, unlike the name predicate.\n *\n * This is connector-side bookkeeping over the CALLER'S OWN payload (acceptable per STD-2's\n * kernel/connector split) — it never re-implements a kernel policy decision, it only predicts\n * the ordering effect of the caller's own batch on the exact-match checks the kernel already\n * performs.\n *\n * Usage contract (see `checkBatchPreviewDuplicate`/`recordBatchPreviewIfConfirmed` below, and\n * their call sites in tools/smart-capture.ts's `handleBatchCapture` loop): check BEFORE issuing\n * this item's `chain.createEntry` preview call, and only record AFTER that call comes back\n * reporting the item would NOT be blocked. Recording eagerly (before knowing the outcome) would\n * flag a later item as a duplicate of an entry that itself would never be written (blocked or\n * failed) — a false positive the review explicitly ruled out (\"prefer FALSE-NEGATIVE over\n * false-positive: never wrongly reject something the real run would accept\").\n *\n * Name collisions MUST be recorded under the EFFECTIVE collection the server actually routed the\n * item to (`chain.createEntry`'s preview-branch `collection` field — see convex/agentKnowledge/\n * createEntryPreview.ts), never the caller's own `collectionSlug` argument: `prepareCreateEntry`\n * can redirect a write (e.g. `collectionSlug: \"chains\"` + a bet-shaped payload routes to\n * \"work-packages\"), and recording under the caller's pre-routing slug would miss a later item\n * whose OWN caller-facing slug already matches the routed destination (round 4, Fix 3).\n */\n\nexport type BatchPreviewDuplicateTracker = {\n /** True when (collection, name) was already `recordName`-ed earlier in this same preview batch. */\n isDuplicateName(collection: string, name: string): boolean;\n /** Record that (collection, name) would actually capture — call ONLY once confirmed non-blocked. Key `collection` on the EFFECTIVE (post-routing) destination, not the caller's raw input. */\n recordName(collection: string, name: string): void;\n /** True when this caller-supplied `entryId` was already `recordEntryId`-ed earlier in this batch. Workspace-wide — mirrors `assertNoDuplicateEntryId`'s scope, no collection argument. */\n isDuplicateEntryId(entryId: string): boolean;\n /** Record that this caller-supplied `entryId` would actually capture — call ONLY once confirmed non-blocked. */\n recordEntryId(entryId: string): void;\n};\n\nexport function createBatchPreviewDuplicateTracker(): BatchPreviewDuplicateTracker {\n const seenByCollection = new Map<string, Set<string>>();\n const seenEntryIds = new Set<string>();\n return {\n isDuplicateName(collection, name) {\n return seenByCollection.get(collection)?.has(name) ?? false;\n },\n recordName(collection, name) {\n let names = seenByCollection.get(collection);\n if (!names) {\n names = new Set();\n seenByCollection.set(collection, names);\n }\n names.add(name);\n },\n isDuplicateEntryId(entryId) {\n return seenEntryIds.has(entryId);\n },\n recordEntryId(entryId) {\n seenEntryIds.add(entryId);\n },\n };\n}\n\n/** Minimal shape of one `handleBatchCapture` per-entry result — matches BatchEntryResult's required fields. */\nexport type BatchPreviewDuplicateResult = {\n entryIdx: number;\n name: string;\n collection: string;\n entryId: string;\n ok: boolean;\n autoLinks: number;\n advisedLinks: number;\n status: \"draft\" | \"committed\" | \"proposed\" | \"draft_on_failure\";\n classifiedBy?: \"llm\" | \"heuristic\" | \"explicit\";\n confidence?: number;\n confidenceTier?: \"high\" | \"medium\" | \"low\";\n error: string;\n};\n\n/**\n * Builds the would-fail result for a batch-local NAME duplicate — lands in `failed`/\n * `failedEntries` via the same `results.filter((r) => !r.ok)` split every other batch failure\n * already uses, so `buildBatchPreviewFromResults` (lib/batchCaptureOutput.ts) reports it\n * honestly as would-fail rather than would-capture.\n */\nexport function buildBatchPreviewDuplicateResult(\n entryIdx: number,\n name: string,\n collection: string,\n classifiedBy: \"llm\" | \"heuristic\" | \"explicit\" | undefined,\n confidence: number | undefined,\n confidenceTier: \"high\" | \"medium\" | \"low\" | undefined,\n): BatchPreviewDuplicateResult {\n return {\n entryIdx,\n name,\n collection,\n entryId: \"\",\n ok: false,\n autoLinks: 0,\n advisedLinks: 0,\n status: \"draft\",\n classifiedBy,\n confidence,\n confidenceTier,\n error: `Duplicate entry: \"${name}\" already claimed by an earlier item in this batch [${collection}] — the real (non-preview) run would write the first and reject this one.`,\n };\n}\n\n/**\n * Builds the would-fail result for a batch-local caller-supplied `entryId` duplicate (round 4,\n * Fix 2) — same `ok:false` shape as the name-duplicate result above, but the collision is on\n * `entryId` (workspace-wide, per `assertNoDuplicateEntryId`), not on (collection, name).\n */\nexport function buildBatchPreviewDuplicateEntryIdResult(\n entryIdx: number,\n name: string,\n collection: string,\n entryId: string,\n classifiedBy: \"llm\" | \"heuristic\" | \"explicit\" | undefined,\n confidence: number | undefined,\n confidenceTier: \"high\" | \"medium\" | \"low\" | undefined,\n): BatchPreviewDuplicateResult {\n return {\n entryIdx,\n name,\n collection,\n entryId: \"\",\n ok: false,\n autoLinks: 0,\n advisedLinks: 0,\n status: \"draft\",\n classifiedBy,\n confidence,\n confidenceTier,\n error: `Duplicate entry: ID \"${entryId}\" already claimed by an earlier item in this batch (workspace-wide) — the real (non-preview) run would write the first and reject this one.`,\n };\n}\n\n/**\n * Runs both batch-local duplicate checks (entryId, then name — same precedence\n * `handleBatchCapture`'s loop uses) for one item BEFORE its `chain.createEntry` preview call.\n * Returns the would-fail result to push (and `continue` on), or null when the item should\n * proceed — collapses two hand-rolled `if` blocks at the call site into one.\n */\nexport function checkBatchPreviewDuplicate(\n tracker: BatchPreviewDuplicateTracker,\n args: {\n preview: boolean | undefined;\n entryIdx: number;\n name: string;\n collection: string;\n callerEntryId: string | undefined;\n classifiedBy: \"llm\" | \"heuristic\" | \"explicit\" | undefined;\n confidence: number | undefined;\n confidenceTier: \"high\" | \"medium\" | \"low\" | undefined;\n },\n): BatchPreviewDuplicateResult | null {\n if (!args.preview) return null;\n if (args.callerEntryId && tracker.isDuplicateEntryId(args.callerEntryId)) {\n return buildBatchPreviewDuplicateEntryIdResult(\n args.entryIdx, args.name, args.collection, args.callerEntryId,\n args.classifiedBy, args.confidence, args.confidenceTier,\n );\n }\n if (tracker.isDuplicateName(args.collection, args.name)) {\n return buildBatchPreviewDuplicateResult(\n args.entryIdx, args.name, args.collection, args.classifiedBy, args.confidence, args.confidenceTier,\n );\n }\n return null;\n}\n\n/**\n * Records a CONFIRMED non-blocked item's (collection, name) and, when the caller supplied one,\n * `entryId` onto the tracker — a no-op when `wouldCapture` is false (see the module doc\n * comment's \"prefer FALSE-NEGATIVE over false-positive\" contract). `effectiveCollection` MUST be\n * the EFFECTIVE (post-routing) collection the server's preview reported, not the caller's raw slug.\n */\nexport function recordBatchPreviewIfConfirmed(\n tracker: BatchPreviewDuplicateTracker,\n args: { wouldCapture: boolean; effectiveCollection: string; name: string; callerEntryId: string | undefined },\n): void {\n if (!args.wouldCapture) return;\n tracker.recordName(args.effectiveCollection, args.name);\n if (args.callerEntryId) tracker.recordEntryId(args.callerEntryId);\n}\n\n/**\n * P0 round 4 (fix 2/3, root): re-checks and records a batch item's outcome AFTER its\n * `chain.createEntry` preview call has come back — the counterpart to\n * `checkBatchPreviewDuplicate`'s BEFORE-the-call check, needed because that earlier check is\n * keyed on the caller's PRE-routing `collectionSlug`. It cannot see THIS item itself routing\n * into a DIFFERENT effective collection (e.g. `collectionSlug: \"chains\"` + a bet-shaped payload\n * routes to \"work-packages\") that an EARLIER item in the same batch already claimed under that\n * destination — a real (non-preview) run writes the earlier item and rejects this one via\n * `assertNoDuplicateEntryName`, scoped per (effective) collection.\n *\n * `args.wouldCapture` must already reflect this item's own would-block verdict (false for a\n * would-BLOCK item, which is never written either way and so can never collide) — this function\n * only adds the post-routing name recheck on top, and never double-checks/double-records: it\n * either returns a would-fail duplicate result (nothing recorded) or records the confirmed\n * capture (nothing returned), never both.\n */\nexport function reconcileBatchPreviewDuplicate(\n tracker: BatchPreviewDuplicateTracker,\n args: {\n wouldCapture: boolean;\n effectiveCollection: string;\n entryIdx: number;\n name: string;\n callerEntryId: string | undefined;\n classifiedBy: \"llm\" | \"heuristic\" | \"explicit\" | undefined;\n confidence: number | undefined;\n confidenceTier: \"high\" | \"medium\" | \"low\" | undefined;\n },\n): BatchPreviewDuplicateResult | null {\n if (args.wouldCapture && tracker.isDuplicateName(args.effectiveCollection, args.name)) {\n return buildBatchPreviewDuplicateResult(\n args.entryIdx, args.name, args.effectiveCollection, args.classifiedBy, args.confidence, args.confidenceTier,\n );\n }\n recordBatchPreviewIfConfirmed(tracker, {\n wouldCapture: args.wouldCapture,\n effectiveCollection: args.effectiveCollection,\n name: args.name,\n callerEntryId: args.callerEntryId,\n });\n return null;\n}\n","import { kernelQuery } from \"../client.js\";\nimport { runContradictionCheck, type ContradictionWarning } from \"./smart-capture.js\";\n// WP-488 Slice 3 (FEAT-1377): type-only — resolved via a tsconfig.json path alias, not an\n// npm dependency (see tsconfig.json's comment: Railway's isolated Docker build for this\n// package can't resolve a private workspace package). Erased entirely at build time.\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\n\nexport interface SemanticConflictResult {\n chainEntryId: string;\n chainEntryName: string;\n chainEntryDescription: string;\n type: \"contradiction\" | \"supersession\" | \"duplicate\" | \"overlap\";\n confidence: number;\n explanation: string;\n}\n\nexport interface ConflictPreflightResult {\n source: \"semantic\" | \"heuristic\";\n conflicts: SemanticConflictResult[];\n advisoryWarnings: ContradictionWarning[];\n}\n\n/**\n * Run the staging-grade semantic conflict detector when available.\n * Falls back to the existing heuristic warning path if the bridge is unavailable.\n *\n * WP-485 Slice 2b (R2, FEAT-1370): this is DISCOVERY ONLY — it used to also compute\n * `blockingContradictions` via a local `BLOCKING_CONTRADICTION_THRESHOLD` comparison, one of\n * THREE independent copies of the same enforcement decision across the MCP connector (the\n * others: `promote.ts`, `smart-capture.ts`). Deleted: the enforcement decision now happens ONE\n * place, server-side, inside `commitEntry`'s evaluate()/assessContradiction gate (Slice 2a).\n * Callers hand `conflicts` to the server as evidence and render whatever `contradictionAdvisory`\n * the server computes — never decide locally.\n */\nexport async function runConflictPreflight(\n name: string,\n description: string,\n collectionHint?: string,\n): Promise<ConflictPreflightResult> {\n try {\n // WP-488 Slice 3: typed via GatewayRouteReturnByName off the real Convex ref\n // (internal.intelligence.conflictDetection.detectSemanticConflicts's declared\n // `Promise<ConflictResult[]>`) instead of a hand-rolled generic — the server never\n // returns null/undefined (verified: the action's return type is always an array), the\n // `?? []` below stays as defensive runtime handling of a malformed HTTP response, not\n // because the real type allows it. `ConflictResult[]`'s fields are a strict superset of\n // the local `SemanticConflictResult` (extra `chainEntryDocId` etc.) — structurally\n // assignable to the narrower local shape used by `ConflictPreflightResult.conflicts`.\n const conflicts = await kernelQuery<GatewayRouteReturnByName<\"chain.detectSemanticConflicts\">>(\"chain.detectSemanticConflicts\", {\n name,\n description,\n ...(collectionHint ? { collectionHint } : {}),\n });\n\n return {\n source: \"semantic\",\n conflicts: conflicts ?? [],\n advisoryWarnings: [],\n };\n } catch (err) {\n console.error('[conflict-preflight] Semantic conflict detection unavailable, falling back to heuristic:', err instanceof Error ? err.message : String(err));\n const advisoryWarnings = await runContradictionCheck(name, description);\n return {\n source: \"heuristic\",\n conflicts: [],\n advisoryWarnings,\n };\n }\n}\n","/**\n * `get-history` / `entries action=\"history\"` handler body (WP-484 S1: extracted so both callers\n * share it). Split out of tools/knowledge.ts (not inline) — STD-2/DEC-1504: knowledge.ts is a\n * grandfathered, shrink-only file; this extraction is the WP-582 B1 offset for that PR's\n * publishAdvisories render addition.\n */\nimport { z } from \"zod/v3\";\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelQuery } from \"../../client.js\";\nimport { success, successResult, type ToolResult } from \"../../envelope.js\";\n\nexport const getHistorySchema = z.object({\n entryId: z.string().describe(\"Entry ID, e.g. 'T-SUPPLIER', '<PREFIX>-<n>'\"),\n});\n\nexport async function handleGetHistory({ entryId }: z.infer<typeof getHistorySchema>): Promise<ToolResult> {\n const history = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntryHistory\">>(\"chain.listEntryHistory\", { entryId });\n\n if (history.length === 0) {\n return successResult(\n `No history found for ${entryId}.`,\n `No history events recorded for ${entryId}.`,\n { entryId, eventCount: 0, events: [] },\n );\n }\n\n const formatted = history\n .map((rawH) => {\n // `annotateVerifiedHistory`'s generic (convex/lib/attestEntry.ts, shared by both\n // connectors) infers its type parameter as narrowly as its own constraint\n // (Pick<Doc<'entryHistory'>, 'event'> & Partial<...>) rather than the full raw\n // doc it's actually called with — `timestamp`/`changes`/`changedBy` are real\n // fields on the row but not on the inferred element type (PR #395, Lane C S3b\n // annotation pass). Cast here rather than widen the shared generic's constraint.\n const h = rawH as typeof rawH & { timestamp: number; changes?: unknown; changedBy?: string };\n const date = new Date(h.timestamp).toISOString();\n const changes = h.changes ? ` — ${JSON.stringify(h.changes)}` : \"\";\n // WP-D (attestation spec §7.2): server-derived qualifier beside legacy 'verified'\n // events — the ledger sentence stays as written, the display stops lying.\n const qualifier = h.legacyQualifier ? ` [${h.legacyQualifier}]` : \"\";\n return `- **${date}** ${h.event}${h.changedBy ? ` _(${h.changedBy})_` : \"\"}${changes}${qualifier}`;\n })\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text: `# History for \\`${entryId}\\` (${history.length} events)\\n\\n${formatted}` }],\n structuredContent: success(\n `Found ${history.length} history events for ${entryId}.`,\n { entryId, eventCount: history.length, events: history },\n ),\n };\n}\n","import type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, getAgentSessionId } from \"../client.js\";\nimport { success, successResult, failureResult, type ToolResult } from \"../envelope.js\";\nimport { resolveProjectRoot } from \"../lib/resolve-project-root.js\";\n\n// ── Types ──────────────────────────────────────────────────────────────\n\ntype MappingKind = \"file\" | \"schema\" | \"conceptual\";\ntype CheckResult = \"verified\" | \"drifted\" | \"unverifiable\";\n\ninterface MappingCheck {\n entryId: string;\n entryName: string;\n field: string;\n kind: MappingKind;\n result: CheckResult;\n reason: string;\n currentStatus: string;\n}\n\ninterface RefCheck {\n entryId: string;\n entryName: string;\n refValue: string;\n found: boolean;\n}\n\n// ── Schema Parser ──────────────────────────────────────────────────────\n\nfunction parseConvexSchema(schemaPath: string): Map<string, Set<string>> {\n const content = readFileSync(schemaPath, \"utf-8\");\n const tables = new Map<string, Set<string>>();\n let currentTable: string | null = null;\n\n for (const line of content.split(\"\\n\")) {\n const tableMatch = line.match(/^\\t(\\w+):\\s*defineTable\\(/);\n if (tableMatch) {\n currentTable = tableMatch[1];\n tables.set(currentTable, new Set());\n continue;\n }\n\n if (currentTable && /^\\t[}\\)]/.test(line) && !/^\\t\\t/.test(line)) {\n currentTable = null;\n continue;\n }\n\n if (currentTable) {\n const fieldMatch = line.match(/^\\t\\t(\\w+):\\s*v\\./);\n if (fieldMatch) tables.get(currentTable)!.add(fieldMatch[1]);\n }\n }\n\n return tables;\n}\n\n// ── Code Mapping Classifiers ───────────────────────────────────────────\n\nfunction cleanFieldRef(field: string): string {\n return field\n .replace(/\\s*\\(.*\\)\\s*$/, \"\")\n .replace(/\\s*=\\s*.*$/, \"\")\n .trim();\n}\n\nfunction splitMultiRefs(field: string): string[] {\n if (field.includes(\" + \")) return field.split(/\\s*\\+\\s*/);\n return [field];\n}\n\nconst FILE_EXT_RE = /\\.(ts|js|svelte|json|css|md|jsx|tsx|mjs|cjs)(?:\\s|$)/i;\n\nfunction classifyRef(cleaned: string): MappingKind {\n if (cleaned.includes(\"/\") || FILE_EXT_RE.test(cleaned) || /^\\.\\w+/.test(cleaned)) {\n return \"file\";\n }\n if (/^\\w+\\.\\w+$/.test(cleaned)) return \"schema\";\n if (/^\\w+\\s+table$/i.test(cleaned)) return \"schema\";\n return \"conceptual\";\n}\n\n// ── Verification Checkers ──────────────────────────────────────────────\n\nfunction checkFileRef(ref: string, root: string): { result: CheckResult; reason: string } {\n const filePart = ref.split(/\\s+/)[0];\n const fullPath = resolve(root, filePart);\n if (existsSync(fullPath)) return { result: \"verified\", reason: \"exists\" };\n return { result: \"drifted\", reason: `not found: ${filePart}` };\n}\n\nfunction checkSchemaRef(\n ref: string,\n schema: Map<string, Set<string>>,\n): { result: CheckResult; reason: string } {\n const tableOnlyMatch = ref.match(/^(\\w+)\\s+table$/i);\n if (tableOnlyMatch) {\n const table = tableOnlyMatch[1];\n if (schema.has(table)) return { result: \"verified\", reason: `table \"${table}\" exists` };\n return { result: \"drifted\", reason: `table \"${table}\" not found in schema` };\n }\n\n const dotIdx = ref.indexOf(\".\");\n if (dotIdx > 0) {\n const table = ref.slice(0, dotIdx);\n const field = ref.slice(dotIdx + 1);\n if (!schema.has(table)) return { result: \"drifted\", reason: `table \"${table}\" not found in schema` };\n if (!schema.get(table)!.has(field)) return { result: \"drifted\", reason: `field \"${field}\" not found in table \"${table}\"` };\n return { result: \"verified\", reason: `${table}.${field} exists` };\n }\n\n return { result: \"unverifiable\", reason: \"could not parse schema reference\" };\n}\n\n// ── Trust Report Formatter ─────────────────────────────────────────────\n\nfunction formatTrustReport(\n collection: string,\n entryCount: number,\n mappings: MappingCheck[],\n refs: RefCheck[],\n fixes: string[],\n mode: string,\n schemaTableCount: number,\n projectRoot: string,\n): string {\n const verified = mappings.filter((c) => c.result === \"verified\").length;\n const drifted = mappings.filter((c) => c.result === \"drifted\").length;\n const unverifiable = mappings.filter((c) => c.result === \"unverifiable\").length;\n\n const refsValid = refs.filter((c) => c.found).length;\n const refsBroken = refs.filter((c) => !c.found).length;\n\n const totalChecks = mappings.length + refs.length;\n const totalPassed = verified + refsValid;\n const trustScore = totalChecks > 0 ? Math.round((totalPassed / totalChecks) * 100) : 100;\n\n const lines: string[] = [\n `# Trust Report: ${collection} (${entryCount} entries scanned)`,\n \"\",\n ];\n\n if (mappings.length > 0) {\n lines.push(\n \"## Code Mapping Verification\",\n `- ${mappings.length} mappings checked`,\n `- ${verified} verified (${Math.round((verified / mappings.length) * 100)}%)`,\n `- ${drifted} drifted (file/schema not found)`,\n `- ${unverifiable} unverifiable (conceptual — skipped)`,\n \"\",\n );\n }\n\n if (drifted > 0) {\n lines.push(\"### Drifted Mappings\");\n for (const mc of mappings.filter((c) => c.result === \"drifted\")) {\n lines.push(`- **${mc.entryId}** (${mc.entryName}): \\`${mc.field}\\` — ${mc.reason}`);\n }\n lines.push(\"\");\n }\n\n if (unverifiable > 0) {\n lines.push(\"### Unverifiable (Conceptual)\");\n for (const mc of mappings.filter((c) => c.result === \"unverifiable\")) {\n lines.push(`- **${mc.entryId}** (${mc.entryName}): \\`${mc.field}\\``);\n }\n lines.push(\"\");\n }\n\n if (refs.length > 0) {\n lines.push(\n \"## Cross-Reference Verification\",\n `- ${refs.length} references checked`,\n `- ${refsValid} valid (${refs.length > 0 ? Math.round((refsValid / refs.length) * 100) : 0}%)`,\n `- ${refsBroken} broken`,\n \"\",\n );\n }\n\n if (refsBroken > 0) {\n lines.push(\"### Broken References\");\n for (const rc of refs.filter((c) => !c.found)) {\n lines.push(`- **${rc.entryId}** (${rc.entryName}): relatedRules \\`${rc.refValue}\\` — entry not found`);\n }\n lines.push(\"\");\n }\n\n lines.push(`## Trust Score: ${trustScore}% (${totalPassed} of ${totalChecks} checks passed)`);\n\n if (mode === \"fix\" && fixes.length > 0) {\n lines.push(\n \"\",\n \"## Applied Fixes\",\n `Updated codeMapping status from \\`aligned\\` → \\`drifted\\` on ${fixes.length} entr${fixes.length === 1 ? \"y\" : \"ies\"}:`,\n );\n for (const eid of fixes) lines.push(`- ${eid}`);\n } else if (mode === \"report\" && drifted > 0) {\n const fixable = mappings.filter((c) => c.result === \"drifted\" && c.currentStatus === \"aligned\").length;\n if (fixable > 0) {\n lines.push(\"\", `_${fixable} mapping(s) marked \"aligned\" but actually drifted. Run with mode=\"fix\" to update._`);\n }\n }\n\n lines.push(\"\", \"---\", `_Schema: ${schemaTableCount} tables parsed from convex/schema.ts. Project root: ${projectRoot}_`);\n\n return lines.join(\"\\n\");\n}\n\n// ── Tool Registration ──────────────────────────────────────────────────\n\nexport const verifySchema = z.object({\n collection: z.string().max(200).default(\"glossary\")\n .describe(\"Collection slug to verify (default: glossary)\"),\n mode: z.enum([\"report\", \"fix\"]).default(\"report\")\n .describe(\"'report' = read-only trust report. 'fix' = also update drifted codeMapping statuses.\"),\n});\n\nexport const verifyEntrySchema = z.object({\n entryId: z.string().max(200).describe(\"Human entry ID (e.g. '<PREFIX>-<n>') to mark as verified\"),\n});\n\n/**\n * WP-484 S2 (§3): extracted verify-chain handler — reused by the legacy\n * `verify` standalone tool AND `quality action=verify-chain` (absorbed per\n * §3 core-nouns table). One business-logic path.\n */\nexport async function handleVerifyChain(\n server: McpServer,\n { collection, mode }: { collection: string; mode: \"report\" | \"fix\" },\n) {\n const projectRoot = resolveProjectRoot();\n if (!projectRoot) {\n return failureResult(\n \"# Verification Failed\\n\\n\" +\n \"Cannot find project root (looked for `convex/schema.ts` in cwd and parent directory).\\n\\n\" +\n \"Set `WORKSPACE_PATH` in `.env.mcp` to the absolute path of the Product Brain project root.\",\n \"VALIDATION_ERROR\",\n \"Cannot find project root. Set WORKSPACE_PATH in .env.mcp.\",\n );\n }\n\n const schema = parseConvexSchema(resolve(projectRoot, \"convex/schema.ts\"));\n\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Verifying \"${collection}\" against ${schema.size} schema tables at ${projectRoot}`,\n logger: \"product-os\",\n });\n\n const scopedEntries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: collection });\n\n if (scopedEntries.length === 0) {\n return failureResult(\n `No entries found in '${collection}'. Nothing to verify.`,\n \"NOT_FOUND\",\n `No entries found in '${collection}'. Nothing to verify.`,\n \"Capture entries first, then verify.\",\n [{ tool: \"capture\", description: \"Capture an entry\", parameters: {} }],\n );\n }\n\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Scanning ${scopedEntries.length} entries in ${collection}...`,\n logger: \"product-brain\",\n });\n\n // Build cross-reference lookup: fetch all entries to check relatedRules\n let allEntryIds: Set<string>;\n try {\n const allEntries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\n \"chain.listEntries\",\n { fields: [\"entryId\"] },\n );\n allEntryIds = new Set((allEntries ?? []).map((e) => e.entryId).filter(Boolean) as string[]);\n } catch {\n allEntryIds = new Set(scopedEntries.map((e: any) => e.entryId).filter(Boolean));\n }\n\n const mappingChecks: MappingCheck[] = [];\n const refChecks: RefCheck[] = [];\n\n for (let idx = 0; idx < scopedEntries.length; idx++) {\n const entry = scopedEntries[idx];\n\n if (idx > 0 && idx % 10 === 0) {\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Scanned ${idx}/${scopedEntries.length} entries...`,\n logger: \"product-brain\",\n });\n }\n\n // `chain.listEntries`'s handler infers a union return type (raw `EntryDoc[]` when no\n // `fields` projection is requested, vs `Record<string, unknown>[]` when it is) —\n // property access resolves to `unknown` across that union even though this call site\n // never passes `fields` (always the `EntryDoc[]` branch at runtime). Same documented\n // residual as packages/mcp-server/src/prompts/index.ts (PR #395, Lane C S3b pass).\n const eid = (entry.entryId as string | undefined) ?? (entry.name as string);\n const ename = entry.name as string;\n\n // ── Code mapping verification ──\n const codeMappings: any[] = entry.data?.codeMapping ?? [];\n for (const cm of codeMappings) {\n const rawField: string = cm.field ?? \"\";\n for (const rawRef of splitMultiRefs(rawField)) {\n const cleaned = cleanFieldRef(rawRef);\n if (!cleaned) continue;\n\n const kind = classifyRef(cleaned);\n let result: CheckResult;\n let reason: string;\n\n if (kind === \"file\") {\n ({ result, reason } = checkFileRef(cleaned, projectRoot));\n } else if (kind === \"schema\") {\n ({ result, reason } = checkSchemaRef(cleaned, schema));\n } else {\n result = \"unverifiable\";\n reason = \"conceptual reference\";\n }\n\n mappingChecks.push({\n entryId: eid, entryName: ename, field: rawRef.trim(),\n kind, result, reason, currentStatus: cm.status ?? \"unknown\",\n });\n }\n }\n\n // ── Cross-reference verification (relatedRules only) ──\n const MAX_CROSS_REFS = 50;\n const relatedRules: string[] = entry.data?.relatedRules ?? [];\n for (const ruleId of relatedRules) {\n if (refChecks.length >= MAX_CROSS_REFS) break;\n refChecks.push({\n entryId: eid, entryName: ename, refValue: ruleId,\n found: allEntryIds.has(ruleId),\n });\n }\n }\n\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Scan complete. Building trust report...`,\n logger: \"product-brain\",\n });\n\n // ── Fix mode: update aligned → drifted ──\n const fixes: string[] = [];\n const fixUpdateWarnings: Array<{ entryId: string; normalizationWarnings: string[]; validationWarnings: string[] }> = [];\n // WP-465 slice ⑤ (Option B): coherency-refused fixes — the drift update did NOT apply,\n // so they are surfaced separately and never counted as fixed.\n const fixRefusals: Array<{ entryId: string; reason: string }> = [];\n if (mode === \"fix\") {\n const driftedByEntry = new Map<string, Set<string>>();\n for (const mc of mappingChecks) {\n if (mc.result === \"drifted\" && mc.currentStatus === \"aligned\") {\n if (!driftedByEntry.has(mc.entryId)) driftedByEntry.set(mc.entryId, new Set());\n driftedByEntry.get(mc.entryId)!.add(mc.field);\n }\n }\n\n for (const [eid, driftedFields] of driftedByEntry) {\n const entry = scopedEntries.find((e: any) => (e.entryId ?? e.name) === eid);\n if (!entry?.entryId) continue;\n // Same `chain.listEntries` union residual as above — `entryId` is provably a\n // truthy string past the guard, but the type stays `unknown` across the union.\n const targetEntryId = entry.entryId as string;\n\n const updated = (entry.data?.codeMapping ?? []).map((cm: any) =>\n cm.status === \"aligned\" && driftedFields.has(cm.field)\n ? { ...cm, status: \"drifted\" }\n : cm,\n );\n\n const updateResult = await kernelMutation<GatewayRouteReturnByName<\"chain.updateEntry\">>(\"chain.updateEntry\", {\n entryId: targetEntryId,\n data: { codeMapping: updated },\n });\n // WP-465 slice ⑤ (Option B): a coherency refusal RETURNS a structured payload — the\n // drift fix did NOT apply, so surface it instead of counting it as fixed.\n if (updateResult.outcome === \"refused\") {\n fixRefusals.push({\n entryId: targetEntryId,\n reason: updateResult.refusal?.reason ?? \"coherency gate refused this update\",\n });\n continue;\n }\n if (updateResult.normalizationWarnings.length > 0 || updateResult.validationWarnings.length > 0) {\n fixUpdateWarnings.push({\n entryId: targetEntryId,\n normalizationWarnings: updateResult.normalizationWarnings,\n validationWarnings: updateResult.validationWarnings,\n });\n }\n fixes.push(targetEntryId);\n }\n }\n\n const verified = mappingChecks.filter((c) => c.result === \"verified\").length;\n const drifted = mappingChecks.filter((c) => c.result === \"drifted\").length;\n const unverifiable = mappingChecks.filter((c) => c.result === \"unverifiable\").length;\n const refsValid = refChecks.filter((c) => c.found).length;\n const refsBroken = refChecks.filter((c) => !c.found).length;\n const totalChecks = mappingChecks.length + refChecks.length;\n const totalPassed = verified + refsValid;\n const trustScore = totalChecks > 0 ? Math.round((totalPassed / totalChecks) * 100) : 100;\n\n const report = formatTrustReport(\n collection, scopedEntries.length,\n mappingChecks, refChecks, fixes, mode,\n schema.size, projectRoot,\n );\n\n let reportText = report;\n if (fixRefusals.length > 0) {\n reportText += '\\n\\n---\\n\\n🛑 **Coherency refusals (fix NOT applied — entry unchanged):**';\n for (const r of fixRefusals) {\n reportText += `\\n - **${r.entryId}**: ${r.reason}`;\n }\n }\n if (fixUpdateWarnings.length > 0) {\n reportText += '\\n\\n---\\n\\n⚠️ **Fix update warnings:**';\n for (const w of fixUpdateWarnings) {\n for (const nw of w.normalizationWarnings) {\n reportText += `\\n - **${w.entryId}** (normalization): ${nw}`;\n }\n for (const vw of w.validationWarnings) {\n reportText += `\\n - **${w.entryId}** (validation): ${vw}`;\n }\n }\n }\n\n return {\n content: [{ type: \"text\" as const, text: reportText }],\n structuredContent: success(\n `Trust report for ${collection}: ${totalPassed}/${totalChecks} checks passed (${trustScore}%).`,\n {\n collection,\n entryCount: scopedEntries.length,\n trustScore,\n totalChecks,\n totalPassed,\n verified,\n drifted,\n unverifiable,\n refsValid,\n refsBroken,\n fixesApplied: fixes.length,\n ...(fixRefusals.length > 0 ? { fixesRefused: fixRefusals.length, coherencyRefusals: fixRefusals } : {}),\n mode,\n },\n ),\n };\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `verify` / `verify-entry`\n// tool registrations retired here. handleVerifyChain / handleVerifyEntry stay\n// live — quality.ts (action=verify-chain) and entries.ts (action=verify) are\n// their only remaining callers.\n\n/**\n * WP-484 S1 (§3/§4 entries-family migration): verify-entry's handler body,\n * extracted so both `verify-entry` and `entries action=\"verify\"` share it.\n */\nexport async function handleVerifyEntry({ entryId }: z.infer<typeof verifyEntrySchema>): Promise<ToolResult> {\n const agentSessionId = getAgentSessionId();\n const result = await kernelMutation<GatewayRouteReturnByName<\"chain.verifyEntry\">>(\n \"chain.verifyEntry\",\n {\n entryId,\n ...(agentSessionId ? { sessionId: agentSessionId } : {}),\n },\n );\n // WP-A T8: honest label when the server ships verifiedBy — connectors never re-derive\n // (spec §5). Old server omits the field, so keep today's bare text (spec §11 rollout rule).\n // Final-review Fix 3: a noop re-verify must say \"already verified\" — the mutation\n // performed no fresh attestation, so claiming \"verified\" is a lie of omission.\n //\n // Attestation-model finding (PR #341 review): a non-'attested' basis means\n // verifiedBy is a QUALIFIER, not a person's name (e.g. a legacy row's\n // 'legacy — unclassified') — rendering it as \"— by <qualifier>\" produces the\n // nonsense \"is already verified — by legacy — unclassified\". Branch on\n // attestation.basis the same way packages/mcp-server/src/tools/entries.ts's\n // renderVerificationLine does: attested → \"— by <name> (<strength>)\"; any\n // other basis → bare qualifier \"(<value>)\". Never re-derive strength here.\n const basis = result.attestation?.basis;\n const strength = result.attestation?.strength;\n const verifiedBySuffix = result.verifiedBy\n ? basis && basis !== \"attested\"\n ? ` (${result.verifiedBy})`\n : ` — by ${result.verifiedBy}${strength ? ` (${strength})` : \"\"}`\n : \"\";\n const message = result.alreadyVerified\n ? `Entry ${entryId} is already verified${verifiedBySuffix}.`\n : `Entry ${entryId} verified${verifiedBySuffix}.`;\n // successResult wraps the envelope into a ToolResult ({ content,\n // structuredContent }); bare success() omits structuredContent, which\n // makes thinWrapper throw \"migration incomplete\" AFTER the mutation has\n // already persisted — a gate that lies about failing (TEN-2307).\n return successResult(message, message, result);\n}\n","/**\n * Shared project root resolution for MCP tools.\n *\n * Checks WORKSPACE_PATH, cwd, and parent of cwd for a Convex project\n * (convex/schema.ts marker). Returns null if no valid root is found.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nexport function resolveProjectRoot(): string | null {\n const candidates = [\n process.env.WORKSPACE_PATH,\n process.cwd(),\n // Parent of cwd: handles monorepo subpackages (e.g. packages/mcp-server)\n // where the Convex schema lives one level up.\n resolve(process.cwd(), \"..\"),\n ].filter(Boolean) as string[];\n\n for (const dir of candidates) {\n const resolved = resolve(dir);\n if (existsSync(resolve(resolved, \"convex/schema.ts\"))) return resolved;\n }\n return null;\n}\n","/** Entry collection-move transport and response contract. */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { getAgentSessionId, kernelMutation } from \"../client.js\";\nimport { failureResult, notFoundResult, success } from \"../envelope.js\";\n\nexport const moveEntrySchema = z.object({\n entryId: z.string().describe(\"Entry ID to move, e.g. '<PREFIX>-<n>'\"),\n toCollection: z.string().describe(\"Target collection slug, e.g. 'decisions', 'architecture'\"),\n});\n\nexport async function handleMoveEntry(entryId: string, toCollection: string) {\n try {\n const sessionId = getAgentSessionId();\n const result = await kernelMutation<GatewayRouteReturnByName<\"chain.moveToCollection\">>(\"chain.moveToCollection\", {\n entryId,\n toCollectionSlug: toCollection,\n changedBy: sessionId ? `agent:${sessionId}` : undefined,\n });\n if (result.outcome === \"refused\") {\n const recovery = result.refusal.requiredAction ?? \"Ask the record owner or relevant Team Lead for the required authority change.\";\n return failureResult(\n `Move refused for **${entryId}**.\\n\\n${result.refusal.reason}\\n\\n${recovery}`,\n \"AUTHORITY_REFUSED\",\n result.refusal.reason,\n recovery,\n undefined,\n { entryId, toCollection, refusal: result.refusal },\n );\n }\n\n const lines = [\n `## Move Result`,\n \"\",\n `Moved **${result.entryId}** from \\`${result.fromCollection}\\` → \\`${result.toCollection}\\``,\n ];\n if (result.workflowStatusReset) {\n lines.push(``, `⚠️ Workflow status \\`${result.previousWorkflowStatus}\\` was reset (incompatible with target collection).`);\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Moved ${result.entryId} from ${result.fromCollection} to ${result.toCollection}.`,\n result,\n [\n { tool: \"entries\", description: \"View updated entry\", parameters: { action: \"get\", entryId } },\n { tool: \"quality\", description: \"Re-check quality\", parameters: { action: \"check\", entryId } },\n ],\n ),\n };\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"not found\")) {\n return notFoundResult(entryId, `Could not move entry: ${msg}`);\n }\n return failureResult(\n `Could not move **${entryId}** to \\`${toCollection}\\`: ${msg}`,\n \"MOVE_FAILED\",\n msg,\n \"Check the entry ID and target collection slug, then retry.\",\n [{ tool: \"entries\", description: \"Search for entry\", parameters: { action: \"search\", query: entryId } }],\n );\n }\n}\n","/**\n * Relations compound tool — create, batch-create, dismiss, delete.\n * Consolidates relate-entries, batch-relate, dismiss-suggestion into one write tool.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, getWorkspaceContext, getAgentSessionId, requireWriteAccess, runWithToolContext } from \"../client.js\";\nimport { success, thinWrapper, parseOrFail, notFoundResult, successResult, failureResult, type NextAction, type ToolResult } from \"../envelope.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { handleFind, handleSuggest } from \"./graph.js\";\n\n// WP-484 S2 (§3): `relations` absorbs `graph` → find/suggest. Legacy `graph`\n// tool stays registered alongside (§7 \"alongside\" mechanic) — both call the\n// SAME handleFind/handleSuggest functions, one business-logic path.\nconst RELATIONS_ACTIONS = [\"create\", \"batch-create\", \"dismiss\", \"delete\", \"find\", \"suggest\"] as const;\ntype RelationsAction = (typeof RELATIONS_ACTIONS)[number];\n\nconst relationItemSchema = z.object({\n from: z.string().max(200),\n to: z.string().max(200),\n type: z.string().max(200),\n});\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const relationsSchema = z.object({\n action: z.enum(RELATIONS_ACTIONS).describe(\n \"'create': link two entries. 'batch-create': create multiple relations (validates every item before writing any). \" +\n \"'dismiss': record that a suggestion was not relevant. 'delete': remove a relation. \" +\n \"'find': traverse relations from an entry (graph walk, absorbs graph action=find). \" +\n \"'suggest': discover potential connections for an entry (absorbs graph action=suggest).\",\n ),\n from: z.string().max(200).optional().describe(\"For 'create'/'dismiss'/'delete': source entry ID.\"),\n to: z.string().max(200).optional().describe(\"For 'create'/'dismiss'/'delete': target entry ID.\"),\n type: z.string().max(200).optional().describe(\"For 'create'/'dismiss'/'delete': relation type.\"),\n score: z.number().optional().describe(\"For 'dismiss': suggestion score from action=suggest.\"),\n relations: z.array(relationItemSchema).min(1).max(20).optional().describe(\"For 'batch-create': array of {from, to, type}.\"),\n // WP-316 S3: Preview gate — dry-run mode for action=create.\n preview: z.boolean().optional().describe(\"For 'create': if true, validates the relation without writing. Returns what would happen. Default false.\"),\n entryId: z.string().max(200).optional().describe(\"For 'find'/'suggest': entry ID, e.g. '<PREFIX>-<n>'.\"),\n direction: z.enum([\"incoming\", \"outgoing\", \"both\"]).optional().describe(\"For 'find': 'incoming' = what references this, 'outgoing' = what this references. Default 'both'.\"),\n limit: z.number().min(1).max(20).optional().describe(\"For 'suggest': max suggestions to return. Default 10.\"),\n depth: z.number().min(1).max(3).optional().describe(\"For 'suggest': graph traversal depth. Default 2.\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion.\nconst relationsCreateVariant = z.object({\n action: z.literal(\"create\"),\n from: z.string().max(200),\n to: z.string().max(200),\n type: z.string().max(200),\n score: z.number().optional(),\n preview: z.boolean().optional(),\n});\nconst relationsBatchCreateVariant = z.object({\n action: z.literal(\"batch-create\"),\n relations: z.array(relationItemSchema).min(1).max(20),\n});\nconst relationsDismissVariant = z.object({\n action: z.literal(\"dismiss\"),\n from: z.string().max(200),\n to: z.string().max(200),\n type: z.string().max(200).optional(),\n score: z.number().optional(),\n});\nconst relationsDeleteVariant = z.object({\n action: z.literal(\"delete\"),\n from: z.string().max(200),\n to: z.string().max(200),\n type: z.string().max(200),\n});\nconst relationsFindVariant = z.object({\n action: z.literal(\"find\"),\n entryId: z.string().max(200),\n direction: z.enum([\"incoming\", \"outgoing\", \"both\"]).optional().default(\"both\"),\n});\nconst relationsSuggestVariant = z.object({\n action: z.literal(\"suggest\"),\n entryId: z.string().max(200),\n limit: z.number().min(1).max(20).optional().default(10),\n depth: z.number().min(1).max(3).optional().default(2),\n});\n\nexport const relationsActionUnion = z.discriminatedUnion(\"action\", [\n relationsCreateVariant,\n relationsBatchCreateVariant,\n relationsDismissVariant,\n relationsDeleteVariant,\n relationsFindVariant,\n relationsSuggestVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const RELATIONS_ACTION_SPECS: Record<RelationsAction, ActionParamSpec> = {\n create: { params: [\"from\", \"to\", \"type\", \"score\", \"preview\"], description: \"from, to, and type are required.\" },\n \"batch-create\": { params: [\"relations\"], description: \"relations (1-20 items) is required.\" },\n dismiss: { params: [\"from\", \"to\", \"type\", \"score\"], description: \"from and to are required.\" },\n delete: { params: [\"from\", \"to\", \"type\"], description: \"from, to, and type are required.\" },\n find: { params: [\"entryId\", \"direction\"], description: \"entryId is required.\" },\n suggest: { params: [\"entryId\", \"limit\", \"depth\"], description: \"entryId is required.\" },\n};\n\nexport function registerRelationsTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const relationsHandlers: Record<RelationsAction, (data: any) => Promise<ToolResult>> = {\n create: (data) => handleCreate(data.from, data.to, data.type, data.score, data.preview),\n \"batch-create\": (data) => handleBatchCreate(data.relations),\n dismiss: (data) => handleDismiss(data.from, data.to, data.type ?? \"related_to\", data.score),\n delete: (data) => handleDelete(data.from, data.to, data.type),\n find: (data) => handleFind(data.entryId, data.direction ?? \"both\"),\n suggest: (data) => handleSuggest(data.entryId, data.limit ?? 10, data.depth ?? 2),\n };\n\n server.registerTool(\n \"relations\",\n {\n title: \"Relations\",\n description:\n \"Create, manage, and discover relations between entries.\\n\\n\" +\n \"- **create**: Link two entries with a typed relation. Use action=suggest to discover connections.\\n\" +\n \"- **batch-create**: Create multiple relations in one call (validates every item before writing any). Use after action=suggest.\\n\" +\n \"- **dismiss**: Record that a suggested link was not relevant. Improves future suggestion quality.\\n\" +\n \"- **delete**: Remove a relation by from, to, and type.\\n\" +\n \"- **find**: Traverse relations from a specific entry — shows incoming/outgoing connections. NOT full-text search (use entries action=search).\\n\" +\n \"- **suggest**: Discover potential relations for an entry using graph-aware intelligence. Returns ranked suggestions with confidence scores.\",\n inputSchema: relationsSchema,\n // Mixed read/write noun (§3 R3): find/suggest are read-only, create/batch-create/dismiss/delete write.\n annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(relationsSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"relations\", action }, () =>\n dispatchDiscriminated(\"relations\", relationsActionUnion, parsed.data, RELATIONS_ACTION_SPECS, relationsHandlers),\n );\n }),\n );\n}\n\nasync function handleCreate(from: string, to: string, type: string, score?: number, preview?: boolean) {\n requireWriteAccess();\n const agentSessionId = getAgentSessionId();\n\n type CreateResult = {\n preview?: boolean;\n status?: string;\n chainDebtPrevented?: boolean;\n proposalId?: string;\n originalType?: string;\n suggestedAlternatives?: Array<{ type: string; reason: string }>;\n existing?: boolean;\n fromEntryId?: string;\n toEntryId?: string;\n message?: string;\n relationId?: string;\n suggestedType?: { type: string; confidence: number; reasoning: string; governancePosture?: string };\n // WP-586 review fix (Codex P2): the D4 product-anchor check's preview prediction —\n // a strategy belongs_to a non-product/deprecated-product target, surfaced here\n // instead of always reporting \"would relate\" for a request the real call rejects.\n wouldBlock?: boolean;\n blockingReason?: string;\n // WP-625 review round 1 (finding #4): the relate door's advisory legality + altitude\n // checks (REL-LEGAL-1/ALT-1/ALT-2) — this tool wrapper used to drop them entirely,\n // so the pb CLI got the warning and this surface silently didn't.\n advisories?: Array<{ ruleId: string; ruleText: string; severity: string; stage: string }>;\n };\n const result = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelation\">>(\"chain.createEntryRelation\", {\n fromEntryId: from,\n toEntryId: to,\n type,\n suggestionScore: score ?? undefined,\n // WP-474 E4-REWIRE: explicit relate = human/agent-CHOSEN type → mark \"user\"\n // (DEC-1399: out of gate scope, but positively marked so the judge never keys off absence).\n proposedBy: \"user\",\n sessionId: agentSessionId ?? undefined,\n ...(preview ? { preview: true } : {}),\n });\n\n // WP-363 S5: Chain debt prevented — misuse pattern intercepted, agent-proposal created.\n if (result?.chainDebtPrevented) {\n const alts = result.suggestedAlternatives ?? [];\n const altList = alts.map((a) => ` • \\`${a.type}\\`: ${a.reason}`).join(\"\\n\");\n return {\n content: [{\n type: \"text\" as const,\n text: `# Chain Debt Prevented\\n\\n**\"${result.originalType ?? type}\"** was intercepted as a common misuse for this entry pair and converted to an agent sign-off proposal.\\n\\n**Proposal ID:** \\`${result.proposalId}\\`\\n\\n**Suggested alternatives:**\\n${altList}\\n\\nReview at /review in Cortex UI.`,\n }],\n structuredContent: success(\n `Chain debt prevented: \"${result.originalType ?? type}\" was intercepted and converted to an agent sign-off proposal.`,\n {\n chainDebtPrevented: true,\n proposalId: result.proposalId,\n originalType: result.originalType ?? type,\n suggestedAlternatives: result.suggestedAlternatives,\n },\n [\n { tool: \"relations\", description: \"Use correct type (e.g. informed_by)\", parameters: { action: \"create\", from, to, type: alts[0]?.type ?? \"informed_by\" } },\n ],\n ),\n };\n }\n\n // WP-316 S3: Preview gate — return dry-run result without recording session activity.\n if (result?.preview) {\n // WP-586 review fix (Codex P2): the D4 anchor check would reject this on the real\n // call — report the block instead of promising \"would relate\"/\"Create for real\".\n if (result.wouldBlock) {\n return {\n content: [{ type: \"text\" as const, text: `# Preview: would relate ${from} → ${to} (${type}) — BLOCKED\\n\\n${result.blockingReason ?? \"This relation would be rejected.\"}` }],\n structuredContent: success(\n `Preview: relating ${from} → ${to} (${type}) would be blocked`,\n { status: \"preview-blocked\" as const, from, to, type, blockingReason: result.blockingReason ?? null },\n [],\n ),\n };\n }\n const suggested = result.suggestedType;\n // WP-316 gap fix: add governance posture so agents know whether the suggested type requires consent.\n const suggestedWithPosture = suggested\n ? { ...suggested, governancePosture: suggested.type === \"governs\" ? \"requires_consent\" : \"direct\" }\n : undefined;\n // WP-625 review round 1 (finding #4): render advisories the same way pb relate does —\n // naming the rule and the org stage — never a silent drop on this surface.\n const advisoryText = (result.advisories ?? []).map((a) => `\\n\\n⚠ **${a.ruleId}** (org stage: ${a.stage}): ${a.ruleText}`).join(\"\");\n return {\n content: [{ type: \"text\" as const, text: `# Preview: would relate ${from} → ${to} (${type})\\n\\nNo DB writes — call without \\`preview:true\\` to create for real.${suggestedWithPosture ? `\\n\\n**Type suggestion:** \\`${suggestedWithPosture.type}\\` may be more precise (${suggestedWithPosture.confidence}% confidence). Governance: ${suggestedWithPosture.governancePosture}.` : \"\"}${advisoryText}` }],\n structuredContent: success(\n `Preview: would relate ${from} → ${to} (${type}) — no DB writes`,\n {\n status: \"preview\" as const, from, to, type,\n ...(suggestedWithPosture && { suggestedType: suggestedWithPosture }),\n ...(result.advisories && result.advisories.length > 0 && { advisories: result.advisories }),\n },\n [{ tool: \"relations\", description: \"Create for real\", parameters: { action: \"create\", from, to, type } }],\n ),\n };\n }\n\n const wsCtx = await getWorkspaceContext();\n if (result?.status === \"proposal_created\") {\n const existingNote = result.existing ? \" (existing proposal reused)\" : \"\";\n return {\n content: [{\n type: \"text\" as const,\n text: `# Proposal Created — Governs Relation\\n\\n**${result.fromEntryId ?? from}** —[${type}]→ **${result.toEntryId ?? to}**\\n\\n${result.message ?? \"Governs relation requires async consent. A proposal was created for review.\"}\\n\\n**Proposal ID:** \\`${result.proposalId}\\`${existingNote}\\n**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})\\n\\nThe relation was **not applied** — it will be created when the proposal is approved.`,\n }],\n structuredContent: success(\n `Proposal created for ${from} → ${to} (${type}). Awaiting consent.`,\n { status: \"proposal_created\" as const, from, to, type, proposalId: result.proposalId },\n ),\n };\n }\n\n const lines = [\n `# Relation Created`,\n \"\",\n `**${from}** —[${type}]→ **${to}**`,\n `**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`,\n ];\n\n const suggested = result?.suggestedType;\n // WP-316 gap fix: add governance posture so agents know whether the suggested type requires consent.\n const suggestedWithPosture = suggested\n ? { ...suggested, governancePosture: suggested.type === \"governs\" ? \"requires_consent\" : \"direct\" }\n : undefined;\n if (suggestedWithPosture) {\n lines.push(\"\");\n lines.push(`**Type suggestion:** \\`${suggestedWithPosture.type}\\` may be more precise (${suggestedWithPosture.confidence}% confidence). Governance: ${suggestedWithPosture.governancePosture}.`);\n lines.push(`_${suggestedWithPosture.reasoning}_`);\n lines.push(`To use instead: \\`relations action=create from=\"${from}\" to=\"${to}\" type=\"${suggestedWithPosture.type}\"\\``);\n }\n // WP-625 review round 1 (finding #4): same advisory surfacing as the preview branch above —\n // a real create can carry REL-LEGAL-1/ALT-1/ALT-2 advisories too (the write is never blocked).\n for (const a of result?.advisories ?? []) {\n lines.push(\"\");\n lines.push(`⚠ **${a.ruleId}** (org stage: ${a.stage}): ${a.ruleText}`);\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Created relation ${from} → ${to} (${type}).`,\n {\n status: \"created\" as const, from, to, type,\n ...(suggestedWithPosture && { suggestedType: suggestedWithPosture }),\n ...(result?.advisories && result.advisories.length > 0 && { advisories: result.advisories }),\n },\n [{ tool: \"relations\", description: \"See connections\", parameters: { action: \"find\", entryId: from } }],\n ),\n };\n}\n\nasync function handleBatchCreate(relations: Array<{ from: string; to: string; type: string }>) {\n requireWriteAccess();\n const agentSessionId = getAgentSessionId();\n\n type RelResult = { from: string; to: string; type: string; ok: boolean; error?: string; proposalCreated?: boolean; proposalId?: string };\n const results: RelResult[] = [];\n\n // Governs relations need proposal flow — use single mutation\n const governsRels = relations.filter(r => r.type === \"governs\");\n const batchRels = relations.filter(r => r.type !== \"governs\");\n\n // Batch non-governs in one transaction (BET-105 E4)\n if (batchRels.length > 0) {\n try {\n const batchResult = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelations\">>(\"chain.createEntryRelations\", {\n // WP-474 E4-REWIRE: explicit relate tool creates CHOSEN edges — mark provenance\n // \"user\" (no confidence; human-chosen) so the census can distinguish them.\n relations: batchRels.map(r => ({ fromEntryId: r.from, toEntryId: r.to, type: r.type, proposedBy: \"user\" })),\n sessionId: agentSessionId ?? undefined,\n });\n for (let i = 0; i < batchRels.length; i++) {\n const rel = batchRels[i];\n const res = batchResult.results[i];\n results.push({ ...rel, ok: res?.ok ?? false, error: res?.error });\n }\n } catch (e: unknown) {\n for (const rel of batchRels) {\n results.push({ ...rel, ok: false, error: e instanceof Error ? e.message : \"Batch failed\" });\n }\n }\n }\n\n // Governs relations individually (proposal flow requires single mutation)\n for (const rel of governsRels) {\n try {\n const result = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelation\">>(\"chain.createEntryRelation\", {\n fromEntryId: rel.from,\n toEntryId: rel.to,\n type: rel.type,\n // WP-474 E4-REWIRE: explicit batch-relate governs = human/agent-CHOSEN → \"user\".\n proposedBy: \"user\",\n sessionId: agentSessionId ?? undefined,\n });\n results.push({\n ...rel,\n ok: true,\n proposalCreated: result?.status === \"proposal_created\",\n proposalId: result?.proposalId,\n });\n } catch (e: unknown) {\n results.push({ ...rel, ok: false, error: e instanceof Error ? e.message : \"Unknown error\" });\n }\n }\n\n const created = results.filter((r) => r.ok && !r.proposalCreated);\n const proposals = results.filter((r) => r.ok && r.proposalCreated);\n const failed = results.filter((r) => !r.ok);\n\n const lines = [`# Batch Link Results\\n`];\n lines.push(`**${created.length}** created, **${proposals.length}** proposals, **${failed.length}** failed out of ${relations.length} total.\\n`);\n\n if (created.length > 0) {\n lines.push(\"## Created\");\n for (const r of created) {\n lines.push(`- **${r.from}** —[${r.type}]→ **${r.to}**`);\n }\n }\n\n if (proposals.length > 0) {\n lines.push(\"\");\n lines.push(\"## Proposals (governs — not yet applied)\");\n for (const r of proposals) {\n lines.push(`- **${r.from}** —[${r.type}]→ **${r.to}** — proposal \\`${r.proposalId}\\``);\n }\n }\n\n if (failed.length > 0) {\n lines.push(\"\");\n lines.push(\"## Failed\");\n for (const r of failed) {\n lines.push(`- **${r.from}** → **${r.to}** (${r.type}): _${r.error}_`);\n }\n }\n\n const next: NextAction[] = failed.length === 0\n ? [{ tool: \"relations\", description: \"Check connections\", parameters: { action: \"find\", entryId: relations[0].from } }]\n : [];\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Batch: ${created.length} created, ${proposals.length} proposals, ${failed.length} failed of ${relations.length}.`,\n { created: created.length, proposals: proposals.length, failed: failed.length, total: relations.length, results },\n next.length ? next : undefined,\n ),\n };\n}\n\nasync function handleDismiss(from: string, to: string, type: string, score?: number) {\n requireWriteAccess();\n\n const fromEntry = await kernelQuery<{ _id: string } | null>(\"chain.getEntry\", { entryId: from });\n if (!fromEntry) {\n return notFoundResult(from);\n }\n const toEntry = await kernelQuery<{ _id: string } | null>(\"chain.getEntry\", { entryId: to });\n if (!toEntry) {\n return notFoundResult(to);\n }\n\n await kernelMutation(\"chain.dismissSuggestion\", {\n fromEntryId: fromEntry._id,\n suggestedEntryId: toEntry._id,\n recommendedType: type,\n score: score ?? 0,\n });\n\n return successResult(\n `Dismissed suggestion: ${from} → ${to} (${type}). Feedback recorded for scoring improvements.`,\n `Dismissed suggestion ${from} → ${to} (${type}). Feedback recorded.`,\n { from, to, type },\n );\n}\n\nasync function handleDelete(from: string, to: string, type: string) {\n requireWriteAccess();\n\n await kernelMutation<GatewayRouteReturnByName<\"chain.removeEntryRelation\">>(\"chain.removeEntryRelation\", {\n fromEntryId: from,\n toEntryId: to,\n type,\n });\n\n return successResult(\n `Removed relation: ${from} —[${type}]→ ${to}.`,\n `Relation ${from} → ${to} (${type}) removed.`,\n { from, to, type },\n [{ tool: \"relations\", description: \"Check remaining connections\", parameters: { action: \"find\", entryId: from } }],\n );\n}\n","/**\n * Graph compound tool — find, suggest.\n * Consolidates find-related and suggest-links into one read-only tool.\n * find: traverses relations from a specific entry (graph walk). NOT full-text search — use entries action=search.\n * suggest: recommends new relations (link discovery).\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery } from \"../client.js\";\nimport { success, notFoundResult, failureResult } from \"../envelope.js\";\n\nconst GRAPH_ACTIONS = [\"find\", \"suggest\"] as const;\n\nexport const graphSchema = z.object({\n action: z.enum(GRAPH_ACTIONS).describe(\n \"'find': traverse relations from an entry (graph walk). 'suggest': discover potential connections for an entry.\",\n ),\n entryId: z.string().max(200).describe(\"Entry ID, e.g. '<PREFIX>-<n>'\"),\n direction: z.enum([\"incoming\", \"outgoing\", \"both\"]).default(\"both\").optional()\n .describe(\"For find: 'incoming' = what references this, 'outgoing' = what this references\"),\n limit: z.number().min(1).max(20).default(10).optional()\n .describe(\"For suggest: max suggestions to return\"),\n depth: z.number().min(1).max(3).default(2).optional()\n .describe(\"For suggest: graph traversal depth\"),\n});\n\nexport const graphFindOutputSchema = z.object({\n entryId: z.string(),\n relations: z.array(z.object({\n entryId: z.string().optional(),\n name: z.string(),\n type: z.string(),\n direction: z.enum([\"outgoing\", \"incoming\"]),\n })),\n total: z.number(),\n});\n\nexport const graphSuggestOutputSchema = z.object({\n entryId: z.string(),\n suggestions: z.array(z.object({\n targetEntryId: z.string().optional(),\n targetName: z.string(),\n relationType: z.string(),\n direction: z.string(),\n confidence: z.number(),\n reason: z.string(),\n })),\n total: z.number(),\n});\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `graph` tool retired\n// here. handleFind / handleSuggest stay live — relations.ts (the `relations`\n// compound, action=find / action=suggest) is their only remaining caller.\n\nexport async function handleFind(entryId: string, direction: \"incoming\" | \"outgoing\" | \"both\") {\n const relations = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntryRelations\">>(\"chain.listEntryRelations\", { entryId });\n\n if (relations.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: `No relations found for \\`${entryId}\\`. Use relations action=create to create connections.` }],\n structuredContent: success(\n `No relations found for '${entryId}'.`,\n { entryId, relations: [], nodes: [], edges: [], total: 0 },\n [\n { tool: \"relations\", description: \"Create a relation\", parameters: { action: \"create\", from: entryId } },\n { tool: \"relations\", description: \"Get suggestions\", parameters: { action: \"suggest\", entryId } },\n ],\n ),\n };\n }\n\n const sourceEntry = await kernelQuery<{ _id: string; name: string } | null>(\"chain.getEntry\", { entryId });\n if (!sourceEntry) {\n return notFoundResult(entryId, `Entry '${entryId}' not found. Try entries action=search to find the right ID.`);\n }\n const sourceInternalId = sourceEntry._id;\n\n const MAX_RELATIONS = 25;\n const truncated = relations.length > MAX_RELATIONS;\n const capped = relations.slice(0, MAX_RELATIONS);\n\n const otherIds = new Set<string>();\n for (const r of capped) {\n const otherId = r.fromId === sourceInternalId ? r.toId : r.fromId;\n otherIds.add(otherId);\n }\n\n const otherEntries = new Map<string, { entryId?: string; name: string; collectionId: string }>();\n for (const id of otherIds) {\n const entry = await kernelQuery<{ _id: string; entryId?: string; name: string; collectionId: string } | null>(\"chain.getEntry\", { id });\n if (entry) {\n otherEntries.set(entry._id, { entryId: entry.entryId, name: entry.name, collectionId: entry.collectionId });\n }\n }\n\n const collections = await kernelQuery<Array<{ _id: string; slug: string }>>(\"chain.listCollections\");\n const collMap = new Map<string, string>();\n for (const c of collections) collMap.set(c._id, c.slug);\n\n const lines: string[] = [`## Find Result`, \"\", `# Relations for ${entryId}: ${sourceEntry.name}`, \"\"];\n\n const enriched = capped.map((r) => {\n const isOutgoing = r.fromId === sourceInternalId;\n const otherId = isOutgoing ? r.toId : r.fromId;\n const other = otherEntries.get(otherId);\n const otherLabel = other?.entryId ? `${other.entryId}: ${other.name}` : (other?.name ?? \"(deleted)\");\n const colSlug = other ? (collMap.get(other.collectionId) ?? \"unknown\") : \"unknown\";\n return { isOutgoing, type: r.type, otherLabel, colSlug, otherEntryId: other?.entryId, otherName: other?.name ?? \"(deleted)\" };\n });\n\n const outgoing = enriched.filter((r) => r.isOutgoing);\n const incoming = enriched.filter((r) => !r.isOutgoing);\n\n if ((direction === \"outgoing\" || direction === \"both\") && outgoing.length > 0) {\n lines.push(`## Outgoing (${outgoing.length})`);\n for (const r of outgoing) {\n lines.push(`- → **${r.type}** ${r.otherLabel} [${r.colSlug}]`);\n }\n lines.push(\"\");\n }\n\n if ((direction === \"incoming\" || direction === \"both\") && incoming.length > 0) {\n lines.push(`## Incoming (${incoming.length})`);\n for (const r of incoming) {\n lines.push(`- ← **${r.type}** ${r.otherLabel} [${r.colSlug}]`);\n }\n lines.push(\"\");\n }\n\n const shown = direction === \"outgoing\" ? outgoing : direction === \"incoming\" ? incoming : enriched;\n if (shown.length === 0) {\n lines.push(`No ${direction} relations found for \\`${entryId}\\`.`);\n }\n\n if (truncated) {\n lines.push(`_Showing first ${MAX_RELATIONS} of ${relations.length} relations. Use entries action=get for the full picture._`);\n }\n\n const structuredRelations = shown.map((r) => ({\n entryId: r.otherEntryId,\n name: r.otherName,\n type: r.type,\n direction: (r.isOutgoing ? \"outgoing\" : \"incoming\") as \"outgoing\" | \"incoming\",\n }));\n\n const nodes = [\n { id: entryId, name: sourceEntry.name, collectionName: \"\" },\n ...shown.map((r) => ({\n id: r.otherEntryId ?? String(Math.random()),\n name: r.otherName,\n collectionName: r.colSlug,\n })),\n ];\n const edges = shown\n .filter((r) => r.otherEntryId)\n .map((r) => ({\n source: entryId,\n target: r.otherEntryId!,\n type: r.type,\n }));\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Found ${relations.length} relations for ${entryId}.`,\n { entryId, relations: structuredRelations, nodes, edges, total: relations.length },\n [{ tool: \"entries\", description: \"View entry details\", parameters: { action: \"get\", entryId } }],\n ),\n };\n}\n\nexport async function handleSuggest(entryId: string, limit: number, depth: number) {\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.graphSuggestLinks\">>(\"chain.graphSuggestLinks\", {\n entryId,\n maxHops: depth,\n limit,\n });\n\n if (!result?.suggestions || result.suggestions.length === 0) {\n return failureResult(\n `No suggestions found for '${entryId}' — it may already be well-connected, or no similar entries exist.`,\n \"NOT_FOUND\",\n `No suggestions found for '${entryId}'.`,\n \"Entry may already be well-connected.\",\n [{ tool: \"relations\", description: \"Check existing relations\", parameters: { action: \"find\", entryId } }],\n );\n }\n\n const resolved = result.resolvedEntry;\n const resolvedLabel = resolved\n ? `\\`${resolved.entryId ?? resolved.name}\\` (${resolved.name})`\n : `\\`${entryId}\\``;\n\n const suggestions = result.suggestions;\n const graphCount = suggestions.filter((s) => s.graphDistance > 0).length;\n const textCount = suggestions.filter((s) => s.graphDistance === -1).length;\n const sourceId = resolved?.entryId ?? entryId;\n\n const lines = [\n `## Suggest Result`,\n \"\",\n `# Link Suggestions for ${resolvedLabel}`,\n `_${suggestions.length} potential connections (${graphCount} via graph, ${textCount} via text similarity)._`,\n \"\",\n ];\n\n const top3 = suggestions.slice(0, 3);\n lines.push(\"## Quick Wins (top 3)\");\n const batchArgs: string[] = [];\n for (const s of top3) {\n const tid = s.entryId ?? \"(no ID)\";\n const relType = s.recommendedRelationType || \"related_to\";\n lines.push(`- **${tid}**: ${s.name} [${s.collectionSlug}] — ${s.score}/100 → \\`${relType}\\``);\n if (s.entryId) batchArgs.push(`{from:\"${sourceId}\",to:\"${tid}\",type:\"${relType}\"}`);\n }\n lines.push(\"\");\n if (batchArgs.length > 0) {\n lines.push(`**Link all 3:** \\`relations action=batch-create relations=[${batchArgs.join(\",\")}]\\``);\n lines.push(\"\");\n }\n\n if (suggestions.length > 3) {\n lines.push(\"## All Suggestions\");\n for (let i = 0; i < suggestions.length; i++) {\n const s = suggestions[i];\n const scoreBar = \"█\".repeat(Math.round(s.score / 10)) + \"░\".repeat(10 - Math.round(s.score / 10));\n const hopLabel = s.graphDistance > 0 ? `${s.graphDistance}-hop` : \"text\";\n const recType = s.recommendedRelationType !== \"related_to\" ? ` → \\`${s.recommendedRelationType}\\`` : \"\";\n lines.push(`${i + 1}. **${s.entryId ?? \"(no ID)\"}**: ${s.name} [${s.collectionSlug}] (${hopLabel})`);\n lines.push(` ${scoreBar} ${s.score}/100${recType}`);\n if (s.preview) lines.push(` ${s.preview}`);\n lines.push(` _${s.reasoning}_`);\n }\n }\n\n lines.push(\"\");\n lines.push(`**To link one:** \\`relations action=create from=\"${sourceId}\" to=\"{target_id}\" type=\"{type}\"\\``);\n lines.push(`**To dismiss:** \\`relations action=dismiss from=\"${sourceId}\" to=\"{target_id}\" type=\"{type}\"\\``);\n\n const structuredSuggestions = suggestions.map((s) => ({\n targetEntryId: s.entryId,\n targetName: s.name,\n relationType: s.recommendedRelationType || \"related_to\",\n direction: \"outgoing\" as const,\n confidence: s.score,\n reason: s.reasoning,\n }));\n\n const nodes = [\n { id: sourceId, name: resolved?.name ?? entryId, collectionName: \"\" },\n ...suggestions.map((s) => ({\n id: s.entryId ?? String(Math.random()),\n name: s.name,\n collectionName: s.collectionSlug,\n })),\n ];\n const edges = suggestions\n .filter((s) => s.entryId)\n .map((s) => ({\n source: sourceId,\n target: s.entryId!,\n type: s.recommendedRelationType || \"suggested\",\n }));\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Found ${suggestions.length} link suggestions for ${resolvedLabel}.`,\n { entryId: sourceId, suggestions: structuredSuggestions, nodes, edges, total: suggestions.length },\n [{ tool: \"relations\", description: \"Create links\", parameters: { action: \"batch-create\" } }],\n ),\n };\n}\n","/**\n * Context compound tool — gather, build.\n * Consolidates gather-context and get-build-context into one tool.\n * gather: entry-based graph traversal, task-based auto-load, or graph mode with provenance.\n * build: structured build spec for an entry (requires active session).\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, getWorkspaceId, requireActiveSession, runWithToolContext } from \"../client.js\";\nimport { success, failure, thinWrapper, parseOrFail, notFoundResult, validationResult, type ToolResult } from \"../envelope.js\";\nimport { translateStaleToolNames } from \"./knowledge-helpers.js\";\nimport { trackKnowledgeGap } from \"../analytics.js\";\nimport { recordGap } from \"../gap-store.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { handleGetLastVerifiedBrief } from \"./documents.js\";\n\nfunction annotateStaleNames(text: string): string {\n const footnote = translateStaleToolNames(text);\n return footnote ? text + footnote : text;\n}\n\n/**\n * Collection header hint for epistemic collections in context views.\n * BET-281: When governanceRole field is available on collections, replace\n * name-based checks with governanceRole === 'epistemic'. Currently the\n * collection display name is stable and this is pure UX chrome.\n */\nfunction epistemicCollectionHint(collectionName: string): string {\n const lc = collectionName.toLowerCase();\n if (lc === \"insights\") return \" — _verify confidence with `entries action=get`_\";\n if (lc === \"assumptions\") return \" — _check evidence strength with `entries action=get`_\";\n return \"\";\n}\n\ninterface ContextEntry {\n // `entryId` is a REQUIRED key (never optional-undefined) on BOTH real server sources this\n // type covers: convex/chain/chainIntelligence.ts's `ContextEntry.entryId: string | null`\n // AND convex/agentKnowledge/startupResolver.ts's `StartupContextEntry.entryId: string |\n // null` — verified, both always send the key (nullable, not absent). Non-optional here\n // matches reality (Copilot nit, PR #397 review).\n entryId: string | null;\n name: string;\n // Matches convex/agentKnowledge/startupResolver.ts's `StartupContextEntry.collectionName:\n // string | null` — this file also receives that shape directly (see `byCollection` below).\n collectionName: string | null;\n relationType: string;\n relationDirection: \"outgoing\" | \"incoming\";\n hop: number;\n score?: number;\n scoreFlags?: string[];\n // `preview` genuinely DIFFERS across this type's two real server sources: REQUIRED on\n // convex/chain/chainIntelligence.ts's `ContextEntry.preview: string | null`, but OPTIONAL\n // on convex/agentKnowledge/startupResolver.ts's `StartupContextEntry.preview?: string |\n // null`. Stays optional here (the weaker of the two guarantees) so this shared type remains\n // structurally safe for entries assigned from either route (Copilot nit, PR #397 review —\n // the prior comment here incorrectly claimed universal non-optionality).\n preview?: string | null;\n /** BET-240 S0: Entry provenance — human, agent, or external. */\n origin?: \"human\" | \"agent\" | \"external\";\n provenance?: Array<{ entryId?: string | null; name: string; relationType: string }>;\n}\n\ninterface GatherResult {\n root: { entryId: string; name: string } | null;\n related: ContextEntry[];\n totalRelations: number;\n hopsTraversed: number;\n}\n\ninterface GraphGatherResult {\n root: { entryId: string; name: string } | null;\n context: ContextEntry[];\n totalFound: number;\n hopsTraversed: number;\n}\n\n// `TaskGatherResult` (a hand-written local mirror) was retired — PR #395, Lane C S3b\n// annotation pass. The task-mode branch of `handleGather` below types its own `result`\n// via `chain.resolveTaskStartupHybrid`/`chain.resolveTaskStartup` (both share this shape);\n// `BindingGovernanceEntry` now derives directly from that real server type instead of a\n// second, independently-drifting mirror.\ntype TaskGatherResultRoute = GatewayRouteReturnByName<\"chain.resolveTaskStartup\">;\ntype BindingGovernanceEntry = TaskGatherResultRoute[\"bindingGovernance\"][\"principles\"][number];\n\ninterface JourneyStage {\n slotId: string;\n label: string;\n ingredients: Array<{ entryId: string; name: string; status: string }>;\n}\n\ninterface JourneyGatherResult {\n map: { entryId: string; name: string; templateId: string; templateName: string };\n stages: JourneyStage[];\n context: ContextEntry[];\n totalFound: number;\n seedCount: number;\n truncated: boolean;\n}\n\ninterface BuildResult {\n entry: { name: string; entryId?: string; collectionSlug: string; status: string; data: Record<string, unknown> };\n relatedByCollection: Record<string, Array<{ entryId?: string; name: string; relationType: string }>>;\n businessRules: Array<{ entryId?: string; name: string; description?: string }>;\n glossaryTerms: Array<{ entryId?: string; name: string; definition?: string }>;\n rulesToHonor: unknown[];\n chainRefs: string[];\n contextTruncated: boolean;\n}\n\ninterface NeighborhoodItem {\n entryDocId: string;\n entryId: string | null;\n name: string;\n status?: string;\n hop?: number;\n relationType?: string;\n unresolvedFlag?: boolean;\n openCount?: number;\n blockedCount?: number;\n}\n\ninterface NeighborhoodResult {\n blockingChain: NeighborhoodItem[];\n dependencyChain: NeighborhoodItem[];\n parentContext: (NeighborhoodItem & { openCount: number; blockedCount: number }) | null;\n relatedTensions: NeighborhoodItem[];\n stalenessSignal: { isStale: boolean; daysSinceUpdate: number } | null;\n isolationSignal: boolean;\n}\n\n// WP-484 S2 (§3): `context` absorbs `documents` → action=last-verified-brief.\n// Legacy `documents` tool stays registered alongside (§7 \"alongside\"\n// mechanic) — both call the SAME handleGetLastVerifiedBrief function, one\n// business-logic path.\nconst CONTEXT_ACTIONS = [\"gather\", \"build\", \"neighborhood\", \"changes\", \"chain\", \"cross-cut\", \"incremental\", \"brief\", \"last-verified-brief\"] as const;\ntype ContextAction = (typeof CONTEXT_ACTIONS)[number];\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const contextSchema = z.object({\n // provenance: neighborhood BET-142; changes/chain/cross-cut/incremental/brief BET-239 (E4, E6)\n action: z.enum(CONTEXT_ACTIONS).describe(\n \"'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). \" +\n \"'build': structured build spec for an entry. \" +\n \"'neighborhood': typed graph neighborhood for an entry — blocking chain, dependencies, parent context, tensions, staleness. \" +\n \"'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. \" +\n \"'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). \" +\n \"'cross-cut': structural aggregation — all relations of a given type grouped by source collection. Requires 'relationType' parameter. \" +\n \"'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. \" +\n \"'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets + tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. \" +\n \"'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair (absorbs documents action=get-last-verified-brief). Requires templateId and scopeKey.\",\n ),\n entryId: z.string().max(200).optional().describe(\"For 'build'/'neighborhood'/'chain': entry ID, e.g. '<PREFIX>-<n>'. For 'gather': optional entry ID for entry-graph mode.\"),\n mapEntryId: z.string().max(200).optional().describe(\n \"For 'gather': journey map entry ID for journey-aware context. Returns context organised by journey stage. \" +\n \"Takes precedence over entryId when both are supplied. Example: '<PREFIX>-<n>'.\",\n ),\n task: z.string().max(2000).optional().describe(\"For 'gather': natural-language task description for loading task-relevant governance, binding constraints, and supporting context.\"),\n since: z.string().max(200).optional().describe(\n \"For 'changes': ISO 8601 timestamp — returns entries/relations modified since this time. \" +\n \"For 'brief' briefType='delta': optional custom timestamp. Example: '2026-03-24T00:00:00Z'.\",\n ),\n direction: z.enum([\"outgoing\", \"incoming\"]).default(\"outgoing\").optional()\n .describe(\"For 'chain' action: traversal direction. 'outgoing' follows relations from source, 'incoming' follows relations to source. Default: outgoing.\"),\n relationType: z.string().max(200).optional().describe(\n \"Relation type filter. For 'chain': optional filter to traverse only this relation type. \" +\n \"For 'cross-cut': required — scans all relations of this type across the workspace. \" +\n \"Examples: 'part_of', 'informs', 'governs', 'blocks', 'depends_on'.\",\n ),\n mode: z.enum([\"search\", \"graph\"]).default(\"search\").optional()\n .describe(\"For gather: 'search' (default) or 'graph' (enhanced with provenance paths). Ignored when mapEntryId is provided.\"),\n maxHops: z.number().min(1).max(4).default(2)\n .describe(\"Relation traversal depth (1=direct only, 2=default, 3=wide net, 4=deep chain walk)\"),\n maxResults: z.number().min(1).max(25).default(10).optional()\n .describe(\"Max entries to return in gather task mode (default 10)\"),\n strategy: z.enum([\"hybrid\", \"keyword\"]).default(\"keyword\").optional()\n .describe(\"Seed strategy for task-based gather: 'keyword' (FTS only, default) or 'hybrid' (vector + FTS). Only affects task mode.\"),\n skill: z.string().max(200).optional().describe(\n \"Skill name for 'incremental' action — identifies which skill's brief history to compare against. \" +\n \"Examples: 'preflight', 'shaping', 'review'. Required when action is 'incremental'.\",\n ),\n briefType: z.enum([\"steering\", \"confidence\", \"delta\"]).optional().describe(\n \"Compound query type for 'brief' action. \" +\n \"'steering': 7d changes + structural aggregation (part_of, depends_on, constrains) + incremental delta + workspace readiness. \" +\n \"'confidence': 7d changes + active bets summary + active tensions breakdown. \" +\n \"'delta': changes + relations since a custom timestamp (use 'since' param). \" +\n \"Required when action is 'brief'.\",\n ),\n templateId: z.string().max(200).optional().describe(\n \"For 'last-verified-brief': brief template identifier — currently 'steering-brief' is the only registered template.\",\n ),\n scopeKey: z.string().max(200).optional().describe(\n \"For 'last-verified-brief': canonical scope key — 'workspace:<workspaceId>' or 'initiative:<INI-ID>'.\",\n ),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion.\nconst contextGatherVariant = z.object({\n action: z.literal(\"gather\"),\n entryId: z.string().max(200).optional(),\n mapEntryId: z.string().max(200).optional(),\n task: z.string().max(2000).optional(),\n mode: z.enum([\"search\", \"graph\"]).optional().default(\"search\"),\n maxHops: z.number().min(1).max(4).optional().default(2),\n maxResults: z.number().min(1).max(25).optional().default(10),\n strategy: z.enum([\"hybrid\", \"keyword\"]).optional().default(\"keyword\"),\n});\nconst contextBuildVariant = z.object({\n action: z.literal(\"build\"),\n entryId: z.string().max(200),\n maxHops: z.number().min(1).max(4).optional().default(2),\n});\nconst contextNeighborhoodVariant = z.object({\n action: z.literal(\"neighborhood\"),\n entryId: z.string().max(200),\n});\nconst contextChangesVariant = z.object({\n action: z.literal(\"changes\"),\n since: z.string().max(200),\n});\nconst contextChainVariant = z.object({\n action: z.literal(\"chain\"),\n entryId: z.string().max(200),\n direction: z.enum([\"outgoing\", \"incoming\"]).optional().default(\"outgoing\"),\n maxHops: z.number().min(1).max(4).optional().default(2),\n relationType: z.string().max(200).optional(),\n});\nconst contextCrossCutVariant = z.object({\n action: z.literal(\"cross-cut\"),\n relationType: z.string().max(200),\n});\nconst contextIncrementalVariant = z.object({\n action: z.literal(\"incremental\"),\n skill: z.string().max(200),\n});\nconst contextBriefVariant = z.object({\n action: z.literal(\"brief\"),\n briefType: z.enum([\"steering\", \"confidence\", \"delta\"]),\n since: z.string().max(200).optional(),\n});\nconst contextLastVerifiedBriefVariant = z.object({\n action: z.literal(\"last-verified-brief\"),\n templateId: z.string().max(200),\n scopeKey: z.string().max(200),\n});\n\nexport const contextActionUnion = z.discriminatedUnion(\"action\", [\n contextGatherVariant,\n contextBuildVariant,\n contextNeighborhoodVariant,\n contextChangesVariant,\n contextChainVariant,\n contextCrossCutVariant,\n contextIncrementalVariant,\n contextBriefVariant,\n contextLastVerifiedBriefVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const CONTEXT_ACTION_SPECS: Record<ContextAction, ActionParamSpec> = {\n gather: { params: [\"entryId\", \"mapEntryId\", \"task\", \"mode\", \"maxHops\", \"maxResults\", \"strategy\"], description: \"All params optional; entryId/mapEntryId/task select the mode.\" },\n build: { params: [\"entryId\", \"maxHops\"], description: \"entryId is required.\" },\n neighborhood: { params: [\"entryId\"], description: \"entryId is required.\" },\n changes: { params: [\"since\"], description: \"since (ISO 8601) is required.\" },\n chain: { params: [\"entryId\", \"direction\", \"maxHops\", \"relationType\"], description: \"entryId is required.\" },\n \"cross-cut\": { params: [\"relationType\"], description: \"relationType is required.\" },\n incremental: { params: [\"skill\"], description: \"skill is required.\" },\n brief: { params: [\"briefType\", \"since\"], description: \"briefType is required.\" },\n \"last-verified-brief\": { params: [\"templateId\", \"scopeKey\"], description: \"Both templateId and scopeKey are required.\" },\n};\n\nexport function registerContextTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const contextHandlers: Record<ContextAction, (data: any) => Promise<ToolResult>> = {\n gather: (data) => data.mapEntryId\n ? handleJourneyGather(server, data.mapEntryId, data.maxHops ?? 2, data.maxResults ?? 20)\n : handleGather(server, data.entryId, data.task, data.mode ?? \"search\", data.maxHops ?? 2, data.maxResults ?? 10, data.strategy ?? \"keyword\"),\n build: (data) => handleBuild(server, data.entryId, data.maxHops ?? 2),\n neighborhood: (data) => handleNeighborhood(data.entryId),\n changes: (data) => handleChanges(data.since),\n chain: (data) => handleChainWalk(data.entryId, data.direction ?? \"outgoing\", data.maxHops ?? 2, data.relationType),\n \"cross-cut\": (data) => handleCrossCut(data.relationType),\n incremental: (data) => handleIncremental(data.skill),\n brief: (data) => {\n const sinceMs = data.briefType === \"delta\" && data.since ? Date.parse(data.since) : undefined;\n if (data.briefType === \"delta\" && data.since && (sinceMs === undefined || isNaN(sinceMs))) {\n return Promise.resolve({\n content: [{ type: \"text\" as const, text: `Invalid 'since' timestamp: '${data.since}'. Use ISO 8601 format (e.g. '2026-03-24T00:00:00Z').` }],\n structuredContent: failure(\"VALIDATION_ERROR\", `Invalid 'since' timestamp: '${data.since}'.`),\n });\n }\n return handleBrief(data.briefType, sinceMs);\n },\n \"last-verified-brief\": (data) => handleGetLastVerifiedBrief(data.templateId, data.scopeKey),\n };\n\n server.registerTool(\n \"context\",\n {\n title: \"Context\",\n description:\n \"Assemble knowledge context in one call. Nine actions:\\n\\n\" +\n \"- **gather**: Three modes — (1) By entry: traverse the graph around a specific entry. \" +\n \"(2) By task: load task-relevant governance, binding constraints, and supporting domain knowledge for a natural-language task. \" +\n \"(3) Graph mode (entryId + mode='graph'): enhanced traversal with provenance paths.\\n\" +\n \"- **build**: Structured build spec for any entry — data, related entries, business rules, \" +\n \"glossary terms, chain refs. Use when starting a build. Requires active session.\\n\" +\n \"- **neighborhood**: Typed graph neighborhood — blocking chain (what this blocks, 3 hops), \" +\n \"dependency chain (what blocks this), parent context (sibling count), related tensions, \" +\n \"staleness signal, isolation signal. Fast indexed lookups. Requires entryId.\\n\" +\n \"- **changes**: Detect entries modified and relations created since a timestamp. \" +\n \"Use for incremental updates instead of full traversal. Requires 'since' (ISO 8601). \" +\n // BET-239\n \"Returns grouped counts by collection. Cap: 200 entries.\\n\" +\n // BET-239\n \"- **chain**: Directed deep traversal along one relation type to depth 4. \" +\n \"Use for dependency analysis, governance chains, strategic alignment. Requires entryId. \" +\n \"Optional: direction (outgoing/incoming), relationType, maxHops (1-4). \" +\n \"Cycle detection, fan-out cap 10/hop, total cap 100 nodes. Returns tree + edges.\\n\" +\n \"- **cross-cut**: Structural aggregation — all relations of a given type across the workspace, \" +\n \"grouped by source collection. Use to answer 'show me everything connected by part_of'. \" +\n // BET-239\n \"Requires 'relationType'. Cap: 500 entries.\\n\" +\n \"- **incremental**: Delta since last brief run for a skill. Returns only entries changed since \" +\n \"the skill's last brief, filtering out previously surfaced entries. Requires 'skill' parameter. \" +\n // BET-239 E4\n \"Use for steering briefs that need incremental awareness.\\n\" +\n \"- **brief**: Compound intelligence query composing multiple primitives. Requires 'briefType': \" +\n \"'steering' (7d changes + structure + delta + readiness), 'confidence' (7d changes + active work packages + tensions), \" +\n // BET-239 E6\n \"or 'delta' (changes since custom timestamp). Auto-records brief run for steering.\\n\" +\n \"- **last-verified-brief**: Fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair \" +\n \"(absorbs `documents`). Use to build delta narratives.\",\n inputSchema: contextSchema,\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(contextSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"context\", action }, () =>\n dispatchDiscriminated(\"context\", contextActionUnion, parsed.data, CONTEXT_ACTION_SPECS, contextHandlers),\n );\n }),\n );\n}\n\nasync function handleGather(\n server: McpServer,\n entryId: string | undefined,\n task: string | undefined,\n mode: \"search\" | \"graph\",\n maxHops: number,\n maxResults: number,\n strategy: \"hybrid\" | \"keyword\" = \"keyword\",\n) {\n if (!entryId && !task) {\n return validationResult(\"Provide either entryId (graph traversal) or task (auto-load context).\");\n }\n\n // Graph mode: enhanced traversal with provenance paths\n if (entryId && mode === \"graph\") {\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Graph traversal for ${entryId} (depth: ${maxHops})...`,\n logger: \"product-brain\",\n });\n\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.graphGatherContext\">>(\"chain.graphGatherContext\", {\n entryId,\n maxHops,\n });\n\n if (!result?.root) {\n return notFoundResult(entryId!, `Entry '${entryId}' not found. Try search to find the right ID.`);\n }\n const root = result.root;\n\n if (result.context.length === 0) {\n const recorded = recordGap({ query: root.entryId, tool: \"context\", action: \"gather\", gapType: \"context_graph_empty\" });\n if (recorded) {\n getWorkspaceId()\n .then((wsId) => trackKnowledgeGap(wsId, { query: root.entryId, tool: \"context\", action: \"gather\", gap_type: \"context_graph_empty\" }))\n .catch(() => {});\n }\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Context for ${root.entryId}: ${root.name}\\n\\n` +\n `_No relations found._ This entry is not yet connected to the knowledge graph.\\n\\n` +\n `Use \\`relations action=suggest\\` to discover potential connections.`,\n }],\n structuredContent: success(\n `No relations found for ${root.entryId}. Entry not yet connected.`,\n { root, context: [], totalFound: 0 },\n [{ tool: \"relations\", description: \"Discover connections\", parameters: { action: \"suggest\", entryId: root.entryId } }],\n ),\n };\n }\n\n const byCollection = new Map<string, ContextEntry[]>();\n for (const entry of result.context) {\n const key = entry.collectionName ?? \"Uncategorized\";\n if (!byCollection.has(key)) byCollection.set(key, []);\n byCollection.get(key)!.push(entry);\n }\n\n const lines: string[] = [\n `# Context for ${root.entryId}: ${root.name} (graph mode)`,\n `_${result.totalFound} related entries across ${byCollection.size} collections (${result.hopsTraversed} hops)_`,\n \"\",\n ];\n\n for (const [collName, entries] of byCollection) {\n lines.push(`## ${collName} (${entries.length})${epistemicCollectionHint(collName)}`);\n for (const e of entries) {\n const arrow = e.relationDirection === \"outgoing\" ? \"→\" : \"←\";\n const id = e.entryId ? `${e.entryId}: ` : \"\";\n const hopLabel = e.hop > 1 ? ` (hop ${e.hop})` : \"\";\n const scoreLabel = typeof e.score === \"number\" ? ` ${e.score}` : \"\";\n const flagsLabel = e.scoreFlags?.length ? ` [${e.scoreFlags.join(\", \")}]` : \"\";\n const originLabel = e.origin ? ` (origin: ${e.origin})` : \"\";\n const provenancePath = e.provenance && e.provenance.length > 1\n ? `\\n _Path: ${e.provenance.map((p) => `${p.entryId ?? p.name} [${p.relationType}]`).join(\" → \")}_`\n : \"\";\n const preview = e.preview ? `\\n ${e.preview.substring(0, 120)}` : \"\";\n lines.push(`- ${arrow} **${e.relationType}** ${id}${e.name}${hopLabel}${scoreLabel}${flagsLabel}${originLabel}${provenancePath}${preview}`);\n }\n lines.push(\"\");\n }\n\n const rootId = root.entryId ?? \"root\";\n const nodes = [\n { id: rootId, name: root.name, collectionName: \"\" },\n ...result.context.map((e) => ({\n id: e.entryId ?? String(Math.random()),\n name: e.name,\n collectionName: e.collectionName,\n })),\n ];\n const edges = result.context\n .filter((e) => e.entryId)\n .map((e) => ({\n source: rootId,\n target: e.entryId!,\n type: e.relationType,\n }));\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Gathered ${result.totalFound} related entries for ${root.entryId} (${result.hopsTraversed} hops, graph mode).`,\n { nodes, edges, root, totalFound: result.totalFound },\n ),\n };\n }\n\n // Task mode: unified search-then-traverse via intelligence layer\n // BET-205 Slice 2: strategy routing — hybrid calls vector+FTS action, keyword uses existing FTS query\n if (task && !entryId) {\n const strategyLabel = strategy === \"hybrid\" ? \"hybrid (vector + FTS)\" : \"keyword (FTS only)\";\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Loading context for task: \"${task.substring(0, 80)}...\" [strategy: ${strategyLabel}]`,\n logger: \"product-brain\",\n });\n\n const result = strategy === \"hybrid\"\n ? await kernelQuery<GatewayRouteReturnByName<\"chain.resolveTaskStartupHybrid\">>(\"chain.resolveTaskStartupHybrid\", {\n task,\n maxHops,\n maxResults,\n })\n : await kernelQuery<GatewayRouteReturnByName<\"chain.resolveTaskStartup\">>(\"chain.resolveTaskStartup\", {\n task,\n maxHops,\n maxResults,\n });\n\n if (!result || result.totalFound === 0) {\n const taskQuery = task.slice(0, 200);\n const recorded = recordGap({ query: taskQuery, tool: \"context\", action: \"gather\", gapType: \"context_task_empty\" });\n if (recorded) {\n getWorkspaceId()\n .then((wsId) => trackKnowledgeGap(wsId, { query: taskQuery, tool: \"context\", action: \"gather\", gap_type: \"context_task_empty\" }))\n .catch(() => {});\n }\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Task Constraints Loaded\\n\\n**Confidence:** None\\n\\n` +\n `No task-relevant governance or supporting context was found yet. If you discover relevant knowledge during this task, ` +\n `use \\`capture\\` with a name and description to add it.\\n\\n` +\n `_This helps future sessions start with better constraints and context._`,\n }],\n structuredContent: failure(\n \"NOT_FOUND\",\n \"No task-relevant governance or supporting context was found yet.\",\n \"If you discover relevant knowledge during this task, capture it with a name and description.\",\n [{ tool: \"entries\", description: \"Search for related terms\", parameters: { action: \"search\", query: task.split(\" \").slice(0, 3).join(\" \") } }],\n ),\n };\n }\n\n const bindingGovernanceCollections = result.bindingGovernance.byCollection ?? [];\n const hasBindingGovernance =\n bindingGovernanceCollections.some((bucket) => bucket.entries.length > 0) ||\n result.bindingGovernance.principles.length > 0 ||\n result.bindingGovernance.standards.length > 0 ||\n result.bindingGovernance.businessRules.length > 0;\n\n const byCollection = new Map<string, ContextEntry[]>();\n for (const entry of result.supportingContext) {\n const key = entry.collectionName ?? \"Uncategorized\";\n if (!byCollection.has(key)) byCollection.set(key, []);\n byCollection.get(key)!.push(entry);\n }\n const steeringCount = result.steeringContext.length;\n const collectionCount = new Set(\n [...result.steeringContext, ...result.supportingContext].map((entry) => entry.collectionName),\n ).size;\n\n // Format seed display — hybrid seeds include source (vector/fts/both), keyword seeds do not\n const seedDisplay = result.seeds?.map((s: any) => {\n const id = s.entryId ?? s.name;\n return s.source ? `${id} [${s.source}]` : id;\n }).join(\", \") ?? \"none\";\n\n const lines: string[] = [\n `# Task Constraints Loaded`,\n `**Confidence:** ${result.confidence.charAt(0).toUpperCase() + result.confidence.slice(1)}`,\n `**Grounding:** ${result.groundingStatus}`,\n `**Strategy:** ${strategyLabel}`,\n `**Matched:** ${result.totalFound} entries across ${collectionCount} collection${collectionCount === 1 ? \"\" : \"s\"}`,\n `**Seeds:** ${seedDisplay}`,\n \"\",\n ];\n\n lines.push(\"_Use this task gather as the live constraint load for the work you are about to do, then open any cited entries for full details._\");\n lines.push(\"\");\n\n if (hasBindingGovernance) {\n lines.push(\"## Binding governance\");\n lines.push(\"_These are the non-optional rules and standards that govern this task._\");\n lines.push(\"\");\n\n const renderGovernanceEntries = (entries: BindingGovernanceEntry[]) => {\n for (const entry of entries) {\n const id = entry.entryId ? `**${entry.entryId}:** ` : \"\";\n const scoreLabel = typeof entry.score === \"number\" ? ` ${entry.score}` : \"\";\n const flagsLabel = entry.scoreFlags?.length ? ` [${entry.scoreFlags.join(\", \")}]` : \"\";\n const originLabel = entry.origin ? ` (origin: ${entry.origin})` : \"\";\n // DEC-446 / TEN-2383: same tier label as orient-shared.ts formatGovernanceEntry\n // tier 1=[direct], tier 2=[domain], tier 3=[org]. Keep in sync with orient-shared.ts.\n const tierLabel = entry.tier === 1 ? \" `[direct]`\" : entry.tier === 2 ? \" `[domain]`\" : entry.tier === 3 ? \" `[org]`\" : \"\";\n lines.push(`- ${id}${entry.name}${tierLabel}${scoreLabel}${flagsLabel}${originLabel}`);\n if (entry.preview) lines.push(` _${entry.preview}_`);\n }\n };\n\n const visibleCollectionBuckets = bindingGovernanceCollections.filter((bucket) => bucket.entries.length > 0);\n if (visibleCollectionBuckets.length > 0) {\n for (const bucket of visibleCollectionBuckets) {\n const title = bucket.collectionName ?? bucket.collectionSlug ?? \"Binding governance\";\n lines.push(`### ${title} (${bucket.entries.length})`);\n renderGovernanceEntries(bucket.entries);\n lines.push(\"\");\n }\n } else {\n const governanceSections: Array<[string, BindingGovernanceEntry[]]> = [\n [\"Principles\", result.bindingGovernance.principles],\n [\"Standards\", result.bindingGovernance.standards],\n [\"Business Rules\", result.bindingGovernance.businessRules],\n ];\n\n for (const [title, entries] of governanceSections) {\n if (entries.length === 0) continue;\n lines.push(`### ${title} (${entries.length})`);\n renderGovernanceEntries(entries);\n lines.push(\"\");\n }\n }\n }\n\n lines.push(\"## Steering context\");\n lines.push(\"_These entries set the frame for the work before you drop into broader supporting detail._\");\n lines.push(\"\");\n if (steeringCount === 0) {\n lines.push(\"_No steering context matched yet._\");\n lines.push(\"\");\n } else {\n for (const entry of result.steeringContext) {\n const id = entry.entryId ? `**${entry.entryId}:** ` : \"\";\n const scoreLabel = typeof entry.score === \"number\" ? ` ${entry.score}` : \"\";\n const flagsLabel = entry.scoreFlags?.length ? ` [${entry.scoreFlags.join(\", \")}]` : \"\";\n const originLabel = entry.origin ? ` (origin: ${entry.origin})` : \"\";\n const hopLabel = entry.hop > 0 ? ` _(hop ${entry.hop}, ${entry.relationDirection === \"outgoing\" ? \"→\" : \"←\"} ${entry.relationType})_` : \"\";\n lines.push(`- ${id}${entry.name}${scoreLabel}${flagsLabel}${originLabel}${hopLabel}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"## Supporting context\");\n lines.push(\"_These entries add implementation detail, history, and neighboring domain context._\");\n lines.push(\"\");\n\n if (byCollection.size === 0) {\n lines.push(\"_No supporting context matched yet. Open the binding governance entries first._\");\n lines.push(\"\");\n } else {\n for (const [collName, entries] of byCollection) {\n lines.push(`### ${collName} (${entries.length})${epistemicCollectionHint(collName)}`);\n for (const e of entries) {\n const arrow = e.relationDirection === \"outgoing\" ? \"→\" : \"←\";\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const scoreLabel = typeof e.score === \"number\" ? ` ${e.score}` : \"\";\n const flagsLabel = e.scoreFlags?.length ? ` [${e.scoreFlags.join(\", \")}]` : \"\";\n const originLabel = e.origin ? ` (origin: ${e.origin})` : \"\";\n const hopLabel = e.hop > 0 ? ` _(hop ${e.hop}, ${arrow} ${e.relationType})_` : \"\";\n lines.push(`- ${id}${e.name}${scoreLabel}${flagsLabel}${originLabel}${hopLabel}`);\n }\n lines.push(\"\");\n }\n }\n\n lines.push(`_Use \\`entries action=get\\` for full details on any entry._`);\n\n const taskEntries = [...result.steeringContext, ...result.supportingContext].map((e) => ({\n entryId: e.entryId ?? String(Math.random()),\n name: e.name,\n collectionName: e.collectionName,\n }));\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Loaded ${result.totalFound} task constraints and related entries (${result.confidence} confidence, ${strategy} strategy).`,\n {\n entries: taskEntries,\n totalFound: result.totalFound,\n confidence: result.confidence,\n groundingStatus: result.groundingStatus,\n strategy,\n bindingGovernance: result.bindingGovernance,\n steeringContext: result.steeringContext.map((entry) => ({\n entryId: entry.entryId ?? null,\n name: entry.name,\n collectionName: entry.collectionName,\n relationType: entry.relationType,\n relationDirection: entry.relationDirection,\n hop: entry.hop,\n score: entry.score,\n scoreFlags: entry.scoreFlags,\n preview: entry.preview,\n origin: entry.origin,\n })),\n supportingContext: result.supportingContext.map((entry) => ({\n entryId: entry.entryId ?? null,\n name: entry.name,\n collectionName: entry.collectionName,\n relationType: entry.relationType,\n relationDirection: entry.relationDirection,\n hop: entry.hop,\n score: entry.score,\n scoreFlags: entry.scoreFlags,\n preview: entry.preview,\n origin: entry.origin,\n })),\n },\n ),\n };\n }\n\n // Entry mode: traverse the knowledge graph around a specific entry\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Gathering context for ${entryId} (depth: ${maxHops})...`,\n logger: \"product-brain\",\n });\n\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.gatherContext\">>(\"chain.gatherContext\", { entryId, maxHops });\n\n if (!result?.root) {\n return notFoundResult(entryId!, `Entry '${entryId}' not found. Try search to find the right ID.`);\n }\n const root = result.root;\n\n if (result.related.length === 0) {\n const recorded = recordGap({ query: root.entryId, tool: \"context\", action: \"gather\", gapType: \"context_entry_isolated\" });\n if (recorded) {\n getWorkspaceId()\n .then((wsId) => trackKnowledgeGap(wsId, { query: root.entryId, tool: \"context\", action: \"gather\", gap_type: \"context_entry_isolated\" }))\n .catch(() => {});\n }\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Context for ${root.entryId}: ${root.name}\\n\\n` +\n `_No relations found._ This entry is not yet connected to the knowledge graph.\\n\\n` +\n `Use \\`relations action=suggest\\` to discover potential connections, or \\`relations action=create\\` to link manually.`,\n }],\n structuredContent: success(\n `No relations found for ${root.entryId}. Entry not yet connected.`,\n { root, related: [], totalRelations: 0 },\n [{ tool: \"relations\", description: \"Discover connections\", parameters: { action: \"suggest\", entryId: root.entryId } }],\n ),\n };\n }\n\n const byCollection = new Map<string, typeof result.related>();\n for (const entry of result.related) {\n const key = entry.collectionName ?? \"Uncategorized\";\n if (!byCollection.has(key)) byCollection.set(key, []);\n byCollection.get(key)!.push(entry);\n }\n\n const lines: string[] = [\n `# Context for ${root.entryId}: ${root.name}`,\n `_${result.totalRelations} related entries across ${byCollection.size} collections (${result.hopsTraversed} hops traversed)_`,\n \"\",\n ];\n\n for (const [collName, entries] of byCollection) {\n lines.push(`## ${collName} (${entries.length})${epistemicCollectionHint(collName)}`);\n for (const e of entries) {\n const arrow = e.relationDirection === \"outgoing\" ? \"\\u2192\" : \"\\u2190\";\n const hopLabel = e.hop > 1 ? ` (hop ${e.hop})` : \"\";\n const id = e.entryId ? `${e.entryId}: ` : \"\";\n lines.push(`- ${arrow} **${e.relationType}** ${id}${e.name}${hopLabel}`);\n }\n lines.push(\"\");\n }\n\n const rootId = root.entryId ?? \"root\";\n const nodes = [\n { id: rootId, name: root.name, collectionName: \"\" },\n ...result.related.map((e) => ({\n id: e.entryId ?? String(Math.random()),\n name: e.name,\n collectionName: e.collectionName,\n })),\n ];\n const edges = result.related\n .filter((e) => e.entryId)\n .map((e) => ({\n source: rootId,\n target: e.entryId!,\n type: e.relationType,\n }));\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Gathered ${result.totalRelations} related entries for ${root.entryId} (${result.hopsTraversed} hops).`,\n { nodes, edges, root, totalRelations: result.totalRelations },\n ),\n };\n}\n\nasync function handleJourneyGather(\n server: McpServer,\n mapEntryId: string,\n maxHops: number,\n maxResults: number,\n) {\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Loading journey context for map ${mapEntryId}...`,\n logger: \"product-brain\",\n });\n\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.journeyAwareGatherContext\">>(\"chain.journeyAwareGatherContext\", {\n mapEntryId,\n maxHops,\n maxResults,\n });\n\n if (!result) {\n return notFoundResult(\n mapEntryId,\n `Journey map '${mapEntryId}' not found or has no slot data. Verify the map entry ID.`,\n \"Verify the map entry ID is correct.\",\n );\n }\n\n if (result.stages.length === 0 || result.seedCount === 0) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Journey Context: ${result.map.name}\\n\\n` +\n `_No ingredients found in this journey map._\\n\\n` +\n `Add journey steps in Cortex — the \\`map\\` MCP tool is no longer available.`,\n }],\n structuredContent: success(\n `Journey map ${result.map.name} has no ingredients.`,\n { map: result.map, stages: result.stages, context: [] },\n ),\n };\n }\n\n const lines: string[] = [\n `# Journey Context: ${result.map.name}`,\n `**Template:** ${result.map.templateName} | **Map ID:** ${result.map.entryId}`,\n `**Steps scanned:** ${result.seedCount}${result.truncated ? ` (capped at 10 — ${result.stages.flatMap((s) => s.ingredients).length} total ingredients)` : \"\"}`,\n `**Related knowledge:** ${result.totalFound} entries`,\n \"\",\n \"## Journey Stages\",\n ];\n\n for (const stage of result.stages) {\n const ingredientList = stage.ingredients.length === 0\n ? \"_empty_\"\n : stage.ingredients.map((i) => `${i.entryId}: ${i.name}`).join(\", \");\n lines.push(`- **${stage.label}**: ${ingredientList}`);\n }\n\n if (result.context.length > 0) {\n lines.push(\"\");\n lines.push(\"## Governance & Intelligence\");\n lines.push(`_Entries from the knowledge graph connected to journey steps:_`);\n lines.push(\"\");\n\n const byCollection = new Map<string, ContextEntry[]>();\n for (const entry of result.context) {\n const key = entry.collectionName ?? \"Uncategorized\";\n if (!byCollection.has(key)) byCollection.set(key, []);\n byCollection.get(key)!.push(entry);\n }\n\n for (const [collName, entries] of byCollection) {\n lines.push(`### ${collName} (${entries.length})`);\n for (const e of entries) {\n const arrow = e.relationDirection === \"outgoing\" ? \"→\" : \"←\";\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const scoreLabel = typeof e.score === \"number\" ? ` ${e.score}` : \"\";\n lines.push(`- ${arrow} ${id}${e.name}${scoreLabel}`);\n }\n lines.push(\"\");\n }\n }\n\n lines.push(`_Use \\`entries action=get\\` for full details. Link governance to steps: \\`relations action=create\\`._`);\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Journey context for ${result.map.name}: ${result.totalFound} related entries across ${result.stages.length} stages.`,\n {\n map: result.map,\n stages: result.stages,\n context: result.context.map((e) => ({\n entryId: e.entryId ?? \"\",\n name: e.name,\n collectionName: e.collectionName,\n })),\n },\n ),\n };\n}\n\nasync function handleNeighborhood(entryId: string) {\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.getEntryNeighborhood\">>(\"chain.getEntryNeighborhood\", { entryId, now: Date.now() });\n\n const lines: string[] = [`# Neighborhood: ${entryId}`, \"\"];\n\n if (result.blockingChain.length > 0) {\n lines.push(`## Blocking Chain (${result.blockingChain.length})`);\n lines.push(`_Entries this one blocks, downstream up to 3 hops:_`);\n for (const item of result.blockingChain) {\n const id = item.entryId ? `**${item.entryId}:** ` : \"\";\n lines.push(`- ${id}${item.name} [status: ${item.status ?? \"unknown\"}, hop ${item.hop}]`);\n }\n lines.push(\"\");\n }\n\n if (result.dependencyChain.length > 0) {\n lines.push(`## Dependency Chain (${result.dependencyChain.length})`);\n lines.push(`_Entries this one depends on or is blocked by:_`);\n for (const item of result.dependencyChain) {\n const id = item.entryId ? `**${item.entryId}:** ` : \"\";\n const unresolved = item.unresolvedFlag ? \" ⚠ unresolved\" : \"\";\n lines.push(`- ${id}${item.name} [${item.relationType ?? \"\"}${unresolved}]`);\n }\n lines.push(\"\");\n }\n\n if (result.parentContext) {\n const p = result.parentContext;\n const id = p.entryId ? `**${p.entryId}:** ` : \"\";\n lines.push(`## Parent Context`);\n lines.push(`- ${id}${p.name} — ${p.openCount} open, ${p.blockedCount} blocked sibling(s)`);\n lines.push(\"\");\n }\n\n if (result.relatedTensions.length > 0) {\n lines.push(`## Related Tensions (${result.relatedTensions.length})`);\n for (const item of result.relatedTensions) {\n const id = item.entryId ? `**${item.entryId}:** ` : \"\";\n lines.push(`- ${id}${item.name} [${item.relationType ?? \"\"}]`);\n }\n lines.push(\"\");\n }\n\n const signals: string[] = [];\n if (result.isolationSignal) signals.push(\"⚠ Isolated (< 2 relations)\");\n if (result.stalenessSignal?.isStale) {\n signals.push(`⚠ Stale (${result.stalenessSignal.daysSinceUpdate} days since update)`);\n }\n if (signals.length > 0) {\n lines.push(`## Signals`);\n for (const s of signals) lines.push(`- ${s}`);\n lines.push(\"\");\n }\n\n const isEmpty = result.blockingChain.length === 0 && result.dependencyChain.length === 0\n && !result.parentContext && result.relatedTensions.length === 0;\n\n if (isEmpty) {\n lines.push(`_No neighborhood data found. Entry may not exist or has no graph connections._`);\n lines.push(`Use \\`relations action=suggest\\` to discover potential connections.`);\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Neighborhood for ${entryId}: ${result.blockingChain.length} blocking, ${result.dependencyChain.length} dependencies, ${result.relatedTensions.length} tensions.`,\n result,\n isEmpty ? [{ tool: \"relations\", description: \"Discover connections\", parameters: { action: \"suggest\", entryId } }] : undefined,\n ),\n };\n}\n\nasync function handleBuild(server: McpServer, entryId: string, maxHops: number) {\n requireActiveSession();\n\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Assembling build context for ${entryId}...`,\n logger: \"product-brain\",\n });\n\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.assembleBuildContext\">>(\"chain.assembleBuildContext\", {\n entryId,\n maxHops,\n });\n\n const { entry, relatedByCollection, businessRules, glossaryTerms, chainRefs, contextTruncated } = result;\n\n const lines: string[] = [\n `# Build Context: ${entry.name}`,\n `**Entry:** ${entry.entryId ?? entry.name} [${entry.collectionSlug}]`,\n `**Status:** ${entry.status}`,\n \"\",\n ];\n\n if (Object.keys(entry.data).length > 0) {\n lines.push(\"## Entry Data\");\n for (const [key, val] of Object.entries(entry.data)) {\n const str = typeof val === \"string\" ? val : JSON.stringify(val);\n if (str.length > 200) {\n lines.push(`- **${key}:** ${str.slice(0, 200)}...`);\n } else {\n lines.push(`- **${key}:** ${str}`);\n }\n }\n lines.push(\"\");\n }\n\n if (businessRules.length > 0) {\n lines.push(\"## Business Rules to Honor\");\n for (const r of businessRules) {\n const id = r.entryId ?? r.name;\n lines.push(`- **${id}:** ${r.name}`);\n if (r.description) lines.push(` ${r.description.slice(0, 150)}${r.description.length > 150 ? \"...\" : \"\"}`);\n }\n lines.push(\"\");\n }\n\n if (glossaryTerms.length > 0) {\n lines.push(\"## Glossary Terms\");\n for (const t of glossaryTerms.slice(0, 15)) {\n const id = t.entryId ?? t.name;\n lines.push(`- **${id}:** ${t.name}`);\n if (t.definition) lines.push(` ${t.definition.slice(0, 120)}${t.definition.length > 120 ? \"...\" : \"\"}`);\n }\n if (glossaryTerms.length > 15) lines.push(` _...and ${glossaryTerms.length - 15} more_`);\n lines.push(\"\");\n }\n\n const relatedCount = Object.values(relatedByCollection).reduce((sum, arr) => sum + arr.length, 0);\n if (relatedCount > 0) {\n lines.push(\"## Related Entries\");\n for (const [coll, entries] of Object.entries(relatedByCollection)) {\n lines.push(`### ${coll} (${entries.length})`);\n for (const e of entries.slice(0, 5)) {\n lines.push(`- ${e.entryId ?? e.name}: ${e.name} [${e.relationType}]`);\n }\n if (entries.length > 5) lines.push(` _...and ${entries.length - 5} more_`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"## Chain Refs to Consult\");\n lines.push(chainRefs.slice(0, 15).map((r: string) => `- ${r}`).join(\"\\n\"));\n\n if (contextTruncated) {\n lines.push(\"\");\n lines.push(\"_Context was truncated (limits: 50 related, 20 rules, 30 glossary). Use entries action=get for full details._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: annotateStaleNames(lines.join(\"\\n\")) }],\n structuredContent: success(\n `Build context for ${entry.name}: ${relatedCount} related, ${businessRules.length} rules, ${glossaryTerms.length} terms.`,\n { entry, relatedByCollection, businessRulesCount: businessRules.length, glossaryTermsCount: glossaryTerms.length, contextTruncated },\n ),\n };\n}\n\n// ─── Cross-Cut (BET-239, Slice 3) ───────────────────────────────────────────\n\ninterface StructuralAggregationItem {\n entryId: string | null;\n name: string;\n relatedEntryId: string | null;\n relatedName: string;\n relatedCollectionSlug: string;\n}\n\ninterface StructuralAggregationResult {\n groups: Record<string, StructuralAggregationItem[]>;\n totalCount: number;\n truncated: boolean;\n}\n\nasync function handleCrossCut(relationType: string) {\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.structuralAggregation\">>(\"chain.structuralAggregation\", {\n relationType,\n });\n\n const groupKeys = Object.keys(result.groups);\n\n if (result.totalCount === 0) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Cross-Cut: ${relationType}\\n\\nNo relations of type '${relationType}' found in this workspace.`,\n }],\n structuredContent: success(\n `No '${relationType}' relations found.`,\n { groups: {}, totalCount: 0, truncated: false },\n ),\n };\n }\n\n const lines: string[] = [\n `# Cross-Cut: ${relationType}`,\n `_${result.totalCount} relations across ${groupKeys.length} source collection${groupKeys.length === 1 ? \"\" : \"s\"}${result.truncated ? \" (TRUNCATED — more relations exist)\" : \"\"}_`,\n \"\",\n ];\n\n for (const [sourceSlug, items] of Object.entries(result.groups)) {\n lines.push(`## ${sourceSlug} (${items.length})`);\n for (const item of items) {\n const fromId = item.entryId ? `**${item.entryId}:** ` : \"\";\n const toId = item.relatedEntryId ?? item.relatedName;\n lines.push(`- ${fromId}${item.name} → ${toId} [${item.relatedCollectionSlug}]`);\n }\n lines.push(\"\");\n }\n\n if (result.truncated) {\n lines.push(\"_Results truncated at 500 relations. Filter by collection or use a more specific relation type._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `${result.totalCount} '${relationType}' relations across ${groupKeys.length} collections.${result.truncated ? \" Truncated.\" : \"\"}`,\n result,\n ),\n };\n}\n\n// ─── Deep Chain Walk (BET-239, Slice 2) ────────────────────────────────────────\n\ninterface ChainWalkNode {\n entryId: string | null;\n name: string;\n collectionSlug: string | null;\n depth: number;\n parentEntryId: string | null;\n}\n\ninterface ChainWalkEdge {\n from: string;\n to: string;\n type: string;\n}\n\ninterface ChainWalkCycle {\n path: string[];\n}\n\ninterface ChainWalkResult {\n nodes: ChainWalkNode[];\n edges: ChainWalkEdge[];\n cycles: ChainWalkCycle[];\n totalNodes: number;\n truncated: boolean;\n snapshotWarning: boolean;\n error?: string;\n}\n\nasync function handleChainWalk(\n entryId: string,\n direction: \"outgoing\" | \"incoming\",\n maxHops: number,\n relationType?: string,\n) {\n // Clamp maxHops for chain action to 1-4\n const clampedHops = Math.max(1, Math.min(4, maxHops));\n\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.deepChainWalk\">>(\"chain.deepChainWalk\", {\n entryId,\n direction,\n maxHops: clampedHops,\n ...(relationType ? { relationType } : {}),\n });\n\n if (result.error) {\n return notFoundResult(entryId, result.error);\n }\n\n if (result.totalNodes <= 1) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Chain Walk: ${entryId}\\n\\n` +\n `_No ${direction} relations found${relationType ? ` of type '${relationType}'` : \"\"}._\\n\\n` +\n `Try \\`context action=chain entryId=\"${entryId}\" direction=\"${direction === \"outgoing\" ? \"incoming\" : \"outgoing\"}\"\\` ` +\n `or remove the relationType filter.`,\n }],\n structuredContent: success(\n `No ${direction} relations found for ${entryId}.`,\n result,\n ),\n };\n }\n\n const lines: string[] = [\n `# Chain Walk: ${entryId}`,\n `**Direction:** ${direction} | **Depth:** ${clampedHops}${relationType ? ` | **Type filter:** ${relationType}` : \"\"}`,\n `**Nodes:** ${result.totalNodes}${result.truncated ? \" (TRUNCATED at 100)\" : \"\"} | **Edges:** ${result.edges.length} | **Cycles:** ${result.cycles.length}`,\n \"\",\n ];\n\n // Render as tree grouped by depth\n const maxDepth = Math.max(...result.nodes.map((n) => n.depth));\n for (let d = 0; d <= maxDepth; d++) {\n const atDepth = result.nodes.filter((n) => n.depth === d);\n if (atDepth.length === 0) continue;\n\n const label = d === 0 ? \"Root\" : `Depth ${d}`;\n lines.push(`## ${label} (${atDepth.length})`);\n for (const node of atDepth) {\n const indent = \" \".repeat(d);\n const id = node.entryId ? `**${node.entryId}:** ` : \"\";\n const collection = node.collectionSlug ? ` [${node.collectionSlug}]` : \"\";\n const parent = node.parentEntryId ? ` (via ${node.parentEntryId})` : \"\";\n lines.push(`${indent}- ${id}${node.name}${collection}${parent}`);\n }\n lines.push(\"\");\n }\n\n // Show cycles if any\n if (result.cycles.length > 0) {\n lines.push(\"## Cycles Detected\");\n for (const cycle of result.cycles) {\n lines.push(`- ${cycle.path.join(\" -> \")}`);\n }\n lines.push(\"\");\n }\n\n // Snapshot warning\n if (result.snapshotWarning) {\n lines.push(\"_Note: This traversal spans multiple reads (Convex action). Data consistency is not guaranteed across hops (TEN-1029)._\");\n }\n\n if (result.truncated) {\n lines.push(\"_Results truncated at 100 nodes. Narrow with relationType filter or reduce maxHops._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Chain walk for ${entryId}: ${result.totalNodes} nodes, ${result.edges.length} edges, ${result.cycles.length} cycles (${direction}, depth ${clampedHops}).`,\n result,\n ),\n };\n}\n\n// ─── Changes (BET-239, FEAT-778) ────────────────────────────────────────────\n\ninterface ChangeDetectionResult {\n entries: Array<{ entryId: string | null; name: string; collectionSlug: string; updatedAt: number }>;\n relations: Array<{ fromEntryId: string | null; toEntryId: string | null; type: string; createdAt: number }>;\n counts: Record<string, number>;\n truncated: boolean;\n}\n\nasync function handleChanges(since: string) {\n const sinceMs = Date.parse(since);\n if (isNaN(sinceMs)) {\n return validationResult(`Invalid 'since' timestamp: '${since}'. Use ISO 8601 format (e.g. '2026-03-24T00:00:00Z').`);\n }\n\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.changeDetection\">>(\"chain.changeDetection\", { since: sinceMs });\n\n const totalEntries = result.entries.length;\n const totalRelations = result.relations.length;\n\n if (totalEntries === 0 && totalRelations === 0) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Changes since ${since}\\n\\nNo entries modified or relations created since this timestamp.`,\n }],\n structuredContent: success(\n `No changes detected since ${since}.`,\n { entries: [], relations: [], counts: {}, truncated: false },\n ),\n };\n }\n\n const lines: string[] = [\n `# Changes since ${since}`,\n `_${totalEntries} entries modified, ${totalRelations} relations created${result.truncated ? \" (TRUNCATED — more changes exist)\" : \"\"}_`,\n \"\",\n ];\n\n // Entries grouped by collection\n if (totalEntries > 0) {\n lines.push(\"## Modified Entries\");\n const sortedCounts = Object.entries(result.counts).sort((a, b) => b[1] - a[1]);\n for (const [slug, count] of sortedCounts) {\n lines.push(`### ${slug} (${count})`);\n const slugEntries = result.entries.filter((e) => e.collectionSlug === slug);\n for (const e of slugEntries) {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const ago = formatTimeAgo(e.updatedAt);\n lines.push(`- ${id}${e.name} _(${ago})_`);\n }\n lines.push(\"\");\n }\n }\n\n // Relations\n if (totalRelations > 0) {\n lines.push(\"## New Relations\");\n for (const r of result.relations) {\n const from = r.fromEntryId ?? \"?\";\n const to = r.toEntryId ?? \"?\";\n const ago = formatTimeAgo(r.createdAt);\n lines.push(`- ${from} **${r.type}** ${to} _(${ago})_`);\n }\n lines.push(\"\");\n }\n\n if (result.truncated) {\n lines.push(\"_Results truncated at 200 entries. Use a more recent timestamp to narrow the window._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `${totalEntries} entries modified, ${totalRelations} relations created since ${since}.${result.truncated ? \" Truncated.\" : \"\"}`,\n result,\n ),\n };\n}\n\n// ─── Incremental (BET-239 E4) ────────────────────────────────────────────\n\ninterface IncrementalResult {\n newEntries: Array<{ entryId: string | null; name: string; collectionSlug: string; updatedAt: number }>;\n counts: Record<string, number>;\n relations: Array<{ fromEntryId: string | null; toEntryId: string | null; type: string; createdAt: number }>;\n truncated: boolean;\n previousRunTimestamp: number | null;\n isFirstRun: boolean;\n}\n\nasync function handleIncremental(skill: string) {\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.incrementalChanges\">>(\"chain.incrementalChanges\", { skill });\n\n const totalEntries = result.newEntries.length;\n\n // Record the brief run so the next call sees an updated \"since last brief\" timestamp.\n // Fire-and-forget: recording failure should not block the response.\n const surfacedIds = result.newEntries\n .map((e) => e.entryId)\n .filter((id): id is string => id !== null);\n kernelMutation<GatewayRouteReturnByName<\"chain.recordBriefRun\">>(\"chain.recordBriefRun\", {\n skill,\n entriesSurfaced: surfacedIds,\n timestamp: Date.now(),\n }).catch(() => {\n // Best-effort — logging omitted to avoid noise. The next brief run\n // will simply re-surface the same entries.\n });\n\n if (totalEntries === 0 && !result.isFirstRun) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Incremental Brief — ${skill}\\n\\nNo new entries since last brief run (${formatTimeAgo(result.previousRunTimestamp!)}).`,\n }],\n structuredContent: success(\n `No new entries for skill '${skill}' since last brief.`,\n result,\n ),\n };\n }\n\n const lines: string[] = [\n `# Incremental Brief — ${skill}`,\n ];\n\n if (result.isFirstRun) {\n lines.push(\"_First run — showing all recent entries._\");\n } else {\n lines.push(`_Delta since last brief (${formatTimeAgo(result.previousRunTimestamp!)})_`);\n }\n\n lines.push(`_${totalEntries} new entries${result.truncated ? \" (TRUNCATED)\" : \"\"}_`);\n lines.push(\"\");\n\n if (totalEntries > 0) {\n lines.push(\"## New Entries\");\n\n // Group by collection\n const byCollection: Record<string, typeof result.newEntries> = {};\n for (const e of result.newEntries) {\n const slug = e.collectionSlug;\n if (!byCollection[slug]) byCollection[slug] = [];\n byCollection[slug].push(e);\n }\n\n const sortedSlugs = Object.entries(byCollection)\n .sort((a, b) => b[1].length - a[1].length)\n .map(([slug]) => slug);\n\n for (const slug of sortedSlugs) {\n const entries = byCollection[slug];\n lines.push(`### ${slug} (${entries.length})`);\n for (const e of entries) {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const ago = formatTimeAgo(e.updatedAt);\n lines.push(`- ${id}${e.name} _(${ago})_`);\n }\n lines.push(\"\");\n }\n }\n\n if (result.truncated) {\n lines.push(\"_Results truncated at 200 entries. Run more frequently to stay within the cap._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `${totalEntries} new entries for skill '${skill}'${result.isFirstRun ? \" (first run)\" : \"\"}.${result.truncated ? \" Truncated.\" : \"\"}`,\n result,\n ),\n };\n}\n\n// ─── Compound Brief (BET-239 E6) ────────────────────────────────────────────\n\nasync function handleBrief(briefType: \"steering\" | \"confidence\" | \"delta\", sinceMs?: number) {\n const args: Record<string, unknown> = { type: briefType };\n if (sinceMs !== undefined) args.since = sinceMs;\n\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.compoundQuery\">>(\"chain.compoundQuery\", args);\n\n if (briefType === \"steering\") {\n return formatSteeringBrief(result);\n }\n\n if (briefType === \"confidence\") {\n return formatConfidencePass(result);\n }\n\n if (briefType === \"delta\") {\n return formatDeltaSync(result);\n }\n\n return validationResult(`Unknown briefType: ${briefType}`);\n}\n\nfunction formatSteeringBrief(result: any) {\n const changes = result.changes;\n const delta = result.delta;\n const readiness = result.readiness;\n\n const lines: string[] = [\n \"# Steering Brief\",\n \"\",\n `## Changes (last 7 days)`,\n `_${changes.entries.length} entries modified, ${changes.relations.length} relations created${changes.truncated ? \" (TRUNCATED)\" : \"\"}_`,\n \"\",\n ];\n\n // Entry counts by collection\n if (Object.keys(changes.counts).length > 0) {\n const sortedCounts = Object.entries(changes.counts as Record<string, number>).sort((a, b) => b[1] - a[1]);\n for (const [slug, count] of sortedCounts) {\n lines.push(`- **${slug}:** ${count}`);\n }\n lines.push(\"\");\n }\n\n // Structural summary\n lines.push(\"## Structure\");\n for (const [relType, agg] of Object.entries(result.structure as Record<string, any>)) {\n const groupCount = Object.keys(agg.groups).length;\n lines.push(`- **${relType}:** ${agg.totalCount} relations across ${groupCount} collection groups${agg.truncated ? \" (TRUNCATED)\" : \"\"}`);\n }\n lines.push(\"\");\n\n // Delta\n lines.push(\"## Incremental Delta (steering skill)\");\n if (delta.isFirstRun) {\n lines.push(\"_First run — all recent entries included._\");\n }\n lines.push(`${delta.newEntries.length} new entries since last steering brief${delta.truncated ? \" (TRUNCATED)\" : \"\"}`);\n lines.push(\"\");\n\n // Readiness\n lines.push(\"## Workspace Readiness\");\n lines.push(`Score: **${readiness.score}%** (${readiness.passedChecks}/${readiness.totalChecks} checks passed)`);\n if (readiness.gaps.length > 0) {\n lines.push(\"\");\n lines.push(\"**Gaps:**\");\n for (const gap of readiness.gaps.slice(0, 5)) {\n lines.push(`- ${gap.label}: ${gap.current}/${gap.required}${gap.guidance ? ` — ${gap.guidance}` : \"\"}`);\n }\n }\n lines.push(\"\");\n\n // BET-240 S6: trust-awareness note — scoring kernel applies implicit trust weighting\n lines.push(\"## Trust\");\n lines.push(\"_Scoring kernel applies trust weighting: human=1.0, agent+verified=0.7, agent+unverified=0.56, external+unverified=0.64. Scores in context/gather reflect this. Use `orient -b` for workspace trust metrics._\");\n lines.push(\"\");\n\n if (result.snapshotWarning) {\n lines.push(\"_Note: Compound query spans multiple reads. Data consistency is not guaranteed across components (TEN-1029)._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Steering brief: ${changes.entries.length} changes, ${delta.newEntries.length} new entries, ${readiness.score}% readiness.`,\n { ...result, trustFilterActive: true },\n ),\n };\n}\n\nfunction formatConfidencePass(result: any) {\n const changes = result.changes;\n\n const lines: string[] = [\n \"# Confidence Pass\",\n \"\",\n `## Changes (last 7 days)`,\n `_${changes.entries.length} entries modified${changes.truncated ? \" (TRUNCATED)\" : \"\"}_`,\n \"\",\n ];\n\n // Active bets\n lines.push(`## Active Work Packages (${result.workPackageCount})`);\n if (result.activeBets.length > 0) {\n for (const bet of result.activeBets) {\n const id = bet.entryId ? `**${bet.entryId}:** ` : \"\";\n lines.push(`- ${id}${bet.name} [${bet.status}]`);\n }\n } else {\n lines.push(\"_No active work packages._\");\n }\n lines.push(\"\");\n\n // Active tensions\n lines.push(`## Active Tensions (${result.tensionCount})`);\n if (result.activeTensions.length > 0) {\n for (const tension of result.activeTensions) {\n const id = tension.entryId ? `**${tension.entryId}:** ` : \"\";\n lines.push(`- ${id}${tension.name}`);\n }\n } else {\n lines.push(\"_No active tensions._\");\n }\n lines.push(\"\");\n\n // BET-240 S6: trust-awareness note for confidence pass\n lines.push(\"## Trust\");\n lines.push(\"_Trust-weighted scoring active: agent-origin and unverified entries receive lower confidence scores (human=1.0, agent+verified=0.7, agent+unverified=0.56). Use `entries action=get` to inspect individual entry origin/verification. Use `orient -b` for workspace trust metrics._\");\n lines.push(\"\");\n\n if (result.snapshotWarning) {\n lines.push(\"_Note: Compound query spans multiple reads. Data consistency is not guaranteed across components (TEN-1029)._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Confidence pass: ${changes.entries.length} changes, ${result.workPackageCount} active work packages, ${result.tensionCount} active tensions.`,\n { ...result, trustFilterActive: true },\n ),\n };\n}\n\nfunction formatDeltaSync(result: any) {\n const changes = result.changes;\n const sinceDate = new Date(result.since).toISOString();\n\n const lines: string[] = [\n `# Delta Sync since ${sinceDate}`,\n `_${changes.entries.length} entries modified, ${changes.relations.length} relations created${changes.truncated ? \" (TRUNCATED)\" : \"\"}_`,\n \"\",\n ];\n\n if (changes.entries.length > 0) {\n lines.push(\"## Modified Entries\");\n const sortedCounts = Object.entries(changes.counts as Record<string, number>).sort((a, b) => b[1] - a[1]);\n for (const [slug, count] of sortedCounts) {\n lines.push(`### ${slug} (${count})`);\n const slugEntries = changes.entries.filter((e: any) => e.collectionSlug === slug);\n for (const e of slugEntries) {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const ago = formatTimeAgo(e.updatedAt);\n lines.push(`- ${id}${e.name} _(${ago})_`);\n }\n lines.push(\"\");\n }\n }\n\n if (changes.relations.length > 0) {\n lines.push(\"## New Relations\");\n for (const r of changes.relations) {\n const from = r.fromEntryId ?? \"?\";\n const to = r.toEntryId ?? \"?\";\n const ago = formatTimeAgo(r.createdAt);\n lines.push(`- ${from} **${r.type}** ${to} _(${ago})_`);\n }\n lines.push(\"\");\n }\n\n if (result.snapshotWarning) {\n lines.push(\"_Note: Compound query spans multiple reads. Data consistency is not guaranteed across components (TEN-1029)._\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Delta sync since ${sinceDate}: ${changes.entries.length} entries, ${changes.relations.length} relations.${changes.truncated ? \" Truncated.\" : \"\"}`,\n result,\n ),\n };\n}\n\n/** Format a timestamp as a human-readable relative time. */\nfunction formatTimeAgo(ms: number): string {\n const diff = Date.now() - ms;\n if (diff < 60_000) return \"just now\";\n if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m ago`;\n if (diff < 86_400_000) return `${Math.floor(diff / 3_600_000)}h ago`;\n return `${Math.floor(diff / 86_400_000)}d ago`;\n}\n","/**\n * Documents tool — MCP read surface for verified brief snapshots.\n *\n * WP-371 S4 (Seam Slice — agent surface side). Compound tool with action-enum\n * dispatch (BR-72 / STD-86). Currently exposes a single read action;\n * additional read actions (e.g. list-recent-verified, get-by-runId) can join\n * the same `documents` surface as the kernel grows.\n *\n * Read-only. v1.1 explicitly excludes any mutation from MCP — agents observe\n * the verification audit trail; they do not write to it.\n *\n * Workspace context is enforced by the HTTP gateway from the API key (BR-18).\n * The MCP tool never accepts or forwards a workspaceId — `kernelQuery`\n * injects it server-side.\n *\n * Chain: WP-371, BR-72 (compound action enum), STD-86 (compound tool standard),\n * BR-18 (gateway enforces workspace from credential), BR-150 (no slug branching).\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery } from \"../client.js\";\nimport { success } from \"../envelope.js\";\n\n// ─── Schema ──────────────────────────────────────────────────────────────────\n\nconst DOCUMENTS_ACTIONS = [\"get-last-verified-brief\"] as const;\n\nexport const documentsSchema = z.object({\n action: z.enum(DOCUMENTS_ACTIONS).describe(\n \"'get-last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair. Returns the verified summary so agents can build delta narratives ('since you last verified, X workstreams advanced').\",\n ),\n templateId: z.string().max(200).describe(\n \"Brief template identifier — currently 'steering-brief' is the only registered template.\",\n ),\n scopeKey: z.string().max(200).describe(\n \"Canonical scope key. Use 'workspace:<workspaceId>' for the full workspace brief, or 'initiative:<INI-ID>' for an initiative-scoped brief. The same formula is applied at write time (chainwork/docKernel/scopeKey.ts), so passing the wrong shape returns exists:false.\",\n ),\n});\n\n// ─── Output types (mirrors getLastVerifiedBrief return shape) ───────────────\n\ninterface VerifiedWorkstreamSnapshot {\n entryId: string;\n name: string;\n status: string;\n whatChanged: string;\n updatedAtAtVerify: number;\n}\n\ninterface VerifiedSummary {\n verifiedAtGlance: string;\n verifiedWorkstreams: VerifiedWorkstreamSnapshot[];\n citedEntryIds: string[];\n chainSyncedAt: number;\n verifiedAt: number;\n verifiedBy: string;\n}\n\n/**\n * Discriminated read result. Matches the chainwork query return shape exactly.\n * Agents key on `exists` first, then on `summary` presence to decide whether\n * a delta narrative is possible.\n */\ntype LastVerifiedBriefResult =\n | { exists: false }\n | {\n exists: true;\n summary: VerifiedSummary | undefined;\n verifiedAt: number;\n };\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `documents` tool retired\n// here. handleGetLastVerifiedBrief stays live — context.ts (the `context`\n// compound, action=last-verified-brief) is its only remaining caller.\n\n// ─── Handler ────────────────────────────────────────────────────────────────\n\nexport async function handleGetLastVerifiedBrief(\n templateId: string,\n scopeKey: string,\n) {\n // kernelQuery injects workspaceId from the API-key context (BR-18).\n const result = await kernelQuery<GatewayRouteReturnByName<\"chainwork.getLastVerifiedBrief\">>(\n \"chainwork.getLastVerifiedBrief\",\n { templateId, scopeKey },\n );\n\n if (!result.exists) {\n const text =\n `No verified brief found for template '${templateId}', scope '${scopeKey}'.\\n\\n` +\n `This is normal for a never-verified initiative or workspace. ` +\n `If you expected a row here, check that the scope key matches the format ` +\n `produced at write time: 'workspace:<workspaceId>' or 'initiative:<INI-ID>'.`;\n return {\n content: [{ type: \"text\" as const, text }],\n structuredContent: success(\n `No verified brief found for ${templateId} / ${scopeKey}.`,\n { exists: false },\n ),\n };\n }\n\n const verifiedAtIso = new Date(result.verifiedAt).toISOString();\n\n if (result.summary === undefined) {\n // Legacy backfilled row — no snapshot data was captured at write time.\n const text =\n `Verified brief found for template '${templateId}', scope '${scopeKey}', ` +\n `verified at ${verifiedAtIso}.\\n\\n` +\n `This row pre-dates snapshot capture (legacy backfill), so no summary is ` +\n `available. The verification timestamp itself is still authoritative — ` +\n `you can reason about staleness, just not delta narratives.`;\n return {\n content: [{ type: \"text\" as const, text }],\n structuredContent: success(\n `Legacy verified brief at ${verifiedAtIso} (no summary).`,\n { exists: true, summary: undefined, verifiedAt: result.verifiedAt },\n ),\n };\n }\n\n // Full S4 row with snapshot.\n const summary = result.summary;\n const lines: string[] = [\n `## Last verified brief — ${templateId} / ${scopeKey}`,\n `Verified at: ${verifiedAtIso} by ${summary.verifiedBy}`,\n `Chain synced at: ${new Date(summary.chainSyncedAt).toISOString()}`,\n \"\",\n `### At a glance (verbatim)`,\n summary.verifiedAtGlance || \"(empty)\",\n \"\",\n `### Workstreams at verification (${summary.verifiedWorkstreams.length})`,\n ];\n for (const ws of summary.verifiedWorkstreams) {\n lines.push(\n `- **${ws.entryId}** ${ws.name} — status: ${ws.status}` +\n (ws.whatChanged ? ` — ${ws.whatChanged}` : \"\"),\n );\n }\n if (summary.citedEntryIds.length > 0) {\n lines.push(\"\");\n lines.push(`### Cited entries (${summary.citedEntryIds.length})`);\n lines.push(summary.citedEntryIds.join(\", \"));\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Verified brief found at ${verifiedAtIso} with ${summary.verifiedWorkstreams.length} workstream snapshot(s).`,\n {\n exists: true,\n summary,\n verifiedAt: result.verifiedAt,\n },\n ),\n };\n}\n","/**\n * Collections compound tool — list, create, update.\n * Consolidates list-collections, create-collection, update-collection into one tool.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, requireWriteAccess, getAgentSessionId, runWithToolContext } from \"../client.js\";\nimport { invalidateCollectionCacheForScope } from \"../lib/collectionCache.js\";\nimport { invalidateProfileCacheForScope, invalidateHubCacheForScope } from \"./smart-capture.js\";\nimport { thinWrapper, success, failureResult, validationResult, successResult, parseOrFail, type ToolResult } from \"../envelope.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { handleLabelsList, handleLabelsCreate, handleLabelsUpdate, handleLabelsDelete, handleLabelsApply, handleLabelsRemove } from \"./labels.js\";\n\ninterface CollectionField {\n key: string;\n type: string;\n required?: boolean;\n searchable?: boolean;\n displayHint?: 'hero' | 'badge' | 'meta' | 'section' | 'hidden' | 'inline-meta';\n zone?: 'header' | 'body' | 'meta';\n colorMap?: Record<string, string>;\n accentSource?: boolean;\n iconMap?: Record<string, string>;\n /** BET-196: Content constraints — maximum character length for field values. */\n maxLength?: number;\n /** BET-196: Content constraints — minimum character length for field values. */\n minLength?: number;\n}\n\ninterface CollectionRecord {\n slug: string;\n name: string;\n description?: string;\n purpose?: string;\n navGroup?: string;\n icon?: string;\n fields: CollectionField[];\n}\n\n// WP-484 S2 (§3, Q4): `collections` absorbs `labels` → label-list/label-create/\n// label-update/label-delete/label-apply/label-remove — 12 actions, AT the §3\n// ceiling, accepted under the two-layer shape + backpressure + served-schema\n// assertion (founder-delegated ruling Q4). Legacy `labels` tool stays\n// registered alongside (§7 \"alongside\" mechanic) — both call the SAME\n// handleLabels* functions, one business-logic path per action.\nconst COLLECTIONS_ACTIONS = [\n \"list\", \"create\", \"update\", \"describe\", \"audit\", \"export\",\n \"label-list\", \"label-create\", \"label-update\", \"label-delete\", \"label-apply\", \"label-remove\",\n] as const;\ntype CollectionsAction = (typeof COLLECTIONS_ACTIONS)[number];\n\nconst qualityCriterionSchema = z.object({\n field: z.string().max(200).describe(\"Entry data field key this criterion applies to, e.g. 'description', 'owner'\"),\n // WP-480 S1: `max_length` — must mirror the Convex rule union, or the tool rejects a\n // valid criterion before the request ever reaches the server.\n rule: z.enum(['required', 'min_length', 'max_length', 'pattern'])\n .describe(\"'required': field must be non-empty (blocks accept). 'min_length': minimum string length (warns). 'max_length': maximum string length (warns). 'pattern': regex match (warns).\"),\n value: z.string().max(500).optional()\n .describe(\"For min_length/max_length: the length bound as a string integer. For pattern: the regex string. Unused for 'required'.\"),\n});\n\nconst fieldSchema = z.object({\n key: z.string().max(200).describe(\"Field key, e.g. 'description', 'severity', 'status'\"),\n label: z.string().max(200).describe(\"Display label, e.g. 'Description', 'Severity'\"),\n type: z.string().max(50).describe(\"Field type: 'string', 'select', 'array', 'number', 'boolean'\"),\n required: z.boolean().optional().describe(\"Whether this field is required\"),\n options: z.array(z.string().max(200)).max(200).optional().describe(\"Options for 'select' type fields\"),\n searchable: z.boolean().optional().describe(\"Whether this field is included in full-text search\"),\n displayHint: z.enum(['hero', 'badge', 'meta', 'section', 'hidden', 'inline-meta']).optional()\n .describe(\"V2 rendering hint: how the field should be displayed in Cortex\"),\n zone: z.enum(['header', 'body', 'meta']).optional()\n .describe(\"V2 layout zone: where the field appears in the entry view\"),\n colorMap: z.record(z.string().max(50)).optional()\n .describe(\"V2 value-to-semantic-color mapping, e.g. { critical: 'danger', low: 'success' }\"),\n // ENT-61\n accentSource: z.boolean().optional()\n .describe(\"When true, this field's colorMap value drives the card-level accent styling\"),\n // ENT-61\n iconMap: z.record(z.string(), z.string().max(50)).optional()\n .describe(\"Maps field values to icons (emoji/symbol), prepended to badge text\"),\n helpText: z.string().max(2000).optional()\n .describe(\"Help text shown in editors and describe output\"),\n optionDescriptions: z.record(z.string().max(500)).optional()\n .describe(\"Per-option guidance for select fields\"),\n // BET-136\n semanticRole: z.enum(['problem', 'appetite', 'elements', 'architecture', 'done_when', 'risks', 'exclusions']).optional()\n .describe(\"Semantic role for schema-driven consumers — enables field-key-independent validation and rendering\"),\n // BET-196\n maxLength: z.number().optional()\n .describe(\"Maximum character length for field values. Three-tier resolution: explicit > displayHint > type fallback.\"),\n // BET-196\n minLength: z.number().optional()\n .describe(\"Minimum character length for field values. Only explicit — no defaults.\"),\n});\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const collectionsSchema = z.object({\n action: z.enum(COLLECTIONS_ACTIONS).describe(\n \"'list': browse all collections. 'create': create a new collection. 'update': update an existing collection. 'describe': full documentation for one collection — fields, option guides, usage guidance, examples. 'audit': health report for all collections — missing classification, icon, displayHint coverage, and field schema gaps. 'export': full system_collection_definitions export with classification metadata (thinkingLayer, classificationPriority, classificationCheck, classificationSignals, governanceRole, governanceFunction, timelineRole, canBeElementOf, descriptionFieldKey). Admin only. \" +\n \"'label-list'/'label-create'/'label-update'/'label-delete'/'label-apply'/'label-remove': manage workspace labels (absorbs the `labels` tool).\",\n ),\n slug: z.string().max(200).optional().describe(\"URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'. For label-*: label slug.\"),\n name: z.string().max(500).optional().describe(\"Display name for create, or new name for update. For label-create: label display name.\"),\n description: z.string().max(20000).optional().describe(\"What this collection is for. For label-create/label-update: what the label means.\"),\n purpose: z.string().max(2000).optional().describe(\"Why this collection exists — strategic reason\"),\n icon: z.string().max(50).optional().describe(\"Emoji icon for the collection\"),\n navGroup: z.enum([\"daily\", \"strategic\", \"governance\", \"reference\", \"collections\"]).optional()\n .describe(\"Sidebar placement: 'daily', 'strategic', 'governance', 'reference', 'collections'\"),\n fields: z.array(fieldSchema).max(200).optional()\n .describe(\"Field definitions for create, or replacement schema for update (replaces all fields)\"),\n axis: z.enum([\"work\", \"none\", \"pending\"]).optional().describe(\"REQUIRED for create: 'work' (needs stageLabelMap + validWorkflowStatuses), 'none', or 'pending'. For update: only settable on a non-system-stratum (custom) collection — the repair path for a legacy collection that predates the axis contract.\"),\n stageLabelMap: z.record(z.string(), z.enum([\"open\", \"in_progress\", \"done\", \"stopped\", \"tag\"])).optional().describe(\"Required when axis is 'work': maps each valid workflowStatus to a canonical stage.\"),\n // ENT-62\n defaultCanonicalKey: z.string().max(200).optional()\n .describe(\"The canonical_key entries in this collection default to (e.g. 'decision', 'insight'). Consumers read from collection doc; code map is fallback.\"),\n // ENT-67\n defaultWorkflowStatus: z.string().max(200).optional()\n .describe(\"Default workflowStatus for new entries. Must be in validWorkflowStatuses when set (e.g. 'hypothesis' for insights).\"),\n // ENT-65\n validWorkflowStatuses: z.array(z.string().max(200)).max(50).optional()\n .describe(\"The allowed workflowStatus values for entries in this collection. New entries are validated against this list. Empty array means no constraint.\"),\n // ENT-65, FEAT-200\n classificationCheck: z.string().max(500).optional()\n .describe(\"LLM decision-tree check for this collection (3–500 chars). Guides the classifier in routing entries here.\"),\n // ENT-65, FEAT-200\n classificationPriority: z.number().optional()\n .describe(\"Classifier priority (1–9, lower = higher priority). Used with classificationCheck to order the decision tree.\"),\n // FEAT-301 Slice 2: quality gate criteria and usage guidance.\n // FEAT-257\n qualityCriteria: z.array(qualityCriterionSchema).max(50).optional()\n .describe(\"Per-collection accept gate rules. 'required' rule hard-blocks accepts on empty fields; 'min_length'/'pattern' rules warn. Pass an empty array to clear all criteria.\"),\n usageGuidance: z.string().max(20000).optional()\n .describe(\"Plain-text guidance shown to agents and users: when to use this collection, when not to, and what makes a good entry.\"),\n // For label-*\n color: z.string().max(50).optional().describe(\"For label-create/label-update: hex color, e.g. '#ef4444'.\"),\n parentSlug: z.string().max(200).optional().describe(\"For label-create: parent group slug for label hierarchy.\"),\n isGroup: z.boolean().optional().describe(\"For label-create/label-update: true if this is a group container, not a taggable label.\"),\n order: z.number().optional().describe(\"For label-create/label-update: sort order within its group.\"),\n entryId: z.string().max(200).optional().describe(\"For label-apply/label-remove: entry ID.\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion.\nconst collectionsListVariant = z.object({ action: z.literal(\"list\") });\nconst collectionsDescribeVariant = z.object({ action: z.literal(\"describe\"), slug: z.string().max(200) });\nconst collectionsCreateVariant = z.object({\n action: z.literal(\"create\"),\n slug: z.string().max(200),\n name: z.string().max(500),\n description: z.string().max(20000).optional(),\n purpose: z.string().max(2000).optional(),\n icon: z.string().max(50).optional(),\n navGroup: z.enum([\"daily\", \"strategic\", \"governance\", \"reference\", \"collections\"]).optional(),\n fields: z.array(fieldSchema).min(1),\n axis: z.enum([\"work\", \"none\", \"pending\"]), // required, mirrors the Convex door's axisValidator (PRRT_kwDORS4ils6ZiYjo)\n stageLabelMap: z.record(z.string(), z.enum([\"open\", \"in_progress\", \"done\", \"stopped\", \"tag\"])).optional(),\n defaultCanonicalKey: z.string().max(200).optional(),\n defaultWorkflowStatus: z.string().max(200).optional(),\n validWorkflowStatuses: z.array(z.string().max(200)).optional(),\n classificationCheck: z.string().max(500).optional(),\n classificationPriority: z.number().optional(),\n});\nconst collectionsUpdateVariant = z.object({\n action: z.literal(\"update\"),\n slug: z.string().max(200),\n name: z.string().max(500).optional(),\n description: z.string().max(20000).optional(),\n purpose: z.string().max(2000).optional(),\n icon: z.string().max(50).optional(),\n navGroup: z.enum([\"daily\", \"strategic\", \"governance\", \"reference\", \"collections\"]).optional(),\n fields: z.array(fieldSchema).optional(), axis: z.enum([\"work\", \"none\", \"pending\"]).optional(), stageLabelMap: z.record(z.string(), z.enum([\"open\", \"in_progress\", \"done\", \"stopped\", \"tag\"])).optional(), // WP-640 SWEEP (P1): axis/stageLabelMap repair legacy custom collections — see collections.ts's updateCollection.\n defaultCanonicalKey: z.string().max(200).optional(),\n defaultWorkflowStatus: z.string().max(200).optional(),\n validWorkflowStatuses: z.array(z.string().max(200)).optional(),\n classificationCheck: z.string().max(500).optional(),\n classificationPriority: z.number().optional(),\n qualityCriteria: z.array(qualityCriterionSchema).optional(),\n usageGuidance: z.string().max(20000).optional(),\n});\nconst collectionsAuditVariant = z.object({ action: z.literal(\"audit\") });\nconst collectionsExportVariant = z.object({ action: z.literal(\"export\") });\nconst collectionsLabelListVariant = z.object({ action: z.literal(\"label-list\") });\nconst collectionsLabelCreateVariant = z.object({\n action: z.literal(\"label-create\"),\n slug: z.string().max(200),\n name: z.string().max(500),\n color: z.string().max(50).optional(),\n description: z.string().max(2000).optional(),\n parentSlug: z.string().max(200).optional(),\n isGroup: z.boolean().optional(),\n order: z.number().optional(),\n});\nconst collectionsLabelUpdateVariant = z.object({\n action: z.literal(\"label-update\"),\n slug: z.string().max(200),\n name: z.string().max(500).optional(),\n color: z.string().max(50).optional(),\n description: z.string().max(2000).optional(),\n isGroup: z.boolean().optional(),\n order: z.number().optional(),\n});\nconst collectionsLabelDeleteVariant = z.object({ action: z.literal(\"label-delete\"), slug: z.string().max(200) });\nconst collectionsLabelApplyVariant = z.object({ action: z.literal(\"label-apply\"), slug: z.string().max(200), entryId: z.string().max(200) });\nconst collectionsLabelRemoveVariant = z.object({ action: z.literal(\"label-remove\"), slug: z.string().max(200), entryId: z.string().max(200) });\n\nexport const collectionsActionUnion = z.discriminatedUnion(\"action\", [\n collectionsListVariant,\n collectionsDescribeVariant,\n collectionsCreateVariant,\n collectionsUpdateVariant,\n collectionsAuditVariant,\n collectionsExportVariant,\n collectionsLabelListVariant,\n collectionsLabelCreateVariant,\n collectionsLabelUpdateVariant,\n collectionsLabelDeleteVariant,\n collectionsLabelApplyVariant,\n collectionsLabelRemoveVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const COLLECTIONS_ACTION_SPECS: Record<CollectionsAction, ActionParamSpec> = {\n list: { params: [], description: \"Browse all collections; no params.\" },\n describe: { params: [\"slug\"], description: \"slug is required.\" },\n create: { params: [\"slug\", \"name\", \"description\", \"purpose\", \"icon\", \"navGroup\", \"fields\", \"axis\", \"stageLabelMap\", \"defaultCanonicalKey\", \"defaultWorkflowStatus\", \"validWorkflowStatuses\", \"classificationCheck\", \"classificationPriority\"], description: \"slug, name, fields, and axis are required. axis:'work' also requires stageLabelMap + validWorkflowStatuses.\" },\n update: { params: [\"slug\", \"name\", \"description\", \"purpose\", \"icon\", \"navGroup\", \"fields\", \"axis\", \"stageLabelMap\", \"defaultCanonicalKey\", \"defaultWorkflowStatus\", \"validWorkflowStatuses\", \"classificationCheck\", \"classificationPriority\", \"qualityCriteria\", \"usageGuidance\"], description: \"slug is required; at least one other field must be provided. axis/stageLabelMap are only settable on a non-system-stratum collection (the repair path for a legacy custom collection missing its axis declaration).\" },\n audit: { params: [], description: \"Health report for all collections; no params.\" },\n export: { params: [], description: \"Full system_collection_definitions export; no params. Admin only.\" },\n \"label-list\": { params: [], description: \"List all labels; no params.\" },\n \"label-create\": { params: [\"slug\", \"name\", \"color\", \"description\", \"parentSlug\", \"isGroup\", \"order\"], description: \"slug and name are required.\" },\n \"label-update\": { params: [\"slug\", \"name\", \"color\", \"description\", \"isGroup\", \"order\"], description: \"slug is required.\" },\n \"label-delete\": { params: [\"slug\"], description: \"slug is required.\" },\n \"label-apply\": { params: [\"slug\", \"entryId\"], description: \"slug and entryId are required.\" },\n \"label-remove\": { params: [\"slug\", \"entryId\"], description: \"slug and entryId are required.\" },\n};\n\nexport function registerCollectionsTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const collectionsHandlers: Record<CollectionsAction, (data: any) => Promise<ToolResult>> = {\n list: () => handleList(),\n describe: (data) => handleDescribe(data.slug),\n create: (data) => handleCreate(\n data.slug, data.name, data.description, data.purpose, data.icon, data.navGroup ?? \"collections\", data.fields,\n { axis: data.axis, stageLabelMap: data.stageLabelMap, defaultCanonicalKey: data.defaultCanonicalKey, defaultWorkflowStatus: data.defaultWorkflowStatus, validWorkflowStatuses: data.validWorkflowStatuses, classificationCheck: data.classificationCheck, classificationPriority: data.classificationPriority },\n ),\n update: (data) => {\n const hasChanges = data.name || data.description || data.purpose || data.icon || data.navGroup || data.fields\n || data.axis !== undefined || data.stageLabelMap !== undefined || data.defaultCanonicalKey !== undefined || data.defaultWorkflowStatus !== undefined || data.validWorkflowStatuses !== undefined\n || data.classificationCheck !== undefined || data.classificationPriority !== undefined || data.qualityCriteria !== undefined || data.usageGuidance !== undefined;\n if (!hasChanges) {\n return Promise.resolve(validationResult(\"Provide at least one field to update (name, description, purpose, icon, navGroup, fields, axis, stageLabelMap, defaultCanonicalKey, defaultWorkflowStatus, validWorkflowStatuses, classificationCheck, classificationPriority, qualityCriteria, or usageGuidance).\"));\n }\n return handleUpdate(\n data.slug, data.name, data.description, data.purpose, data.icon, data.navGroup, data.fields,\n { axis: data.axis, stageLabelMap: data.stageLabelMap, defaultCanonicalKey: data.defaultCanonicalKey, defaultWorkflowStatus: data.defaultWorkflowStatus, validWorkflowStatuses: data.validWorkflowStatuses, classificationCheck: data.classificationCheck, classificationPriority: data.classificationPriority, qualityCriteria: data.qualityCriteria, usageGuidance: data.usageGuidance },\n );\n },\n audit: () => handleAudit(),\n export: () => handleExport(),\n \"label-list\": () => handleLabelsList(),\n \"label-create\": (data) => handleLabelsCreate(data.slug, data.name, data.color, data.description, data.parentSlug, data.isGroup, data.order),\n \"label-update\": (data) => handleLabelsUpdate(data.slug, data.name, data.color, data.description, data.isGroup, data.order),\n \"label-delete\": (data) => handleLabelsDelete(data.slug),\n \"label-apply\": (data) => handleLabelsApply(data.slug, data.entryId),\n \"label-remove\": (data) => handleLabelsRemove(data.slug, data.entryId),\n };\n\n server.registerTool(\n \"collections\",\n {\n title: \"Collections\",\n description:\n \"Manage knowledge collections and workspace labels. Twelve actions:\\n\\n\" +\n \"- **list**: Browse all collections — glossary, business rules, tracking events, etc. \" +\n \"Returns slug, name, description, and field schema. Use before capture to see what exists.\\n\" +\n \"- **describe**: Full documentation for a single collection. Returns field help text, \" +\n \"option decision guides, usage guidance, examples, and cross-references. Use when you need to \" +\n \"understand a collection's purpose, field semantics, or option values.\\n\" +\n \"- **create**: Create a new collection. Provide slug, name, and field schema. \" +\n \"Use when setting up a workspace or tracking a new type of knowledge.\\n\" +\n \"- **update**: Update an existing collection's name, description, purpose, icon, navGroup, fields, or (non-system collections only) axis/stageLabelMap. \" +\n \"Only provide the fields you want to change.\\n\" +\n \"- **audit**: Health report for all workspace collections. Checks classification metadata, icon presence, \" +\n \"displayHint coverage per field, and field schema gaps vs system definitions. \" +\n \"Returns total collections, count with issues, and per-collection issue list.\\n\" +\n \"- **export**: Full system_collection_definitions export as JSON. Includes all classification metadata \" +\n \"(thinkingLayer, classificationPriority, classificationCheck, timelineRole, governanceRole, governanceFunction, etc.). Admin only.\\n\" +\n \"- **label-list/label-create/label-update/label-delete/label-apply/label-remove**: manage workspace \" +\n \"labels (absorbs the `labels` tool) — list all labels, create/update/delete a label, or apply/remove \" +\n \"a label on an entry. Labels can be applied to any entry across any collection for cross-domain filtering.\",\n inputSchema: collectionsSchema,\n annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(collectionsSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"collections\", action }, () =>\n dispatchDiscriminated(\"collections\", collectionsActionUnion, parsed.data, COLLECTIONS_ACTION_SPECS, collectionsHandlers),\n );\n }),\n );\n}\n\ninterface DescribeCollectionRecord {\n slug: string;\n name: string;\n description?: string;\n purpose?: string;\n usageGuidance?: string;\n navGroup?: string;\n governed?: boolean;\n icon?: string;\n idPrefix?: string;\n stratum?: string;\n /** WP-480 S2: served workflow vocabulary — the discovery path connectors point at (TEN-2219). */\n validWorkflowStatuses?: string[];\n fields: Array<CollectionField & {\n label?: string;\n options?: string[];\n helpText?: string;\n optionDescriptions?: Record<string, string>;\n }>;\n examples?: Array<{ name: string; description: string }>;\n crossReferences?: Array<{ slug: string; relationship: string; guidance: string }>;\n}\n\nasync function handleDescribe(slug: string) {\n const col = await kernelQuery<DescribeCollectionRecord | null>(\"chain.getCollection\", { slug });\n\n if (!col) {\n return failureResult(\n `Collection '${slug}' not found.`,\n \"NOT_FOUND\",\n `No collection with slug '${slug}' in this workspace.`,\n \"Use `collections action=list` to see available collections.\",\n );\n }\n\n const sections: string[] = [];\n\n sections.push(`# ${col.name} (\\`${col.slug}\\`)`);\n if (col.description) sections.push(col.description);\n\n const meta = [\n col.governed ? \"**Governed**\" : null,\n col.navGroup ? `**Nav group:** ${col.navGroup}` : null,\n col.idPrefix ? `**Prefix:** ${col.idPrefix}-*` : null,\n col.stratum ? `**Stratum:** ${col.stratum}` : null,\n ].filter(Boolean).join(\" · \");\n if (meta) sections.push(meta);\n\n if (col.usageGuidance) {\n sections.push(`\\n## When to Use\\n\\n${col.usageGuidance}`);\n } else if (col.purpose) {\n sections.push(`\\n## Purpose\\n\\n${col.purpose}`);\n }\n\n // WP-480 S2 (FEAT-1359): serve the workflow vocabulary — this is the discovery\n // path for `workflowStatus` values. Collections without validWorkflowStatuses\n // are unconstrained by design (STD-34) and get no section.\n if (col.validWorkflowStatuses && col.validWorkflowStatuses.length > 0) {\n sections.push(\n `\\n## Workflow Statuses\\n\\nValid \\`workflowStatus\\` values for entries in this collection:\\n${col.validWorkflowStatuses.map((s) => `- ${s}`).join(\"\\n\")}`,\n );\n }\n\n if (col.fields.length > 0) {\n const fieldDocs = col.fields.map((f) => {\n const parts: string[] = [];\n const typeInfo = `${f.type}${f.required ? \", required\" : \"\"}`;\n parts.push(`### \\`${f.key}\\` — ${f.label ?? f.key} (${typeInfo})`);\n if (f.helpText) parts.push(f.helpText);\n if (f.options && f.options.length > 0) {\n const optLines = f.options.map((opt) => {\n const desc = f.optionDescriptions?.[opt];\n return desc ? ` - **${opt}**: ${desc}` : ` - ${opt}`;\n });\n parts.push(`\\nOptions:\\n${optLines.join(\"\\n\")}`);\n }\n return parts.join(\"\\n\");\n });\n sections.push(`\\n## Fields\\n\\n${fieldDocs.join(\"\\n\\n\")}`);\n }\n\n if (col.examples && col.examples.length > 0) {\n const exList = col.examples.map((ex) => `- **${ex.name}** — ${ex.description}`).join(\"\\n\");\n sections.push(`\\n## Examples\\n\\n${exList}`);\n }\n\n if (col.crossReferences && col.crossReferences.length > 0) {\n const refList = col.crossReferences.map((r) =>\n `- **${r.slug}** (${r.relationship}): ${r.guidance}`\n ).join(\"\\n\");\n sections.push(`\\n## Related Collections\\n\\n${refList}`);\n }\n\n return {\n content: [{ type: \"text\" as const, text: sections.join(\"\\n\\n\") }],\n structuredContent: success(\n `Documentation for collection '${col.name}' (${col.slug}).`,\n {\n slug: col.slug,\n name: col.name,\n description: col.description,\n usageGuidance: col.usageGuidance ?? null,\n // WP-480 S2: null = unconstrained by design (STD-34), not \"unknown\".\n validWorkflowStatuses:\n col.validWorkflowStatuses && col.validWorkflowStatuses.length > 0\n ? col.validWorkflowStatuses\n : null,\n fieldCount: col.fields.length,\n fields: col.fields.map((f) => ({\n key: f.key,\n type: f.type,\n required: f.required,\n helpText: f.helpText ?? null,\n options: f.options ?? null,\n optionDescriptions: f.optionDescriptions ?? null,\n })),\n examples: col.examples ?? [],\n crossReferences: col.crossReferences ?? [],\n },\n ),\n };\n}\n\nasync function handleList() {\n const collections = await kernelQuery<CollectionRecord[]>(\"chain.listCollections\");\n\n if (collections.length === 0) {\n return successResult(\n \"No collections found in this workspace.\",\n \"No collections found yet.\",\n { collections: [], total: 0 },\n [{ tool: \"collections\", description: \"Create collection\", parameters: { action: \"create\" } }],\n );\n }\n\n const formatted = collections\n .map((c) => {\n const fieldList = c.fields\n .map((f) => ` - \\`${f.key}\\` (${f.type}${f.required ? \", required\" : \"\"}${f.searchable ? \", searchable\" : \"\"})`)\n .join(\"\\n\");\n const meta = [\n c.description || \"_No description_\",\n c.purpose ? `**Purpose:** ${c.purpose}` : null,\n c.navGroup ? `**Nav group:** ${c.navGroup}` : null,\n ].filter(Boolean).join(\"\\n\");\n return `## ${c.name} (\\`${c.slug}\\`)\\n${meta}\\n\\n**Fields:**\\n${fieldList}`;\n })\n .join(\"\\n\\n---\\n\\n\");\n\n return {\n content: [{ type: \"text\" as const, text: `# Knowledge Collections (${collections.length})\\n\\n${formatted}` }],\n structuredContent: success(\n `Found ${collections.length} collections.`,\n {\n collections: collections.map((c) => ({\n slug: c.slug,\n name: c.name,\n description: c.description,\n fieldCount: c.fields.length,\n })),\n total: collections.length,\n },\n ),\n };\n}\n\ninterface CollectionMetaArgs {\n axis?: \"work\" | \"none\" | \"pending\"; // required server-side at create (PRRT_kwDORS4ils6ZiYjo)\n stageLabelMap?: Record<string, \"open\" | \"in_progress\" | \"done\" | \"stopped\" | \"tag\">;\n defaultCanonicalKey?: string;\n defaultWorkflowStatus?: string;\n validWorkflowStatuses?: string[];\n classificationCheck?: string;\n classificationPriority?: number;\n // FEAT-301 Slice 2\n qualityCriteria?: z.infer<typeof qualityCriterionSchema>[];\n usageGuidance?: string;\n}\n\n// Collapses the repeated `...(meta.X !== undefined && { X })` shape (7x each site) into one call.\nfunction metaFields(m: CollectionMetaArgs): Partial<CollectionMetaArgs> { return Object.fromEntries(Object.entries(m).filter(([, v]) => v !== undefined)) as Partial<CollectionMetaArgs>; }\n\nasync function handleCreate(\n slug: string,\n name: string,\n description: string | undefined,\n purpose: string | undefined,\n icon: string | undefined,\n navGroup: string,\n fields: z.infer<typeof fieldSchema>[],\n meta: CollectionMetaArgs = {},\n) {\n requireWriteAccess();\n\n try {\n await kernelMutation(\"chain.createCollection\", {\n slug,\n name,\n description,\n purpose,\n icon,\n navGroup,\n fields,\n ...metaFields(meta),\n createdBy: getAgentSessionId() ? `agent:${getAgentSessionId()}` : \"mcp\",\n });\n\n // A collection write changes workspace structure — drop this scope's cached\n // shape AND the caches derived from it (profiles, hub-slug set) so the next\n // call (this agent, this workspace) sees it immediately, rather than waiting\n // out the TTL. Scoped, so other tenants are untouched.\n invalidateCollectionCacheForScope();\n invalidateProfileCacheForScope();\n invalidateHubCacheForScope();\n\n const fieldList = fields\n .map((f) => ` - \\`${f.key}\\` (${f.type}${f.required ? \", required\" : \"\"}${f.searchable ? \", searchable\" : \"\"})`)\n .join(\"\\n\");\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Collection Created: ${name}\\n\\n` +\n `**Slug:** \\`${slug}\\`\\n` +\n (description ? `**Description:** ${description}\\n` : \"\") +\n (purpose ? `**Purpose:** ${purpose}\\n` : \"\") +\n `**Nav group:** ${navGroup}\\n` +\n `\\n**Fields:**\\n${fieldList}\\n\\n` +\n `You can now capture entries: \\`capture collection=\"${slug}\" name=\"...\" description=\"...\"\\``,\n }],\n structuredContent: success(\n `Created collection '${name}' (${slug}) with ${fields.length} fields.`,\n { slug, name, description, purpose, navGroup, fieldCount: fields.length },\n [{ tool: \"capture\", description: \"Capture an entry\", parameters: { collection: slug } }],\n ),\n };\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"already exists\")) {\n return failureResult(\n `Collection '${slug}' already exists. Use collections action=update to modify it, or choose a different slug.`,\n \"DUPLICATE\",\n `Collection '${slug}' already exists.`,\n \"Use collections action=update to modify it.\",\n [{ tool: \"collections\", description: \"Update collection\", parameters: { action: \"update\", slug } }],\n );\n }\n const code = (error as { code?: string }).code ?? (error as { data?: { code?: string } }).data?.code;\n if (code === \"COLLECTION_PREFIX_TAKEN\" || msg.includes(\"already used by collection\")) {\n return failureResult(\n msg,\n \"DUPLICATE\",\n msg,\n \"Choose a different prefix by passing the idPrefix parameter, or let the system derive one from a different slug.\",\n [{ tool: \"collections\", description: \"List collections to see taken prefixes\", parameters: { action: \"list\" } }],\n );\n }\n throw error;\n }\n}\n\nasync function handleUpdate(\n slug: string,\n name: string | undefined,\n description: string | undefined,\n purpose: string | undefined,\n icon: string | undefined,\n navGroup: string | undefined,\n fields: z.infer<typeof fieldSchema>[] | undefined,\n meta: CollectionMetaArgs = {},\n) {\n requireWriteAccess();\n\n await kernelMutation(\"chain.updateCollection\", {\n slug,\n ...(name !== undefined && { name }),\n ...(description !== undefined && { description }),\n ...(purpose !== undefined && { purpose }),\n ...(icon !== undefined && { icon }),\n ...(navGroup !== undefined && { navGroup }),\n ...(fields !== undefined && { fields }),\n ...metaFields(meta),\n });\n\n // A collection write changes workspace structure — drop this scope's cached\n // shape AND the caches derived from it (profiles, hub-slug set) so the next\n // call (this agent, this workspace) sees it immediately, rather than waiting\n // out the TTL. Scoped, so other tenants are untouched.\n invalidateCollectionCacheForScope();\n invalidateProfileCacheForScope();\n invalidateHubCacheForScope();\n\n const changes = [name && \"name\", description && \"description\", purpose && \"purpose\", icon && \"icon\", navGroup && \"navGroup\", fields && \"fields\", meta.axis !== undefined && \"axis\", meta.stageLabelMap !== undefined && \"stageLabelMap\", meta.defaultCanonicalKey !== undefined && \"defaultCanonicalKey\", meta.defaultWorkflowStatus !== undefined && \"defaultWorkflowStatus\", meta.validWorkflowStatuses !== undefined && \"validWorkflowStatuses\", meta.classificationCheck !== undefined && \"classificationCheck\", meta.classificationPriority !== undefined && \"classificationPriority\", meta.qualityCriteria !== undefined && \"qualityCriteria\", meta.usageGuidance !== undefined && \"usageGuidance\"]\n .filter(Boolean).join(\", \");\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Collection Updated: \\`${slug}\\`\\n\\nChanged: ${changes || \"no changes\"}.\\n\\n` +\n `Use \\`collections action=list\\` to verify the result.`,\n }],\n structuredContent: success(\n `Updated collection '${slug}'. Changed: ${changes || \"no changes\"}.`,\n { slug, changes },\n ),\n };\n}\n\ninterface AuditIssue {\n code: string;\n message: string;\n fieldKey?: string;\n}\n\ninterface AuditCollectionResult {\n slug: string;\n name: string;\n icon?: string;\n fieldCount: number;\n issues: AuditIssue[];\n}\n\ninterface AuditCollectionsData {\n total: number;\n healthy: number;\n withIssues: number;\n collections: AuditCollectionResult[];\n}\n\nasync function handleAudit() {\n const data = await kernelQuery<GatewayRouteReturnByName<\"chain.auditCollections\">>(\"chain.auditCollections\");\n\n const lines: string[] = [];\n lines.push(`# Collection Audit Report`);\n lines.push(`\\n**Total:** ${data.total} · **Healthy:** ${data.healthy} · **With issues:** ${data.withIssues}`);\n\n if (data.withIssues === 0) {\n lines.push(`\\nAll collections are healthy.`);\n } else {\n const problematic = data.collections.filter((c) => c.issues.length > 0);\n lines.push(`\\n## Collections With Issues\\n`);\n for (const col of problematic) {\n const icon = col.icon ?? \"—\";\n lines.push(`### ${icon} ${col.name} (\\`${col.slug}\\`) — ${col.issues.length} issue(s)`);\n for (const issue of col.issues) {\n lines.push(`- **[${issue.code}]** ${issue.message}`);\n }\n lines.push(\"\");\n }\n }\n\n const healthyCollections = data.collections.filter((c) => c.issues.length === 0);\n if (healthyCollections.length > 0) {\n lines.push(`\\n## Healthy Collections\\n`);\n lines.push(healthyCollections.map((c) => `- ${c.icon ?? \"—\"} \\`${c.slug}\\``).join(\"\\n\"));\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Audit complete. ${data.total} collections: ${data.healthy} healthy, ${data.withIssues} with issues.`,\n data,\n ),\n };\n}\n\n/**\n * BET-288 Slice 5: Export all system_collection_definitions with full classification metadata.\n * Returns the complete definition for every system collection, including fields not in \"describe\":\n * thinkingLayer, classificationPriority, classificationCheck, classificationSignals,\n * governanceRole, governanceFunction, timelineRole, canBeElementOf, descriptionFieldKey.\n * Admin only (enforced by the HTTP route).\n */\nasync function handleExport() {\n const definitions = await kernelQuery<Record<string, unknown>[]>(\"chain.exportDefinitions\");\n\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(definitions, null, 2) }],\n structuredContent: success(\n `Exported ${definitions.length} system collection definitions with full classification metadata.`,\n { definitions, total: definitions.length },\n ),\n };\n}\n","import type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation } from \"../client.js\";\nimport { success, successResult, failureResult } from \"../envelope.js\";\n\nexport const labelsSchema = z.object({\n action: z.enum([\"list\", \"create\", \"update\", \"delete\", \"apply\", \"remove\"])\n .describe(\"Action: list all labels, create/update/delete a label, or apply/remove a label on an entry\"),\n slug: z.string().max(200).optional().describe(\"Label slug (required for create/update/delete/apply/remove)\"),\n name: z.string().max(500).optional().describe(\"Display name (required for create)\"),\n color: z.string().max(50).optional().describe(\"Hex color, e.g. '#ef4444'\"),\n description: z.string().max(2000).optional().describe(\"What this label means\"),\n parentSlug: z.string().max(200).optional().describe(\"Parent group slug for label hierarchy\"),\n isGroup: z.boolean().optional().describe(\"True if this is a group container, not a taggable label\"),\n order: z.number().optional().describe(\"Sort order within its group\"),\n entryId: z.string().max(200).optional().describe(\"Entry ID for apply/remove actions\"),\n});\n\n/**\n * WP-484 S2 (§3): extracted label handlers — reused by the legacy `labels`\n * standalone tool AND `collections action=label-*` (absorbed per §3\n * core-nouns table). One business-logic path per action.\n */\nexport async function handleLabelsList() {\n const labels = await kernelQuery<any[]>(\"chain.listLabels\");\n\n if (labels.length === 0) {\n return successResult(\n \"No labels defined in this workspace yet.\",\n \"No labels defined yet.\",\n { labels: [], total: 0 },\n [{ tool: \"collections\", description: \"Create a label\", parameters: { action: \"label-create\" } }],\n );\n }\n\n const groups = labels.filter((l) => l.isGroup);\n const ungrouped = labels.filter((l) => !l.isGroup && !l.parentId);\n const children = (parentId: string) => labels.filter((l) => l.parentId === parentId);\n\n const lines: string[] = [\"# Workspace Labels\"];\n\n for (const group of groups) {\n lines.push(`\\n## ${group.name}`);\n if (group.description) lines.push(`_${group.description}_`);\n for (const child of children(group._id)) {\n const c = child.color ? ` ${child.color}` : \"\";\n lines.push(` - \\`${child.slug}\\` ${child.name}${c}`);\n }\n }\n\n if (ungrouped.length > 0) {\n lines.push(\"\\n## Ungrouped\");\n for (const label of ungrouped) {\n const c = label.color ? ` ${label.color}` : \"\";\n lines.push(`- \\`${label.slug}\\` ${label.name}${c}${label.description ? ` — _${label.description}_` : \"\"}`);\n }\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Found ${labels.length} labels in ${groups.length} groups.`,\n { labels, total: labels.length },\n ),\n };\n}\n\nexport async function handleLabelsCreate(\n slug: string,\n name: string,\n color?: string,\n description?: string,\n parentSlug?: string,\n isGroup?: boolean,\n order?: number,\n) {\n let parentId: string | undefined;\n if (parentSlug) {\n const labels = await kernelQuery<any[]>(\"chain.listLabels\");\n const parent = labels.find((l: any) => l.slug === parentSlug);\n if (!parent) {\n return failureResult(\n `Parent label '${parentSlug}' not found. Use collections action=label-list to see available groups.`,\n \"NOT_FOUND\",\n `Parent label '${parentSlug}' not found.`,\n \"Use collections action=label-list to see available groups.\",\n [{ tool: \"collections\", description: \"List labels\", parameters: { action: \"label-list\" } }],\n );\n }\n parentId = parent._id;\n }\n\n await kernelMutation(\"chain.createLabel\", { slug, name, color, description, parentId, isGroup, order });\n return successResult(\n `Label '${name}' (${slug}) created.`,\n `Created label '${name}' (${slug}).`,\n { slug, name, color, parentSlug },\n [{ tool: \"collections\", description: \"List labels\", parameters: { action: \"label-list\" } }],\n );\n}\n\nexport async function handleLabelsUpdate(\n slug: string,\n name?: string,\n color?: string,\n description?: string,\n isGroup?: boolean,\n order?: number,\n) {\n await kernelMutation(\"chain.updateLabel\", { slug, name, color, description, isGroup, order });\n return successResult(\n `Label '${slug}' updated.`,\n `Updated label '${slug}'.`,\n { slug },\n [{ tool: \"collections\", description: \"List labels\", parameters: { action: \"label-list\" } }],\n );\n}\n\nexport async function handleLabelsDelete(slug: string) {\n await kernelMutation<GatewayRouteReturnByName<\"chain.deleteLabel\">>(\"chain.deleteLabel\", { slug });\n return successResult(\n `Label '${slug}' removed from all entries and deleted.`,\n `Deleted label '${slug}'.`,\n { slug },\n );\n}\n\nexport async function handleLabelsApply(slug: string, entryId: string) {\n await kernelMutation(\"chain.applyLabel\", { entryId, labelSlug: slug });\n return successResult(`Label '${slug}' applied to ${entryId}.`, `Applied label '${slug}' to ${entryId}.`, { slug, entryId });\n}\n\nexport async function handleLabelsRemove(slug: string, entryId: string) {\n await kernelMutation<GatewayRouteReturnByName<\"chain.removeLabel\">>(\"chain.removeLabel\", { entryId, labelSlug: slug });\n return successResult(`Label '${slug}' removed from ${entryId}.`, `Removed label '${slug}' from ${entryId}.`, { slug, entryId });\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `labels` tool retired\n// here. handleLabels* stay live — collections.ts (the `collections` compound,\n// action=label-*) is their only remaining caller.\n","/** Orient tool — workspace orientation and session bootstrapping. Extracted from health.ts to isolate the orient tool registration; the orient handler is the primary entry point for agents to load workspace context, governance, and active work. */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, kernelCall, getWorkspaceContext, getAgentSessionId, getConversationId, setSessionOriented, isSessionOriented, runWithToolContext, type WorkspaceContext } from \"../client.js\";\nimport { trackWriteBackHintServed } from \"../analytics.js\";\nimport { success, thinWrapper, parseOrFail, type ToolResult } from \"../envelope.js\";\nimport { buildPlannedWork, hasPlannedWork, buildPlannedWorkSection, formatRecoveryBlock, type PriorSession } from \"./planned-work.js\";\nimport {\n buildTaskAlignmentLines,\n buildOperatingProtocol,\n buildCoherenceSection,\n buildDocCompletenessSection,\n formatInitiativeStatusLines,\n formatWorkstreamHealthLines,\n formatWhatNeedsAttentionLines,\n formatWhatNeedsAttentionBrief,\n formatBetConstellationLines,\n formatShapeAdvisorySummaryLine,\n provenanceMark,\n type CoherenceSnapshot,\n type CollectionDocFields,\n type TaskAlignmentPayload,\n type InitiativeStatusItem,\n type WorkstreamHealthItem,\n type WhatNeedsAttention,\n type ConstellationEntryItem,\n} from \"./orient-shared.js\";\nimport { buildRitualsSurfaceLines, buildAlreadyOrientedResult, type RitualsSurfacePayload } from \"./orient-rituals.js\";\nimport { reportOrientWrapperBytes } from \"./orient-metrics.js\";\nimport { buildDegradedPreloadsLine, coherencyCheckTag } from \"./orientDegradation.js\";\nimport { formatTopGapPrompt, formatGapOneLiner, type ReadinessGap, type GapContext } from \"../lib/gapToPrompt.js\";\nimport { getCollectionLabel, type WorkspaceVocabCtx } from \"../lib/canonicalRefs.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { handleStartPb } from \"./start_pb.js\";\nimport { handleRecordActivation } from \"./record_activation.js\";\n\n/** Must match PURPOSE_GAP_PREFIX in convex/lib/constants.ts — kept in sync manually. */\nconst PURPOSE_GAP_PREFIX = \"purpose-gap-\";\n\ntype BudgetFlags = {\n advisory?: boolean;\n warning?: boolean;\n emergencyCapped?: boolean;\n truncated?: boolean;\n overflowed?: boolean;\n breachTier?: \"none\" | \"advisory\" | \"warning\" | \"emergency\";\n queryName?: string;\n attribution?: { feature?: string; route?: string };\n};\n\ntype RcrtVerdict = {\n served: \"ok\" | \"low\" | \"miss\";\n kind: string | null;\n confidence: number;\n rubricVersion: string;\n};\n\ntype DomainDetail = {\n reason?: string | null;\n nextAction?: string | null;\n evidenceGap?: string | null;\n} | null;\n\n/** TEN-1740: structural mirror of convex/agentKnowledge/orientView.ts OrientStrategicContext — packages/* has no import path into convex/, so duplicated here (same pattern as MCPOrientView below); kept in sync manually. */\ntype StrategicContext = {\n vision: string | null;\n purpose: string | null;\n activeBetCount: number;\n currentWorkPackage: string | null;\n activeTensionCount: number;\n productAreas: string[];\n productAreaCount: number;\n playingField: string[];\n playingFieldCount: number;\n};\n\n/** TEN-1740: structural mirror of planned-work.ts's `formatRecoveryBlock` parameter shape\n * (itself a mirror of convex's OrientRecoveryBlock). Declared once so every call site shares\n * one type instead of a per-call-site `as Parameters<...>` cast. */\ntype RecoveryBlockData = {\n sessionId: string;\n status: \"timed_out\" | \"completed\";\n date: string;\n duration: string;\n created: { entryId: string; collection: string; name: string }[];\n modified: { entryId: string; collection: string; name: string }[];\n draftsNeedingAttention: { entryId: string; collection: string; name: string }[];\n relationsCreated: number;\n createdOverflow?: number;\n modifiedOverflow?: number;\n draftsOverflow?: number;\n};\n\nexport function formatRetrievalMissLines(verdict: RcrtVerdict, domain: DomainDetail): string[] {\n const lines: string[] = [];\n if (verdict.served !== \"ok\") {\n if (verdict.served === \"miss\") {\n lines.push(`⚠ RETRIEVAL MISS — ${verdict.kind ?? \"unknown\"}`);\n } else {\n lines.push(`· weak serve (provisional, ${verdict.rubricVersion}): ${verdict.kind ?? \"thin\"}`);\n }\n }\n if (domain?.reason) lines.push(` Reason: ${domain.reason}`);\n if (domain?.nextAction) lines.push(` Next action: ${domain.nextAction}`);\n if (domain?.evidenceGap) lines.push(` Evidence gap: ${domain.evidenceGap}`);\n return lines;\n}\n\nfunction domainDetailFromRetrieval(retrieval: Record<string, unknown> | undefined): DomainDetail {\n if (!retrieval) return null;\n const reason = typeof retrieval.fallbackReason === \"string\" ? retrieval.fallbackReason : null;\n const nextAction = typeof retrieval.fallbackAction === \"string\" ? retrieval.fallbackAction : null;\n const evidenceGap = typeof retrieval.evidenceGap === \"string\" ? retrieval.evidenceGap : null;\n return reason || nextAction || evidenceGap ? { reason, nextAction, evidenceGap } : null;\n}\n\n// WP-480 S3 (FEAT-1360): the taskIsMeaningful predicate mirror is DELETED — the server resolves\n// task-meaningfulness + effective tier and serves them (`taskMeaningful`, `resolvedTier`); this connector consumes them.\n\n/**\n * Mark session oriented in Convex. If persistence fails with an optional coherence snapshot\n * (schema drift / validation), retry without it so orientation can still complete.\n */\nasync function markOrientedWithSnapshotFallback(\n agentSessionId: string,\n coherenceSnapshot?: CoherenceSnapshot,\n): Promise<boolean> {\n try {\n await kernelCall<GatewayRouteReturnByName<\"agent.markOriented\">>(\"agent.markOriented\", {\n sessionId: agentSessionId,\n ...(coherenceSnapshot ? { coherenceSnapshot } : {}),\n });\n setSessionOriented(true);\n return true;\n } catch {\n if (!coherenceSnapshot) return false;\n try {\n await kernelCall<GatewayRouteReturnByName<\"agent.markOriented\">>(\"agent.markOriented\", { sessionId: agentSessionId });\n setSessionOriented(true);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Extract entry IDs from prior sessions for contextual priming.\n * - all: deduplicated from all sessions, capped at 10 (for scoring)\n * - lastSessionOnly: from most recent session only, capped at 5 (for temporal thread)\n */\nfunction extractSessionEntryIds(priorSessions: PriorSession[]): {\n all: string[];\n lastSessionOnly: string[];\n} {\n const allSeen = new Set<string>();\n const all: string[] = [];\n let lastSessionOnly: string[] = [];\n for (let i = 0; i < priorSessions.length; i++) {\n const s = priorSessions[i];\n const created = Array.isArray(s.entriesCreated) ? s.entriesCreated : [];\n const modified = Array.isArray(s.entriesModified) ? s.entriesModified : [];\n const ids = [...created, ...modified].filter((id): id is string => typeof id === \"string\" && id.length > 0);\n if (i === 0) {\n lastSessionOnly = [...new Set(ids)].slice(0, 5);\n }\n for (const id of ids) {\n if (!allSeen.has(id)) {\n allSeen.add(id);\n all.push(id);\n if (all.length >= 10) break;\n }\n }\n if (all.length >= 10) break;\n }\n return { all, lastSessionOnly };\n}\n\n// WP-484 S2 (§3): `orient` absorbs `start_pb` → action=start and `record_activation` →\n// action=record-activation. Prior (action-less) behavior becomes action=task — §3a below carries\n// the superset of every absorbed action's params; §3b (ORIENT_ACTION_UNION) enforces per-action\n// shape. `action` defaults to 'task' so every existing bare-call site keeps working (DEC-283 sweep, S3).\nconst ORIENT_ACTIONS = [\"start\", \"task\", \"record-activation\"] as const;\ntype OrientAction = (typeof ORIENT_ACTIONS)[number];\n\nexport const orientSchema = z.object({\n action: z.enum(ORIENT_ACTIONS).optional().default(\"task\").describe(\n \"'start': universal session opener (absorbs start_pb) — stage-aware setup skill or standup briefing. \" +\n \"'task': task-grounded context loader — the original orient behavior. \" +\n \"'record-activation': chat-only activation receipt writer (absorbs record_activation).\",\n ),\n mode: z.enum([\"full\", \"brief\"]).optional().default(\"full\").describe(\"For 'task': full = full context (default). brief = compact summary for mid-session re-orientation. Prefer using the `tier` param for depth control.\"),\n tier: z.enum([\"summary\", \"standard\", \"full\"]).optional().describe(\n \"For 'task': payload depth. Defaults to summary (~10 KB) when task is provided; standard (~256 KB) when task is absent. Pass summary, standard, or full to override.\",\n ),\n task: z.string().max(2000).optional().describe(\n \"For 'task': natural-language task description for task-scoped context. For 'start': what you're about to work on. When provided to 'task', orient returns scored, relevant entries for the task.\",\n ),\n scope: z.string().max(200).optional().describe(\"For 'task': optional domain scope to filter governance to entries relevant for this domain. Forwarded to Convex for workspace-specific validation.\"),\n // WP-486 Slice 1 (FEAT-1371, TEN-2724): the startup-signal envelope `resolveStartupDomain` already\n // consumes (`startupResolver.ts:344-379`) but this tool never sent. Nested to match the server's\n // `StartupResolutionSignals` shape exactly — every field optional, sanitized server-side.\n startupSignals: z.object({\n changedPaths: z.array(z.string()).max(25).optional().describe(\"Paths changed in the current working tree, if known (e.g. from a prior git status/diff tool call).\"),\n reviewedArtifactRefs: z.array(z.string()).max(25).optional().describe(\"Chain entry IDs the caller has already reviewed this session, if tracked.\"),\n branchName: z.string().max(120).optional().describe(\"Current git branch name, if known.\"),\n worktreeName: z.string().max(120).optional().describe(\"Current worktree/directory name, if known.\"),\n }).optional().describe(\"For 'task': best-effort startup signals for domain resolution — changedPaths/reviewedArtifactRefs/branchName/worktreeName. All optional; omit fields you don't know.\"),\n invocationPath: z.enum(['session-start', 'session-close', 'manual-orient', 'handshake', 'unknown']).optional().describe(\"For 'task': how this orient was invoked. Defaults to 'manual-orient' (the direct `orient task=...` call shape) when omitted.\"),\n confirmedEntryCount: z.number().int().min(0).optional().describe(\n \"For 'record-activation': confirmed-entry count from the Phase 4 capture loop. The mutation enforces >=10.\",\n ),\n entriesAcrossCollections: z.number().int().min(0).optional().describe(\n \"For 'record-activation': number of distinct collections those entries span. The mutation enforces >=2 (diversity soft-gate).\",\n ),\n retrievalDemoConfirmed: z.boolean().optional().describe(\n \"For 'record-activation': true if the retrieval round-trip ran successfully in Phase 4. The mutation rejects false.\",\n ),\n});\n\n// §3b — handler layer: per-action discriminatedUnion.\nconst orientStartVariant = z.object({\n action: z.literal(\"start\"),\n task: z.string().max(2000).optional(),\n});\nconst orientTaskVariant = z.object({\n action: z.literal(\"task\"),\n mode: z.enum([\"full\", \"brief\"]).optional().default(\"full\"),\n tier: z.enum([\"summary\", \"standard\", \"full\"]).optional(),\n task: z.string().max(2000).optional(),\n scope: z.string().max(200).optional(),\n // WP-486 Slice 1 (FEAT-1371) — mirrors orientSchema's top-level declaration above; see its\n // doc comment for the shape rationale.\n startupSignals: z.object({\n changedPaths: z.array(z.string()).max(25).optional(),\n reviewedArtifactRefs: z.array(z.string()).max(25).optional(),\n branchName: z.string().max(120).optional(),\n worktreeName: z.string().max(120).optional(),\n }).optional(),\n invocationPath: z.enum(['session-start', 'session-close', 'manual-orient', 'handshake', 'unknown']).optional(),\n});\nconst orientRecordActivationVariant = z.object({\n action: z.literal(\"record-activation\"),\n confirmedEntryCount: z.number().int().min(0),\n entriesAcrossCollections: z.number().int().min(0),\n retrievalDemoConfirmed: z.boolean(),\n});\n\nexport const orientActionUnion = z.discriminatedUnion(\"action\", [\n orientStartVariant,\n orientTaskVariant,\n orientRecordActivationVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const ORIENT_ACTION_SPECS: Record<OrientAction, ActionParamSpec> = {\n start: { params: [\"task\"], description: \"Universal session opener; task is optional.\" },\n task: { params: [\"mode\", \"tier\", \"task\", \"scope\"], description: \"Task-grounded context loader; all params optional.\" },\n \"record-activation\": {\n params: [\"confirmedEntryCount\", \"entriesAcrossCollections\", \"retrievalDemoConfirmed\"],\n description: \"All three fields are required.\",\n },\n};\n\n// coherencyCheckTag moved to ./orientDegradation.js (STD-2/DEC-1504 shrink-only offset,\n// WP-621 S1) — mirrors packages/cli/src/formatters/orientDegradation.ts's own relocation of\n// the CLI's twin. See that module for the full WP-485/coherence-run-sweep provenance.\n\nfunction taskGroundingWarningLines(task?: string, hasTaskGrounding = false): string[] {\n if (hasTaskGrounding) return [];\n if (task) {\n return [\n \"## Task grounding incomplete\",\n \"_A task was provided, but task-scoped governance/context did not load. Write tools stay locked until the task produces grounded context._\",\n \"\",\n 'Refine the task and rerun `orient task=\"describe the work\"` or use `context action=\"gather\"` for deeper task context.',\n \"\",\n ];\n }\n return [\n \"## Task grounding required\",\n \"_This is workspace orientation only. Do not start implementation, review, diagnosis, auth, security, or governance-sensitive work until you run task-shaped orient._\",\n \"\",\n 'Run `orient task=\"describe the work\"` to load binding governance and supporting context for the actual task.',\n \"\",\n ];\n}\n\nexport function registerOrientTool(server: McpServer) {\n // §3b handler map — dispatched by dispatchDiscriminated via orientActionUnion.\n const orientHandlers: Record<OrientAction, (data: any) => Promise<ToolResult>> = {\n start: (data) => handleStartPb({ task: data.task }),\n task: (data) => _handleOrient({\n mode: data.mode,\n tier: data.tier,\n task: data.task,\n scope: data.scope,\n startupSignals: data.startupSignals,\n invocationPath: data.invocationPath,\n }),\n \"record-activation\": (data) => handleRecordActivation({\n confirmedEntryCount: data.confirmedEntryCount,\n entriesAcrossCollections: data.entriesAcrossCollections,\n retrievalDemoConfirmed: data.retrievalDemoConfirmed,\n }),\n };\n\n server.registerTool(\n \"orient\",\n {\n title: \"Orient\",\n description:\n \"Workspace orientation and session bootstrapping. Three actions:\\n\\n\" +\n \"- **start**: Universal opener (absorbs `start_pb`) — say 'Start PB' to begin every session. \" +\n \"Stage-aware: fresh workspaces (blank/seeded) get the SKILL-pb-setup body verbatim; active workspaces \" +\n \"(grounded/connected) get a standup briefing. Orients the CURRENT session — it does not create one; \" +\n \"for writes, call `session action=start` first.\\n\" +\n \"- **task**: Task-grounded context loader (the original `orient` behavior). Use after `action=start` \" +\n \"to load governance and context for a specific task. Completing orientation unlocks write tools.\\n\" +\n \"- **record-activation**: Chat-only activation receipt writer (absorbs `record_activation`) — closes \" +\n \"the install-to-activation arc for chat-only surfaces.\\n\\n\" +\n \"**tier** (action=task): Controls payload depth.\\n\" +\n \"- `summary` (~10 KB) — compact, calibrated for task-scoped retrieval.\\n\" +\n \"- `standard` (~256 KB) — rich, suited to workspace standups.\\n\" +\n // Bound is deliberate at ALL tiers (STD-219 §4, TEN-3058/WP-634 — boundDirectionText).\n \"- `full` — complete payload, no cap, except strategicContext vision/purpose (always \" +\n \"server-bounded to ~200 chars + an ellipsis marker — no uncapped path at any tier). Use with deliberation.\\n\\n\" +\n \"Defaults: `summary` when `task` is provided; `standard` when `task` is absent. Explicit `tier` always wins.\\n\\n\" +\n \"**mode** (action=task): `full` (default) returns full context. `brief` returns compact summary — mapped to tier=summary internally.\\n\\n\" +\n \"**scope** (action=task): Optional domain scope filtering governance to entries relevant for the specified domain.\",\n inputSchema: orientSchema,\n // Mixed read/write noun (§3 R3): 'start'/'record-activation' write session state.\n annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(orientSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"orient\", action }, () =>\n dispatchDiscriminated(\"orient\", orientActionUnion, parsed.data, ORIENT_ACTION_SPECS, orientHandlers),\n );\n }),\n );\n}\n\n/** DEC-NEW: exported orient request handler — testable target for the surface-forwarding tests (AC #5); body unchanged, only the wrapping was lifted to a named export. */\nexport async function _handleOrient({ mode = \"full\", tier, task, scope, startupSignals, invocationPath }: {\n mode?: \"full\" | \"brief\";\n tier?: \"summary\" | \"standard\" | \"full\";\n task?: string;\n scope?: string;\n /** WP-486 Slice 1 (FEAT-1371) — see orientSchema.startupSignals doc comment. */\n startupSignals?: {\n changedPaths?: string[];\n reviewedArtifactRefs?: string[];\n branchName?: string;\n worktreeName?: string;\n };\n /** WP-486 Slice 1 (FEAT-1371) — defaults to 'manual-orient' below, mirroring the CLI's\n * `pb orient --task` default (`commands/orient.ts`). */\n invocationPath?: 'session-start' | 'session-close' | 'manual-orient' | 'handshake' | 'unknown';\n}) {\n const errors: string[] = [];\n // DEC-NEW + STD-219 §5 chain-version: surface forwards tier by key omission unless\n // the caller passed `tier` explicitly or `mode === 'brief'` (per-mode short-circuit).\n // When callTier is undefined the kernel applies the task-conditional default.\n const callTier: 'summary' | 'standard' | 'full' | undefined =\n tier ?? (mode === 'brief' ? 'summary' : undefined);\n // WP-480 S3 (FEAT-1360): the connector no longer pre-decides the resolved tier — it sends\n // raw inputs and consumes the server's resolution off the served payload (`resolvedTier`,\n // `taskMeaningful`), assigned right after the getOrientView fetch.\n\n // BET-279: --scope without --task is a silent no-op — warn the caller.\n if (scope && !task) {\n errors.push(\"--scope requires --task to filter governance. Scope was ignored.\");\n }\n const agentSessionId = getAgentSessionId();\n\n // WP-582 B2 round 1 (PR #532, T15): the shortcut below skips the full `chain.getOrientView`\n // fetch on purpose (mid-session re-orientation; paying full cost would defeat the point) —\n // but still owes the rituals surface. `buildAlreadyOrientedResult` (orient-rituals.ts) is\n // the offsetting STD-2 split for this file's own budget.\n if (isSessionOriented() && mode === \"brief\" && !task) {\n return buildAlreadyOrientedResult(kernelQuery, agentSessionId, taskGroundingWarningLines());\n }\n\n let wsCtx: WorkspaceContext | null = null;\n try {\n wsCtx = await getWorkspaceContext();\n } catch (e: unknown) {\n errors.push(`Workspace: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n let priorSessions: PriorSession[] = [];\n let recoveryBlock: RecoveryBlockData | null = null;\n\n // TEN-1740: inline structural type covering fields MCP reads from OrientViewModel.\n // TODO: extract to a shared package once workspace/packages/shared-types exists.\n type MCPOrientView = {\n stage: string;\n _truncated?: boolean;\n _budget?: { bytes: number; truncated: boolean; truncationReasons: string[]; overflowed: boolean };\n /** WP-465 slice ③ (§4.1): server-computed pre-build verdict — top-level, budget-exempt. */\n taskAlignment?: TaskAlignmentPayload;\n degradedPreloads?: string[]; // WP-621 S1: which preload(s), if any, degraded this run\n /** WP-582 B2 (FEAT-1404): the rituals surface — three pre-rendered, NON-truncatable\n * one-liners (server-computed, orientRituals.ts). `null`/absent is the no-row arm. */\n directionLine?: string | null;\n verdictAskLine?: string;\n spineLine?: string | null;\n /** PR #538 late review fix (P2): text rendering read it, structuredContent didn't. */\n atCapLine?: string | null;\n fetchFailed?: boolean; // Orient-fix: true only when getRitualsSurface failed open server-side.\n retrievalMiss?: RcrtVerdict;\n /** WP-480 S3 (FEAT-1360): server-resolved task-meaningfulness — optional for old deploys. */\n taskMeaningful?: boolean;\n /** WP-480 S3: the server's OWN tier resolution for this serve — optional for old deploys. */\n resolvedTier?: 'summary' | 'standard' | 'full';\n strategicContext?: StrategicContext;\n governance?: { principles: unknown[]; standards: unknown[]; businessRules: unknown[] };\n activeWorkPackages?: Array<{ entryId: string | null; _id?: string; name: string; origin?: string; linkedTensions?: Array<{ entryId: string | null; name: string; severity?: string; priority?: string }>; coherencyCheckStatus?: \"not_checked\" | \"check_incomplete\" | \"stale\" }>; tensions?: unknown[]; architectureNotes?: unknown[]; proposals?: unknown[]; absenceSignals?: unknown[];\n startup?: { groundingStatus: string; confidence: string; totalFound: number; seeds: unknown[]; bindingGovernance: { principles: unknown[]; standards: unknown[]; businessRules: unknown[]; byCollection?: unknown[] }; domainRetrieval: Record<string, unknown>; steeringContext: unknown[]; supportingContext: unknown[]; taskProfile: { workType: string; domain: string; keywords: string[] } };\n taskContext?: {\n seeds: Array<{ entryId: string | null; name: string; collectionSlug: string | null; provenance?: 'authoritative' | 'provisional' | 'floor'; anchoredBy?: string; why?: string; whyQuality?: 'rationale' | 'missing' | 'restated' }>;\n context: Array<{ entryId: string | null; name: string; collectionSlug: string | null; score: number; hop: number; origin?: 'human' | 'agent' | 'external'; provenance?: 'authoritative' | 'provisional' | 'floor'; anchoredBy?: string; why?: string; whyQuality?: 'rationale' | 'missing' | 'restated' }>;\n totalFound: number;\n confidence: string;\n constellationEntries?: Array<{ entryId: string | null; name: string; collectionSlug: string | null; canonicalKey: string | null }>;\n constellationBetName?: string;\n /** STD-219 §4 (DEC-1147): set when taskContext is a truncation stub, not full grounding. */\n isGroundingStub?: true;\n groundingNote?: string;\n };\n plannedWork?: { uncommittedDrafts: unknown[]; inProgressEntries: unknown[]; openTensions: unknown[] };\n priorSessions?: PriorSession[]; recoveryBlock?: RecoveryBlockData | null;\n writeBackHints?: Array<{ collectionSlug: string; hint: string }>;\n activeGoals?: unknown[]; strategyHighlights?: unknown[]; playingField?: unknown[];\n recentDecisions?: unknown[]; recentlySuperseded?: unknown[]; staleEntries?: unknown[];\n continuingFrom?: Array<{ entryId: string | null; name: string; collectionSlug: string | null; score: number; reasoning: string; canonicalKey: string | null; primer?: string }>;\n lastSessionTouched?: Array<{ entryId: string | null; name: string; collectionSlug: string | null; canonicalKey: string | null; primer?: string }>;\n initiativeStatus?: InitiativeStatusItem[]; workstreamHealth?: WorkstreamHealthItem[];\n whatNeedsAttention?: WhatNeedsAttention;\n trustMetrics?: { verified: number; unverified: number; noStatus: number; total: number; scannedCap: boolean };\n /** WP-560/TEN-2532 — post-merge review (Codex P1): was present on the server view but never rendered here. */\n shapeAdvisorySummary?: { windowDays: number; compoundTotal: number; pendingCount: number; pendingRate: number | null; precisionAgent: number | null; precisionAgentN: number; precisionHuman: number | null; precisionHumanN: number; precisionHumanNote: string | null; candidateRateBySource: Record<string, number | null>; candidateCountBySource?: Record<string, number>; scanTruncated: boolean };\n stalenessThresholdDays?: number;\n };\n let orientView: MCPOrientView | null = null;\n // WP-582 B2 round 1 (Codex P2 review, PR #532, T12): distinguish \"the fetch below threw\"\n // from a genuine no-row arm — both leave orientView null/absent-fielded, but only one is\n // an outage. See buildRitualsSurfaceLines' fetchFailed param.\n let orientFetchFailed = false;\n try {\n const orientArgs: {\n task?: string;\n scope?: string;\n tier?: 'summary' | 'standard' | 'full';\n renderMode?: 'brief' | 'json' | 'pretty';\n sessionId?: string;\n conversationId?: string;\n startupSignals?: {\n changedPaths?: string[];\n reviewedArtifactRefs?: string[];\n branchName?: string;\n worktreeName?: string;\n };\n invocationPath?: 'session-start' | 'session-close' | 'manual-orient' | 'handshake' | 'unknown';\n } = {};\n if (task) orientArgs.task = task;\n if (scope) orientArgs.scope = scope;\n // WP-486 Slice 1 (FEAT-1371, TEN-2724): thread startup-signal envelope (mirrors CLI's\n // `pb orient --task`); `invocationPath`'s 'manual-orient' default applies ONLY to a\n // task-shaped orient (PR #369 review, Codex) — see CLI's identical fix + `kernel/telemetry/contextServed.ts`.\n if (startupSignals && Object.keys(startupSignals).length > 0) orientArgs.startupSignals = startupSignals;\n if (invocationPath) {\n orientArgs.invocationPath = invocationPath;\n } else if (task) {\n orientArgs.invocationPath = 'manual-orient';\n }\n // DEC-NEW: forward tier by key omission when no explicit/brief intent.\n if (callTier) orientArgs.tier = callTier;\n // WP-479 review fix (Codex): MCP is an agent surface (source=mcp) — declare renderMode='json'\n // explicitly so the gateway seam instruments this serve, and thread session/conversation ids.\n orientArgs.renderMode = 'json';\n if (agentSessionId) orientArgs.sessionId = agentSessionId;\n // getConversationId() is HTTP-safe (null in multi-session HTTP mode) — see client.ts.\n const orientConversationId = getConversationId();\n if (orientConversationId) orientArgs.conversationId = orientConversationId;\n // `MCPOrientView.priorSessions: PriorSession[]` (planned-work.ts) declares a `[key: string]:\n // unknown` index signature the server's real element type lacks — cast at the boundary (PR #395, Lane C S3b).\n orientView = (await kernelQuery<GatewayRouteReturnByName<\"chain.getOrientView\">>(\"chain.getOrientView\", orientArgs)) as unknown as MCPOrientView;\n } catch { orientFetchFailed = true; /* rest of the tool degrades gracefully; rituals-line rendering below still needs to know */ }\n\n // WP-480 S3 (FEAT-1360): consume the server's resolution (getOrientView owns the payload) —\n // null-guarded like retrievalMiss for old deploys. Fallback: the caller's explicit tier is\n // still client-known input; else 'standard' / false — honestly degraded, never re-derived.\n const resolvedTier: 'summary' | 'standard' | 'full' =\n orientView?.resolvedTier ?? callTier ?? 'standard';\n const taskMeaningful: boolean = orientView?.taskMeaningful ?? false;\n\n // WP-436 S2: fetch Axis 2 vocabulary context for label resolution (PAT-230, DEC-1021).\n // Non-critical — if fetch fails, resolver falls back to canonicalKey literals.\n let vocabCtx: WorkspaceVocabCtx | undefined;\n try {\n type VocabResult = { collectionLabels?: Record<string, unknown>; collectionDefaults?: Record<string, unknown> };\n const vocab = await kernelQuery<GatewayRouteReturnByName<\"chain.getVocabulary\">>(\"chain.getVocabulary\", {});\n if (vocab?.collectionLabels || vocab?.collectionDefaults) {\n vocabCtx = {\n ...(vocab.collectionLabels ? { collectionLabels: vocab.collectionLabels as WorkspaceVocabCtx['collectionLabels'] } : {}),\n ...(vocab.collectionDefaults ? { collectionDefaults: vocab.collectionDefaults as WorkspaceVocabCtx['collectionDefaults'] } : {}),\n };\n }\n } catch { /* fail-open — vocab labels are advisory */ }\n\n if (orientView) {\n priorSessions = orientView.priorSessions ?? [];\n recoveryBlock = orientView.recoveryBlock ?? null;\n }\n const hasTaskGrounding = Boolean(task && (orientView?.taskContext?.context?.length ?? 0) > 0);\n\n // WP-306 S3: Emit write_back_hint_served event (STD-155)\n if (wsCtx && hasTaskGrounding && orientView?.writeBackHints) {\n const hints = Array.isArray(orientView.writeBackHints) ? orientView.writeBackHints : [];\n if (hints.length > 0) {\n trackWriteBackHintServed(wsCtx.workspaceId, {\n hint_count: hints.length,\n has_task: !!task,\n });\n }\n }\n\n let openTensions: any[] = [];\n try {\n const tensions = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"tensions\" });\n openTensions = (tensions ?? []).filter((e: { workflowStatus?: string }) => e.workflowStatus === \"open\");\n } catch { /* non-critical */ }\n\n let allCollections: CollectionDocFields[] = [];\n try {\n allCollections = (await kernelQuery<CollectionDocFields[]>(\"chain.listCollections\")) ?? [];\n } catch { /* non-critical — doc-completeness section is optional */ }\n\n let readiness: any = null;\n try {\n readiness = await kernelQuery<GatewayRouteReturnByName<\"chain.workspaceReadiness\">>(\"chain.workspaceReadiness\");\n } catch (e: unknown) {\n errors.push(`Readiness: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n // BET-76 safety net: if workspace is blank, redirect to the start tool's project scan flow.\n if (readiness?.stage === \"blank\") {\n const scanLines = [\n `# Welcome to ${wsCtx?.workspaceName ?? \"your workspace\"}`,\n \"\",\n \"Your workspace is fresh — let's set it up.\",\n \"\",\n \"**Recommended:** call the `start` tool instead of `orient` for the best first-run experience.\",\n \"It will guide you through setting up your workspace — you can tell me about your product, scan your codebase, or use a preset.\",\n \"\",\n \"Or tell me about your product and I'll start capturing knowledge directly.\",\n ];\n scanLines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed || orientView?.fetchFailed === true })); // D1 residue fix\n\n // Blank workspaces still route into guided setup; mark oriented so start can proceed smoothly.\n let oriented = false;\n let orientationStatus: \"complete\" | \"failed\" | \"no_session\" = \"no_session\";\n if (agentSessionId) {\n try {\n await kernelCall<GatewayRouteReturnByName<\"agent.markOriented\">>(\"agent.markOriented\", { sessionId: agentSessionId });\n setSessionOriented(true);\n oriented = true;\n orientationStatus = \"complete\";\n } catch {\n orientationStatus = \"failed\";\n }\n }\n\n const blankResult = {\n content: [{ type: \"text\" as const, text: scanLines.join(\"\\n\") }],\n structuredContent: success(\n \"Workspace is blank. Use `orient action=start` for guided setup.\",\n { stage: \"blank\", readinessScore: readiness?.score ?? 0, oriented, orientationStatus, redirectHint: \"Use `orient action=start` for the full guided setup experience.\" },\n [{ tool: \"orient\", description: \"Guided workspace setup\", parameters: { action: \"start\" } }],\n ),\n };\n // WP-376 α.3: blank workspaces don't run the truncatable orient view; treat as not truncated.\n reportOrientWrapperBytes(blankResult, false, resolvedTier, taskMeaningful);\n return blankResult;\n }\n\n const lines: string[] = [];\n const isLowReadiness = readiness && readiness.score < 50;\n\n // --- Identity ---\n if (wsCtx) {\n lines.push(`# ${wsCtx.workspaceName}`);\n lines.push(`_Workspace \\`${wsCtx.workspaceSlug}\\` — Product Brain is healthy._`);\n } else {\n lines.push(\"# Workspace\");\n lines.push(\"_Could not resolve workspace._\");\n }\n lines.push(\"\");\n lines.push(...taskGroundingWarningLines(task, hasTaskGrounding));\n const retrievalMissLines = orientView?.retrievalMiss\n ? formatRetrievalMissLines(\n orientView.retrievalMiss,\n domainDetailFromRetrieval(orientView.startup?.domainRetrieval),\n )\n : [];\n if (retrievalMissLines.length > 0) {\n lines.push(...retrievalMissLines);\n lines.push(\"\");\n }\n\n // --- Brief mode: compact output only ---\n if (mode === \"brief\") {\n const briefStage = readiness?.stage ?? (readiness?.score != null ? (readiness.score < 50 ? \"seeded\" : \"grounded\") : \"unknown\");\n lines.push(`Brain stage: ${briefStage}`);\n if (orientView?.strategicContext) {\n const sc = orientView.strategicContext;\n if (sc.vision) lines.push(`Vision: ${sc.vision}`);\n if (sc.purpose) lines.push(`Purpose: ${sc.purpose}`);\n if (sc.productAreaCount != null && sc.productAreaCount > 0) {\n lines.push(`Product areas (${sc.productAreaCount}): ${(sc.productAreas ?? []).join(\", \")}`);\n }\n if (sc.playingFieldCount != null && sc.playingFieldCount > 0) {\n lines.push(`Playing field (${sc.playingFieldCount}): ${(sc.playingField ?? []).join(\", \")}`);\n }\n // WP-436 S2: resolve via vocab resolver (PAT-230, DEC-1021 Axis 2).\n const wpPlural = getCollectionLabel('work_package', 'plural', vocabCtx);\n lines.push(`${sc.activeBetCount} active ${wpPlural}, ${sc.activeTensionCount} tension(s).`);\n }\n // WP-622 follow-up (Copilot review PR #601/#603): brief mode never carried the strategy floor; filtered defensively — a malformed row would otherwise throw or render \"undefined\".\n const briefStrategyHighlights = (orientView?.strategyHighlights ?? []).filter((e: any) => e != null && typeof e.name === \"string\" && e.name.length > 0);\n if (briefStrategyHighlights.length > 0) {\n lines.push(`Strategy: ${briefStrategyHighlights.map((e: any) => e.name + (typeof e.preview === \"string\" && e.preview ? ` — ${e.preview}` : \"\")).join(\" | \")}`);\n }\n if (orientView?.taskContext && orientView.taskContext.context.length > 0) {\n lines.push(`Task context: ${orientView.taskContext.totalFound} relevant entries (${orientView.taskContext.confidence} confidence).`);\n // STD-219 §4 (DEC-1147): announce a grounding stub even in brief mode.\n if (orientView.taskContext.isGroundingStub && orientView.taskContext.groundingNote) {\n lines.push(`⚠️ ${orientView.taskContext.groundingNote}`);\n }\n }\n // WP-465 slice ③ (§4.1): the server verdict is served in brief mode too —\n // one compact line; full librarian detail rides structuredContent.taskAlignment.\n if (orientView?.taskAlignment) {\n lines.push(`Task alignment: ${orientView.taskAlignment.verdict} — ${orientView.taskAlignment.wording.replace(/\\*\\*/g, \"\")}`);\n }\n const degradedLineBrief = buildDegradedPreloadsLine(orientView?.degradedPreloads); // WP-621 S1\n if (degradedLineBrief) lines.push(degradedLineBrief);\n // WP-582 B2 (FEAT-1404): direction/verdict-ask/spine one-liners.\n lines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed || orientView?.fetchFailed === true }));\n if (orientView?.startup?.domainRetrieval) {\n const retrieval = orientView.startup.domainRetrieval;\n const scopedTo = retrieval.resolvedDomainSlug ? ` (${retrieval.resolvedDomainSlug})` : \"\";\n lines.push(`Domain retrieval: ${retrieval.state}${scopedTo}`);\n if (retrieval.activeSource) lines.push(`Active source: ${retrieval.activeSource}`);\n if (retrieval.directRatifiedCount != null || retrieval.inheritedRatifiedCount != null || retrieval.orgFallbackCount != null) {\n lines.push(`Domain relation evidence: ${retrieval.directRatifiedCount ?? 0} direct, ${retrieval.inheritedRatifiedCount ?? 0} inherited, ${retrieval.orgFallbackCount ?? 0} org fallback`);\n }\n }\n if (orientView?.writeBackHints && orientView.writeBackHints.length > 0) {\n lines.push(\"\");\n lines.push(\"Write-back hints (what to capture this session):\");\n for (const h of orientView.writeBackHints) {\n lines.push(` ${h.collectionSlug}: ${h.hint}`);\n }\n }\n const briefActiveWps = orientView?.activeWorkPackages ?? [];\n if (briefActiveWps.length > 0) {\n for (const e of briefActiveWps) {\n const tensions = e.linkedTensions;\n const tensionPart = tensions?.length\n ? ` — ${tensions.map((t) => `${t.entryId ?? t.name} (${t.severity ?? \"—\"})`).join(\", \")}`\n : \"\";\n const originPart = e.origin ? ` (origin: ${e.origin})` : \"\";\n lines.push(`- \\`${e.entryId ?? e._id}\\` ${e.name}${originPart}${tensionPart}${coherencyCheckTag(e.coherencyCheckStatus)}`);\n }\n }\n // BET-240 S5: trust metrics in brief mode\n if (orientView?.trustMetrics) {\n const tm = orientView.trustMetrics;\n if (tm.unverified > 0 || tm.verified > 0) {\n const capNote = tm.scannedCap ? \"+\" : \"\";\n lines.push(`Trust: ${tm.verified} verified, ${tm.unverified} unverified, ${tm.noStatus} no-status (${tm.total}${capNote} scanned).`);\n }\n }\n // WP-560/TEN-2532 post-merge review (Codex P1): shape-advisory summary in brief mode\n const briefShapeLine = formatShapeAdvisorySummaryLine(orientView?.shapeAdvisorySummary);\n if (briefShapeLine) lines.push(briefShapeLine);\n // BET-126: compact What needs attention in brief mode\n const briefWna = formatWhatNeedsAttentionBrief(orientView?.whatNeedsAttention);\n if (briefWna.length > 0) {\n lines.push(\"\");\n lines.push(...briefWna);\n }\n // FEAT-62: surface top gap in brief mode\n const briefGaps: ReadinessGap[] = readiness?.gaps ?? [];\n if (briefGaps.length > 0) {\n const oneLiner = formatGapOneLiner(briefGaps[0]);\n if (oneLiner) lines.push(oneLiner);\n }\n const briefClassificationGaps = briefGaps.filter((g) => g.id?.startsWith?.(PURPOSE_GAP_PREFIX));\n if (briefClassificationGaps.length > 0) {\n lines.push(`${briefClassificationGaps.length} collection(s) with weak purpose — classification may be inaccurate.`);\n }\n if (recoveryBlock) {\n lines.push(\"\");\n lines.push(...formatRecoveryBlock(recoveryBlock));\n } else if (priorSessions.length > 0) {\n const last = priorSessions[0];\n const date = last.startedAt ? new Date(last.startedAt).toISOString().split(\"T\")[0] : \"unknown\";\n const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;\n const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;\n lines.push(`Last session (${date}): ${created} created, ${modified} modified`);\n }\n let coherenceSnapshot: CoherenceSnapshot | undefined;\n const coherence = await buildCoherenceSection();\n if (coherence) {\n lines.push(\"\");\n lines.push(...coherence.lines);\n coherenceSnapshot = coherence.snapshot ?? undefined;\n }\n\n if (allCollections.length > 0) {\n const docCompleteness = buildDocCompletenessSection(allCollections);\n if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {\n lines.push(...docCompleteness.lines);\n }\n }\n\n if (orientView) {\n lines.push(\"\");\n if (task) {\n const mapGovernanceEntry = (e: any) => ({\n entryId: e.entryId,\n name: e.name,\n description: typeof e.preview === \"string\" ? e.preview : undefined,\n tier: typeof e.tier === \"number\" ? e.tier : undefined,\n // Phase 4 (DEC-1141): thread provenance fields to buildOperatingProtocol.\n provenance: e.provenance as 'authoritative' | 'provisional' | 'floor' | undefined,\n anchoredBy: typeof e.anchoredBy === \"string\" ? e.anchoredBy : undefined,\n });\n const gov = orientView.governance ?? { principles: [], standards: [], businessRules: [] };\n lines.push(...buildOperatingProtocol({\n principles: (gov.principles ?? []).map(mapGovernanceEntry),\n standards: (gov.standards ?? []).map(mapGovernanceEntry),\n businessRules: (gov.businessRules ?? []).map(mapGovernanceEntry),\n }, task));\n } else {\n lines.push(...buildOperatingProtocol());\n }\n }\n\n let orientationStatus: \"complete\" | \"task_required\" | \"failed\" | \"no_session\" = \"no_session\";\n if (agentSessionId && hasTaskGrounding) {\n const orientedOk = await markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapshot);\n if (orientedOk) {\n orientationStatus = \"complete\";\n lines.push(\"---\");\n lines.push(`Orientation complete. Session ${agentSessionId}. Write tools available.`);\n } else {\n orientationStatus = \"failed\";\n lines.push(\"---\");\n lines.push(\"_Warning: Could not mark session as oriented. Write tools may be restricted._\");\n }\n } else if (agentSessionId) {\n orientationStatus = \"task_required\";\n lines.push(\"---\");\n lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task=\"describe the work\"`.');\n } else {\n lines.push(\"---\");\n lines.push(\"_No active agent session. Call `session action=start` to begin._\");\n }\n // BET-β S3b: prefer _budget.truncated; fall back to _truncated for backward compat.\n const briefTruncated = orientView?._budget?.truncated ?? orientView?._truncated ?? false;\n if (briefTruncated) {\n const reasons = orientView?._budget?.truncationReasons;\n lines.push(\"\");\n if (reasons && reasons.length > 0) {\n lines.push(`_Context truncated to fit tier budget: ${reasons.join(', ')}. Use tier=full for complete payload._`);\n } else {\n lines.push(\"_Context truncated to fit tier budget. Use tier=full for complete payload._\");\n }\n }\n if (errors.length > 0) {\n lines.push(\"\");\n for (const err of errors) lines.push(`- ${err}`);\n }\n const briefResult = {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Oriented (brief). Stage: ${readiness?.stage ?? \"unknown\"}.`,\n {\n mode: \"brief\",\n stage: readiness?.stage ?? \"unknown\",\n oriented: hasTaskGrounding ? isSessionOriented() : false,\n sessionId: agentSessionId,\n taskGroundingStatus: hasTaskGrounding ? \"task_scoped\" : task ? \"missing_task_context\" : \"workspace_only\",\n taskGroundingRequired: !hasTaskGrounding,\n // STD-219 §4 (DEC-1147): machine-readable stub flag for agent consumers.\n ...(orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {}),\n // WP-465 slice ③ (§4.1): served verbatim — identical on CLI and MCP.\n ...(orientView?.taskAlignment ? { taskAlignment: orientView.taskAlignment } : {}),\n ...(orientView?.degradedPreloads?.length ? { degradedPreloads: orientView.degradedPreloads } : {}), // WP-621 S1\n // WP-582 B2 round 1 (Codex P2 review, PR #532, T1): omit when `undefined` (old deploy, never served); keep explicit `null` for the documented no-row arm — the two states must stay distinguishable to consumers.\n ...(orientView?.directionLine !== undefined ? { directionLine: orientView.directionLine } : {}),\n ...(orientView?.verdictAskLine !== undefined ? { verdictAskLine: orientView.verdictAskLine } : {}),\n ...(orientView?.spineLine !== undefined ? { spineLine: orientView.spineLine } : {}),\n ...(orientView?.atCapLine !== undefined ? { atCapLine: orientView.atCapLine } : {}), // PR #538 late review (P2)\n ...(orientView?.fetchFailed !== undefined ? { fetchFailed: orientView.fetchFailed } : {}), // PR #539 review fix\n // RCRT miss-alarm: machine-readable verdict for structuredContent consumers (parity with the rendered prose alarm).\n ...(orientView?.retrievalMiss ? { retrievalMiss: orientView.retrievalMiss } : {}),\n orientationStatus,\n nextStep: hasTaskGrounding ? undefined : 'Run `orient task=\"describe the work\"` before substantive work.',\n ...(orientView?._budget ? { _budget: orientView._budget } : {}),\n // WP-560/TEN-2532 post-merge review (Codex P2): the rendered shape-advisory\n // line must reach structuredContent too, not just the text — never a\n // text-only fact a machine consumer can't see.\n ...(orientView?.shapeAdvisorySummary ? { shapeAdvisorySummary: orientView.shapeAdvisorySummary } : {}),\n // WP-622 follow-up (Copilot review PR #601, post-merge): brief structuredContent parity with full mode.\n ...(orientView?.strategyHighlights?.length ? { strategyHighlights: orientView.strategyHighlights } : {}),\n },\n ),\n };\n // WP-376 α.3: surface-side bytes — full assembled MCP tool output.\n reportOrientWrapperBytes(briefResult, briefTruncated, resolvedTier, taskMeaningful);\n return briefResult;\n }\n\n const orientStage: string = readiness?.stage ?? \"seeded\";\n\n // --- Full mode: New vs neglected framing ---\n if (isLowReadiness && wsCtx?.createdAt) {\n const ageDays = Math.floor((Date.now() - wsCtx.createdAt) / (1000 * 60 * 60 * 24));\n if (ageDays >= 30) {\n lines.push(`Your workspace has been around for ${ageDays} days and is still at the **${orientStage}** stage.`);\n lines.push(\"Let's close the gaps — or if the current structure doesn't fit, we can reshape it.\");\n lines.push(\"\");\n }\n }\n // --- Single next action for low-readiness (FEAT-62: conversational gap prompts) ---\n let fullCoherenceSnapshot: CoherenceSnapshot | undefined;\n if (isLowReadiness) {\n // PRRT_kwDORS4ils6X7A9I: taskless Strategic Context (S1/TEN-3058) was unreachable below score 50.\n const scLR = !task ? orientView?.strategicContext : undefined;\n const scLRLines = scLR ? [scLR.vision && `**Vision:** ${scLR.vision}`, scLR.purpose && `**Purpose:** ${scLR.purpose}`].filter((l): l is string => Boolean(l)) : [];\n if (scLRLines.length > 0) lines.push(\"## Strategic Context\", ...scLRLines, \"\");\n const captureBehaviorNote =\n (readiness?.governanceMode ?? wsCtx?.governanceMode ?? \"open\") === \"open\"\n ? \"_In Open mode, captures are accepted automatically unless you ask me to keep them as drafts._\"\n : \"_Everything stays as a draft until you confirm._\";\n\n const gaps: ReadinessGap[] = readiness.gaps ?? [];\n if (gaps.length > 0) {\n const gapCtx: GapContext = {\n stage: orientStage,\n passedChecks: readiness.passedChecks ?? 0,\n totalChecks: readiness.totalChecks ?? 0,\n score: readiness.score ?? 0,\n };\n\n lines.push(formatTopGapPrompt(gaps[0], gaps.length - 1, gapCtx));\n lines.push(\"\");\n lines.push(captureBehaviorNote);\n lines.push(\"\");\n\n const remainingGaps = gaps.length - 1;\n if (remainingGaps > 0 || openTensions.length > 0) {\n const parts: string[] = [];\n if (remainingGaps > 0) parts.push(`${remainingGaps} more area${remainingGaps === 1 ? \"\" : \"s\"} to cover`);\n if (openTensions.length > 0) parts.push(`${openTensions.length} open tension${openTensions.length === 1 ? \"\" : \"s\"}`);\n lines.push(`_${parts.join(\" and \")} — ask for full status to see everything._`);\n lines.push(\"\");\n }\n }\n\n lines.push(\"_Need a collection that doesn't exist yet? Just ask — I'll set it up._\");\n lines.push(\"\");\n } else if (readiness) {\n const fmt = (e: any) => {\n const type = e.canonicalKey ?? 'generic';\n const stratum = e.stratum ?? '?';\n // BET-222 E3: show confidence + review overdue for decisions\n const confidencePart = e.confidence ? ` [confidence: ${e.confidence}]` : '';\n const reviewOverdue = e.reviewAt && new Date(e.reviewAt).getTime() < Date.now();\n const overduePart = reviewOverdue ? ' [review overdue]' : '';\n // BET-240 S0: surface origin for trust visibility\n const originPart = e.origin ? ` (origin: ${e.origin})` : '';\n // Phase 4 (DEC-1141): prefix provenance marker and append anchoredBy compactly.\n const mark = provenanceMark(e.provenance);\n const anchorSuffix = e.anchoredBy ? ` (${e.anchoredBy})` : '';\n // WP-485 Slice 1 review fix (Codex P2, PR #367): only activeWorkPackages entries carry\n // coherencyCheckStatus — undefined (empty string) for every other entry type fmt() renders.\n const coherencyPart = coherencyCheckTag(e.coherencyCheckStatus);\n return `- ${mark}\\`${e.entryId ?? e._id}\\` [${type} · ${stratum}] ${e.name}${anchorSuffix}${originPart}${confidencePart}${overduePart}${coherencyPart}`;\n };\n\n // BET-99 / FEAT-182: Codebase coherence check (runs once, shared across branches)\n const fullCoherence = await buildCoherenceSection();\n if (fullCoherence) {\n fullCoherenceSnapshot = fullCoherence.snapshot ?? undefined;\n }\n\n if (task) {\n // ── FULL LAYER: task provided → rich, task-scoped context ──────────\n lines.push(`**Brain stage: ${orientStage}.** Working on: **${task}**`);\n lines.push(\"\");\n\n if (orientView?.strategicContext) {\n const sc = orientView.strategicContext;\n lines.push(\"## Strategic Context\");\n if (sc.vision) lines.push(`**Vision:** ${sc.vision}`);\n if (sc.purpose) lines.push(`**Purpose:** ${sc.purpose}`);\n if (sc.productAreaCount != null && sc.productAreaCount > 0) lines.push(`**Product areas (${sc.productAreaCount}):** ${(sc.productAreas ?? []).join(\", \")}`);\n if (sc.playingFieldCount != null && sc.playingFieldCount > 0) lines.push(`**Playing field (${sc.playingFieldCount}):** ${(sc.playingField ?? []).join(\", \")}`);\n // WP-436 S4: currentWorkPackage is the canonical field (legacy currentBet dropped).\n const currentWP = sc.currentWorkPackage;\n const wpSingularFull = getCollectionLabel('work_package', 'singular', vocabCtx);\n const wpPluralFull = getCollectionLabel('work_package', 'plural', vocabCtx);\n const betLine = currentWP\n ? `**Current ${wpSingularFull}:** ${currentWP}. ${sc.activeBetCount} active ${wpPluralFull}.`\n : `No active ${wpPluralFull}.`;\n lines.push(`${betLine} ${sc.activeTensionCount} open tension(s).`);\n lines.push(\"\");\n }\n\n if (orientView?.continuingFrom && orientView.continuingFrom.length > 0) {\n lines.push(\"## Continuing from\");\n lines.push(\"_Prior-session entries most relevant to your task._\");\n lines.push(\"\");\n for (const e of orientView.continuingFrom) {\n const id = e.entryId ?? e.name;\n const type = e.canonicalKey ?? \"generic\";\n const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : \"\";\n lines.push(`- \\`${id}\\` (score ${e.score}) [${type}]${coll} — ${e.name}`);\n if (e.reasoning) lines.push(` _${e.reasoning}_`);\n if (\"primer\" in e && typeof e.primer === \"string\" && e.primer.length > 0) {\n const PRIMER_MAX = 1200;\n const primerText = e.primer.length > PRIMER_MAX\n ? e.primer.slice(0, PRIMER_MAX) + \"\\n… (truncated — use entries action=get for full primer)\"\n : e.primer;\n lines.push(\"\");\n lines.push(\" **Primer (paste when starting implementation):**\");\n lines.push(\" ```\");\n for (const line of primerText.split(\"\\n\")) lines.push(\" \" + line);\n lines.push(\" ```\");\n lines.push(\"\");\n }\n }\n lines.push(\"\");\n }\n\n if (orientView?.lastSessionTouched && orientView.lastSessionTouched.length > 0) {\n lines.push(\"## Last session touched\");\n lines.push(\"_Entries created or modified in your most recent session._\");\n lines.push(\"\");\n for (const e of orientView.lastSessionTouched) {\n const id = e.entryId ?? e.name;\n const type = e.canonicalKey ?? \"generic\";\n const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : \"\";\n lines.push(`- \\`${id}\\` [${type}]${coll} — ${e.name}`);\n if (\"primer\" in e && typeof e.primer === \"string\" && e.primer.length > 0) {\n const PRIMER_MAX = 1200;\n const primerText = e.primer.length > PRIMER_MAX\n ? e.primer.slice(0, PRIMER_MAX) + \"\\n… (truncated — use entries action=get for full primer)\"\n : e.primer;\n lines.push(\"\");\n lines.push(\" **Primer:**\");\n lines.push(\" ```\");\n for (const line of primerText.split(\"\\n\")) lines.push(\" \" + line);\n lines.push(\" ```\");\n lines.push(\"\");\n }\n }\n lines.push(\"\");\n }\n\n if (orientView?.taskContext && orientView.taskContext.context.length > 0) {\n const tc = orientView.taskContext;\n lines.push(\"## Task Context\");\n // STD-219 §4 (DEC-1147): announce a grounding stub so the agent knows it is\n // operating lean and must fetch full context before consequential work.\n if (tc.isGroundingStub && tc.groundingNote) {\n lines.push(`> ⚠️ ${tc.groundingNote}`);\n lines.push(\"\");\n }\n if (orientView.startup?.domainRetrieval) {\n const retrieval = orientView.startup.domainRetrieval;\n const scopedTo = retrieval.resolvedDomainSlug ? ` (${retrieval.resolvedDomainSlug})` : \"\";\n lines.push(`_Domain retrieval: ${retrieval.state}${scopedTo}_`);\n if (retrieval.activeSource) lines.push(`_Active source: ${retrieval.activeSource}_`);\n lines.push(\"\");\n }\n lines.push(`_Task-scoped entries (${tc.confidence} confidence, ${tc.totalFound} relevant)`);\n lines.push(\"\");\n for (const e of tc.context) {\n const id = e.entryId ?? e.name;\n const coll = e.collectionSlug ? ` [${e.collectionSlug}]` : \"\";\n const originTag = e.origin ? ` (origin: ${e.origin})` : \"\";\n lines.push(`- \\`${id}\\` (score ${e.score})${coll}${originTag}${e.name !== id ? ` — ${e.name}` : \"\"}`);\n // NOTE (typecheck audit): taskContext.context entries never carry a `preview` field\n // on the wire (orientView.ts) — a dead `if (e.preview)` branch here always\n // evaluated false; removed rather than kept as unreachable code.\n }\n lines.push(\"\");\n }\n\n if (orientView?.taskContext?.constellationEntries && orientView.taskContext.constellationEntries.length > 0) {\n // ConstellationEntryItem requires non-null entryId/collectionSlug; the gateway can serve null\n // for either — fall back the same way the rest of this file does for nullable entryIds; a\n // null collectionSlug fails to match formatBetConstellationLines' known buckets either way.\n const constellationEntries: ConstellationEntryItem[] = orientView.taskContext.constellationEntries.map((e) => ({\n entryId: e.entryId ?? e.name,\n name: e.name,\n collectionSlug: e.collectionSlug ?? \"unclassified\",\n canonicalKey: e.canonicalKey,\n }));\n lines.push(...formatBetConstellationLines(\n constellationEntries,\n orientView.taskContext.constellationBetName,\n ));\n }\n\n if (orientView?.writeBackHints && orientView.writeBackHints.length > 0) {\n lines.push(\"\");\n lines.push(\"## Write-Back Hints\");\n lines.push(\"_What to capture this session (derived from task context):_\");\n lines.push(\"\");\n for (const h of orientView.writeBackHints) {\n lines.push(`- **${h.collectionSlug}**: ${h.hint}`);\n }\n lines.push(\"\");\n }\n\n if (orientView) {\n // WP-465 slice ③ (§4.1): render the SERVER-computed verdict — the local\n // matcher is gone; the resolver lives behind chain.getOrientView so the\n // pb CLI and MCP serve the identical taskAlignment.\n lines.push(...buildTaskAlignmentLines(orientView.taskAlignment));\n const degradedLineFull = buildDegradedPreloadsLine(orientView.degradedPreloads); // WP-621 S1\n if (degradedLineFull) lines.push(degradedLineFull);\n // WP-582 B2 (FEAT-1404): direction/verdict-ask/spine one-liners.\n lines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed || orientView?.fetchFailed === true }));\n // BET-126: Initiative Status, Workstream Health, What Needs Attention (full, with task)\n lines.push(...formatInitiativeStatusLines(orientView.initiativeStatus));\n lines.push(...formatWorkstreamHealthLines(orientView.workstreamHealth));\n lines.push(...formatWhatNeedsAttentionLines(orientView.whatNeedsAttention));\n // BET-240 S5: trust metrics (full, with task)\n if (orientView.trustMetrics) {\n const tm = orientView.trustMetrics;\n if (tm.verified > 0 || tm.unverified > 0) {\n const capNote = tm.scannedCap ? \" (capped at 500)\" : \"\";\n lines.push(\"## Trust metrics\");\n lines.push(`_Entry verification status across workspace${capNote}._`);\n lines.push(\"\");\n lines.push(`- **Verified:** ${tm.verified}`);\n lines.push(`- **Unverified:** ${tm.unverified}`);\n lines.push(`- **No status (pre-BET-240):** ${tm.noStatus}`);\n lines.push(`- **Total scanned:** ${tm.total}`);\n lines.push(\"\");\n }\n }\n // WP-560/TEN-2532 post-merge review (Codex P1): shape-advisory summary (full, with task)\n const taskShapeLine = formatShapeAdvisorySummaryLine(orientView.shapeAdvisorySummary);\n if (taskShapeLine) lines.push(taskShapeLine, \"\");\n }\n\n if (fullCoherence) {\n lines.push(...fullCoherence.lines);\n }\n\n if (allCollections.length > 0) {\n const docCompleteness = buildDocCompletenessSection(allCollections);\n if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {\n lines.push(...docCompleteness.lines);\n }\n }\n\n if (orientView) {\n const fullActiveWps = orientView.activeWorkPackages ?? [];\n if (fullActiveWps.length > 0) {\n lines.push(\"## Active work packages — current scope\");\n lines.push(\"_Work outside these work packages requires explicit user confirmation._\");\n lines.push(\"\");\n for (const e of fullActiveWps) {\n lines.push(fmt(e));\n const tensions = e.linkedTensions;\n if (tensions?.length) {\n const tensionLines = tensions.map((t) => {\n const meta = [t.severity, t.priority].filter(Boolean).join(\", \");\n return `\\`${t.entryId ?? t.name}\\` (${t.name}${meta ? `, ${meta}` : \"\"})`;\n });\n lines.push(` Tensions: ${tensionLines.join(\"; \")}`);\n }\n }\n lines.push(\"\");\n }\n const fullActiveGoals = orientView.activeGoals ?? [];\n if (fullActiveGoals.length > 0) {\n lines.push(\"## Active goals\");\n fullActiveGoals.forEach((e) => lines.push(fmt(e)));\n lines.push(\"\");\n }\n const fullStrategyHighlights = orientView.strategyHighlights ?? [];\n if (fullStrategyHighlights.length > 0) {\n lines.push(\"## Strategy highlights\");\n lines.push(\"_One-sentence strategy, positioning, moat, business model, GTM — high-level strategic context._\");\n lines.push(\"\");\n // WP-622 (Copilot review PR #601 P2): fmt() alone never carries preview — append it here rather than widen fmt() for every other section.\n fullStrategyHighlights.forEach((e: any) => lines.push(fmt(e) + (e.preview ? ` — ${e.preview}` : \"\")));\n lines.push(\"\");\n }\n const fullPlayingField = orientView.playingField ?? [];\n if (fullPlayingField.length > 0) {\n lines.push(\"## Playing field\");\n lines.push(\"_Products and opportunities in the strategic landscape._\");\n lines.push(\"\");\n fullPlayingField.forEach((e) => lines.push(fmt(e)));\n lines.push(\"\");\n }\n const fullRecentDecisions = orientView.recentDecisions ?? [];\n if (fullRecentDecisions.length > 0) {\n lines.push(\"## Recent decisions\");\n fullRecentDecisions.forEach((e) => lines.push(fmt(e)));\n lines.push(\"\");\n }\n const fullRecentlySuperseded = orientView.recentlySuperseded ?? [];\n if (fullRecentlySuperseded.length > 0) {\n lines.push(\"## Recently superseded\");\n fullRecentlySuperseded.forEach((e) => lines.push(fmt(e)));\n lines.push(\"\");\n }\n const fullStaleEntries = orientView.staleEntries ?? [];\n if (fullStaleEntries.length > 0) {\n lines.push(\"## Needs confirmation\");\n lines.push(`_Domain stratum entries not confirmed in ${orientView.stalenessThresholdDays} days._`);\n fullStaleEntries.forEach((e) => lines.push(fmt(e)));\n lines.push(\"\");\n }\n const fullArchitectureNotes = orientView.architectureNotes ?? [];\n if (fullArchitectureNotes.length > 0) {\n lines.push(\"## Architecture notes\");\n fullArchitectureNotes.forEach((e) => lines.push(fmt(e)));\n lines.push(\"\");\n }\n\n const mapGovernanceEntry = (e: any) => ({\n entryId: e.entryId,\n name: e.name,\n description: typeof e.preview === \"string\" ? e.preview : undefined,\n tier: typeof e.tier === \"number\" ? e.tier : undefined,\n // Phase 4 (DEC-1141): thread provenance fields to buildOperatingProtocol.\n provenance: e.provenance as 'authoritative' | 'provisional' | 'floor' | undefined,\n anchoredBy: typeof e.anchoredBy === \"string\" ? e.anchoredBy : undefined,\n });\n const gov = orientView.governance ?? { principles: [], standards: [], businessRules: [] };\n lines.push(...buildOperatingProtocol({\n principles: (gov.principles ?? []).map(mapGovernanceEntry),\n standards: (gov.standards ?? []).map(mapGovernanceEntry),\n businessRules: (gov.businessRules ?? []).map(mapGovernanceEntry),\n }, task));\n }\n\n let allEntries: any[] = [];\n try {\n allEntries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", {\n fields: [\"_id\", \"entryId\", \"name\", \"status\", \"workflowStatus\", \"collectionSlug\", \"stratum\", \"canonicalKey\"],\n }) ?? [];\n } catch { /* non-critical */ }\n\n const plannedWork = buildPlannedWork(allEntries);\n\n if (hasPlannedWork(plannedWork)) {\n lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));\n } else if (recoveryBlock) {\n lines.push(...formatRecoveryBlock(recoveryBlock));\n }\n } else {\n // ── COMPACT LAYER: no task → standup + Strategic Context (S1/TEN-3058) + OP (compact) + session continuity + CTA. Everything else loads on demand once a task is stated.\n lines.push(`**Brain stage: ${orientStage}.**`);\n lines.push(\"\");\n // S1 follow-up (TEN-3058, WP-634 TASK-41): stop gating Strategic Context on task presence — always populated, now server-bounded at every tier (verbatim, no capping here).\n const scNoTask = orientView?.strategicContext;\n const scNoTaskLines = scNoTask ? [scNoTask.vision && `**Vision:** ${scNoTask.vision}`, scNoTask.purpose && `**Purpose:** ${scNoTask.purpose}`].filter((l): l is string => Boolean(l)) : [];\n if (scNoTaskLines.length > 0) lines.push(\"## Strategic Context\", ...scNoTaskLines, \"\");\n // WP-582 B2 round 1 (PR #532, T13): buildRitualsSurfaceLines, same helper as the task branch (structuredContent already had it; the TEXT rendering was the gap).\n lines.push(...buildRitualsSurfaceLines(orientView, { fetchFailed: orientFetchFailed || orientView?.fetchFailed === true }));\n\n if (orientView?.activeWorkPackages?.length) {\n lines.push(\"## Active work packages — current scope\");\n lines.push(\"_Work outside these work packages requires explicit user confirmation._\");\n lines.push(\"\");\n for (const e of orientView.activeWorkPackages) {\n lines.push(fmt(e));\n }\n lines.push(\"\");\n }\n\n // BET-126: Initiative Status, Workstream Health, What Needs Attention (full, no task)\n lines.push(...formatInitiativeStatusLines(orientView?.initiativeStatus));\n lines.push(...formatWorkstreamHealthLines(orientView?.workstreamHealth));\n lines.push(...formatWhatNeedsAttentionLines(orientView?.whatNeedsAttention));\n\n // BET-240 S5: trust metrics (full, no task)\n if (orientView?.trustMetrics) {\n const tm = orientView.trustMetrics;\n if (tm.verified > 0 || tm.unverified > 0) {\n const capNote = tm.scannedCap ? \" (capped at 500)\" : \"\";\n lines.push(\"## Trust metrics\");\n lines.push(`_Entry verification status across workspace${capNote}._`);\n lines.push(\"\");\n lines.push(`- **Verified:** ${tm.verified}`);\n lines.push(`- **Unverified:** ${tm.unverified}`);\n lines.push(`- **No status (pre-BET-240):** ${tm.noStatus}`);\n lines.push(`- **Total scanned:** ${tm.total}`);\n lines.push(\"\");\n }\n }\n // WP-560/TEN-2532 post-merge review (Codex P1): shape-advisory summary (full, no task)\n const noTaskShapeLine = formatShapeAdvisorySummaryLine(orientView?.shapeAdvisorySummary);\n if (noTaskShapeLine) lines.push(noTaskShapeLine, \"\");\n\n lines.push(...buildOperatingProtocol());\n\n if (fullCoherence) {\n lines.push(...fullCoherence.lines);\n }\n\n if (allCollections.length > 0) {\n const docCompleteness = buildDocCompletenessSection(allCollections);\n if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {\n lines.push(...docCompleteness.lines);\n }\n }\n\n if (priorSessions.length > 0 && !recoveryBlock) {\n const last = priorSessions[0];\n const date = last.startedAt ? new Date(last.startedAt).toISOString().split(\"T\")[0] : \"unknown\";\n const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;\n const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;\n lines.push(`_Last session (${date}): ${created} created, ${modified} modified._`);\n lines.push(\"\");\n }\n\n if (recoveryBlock) {\n lines.push(...formatRecoveryBlock(recoveryBlock));\n }\n\n lines.push(\"**What are you working on?** Tell me and I'll load relevant governance and context.\");\n lines.push(\"\");\n }\n }\n\n // --- Classification gaps (INS-116) ---\n const classificationGaps = readiness?.gaps?.filter((g: { id?: string }) => g.id?.startsWith?.(PURPOSE_GAP_PREFIX)) ?? [];\n if (classificationGaps.length > 0) {\n lines.push(\"## Classification gaps\");\n lines.push(\"_Collections with weak purpose — entry classification may be inaccurate._\");\n lines.push(\"\");\n for (const g of classificationGaps) {\n lines.push(`- ${(g as { label?: string }).label ?? g.id?.replace?.(\"purpose-gap-\", \"\") ?? \"unknown\"}`);\n }\n lines.push(\"\");\n }\n\n if (errors.length > 0) {\n lines.push(\"## Errors\");\n for (const err of errors) lines.push(`- ${err}`);\n lines.push(\"\");\n }\n\n // --- Mark session as oriented ---\n let orientationStatus: \"complete\" | \"task_required\" | \"failed\" | \"no_session\" = \"no_session\";\n if (agentSessionId && hasTaskGrounding) {\n const orientedOk = await markOrientedWithSnapshotFallback(agentSessionId, fullCoherenceSnapshot);\n if (orientedOk) {\n orientationStatus = \"complete\";\n\n lines.push(\"---\");\n lines.push(`Orientation complete. Session ${agentSessionId}. Write tools available.`);\n } else {\n orientationStatus = \"failed\";\n lines.push(\"---\");\n lines.push(\"_Warning: Could not mark session as oriented. Write tools may be restricted._\");\n }\n\n // Record session signal: orient was called (implicit feedback for the intelligence kernel)\n try {\n await kernelMutation(\"chain.recordSessionSignal\", {\n sessionId: agentSessionId,\n signalType: \"immediate_context_load\",\n metadata: { source: \"orient\" },\n });\n } catch (err) {\n process.stderr.write(`[MCP] recordSessionSignal failed: ${(err as Error).message}\\n`);\n // Non-fatal: orient still succeeds; signal is for analytics\n }\n } else if (agentSessionId) {\n orientationStatus = \"task_required\";\n lines.push(\"---\");\n lines.push('Workspace orientation loaded. Write tools stay locked until you run `orient task=\"describe the work\"`.');\n } else {\n lines.push(\"---\");\n lines.push(\"_No active agent session. Call `session action=start` to begin a tracked session._\");\n }\n\n // BET-β S3b: prefer _budget.truncated; fall back to _truncated for backward compat.\n const fullTruncated = orientView?._budget?.truncated ?? orientView?._truncated ?? false;\n if (fullTruncated) {\n const reasons = orientView?._budget?.truncationReasons;\n lines.push(\"\");\n if (reasons && reasons.length > 0) {\n lines.push(`_Context truncated to fit tier budget: ${reasons.join(', ')}. Use tier=full for complete payload._`);\n } else {\n lines.push(\"_Context truncated to fit tier budget. Use tier=full for complete payload._\");\n }\n }\n\n const fullResult = {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Oriented (full). Stage: ${orientStage}. ${isLowReadiness ? \"Low readiness — gaps remain.\" : \"Ready.\"}`,\n {\n mode: \"full\",\n stage: orientStage,\n oriented: hasTaskGrounding ? isSessionOriented() : false,\n sessionId: agentSessionId,\n taskGroundingStatus: hasTaskGrounding ? \"task_scoped\" : task ? \"missing_task_context\" : \"workspace_only\",\n taskGroundingRequired: !hasTaskGrounding,\n // STD-219 §4 (DEC-1147): machine-readable stub flag for agent consumers.\n ...(orientView?.taskContext?.isGroundingStub ? { groundingStub: true } : {}),\n // WP-465 slice ③ (§4.1): served verbatim — identical on CLI and MCP.\n ...(orientView?.taskAlignment ? { taskAlignment: orientView.taskAlignment } : {}),\n ...(orientView?.degradedPreloads?.length ? { degradedPreloads: orientView.degradedPreloads } : {}), // WP-621 S1\n // WP-582 B2 round 1 (Codex P2 review, PR #532, T1): served verbatim ONLY when the\n // server actually sent the field — see the matching brief-mode comment above for the\n // undefined-vs-null distinction this preserves.\n ...(orientView?.directionLine !== undefined ? { directionLine: orientView.directionLine } : {}),\n ...(orientView?.verdictAskLine !== undefined ? { verdictAskLine: orientView.verdictAskLine } : {}),\n ...(orientView?.spineLine !== undefined ? { spineLine: orientView.spineLine } : {}),\n ...(orientView?.atCapLine !== undefined ? { atCapLine: orientView.atCapLine } : {}), // PR #538 late review (P2)\n ...(orientView?.fetchFailed !== undefined ? { fetchFailed: orientView.fetchFailed } : {}), // PR #539 review fix\n // RCRT miss-alarm: machine-readable verdict for structuredContent\n // consumers (parity with the rendered prose alarm).\n ...(orientView?.retrievalMiss ? { retrievalMiss: orientView.retrievalMiss } : {}),\n domainRetrieval: orientView?.startup?.domainRetrieval,\n orientationStatus,\n nextStep: hasTaskGrounding ? undefined : 'Run `orient task=\"describe the work\"` before substantive work.',\n ...(orientView?._budget ? { _budget: orientView._budget } : {}),\n // WP-560/TEN-2532 post-merge review (Codex P2): the rendered shape-advisory\n // line must reach structuredContent too, not just the text.\n ...(orientView?.shapeAdvisorySummary ? { shapeAdvisorySummary: orientView.shapeAdvisorySummary } : {}),\n // WP-622 (Copilot review PR #601 P2): was dropped from the full-mode machine payload.\n ...(orientView?.strategyHighlights?.length ? { strategyHighlights: orientView.strategyHighlights } : {}),\n },\n ),\n };\n // WP-376 α.3: surface-side bytes — full assembled MCP tool output.\n reportOrientWrapperBytes(fullResult, fullTruncated, resolvedTier, taskMeaningful);\n return fullResult;\n}\n","/**\n * Shared \"planned work\" query and formatting for orient/start.\n *\n * Surfaces uncommitted drafts, in-progress features/decisions, and\n * open tensions as a single \"Continue from\" section with a concrete CTA.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelQuery } from \"../client.js\";\n\n/** Loosely-typed session record returned by agent.recentSessions. */\nexport interface PriorSession {\n startedAt?: string | number;\n entriesCreated?: string[] | number;\n entriesModified?: string[] | number;\n [key: string]: unknown;\n}\n\nexport interface PlannedWork {\n uncommittedDrafts: Array<{ name: string; collection: string }>;\n inProgressEntries: Array<{ name: string; collection: string; entryId: string }>;\n openTensions: Array<{ name: string; entryId: string }>;\n}\n\nexport function buildPlannedWork(allEntries: any[]): PlannedWork {\n const result: PlannedWork = {\n uncommittedDrafts: [],\n inProgressEntries: [],\n openTensions: [],\n };\n\n for (const entry of allEntries) {\n if (entry.stratum === 'system') continue;\n\n const collection = entry.collectionSlug ?? entry.collection ?? \"unknown\";\n\n if (entry.status === \"draft\") {\n result.uncommittedDrafts.push({ name: entry.name, collection });\n }\n\n // BET-281: Use canonicalKey to identify tensions instead of hardcoded slug.\n // canonicalKey is optional on entries, so fall back to slug for backward compat.\n const isTension = entry.canonicalKey === \"tension\" || collection === \"tensions\";\n if (isTension && entry.workflowStatus === \"open\") {\n result.openTensions.push({ name: entry.name, entryId: entry.entryId ?? entry._id });\n }\n\n if (entry.workflowStatus === \"in-progress\") {\n result.inProgressEntries.push({\n name: entry.name,\n collection,\n entryId: entry.entryId ?? entry._id,\n });\n }\n }\n\n return result;\n}\n\nexport async function queryPlannedWork(): Promise<PlannedWork> {\n try {\n const allEntries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", {\n fields: [\"_id\", \"entryId\", \"name\", \"status\", \"workflowStatus\", \"collectionSlug\", \"stratum\", \"canonicalKey\"],\n });\n if (!allEntries) return { uncommittedDrafts: [], inProgressEntries: [], openTensions: [] };\n return buildPlannedWork(allEntries);\n } catch {\n return { uncommittedDrafts: [], inProgressEntries: [], openTensions: [] };\n }\n}\n\nexport function hasPlannedWork(work: PlannedWork): boolean {\n return (\n work.uncommittedDrafts.length > 0 ||\n work.inProgressEntries.length > 0 ||\n work.openTensions.length > 0\n );\n}\n\n/** ENT-yaic53: Format recovery block from Convex structured data. */\nexport function formatRecoveryBlock(block: {\n sessionId: string;\n status: 'timed_out' | 'completed';\n date: string;\n duration: string;\n created: { entryId: string; collection: string; name: string }[];\n modified: { entryId: string; collection: string; name: string }[];\n draftsNeedingAttention: { entryId: string; collection: string; name: string }[];\n relationsCreated: number;\n createdOverflow?: number;\n modifiedOverflow?: number;\n draftsOverflow?: number;\n}): string[] {\n const fmt = (items: { entryId: string; collection: string; name: string }[], overflow?: number) =>\n items.map((e) => `${e.entryId} [${e.collection}] ${e.name}`).join(', ') +\n (overflow && overflow > 0 ? ` (+${overflow} more)` : '');\n\n const lines: string[] = [\n '## Previous Session Recovery',\n '',\n `Previous session — ${block.date}, ${block.duration}, status: ${block.status}`,\n `Created (${block.created.length + (block.createdOverflow ?? 0)}): ${fmt(block.created, block.createdOverflow)}`,\n `Modified (${block.modified.length + (block.modifiedOverflow ?? 0)}): ${fmt(block.modified, block.modifiedOverflow)}`,\n `Items pending review (${block.draftsNeedingAttention.length + (block.draftsOverflow ?? 0)}): ${fmt(block.draftsNeedingAttention, block.draftsOverflow)}`,\n `Relations created: ${block.relationsCreated}`,\n '',\n ];\n return lines;\n}\n\nexport function buildPlannedWorkSection(\n work: PlannedWork,\n priorSessions: PriorSession[],\n recoveryBlock?: { sessionId: string; status: 'timed_out' | 'completed'; date: string; duration: string; created: { entryId: string; collection: string; name: string }[]; modified: { entryId: string; collection: string; name: string }[]; draftsNeedingAttention: { entryId: string; collection: string; name: string }[]; relationsCreated: number; createdOverflow?: number; modifiedOverflow?: number; draftsOverflow?: number } | null,\n): string[] {\n if (!hasPlannedWork(work) && priorSessions.length === 0) return [];\n\n const lines: string[] = [];\n lines.push(\"## Continue from where you left off\");\n lines.push(\"\");\n\n if (work.inProgressEntries.length > 0) {\n const top = work.inProgressEntries[0];\n lines.push(`- **Active: ${top.name}** (${top.collection}) — want to continue?`);\n for (const entry of work.inProgressEntries.slice(1, 3)) {\n lines.push(`- ${entry.name} (${entry.collection})`);\n }\n if (work.inProgressEntries.length > 3) {\n lines.push(`- _...and ${work.inProgressEntries.length - 3} more in progress_`);\n }\n }\n\n if (work.uncommittedDrafts.length > 0) {\n const count = work.uncommittedDrafts.length;\n const label = count === 1 ? \"1 item pending\" : `${count} items pending`;\n const topNames = work.uncommittedDrafts\n .slice(0, 3)\n .map((d) => d.name)\n .join(\", \");\n lines.push(`- **${label}** — ${topNames}${count > 3 ? \", ...\" : \"\"}`);\n }\n\n if (work.openTensions.length > 0) {\n const top = work.openTensions[0];\n const count = work.openTensions.length;\n if (count === 1) {\n lines.push(`- **Open tension: ${top.name}** — discuss or capture a decision?`);\n } else {\n lines.push(`- **${count} open tensions** — top: ${top.name}`);\n }\n }\n\n if (priorSessions.length > 0 && !hasPlannedWork(work) && !recoveryBlock) {\n const last = priorSessions[0];\n // BUG FIX: `startedAt` is optional; `new Date(undefined)` throws RangeError on\n // .toISOString() (\"Invalid time value\") rather than producing a usable date.\n const date = last.startedAt !== undefined\n ? new Date(last.startedAt).toISOString().split(\"T\")[0]\n : \"unknown date\";\n const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;\n const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;\n if (created > 0 || modified > 0) {\n lines.push(`- **Last session** (${date}): ${created} created, ${modified} modified`);\n }\n }\n\n if (recoveryBlock) {\n lines.push('');\n lines.push(...formatRecoveryBlock(recoveryBlock));\n }\n\n lines.push(\"\");\n return lines;\n}\n","/**\n * Registry Manifest + Rules — connector-owned configuration data.\n * BET-99 / ARCH-16 / ARCH-19 / TEN-2781\n *\n * SINGLE-HOMED HERE (Lane D S1): this is manifest+rules DATA, not algorithm — the\n * `path`/`exportName`/`keyExtraction` fields are LOCAL-resolver instructions (the\n * resolver needs them locally to parse the agent's checkout), so this stays\n * connector-side and is sent over the wire to `chain.evaluateCoherence` alongside the\n * locally-resolved slugs (kernel/codebaseCoherence/engine.ts owns the pure algorithm\n * only — no config of its own, mirrors kernel/relations/scoreLinkCandidates.ts's\n * connector-supplied collMap/hubSlugs). There used to be a top-level \"canonical\" copy\n * (src/lib/coherence/registry-manifest.ts + rules/collection-registries.ts) with no\n * live importer, byte-synced here by `scripts/sync-coherence-to-mcp.mjs` — both the\n * canonical copy and the sync script are retired in this same slice. The\n * `subset-renderers` invariant (renderers ids ⊆ classification-map ids) that used to\n * ride the cross-copy drift gate is now a single in-repo unit test — see\n * `__tests__/data-manifest-consistency.test.ts`.\n *\n * ENT-65 (FEAT-201): Cross-registry sync rules for CLASSIFICATION_MAP ↔ DEFAULT_COLLECTIONS\n * and CLASSIFICATION_MAP ↔ CLASSIFICATION_META were removed. These constants are seed-only.\n */\n\nimport type { CoherenceRule, RegistryRef } from \"./types.js\";\n\nexport const REGISTRY_MANIFEST: readonly RegistryRef[] = [\n // ── Canonical UI registries ──────────────────────────────────────\n // BET-143 Slice 4: ui-colors removed — color is now a field on collection docs (schema.ts).\n {\n id: \"routes\",\n path: \"src/lib/navigation.ts\",\n exportName: \"COLLECTION_ROUTES\",\n description: \"Collection slug to dedicated route path\",\n expectedCoverage: \"curated\",\n keyExtraction: \"object-keys\",\n },\n {\n id: \"gap-paths\",\n path: \"src/lib/navigation.ts\",\n exportName: \"GAP_PATHS\",\n description: \"Readiness gap ID to workspace-relative route path\",\n expectedCoverage: \"curated\",\n keyExtraction: \"object-keys\",\n },\n // BET-280 S3: display-fields removed — DISPLAY_FIELDS constant deleted, field display is now schema-driven.\n // BET-280 S3: brain-icons removed — COLLECTION_ICONS unexported, getCollectionIcon() is a local rendering fallback only.\n\n // ── Graph visualization registries ───────────────────────────────\n // BET-143 Slice 4: graph-colors and graph-type-colors removed.\n // Graph rendering uses local fallback palettes (canvas needs resolved hex/CSS vars, not DB reads).\n\n // ── Cortex registries ────────────────────────────────────────────\n {\n id: \"renderers\",\n path: \"src/lib/components/studio/renderers/index.ts\",\n exportName: \"COLLECTION_RENDERERS\",\n description: \"Custom Svelte renderer component per collection\",\n expectedCoverage: \"subset\",\n keyExtraction: \"object-keys\",\n },\n\n // ── Backend registries ───────────────────────────────────────────\n {\n id: \"classification-map\",\n path: \"convex/lib/seedClassificationRegistry.ts\",\n exportName: \"SEED_CLASSIFICATION_REGISTRY\",\n // ENT-65\n description: \"Seed-only: governance, nav group, ID prefix. Runtime reads from DB collection doc.\",\n expectedCoverage: \"curated\",\n keyExtraction: \"array-slug\",\n },\n // TEN-598: default-collections removed. Collection definitions live in system_collection_definitions (DB).\n] as const;\n\nexport const COLLECTION_REGISTRY_RULES: readonly CoherenceRule[] = [\n // ── Subset: specialized registries should only reference known collections ──\n // BET-143 Slice 4: brain-colors, graph-colors, graph-type-colors rules removed —\n // those registries were deleted when color moved to collection docs.\n // BET-280 S3: brain-icons rule removed — COLLECTION_ICONS unexported, no longer a registry.\n // BET-280 S3: display-fields rule removed — DISPLAY_FIELDS deleted, field display is schema-driven.\n {\n id: \"subset-renderers\",\n type: \"subset\",\n description: \"Renderers should only reference classified collections\",\n subject: \"renderers\",\n reference: \"classification-map\",\n },\n] as const;\n","/**\n * Filesystem Registry Resolver — MCP-specific.\n * BET-99 / FEAT-182 / ARCH-19\n *\n * Reads source files from the project root and extracts collection slug sets\n * using the keyExtraction hints from the registry manifest.\n *\n * Design constraints:\n * - Dev-time only. Synchronous I/O is acceptable — this runs in orient/wrapup/review,\n * not in response to user actions or page loads (BET-99 no-go #5).\n * - Heuristic parser, not AST-based (BET-99 no-go #8). Template literals with\n * expression interpolation are not supported; backtick strings are treated as\n * opaque (skipped to closing backtick). This is sufficient for the structured\n * registries in the manifest.\n * - Gracefully skips unreadable files — never throws to callers.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { KeyExtraction, RegistryRef, ResolvedRegistries } from \"./types.js\";\n\n/**\n * Resolve all registries from source files, returning slug sets keyed by registry ID.\n * Silently skips registries whose files can't be read or parsed.\n */\nexport function resolveRegistries(\n projectRoot: string,\n manifest: readonly RegistryRef[],\n): ResolvedRegistries {\n if (!projectRoot) return {};\n\n const resolved: Record<string, ReadonlySet<string>> = {};\n\n for (const ref of manifest) {\n try {\n const filePath = resolve(projectRoot, ref.path);\n const content = readFileSync(filePath, \"utf-8\");\n const block = extractBlock(content, ref.exportName);\n if (!block) continue;\n\n const keys = extractKeys(block, ref.keyExtraction);\n if (keys.size > 0) {\n resolved[ref.id] = keys;\n }\n } catch (err) {\n if (process.env.DEBUG_COHERENCE) {\n console.debug(`[coherence] Skipping ${ref.id} (${ref.path}):`, err instanceof Error ? err.message : err);\n }\n }\n }\n\n return resolved;\n}\n\n// ── Block extraction ──────────────────────────────────────────────────────────\n\nfunction extractBlock(content: string, exportName: string): string | null {\n const escaped = exportName.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const pattern = new RegExp(\n `(?:export\\\\s+)?(?:const|let|var)\\\\s+${escaped}\\\\b[^=]*=\\\\s*`,\n );\n const match = pattern.exec(content);\n if (!match) return null;\n\n let pos = match.index + match[0].length;\n while (pos < content.length && /\\s/.test(content[pos]!)) pos++;\n\n const ch = content[pos];\n\n if (ch === \"{\" || ch === \"[\") {\n return extractBalanced(content, pos, ch, ch === \"{\" ? \"}\" : \"]\");\n }\n\n // new Set([...])\n if (content.slice(pos).startsWith(\"new Set\") || content.slice(pos).startsWith(\"new\\nSet\") || content.slice(pos).startsWith(\"new\\n\\tSet\")) {\n const setMatch = content.slice(pos).match(/^new\\s+Set\\s*\\(\\s*\\[/);\n if (setMatch) {\n return extractBalanced(content, pos + setMatch[0].length - 1, \"[\", \"]\");\n }\n }\n\n return null;\n}\n\nfunction extractBalanced(\n content: string,\n openPos: number,\n openChar: string,\n closeChar: string,\n): string | null {\n let depth = 1;\n let i = openPos + 1;\n\n while (i < content.length && depth > 0) {\n const ch = content[i]!;\n\n if (ch === \"'\" || ch === '\"' || ch === \"`\") {\n i = skipString(content, i, ch);\n continue;\n }\n if (ch === \"/\" && i + 1 < content.length && content[i + 1] === \"/\") {\n while (i < content.length && content[i] !== \"\\n\") i++;\n continue;\n }\n if (ch === \"/\" && i + 1 < content.length && content[i + 1] === \"*\") {\n i += 2;\n while (i < content.length) {\n if (content[i] === \"/\" && i > 0 && content[i - 1] === \"*\") { i++; break; }\n i++;\n }\n continue;\n }\n\n if (ch === openChar) depth++;\n else if (ch === closeChar) depth--;\n i++;\n }\n\n if (depth !== 0) return null;\n return content.slice(openPos + 1, i - 1);\n}\n\n/**\n * Skip past a string literal. Handles single/double quotes with backslash escapes.\n * Template literals: skips to closing backtick but does NOT handle ${} interpolation —\n * nested braces inside template expressions may cause early termination. Acceptable\n * because registry files use simple string literals, not template expressions.\n */\nfunction skipString(content: string, start: number, quote: string): number {\n let i = start + 1;\n while (i < content.length) {\n const ch = content[i]!;\n if (ch === \"\\\\\") {\n i += 2;\n continue;\n }\n if (ch === quote) return i + 1;\n i++;\n }\n return i;\n}\n\n// ── Key extraction ────────────────────────────────────────────────────────────\n\nfunction extractKeys(block: string, extraction: KeyExtraction): Set<string> {\n switch (extraction) {\n case \"object-keys\":\n return extractObjectKeys(block);\n case \"array-slug\":\n return extractArraySlugs(block);\n case \"set-values\":\n return extractSetValues(block);\n }\n}\n\n/**\n * Extract top-level keys from an object literal block.\n * Tracks brace/bracket depth so nested property names are ignored.\n */\nfunction extractObjectKeys(block: string): Set<string> {\n const keys = new Set<string>();\n let depth = 0;\n let i = 0;\n\n while (i < block.length) {\n const ch = block[i]!;\n\n if (ch === \"/\" && i + 1 < block.length && block[i + 1] === \"/\") {\n while (i < block.length && block[i] !== \"\\n\") i++;\n continue;\n }\n if (ch === \"/\" && i + 1 < block.length && block[i + 1] === \"*\") {\n i += 2;\n while (i < block.length) {\n if (block[i] === \"/\" && i > 0 && block[i - 1] === \"*\") { i++; break; }\n i++;\n }\n continue;\n }\n\n // At depth 0, try matching quoted keys before consuming strings as values\n if (depth === 0) {\n const rest = block.slice(i);\n const quoted = rest.match(/^(['\"])([\\w-]+)\\1\\s*:/);\n if (quoted) {\n keys.add(quoted[2]!);\n i += quoted[0].length;\n continue;\n }\n const ident = rest.match(/^([\\w-]+)\\s*:/);\n if (ident) {\n keys.add(ident[1]!);\n i += ident[0].length;\n continue;\n }\n }\n\n if (ch === \"'\" || ch === '\"' || ch === \"`\") {\n i = skipString(block, i, ch);\n continue;\n }\n\n if (ch === \"{\" || ch === \"[\" || ch === \"(\") { depth++; i++; continue; }\n if (ch === \"}\" || ch === \"]\" || ch === \")\") { depth--; i++; continue; }\n\n i++;\n }\n\n return keys;\n}\n\nfunction extractArraySlugs(block: string): Set<string> {\n const slugs = new Set<string>();\n for (const m of block.matchAll(/slug:\\s*['\"](\\w[\\w-]*)['\"]/g)) {\n slugs.add(m[1]!);\n }\n return slugs;\n}\n\nfunction extractSetValues(block: string): Set<string> {\n const values = new Set<string>();\n for (const m of block.matchAll(/['\"](\\w[\\w-]*)['\"]/g)) {\n values.add(m[1]!);\n }\n return values;\n}\n","/**\n * Git-diff registry detection — FEAT-184 / BET-99.\n *\n * Detects whether files listed in the registry manifest were modified\n * since a given ref (or within the working tree). Uses conservative matching:\n * any change to a manifest-listed file triggers a coherence check.\n * False positives are cheap; false negatives are the failure mode (RH2).\n *\n * Dev-time only: uses synchronous `execSync` with a 5s timeout. Acceptable\n * because this runs at wrapup time, not in response to user actions (no-go #5).\n */\n\nimport { execSync } from \"node:child_process\";\nimport { REGISTRY_MANIFEST } from \"./data.js\";\n\n/**\n * Get the set of manifest file paths that have been modified.\n * Checks both staged and unstaged changes against the working tree.\n * Returns an empty set if git is unavailable or the command fails.\n */\nexport function detectTouchedRegistries(projectRoot: string): Set<string> {\n if (!projectRoot) return new Set();\n\n const manifestPaths = new Set(REGISTRY_MANIFEST.map((r) => r.path));\n const touched = new Set<string>();\n\n try {\n const raw = execSync(\"git diff --name-only HEAD 2>/dev/null || git diff --name-only\", {\n cwd: projectRoot,\n encoding: \"utf-8\",\n timeout: 5_000,\n });\n\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed && manifestPaths.has(trimmed)) {\n touched.add(trimmed);\n }\n }\n } catch (err) {\n if (process.env.DEBUG_COHERENCE) {\n console.debug(\"[coherence] Git detection failed:\", err instanceof Error ? err.message : err);\n }\n }\n\n return touched;\n}\n\n/**\n * Quick boolean check: did this session's working tree touch any registry file?\n */\nexport function hasRegistryChanges(projectRoot: string): boolean {\n return detectTouchedRegistries(projectRoot).size > 0;\n}\n","/**\n * Codebase Coherence Check — MCP Integration Module.\n * BET-99 / FEAT-182 / ARCH-19 / TEN-2781 / Lane D S1.\n *\n * Orchestrates the coherence pipeline: resolve registries from LOCAL source files\n * (the Convex server has no access to the agent's checkout — this stays connector-\n * side), call the SERVED kernel verdict (`chain.evaluateCoherence`,\n * kernel/codebaseCoherence/engine.ts), render markdown for orient/start and the\n * review gate, and produce a snapshot for persistence.\n *\n * Was: canonical engine synced from top-level src/lib/coherence/ (byte-hash pinned by\n * scripts/check-mcp-lib-drift.mjs). Now: this module keeps only what is genuinely\n * LOCAL — the filesystem resolver (resolver.ts), git-diff detection\n * (git-detection.ts), and ALL rendering. The pure algorithm moved to\n * kernel/codebaseCoherence/{engine.ts,types.ts} (STD-K1 clean) and is served over the\n * AKI gateway — so the coherence engine's sync script\n * (scripts/sync-coherence-to-mcp.mjs) and its top-level canonical copy are deleted, and\n * COHERENCE's ENTRY in the MCP drift gate is removed (TEN-2781, Lane D S1).\n *\n * Precise scope (do NOT overstate as \"the drift gate retired\"): only coherence's pin was\n * dropped. scripts/check-mcp-lib-drift.mjs is still live and still content-hash-pins\n * fieldTypes, workflowRun, and inferSourceDate (see that script's header), and the\n * separate embedded-copies drift check (scripts/generate-mcp-embedded-copies.mjs --check)\n * still pins flags.ts / logo-markup.ts. Those blocks and their sync scripts remain.\n *\n * ASYNC (MAJOR — not a drop-in): the engine call is now `await kernelQuery(...)`, so\n * the whole pipeline is async. `runCoherenceCheck`, `checkAndRender`, and\n * `renderCoherenceGate` all return Promises. Every call site awaits:\n * packages/mcp-server/src/tools/{start_pb.ts:270, orient.ts:796, orient.ts:963,\n * wrapup.ts:421}, and orient-shared.ts's `buildCoherenceSection` wrapper. Rendering\n * LOGIC is unchanged — but the call SHAPE is not, so this is not \"rendering\n * unchanged\" outright.\n *\n * VISIBLE FAIL-OPEN (TEN-2781 Design, MAJOR). On a `kernelQuery` rejection (gateway\n * unreachable), this degrades to an EXPLICIT skipped-state — never a silent pass that\n * reads as coherent/green:\n * - Orient/start (`checkAndRender`): `## Codebase Coherence` + a single\n * \"_Coherence check skipped — gateway unreachable..._\" line. No \"All registries\n * aligned\", no gap counts.\n * - Review gate (`renderCoherenceGate`): `### Coherence Gate` +\n * `**Gate: SKIPPED** — ... This is NOT a pass; ...` and verdict `\"unavailable\"`\n * — distinct from `\"no-baseline\"` (too few LOCAL registries resolved — never even\n * reaches the gateway) and from any pass/degraded verdict.\n * This is fail-OPEN (the entry/orient/session still completes) but never SILENT (the\n * reader always sees that drift was not evaluated this session).\n */\n\nimport { REGISTRY_MANIFEST, COLLECTION_REGISTRY_RULES } from \"./data.js\";\nimport { resolveRegistries } from \"./resolver.js\";\nimport { kernelQuery, KernelCallError } from \"../../client.js\";\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport type { CoherenceReport, CoherenceSnapshot, CoherenceViolation, RuleSeverity } from \"./types.js\";\n\n/**\n * Describe a `kernelQuery` rejection concretely — PR #405 review (Codex P2): every\n * failure used to collapse into the same \"gateway unreachable\" line, masking\n * deployment skew, an expired credential, a server-side validation rejection, or a\n * handler exception behind one undifferentiated message. `KernelCallError` (thrown by\n * client.ts's callGateway when the gateway RESPONDS with a non-success status —\n * validation/auth/handler failures) carries a real `.code`/`.message`; a plain network\n * failure (DNS, timeout, connection refused — callGateway's fetch itself throwing)\n * carries only `.message`. Either way this is still fail-OPEN (the caller always gets a\n * `'skipped'` outcome, never a thrown error) — just honest about WHY, per the doneWhen's\n * \"never silent\" requirement extending to \"never opaque.\"\n */\nfunction describeGatewayFailure(err: unknown): string {\n if (err instanceof KernelCallError) {\n return err.code ? `${err.code}: ${err.message}` : err.message;\n }\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nexport type { CoherenceReport, CoherenceSnapshot, CoherenceViolation } from \"./types.js\";\nexport { detectTouchedRegistries, hasRegistryChanges } from \"./git-detection.js\";\n\ntype EvaluateCoherenceResult = GatewayRouteReturnByName<\"chain.evaluateCoherence\">;\n\n/**\n * Outcome of one coherence-check attempt.\n * - `ok`: the served verdict was computed successfully.\n * - `no-data`: fewer than 2 registries resolved LOCALLY — nothing to compare. This is\n * unrelated to gateway health; the served route is never even called (DEC-169: early\n * exit before the round trip).\n * - `skipped`: the `chain.evaluateCoherence` gateway call rejected — VISIBLE fail-open,\n * see file header. Never silently treated as \"aligned.\" `reason` carries the concrete\n * failure (network error, or the gateway's own code+message) — never opaque.\n */\nexport type CoherenceCheckOutcome =\n | { status: \"ok\"; report: CoherenceReport; snapshot: CoherenceSnapshot }\n | { status: \"no-data\" }\n | { status: \"skipped\"; reason: string };\n\n/**\n * Run the full coherence check pipeline: resolve registries LOCALLY, then call the\n * served kernel verdict. Returns null-equivalent (`'no-data'`) when too few registries\n * resolve — same early-exit DEC-169 always did, now made explicit in the outcome type\n * instead of a bare `null` so callers can tell \"nothing to check\" apart from \"gateway\n * unreachable.\"\n */\nexport async function runCoherenceCheck(projectRoot: string): Promise<CoherenceCheckOutcome> {\n const resolved = resolveRegistries(projectRoot, REGISTRY_MANIFEST);\n\n // Need at least 2 resolved registries for any rule to evaluate — a purely LOCAL\n // determination, made before ever touching the gateway (DEC-169 perf budget).\n if (Object.keys(resolved).length < 2) return { status: \"no-data\" };\n\n const resolvedWire = Object.entries(resolved).map(([id, slugs]) => ({ id, slugs: [...slugs] }));\n\n try {\n const result = await kernelQuery<EvaluateCoherenceResult>(\"chain.evaluateCoherence\", {\n manifest: REGISTRY_MANIFEST,\n rules: COLLECTION_REGISTRY_RULES,\n resolved: resolvedWire,\n });\n return { status: \"ok\", report: result.report, snapshot: result.snapshot };\n } catch (err) {\n const reason = describeGatewayFailure(err);\n if (process.env.DEBUG_COHERENCE) {\n console.debug(\"[coherence] chain.evaluateCoherence gateway call failed:\", reason);\n }\n return { status: \"skipped\", reason };\n }\n}\n\n// ── Orient / Start rendering ──────────────────────────────────────────────────\n\nexport function renderCoherenceLines(report: CoherenceReport): string[] {\n const lines: string[] = [\"## Codebase Coherence\"];\n\n if (report.summary.total === 0) {\n lines.push(\"All registries aligned — no gaps detected.\");\n lines.push(\"\");\n return lines;\n }\n\n const parts: string[] = [];\n if (report.summary.errors > 0) parts.push(`${report.summary.errors} error${report.summary.errors === 1 ? \"\" : \"s\"}`);\n if (report.summary.warnings > 0) parts.push(`${report.summary.warnings} warning${report.summary.warnings === 1 ? \"\" : \"s\"}`);\n if (report.summary.infos > 0) parts.push(`${report.summary.infos} info`);\n lines.push(`**${report.summary.total} gap${report.summary.total === 1 ? \"\" : \"s\"}** across ${report.totalRegistries} registries (${parts.join(\", \")})`);\n\n const errors = report.violations.filter((v) => v.severity === \"error\");\n const warnings = report.violations.filter((v) => v.severity === \"warning\");\n\n if (errors.length > 0) {\n lines.push(\"\");\n lines.push(\"**Errors** (must fix):\");\n for (const v of errors.slice(0, 5)) {\n lines.push(`- ${v.message}`);\n }\n if (errors.length > 5) lines.push(`- ...and ${errors.length - 5} more`);\n }\n\n if (warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"**Warnings**:\");\n for (const v of warnings.slice(0, 3)) {\n lines.push(`- ${v.message}`);\n }\n if (warnings.length > 3) lines.push(`- ...and ${warnings.length - 3} more`);\n }\n\n lines.push(\"\");\n return lines;\n}\n\n/**\n * One-call convenience: check + render + snapshot.\n * Returns `null` ONLY for the LOCAL 'no-data' case (too few registries resolved —\n * same as pre-Lane-D behavior: no section rendered at all). A gateway-unreachable\n * `'skipped'` outcome is NOT null — it renders the visible skip banner (file header:\n * never silent).\n */\nexport async function checkAndRender(projectRoot: string): Promise<{\n lines: string[];\n snapshot: CoherenceSnapshot | null;\n} | null> {\n const outcome = await runCoherenceCheck(projectRoot);\n if (outcome.status === \"no-data\") return null;\n\n if (outcome.status === \"skipped\") {\n return {\n lines: [\n \"## Codebase Coherence\",\n `_Coherence check skipped — gateway unreachable. Registry drift not evaluated this session. (Reason: ${outcome.reason})_`,\n \"\",\n ],\n snapshot: null,\n };\n }\n\n return {\n lines: renderCoherenceLines(outcome.report),\n snapshot: outcome.snapshot,\n };\n}\n\n// ── Delta rendering (FEAT-183 / FEAT-184) ────────────────────────────────────\n\nexport type CoherenceVerdict = \"improved\" | \"degraded\" | \"unchanged\";\n\nexport interface CoherenceDelta {\n before: CoherenceSnapshot;\n after: CoherenceSnapshot;\n gapsFixed: number;\n gapsIntroduced: number;\n netChange: number;\n verdict: CoherenceVerdict;\n}\n\n/**\n * Compare two snapshots to produce a delta with verdict.\n * Used by review workflow (FEAT-183) and session wrapup (FEAT-184).\n *\n * Note: `gapsFixed`/`gapsIntroduced` are derived from topGaps (capped at 10),\n * while `netChange` uses totalGaps (uncapped). When many gaps exist, the\n * itemized counts are a lower bound — the render copy reflects this.\n */\nexport function computeDelta(before: CoherenceSnapshot, after: CoherenceSnapshot): CoherenceDelta {\n const beforeSet = new Set(before.topGaps.map((g) => `${g.registry}::${g.slug}`));\n const afterSet = new Set(after.topGaps.map((g) => `${g.registry}::${g.slug}`));\n\n let gapsFixed = 0;\n for (const key of beforeSet) {\n if (!afterSet.has(key)) gapsFixed++;\n }\n let gapsIntroduced = 0;\n for (const key of afterSet) {\n if (!beforeSet.has(key)) gapsIntroduced++;\n }\n\n const netChange = after.totalGaps - before.totalGaps;\n const verdict: CoherenceVerdict =\n netChange < 0 ? \"improved\" : netChange > 0 ? \"degraded\" : \"unchanged\";\n\n return { before, after, gapsFixed, gapsIntroduced, netChange, verdict };\n}\n\n/**\n * Render a coherence delta as markdown lines for review or wrapup.\n * Gate logic: degraded → warning flag, improved → celebration, unchanged → neutral.\n */\nexport function renderCoherenceDelta(delta: CoherenceDelta): string[] {\n const lines: string[] = [\"### Coherence Delta\"];\n\n const p = (n: number) => n === 1 ? \"\" : \"s\";\n const absNet = Math.abs(delta.netChange);\n const approx = absNet > delta.gapsFixed + delta.gapsIntroduced;\n const prefix = approx ? \"at least \" : \"\";\n\n if (delta.verdict === \"improved\") {\n lines.push(\n `Registry coherence **improved**: ${prefix}${delta.gapsFixed} gap${p(delta.gapsFixed)} fixed` +\n (delta.gapsIntroduced > 0 ? `, ${delta.gapsIntroduced} introduced` : \"\") +\n ` (net ${delta.netChange}). ${delta.after.totalGaps} gap${p(delta.after.totalGaps)} remain${delta.after.totalGaps === 1 ? \"s\" : \"\"}.`,\n );\n } else if (delta.verdict === \"degraded\") {\n lines.push(\n `**Registry coherence degraded**: ${prefix}${delta.gapsIntroduced} new gap${p(delta.gapsIntroduced)} introduced` +\n (delta.gapsFixed > 0 ? `, ${delta.gapsFixed} fixed` : \"\") +\n ` (net +${delta.netChange}). ${delta.after.totalGaps} gap${p(delta.after.totalGaps)} total.`,\n );\n } else {\n lines.push(\n `Registry coherence unchanged. ${delta.after.totalGaps} gap${p(delta.after.totalGaps)} remain${delta.after.totalGaps === 1 ? \"s\" : \"\"}` +\n (delta.gapsFixed > 0 ? ` (${delta.gapsFixed} fixed, ${delta.gapsIntroduced} introduced)` : \"\") +\n \".\",\n );\n }\n\n lines.push(\"\");\n return lines;\n}\n\n/**\n * Coherence gate for review workflow Round 02 (FEAT-183).\n * Produces a pass/fail section comparing session-start snapshot against current state.\n * Gracefully degrades to absolute report when no prior snapshot exists — and to an\n * explicit `\"unavailable\"` verdict (never a silent pass) when the gateway is unreachable.\n */\nexport async function renderCoherenceGate(\n projectRoot: string,\n sessionSnapshot: CoherenceSnapshot | null,\n): Promise<{\n lines: string[];\n verdict: CoherenceVerdict | \"no-baseline\" | \"unavailable\";\n afterSnapshot: CoherenceSnapshot | null;\n}> {\n const outcome = await runCoherenceCheck(projectRoot);\n\n if (outcome.status === \"skipped\") {\n return {\n lines: [\n \"### Coherence Gate\",\n `**Gate: SKIPPED** — coherence check could not run (gateway unreachable). This is NOT a pass; registry drift was not evaluated. Reason: ${outcome.reason}.`,\n \"\",\n ],\n verdict: \"unavailable\",\n afterSnapshot: null,\n };\n }\n\n if (outcome.status === \"no-data\") {\n // PR #405 review (Copilot): this branch means fewer than 2 registries resolved\n // LOCALLY (resolveRegistries's own early exit, see runCoherenceCheck) — it has\n // nothing to do with filesystem availability (a fully-readable filesystem with a\n // manifest that resolves too few registries hits this path too). The old wording\n // (\"filesystem unavailable\") implied an I/O failure that may not have occurred.\n return {\n lines: [\"### Coherence Gate\", \"Could not run coherence check (fewer than 2 registries resolved locally).\", \"\"],\n verdict: \"no-baseline\",\n afterSnapshot: null,\n };\n }\n\n const { report, snapshot: afterSnapshot } = outcome;\n\n if (!sessionSnapshot) {\n const absolute = renderCoherenceLines(report);\n absolute[0] = \"### Coherence Gate (no baseline)\";\n absolute.splice(1, 0, \"_No session-start snapshot available — showing absolute state._\");\n return { lines: absolute, verdict: \"no-baseline\", afterSnapshot };\n }\n\n const delta = computeDelta(sessionSnapshot, afterSnapshot);\n const lines = renderCoherenceDelta(delta);\n\n if (delta.verdict === \"degraded\") {\n lines.push(\"**Gate: WARN** — This implementation introduced registry drift. Review the new gaps before shipping.\");\n\n const newGaps = delta.after.topGaps.filter(\n (g) => !delta.before.topGaps.some((b) => b.registry === g.registry && b.slug === g.slug),\n );\n if (newGaps.length > 0) {\n lines.push(\"\");\n lines.push(\"New gaps:\");\n for (const g of newGaps.slice(0, 5)) {\n lines.push(`- \\`${g.slug}\\` missing from \\`${g.registry}\\` (${g.severity})`);\n }\n if (newGaps.length > 5) lines.push(`- ...and ${newGaps.length - 5} more`);\n }\n lines.push(\"\");\n } else if (delta.verdict === \"improved\") {\n lines.push(\"**Gate: PASS** — Nice work, coherence improved this session.\");\n lines.push(\"\");\n } else {\n lines.push(\"**Gate: PASS** — No coherence change.\");\n lines.push(\"\");\n }\n\n return { lines, verdict: delta.verdict, afterSnapshot };\n}\n\n// ── Persistent gap detection + tension offers (BET-101 / Phase 6) ────────────\n\nexport interface PersistentGap {\n registry: string;\n slug: string;\n severity: RuleSeverity;\n violation: CoherenceViolation | null;\n}\n\n/**\n * Find gaps that persisted across the session (present in both before and after).\n * These are candidates for Chain capture as tensions — the session didn't fix them,\n * so they represent structural drift worth tracking.\n */\nexport function findPersistentGaps(\n delta: CoherenceDelta,\n currentViolations: CoherenceViolation[],\n): PersistentGap[] {\n const beforeSet = new Set(delta.before.topGaps.map((g) => `${g.registry}::${g.slug}`));\n const afterSet = new Set(delta.after.topGaps.map((g) => `${g.registry}::${g.slug}`));\n\n const persistentKeys = new Set<string>();\n for (const key of beforeSet) {\n if (afterSet.has(key)) persistentKeys.add(key);\n }\n\n if (persistentKeys.size === 0) return [];\n\n const violationMap = new Map<string, CoherenceViolation>();\n for (const v of currentViolations) {\n violationMap.set(`${v.registryId}::${v.collectionSlug}`, v);\n }\n\n return [...persistentKeys].map((key) => {\n const [registry = \"\", slug = \"\"] = key.split(\"::\", 2);\n return {\n registry,\n slug,\n severity: (delta.after.topGaps.find((g) => g.registry === registry && g.slug === slug)?.severity ?? \"warning\") as RuleSeverity,\n violation: violationMap.get(key) ?? null,\n };\n });\n}\n\n/**\n * Render offer-to-capture section for persistent gaps.\n * Lists each gap with a ready-to-use `capture` command template.\n * BET-101 no-go #3: never auto-create — this is an offer, not an action.\n */\nexport function renderPersistentGapOffers(gaps: PersistentGap[]): string[] {\n if (gaps.length === 0) return [];\n\n const lines: string[] = [\n \"### Persistent Coherence Gaps\",\n \"\",\n \"These gaps existed before and after this session — they represent structural registry drift.\",\n \"Want me to capture them as tensions on the Chain?\",\n \"\",\n ];\n\n const SEVERITY_RANK: Record<RuleSeverity, number> = { error: 0, warning: 1, info: 2 };\n const errorsFirst = [...gaps].sort((a, b) =>\n SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity],\n );\n\n for (const gap of errorsFirst.slice(0, 5)) {\n const v = gap.violation;\n const fixHint = v?.fix ? ` — ${v.fix}` : \"\";\n lines.push(\n `- **\\`${gap.slug}\\`** missing from \\`${gap.registry}\\` (${gap.severity})${fixHint}`,\n );\n }\n\n if (errorsFirst.length > 5) {\n lines.push(`- ...and ${errorsFirst.length - 5} more`);\n }\n\n lines.push(\"\");\n lines.push(\n '_Say \"capture these as tensions\" to accept them onto the Chain, or skip to continue._',\n );\n lines.push(\"\");\n\n return lines;\n}\n","/**\n * Doc-Completeness Check — ENT-65 / FEAT-201\n * BET-99: Complements the code-based coherence engine with DB-sourced field checks.\n *\n * Checks that collection documents have the required fields populated after the\n * DB-first migration. These checks replace the removed cross-registry sync rules\n * (sync-classification-defaults, sync-classification-classifier) which produced\n * false positives once CLASSIFICATION_MAP and CLASSIFICATION_META became seed-only.\n *\n * Rules:\n * - All collections: idPrefix, governed must be set\n * - Classifier collections (classificationCheck present): classificationPriority required\n * - Workflow collections (validWorkflowStatuses present): array must be non-empty\n */\n\nexport interface CollectionDocFields {\n slug: string;\n governed?: boolean | null;\n navGroup?: string | null;\n idPrefix?: string | null;\n validWorkflowStatuses?: string[] | null;\n classificationCheck?: string | null;\n classificationPriority?: number | null;\n}\n\nexport interface DocCompletenessViolation {\n slug: string;\n field: string;\n message: string;\n severity: \"error\" | \"warning\";\n fix: string;\n}\n\nexport interface DocCompletenessReport {\n checkedAt: number;\n totalChecked: number;\n violations: DocCompletenessViolation[];\n summary: { errors: number; warnings: number; total: number };\n}\n\n/**\n * Check collection docs for required field completeness.\n * Pure function — accepts pre-fetched collection data, no I/O.\n */\nexport function checkDocCompleteness(\n collections: CollectionDocFields[],\n checkedAt?: number,\n): DocCompletenessReport {\n const violations: DocCompletenessViolation[] = [];\n\n for (const col of collections) {\n const { slug } = col;\n\n // governed must be set (boolean)\n if (col.governed === undefined || col.governed === null) {\n violations.push({\n slug,\n field: \"governed\",\n message: `\"${slug}\" is missing the governed flag`,\n severity: \"warning\",\n fix: `Set governed on the \"${slug}\" collection document`,\n });\n }\n\n // idPrefix must be set\n if (!col.idPrefix) {\n violations.push({\n slug,\n field: \"idPrefix\",\n message: `\"${slug}\" is missing idPrefix`,\n severity: \"warning\",\n fix: `Set idPrefix on the \"${slug}\" collection document`,\n });\n }\n\n // Classifier fields must be consistent: check ↔ priority together\n const hasCheck = typeof col.classificationCheck === \"string\" && col.classificationCheck.length >= 3;\n const hasPriority = col.classificationPriority != null;\n\n if (hasCheck && !hasPriority) {\n violations.push({\n slug,\n field: \"classificationPriority\",\n message: `\"${slug}\" has classificationCheck but missing classificationPriority (1–9)`,\n severity: \"error\",\n fix: `Set classificationPriority (1–9) on the \"${slug}\" collection document`,\n });\n }\n\n if (hasPriority && !hasCheck) {\n violations.push({\n slug,\n field: \"classificationCheck\",\n message: `\"${slug}\" has classificationPriority but missing classificationCheck`,\n severity: \"error\",\n fix: `Set classificationCheck (3–500 chars) on the \"${slug}\" collection document`,\n });\n }\n\n // validWorkflowStatuses must be non-empty when present\n if (Array.isArray(col.validWorkflowStatuses) && col.validWorkflowStatuses.length === 0) {\n violations.push({\n slug,\n field: \"validWorkflowStatuses\",\n message: `\"${slug}\" has an empty validWorkflowStatuses array`,\n severity: \"error\",\n fix: `Add at least one status to validWorkflowStatuses on \"${slug}\", or remove the field`,\n });\n }\n }\n\n const errors = violations.filter((v) => v.severity === \"error\").length;\n const warnings = violations.filter((v) => v.severity === \"warning\").length;\n\n return {\n checkedAt: checkedAt ?? Date.now(),\n totalChecked: collections.length,\n violations,\n summary: { errors, warnings, total: violations.length },\n };\n}\n\n/**\n * Render doc-completeness report as orient section lines.\n * Returns empty array when there are no violations (clean state).\n */\nexport function renderDocCompletenessLines(report: DocCompletenessReport): string[] {\n // TEN-2036: clearer label than \"Classification Doc-Completeness\" — names what the report counts.\n const lines: string[] = [\"## Collection Documentation Gaps\"];\n\n if (report.summary.total === 0) {\n lines.push(`All ${report.totalChecked} collection docs have required fields populated.`);\n lines.push(\"\");\n return lines;\n }\n\n const parts: string[] = [];\n if (report.summary.errors > 0) parts.push(`${report.summary.errors} error${report.summary.errors === 1 ? \"\" : \"s\"}`);\n if (report.summary.warnings > 0) parts.push(`${report.summary.warnings} warning${report.summary.warnings === 1 ? \"\" : \"s\"}`);\n lines.push(`**${report.summary.total} gap${report.summary.total === 1 ? \"\" : \"s\"}** across ${report.totalChecked} collections (${parts.join(\", \")})`);\n\n const errors = report.violations.filter((v) => v.severity === \"error\");\n const warnings = report.violations.filter((v) => v.severity === \"warning\");\n\n // TEN-2035: bumped truncation caps from 5/3 to 10 each. Earlier limit hid 24+\n // warnings behind \"...and N more\" — high enough that triage was blocked. 10\n // covers most workspaces in full and keeps the worst case to a single\n // truncation line.\n const ERROR_INLINE = 10;\n const WARNING_INLINE = 10;\n\n if (errors.length > 0) {\n lines.push(\"\");\n lines.push(\"**Errors** (must fix):\");\n for (const v of errors.slice(0, ERROR_INLINE)) {\n lines.push(`- ${v.message} — ${v.fix}`);\n }\n if (errors.length > ERROR_INLINE) lines.push(`- ...and ${errors.length - ERROR_INLINE} more`);\n }\n\n if (warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"**Warnings**:\");\n for (const v of warnings.slice(0, WARNING_INLINE)) {\n lines.push(`- ${v.message}`);\n }\n if (warnings.length > WARNING_INLINE) lines.push(`- ...and ${warnings.length - WARNING_INLINE} more`);\n }\n\n lines.push(\"\");\n return lines;\n}\n","/**\n * Shared functions for orient and start tools. Single code path for the task-alignment render\n * (WP-465 ③ — verdict is server-computed), operating protocol (STA-3), codebase coherence\n * (BET-99 / FEAT-182), and doc-completeness (ENT-65 / FEAT-201).\n */\n\nimport { checkAndRender, renderCoherenceGate, type CoherenceSnapshot, type CoherenceVerdict } from \"../lib/coherence/index.js\";\nimport { checkDocCompleteness, renderDocCompletenessLines, type CollectionDocFields } from \"../lib/coherence/doc-completeness.js\";\nimport { resolveProjectRoot } from \"../lib/resolve-project-root.js\";\n\nexport type { CoherenceSnapshot, CoherenceVerdict } from \"../lib/coherence/index.js\";\nexport { renderCoherenceGate } from \"../lib/coherence/index.js\";\n\nexport interface CoherenceResult {\n lines: string[];\n /** null when the gateway was unreachable (visible skip banner rendered in `lines`\n * instead) — see lib/coherence/index.ts's `checkAndRender`. */\n snapshot: CoherenceSnapshot | null;\n}\n\n/**\n * Run codebase coherence check and produce orient/start section lines. Returns null when check\n * can't run at all (DEC-169: early-exit on resolution failure before touching the gateway).\n * ASYNC (TEN-2781): a served kernel round trip (`chain.evaluateCoherence`); a gateway-unreachable\n * outcome is NOT null — it returns the visible skip banner, never a silent pass.\n */\nexport async function buildCoherenceSection(projectRoot?: string): Promise<CoherenceResult | null> {\n try {\n const root = projectRoot ?? resolveProjectRoot() ?? process.cwd();\n return await checkAndRender(root);\n } catch (err) {\n if (process.env.DEBUG_COHERENCE) {\n console.debug(\"[coherence] buildCoherenceSection failed:\", err instanceof Error ? err.message : err);\n }\n return null;\n }\n}\n\nexport { type CollectionDocFields } from \"../lib/coherence/doc-completeness.js\";\n\nexport interface DocCompletenessResult {\n lines: string[];\n errorCount: number;\n warningCount: number;\n}\n\n/**\n * Run doc-completeness check against fetched collection docs (ENT-65 / FEAT-201, replaces the\n * removed cross-registry sync rules). Caller fetches collections — this is a pure render wrapper.\n */\nexport function buildDocCompletenessSection(\n collections: CollectionDocFields[],\n): DocCompletenessResult {\n const report = checkDocCompleteness(collections);\n const lines = renderDocCompletenessLines(report);\n return { lines, errorCount: report.summary.errors, warningCount: report.summary.warnings };\n}\n\n// ─── Task alignment (WP-465 slice ③ — server verdict, connector renders) ─────\n// The local `runAlignmentCheck` matcher that used to live here MOVED into the Convex orient view\n// (convex/lib/gates/taskAlignmentPolicy.ts): both the pb CLI and this MCP server consume the SAME\n// server-computed `taskAlignment` verdict from `chain.getOrientView` (DEC-1277 §4.1 — one matcher).\n\n/** Structural mirror of the served OrientTaskAlignment payload (TEN-2278: the\n * connector cannot import convex/, so the shape is mirrored here). */\nexport interface TaskAlignmentPayload {\n verdict: \"aligned\" | \"misaligned\" | \"cold-start\" | \"unavailable\" | \"abstain\"; // WP-621 S1: +'abstain'\n disposition: \"allow\" | \"advisory\";\n coldStart: boolean;\n matchedEntry: { entryId: string | null; name: string } | null;\n matchSource: \"active_work_package\" | \"task_context\" | null;\n activeWorkPackageCount: number;\n candidates: Array<{ entryId: string; name: string; collectionSlug: string; overlapRatio: number }>;\n escapeRoutes: Array<{ kind: \"link\" | \"draft-proposal\" | \"record-divergence\"; instruction: string }>;\n citedRule: { entryId: string | null; name: string } | null;\n wording: string;\n}\n\n/**\n * Render the server-computed task-alignment verdict. Pure rendering — wording, candidates, escape\n * routes, and rule citation all arrive in the payload. Returns [] when no verdict was served.\n */\nexport function buildTaskAlignmentLines(\n ta: TaskAlignmentPayload | undefined | null,\n): string[] {\n if (!ta) return [];\n const lines: string[] = [\"## Alignment Check\"];\n lines.push(ta.wording);\n\n if (ta.candidates.length > 0) {\n lines.push(\"\");\n lines.push(\"**Candidate authorizing entries:**\");\n for (const c of ta.candidates) {\n lines.push(`- \\`${c.entryId}\\` [${c.collectionSlug}] ${c.name} (${Math.round(c.overlapRatio * 100)}% overlap)`);\n }\n }\n\n if (ta.escapeRoutes.length > 0) {\n lines.push(\"\");\n lines.push(\"**Your routes:**\");\n for (let i = 0; i < ta.escapeRoutes.length; i++) {\n lines.push(`${i + 1}. **${ta.escapeRoutes[i].kind}** — ${ta.escapeRoutes[i].instruction}`);\n }\n }\n\n if ((ta.verdict === \"misaligned\" || ta.verdict === \"abstain\") && ta.citedRule) { // WP-621 S1: abstain cites too\n lines.push(\"\");\n lines.push(`_Workspace rule: \\`${ta.citedRule.entryId ?? \"\"}\\` ${ta.citedRule.name}._`);\n }\n\n lines.push(\"\");\n return lines;\n}\n\nconst CORE_PROTOCOL_BASE = [\n \"**Search before proposing.** Before suggesting new features, architecture, or changes, \" +\n \"search the Chain: `entries action=search query=\\\"<relevant terms>\\\"`. Build on what exists.\",\n \"**Reference by ID.** When discussing a topic that has Chain entries, cite them by entry ID \" +\n \"(e.g. `DEC-50`, `PRI-3`). This keeps conversations grounded in shared knowledge.\",\n \"**Check scope.** If the proposed work doesn't fall under an active work package, stop and say so. \" +\n \"Do not design implementation for out-of-scope work without explicit user go-ahead.\",\n \"**Capture continuously.** When a decision, tension, insight, or new term surfaces during \" +\n \"work, capture it as a draft immediately. Don't defer to \\\"later.\\\"\",\n];\n\nconst RULE5_WITH_GOVERNANCE =\n \"**Validate against governance.** Before proposing any solution, check it against the \" +\n \"Workspace Governance directives below. If your proposal conflicts with a principle, standard, \" +\n \"or business rule — stop, name the conflict, and get explicit user confirmation before proceeding.\";\n\nconst RULE5_COMPACT =\n \"**Validate against governance.** Before proposing or building anything, call \" +\n \"`orient task=\\\"<your task>\\\"` to load relevant governance. If your proposal conflicts with a \" +\n \"principle, standard, or business rule — stop, name the conflict, and get explicit user confirmation.\";\n\nexport interface StandardEntry {\n entryId?: string | null;\n name: string;\n description?: string;\n /**\n * DEC-446: Relevance tier from backend. No-task scheme: 1=org, 2=domain, 3=contextual/fallback.\n * With-task: 1=governs-task-seed, 2=domain+governs, 3=org+governs, 4=fallback (see tierOf).\n */\n tier?: number;\n /** Phase 4 (DEC-1141): authority provenance tier for active governance entries. */\n provenance?: 'authoritative' | 'provisional' | 'floor';\n /** Phase 4 (DEC-1142): team name when anchor resolves — render hint, never a gate. */\n anchoredBy?: string;\n}\n\n/**\n * Phase 4 (DEC-1141): compact single-char provenance marker (★ authoritative, ~ provisional,\n * · floor; empty when absent). Mirrors the CLI's provenanceMark for consistent cross-surface UX.\n */\nexport function provenanceMark(p?: string): string {\n if (p === 'authoritative') return '★ ';\n if (p === 'provisional') return '~ ';\n if (p === 'floor') return '· ';\n return '';\n}\n\nexport interface GovernanceEntries {\n principles?: StandardEntry[];\n standards?: StandardEntry[];\n businessRules?: StandardEntry[];\n}\n\n/** A work-packages entry rendered as an active bet in the \"current scope\" list. */\nexport interface ActiveBet {\n entryId?: string | null;\n name: string;\n}\n\nconst MAX_ENTRIES_NO_TASK = 3;\nconst MAX_ENTRIES_WITH_TASK = 5;\n\n// NOTE: the keyword extractor that used to live here moved server-side with the\n// matcher (convex/lib/gates/taskAlignmentPolicy.ts extractTaskKeywords).\n\nfunction formatGovernanceEntry(entry: StandardEntry): string {\n const id = entry.entryId ?? entry.name;\n const desc = entry.description\n ? ` — ${entry.description.slice(0, 120)}${entry.description.length > 120 ? \"...\" : \"\"}`\n : \"\";\n // DEC-446 / TEN-2383: tier label. Tier meanings differ by scheme (see StandardEntry JSDoc).\n // tier 1 = direct (governs-seed under task, or org in no-task)\n // tier 2 = domain (domain+governs under task, or domain in no-task)\n // tier 3 = org (org+governs under task) or contextual/fallback (no-task)\n const tierLabel = entry.tier === 1 ? \" `[direct]`\" : entry.tier === 2 ? \" `[domain]`\" : entry.tier === 3 ? \" `[org]`\" : \"\";\n // Phase 4 (DEC-1141): prefix provenance marker and append anchoredBy when present.\n const mark = provenanceMark(entry.provenance);\n const anchorSuffix = entry.anchoredBy ? ` (${entry.anchoredBy})` : \"\";\n return `- ${mark}**[${id}]** ${entry.name}${anchorSuffix}${tierLabel}${desc}`;\n}\n\n/**\n * Build the Operating Protocol section for orient/start output. Two modes: with governance entries\n * (full, rule 5 says \"check directives below\") or without (compact, \"call orient task=... to load\n * governance\"). Accepts either the new GovernanceEntries object or a plain StandardEntry[].\n */\nexport function buildOperatingProtocol(\n governanceOrStandards?: GovernanceEntries | StandardEntry[],\n task?: string,\n): string[] {\n const governance: GovernanceEntries = Array.isArray(governanceOrStandards)\n ? { standards: governanceOrStandards }\n : governanceOrStandards ?? {};\n\n const { principles = [], standards = [], businessRules = [] } = governance;\n const hasGovernance =\n principles.length > 0 || standards.length > 0 || businessRules.length > 0;\n\n const rule5 = hasGovernance ? RULE5_WITH_GOVERNANCE : RULE5_COMPACT;\n const protocol = [...CORE_PROTOCOL_BASE, rule5];\n\n const lines: string[] = [\n \"## Operating Protocol\",\n \"_How to work in this workspace. Follow these before and during every task._\",\n \"\",\n ];\n\n for (let i = 0; i < protocol.length; i++) {\n lines.push(`${i + 1}. ${protocol[i]}`);\n }\n\n if (hasGovernance) {\n lines.push(\"\");\n lines.push(\"### Workspace governance directives\");\n\n const types: Array<{\n header: string;\n entries: StandardEntry[];\n }> = [\n { header: \"**Active principles:**\", entries: principles },\n { header: \"**Active business rules:**\", entries: businessRules },\n { header: \"**Active standards:**\", entries: standards },\n ];\n\n if (task) {\n // DEC-446 / TEN-2383: backend provides tier labels via Convex orient/startup paths; start_pb\n // and other callers may supply governance from chain.listEntries (no tier field). Graceful\n // degradation: per-bucket, tier-sort when present, else preserve stable insertion order.\n let shownCount = 0;\n let totalGovernance = 0;\n let anyTierRanking = false;\n\n for (const type of types) {\n if (type.entries.length === 0) continue;\n totalGovernance += type.entries.length;\n\n // Per-bucket tier check: if ANY entry in this bucket has a tier, sort by tier.\n // Otherwise preserve insertion order (e.g. start_pb governance from listEntries).\n const bucketHasTiers = type.entries.some((e) => e.tier !== undefined);\n if (bucketHasTiers) anyTierRanking = true;\n const sorted = bucketHasTiers\n ? [...type.entries].sort((a, b) => (a.tier ?? 99) - (b.tier ?? 99))\n : [...type.entries];\n\n const capped = sorted.slice(0, MAX_ENTRIES_WITH_TASK);\n if (capped.length > 0) {\n shownCount += capped.length;\n lines.push(type.header);\n for (const e of capped) {\n lines.push(formatGovernanceEntry(e));\n }\n lines.push(\"\");\n }\n }\n\n // TEN-2383 / TEN-2431: tier labels arrive from the shared backend ranker (DEC-446) — orient via\n // chain.getOrientView, start_pb via chain.getBindingGovernanceView (the SAME scope-BLIND\n // derivation). Untiered entries (legacy/test StandardEntry[] callers) degrade to stable\n // insertion order, never the keyword-relevance \"fifth scheme\" PR #214 removed.\n const filterNote = anyTierRanking ? \"ranked by relevance\" : \"in listing order\";\n lines.push(\n `_${shownCount} of ${totalGovernance} governance entries shown, ${filterNote}._`,\n );\n } else {\n for (const type of types) {\n if (type.entries.length === 0) continue;\n lines.push(type.header);\n for (const e of type.entries.slice(0, MAX_ENTRIES_NO_TASK)) {\n lines.push(formatGovernanceEntry(e));\n }\n lines.push(\"\");\n }\n lines.push(\n '_Showing top governance entries. Use `orient task=\"...\"` for task-relevant filtering._',\n );\n }\n }\n\n lines.push(\"\");\n return lines;\n}\n\n// ─── BET-126 Slice 2: Hierarchy-aware orient sections ────────────────────────\n\n/** Initiative status item from getOrientEntries (BET-126). */\nexport interface InitiativeStatusItem {\n id: string;\n entryId: string;\n name: string;\n targetDate: number | null;\n daysRemaining: number | null;\n}\n\n/** Workstream health item from getOrientEntries (BET-126). */\nexport interface WorkstreamHealthItem {\n id: string;\n name: string;\n betCount: number;\n activeBetNames: string[];\n}\n\n/** WP-383 S3: Advisory signal — bet with a validates relation to a KR whose outcome verification is overdue. */\nexport interface OverdueOutcomeBlocker {\n betId: string;\n betName: string;\n krId: string;\n krName: string;\n scheduledVerificationDate: string;\n daysOverdue: number;\n}\n\n/** What needs attention from getOrientEntries (BET-126). */\nexport interface WhatNeedsAttention {\n overdueBets: string[];\n blockedBets: string[];\n criticalPathBets: string[];\n /** WP-383 S3: Advisory — bets whose validates-linked KR verification window has passed. */\n overdueOutcomeBlockers?: OverdueOutcomeBlocker[];\n}\n\n/** Constellation entry item from getOrientEntries (BET-126 Slice 3). */\nexport interface ConstellationEntryItem {\n entryId: string;\n name: string;\n collectionSlug: string;\n canonicalKey: string | null;\n}\n\n/** Format Bet Constellation section for full-mode orient (BET-126 Slice 3); empty array if constellationEntries is empty — no empty headers. */\nexport function formatBetConstellationLines(\n constellationEntries: ConstellationEntryItem[] | undefined | null,\n constellationBetName?: string,\n): string[] {\n if (!constellationEntries?.length) return [];\n const betName = constellationBetName ?? \"Matched work package\";\n const lines: string[] = [\n `## Work Package Constellation — ${betName}`,\n \"_Decisions, tensions, and features related to the matched work package._\",\n \"\",\n ];\n const bySlug = new Map<string, ConstellationEntryItem[]>();\n for (const e of constellationEntries) {\n const list = bySlug.get(e.collectionSlug) ?? [];\n list.push(e);\n bySlug.set(e.collectionSlug, list);\n }\n const order = [\"decisions\", \"tensions\", \"features\"];\n for (const slug of order) {\n const entries = bySlug.get(slug);\n if (!entries?.length) continue;\n const label = slug.charAt(0).toUpperCase() + slug.slice(1);\n lines.push(`**${label}:**`);\n for (const e of entries) {\n lines.push(`- \\`${e.entryId}\\` — ${e.name}`);\n }\n lines.push(\"\");\n }\n return lines;\n}\n\n/** Format Initiative Status section for full-mode orient; empty array if initiatives is empty — no empty headers. */\nexport function formatInitiativeStatusLines(\n initiatives: InitiativeStatusItem[] | undefined | null,\n): string[] {\n if (!initiatives?.length) return [];\n const lines: string[] = [\"## Initiative Status\", \"\"];\n for (const i of initiatives) {\n const dateStr =\n i.targetDate != null\n ? new Date(i.targetDate).toISOString().split(\"T\")[0]\n : null;\n const daysPart =\n i.daysRemaining != null && dateStr\n ? `${i.daysRemaining} days to ${dateStr}`\n : dateStr\n ? `Target: ${dateStr}`\n : \"\";\n lines.push(`- \\`${i.entryId}\\` ${i.name}${daysPart ? ` — ${daysPart}` : \"\"}`);\n }\n lines.push(\"\");\n return lines;\n}\n\n/** Format Workstream Health section for full-mode orient; empty array if workstreams is empty — no empty headers. */\nexport function formatWorkstreamHealthLines(\n workstreams: WorkstreamHealthItem[] | undefined | null,\n): string[] {\n if (!workstreams?.length) return [];\n const lines: string[] = [\"## Workstream Health\", \"\"];\n for (const ws of workstreams) {\n const betDetail = ws.activeBetNames?.length\n ? ws.activeBetNames.join(\", \")\n : `${ws.betCount} work package(s)`;\n lines.push(`- ${ws.name} — ${betDetail}`);\n }\n lines.push(\"\");\n return lines;\n}\n\n/** Format What Needs Attention section for full-mode orient; empty array if nothing needs attention — no empty headers. */\nexport function formatWhatNeedsAttentionLines(\n wna: WhatNeedsAttention | undefined | null,\n): string[] {\n if (!wna) return [];\n const hasOverdue = (wna.overdueBets?.length ?? 0) > 0;\n const hasBlocked = (wna.blockedBets?.length ?? 0) > 0;\n const hasCritical = (wna.criticalPathBets?.length ?? 0) > 0;\n const hasOutcomeBlockers = (wna.overdueOutcomeBlockers?.length ?? 0) > 0;\n if (!hasOverdue && !hasBlocked && !hasCritical && !hasOutcomeBlockers) return [];\n const lines: string[] = [\"## What Needs Attention\", \"\"];\n if (hasOverdue) {\n lines.push(\"**Overdue:**\");\n for (const id of wna.overdueBets ?? []) lines.push(`- \\`${id}\\``);\n lines.push(\"\");\n }\n if (hasBlocked) {\n lines.push(\"**Blocked:**\");\n for (const id of wna.blockedBets ?? []) lines.push(`- \\`${id}\\``);\n lines.push(\"\");\n }\n if (hasCritical) {\n lines.push(\"**Critical path:**\");\n for (const id of wna.criticalPathBets ?? []) lines.push(`- \\`${id}\\``);\n lines.push(\"\");\n }\n if (hasOutcomeBlockers) {\n lines.push(\"**Overdue outcome verifications (advisory):**\");\n for (const b of wna.overdueOutcomeBlockers ?? []) {\n lines.push(`- \\`${b.betId}\\` → \\`${b.krId}\\` (${b.daysOverdue}d overdue — ${b.scheduledVerificationDate})`);\n }\n lines.push(\"\");\n }\n return lines;\n}\n\n/**\n * Compact \"What needs attention\" block for brief mode (1–3 bullets: overdue, blocked).\n * Returns empty array if nothing needs attention.\n */\nexport function formatWhatNeedsAttentionBrief(\n wna: WhatNeedsAttention | undefined | null,\n): string[] {\n if (!wna) return [];\n const overdue = wna.overdueBets ?? [];\n const blocked = wna.blockedBets ?? [];\n const critical = wna.criticalPathBets ?? [];\n const outcomeBlockers = wna.overdueOutcomeBlockers ?? [];\n if (overdue.length === 0 && blocked.length === 0 && critical.length === 0 && outcomeBlockers.length === 0) return [];\n const bullets: string[] = [\n ...overdue.slice(0, 2).map((id) => `\\`${id}\\` (overdue)`),\n ...blocked.slice(0, 2).map((id) => `\\`${id}\\` (blocked)`),\n ...critical.slice(0, 1).map((id) => `\\`${id}\\` (critical path)`),\n ...(outcomeBlockers.length > 0\n ? [`${outcomeBlockers.length} bet${outcomeBlockers.length > 1 ? \"s\" : \"\"} with overdue outcome verification`]\n : []),\n ].slice(0, 3);\n if (bullets.length === 0) return [];\n const lines: string[] = [\"**What needs attention:**\", ...bullets.map((b) => `- ${b}`), \"\"];\n return lines;\n}\n\n/** WP-560/TEN-2532 — orient/session-start shape-advisory summary shape (mirrors convex/shape/\n * precision.ts's ShapeAdvisorySummary); shared so every render site uses ONE formatter. */\nexport interface ShapeAdvisorySummaryView {\n windowDays: number; compoundTotal: number; pendingCount: number; pendingRate: number | null;\n precisionAgent: number | null; precisionAgentN: number;\n precisionHuman: number | null; precisionHumanN: number; precisionHumanNote: string | null;\n candidateRateBySource: Record<string, number | null>;\n /** Additive wire-compat sibling (precision.ts header); absent on an old-deploy payload. */\n candidateCountBySource?: Record<string, number>;\n scanTruncated: boolean;\n}\n\n/** WP-560/TEN-2532 (Codex P1): reached the server view but was never rendered on either MCP\n * surface — mirrors BET-240 S5's trustMetrics pattern (one shared formatter, every render site\n * calls it). Returns undefined when there's nothing to show. */\nexport function formatShapeAdvisorySummaryLine(sas?: ShapeAdvisorySummaryView): string | undefined {\n const sourceEntries = sas ? Object.entries(sas.candidateRateBySource ?? {}) : [];\n if (!sas || (sas.compoundTotal === 0 && sourceEntries.length === 0)) return undefined;\n // Covers EVERY gated capture, not just compound — render even at compoundTotal:0. (n=) comes\n // from the additive candidateCountBySource sibling (absent on an old deploy — falls back to none).\n const counts = sas?.candidateCountBySource ?? {};\n const candidatePart = sourceEntries.length > 0\n ? ` candidateRateBySource: ${sourceEntries.map(([src, rate]) => `${src} ${rate !== null ? `${Math.round(rate * 100)}%` : \"n/a\"}${counts[src] !== undefined ? ` (n=${counts[src]})` : \"\"}`).join(\", \")}.`\n : \"\";\n // Computed BEFORE either return branch — a zero-compound + truncated scan must still disclose it.\n const truncatedNote = sas.scanTruncated ? \" [truncated — more rows exist in this window than were scanned]\" : \"\";\n if (sas.compoundTotal === 0) {\n return `Shape advisories (${sas.windowDays}d): 0 compound.${truncatedNote}${candidatePart}`;\n }\n const agentPart = `${sas.precisionAgent !== null ? `${Math.round(sas.precisionAgent * 100)}%` : \"n/a\"} (n=${sas.precisionAgentN})`;\n const humanPart = sas.precisionHumanN > 0 ? `${Math.round((sas.precisionHuman ?? 0) * 100)}% (n=${sas.precisionHumanN})` : (sas.precisionHumanNote ?? \"no human verdicts yet\");\n // Decision-relevant: high pending means verdicts are missing, not that precision is low.\n const pendingRatePart = sas.pendingRate !== null ? ` (${Math.round(sas.pendingRate * 100)}% pending)` : \"\";\n return `Shape advisories (${sas.windowDays}d): ${sas.pendingCount} pending / ${sas.compoundTotal} compound${pendingRatePart} — precisionAgent ${agentPart}, precisionHuman ${humanPart}.${truncatedNote}${candidatePart}`;\n}\n","/**\n * WP-582 B2 (FEAT-1404) — the orient \"rituals surface\": direction/verdict-ask/spine one-liners,\n * server-computed (convex/agentKnowledge/orientRituals.ts) and rendered identically here and on\n * the pb CLI (TEN-2278: this connector cannot import convex/, so the payload is pre-rendered\n * strings — same pattern as `buildTaskAlignmentLines`, orient-shared.ts). New file rather than an\n * addition to orient-shared.ts (already at the STD-2/DEC-1504 500-LOC budget).\n *\n * `buildAlreadyOrientedResult` (added PR #532 round 1, T15) also lives here rather than inline in\n * orient.ts — that file is grandfathered at its own 500-LOC budget (STD-2/DEC-1504), so this is\n * the offsetting extraction for the round's fixes there.\n */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { success, type ToolResult } from \"../envelope.js\";\n\nexport interface RitualsSurfacePayload {\n directionLine?: string | null;\n verdictAskLine?: string;\n spineLine?: string | null;\n /** D1 residue fix (named item c): data-driven, no fallback — absent/null means nothing to\n * disclose (no C1 data yet, or nothing has ever been dropped), never a blank line. */\n atCapLine?: string | null;\n}\n\n/**\n * `directionLine`/`spineLine` always render one line each — falling back to an explicit\n * \"not computed yet\" line rather than being silently absent when the server serves `null` (the\n * no-row arm doneWhen names). `verdictAskLine` renders ONLY when the server sent a non-empty\n * string: it has no no-row arm of its own (zero live asks is a well-defined state), so an\n * empty/absent value means \"nothing to ask\" — correctly nothing, not a fallback line.\n *\n * WP-582 B2 round 1 (Codex P2 review, PR #532, T12): `fetchFailed` distinguishes \"the\n * chain.getOrientView call itself threw and orient.ts swallowed it\" from a genuine no-row arm —\n * without it both render the identical \"not computed yet\" text and an agent cannot tell an\n * outage from a workspace that has simply never run `pb direction refresh`.\n */\nexport function buildRitualsSurfaceLines(\n view: RitualsSurfacePayload | null | undefined,\n opts?: { fetchFailed?: boolean },\n): string[] {\n const lines: string[] = [\"\"];\n if (opts?.fetchFailed) {\n lines.push(\"Direction: unavailable — orient fetch failed, retry `orient`\");\n lines.push(\"Spine check: unavailable — orient fetch failed, retry `orient`\");\n return lines;\n }\n lines.push(view?.directionLine ?? \"Direction: not computed yet — `pb direction refresh`\");\n if (view?.verdictAskLine) lines.push(view.verdictAskLine);\n lines.push(view?.spineLine ?? \"Spine check: not computed yet — `pb quality spine-check`\");\n if (view?.atCapLine) lines.push(view.atCapLine);\n return lines;\n}\n\n/**\n * The \"already oriented, brief mode, no task\" shortcut (orient.ts) skips the full\n * `chain.getOrientView` fetch on purpose — it's the mid-session re-orientation shape, and paying\n * getOrientView's governance/domain/gather cost would defeat the point of a shortcut (T15). It\n * still owes the rituals surface, via the lightweight, dedicated `chain.getRitualsSurface` route\n * (registered convex/http.ts, security-contract-checked in\n * scripts/lib/directionTraceSecurityChecks.mjs) instead.\n */\nexport async function buildAlreadyOrientedResult(\n kernelQuery: <T>(fn: string, args?: Record<string, unknown>) => Promise<T>,\n agentSessionId: string | null,\n taskGroundingWarningLines: string[],\n): Promise<ToolResult> {\n let ritualsFetchFailed = false;\n let rituals: RitualsSurfacePayload | null = null;\n try {\n // PR #532 late review fix (P2, \"add a time bucket to the direct rituals query\"): matches\n // conflictQueue.ts's minute-bucket convention — forces a fresh reactive result once a snooze\n // expires on wall-clock time alone, with no corresponding DB write to bust the cache.\n rituals = await kernelQuery<GatewayRouteReturnByName<\"chain.getRitualsSurface\">>(\"chain.getRitualsSurface\", {\n now: Math.floor(Date.now() / 60_000) * 60_000,\n });\n } catch {\n ritualsFetchFailed = true;\n }\n const ritualsLines = buildRitualsSurfaceLines(rituals, { fetchFailed: ritualsFetchFailed });\n return {\n content: [{\n type: \"text\" as const,\n text:\n \"Already oriented. Session active, writes unlocked.\\n\" +\n ritualsLines.join(\"\\n\") + \"\\n\\n\" +\n taskGroundingWarningLines.join(\"\\n\") +\n \"Use `orient mode='full'` for workspace context or `orient task='...'` before substantive work.\",\n }],\n structuredContent: success(\n \"Already oriented. Session active, writes unlocked.\",\n {\n alreadyOriented: true,\n sessionId: agentSessionId,\n taskGroundingStatus: \"workspace_only\",\n taskGroundingRequired: true,\n nextStep: 'Run `orient task=\"describe the work\"` before substantive work.',\n // T1's undefined-vs-null distinction: omit the key on a fetch failure, keep an explicit\n // null for a genuine no-row arm.\n ...(rituals?.directionLine !== undefined ? { directionLine: rituals.directionLine } : {}),\n ...(rituals?.verdictAskLine !== undefined ? { verdictAskLine: rituals.verdictAskLine } : {}),\n ...(rituals?.spineLine !== undefined ? { spineLine: rituals.spineLine } : {}),\n // PR #538 late review fix (P2, \"include at-cap disclosure in structured orient output\"):\n // atCapLine renders in TEXT (buildRitualsSurfaceLines) but was never mirrored into\n // structuredContent — a structured-content consumer silently missed the dropped-at-cap\n // warning even when the same response's text carried it.\n ...(rituals?.atCapLine !== undefined ? { atCapLine: rituals.atCapLine } : {}),\n },\n ),\n };\n}\n","/**\n * `reportOrientWrapperBytes` — extracted out of orient.ts (STD-2/DEC-1504: that file is\n * grandfathered shrink-only, so WP-582 B2's growth there needs an equal-or-greater offsetting\n * extraction in the SAME PR). Pure fire-and-forget observability helper, module-private in its\n * original home.\n */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelMutation, getAgentSessionId, getConversationId } from \"../client.js\";\n\n/**\n * WP-376 α.3: measure assembled MCP tool output bytes for orient and report\n * fire-and-forget to the gateway. The number captured here is the byte size\n * of the full MCP `tool_result` payload (content array JSON-serialized) — the\n * surface-side counterpart to the gateway's envelope-bytes measurement.\n *\n * Errors are swallowed: observability must never block the orient response or\n * affect the user-visible output. The gateway resolves workspaceId / apiKeyId\n * from the API-key context (BR-18 + injectSessionAuth).\n *\n * Skipped when `truncated` cannot be determined AND no orient view returned\n * (e.g. the early `Already oriented` return path with no orient data).\n *\n * DEC-NEW: also reports the resolved tier + task-presence for observability.\n */\nexport function reportOrientWrapperBytes(\n toolResult: { content: Array<{ type: string; text: string }>; structuredContent?: unknown },\n truncated: boolean,\n tier: \"summary\" | \"standard\" | \"full\",\n taskProvided: boolean,\n): void {\n try {\n const fullToolOutput = JSON.stringify({ content: toolResult.content ?? [] });\n const bytes = Buffer.byteLength(fullToolOutput, \"utf8\");\n // Thread the active session context (Codex re-review) so the server's N-per-key ambiguity guard doesn't drop this rendered-byte report.\n const sessionId = getAgentSessionId();\n const conversationId = getConversationId();\n void kernelMutation<GatewayRouteReturnByName<\"agent.reportOrientMetric\">>(\"agent.reportOrientMetric\", {\n bytes,\n truncated,\n tier,\n taskProvided,\n ...(sessionId ? { sessionId } : {}),\n ...(conversationId ? { conversationId } : {}),\n }).catch(() => {\n // Best-effort observability — silently swallow.\n });\n } catch {\n // Even building the byte count failed (e.g. circular structuredContent in\n // an unexpected shape) — never let it surface to the caller.\n }\n}\n","/**\n * WP-621 (grounding S1, Copilot review PR #599): the server's `degradedPreloads` marker\n * (convex/agentKnowledge/orientPreloadFallbacks.ts) named which task preload(s) fell back to a\n * typed-empty default this run — but it was served only on the raw Convex view, never rendered\n * by either connector, so a degraded run silently looked like a normal thinner result\n * (undermining \"serve less, LABELLED\"). Offset extraction out of tools/orient.ts (STD-2/\n * DEC-1504 shrink-only budget) — one shared line-builder for both the brief and full text\n * renderers.\n */\nexport function buildDegradedPreloadsLine(degraded?: readonly string[] | null): string | null {\n if (!degraded || degraded.length === 0) return null;\n return `⚠️ Degraded this run: ${degraded.join(\", \")} preload(s) failed open — results may be thinner than usual.`;\n}\n\n/**\n * WP-485 Slice 1 review fix (Codex P2, PR #367, \"Render coherency status on the MCP orient\n * surface\"): mirrors packages/cli/src/formatters/orientDegradation.ts's own coherencyCheckTag —\n * the CLI formatter surfaced this per-bet marker, but the MCP orient tool never rendered it, so\n * an MCP agent saw silent-clean for a bet whose latest contradiction-detection status is\n * partial/unavailable/never-run. coherence-run-sweep fix (PR #423, Codex P2): TEN-2746 §2c added\n * a THIRD status, 'stale' — an MCP agent (the surface that actually performs `updateEntry`) saw\n * a stale active work package fall through to the empty-string branch and render as silently\n * fresh. Relocated here (STD-2/DEC-1504 shrink-only offset, WP-621 S1).\n */\nexport function coherencyCheckTag(status: \"not_checked\" | \"check_incomplete\" | \"stale\" | undefined): string {\n if (status === \"not_checked\") return \" [not checked]\";\n if (status === \"check_incomplete\") return \" [check incomplete]\";\n if (status === \"stale\") return \" [stale — entry changed since last check]\";\n return \"\";\n}\n","/**\n * gapToPrompt.ts — Readiness gaps as conversation, not compliance.\n *\n * FEAT-62 (BET-64 Slice 1): Translates raw readiness gap data into\n * natural-language prompts with contextual framing. The user should\n * hear a collaborator suggesting what to work on — never a checklist.\n *\n * Consumed by orient (health.ts) and start (start.ts).\n * Source prompts come from collection.readinessGuidance (DB).\n */\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface ReadinessGap {\n id: string;\n label: string;\n guidance: string;\n capabilityGuidance?: string;\n canonicalKey?: string;\n current: number;\n required: number;\n}\n\nexport interface GapContext {\n stage: string;\n passedChecks: number;\n totalChecks: number;\n score: number;\n}\n\n// ── Label cleanup ────────────────────────────────────────────────────────────\n// Raw gap labels come through as \"Glossary has entries\" or \"Strategy — your\n// product vision\". Strip the mechanical suffixes to get a clean noun.\n\nfunction cleanLabel(label: string): string {\n return label\n .replace(/ has entries$/i, \"\")\n .replace(/ coverage$/i, \"\")\n .replace(/^Strategy — /i, \"\");\n}\n\n// ── Progress framing ─────────────────────────────────────────────────────────\n// One sentence that grounds the user in where they are. Warm, not clinical.\n\nfunction progressFrame(ctx: GapContext): string {\n if (ctx.passedChecks === 0) {\n return \"Your Brain is just getting started.\";\n }\n if (ctx.passedChecks === 1) {\n return \"Your Brain has one area covered so far.\";\n }\n if (ctx.score >= 70) {\n return `Your Brain covers ${ctx.passedChecks} areas — almost there.`;\n }\n return `Your Brain covers ${ctx.passedChecks} of ${ctx.totalChecks} areas.`;\n}\n\n// ── Single gap prompt ────────────────────────────────────────────────────────\n\n/**\n * Format the most impactful gap as a conversational next-step prompt.\n * Used in orient (low-readiness) and start (orient-style) responses.\n */\nexport function formatTopGapPrompt(\n gap: ReadinessGap,\n remaining: number,\n ctx: GapContext,\n): string {\n const prompt = gap.capabilityGuidance ?? gap.guidance;\n const label = cleanLabel(gap.label);\n\n const lines = [\n progressFrame(ctx),\n remaining > 0\n ? `The biggest gap right now: **${label}**.`\n : `One area would strengthen it: **${label}**.`,\n \"\",\n prompt,\n ];\n\n return lines.join(\"\\n\");\n}\n\n// ── Multi-gap list ───────────────────────────────────────────────────────────\n\n/**\n * Format multiple gaps as natural suggestions (not a checklist).\n * Used in start seeded response and orient full mode.\n */\nexport function formatGapList(\n gaps: ReadinessGap[],\n limit = 3,\n): string[] {\n const topGaps = gaps.slice(0, limit);\n if (topGaps.length === 0) return [];\n\n const lines: string[] = [\n \"Here's where your Brain would benefit most:\",\n \"\",\n ];\n\n for (let i = 0; i < topGaps.length; i++) {\n const gap = topGaps[i];\n const prompt = gap.capabilityGuidance ?? gap.guidance;\n const label = cleanLabel(gap.label);\n lines.push(`${i + 1}. **${label}** — ${prompt}`);\n }\n\n return lines;\n}\n\n// ── Brief-mode one-liner ─────────────────────────────────────────────────────\n\n/**\n * One-line gap summary for brief orient mode.\n * Returns null if no gaps.\n */\nexport function formatGapOneLiner(gap: ReadinessGap | undefined): string | null {\n if (!gap) return null;\n const prompt = gap.capabilityGuidance ?? gap.guidance;\n return `Next gap: ${prompt}`;\n}\n","/**\n * Synced from convex/lib/canonicalRefs.ts (WP-345: canonical refs, NG4: MCP import boundary).\n * GENERATED by scripts/generate-canonical-refs-copies.mjs — DO NOT EDIT BY HAND.\n * Run `npm run refs:sync` to regenerate after editing the source.\n */\n/**\n * Canonical Refs — pure parser for semantic ref syntax.\n *\n * WP-640 S2 (TASK-63): THIS FILE IS THE SINGLE SOURCE. `packages/cli/src/lib/canonicalRefs.ts`\n * and `packages/mcp-server/src/lib/canonicalRefs.ts` are GENERATED mirrors (scripts/generate-\n * canonical-refs-copies.mjs) — never hand-edit them. Edit here, then `npm run refs:sync` (writes\n * both copies) and `npm run refs:sync:check` to verify (no drift). Folding all three into a real\n * shared package (e.g. `kernel`, which already declares \"ZERO Convex imports\" and is already a\n * `cli` devDependency) was considered and DECLINED: `scripts/check-mcp-boundaries.mjs` (BR-25,\n * TEN-174) unconditionally fails any `packages/mcp-server/src` file importing from outside the\n * package — a live `kernel` import there is structurally blocked, not just risky — and a new\n * kernel/ folder also needs a WP-537 kind-manifest row. This generate+check pair reuses the SAME\n * \"copy-free at the source-editing level, physically-copied at the build level\" pattern\n * `scripts/generate-mcp-embedded-copies.mjs` already established for flags_core.ts/logo-markup.ts\n * for exactly this MCP-boundary reason — not a new mechanism, the established one. It collapses\n * the \"3 independently hand-copy-pasted files\" problem the doneWhen names (a human previously had\n * to remember to edit three files identically) down to ONE edited source with caught drift. NG4\n * (WP-345) is UNCHANGED: CLI/MCP still must not import the resolver (convex/canonicalRefs.ts, no\n * `lib/`) — only this pure parser.\n *\n * Zero Convex imports. This file is drift-synced to:\n * - packages/cli/src/lib/canonicalRefs.ts (CLI copy — identical logic)\n * - packages/mcp-server/src/lib/canonicalRefs.ts (MCP copy — identical logic)\n *\n * NG4 (WP-345): CLI/MCP MUST NOT import the resolver (convex/canonicalRefs.ts).\n * They import only this pure parser module.\n *\n * DEC-A/WP-354: semantic refs syntax is {{ref:canonicalKey}},\n * {{ref:canonicalKey:display}}, {{ref:domain:data/analytics}}, or\n * {{ref:entry:DEC-123}}.\n * Chain: WP-345 E4, DEC-K (projection hash trailer)\n *\n * WP-436 S1 — Axis 2 vocabulary resolver (DEC-1021, STD-253):\n * {{vocab:<canonicalKey>.<form>}} tokens + getCollectionLabel resolver.\n * PAT-230: resolver is pure — no Convex import, workspace context passed as arg.\n */\n\n/**\n * WP-354 Build-Order #6: Setup-ref resolver return shape.\n *\n * All consumers (CLI, MCP, handshake, editor health) must read\n * the discriminated kind+status fields instead of an optional resolved object.\n *\n * Spec: docs/system/design/authority-domains-design-spec.md §632\n * Chain: WP-354 Slice H, STD-101 (single source of truth)\n *\n * drift-synced to:\n * - packages/cli/src/lib/canonicalRefs.ts\n * - packages/mcp-server/src/lib/canonicalRefs.ts\n */\nexport type SetupRefResolution = {\n\tref: string;\n\tkind: 'entry' | 'domain' | 'seed' | 'unknown';\n\tstatus:\n\t\t| 'resolved' // entry/domain found\n\t\t| 'unresolved' // valid syntax but no match\n\t\t| 'unsupported-future' // seed:* — future scope\n\t\t| 'invalid' // ref couldn't be parsed\n\t\t;\n\t/** Human-readable entryId (e.g. 'BR-5'). Only when status='resolved' for kind='entry' or 'domain'. */\n\tlocalEntryId?: string;\n\t/** Domain slug (e.g. 'engineering/backend'). Only when kind='domain' and status='resolved'. */\n\tcanonicalSlug?: string;\n\t/** true when kind is 'entry' or 'domain'; false for seed/unknown */\n\trequired: boolean;\n\tmessage?: string;\n\taction?: string;\n};\n\n/**\n * Regex for matching semantic refs. Captures: [1] ref key/path, [2] optional display label.\n */\nconst SEMANTIC_REF_REGEX = /\\{\\{ref:([a-zA-Z0-9_./-]+(?::[a-zA-Z0-9_./-]+)?)(?::([^}]+))?\\}\\}/g;\n\n/**\n * Extracts canonical keys from a body string.\n * Handles {{ref:key}} and {{ref:key:display}}.\n *\n * Returns deduplicated array of canonical keys in order of first appearance.\n */\nexport function parseSemanticRefs(body: string): string[] {\n\tif (!body || body.length === 0) return [];\n\n\tconst keys: string[] = [];\n\tconst seen = new Set<string>();\n\n\t// Reset lastIndex for global regex before each use\n\tconst regex = new RegExp(SEMANTIC_REF_REGEX.source, 'g');\n\tlet match: RegExpExecArray | null;\n\n\twhile ((match = regex.exec(body)) !== null) {\n\t\tconst key = match[1];\n\t\tif (key && !seen.has(key)) {\n\t\t\tseen.add(key);\n\t\t\tkeys.push(key);\n\t\t}\n\t}\n\n\treturn keys;\n}\n\n/**\n * Renders a resolved ref for display in projected output.\n * Falls back to the raw key wrapped in brackets if no resolved name is available.\n *\n * Examples:\n * renderSemanticRef('bet', 'Active Bets') → 'Active Bets'\n * renderSemanticRef('bet') → '[bet]'\n * renderSemanticRef('bet', undefined) → '[bet]'\n */\nexport function renderSemanticRef(key: string, resolvedName?: string): string {\n\tif (resolvedName && resolvedName.trim().length > 0) {\n\t\treturn resolvedName.trim();\n\t}\n\treturn `[${key}]`;\n}\n\n/**\n * Replaces all semantic refs in a body string with their resolved display names.\n *\n * resolvedMap: Map<canonicalKey, resolvedName> — keys not in the map are rendered\n * as [unresolved: key] to make missing refs visible.\n */\nexport function replaceSemanticRefs(body: string, resolvedMap: Map<string, string>): string {\n\tif (!body || body.length === 0) return body;\n\n\tconst regex = new RegExp(SEMANTIC_REF_REGEX.source, 'g');\n\n\treturn body.replace(regex, (_match, key: string, displayLabel: string | undefined) => {\n\t\t// If an inline display label is provided, it takes precedence over the resolved name\n\t\tif (displayLabel && displayLabel.trim().length > 0) {\n\t\t\treturn displayLabel.trim();\n\t\t}\n\t\tconst resolved = resolvedMap.get(key);\n\t\tif (resolved) {\n\t\t\treturn resolved;\n\t\t}\n\t\treturn `[unresolved: ${key}]`;\n\t});\n}\n\n// ─── Axis 2 Vocabulary Resolver (WP-436 S1) ─────────────────────────────────\n// STD-253: {{vocab:<canonicalKey>.<form>}} token grammar.\n// PAT-230: pure resolver — no Convex import. WorkspaceCtx is passed as arg.\n// DEC-1021: Axis 2 is INDEPENDENT of Axis 1 (displayNames). Never merge.\n\n/**\n * Label set for a single canonical type (Axis 2, DEC-1021).\n * All fields optional — undefined means \"derive from next layer\".\n */\nexport type LabelSet = {\n\tsingular?: string;\n\tplural?: string;\n\tverb_start?: string;\n\tverb_commit?: string;\n\tverb_review?: string;\n\tverb_complete?: string;\n\tverb_archive?: string;\n};\n\n/** Valid form names for a LabelSet. */\nexport type LabelForm = keyof LabelSet;\n\n/**\n * Minimal workspace context for Axis 2 resolution.\n * Passed by the caller — keeps the resolver pure (PAT-230).\n */\nexport type WorkspaceVocabCtx = {\n\t/** Per-workspace overrides: canonicalKey → LabelSet (partial). */\n\tcollectionLabels?: Record<string, LabelSet | undefined>;\n\t/**\n\t * Layer 2 defaults from system_collection_definitions.labels, keyed by canonicalKey.\n\t * Fetched via chain.getVocabulary collectionDefaults and threaded through by the caller.\n\t * Used as fallback when no workspace override exists and collectionCtx is not passed.\n\t * WP-436 completion — wires dead Layer 2 to consumers.\n\t */\n\tcollectionDefaults?: Record<string, LabelSet | undefined>;\n};\n\n/**\n * Minimal collection context for Axis 2 resolution.\n * Passed by the caller — keeps the resolver pure (PAT-230).\n */\nexport type CollectionVocabCtx = {\n\t/** Collection-level default labels (from system_collection_definitions.labels). */\n\tlabels?: LabelSet;\n};\n\n/**\n * Regex for matching vocab tokens: {{vocab:<canonicalKey>.<form>}}\n * STD-253: canonicalKey + form are both lowercase snake_case.\n * Captures: [1] canonicalKey, [2] form.\n */\nexport const VOCAB_TOKEN_REGEX = /\\{\\{vocab:([a-z_]+)\\.([a-z_]+)\\}\\}/g;\n\n/**\n * Resolve the display label for a canonical type + form.\n *\n * Resolution chain (DEC-1021):\n * 1. workspaceCtx.collectionLabels[canonicalKey][form] — workspace override\n * 2. collectionCtx.labels[form] — collection default\n * 3. canonicalKey literal — fallback (no throw)\n *\n * Pure function. No Convex imports. No side effects. (PAT-230)\n *\n * @param canonicalKey - e.g. 'work_package', 'decision'\n * @param form - e.g. 'singular', 'plural', 'verb_start'\n * @param workspaceCtx - optional workspace-level override context\n * @param collectionCtx - optional collection-level default context\n * @returns resolved label string\n */\nexport function getCollectionLabel(\n\tcanonicalKey: string,\n\tform: string,\n\tworkspaceCtx?: WorkspaceVocabCtx,\n\tcollectionCtx?: CollectionVocabCtx,\n): string {\n\t// Layer 1: workspace override\n\tconst wsLabels = workspaceCtx?.collectionLabels?.[canonicalKey];\n\tif (wsLabels) {\n\t\tconst wsVal = (wsLabels as Record<string, string | undefined>)[form];\n\t\tif (wsVal !== undefined && wsVal.length > 0) return wsVal;\n\t}\n\n\t// Layer 2: explicit collection ctx (granular call sites — handshake projector)\n\tconst colLabels = collectionCtx?.labels;\n\tif (colLabels) {\n\t\tconst colVal = (colLabels as Record<string, string | undefined>)[form];\n\t\tif (colVal !== undefined && colVal.length > 0) return colVal;\n\t}\n\n\t// Layer 2.5: collection defaults from WorkspaceVocabCtx (threaded via chain.getVocabulary)\n\t// New: wires the dead Layer 2 path for consumers that don't pass explicit collectionCtx.\n\tconst defaultLabels = workspaceCtx?.collectionDefaults?.[canonicalKey];\n\tif (defaultLabels) {\n\t\tconst defVal = (defaultLabels as Record<string, string | undefined>)[form];\n\t\tif (defVal !== undefined && defVal.length > 0) return defVal;\n\t}\n\n\t// Layer 3: canonicalKey literal fallback\n\treturn canonicalKey;\n}\n\n/**\n * Replace all {{vocab:<canonicalKey>.<form>}} tokens in a string.\n *\n * For each token, calls getCollectionLabel with the provided contexts.\n * STD-253.\n */\nexport function replaceVocabTokens(\n\tbody: string,\n\tworkspaceCtx?: WorkspaceVocabCtx,\n\tcollectionCtxMap?: Map<string, CollectionVocabCtx>,\n): string {\n\tif (!body || body.length === 0) return body;\n\n\tconst regex = new RegExp(VOCAB_TOKEN_REGEX.source, 'g');\n\n\treturn body.replace(regex, (_match, canonicalKey: string, form: string) => {\n\t\tconst collectionCtx = collectionCtxMap?.get(canonicalKey);\n\t\treturn getCollectionLabel(canonicalKey, form, workspaceCtx, collectionCtx);\n\t});\n}\n","/**\n * `start_pb` MCP tool — universal session opener implementing PAT-227.\n *\n * WP-433 S3 (FEAT-1296) — collapses `start` + `start_pb` into ONE tool. Canonical name: keeping\n * `start_pb` (Option A, DEC supersedes DEC-997) — the user trigger is literally \"Start PB\".\n *\n * Stage-branched delivery (PAT-227):\n * blank / seeded → SKILL-pb-setup body verbatim via loadSkillBody (DEC-1016 SSOT)\n * grounded / connected → orient-style standup briefing from start.ts buildOrientResponse\n * readiness failure → orient-style (safest degraded path — never show setup on active ws)\n *\n * TEN-2028: surfaceCapability self-declaration removed from recordSetupInvocation call (it was\n * best-effort / wrapped in try-catch). stampMcpOnlySurface stays, blank/seeded only (DEC-993/STD-235).\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport {\n kernelQuery,\n kernelMutation,\n kernelCall,\n getWorkspaceContext,\n getAgentSessionId,\n getConversationId,\n setSessionOriented,\n} from \"../client.js\";\nimport { success, failure, textContent, type NextAction } from \"../envelope.js\";\nimport { loadSkillBody, type SkillBodyResult } from \"./skills.js\";\nimport { queryPlannedWork, hasPlannedWork, buildPlannedWorkSection, formatRecoveryBlock, type PriorSession } from \"./planned-work.js\";\nimport { buildOperatingProtocol, buildCoherenceSection, buildDocCompletenessSection, formatShapeAdvisorySummaryLine, type ActiveBet, type CoherenceSnapshot, type StandardEntry, type CollectionDocFields, type GovernanceEntries, type ShapeAdvisorySummaryView } from \"./orient-shared.js\";\nimport { getTopGaps } from \"../gap-store.js\";\nimport { formatTopGapPrompt, formatGapList, type ReadinessGap, type GapContext } from \"../lib/gapToPrompt.js\";\nimport { FEEDBACK_SUBMIT_HINT } from \"../lib/sessionNotices.js\";\n\nexport const startPbSchema = z.object({\n task: z\n .string()\n .max(2000)\n .optional()\n .describe(\n \"What you're about to work on (e.g. 'implementing auth middleware'). \" +\n \"Grounded/connected workspaces: filters governance to show relevant principles, standards, and business rules. \" +\n \"Blank/seeded workspaces: ignored (setup flow takes over).\",\n ),\n // TEN-2431: no `scope` param — start_pb's governance matches orient's scope-BLIND RENDERED\n // governance; domain-scoping is deferred to TEN-2429 (must change both together, INS-1864).\n});\n\nconst PB_SETUP_SKILL_ENTRY_ID = \"SKILL-pb-setup\";\n\n// Codex P2 (PR #372): the feedback invite (FEEDBACK_SUBMIT_HINT, ../lib/sessionNotices.js) rides\n// EVERY start response shape — the setup path (blank/seeded) returns early, and without the hint\n// there, agents starting against a fresh workspace never saw it, even though setup friction is a\n// primary capture scenario. WP-584 S4: session.ts imports the SAME constant instead of its own\n// independent copy (FEAT-1412's triplication fix).\n\n/**\n * TEN-1740: structural mirror of planned-work.ts's `formatRecoveryBlock` parameter shape\n * (itself a mirror of convex's OrientRecoveryBlock; also mirrored in orient.ts's\n * `RecoveryBlockData`). Declared once here so every call site in this file shares one type\n * instead of a per-call-site `as Parameters<...>` cast.\n */\ntype RecoveryBlockData = {\n sessionId: string;\n status: \"timed_out\" | \"completed\";\n date: string;\n duration: string;\n created: { entryId: string; collection: string; name: string }[];\n modified: { entryId: string; collection: string; name: string }[];\n draftsNeedingAttention: { entryId: string; collection: string; name: string }[];\n relationsCreated: number;\n createdOverflow?: number;\n modifiedOverflow?: number;\n draftsOverflow?: number;\n};\n\n/** Shape returned by chain.workspaceReadiness — local mirror of Convex type. */\ninterface WorkspaceReadiness {\n score: number;\n totalChecks: number;\n passedChecks: number;\n checks: Array<{ passed: boolean; label: string; current: number; required: number }>;\n gaps: ReadinessGap[];\n stats: {\n totalEntries: number;\n activeCount: number;\n draftCount: number;\n totalRelations: number;\n collectionCount: number;\n orphanedCount: number;\n };\n stage: \"blank\" | \"seeded\" | \"grounded\" | \"connected\";\n scoringVersion: \"v1\" | \"v2\";\n governanceMode?: string;\n}\n\nasync function tryMarkOriented(\n agentSessionId: string | null,\n coherenceSnapshot?: CoherenceSnapshot,\n): Promise<{\n oriented: boolean;\n orientationStatus: \"complete\" | \"failed\" | \"no_session\";\n}> {\n if (!agentSessionId) return { oriented: false, orientationStatus: \"no_session\" };\n try {\n await kernelCall<GatewayRouteReturnByName<\"agent.markOriented\">>(\"agent.markOriented\", {\n sessionId: agentSessionId,\n ...(coherenceSnapshot ? { coherenceSnapshot } : {}),\n });\n setSessionOriented(true);\n return { oriented: true, orientationStatus: \"complete\" };\n } catch {\n if (!coherenceSnapshot) {\n return { oriented: false, orientationStatus: \"failed\" };\n }\n try {\n await kernelCall<GatewayRouteReturnByName<\"agent.markOriented\">>(\"agent.markOriented\", { sessionId: agentSessionId });\n setSessionOriented(true);\n return { oriented: true, orientationStatus: \"complete\" };\n } catch {\n return { oriented: false, orientationStatus: \"failed\" };\n }\n }\n}\n\n/** TEN-547: Bets collection filter — status at top-level or in data. */\nfunction isActiveNowBet(e: { status?: string; data?: Record<string, unknown> }): boolean {\n const status = e.status ?? (e.data as { status?: string } | undefined)?.status;\n const horizon = (e.data as { horizon?: string } | undefined)?.horizon;\n return status === \"active\" && horizon === \"now\";\n}\n\nfunction computeWorkspaceAge(createdAt: number | null): { ageDays: number; isNeglected: boolean } {\n if (!createdAt) return { ageDays: 0, isNeglected: false };\n const ageDays = Math.floor((Date.now() - createdAt) / (1000 * 60 * 60 * 24));\n return { ageDays, isNeglected: ageDays >= 30 };\n}\n\nfunction pickNextTensionPrompt(\n openTensions: Array<{ name: string }>,\n): { action: string; cta: string } | null {\n if (openTensions.length === 0) return null;\n const t = openTensions[0];\n return {\n action: `Open tension: ${t.name}`,\n cta: \"Want to discuss this tension or capture a decision about it?\",\n };\n}\n\n/**\n * Blank/seeded stage: return SKILL-pb-setup body verbatim (DEC-1016 SSOT).\n * Also stamps the MCP-only surface for chat-only callers (DEC-993 / STD-235).\n *\n * TEN-2028: recordSetupInvocation call removed — it required surfaceCapability\n * as a required argument, which would constitute self-declaration of surface\n * capability. The invocation receipt can be recorded by the CLI path or a\n * dedicated record_activation call post-onboarding.\n */\nasync function buildSetupResponse(\n agentSessionId: string | null,\n): Promise<{ text: string; structuredContent: Record<string, unknown> }> {\n // DEC-993 / STD-235: stamp manifest.surfaces with mcp-only (forward-only union)\n await kernelMutation<GatewayRouteReturnByName<\"setup.stampMcpOnlySurface\">>(\n \"setup.stampMcpOnlySurface\",\n {},\n );\n\n const skill: SkillBodyResult = await loadSkillBody(PB_SETUP_SKILL_ENTRY_ID);\n\n const { oriented, orientationStatus } = await tryMarkOriented(agentSessionId);\n\n return {\n text: skill.body,\n structuredContent: success(\n `pb-setup ready. Delivering SKILL-pb-setup body (${skill.body.length} chars).`,\n {\n bootstrap: \"pb-setup\",\n skillEntryId: skill.entryId,\n skillBody: skill.body,\n stage: \"setup\",\n oriented,\n orientationStatus,\n ...(agentSessionId ? { sessionId: agentSessionId } : {}),\n instructions: \"Read skillBody and follow it; use entries/orient MCP tools per PAT-227.\",\n },\n ),\n };\n}\n\n/**\n * Grounded/connected stage: return orient-style standup briefing.\n * Mirrors buildOrientResponse from the former start.ts.\n */\n/**\n * TEN-2431: rendered-governance row shape returned by chain.getBindingGovernanceView.\n * These are orient's top-level display rows (makeOrientToDisplay) — `tier` rides each\n * entry (DEC-446 tiered ranker); `preview` is the description/WHY.\n */\ntype BindingGovernanceEntry = { entryId?: string | null; name: string; preview?: string; tier?: number };\ntype BindingGovernanceView = {\n bindingGovernance?: {\n principles?: BindingGovernanceEntry[];\n standards?: BindingGovernanceEntry[];\n businessRules?: BindingGovernanceEntry[];\n };\n};\n\nasync function buildOrientResponse(\n wsCtx: { workspaceName: string; workspaceSlug: string; workspaceId: string; createdAt?: number | null; governanceMode?: string },\n agentSessionId: string | null,\n errors: string[],\n task?: string,\n): Promise<{ text: string; structuredContent: Record<string, unknown> }> {\n const { ageDays, isNeglected } = computeWorkspaceAge(wsCtx.createdAt ?? null);\n\n let priorSessions: PriorSession[] = [];\n let recoveryBlock: RecoveryBlockData | null = null;\n try {\n // WP-479 review fix (Codex): scope recovery to THIS conversation when one resolves. Once N\n // conversations share one API key, a bare `{ limit: 3 }` surfaces another concurrent\n // conversation's closed sessions/drafts for the same key — the cross-talk the server-side\n // conversationId filter (agentSessions.getRecentClosedSessions) exists to prevent. Thread the\n // MCP conversation identity so the filter engages; absent identity ⇒ legacy shared behavior.\n const recentConversationId = getConversationId();\n const sessionsResult = await kernelQuery<GatewayRouteReturnByName<\"agent.recentSessions\">>(\n \"agent.recentSessions\",\n recentConversationId ? { limit: 3, conversationId: recentConversationId } : { limit: 3 },\n );\n priorSessions = sessionsResult?.sessions ?? [];\n recoveryBlock = sessionsResult?.recoveryBlock ?? null;\n } catch { /* non-critical */ }\n\n let openTensions: Array<{ name: string; entryId?: string }> = [];\n try {\n // Same `chain.listEntries` union residual documented in wrapup.ts — cast to the fields\n // this call actually reads (PR #395, Lane C S3b annotation pass).\n const tensions = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"tensions\" });\n openTensions = ((tensions ?? []) as Array<{ name: string; entryId?: string; workflowStatus?: string }>).filter(\n (e) => e.workflowStatus === \"open\",\n );\n } catch { /* non-critical */ }\n\n let readiness: WorkspaceReadiness | null = null;\n try {\n readiness = await kernelQuery<GatewayRouteReturnByName<\"chain.workspaceReadiness\">>(\"chain.workspaceReadiness\");\n } catch (e: unknown) {\n errors.push(`Readiness: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n const lines: string[] = [];\n const isLowReadiness = readiness !== null && readiness.score < 50;\n const isHighReadiness = readiness !== null && readiness.score >= 50;\n const stage: string | null = readiness?.stage ?? null;\n const captureBehaviorNote =\n wsCtx.governanceMode === \"open\"\n ? \"_In Open mode, user-authored captures are accepted immediately unless you ask me to keep them as drafts._\"\n : \"_Everything I capture stays pending until you confirm._\";\n\n const coherence = await buildCoherenceSection();\n\n let allCollections: CollectionDocFields[] = [];\n try {\n allCollections = (await kernelQuery<CollectionDocFields[]>(\"chain.listCollections\")) ?? [];\n } catch { /* non-critical */ }\n\n // PR #519 review round 2 (Codex P1, load-bearing): action=start is the tool's documented\n // universal opener — it must carry the same shapeAdvisorySummary line orient's other 3 render\n // sites do, via its own lightweight route (chain.shapeAdvisorySummary, precision.ts header).\n let shapeAdvisorySummary: ShapeAdvisorySummaryView | undefined;\n try {\n shapeAdvisorySummary = await kernelQuery<ShapeAdvisorySummaryView>(\"chain.shapeAdvisorySummary\");\n } catch { /* non-critical */ }\n\n lines.push(`# ${wsCtx.workspaceName}`);\n lines.push(\"_Product Brain is ready._\");\n lines.push(\"\");\n const startShapeLine = formatShapeAdvisorySummaryLine(shapeAdvisorySummary);\n if (startShapeLine) lines.push(startShapeLine, \"\");\n\n if (isLowReadiness && isNeglected) {\n const stageNote = stage ? ` and is still at the **${stage}** stage` : \"\";\n lines.push(`Your workspace has been around for ${ageDays} days${stageNote}.`);\n lines.push(\"Let's close the gaps — or if the current structure doesn't fit, we can reshape it.\");\n lines.push(\"\");\n } else if (isLowReadiness) {\n lines.push(\"Let's get your workspace active.\");\n lines.push(\"\");\n }\n\n if (isLowReadiness && readiness) {\n const gaps: ReadinessGap[] = readiness.gaps ?? [];\n if (gaps.length > 0) {\n const gapCtx: GapContext = {\n stage: stage ?? \"seeded\",\n passedChecks: readiness.passedChecks ?? 0,\n totalChecks: readiness.totalChecks ?? 0,\n score: readiness.score ?? 0,\n };\n\n lines.push(formatTopGapPrompt(gaps[0], gaps.length - 1, gapCtx));\n lines.push(\"\");\n lines.push(captureBehaviorNote);\n lines.push(\"\");\n\n const remainingGaps = gaps.length - 1;\n if (remainingGaps > 0 || openTensions.length > 0) {\n const parts: string[] = [];\n if (remainingGaps > 0) parts.push(`${remainingGaps} more area${remainingGaps === 1 ? \"\" : \"s\"} to cover`);\n if (openTensions.length > 0) parts.push(`${openTensions.length} open tension${openTensions.length === 1 ? \"\" : \"s\"}`);\n lines.push(`_${parts.join(\" and \")} — ask for full status to see everything._`);\n lines.push(\"\");\n }\n } else {\n const tensionPrompt = pickNextTensionPrompt(openTensions);\n if (tensionPrompt) {\n lines.push(`**${tensionPrompt.action}**`);\n lines.push(tensionPrompt.cta);\n lines.push(\"\");\n }\n }\n\n lines.push(\"_Need a collection that doesn't exist yet? Just ask — I'll set it up._\");\n lines.push(\"\");\n } else if (isHighReadiness) {\n let activeBets: ActiveBet[] = [];\n try {\n // Same `chain.listEntries` union residual documented in wrapup.ts (PR #395, Lane C S3b).\n const betsEntries = (await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"work-packages\" })) as\n | Array<{ name: string; entryId?: string | null; status?: string; data?: Record<string, unknown> }>\n | null\n | undefined;\n activeBets = (betsEntries ?? [])\n .filter((e) => isActiveNowBet(e))\n .map((e) => ({ name: e.name, entryId: e.entryId ?? null }))\n .slice(0, 8);\n } catch { /* non-critical */ }\n\n // TEN-2431: route governance through the SHARED DEC-446 tiered ranker via the backend\n // (chain.getBindingGovernanceView) instead of the old hand-rolled listing-order chain.listEntries\n // loop — serves start_pb the SAME governance orient RENDERS for the same task, scope-BLIND and\n // tiered. Domain-scoping is DEFERRED to TEN-2429 (INS-1864, both surfaces together), so no scope\n // arg here. Task-path only: orient's no-task path renders the compact protocol with NO governance.\n // Non-fatal: a governance-load failure must not break the universal session opener (first call).\n let governanceEntries: GovernanceEntries = { principles: [], standards: [], businessRules: [] };\n if (task) {\n try {\n const view = await kernelQuery<GatewayRouteReturnByName<\"chain.getBindingGovernanceView\">>(\"chain.getBindingGovernanceView\", { task });\n const bg = view?.bindingGovernance;\n if (bg) {\n // Map backend rendered governance rows → buildOperatingProtocol's entry shape. The rows\n // are orient's top-level display rows (makeOrientToDisplay): `preview` is the description,\n // `tier` is threaded so the shared ranker's ordering is preserved (buildOperatingProtocol\n // tier-sorts when any entry has a tier).\n const mapGovEntry = (e: BindingGovernanceEntry): StandardEntry => ({\n entryId: e.entryId ?? undefined,\n name: e.name,\n description: typeof e.preview === \"string\" ? e.preview : undefined,\n tier: typeof e.tier === \"number\" ? e.tier : undefined,\n });\n governanceEntries = {\n principles: (bg.principles ?? []).map(mapGovEntry),\n standards: (bg.standards ?? []).map(mapGovEntry),\n businessRules: (bg.businessRules ?? []).map(mapGovEntry),\n };\n }\n } catch { /* non-critical */ }\n }\n\n if (task) {\n if (activeBets.length > 0) {\n lines.push(\"\");\n lines.push(\"## Active work packages — current scope\");\n lines.push(\"_Work outside these work packages requires explicit user confirmation._\");\n lines.push(\"\");\n for (const e of activeBets) {\n lines.push(`- \\`${e.entryId ?? e.name}\\` ${e.name}`);\n }\n lines.push(\"\");\n }\n\n // TEN-2431: governance now comes from the shared tiered + domain-scoped backend view\n // (governanceEntries, fetched above), NOT a hand-rolled per-slug listEntries loop.\n lines.push(...buildOperatingProtocol(governanceEntries, task));\n\n if (coherence) {\n lines.push(...coherence.lines);\n }\n\n if (allCollections.length > 0) {\n const docCompleteness = buildDocCompletenessSection(allCollections);\n if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {\n lines.push(...docCompleteness.lines);\n }\n }\n\n const plannedWork = await queryPlannedWork();\n\n if (hasPlannedWork(plannedWork)) {\n lines.push(\"\");\n lines.push(...buildPlannedWorkSection(plannedWork, priorSessions, recoveryBlock));\n } else if (recoveryBlock) {\n lines.push(\"\");\n lines.push(...formatRecoveryBlock(recoveryBlock));\n }\n\n try {\n // Active-default (DEC-473) means returned rows are already active;\n // we only need seededByPlatform + collectionId to count committed work.\n // (No `collection` field exists server-side — schema stores collectionId\n // only — so the old `?? e.collection` fallback was always inert.)\n const allEntries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\n \"chain.listEntries\",\n { fields: [\"seededByPlatform\", \"collectionId\"] },\n );\n const committed = (allEntries ?? []).filter((e) => !e.seededByPlatform);\n const committedCollections = new Set(committed.map((e) => e.collectionId));\n\n if (committed.length >= 10 && committedCollections.size >= 3) {\n lines.push(\"\");\n lines.push(`_${committed.length} entries across ${committedCollections.size} collections on the Chain._`);\n }\n } catch { /* non-critical */ }\n\n lines.push(\"\");\n lines.push(`Working on: **${task}**`);\n lines.push(\"\");\n } else {\n if (activeBets.length > 0) {\n lines.push(\"\");\n lines.push(\"## Active work packages — current scope\");\n lines.push(\"_Work outside these work packages requires explicit user confirmation._\");\n lines.push(\"\");\n for (const e of activeBets) {\n lines.push(`- \\`${e.entryId ?? e.name}\\` ${e.name}`);\n }\n lines.push(\"\");\n }\n\n lines.push(...buildOperatingProtocol());\n\n if (coherence) {\n lines.push(...coherence.lines);\n }\n\n if (allCollections.length > 0) {\n const docCompleteness = buildDocCompletenessSection(allCollections);\n if (docCompleteness.errorCount > 0 || docCompleteness.warningCount > 0) {\n lines.push(...docCompleteness.lines);\n }\n }\n\n if (priorSessions.length > 0 && !recoveryBlock) {\n const last = priorSessions[0];\n const date = last.startedAt ? new Date(last.startedAt).toISOString().split(\"T\")[0] : \"unknown\";\n const created = Array.isArray(last.entriesCreated) ? last.entriesCreated.length : last.entriesCreated ?? 0;\n const modified = Array.isArray(last.entriesModified) ? last.entriesModified.length : last.entriesModified ?? 0;\n lines.push(`_Last session (${date}): ${created} created, ${modified} modified._`);\n lines.push(\"\");\n }\n\n if (recoveryBlock) {\n lines.push(\"\");\n lines.push(...formatRecoveryBlock(recoveryBlock));\n }\n\n lines.push(\"**What are you working on?** Tell me and I'll load relevant governance and context.\");\n lines.push(\"\");\n }\n }\n\n if (errors.length > 0) {\n lines.push(\"## Errors\");\n for (const err of errors) lines.push(`- ${err}`);\n lines.push(\"\");\n }\n\n const { oriented, orientationStatus } = await tryMarkOriented(agentSessionId, coherence?.snapshot ?? undefined);\n\n const stageLabel = stage ?? \"active\";\n const gapCount = readiness?.gaps?.length ?? 0;\n const summaryParts = [`Product Brain ready. Stage: ${stageLabel}.`];\n if (gapCount > 0) summaryParts.push(`${gapCount} gap${gapCount === 1 ? \"\" : \"s\"}.`);\n if (openTensions.length > 0) summaryParts.push(`${openTensions.length} open tension${openTensions.length === 1 ? \"\" : \"s\"}.`);\n\n const next: NextAction[] = [];\n if (gapCount > 0) {\n next.push({ tool: \"capture\", description: \"Fill a gap\", parameters: {} });\n }\n if (openTensions.length > 0) {\n next.push({ tool: \"entries\", description: \"View open tensions\", parameters: { action: \"list\", collection: \"tensions\" } });\n }\n\n return {\n text: lines.join(\"\\n\"),\n structuredContent: success(\n summaryParts.join(\" \"),\n {\n stage,\n readinessScore: readiness?.score ?? null,\n totalGaps: gapCount,\n openTensions: openTensions.length,\n oriented,\n orientationStatus,\n ...(agentSessionId ? { sessionId: agentSessionId } : {}),\n // PR #519 review round 3 (Codex P2): the rendered shape-advisory line must reach\n // structuredContent too, matching orient.ts's brief/full sites.\n ...(shapeAdvisorySummary ? { shapeAdvisorySummary } : {}),\n },\n next.length > 0 ? next : undefined,\n ),\n };\n}\n\n/**\n * WP-484 S2 (§3): extracted request handler — reused by the legacy `start_pb`\n * standalone tool AND the new `orient action=start` (the two call `start_pb`\n * absorbs into `orient`, §3 core-nouns table). One business-logic path.\n */\nexport async function handleStartPb({ task }: { task?: string }) {\n const errors: string[] = [];\n const agentSessionId = getAgentSessionId();\n\n let wsCtx: Awaited<ReturnType<typeof getWorkspaceContext>> | null = null;\n try {\n wsCtx = await getWorkspaceContext();\n } catch (e: unknown) {\n errors.push(`Workspace: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n if (!wsCtx) {\n const text =\n \"# Could not connect to Product Brain\\n\\n\" +\n (errors.length > 0 ? errors.map((e) => `- ${e}`).join(\"\\n\") : \"Check your API key and CONVEX_SITE_URL.\");\n return {\n content: [{ type: \"text\" as const, text }],\n structuredContent: failure(\n \"BACKEND_UNAVAILABLE\",\n \"Could not connect to Product Brain.\",\n \"Check your API key and CONVEX_SITE_URL.\",\n ),\n };\n }\n\n // Branch on readiness stage (PAT-227).\n // Do NOT default to \"blank\" on readiness failure — an active workspace\n // seeing setup instructions on a transient error would be actively harmful.\n let stage: string | null = null;\n try {\n const readiness = await kernelQuery<GatewayRouteReturnByName<\"chain.workspaceReadiness\">>(\"chain.workspaceReadiness\");\n stage = readiness?.stage ?? \"blank\";\n } catch {\n errors.push(\"Readiness check unavailable — showing workspace summary.\");\n }\n\n if (stage === \"blank\" || stage === \"seeded\") {\n // DEC-993 / STD-235: stamp surface + return setup skill body verbatim\n // (the skill body leads unmodified; the feedback hint is appended after it).\n const result = await buildSetupResponse(agentSessionId);\n return {\n content: textContent(`${result.text}\\n\\n${FEEDBACK_SUBMIT_HINT}`),\n structuredContent: result.structuredContent,\n };\n }\n\n // grounded, connected, or readiness failed → orient-style standup\n if (stage === \"grounded\" || stage === \"connected\") {\n void kernelMutation<GatewayRouteReturnByName<\"chain.setOnboardingCompleted\">>(\"chain.setOnboardingCompleted\", {}).catch(() => { /* non-critical */ });\n }\n\n const orientResult = await buildOrientResponse(wsCtx, agentSessionId, errors, task);\n return {\n content: [{ type: \"text\" as const, text: `${orientResult.text}\\n\\n${FEEDBACK_SUBMIT_HINT}` }],\n structuredContent: orientResult.structuredContent,\n };\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `start_pb` tool retired\n// here. handleStartPb stays live — orient.ts (the `orient` compound,\n// action=start) is its only remaining caller.\n","/**\n * `skills` MCP tool — generic workspace skill-body loader (WP-431 S5, DEC-998).\n *\n * Pure entryId-keyed retrieval: no allow-list, no pb-setup-specific code path.\n * Any caller passing a SKILL-* entryId for their workspace gets the skill body\n * back. The chat-only `start_pb` bootstrap calls this tool internally so the\n * load path stays single-source (S6 contract test pins that).\n *\n * Auth perimeter mirrors `recordTransition` (STD-234): the AKI gateway injects\n * `apiKeyId | personId | clerkUserId` server-side; this tool just calls the\n * gateway via `kernelQuery` and lets the server resolve identity.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, getWorkspaceId } from \"../client.js\";\n\nexport const skillsSchema = z.object({\n entryId: z\n .string()\n .min(1)\n .describe(\n \"Workspace-scoped skill entry id (e.g. 'SKILL-pb-setup'). The tool refuses \" +\n \"non-skill entries (canonicalKey !== 'skill') with INVALID_KIND.\",\n ),\n});\n\nexport interface SkillBodyResult {\n entryId: string;\n name: string;\n body: string;\n contentType: \"text/markdown\";\n retrievedAt: number;\n}\n\n/**\n * Load a SKILL-* entry's body for the caller's workspace. Internal helper used\n * by both the `skills` tool registration and `start_pb` (which routes through\n * the same loader by contract — DEC-997).\n */\nexport async function loadSkillBody(entryId: string): Promise<SkillBodyResult> {\n const workspaceId = await getWorkspaceId();\n return await kernelQuery<GatewayRouteReturnByName<\"setup.getSkillBody\">>(\"setup.getSkillBody\", {\n workspaceId,\n entryId,\n });\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `skills` tool retired\n// here. loadSkillBody stays live — workflows.ts (the `workflows` compound,\n// action=load-skill) and start_pb.ts's chat-only bootstrap are its remaining\n// callers.\n","/**\n * FEAT-1409 spine core — MCP rendering of the channel-agnostic session-start notice contract.\n * Convex never renders a notice; this file owns the ONLY MCP-side mapping from a notice's\n * neutral `action.verb` to the existing `NextAction` shape, emitted through the existing `next`\n * field (HARD CONSTRAINT 2 — no surface syntax in Convex, no parallel action list).\n */\nimport type { NextAction } from \"../envelope.js\";\n\n/**\n * Review finding: question/outcome text is workspace-controlled (decline/force-close reasons,\n * role/person/dependent-entry names) and reaches this renderer's output unsanitized — an MCP\n * client that prints the text response to a terminal (many do) inherits the same ANSI/control-\n * char injection risk BET-269 C3 already guards on the CLI side. This package cannot import\n * packages/cli/src/lib/strip.ts at runtime (mcp-server's isolated Docker build resolves no\n * private workspace package, per this file's own header) — same MCP-twin duplication convention\n * as every other function here, mirroring stripControlChars's own regex verbatim.\n */\n// eslint-disable-next-line no-control-regex\nconst ANSI_AND_CONTROL_RE = /\\x1b\\[[0-9;]*[A-Za-z]|\\x1b\\][^\\x07]*\\x07|\\x1b[^[\\]0-9;A-Za-z]?|[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/g;\nfunction safe(str: string | undefined): string {\n return str ? str.replace(ANSI_AND_CONTROL_RE, \"\") : \"\";\n}\n\n/**\n * WP-584 S4 (FEAT-1412): the always-on feedback-invite line — KEY-85's baseline \"exactly 1\n * line\" every session-start response carries regardless of notices. Single source WITHIN this\n * package now (start_pb.ts and session.ts both import it — they used to each carry their own\n * literal, drifted apart in nothing but coincidence). NOT collapsed with packages/cli's own copy\n * (formatters/session.ts's `FEEDBACK_SUBMIT_HINT`): command syntax differs per surface\n * (`feedback action=submit` here vs `pb feedback submit -c <bug|friction|idea|praise|other>\n * \"<message>\"` there) and mcp-server's isolated Docker build cannot resolve a private workspace\n * package at runtime (packages/kernel-client's own package.json documents this exact\n * constraint — mcp-server only gets a TYPE-ONLY tsconfig path alias to it, never a runtime\n * value import). scripts/check-notice-hint-drift.mjs is the drift guard for the SHARED\n * substance between the two packages' copies.\n */\nexport const FEEDBACK_SUBMIT_HINT =\n \"Friction or ideas? Use `feedback action=submit` — describe how pb behaved, not your workspace content. Once screening completes, it enters the builders' triage queue.\";\n\nexport interface AgentSessionStartNoticeAction {\n verb: string;\n args: Record<string, string | number | boolean | null>;\n /** Optional, additive — the original §3.9a verb label (convex/lib/notices/types.ts's\n * NoticeAction.label doc comment: the route alone can't distinguish 'take it' from\n * 'reassign', or 'pass' from 'decline'). */\n label?: string;\n}\n\n/** WP-638 S4 (§7.5) — the MCP-side twin of convex/lib/notices/types.ts's `NoticeQuestionBrief`. */\nexport interface AgentSessionStartQuestionBrief {\n name: string;\n question: string;\n asker: string;\n sourcePointer: string;\n domain: string;\n whyYou: string;\n ageDays: number;\n dependents: { count: number; truncated?: boolean; named: { name: string; id: string }[] };\n declineContext?: string;\n answerContext?: string;\n actions: AgentSessionStartNoticeAction[];\n}\n\n/** FEAT-1409 spine core — the channel-agnostic session-start notice (convex/lib/notices/types.ts's\n * `Notice`, mirrored here for the MCP surface). Canonical home for the MCP-side notice shape —\n * client.ts re-exports it (STD-2/DEC-1504: client.ts is grandfathered shrink-only). */\nexport interface AgentSessionStartNotice {\n source: string;\n type: string;\n severity: \"none\" | \"advisory\" | \"warning\" | \"emergency\";\n subject: string;\n change: string;\n occurredAt: number;\n action: AgentSessionStartNoticeAction;\n /** WP-638 S4 (§7.5, R23) — the Notice-contract extension, additive/optional. */\n payload?: { questions: AgentSessionStartQuestionBrief[]; truncated?: boolean };\n requiresDisposition?: boolean;\n actions?: AgentSessionStartNoticeAction[];\n}\n\n/**\n * verb -> the NextAction this MCP surface already exposes for it. `feedback.list` (S1,\n * feedback-status) and `feedback.queue` (S4/TEN-2971, feedback-queue — the vendor triage\n * standing notice) both map to the existing `feedback` compound tool's own actions — HARD\n * CONSTRAINT 10, no new gateway route / no new tool.\n *\n * Returns null for an unmapped verb (review round 1, Copilot). The previous fallback emitted\n * `{ tool: verb }`, which is NOT a registered MCP tool name (see src/server.ts) — so a future\n * producer's verb would have handed the agent a structured action that fails on invocation. A\n * `NextAction` is machine-consumable, unlike the CLI's verb fallback, which is only ever\n * rendered as display text (packages/cli/src/lib/sessionNotices.ts) and stays honest as-is.\n *\n * Dropping the ACTION is not dropping the NOTICE: `formatNoticeLines` still renders the\n * notice's subject and change, so an unmapped verb degrades to \"you are told about it, with no\n * one-click action\" rather than to a broken tool call.\n */\n// WP-638 S4 (R24 — moved here from S5 so the mapping ships in the slice whose doneWhen quotes\n// it, §16.2 S4(j)): the eight routed-question verbs join feedback's two.\nfunction nextActionForVerb(verb: string, args: Record<string, string | number | boolean | null>): NextAction | null {\n switch (verb) {\n case \"feedback.list\":\n return { tool: \"feedback\", description: \"Read your workspace's own feedback (all statuses)\", parameters: { action: \"list\" } };\n case \"feedback.queue\":\n return { tool: \"feedback\", description: \"Read the vendor triage queue (system admins only)\", parameters: { action: \"queue\" } };\n case \"question.create\":\n return { tool: \"question\", description: \"Create a routed question\", parameters: { action: \"create\" } };\n case \"question.adopt\":\n return { tool: \"question\", description: \"Attach routing to a captured tension\", parameters: { action: \"adopt\" } };\n case \"question.assign\":\n return { tool: \"question\", description: \"Confirm or reassign a question\", parameters: { action: \"assign\" } };\n case \"question.snooze\":\n return { tool: \"question\", description: \"Snooze a routed/escalated question\", parameters: { action: \"snooze\" } };\n case \"question.decline\":\n return { tool: \"question\", description: \"Pass on or decline a question\", parameters: { action: \"decline\" } };\n case \"question.answer\":\n return { tool: \"question\", description: \"Answer a question\", parameters: { action: \"answer\" } };\n case \"question.forceClose\":\n return { tool: \"question\", description: \"Team-Lead-only force-close\", parameters: { action: \"force-close\" } };\n case \"question.list\":\n // Review finding: the outcomes producer's asker-arm action carries `{ mine: true }`\n // (§7.3(a)) so the reader lands on their OWN history, not the ack-gate obligation view\n // (which excludes exactly the processed question the notice is about).\n return { tool: \"question\", description: args.mine === true ? \"List every question you asked\" : \"List open questions\", parameters: { action: \"list\", ...(args.mine === true ? { mine: true } : {}) } };\n default:\n return null;\n }\n}\n\nexport function noticesToNextActions(notices: readonly AgentSessionStartNotice[] | undefined): NextAction[] {\n if (!notices || notices.length === 0) return [];\n const actions = notices\n .map((n) => nextActionForVerb(n.action.verb, n.action.args))\n .filter((a): a is NextAction => a !== null);\n // Review finding: a session with many outcome notices (each carrying the identical\n // `question action=list mine=true/false` next-action, §7.3) produced one indistinguishable\n // duplicate per outcome — dedupe by tool+parameters, keeping the first (earliest) description.\n const seen = new Set<string>();\n return actions.filter((a) => {\n const key = `${a.tool}:${JSON.stringify(a.parameters)}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nconst QUESTION_ACK_GATE_SOURCE_ID = \"question-ack-gate\";\n\n/**\n * §7.5's verbatim block, the MCP twin of packages/cli/src/lib/sessionNotices.ts's\n * `formatQuestionAckGateBlock` — same fixed elements, same canonical closing sentence, quoted\n * identically (§7.5/§10/§16.2 S4(f)).\n */\n/** display verb (e.g. \"take it\") from the neutral gateway route name a brief's own `actions`\n * carry — the inverse of convex/lib/questionDisplayStrings.ts's `questionVerbToRoute`. */\nfunction displayVerbFromRoute(route: string): string {\n switch (route) {\n case \"question.assign\": return \"take it / reassign\";\n case \"question.decline\": return \"pass / decline\";\n case \"question.forceClose\": return \"force-close\";\n default: return route.replace(/^question\\./, \"\");\n }\n}\n\nfunction formatQuestionBrief(q: AgentSessionStartQuestionBrief): string[] {\n const lines: string[] = [];\n lines.push(` [${safe(q.sourcePointer)}] ${safe(q.name)} — ${safe(q.whyYou)}, ${q.ageDays}d`);\n lines.push(` \"${safe(q.question)}\" — asked by ${safe(q.asker)}${q.domain ? `, ${safe(q.domain)} domain` : \"\"}`);\n if (q.dependents.count > 0) {\n const names = q.dependents.named.map((d) => `${safe(d.name)} (${safe(d.id)})`).join(\", \");\n const countLabel = q.dependents.truncated ? `${q.dependents.count}+` : String(q.dependents.count);\n lines.push(` blocks ${countLabel} item(s)${names ? `: ${names}` : \"\"}`);\n }\n if (q.declineContext) lines.push(` declined: ${safe(q.declineContext)}`);\n if (q.answerContext) lines.push(` ${safe(q.answerContext)}`);\n // Prefer the server's own `label` (the actual §3.9a verb legal for this row) over the\n // route-derived guess, which collapses 'take it'/'reassign' and 'pass'/'decline' together.\n const verbList = [...new Set(q.actions.map((a) => safe(a.label) || displayVerbFromRoute(a.verb)))].join(\" · \") || \"answer\";\n lines.push(` ${verbList} -> question action=answer entryId=${safe(q.sourcePointer)} text=\"<your answer>\"`);\n return lines;\n}\n\nfunction formatQuestionAckGateBlock(notice: AgentSessionStartNotice): string[] {\n const questions = notice.payload?.questions ?? [];\n const lines: string[] = [];\n lines.push(`- ${questions.length} open question${questions.length === 1 ? \"\" : \"s\"} need you before you continue.`);\n for (const q of questions) lines.push(...formatQuestionBrief(q));\n lines.push(\" Deal with each question above before proceeding.\");\n if (notice.payload?.truncated) {\n lines.push(\" (This list may be incomplete — you may have more open questions than shown.)\");\n }\n return lines;\n}\n\n/** One line per notice, oldest first (server already sorts producers' output this way) — except\n * the question-ack-gate notice, which renders §7.5's full multi-line block (see the CLI twin's\n * own doc comment for why this is additive and every other producer's one-liner is untouched). */\nexport function formatNoticeLines(notices: readonly AgentSessionStartNotice[] | undefined): string[] {\n if (!notices || notices.length === 0) return [];\n return notices.flatMap((n) =>\n n.source === QUESTION_ACK_GATE_SOURCE_ID && n.payload\n ? formatQuestionAckGateBlock(n)\n : [`- ${safe(n.subject)} (${safe(n.change)})`],\n );\n}\n\n/** WP-638 S4 (§10.3) — the bounded adopt-discovery advisory line, MCP twin of the CLI's own\n * `formatAdoptDiscoveryLine`. `display` is the server's own pre-formatted count (\"3\" or, at the\n * scan cap, \"20+\") — silence when absent. */\nexport function formatAdoptDiscoveryLine(display: string | undefined): string[] {\n if (!display) return [];\n return [`- ${display} open question${display === \"1\" ? \"\" : \"s\"} you raised have no owner yet — use \\`question action=adopt\\` to route one.`];\n}\n","/**\n * `record_activation` MCP tool — chat-only activation receipt writer (WP-431\n * final pre-ship fix).\n *\n * Why this exists:\n * The pb-setup skill's Phase 5 needs a path for chat-only agents to call\n * `setup.recordActivationReceipt`. Before this tool, the skill body told\n * chat-only agents to use `commit-entry` — but `commit-entry` writes to the\n * `entries` table (chain.commitEntry), not to `setup_receipt`. That meant\n * chat-only users could reach Phase 5 readiness yet never write the\n * activation receipt, leaving KEY-32-chat unmeasurable and doneWhen #6 of\n * WP-431 violated for the chat-only surface.\n *\n * Contract:\n * - Caller passes the activation evidence (confirmedEntryCount,\n * entriesAcrossCollections, retrievalDemoConfirmed). The tool HARDCODES\n * `surfaceCapability='chat-only'` because this tool exists exclusively for\n * chat-only paths — CLI agents have shell access and call the gateway\n * directly. Allowing the caller to override surfaceCapability would defeat\n * the whole purpose of the dual-threshold KEY-32 metric.\n * - Calls `setup.recordActivationReceipt` via `kernelMutation` (which routes\n * through the AKI gateway with `injectSessionAuth: true`, mirroring how\n * S5's `start_pb` calls `setup.stampMcpOnlySurface`). The gateway injects\n * `apiKeyId | personId | clerkUserId` server-side; this tool never sees\n * identity material.\n * - Returns `{ activated, alreadyActivated, receiptId }` — the\n * `alreadyActivated` flag is forwarded directly from the mutation so\n * re-runs short-circuit cleanly (DEC-957 re-run-safe).\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { kernelMutation } from \"../client.js\";\nimport { success, textContent } from \"../envelope.js\";\n\nexport const recordActivationSchema = z.object({\n confirmedEntryCount: z\n .number()\n .int()\n .min(0)\n // DEC-994\n .describe(\n \"Confirmed-entry count from the Phase 4 capture loop. The mutation enforces >=10.\",\n ),\n entriesAcrossCollections: z\n .number()\n .int()\n .min(0)\n // DEC-994\n .describe(\n \"Number of distinct collections those entries span. The mutation enforces >=2 (diversity soft-gate).\",\n ),\n retrievalDemoConfirmed: z\n .boolean()\n // BR-141\n .describe(\n \"True if the retrieval round-trip ran successfully in Phase 4. The mutation rejects false.\",\n ),\n});\n\ninterface RecordActivationResult {\n activated: boolean;\n alreadyActivated: boolean;\n receiptId: string | null;\n}\n\ninterface RecordActivationMutationResponse {\n alreadyActivated: boolean;\n receiptId: string;\n}\n\n/**\n * WP-484 S2 (§3): extracted request handler — reused by the legacy\n * `record_activation` standalone tool AND the new `orient\n * action=record-activation` (absorbed per §3 core-nouns table). One\n * business-logic path.\n */\nexport async function handleRecordActivation({\n confirmedEntryCount,\n entriesAcrossCollections,\n retrievalDemoConfirmed,\n}: {\n confirmedEntryCount: number;\n entriesAcrossCollections: number;\n retrievalDemoConfirmed: boolean;\n}) {\n const mutationResult = await kernelMutation<GatewayRouteReturnByName<\"setup.recordActivationReceipt\">>(\n \"setup.recordActivationReceipt\",\n {\n surfaceCapability: \"chat-only\",\n confirmedEntryCount,\n entriesAcrossCollections,\n retrievalDemoConfirmed,\n },\n );\n\n const result: RecordActivationResult = {\n activated: true,\n alreadyActivated: mutationResult.alreadyActivated,\n receiptId: mutationResult.receiptId ?? null,\n };\n\n const summary = mutationResult.alreadyActivated\n ? \"Activation receipt already recorded — chat-only flow short-circuits.\"\n : \"Activation recorded — chat-only flow complete.\";\n\n return {\n content: textContent(summary),\n structuredContent: success(summary, result),\n };\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `record_activation` tool\n// retired here. handleRecordActivation stays live — orient.ts (the `orient`\n// compound, action=record-activation) is its only remaining caller.\n","/**\n * Workflows compound tool — list, checkpoint, get-run.\n * Consolidates workflow discovery, checkpoint persistence, and run inspection.\n * Chain: FEAT-MCP-001 (MCP Server), BET-85\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport {\n getAgentSessionId,\n kernelQuery,\n kernelMutation,\n requireActiveSession,\n runWithToolContext,\n requireWriteAccess,\n} from \"../client.js\";\nimport { resolveCollection } from \"../lib/resolveCollection.js\";\nimport { thinWrapper, success, failure, validationResult, successResult, parseOrFail, textContent, type NextAction, type ToolResult } from \"../envelope.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { loadSkillBody } from \"./skills.js\";\nimport {\n getWorkflowDescriptor,\n getWorkflow,\n listWorkflows,\n type WorkflowDefinition,\n} from \"../workflows/definitions.js\";\nimport {\n describeWorkflowPrimaryOutput,\n getWorkflowSummaryCaptureDefinition,\n getWorkflowTemplateMetadata,\n} from \"../workflows/descriptor.js\";\nimport type {\n JsonValue,\n WorkflowRunOutput,\n WorkflowRunRenderProjection,\n} from \"../workflows/run-model.js\";\nimport { workflowRunOutputToText } from \"../workflows/run-model.js\";\n\n// WP-484 S2 (§3): `workflows` absorbs `skills` → load-skill. Legacy `skills`\n// tool stays registered alongside (§7 \"alongside\" mechanic) — both call the\n// SAME loadSkillBody function, one business-logic path.\nconst WORKFLOWS_ACTIONS = [\"list\", \"start\", \"checkpoint\", \"get-run\", \"load-skill\"] as const;\ntype WorkflowsAction = (typeof WORKFLOWS_ACTIONS)[number];\ntype WorkflowCheckpointOutputInput = string | WorkflowRunOutput;\n\nconst jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(jsonValueSchema),\n z.record(jsonValueSchema),\n ]),\n);\n\nconst workflowRunOutputInputSchema: z.ZodType<WorkflowRunOutput> = z.union([\n z.object({\n format: z.literal(\"freetext\"),\n value: z.string(),\n }),\n z.object({\n format: z.literal(\"list\"),\n value: z.array(z.string()),\n }),\n z.object({\n format: z.literal(\"choice\"),\n value: z.union([z.string(), z.array(z.string())]),\n }),\n z.object({\n format: z.literal(\"structured\"),\n value: jsonValueSchema,\n }),\n]);\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const workflowsSchema = z.object({\n action: z.enum(WORKFLOWS_ACTIONS).describe(\n \"'list': browse available workflows. 'start': start or resume a workflow — returns first (or current) round and next-step checkpoint call. 'checkpoint': record round output or final summary. 'get-run': inspect a persisted workflow run. \" +\n \"'load-skill': load the markdown body of a SKILL-* entry from the workspace (absorbs the `skills` tool). Requires entryId.\",\n ),\n workflowId: z.string().max(200).optional().describe(\"Workflow ID for start, checkpoint, or get-run, e.g. 'retro', 'implementation-review'\"),\n runId: z.string().max(200).optional().describe(\"Workflow run ID: for get-run, which run to load; for checkpoint, target this run (avoids session drift — pass runId from get-run).\"),\n roundId: z.string().max(200).optional().describe(\"Round ID for checkpoint, e.g. 'what-went-well'\"),\n output: z.union([z.string(), workflowRunOutputInputSchema]).optional().describe(\"The round's output — either legacy synthesized text or a typed workflow run payload.\"),\n isFinal: z.boolean().optional().describe(\"If true, finalize an existing durable workflow run from its terminal round and create the summary chain entry.\"),\n restart: z.boolean().optional().describe(\"If true, start a new durable run from the workflow's first round in the current session.\"),\n summaryName: z.string().max(500).optional().describe(\"Optional name for final chain entry. If omitted, the workflow summary template is used.\"),\n summaryDescription: z.string().max(20000).optional().describe(\"Optional override for the final chain entry description. Defaults to the final round output text.\"),\n summaryEntryId: z.string().max(200).optional().describe(\"Link an existing entry as the run's summary instead of creating one. Used by facilitated workflows (e.g. shape) where the primary record is created by the specialized tool.\"),\n entryId: z.string().max(200).optional().describe(\"For 'load-skill': workspace-scoped skill entry id (e.g. 'SKILL-pb-setup'). Refuses non-skill entries (canonicalKey !== 'skill') with INVALID_KIND.\"),\n // WP-513: team+role to create the finalize summary AS OWNER of (rung 2 only).\n ownerTeamEntryId: z.string().max(200).optional().describe(\"For 'checkpoint' (isFinal): owning team (rung-2).\"),\n ownerRoleEntryId: z.string().max(200).optional().describe(\"For 'checkpoint' (isFinal): owning role (rung-2).\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion.\nconst workflowsListVariant = z.object({ action: z.literal(\"list\") });\n// Note: \"runId OR workflowId required\" is a cross-field check the\n// discriminatedUnion can't express (z.discriminatedUnion members must be\n// plain ZodObjects, not ZodEffects) — enforced in the handler instead,\n// mirroring context.ts's entryId-or-task check for 'gather'.\nconst workflowsGetRunVariant = z.object({\n action: z.literal(\"get-run\"),\n runId: z.string().max(200).optional(),\n workflowId: z.string().max(200).optional(),\n});\nconst workflowsStartVariant = z.object({ action: z.literal(\"start\"), workflowId: z.string().max(200) });\nconst workflowsCheckpointVariant = z.object({\n action: z.literal(\"checkpoint\"),\n workflowId: z.string().max(200),\n roundId: z.string().max(200),\n output: z.union([z.string(), workflowRunOutputInputSchema]),\n isFinal: z.boolean().optional(),\n restart: z.boolean().optional(),\n summaryName: z.string().max(500).optional(),\n summaryDescription: z.string().max(20000).optional(),\n summaryEntryId: z.string().max(200).optional(),\n runId: z.string().max(200).optional(),\n ownerTeamEntryId: z.string().max(200).optional(), ownerRoleEntryId: z.string().max(200).optional(),\n});\nconst workflowsLoadSkillVariant = z.object({ action: z.literal(\"load-skill\"), entryId: z.string().max(200).min(1) });\n\nexport const workflowsActionUnion = z.discriminatedUnion(\"action\", [\n workflowsListVariant,\n workflowsGetRunVariant,\n workflowsStartVariant,\n workflowsCheckpointVariant,\n workflowsLoadSkillVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const WORKFLOWS_ACTION_SPECS: Record<WorkflowsAction, ActionParamSpec> = {\n list: { params: [], description: \"Browse available workflows; no params.\" },\n \"get-run\": { params: [\"runId\", \"workflowId\"], description: \"runId or workflowId is required.\" },\n start: { params: [\"workflowId\"], description: \"workflowId is required.\" },\n checkpoint: { params: [\"workflowId\", \"roundId\", \"output\", \"isFinal\", \"restart\", \"summaryName\", \"summaryDescription\", \"summaryEntryId\", \"runId\", \"ownerTeamEntryId\", \"ownerRoleEntryId\"], description: \"workflowId, roundId, and output are required.\" },\n \"load-skill\": { params: [\"entryId\"], description: \"entryId is required.\" },\n};\n\nfunction formatWorkflowCard(wf: WorkflowDefinition): string {\n const roundList = wf.rounds\n .map((r) => ` ${r.num}. ${r.label} (${r.type}, ~${r.maxDurationHint ?? \"?\"})`)\n .join(\"\\n\");\n const descriptor = getWorkflowDescriptor(wf.id);\n const outputDescription = descriptor\n ? describeWorkflowPrimaryOutput(descriptor)\n : wf.kbOutputCollection\n ? `Primary record routes to \\`${wf.kbOutputCollection}\\`.`\n : \"Primary output routing is resolved at runtime.\";\n\n return (\n `## ${wf.icon} ${wf.name}\\n` +\n `**ID**: \\`${wf.id}\\`\\n` +\n `${wf.shortDescription}\\n\\n` +\n `**Rounds** (${wf.rounds.length}):\\n${roundList}\\n\\n` +\n `**Output**: ${outputDescription}\\n` +\n `_Trigger via Facilitator Mode: say \"run retro\", \"shape this\", \"review implementation\", or \"process change\" in Cursor._`\n );\n}\n\n/**\n * Thin-wrapper contract for MCP workflow tools (TEN-667).\n *\n * MCP handles ONLY:\n * 1. Workflow definition lookup — definitions are MCP-local code (packages/mcp-server/src/workflows/)\n * 2. Round validation against the definition — requires local definition access\n * 3. Argument translation — coerce MCP text/string inputs to typed WorkflowRunOutput\n * 4. Collection pre-resolution — classifier mode requires an LLM action (cannot run in a mutation)\n * 5. Response formatting — MCP tool protocol envelope\n *\n * Everything else lives in Convex:\n * - Run state machine (create, advance, complete): lib/workflowRun.ts\n * - Persistence: chainwork/engine.ts (internal mutations, MCP gateway path)\n * - Public write surface for Brain/non-MCP consumers: chainwork/mutations.ts (TEN-667)\n * - Auth: requirePerson (public) or requireActiveWorkflowSession (internal/MCP)\n *\n * Do NOT add state machine logic, run lifecycle checks, or persistence here.\n */\n\nexport function validateFinalWorkflowCheckpoint(\n workflow: WorkflowDefinition,\n roundId: string,\n): string | null {\n const finalRound = workflow.rounds.at(-1);\n\n if (!finalRound) {\n return `Workflow '${workflow.id}' has no rounds and cannot create a final summary.`;\n }\n\n if (roundId !== finalRound.id) {\n return (\n `Workflow '${workflow.id}' can only create a final summary from its terminal round ` +\n `'${finalRound.id}' (${finalRound.label}).`\n );\n }\n\n return null;\n}\n\n// ─── Closest-match helpers (used for round ID self-correction) ──────────────\n// BET-78 (response envelope): errors must carry next-step commands agents can\n// execute directly. INS-61: design for the dumbest agent — if a round ID typo\n// causes a silent \"not found\", the agent retries blindly. Suggesting the\n// closest round turns a dead-end into a one-shot recovery.\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>\n Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n );\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j]!, dp[i][j - 1]!, dp[i - 1][j - 1]!);\n }\n }\n return dp[m][n]!;\n}\n\n/**\n * Returns the closest matching round for a given input ID, or null if no round\n * is similar enough to confidently suggest. Prioritises substring containment\n * over edit distance so \"orient-scope\" → \"orient\" works without needing a low\n * edit-distance threshold.\n */\nfunction findClosestRound(\n input: string,\n rounds: WorkflowDefinition[\"rounds\"],\n): WorkflowDefinition[\"rounds\"][number] | null {\n if (rounds.length === 0) return null;\n\n // Prefer substring containment (either direction) — catches truncations and\n // common over-hyphenation mistakes before paying for edit-distance.\n const substringMatch = rounds.find(\n (r) => r.id.includes(input) || input.includes(r.id),\n );\n if (substringMatch) return substringMatch;\n\n // Fall back to edit distance. Only suggest if distance ≤ half the longer\n // string — avoids wild guesses on completely unrelated IDs.\n let best = rounds[0]!;\n let bestDist = levenshtein(input, best.id);\n for (const r of rounds.slice(1)) {\n const dist = levenshtein(input, r.id);\n if (dist < bestDist) {\n bestDist = dist;\n best = r;\n }\n }\n\n const threshold = Math.ceil(Math.max(input.length, best.id.length) / 2);\n return bestDist <= threshold ? best : null;\n}\n\nexport function registerWorkflowTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const workflowsHandlers: Record<WorkflowsAction, (data: any) => Promise<ToolResult>> = {\n list: () => handleList(),\n \"get-run\": (data) => {\n if (!data.runId && !data.workflowId) {\n return Promise.resolve(validationResult(\"runId or workflowId is required when action is 'get-run'.\"));\n }\n return handleGetRun(data.runId, data.workflowId);\n },\n start: (data) => handleStart(data.workflowId),\n checkpoint: (data) => handleCheckpoint(\n data.workflowId, data.roundId, data.output, data.isFinal, data.restart,\n data.summaryName, data.summaryDescription, data.summaryEntryId, data.runId,\n data.ownerTeamEntryId, data.ownerRoleEntryId,\n ),\n \"load-skill\": async (data) => {\n const result = await loadSkillBody(data.entryId);\n const summary = `Loaded ${result.entryId} (${result.body.length} chars).`;\n return { content: textContent(result.body), structuredContent: success(summary, result) };\n },\n };\n\n server.registerTool(\n \"workflows\",\n {\n title: \"Workflows\",\n description:\n \"Chainwork workflow discovery, start/resume, checkpointing, run inspection, and skill loading. Five actions:\\n\\n\" +\n \"- **list**: Browse available workflows — retro, shape-a-bet, implementation-review, process-change.\\n\" +\n \"- **start**: Start or resume a workflow. Call with workflowId (e.g. 'implementation-review', 'retro', 'shape', 'process-change'). \" +\n \"Returns the first (or current) round instructions and the exact checkpoint call to use when the round is complete. \" +\n \"Use this when the user says 'run implementation review', 'run retro', 'shape this', or 'process change' — it is the tool entry point for running a workflow.\\n\" +\n \"- **checkpoint**: Record round output during Facilitator Mode. Persists progress. \" +\n \"At completion, some workflows support isFinal=true to create the summary chain entry.\\n\" +\n \"- **get-run**: Inspect a persisted workflow run by run ID or by workflow ID in the current session.\\n\" +\n \"- **load-skill**: Load the markdown body of a SKILL-* entry from the current workspace (absorbs `skills`). \" +\n \"Generic loader — works for any skill, e.g. SKILL-pb-setup, SKILL-shape, SKILL-review.\",\n inputSchema: workflowsSchema,\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(workflowsSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"workflows\", action }, () =>\n dispatchDiscriminated(\"workflows\", workflowsActionUnion, parsed.data, WORKFLOWS_ACTION_SPECS, workflowsHandlers),\n );\n }),\n );\n}\n\nasync function handleList() {\n const workflows = listWorkflows();\n\n if (workflows.length === 0) {\n return successResult(\n \"No workflows registered yet. Check back after the workflow definitions are configured.\",\n \"No workflows registered yet.\",\n { workflows: [], total: 0 },\n );\n }\n\n const cards = workflows.map(formatWorkflowCard).join(\"\\n\\n---\\n\\n\");\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Available Chainwork Workflows\\n\\n` +\n `${workflows.length} workflow(s) available. Trigger via Facilitator Mode in Cursor (say \"run retro\", \"shape this\", \"review implementation\", or \"process change\").\\n\\n` +\n `---\\n\\n${cards}`,\n }],\n structuredContent: success(\n `Found ${workflows.length} workflow(s).`,\n {\n workflows: workflows.map((w) => ({\n id: w.id,\n name: w.name,\n rounds: w.rounds.length,\n outputCollection: w.kbOutputCollection ?? null,\n })),\n total: workflows.length,\n },\n ),\n };\n}\n\n/** TEN-244: Bridge for \"run workflow\" — start returns first (or current) round so agents have a tool entry point. */\nexport async function handleStart(workflowId: string) {\n requireActiveSession();\n const agentSessionId = getAgentSessionId();\n if (!agentSessionId) {\n return validationResult(\n \"Active agent session required to start a workflow. Ensure the client has an active session.\",\n );\n }\n\n const wf = getWorkflow(workflowId);\n if (!wf) {\n const available = listWorkflows().map((w) => w.id).join(\", \");\n return {\n content: [{\n type: \"text\" as const,\n text:\n `Workflow \"${workflowId}\" not found. Available: ${available}.\\n\\n` +\n `Use workflows action=list to see workflow names and round structure.`,\n }],\n structuredContent: failure(\n \"NOT_FOUND\",\n `Workflow '${workflowId}' not found.`,\n `Available: ${available}`,\n [{ tool: \"workflows\", description: \"List workflows\", parameters: { action: \"list\" } }],\n ),\n };\n }\n\n const firstRound = wf.rounds[0];\n if (!firstRound) {\n return validationResult(\n `Workflow '${workflowId}' has no rounds. Use workflows action=list to choose another workflow.`,\n );\n }\n\n // Resume: if there is an active run for this session+workflow, return current round and runId\n let run: PersistedWorkflowRun | null = null;\n try {\n run = await kernelQuery<GatewayRouteReturnByName<\"chainwork.getLatestWorkflowRun\">>(\"chainwork.getLatestWorkflowRun\", {\n agentSessionId,\n workflowId: wf.id,\n });\n } catch {\n // Proceed with start (no run yet)\n }\n\n const isResume = run?.status === \"active\" && run.currentRoundId != null;\n const round = isResume\n ? wf.rounds.find((r) => r.id === run!.currentRoundId) ?? firstRound\n : firstRound;\n\n const skillHint =\n wf.id === \"implementation-review\"\n ? \"Read the implementation-review skill (.cursor/skills/implementation-review/SKILL.md) for full facilitation instructions.\"\n : wf.id === \"shape\"\n ? \"Read the shaping skill (.cursor/skills/shaping/SKILL.md) for full facilitation instructions.\"\n : null;\n\n const nextStep =\n `When this round is complete, call \\`workflows\\` with \\`action=checkpoint\\`, \\`workflowId=\"${wf.id}\"\\`, \\`roundId=\"${round.id}\"\\`, and \\`output\\` set to the round's synthesized output.` +\n (run?.runId ? ` Pass \\`runId=\"${run.runId}\"\\` to checkpoint into the existing run.` : \"\");\n\n const lines = [\n isResume ? `# Resume: ${wf.name} (\\`${wf.id}\\`)` : `# Start: ${wf.name} (\\`${wf.id}\\`)`,\n \"\",\n `**Round ${round.num} — ${round.label}** (\\`${round.id}\\`)`,\n \"\",\n round.instruction,\n \"\",\n \"**Facilitator guidance:**\",\n round.facilitatorGuidance,\n \"\",\n \"**Next step:**\",\n nextStep,\n ...(skillHint ? [\"\", skillHint] : []),\n ];\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n isResume\n ? `Resume workflow ${wf.id} at round ${round.num} (${round.label}).`\n : `Start workflow ${wf.id} — round ${round.num} (${round.label}).`,\n {\n workflowId: wf.id,\n workflowName: wf.name,\n runId: run?.runId ?? null,\n round: {\n id: round.id,\n num: round.num,\n label: round.label,\n instruction: round.instruction,\n facilitatorGuidance: round.facilitatorGuidance,\n outputFormat: round.outputSchema.format,\n },\n nextStep: {\n action: \"checkpoint\",\n workflowId: wf.id,\n roundId: round.id,\n ...(run?.runId ? { runId: run.runId } : {}),\n },\n },\n [\n {\n tool: \"workflows\",\n description: `Checkpoint round ${round.num} when complete`,\n parameters: {\n action: \"checkpoint\",\n workflowId: wf.id,\n roundId: round.id,\n ...(run?.runId ? { runId: run.runId } : {}),\n },\n },\n ],\n ),\n };\n}\n\ninterface PersistedWorkflowRun {\n runId: string;\n // Matches the server's real shape (`Id<\"agentSessions\"> | undefined` — a workflow run\n // isn't always started by an agent session), not required (PR #395, Lane C S3b pass).\n agentSessionId: string | undefined;\n workflowId: string;\n workflowName: string;\n templateSlug: string;\n templateName: string;\n status: \"active\" | \"completed\";\n startedAt: string;\n completedAt: string | null;\n currentRoundId: string | null;\n checkpoints: Array<{\n roundId: string;\n output: WorkflowRunOutput;\n recordedAt: string;\n }>;\n summary: {\n docId: string | null;\n entryId: string;\n collection: string | null;\n capturedAt: string | null;\n } | null;\n projection: WorkflowRunRenderProjection;\n}\n\nexport async function handleGetRun(\n runId?: string,\n workflowId?: string,\n) {\n let run: PersistedWorkflowRun | null;\n if (runId) {\n run = await kernelQuery<GatewayRouteReturnByName<\"chainwork.getWorkflowRun\">>(\"chainwork.getWorkflowRun\", {\n runId,\n });\n } else {\n requireActiveSession();\n\n const agentSessionId = getAgentSessionId();\n if (!agentSessionId) {\n return validationResult(\n \"Active session required for workflow run inspection by workflowId.\",\n );\n }\n\n run = await kernelQuery<GatewayRouteReturnByName<\"chainwork.getLatestWorkflowRun\">>(\"chainwork.getLatestWorkflowRun\", {\n agentSessionId,\n workflowId,\n });\n }\n\n if (!run) {\n const target = runId\n ? `workflow run '${runId}'`\n : `workflow '${workflowId}' in the current session`;\n return validationResult(`No persisted run found for ${target}.`);\n }\n\n if (workflowId && run.workflowId !== workflowId) {\n return validationResult(\n `Workflow run '${run.runId}' belongs to workflow '${run.workflowId}', not '${workflowId}'.`,\n );\n }\n\n const stepLines = run.projection.steps.map((step) => {\n const status = step.status.toUpperCase();\n const outputSummary = step.output\n ? ` — ${workflowRunOutputToText(step.output)}`\n : \"\";\n return `- ${step.num}. ${step.label} [${status}]${outputSummary}`;\n });\n\n const lines = [\n `# Workflow Run: ${run.workflowName}`,\n \"\",\n `- Run ID: \\`${run.runId}\\``,\n `- Workflow ID: \\`${run.workflowId}\\``,\n `- Status: ${run.status}`,\n `- Progress: ${run.projection.completedCount}/${run.projection.totalCount}`,\n `- Current round: ${run.currentRoundId ? `\\`${run.currentRoundId}\\`` : \"complete\"}`,\n `- Renderable sections: ${Object.keys(run.projection.render.links).length}/${run.projection.render.sections.length}`,\n `- Started: ${run.startedAt}`,\n ...(run.completedAt ? [`- Completed: ${run.completedAt}`] : []),\n ...(run.summary\n ? [`- Summary entry: \\`${run.summary.entryId}\\``]\n : []),\n \"\",\n \"## Steps\",\n ...stepLines,\n ];\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Loaded workflow run ${run.runId} (${run.workflowName}).`,\n run,\n run.summary\n ? [\n {\n tool: \"relations\",\n description: \"Discover connections for the summary entry\",\n parameters: { action: \"suggest\", entryId: run.summary.entryId },\n },\n ]\n : undefined,\n ),\n };\n}\n\nexport async function handleCheckpoint(\n workflowId: string, roundId: string, output: WorkflowCheckpointOutputInput,\n isFinal?: boolean, restart?: boolean, summaryName?: string, summaryDescription?: string,\n summaryEntryId?: string, runId?: string | null, ownerTeamEntryId?: string, ownerRoleEntryId?: string,\n) {\n const wf = getWorkflow(workflowId);\n if (!wf) {\n return {\n content: [{\n type: \"text\" as const,\n text:\n `Workflow \"${workflowId}\" not found. ` +\n `Available: ${listWorkflows().map((w) => w.id).join(\", \")}.\\n\\n` +\n `This checkpoint was NOT saved. Continue the conversation — the facilitator has the context.`,\n }],\n structuredContent: failure(\n \"NOT_FOUND\",\n `Workflow '${workflowId}' not found.`,\n \"Use workflows action=list to see available workflows.\",\n [{ tool: \"workflows\", description: \"List workflows\", parameters: { action: \"list\" } }],\n ),\n };\n }\n\n const round = wf.rounds.find((r) => r.id === roundId);\n if (!round) {\n const availableRounds = wf.rounds.map((r) => r.id).join(\", \");\n const closest = findClosestRound(roundId, wf.rounds);\n\n const correctionActions: NextAction[] = closest\n ? [\n {\n tool: \"workflows\",\n description: `Retry with corrected round ID '${closest.id}'`,\n parameters: { action: \"checkpoint\", workflowId, roundId: closest.id },\n },\n ]\n : [\n {\n tool: \"workflows\",\n description: \"List workflows to inspect round IDs\",\n parameters: { action: \"list\" },\n },\n ];\n\n const suggestionHint = closest ? ` Did you mean '${closest.id}'?` : \"\";\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `Round \"${roundId}\" not found in workflow \"${workflowId}\".${suggestionHint} ` +\n `Available rounds: ${availableRounds}.\\n\\n` +\n `This checkpoint was NOT saved. The conversation context is preserved — continue facilitating.`,\n }],\n structuredContent: failure(\n \"NOT_FOUND\",\n `Round '${roundId}' not found in workflow '${workflowId}'.`,\n closest\n ? `Did you mean '${closest.id}'? Available rounds: ${availableRounds}`\n : `Available rounds: ${availableRounds}`,\n correctionActions,\n ),\n };\n }\n\n const lines: string[] = [\n `## Checkpoint: Round ${round.num} — ${round.label}`,\n `Workflow: ${wf.name} (\\`${wf.id}\\`)`,\n \"\",\n ];\n\n if (restart && isFinal) {\n return validationResult(\n \"restart cannot be combined with isFinal. Restart from the first round, then continue the workflow normally.\",\n );\n }\n\n let normalizedOutput: WorkflowRunOutput;\n try {\n normalizedOutput = coerceWorkflowRunOutput(round, output);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return validationResult(message);\n }\n\n const outputPreview = workflowRunOutputToText(normalizedOutput);\n\n if (isFinal) {\n const finalCheckpointValidationError = validateFinalWorkflowCheckpoint(\n wf,\n roundId,\n );\n if (finalCheckpointValidationError) {\n return validationResult(finalCheckpointValidationError);\n }\n\n const descriptor = getWorkflowDescriptor(workflowId);\n const template = descriptor\n ? getWorkflowTemplateMetadata(descriptor)\n : { slug: wf.id, name: wf.name };\n const summaryCapture = descriptor\n ? getWorkflowSummaryCaptureDefinition(descriptor)\n : wf.kbOutputCollection && wf.kbOutputTemplate\n ? {\n routing: {\n mode: \"fixed\" as const,\n collection: wf.kbOutputCollection,\n },\n nameTemplate: wf.kbOutputTemplate.nameTemplate,\n descriptionField: wf.kbOutputTemplate.descriptionField,\n descriptionSource: \"final-output-text\" as const,\n }\n : null;\n\n if (!summaryCapture && !summaryEntryId) {\n return validationResult(\n `Workflow '${workflowId}' does not support final summary capture through workflows.checkpoint. Follow the workflow guidance and use capture directly for its primary record, or pass summaryEntryId to link an existing entry.`,\n );\n }\n\n requireWriteAccess();\n const agentSessionId = getAgentSessionId();\n if (!agentSessionId) {\n return validationResult(\n \"Active agent session required for workflow checkpoint persistence.\",\n );\n }\n\n if (summaryEntryId && !summaryCapture) {\n return handleFacilitatedFinalization(\n wf, descriptor, roundId, normalizedOutput, agentSessionId, summaryEntryId, lines, runId,\n );\n }\n\n // After the guards above, summaryCapture is guaranteed non-null:\n // - Line 523: both null → early return\n // - Line 537: summaryEntryId truthy + summaryCapture null → early return\n const resolvedSummaryCapture = summaryCapture!;\n\n\n const existingRun = await kernelQuery<GatewayRouteReturnByName<\"chainwork.getLatestWorkflowRun\">>(\n \"chainwork.getLatestWorkflowRun\",\n {\n agentSessionId,\n workflowId: wf.id,\n },\n );\n if (!existingRun) {\n return validationResult(\n `Workflow '${workflowId}' has no durable run to finalize yet. Record checkpoints for the earlier rounds first.`,\n );\n }\n\n try {\n // FEAT-157: Pre-resolve collection for classifier-mode workflows (two-call pattern, DEC-163).\n // The Convex mutation can't call the LLM action, so MCP orchestrates.\n let resolvedCollectionSlug: string | undefined;\n if (resolvedSummaryCapture.routing.mode === \"classifier\") {\n const classifyName = summaryName ?? wf.name;\n const classifyDesc = summaryDescription ?? outputPreview;\n const resolved = await resolveCollection({ name: classifyName, description: classifyDesc });\n if (resolved && resolved.tier !== \"low\") {\n resolvedCollectionSlug = resolved.collection;\n }\n }\n\n const result = await kernelMutation<{\n runId: string;\n summary: {\n docId: string;\n entryId: string;\n name: string;\n created: boolean;\n collection: string | null;\n };\n }>(\"chainwork.finalizeWorkflowRun\", {\n agentSessionId,\n workflowId: wf.id,\n workflowName: wf.name,\n templateSlug: template.slug,\n templateName: template.name,\n steps: wf.rounds.map((workflowRound) => ({\n roundId: workflowRound.id,\n num: workflowRound.num,\n label: workflowRound.label,\n type: workflowRound.type,\n outputField: workflowRound.outputSchema.field,\n outputFormat: workflowRound.outputSchema.format,\n })),\n finalRoundId: roundId,\n finalOutput: normalizedOutput,\n summaryCapture: {\n routing:\n resolvedSummaryCapture.routing.mode === \"fixed\"\n ? {\n mode: \"fixed\" as const,\n collection: resolvedSummaryCapture.routing.collection,\n }\n : {\n mode: \"classifier\" as const,\n },\n nameTemplate: resolvedSummaryCapture.nameTemplate,\n descriptionField: resolvedSummaryCapture.descriptionField,\n descriptionSource: resolvedSummaryCapture.descriptionSource,\n },\n summaryDescription,\n summaryName,\n resolvedCollectionSlug,\n // WP-513 review round 3 (P1): rung-2 owner — no-op pre-rung-2.\n ...(ownerTeamEntryId ? { ownerTeamEntryId } : {}),\n ...(ownerRoleEntryId ? { ownerRoleEntryId } : {}),\n });\n\n lines.push(\n result.summary.created\n ? `**Draft Created**: \\`${result.summary.entryId}\\``\n : `**Draft Already Exists**: \\`${result.summary.entryId}\\``,\n `Collection: \\`${result.summary.collection ?? (resolvedSummaryCapture.routing.mode === \"fixed\" ? resolvedSummaryCapture.routing.collection : \"classifier-routed\")}\\``,\n `Name: ${result.summary.name}`,\n \"\",\n `The summary is captured as a draft. Use \\`entries action=commit entryId=\"${result.summary.entryId}\"\\` to promote it to the Chain.`,\n `Use \\`relations action=suggest entryId=\"${result.summary.entryId}\"\\` to discover connections.`,\n );\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Draft '${result.summary.name}' ${result.summary.created ? \"created\" : \"reused\"} (${result.summary.entryId}) for workflow ${workflowId}.`,\n {\n entryId: result.summary.entryId,\n workflowId,\n roundId,\n collection:\n result.summary.collection ??\n (resolvedSummaryCapture.routing.mode === \"fixed\"\n ? resolvedSummaryCapture.routing.collection\n : null),\n isFinal: true,\n runId: result.runId,\n created: result.summary.created,\n },\n [\n {\n tool: \"entries\",\n description: \"Promote draft to Chain\",\n parameters: { action: \"commit\", entryId: result.summary.entryId },\n },\n {\n tool: \"relations\",\n description: \"Discover connections\",\n parameters: { action: \"suggest\", entryId: result.summary.entryId },\n },\n ],\n ),\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n lines.push(\n `**Chain accept failed**: ${msg}`,\n \"\",\n `The workflow output is preserved in this conversation. `,\n `You can manually create the entry later using \\`capture\\` with:`,\n `- Collection: \\`${resolvedSummaryCapture.routing.mode === \"fixed\" ? resolvedSummaryCapture.routing.collection : \"classifier-routed\"}\\``,\n `- Name: ${summaryName ?? resolvedSummaryCapture.nameTemplate}`,\n `- Description: ${summaryDescription ?? outputPreview}`,\n );\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: failure(\n \"BACKEND_ERROR\",\n `Chain accept failed: ${msg}.`,\n \"Capture manually with the capture tool.\",\n [{ tool: \"capture\", description: \"Capture manually\", parameters: {} }],\n ),\n };\n }\n } else {\n requireWriteAccess();\n const agentSessionId = getAgentSessionId();\n if (!agentSessionId) {\n return validationResult(\n \"Active agent session required for workflow checkpoint persistence.\",\n );\n }\n\n try {\n const descriptor = getWorkflowDescriptor(workflowId);\n const template = descriptor\n ? getWorkflowTemplateMetadata(descriptor)\n : { slug: wf.id, name: wf.name };\n const checkpointResult = await kernelMutation<GatewayRouteReturnByName<\"chainwork.recordWorkflowCheckpoint\">>(\"chainwork.recordWorkflowCheckpoint\", {\n agentSessionId,\n workflowId: wf.id,\n workflowName: wf.name,\n templateSlug: template.slug,\n templateName: template.name,\n steps: wf.rounds.map((workflowRound) => ({\n roundId: workflowRound.id,\n num: workflowRound.num,\n label: workflowRound.label,\n type: workflowRound.type,\n outputField: workflowRound.outputSchema.field,\n outputFormat: workflowRound.outputSchema.format,\n })),\n checkpoint: {\n roundId,\n output: normalizedOutput,\n recordedAt: new Date().toISOString(),\n },\n restart,\n ...(runId ? { runId } : {}),\n ...(summaryEntryId ? { summaryEntryId } : {}),\n });\n\n lines.push(\n `Round ${round.num} output recorded.`,\n `Output: ${outputPreview.substring(0, 200)}${outputPreview.length > 200 ? \"...\" : \"\"}`,\n `Progress: ${checkpointResult.projection.completedCount}/${checkpointResult.projection.totalCount} rounds completed.`,\n );\n\n const nextWorkflowRound = checkpointResult.projection.currentRoundId\n ? wf.rounds.find((workflowRound) => workflowRound.id === checkpointResult.projection.currentRoundId)\n : undefined;\n const nextRound = nextWorkflowRound\n ? { id: nextWorkflowRound.id, num: nextWorkflowRound.num, label: nextWorkflowRound.label }\n : undefined;\n\n if (checkpointResult.summary?.linked) {\n lines.push(\n \"\",\n `**Run completed.** Summary linked to existing entry \\`${checkpointResult.summary.entryId}\\`.`,\n );\n } else if (nextWorkflowRound) {\n lines.push(\n \"\",\n `**Next**: Round ${nextWorkflowRound.num} — ${nextWorkflowRound.label}`,\n `_${nextWorkflowRound.instruction}_`,\n );\n } else {\n lines.push(\n \"\",\n `**All rounds complete.** Call this tool again with \\`isFinal: true\\` to accept onto the Chain.`,\n );\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Round ${round.num} (${round.label}) output recorded for workflow ${workflowId}.`,\n {\n workflowId,\n roundId,\n roundNum: round.num,\n roundLabel: round.label,\n isFinal: false,\n nextRound,\n runId: checkpointResult.runId,\n runStatus: checkpointResult.run.status,\n progress: {\n completedCount: checkpointResult.projection.completedCount,\n totalCount: checkpointResult.projection.totalCount,\n },\n },\n ),\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n lines.push(\n `**Checkpoint persistence failed**: ${msg}`,\n \"\",\n `The conversation context is preserved, but this round was not saved as a durable workflow checkpoint.`,\n );\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: failure(\n \"BACKEND_ERROR\",\n `Workflow checkpoint persistence failed: ${msg}.`,\n \"Continue the workflow in conversation or retry the checkpoint.\",\n ),\n };\n }\n }\n}\n\nasync function handleFacilitatedFinalization(\n wf: WorkflowDefinition,\n descriptor: ReturnType<typeof getWorkflowDescriptor>,\n roundId: string,\n normalizedOutput: WorkflowRunOutput,\n agentSessionId: string,\n summaryEntryId: string,\n lines: string[],\n runId?: string | null,\n) {\n const template = descriptor\n ? getWorkflowTemplateMetadata(descriptor)\n : { slug: wf.id, name: wf.name };\n\n try {\n const checkpointResult = await kernelMutation<GatewayRouteReturnByName<\"chainwork.recordWorkflowCheckpoint\">>(\"chainwork.recordWorkflowCheckpoint\", {\n agentSessionId,\n workflowId: wf.id,\n workflowName: wf.name,\n templateSlug: template.slug,\n templateName: template.name,\n steps: wf.rounds.map((workflowRound) => ({\n roundId: workflowRound.id,\n num: workflowRound.num,\n label: workflowRound.label,\n type: workflowRound.type,\n outputField: workflowRound.outputSchema.field,\n outputFormat: workflowRound.outputSchema.format,\n })),\n checkpoint: {\n roundId,\n output: normalizedOutput,\n recordedAt: new Date().toISOString(),\n },\n summaryEntryId,\n ...(runId ? { runId } : {}),\n });\n\n const linked = checkpointResult.summary?.linked ?? false;\n lines.push(\n `**Run finalized**: Linked to existing entry \\`${summaryEntryId}\\`.`,\n `Status: ${checkpointResult.run.status}`,\n `Progress: ${checkpointResult.projection.completedCount}/${checkpointResult.projection.totalCount}`,\n );\n\n if (!linked && checkpointResult.run.status !== \"completed\") {\n lines.push(\n \"\",\n `Note: The run is not yet completed — the summary will be linked when all rounds are checkpointed.`,\n );\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Workflow ${wf.id} finalized with linked entry ${summaryEntryId}.`,\n {\n entryId: summaryEntryId,\n workflowId: wf.id,\n roundId,\n isFinal: true,\n runId: checkpointResult.runId,\n linked,\n runStatus: checkpointResult.run.status,\n },\n [\n {\n tool: \"relations\",\n description: \"Discover connections\",\n parameters: { action: \"suggest\", entryId: summaryEntryId },\n },\n ],\n ),\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n lines.push(\n `**Finalization failed**: ${msg}`,\n \"\",\n `The workflow output is preserved in this conversation.`,\n );\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: failure(\n \"BACKEND_ERROR\",\n `Facilitated finalization failed: ${msg}.`,\n \"The facilitate tool's state is preserved — retry the checkpoint or continue in conversation.\",\n ),\n };\n }\n}\n\nexport function coerceWorkflowRunOutput(\n round: WorkflowDefinition[\"rounds\"][number],\n output: WorkflowCheckpointOutputInput,\n): WorkflowRunOutput {\n if (typeof output !== \"string\") {\n assertWorkflowRunOutputMatchesRound(round, output);\n return output;\n }\n\n const trimmed = output.trim();\n\n switch (round.outputSchema.format) {\n case \"freetext\":\n return { format: \"freetext\", value: trimmed };\n case \"list\":\n return { format: \"list\", value: parseListOutput(trimmed) };\n case \"choice\":\n return { format: \"choice\", value: trimmed };\n case \"structured\":\n return { format: \"structured\", value: { text: trimmed } };\n }\n}\n\nfunction assertWorkflowRunOutputMatchesRound(\n round: WorkflowDefinition[\"rounds\"][number],\n output: WorkflowRunOutput,\n): void {\n if (output.format !== round.outputSchema.format) {\n throw new Error(\n `Round '${round.id}' expects '${round.outputSchema.format}' output, received '${output.format}'.`,\n );\n }\n}\n\nexport function parseListOutput(output: string): string[] {\n const lines = output\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => line.replace(/^[-*]\\s+/, \"\").replace(/^\\d+\\.\\s+/, \"\").trim())\n .filter(Boolean);\n\n return lines.length > 0 ? lines : [output];\n}\n","/**\n * BET-85 — Canonical workflow descriptor for ChainWork workflows.\n *\n * The MCP runtime still consumes `WorkflowDefinition`, but built-in workflows\n * are authored as `WorkflowDescriptor` objects and compiled to the runtime\n * shape. The descriptor is the authoring contract; the compiled definition is a\n * backward-compatible runtime view for existing MCP surfaces.\n */\n\nexport type WorkflowOutputFormat =\n | \"freetext\"\n | \"list\"\n | \"choice\"\n | \"structured\";\n\nexport interface WorkflowRound {\n id: string;\n num: string;\n label: string;\n type: \"open\" | \"choice\" | \"synthesis\" | \"commit\" | \"close\";\n instruction: string;\n facilitatorGuidance: string;\n questions?: WorkflowQuestion[];\n outputSchema: {\n field: string;\n description: string;\n format: WorkflowOutputFormat;\n };\n kbCollection?: string;\n maxDurationHint?: string;\n}\n\nexport interface WorkflowQuestion {\n id: string;\n prompt: string;\n options?: { id: string; label: string }[];\n allowMultiple?: boolean;\n required?: boolean;\n}\n\nexport interface WorkflowDefinition {\n id: string;\n name: string;\n shortDescription: string;\n icon: string;\n facilitatorPreamble: string;\n rounds: WorkflowRound[];\n kbOutputCollection?: string;\n kbOutputTemplate?: {\n nameTemplate: string;\n descriptionField: string;\n };\n errorRecovery: string;\n}\n\nexport type WorkflowPrimaryRecordRouting =\n | { mode: \"fixed\"; collection: string }\n | { mode: \"classifier\" };\n\nexport type WorkflowSummaryDescriptionSource =\n | \"final-output-text\"\n | { mode: \"step-output-field\"; field: string };\n\nexport interface WorkflowSummaryCapture {\n createsPrimaryRecord: boolean;\n nameTemplate: string;\n descriptionField?: string;\n descriptionSource?: WorkflowSummaryDescriptionSource;\n}\n\nexport interface WorkflowEmittedArtifact {\n kind: \"entry\" | \"update\";\n collection?: string;\n description: string;\n}\n\nexport interface WorkflowDescriptor {\n id: string;\n name: string;\n shortDescription: string;\n icon: string;\n facilitatorPreamble: string;\n rounds: WorkflowRound[];\n template: {\n slug: string;\n name: string;\n };\n output: {\n primaryRecord: {\n routing: WorkflowPrimaryRecordRouting;\n };\n summaryCapture?: WorkflowSummaryCapture;\n emits?: WorkflowEmittedArtifact[];\n };\n runtime: {\n kind: \"guided\" | \"facilitated\";\n primaryTool?: string;\n };\n errorRecovery: string;\n}\n\nfunction cloneWorkflowQuestion(question: WorkflowQuestion): WorkflowQuestion {\n return {\n ...question,\n options: question.options?.map((option) => ({ ...option })),\n };\n}\n\nfunction cloneWorkflowRound(round: WorkflowRound): WorkflowRound {\n return {\n ...round,\n questions: round.questions?.map(cloneWorkflowQuestion),\n outputSchema: { ...round.outputSchema },\n };\n}\n\nexport function cloneWorkflowDescriptor(\n descriptor: WorkflowDescriptor,\n): WorkflowDescriptor {\n return {\n ...descriptor,\n rounds: descriptor.rounds.map(cloneWorkflowRound),\n template: { ...descriptor.template },\n output: {\n primaryRecord: {\n routing:\n descriptor.output.primaryRecord.routing.mode === \"fixed\"\n ? {\n mode: \"fixed\",\n collection: descriptor.output.primaryRecord.routing.collection,\n }\n : { mode: \"classifier\" },\n },\n summaryCapture: descriptor.output.summaryCapture\n ? { ...descriptor.output.summaryCapture }\n : undefined,\n emits: descriptor.output.emits?.map((emitted) => ({ ...emitted })),\n },\n runtime: { ...descriptor.runtime },\n };\n}\n\nexport function cloneWorkflowDefinition(\n definition: WorkflowDefinition,\n): WorkflowDefinition {\n return {\n ...definition,\n rounds: definition.rounds.map(cloneWorkflowRound),\n kbOutputTemplate: definition.kbOutputTemplate\n ? { ...definition.kbOutputTemplate }\n : undefined,\n };\n}\n\nexport function validateWorkflowDescriptor(\n descriptor: WorkflowDescriptor,\n): void {\n if (descriptor.rounds.length === 0) {\n throw new Error(`Workflow '${descriptor.id}' must define at least one round.`);\n }\n\n const roundIds = new Set<string>();\n for (const [index, round] of descriptor.rounds.entries()) {\n if (roundIds.has(round.id)) {\n throw new Error(`Workflow '${descriptor.id}' has duplicate round id '${round.id}'.`);\n }\n roundIds.add(round.id);\n\n const expectedNum = String(index + 1).padStart(2, \"0\");\n if (round.num !== expectedNum) {\n throw new Error(\n `Workflow '${descriptor.id}' round '${round.id}' has num '${round.num}', expected '${expectedNum}'.`,\n );\n }\n\n const questionIds = new Set<string>();\n for (const question of round.questions ?? []) {\n if (questionIds.has(question.id)) {\n throw new Error(\n `Workflow '${descriptor.id}' round '${round.id}' has duplicate question id '${question.id}'.`,\n );\n }\n questionIds.add(question.id);\n }\n }\n\n if (\n descriptor.runtime.kind === \"facilitated\" &&\n !descriptor.runtime.primaryTool\n ) {\n throw new Error(\n `Workflow '${descriptor.id}' is facilitated and must define runtime.primaryTool.`,\n );\n }\n\n if (\n descriptor.output.summaryCapture?.createsPrimaryRecord &&\n descriptor.output.primaryRecord.routing.mode === \"fixed\" &&\n descriptor.output.summaryCapture.descriptionField === \"\"\n ) {\n throw new Error(\n `Workflow '${descriptor.id}' summaryCapture.descriptionField cannot be empty.`,\n );\n }\n}\n\nexport function getWorkflowSummaryCaptureDefinition(\n descriptor: WorkflowDescriptor,\n): {\n routing: WorkflowPrimaryRecordRouting;\n nameTemplate: string;\n descriptionField?: string;\n descriptionSource: WorkflowSummaryDescriptionSource;\n} | null {\n const { summaryCapture } = descriptor.output;\n const { routing } = descriptor.output.primaryRecord;\n\n if (!summaryCapture || !summaryCapture.createsPrimaryRecord) {\n return null;\n }\n\n return {\n routing:\n routing.mode === \"fixed\"\n ? { mode: \"fixed\", collection: routing.collection }\n : { mode: \"classifier\" },\n nameTemplate: summaryCapture.nameTemplate,\n descriptionField: summaryCapture.descriptionField,\n descriptionSource: summaryCapture.descriptionSource ?? \"final-output-text\",\n };\n}\n\nexport function getWorkflowPrimaryRecordCollection(\n descriptor: WorkflowDescriptor,\n): string | null {\n const { routing } = descriptor.output.primaryRecord;\n return routing.mode === \"fixed\" ? routing.collection : null;\n}\n\nexport function getWorkflowTemplateMetadata(\n descriptor: WorkflowDescriptor,\n): { slug: string; name: string } {\n return {\n slug: descriptor.template.slug,\n name: descriptor.template.name,\n };\n}\n\nexport function getWorkflowContextCollection(\n descriptor: WorkflowDescriptor,\n): string | null {\n return getWorkflowPrimaryRecordCollection(descriptor);\n}\n\nexport function describeWorkflowPrimaryOutput(\n descriptor: WorkflowDescriptor,\n): string {\n const { routing } = descriptor.output.primaryRecord;\n\n if (routing.mode === \"fixed\") {\n return `Primary record routes to \\`${routing.collection}\\`.`;\n }\n\n return \"Primary record is classifier-routed at runtime.\";\n}\n\nexport function compileWorkflowDefinition(\n descriptor: WorkflowDescriptor,\n): WorkflowDefinition {\n validateWorkflowDescriptor(descriptor);\n const clonedDescriptor = cloneWorkflowDescriptor(descriptor);\n const primaryRecordCollection = getWorkflowPrimaryRecordCollection(\n clonedDescriptor,\n );\n const summaryCapture = getWorkflowSummaryCaptureDefinition(clonedDescriptor);\n\n return {\n id: clonedDescriptor.id,\n name: clonedDescriptor.name,\n shortDescription: clonedDescriptor.shortDescription,\n icon: clonedDescriptor.icon,\n facilitatorPreamble: clonedDescriptor.facilitatorPreamble,\n rounds: clonedDescriptor.rounds,\n kbOutputCollection: primaryRecordCollection ?? undefined,\n kbOutputTemplate:\n summaryCapture && summaryCapture.routing.mode === \"fixed\"\n ? {\n nameTemplate: summaryCapture.nameTemplate,\n descriptionField: summaryCapture.descriptionField ?? \"description\",\n }\n : undefined,\n errorRecovery: clonedDescriptor.errorRecovery,\n };\n}\n","/**\n * Chainwork Workflow Definitions — ARCH-node-mcp (Core layer)\n * Chain: GT-006 (MCP), FEAT-MCP-001, BET-85\n *\n * Built-in workflows are authored as canonical descriptors, then compiled to the\n * current WorkflowDefinition runtime shape. This keeps runtime behavior stable\n * while giving BET-85 a single registry contract to build on.\n */\n\nimport {\n cloneWorkflowDefinition,\n cloneWorkflowDescriptor,\n compileWorkflowDefinition,\n type WorkflowDefinition,\n type WorkflowDescriptor,\n} from \"./descriptor.js\";\n\nexport type {\n WorkflowDefinition,\n WorkflowDescriptor,\n WorkflowQuestion,\n WorkflowRound,\n} from \"./descriptor.js\";\n\n// ── Retro Workflow ──────────────────────────────────────────────────────────\n\nconst RETRO_WORKFLOW_DESCRIPTOR: WorkflowDescriptor = {\n id: \"retro\",\n name: \"Retrospective\",\n shortDescription:\n \"Structured team retrospective — reflect, surface patterns, commit to actions. Accepts a decision entry onto the Chain.\",\n template: {\n slug: \"retro\",\n name: \"Retrospective\",\n },\n icon: \"◎\",\n facilitatorPreamble: `You are now in **Facilitator Mode**. You are not a coding assistant — you are a facilitator running a structured retrospective.\n\n## Your Behavior\n\n1. **Guide, don't solve.** Ask questions, reflect back, synthesize. Never jump to solutions.\n2. **One round at a time.** Complete each round fully before moving to the next. No skipping.\n3. **Use structured questions** (AskQuestion tool) for choices and multi-select. Use open conversation for reflection.\n4. **Create a Plan** at the start showing all rounds as tasks. Update it as you progress.\n5. **Synthesize between rounds.** After collecting input, reflect back what you heard before moving on.\n6. **Never go silent.** If something fails, say what happened and what to do next.\n7. **Finalize through the workflow substrate.** Complete the terminal round with \\`workflows action=checkpoint ... isFinal=true\\` so the durable run creates the retro draft record.\n8. **Session before checkpoint (default).** Before the **first** \\`workflows action=checkpoint\\` in this run, ensure an **active** agent write session: MCP \\`session action=start\\` or \\`pb session start\\` (DEC-9, STD-135). Inactive or superseded sessions commonly return **400** on checkpoint — durable progress is lost unless the chat record or a **handoff block** preserves it (see handoff skill: Facilitated workflow handoff).\n9. **Hand off mid-flight.** If the user switches agents or checkpoint keeps failing, emit the **Facilitated workflow handoff** package from \\`.productbrain/skills/handoff.md\\` (copy-paste block). Another agent resumes from that block + \\`workflows get-run\\` or \\`start\\` with \\`restart=true\\` — see workflow \\`errorRecovery\\`.\n10. **Match the energy.** Be warm but structured. This is a ceremony, not a checklist.\n\n## Communication Style\n\n- Start each round with its number, name, and a brief instruction\n- Use quotes and emphasis to reflect back what the participant said\n- End each round with a brief synthesis before transitioning\n- When a round is complete, mark it as done in the Plan\n- If the participant seems stuck, offer prompts — never pressure\n- If a tool call fails, explain what happened and offer an alternative path\n\n## Error Recovery\n\nIf at any point a tool call or MCP operation fails:\n1. Tell the participant what you were trying to do\n2. Explain what went wrong (briefly, no stack traces)\n3. Offer a manual alternative (e.g., \"I'll capture this in the conversation instead\")\n4. Continue the workflow — never halt completely\n\n## Plan Structure\n\nCreate a Cursor Plan with these rounds as tasks. Mark each in_progress as you enter it, completed when done.`,\n\n rounds: [\n {\n id: \"set-stage\",\n num: \"01\",\n label: \"Set the Stage\",\n type: \"choice\",\n instruction:\n \"Before we dive in, let's frame what we're reflecting on. What's the scope of this retro?\",\n facilitatorGuidance:\n \"Start warm. Ask the participant to pick or describe what they're retro-ing. Confirm the scope before proceeding. If they gave context already in their initial message, use it — don't make them repeat.\",\n questions: [\n {\n id: \"scope\",\n prompt:\n \"What are we reflecting on? Pick one or describe your own.\",\n options: [\n { id: \"last-week\", label: \"Last week's work\" },\n { id: \"last-sprint\", label: \"Last sprint/cycle\" },\n { id: \"specific-project\", label: \"A specific project or feature\" },\n { id: \"process\", label: \"A process or workflow\" },\n { id: \"custom\", label: \"Something else — let me describe it\" },\n ],\n },\n ],\n outputSchema: {\n field: \"scope\",\n description: \"What timeframe or project is being retro'd\",\n format: \"freetext\",\n },\n maxDurationHint: \"2 min\",\n },\n {\n id: \"what-went-well\",\n num: \"02\",\n label: \"What Went Well\",\n type: \"open\",\n instruction:\n \"Let's start with the good. What went well? What are you proud of? What should we do more of?\",\n facilitatorGuidance:\n \"Celebrate. Reflect back each win with genuine emphasis. Ask follow-ups like 'What made that work?' or 'Who else contributed to that?' Collect at least 3 items before synthesizing. Don't rush past the positive — teams skip this too fast.\",\n outputSchema: {\n field: \"wentWell\",\n description: \"List of things that went well\",\n format: \"list\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"what-didnt-go-well\",\n num: \"03\",\n label: \"What Didn't Go Well\",\n type: \"open\",\n instruction:\n \"Now the harder part. What didn't go well? What frustrated you? Where did things break down?\",\n facilitatorGuidance:\n \"Create safety. Acknowledge that this is harder. Don't judge or immediately problem-solve — just listen and capture. Ask 'What was the impact of that?' and 'When did you first notice it?'. Reflect back without softening. Collect at least 3 items.\",\n outputSchema: {\n field: \"didntGoWell\",\n description: \"List of things that didn't go well\",\n format: \"list\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"patterns\",\n num: \"04\",\n label: \"Patterns & Insights\",\n type: \"synthesis\",\n instruction:\n \"Looking at what went well and what didn't — what patterns do you see? What's the deeper insight?\",\n facilitatorGuidance:\n \"This is YOUR moment as facilitator. Synthesize what you've heard across rounds 2 and 3. Surface themes, connections, and contradictions. Propose 2-3 patterns and ask the participant to react. This round transforms raw observations into actionable insights. Don't let the participant skip the 'why' — push for root causes.\",\n outputSchema: {\n field: \"patterns\",\n description: \"Synthesized patterns and insights\",\n format: \"structured\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"actions\",\n num: \"05\",\n label: \"Actions & Commitments\",\n type: \"commit\",\n instruction:\n \"Based on these patterns, what will we actually change? Be specific — who does what, by when?\",\n facilitatorGuidance:\n \"Push for specificity. 'Be better at X' is not an action. 'Randy will set up a 15-min weekly check-in by Friday' is. Each action needs an owner and a deadline. Aim for 2-4 concrete actions. Use AskQuestion to confirm the final list. These become the retro's output.\",\n questions: [\n {\n id: \"action-confirm\",\n prompt: \"Are these actions concrete enough to actually happen?\",\n options: [\n { id: \"yes\", label: \"Yes — these are clear and actionable\" },\n { id: \"refine\", label: \"Let me refine some of these\" },\n { id: \"add\", label: \"I want to add more\" },\n ],\n },\n ],\n outputSchema: {\n field: \"actions\",\n description: \"Committed actions with owners and deadlines\",\n format: \"structured\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"close\",\n num: \"06\",\n label: \"Close & Capture\",\n type: \"close\",\n instruction:\n \"One last thing — in one sentence, what's the single most important thing you're taking away from this retro?\",\n facilitatorGuidance:\n \"Keep it brief. One sentence reflection. Then summarize the entire retro: scope, key wins, key pain points, patterns identified, actions committed. Finalize the durable run through \\`workflows action=checkpoint\\` with \\`isFinal=true\\` so the retro draft record is created via the workflow substrate. Then ask if they want to accept that draft onto the Chain. Thank them for the retro.\",\n outputSchema: {\n field: \"takeaway\",\n description: \"Single-sentence takeaway\",\n format: \"freetext\",\n },\n kbCollection: \"decisions\",\n maxDurationHint: \"2 min\",\n },\n ],\n\n output: {\n primaryRecord: {\n routing: {\n mode: \"fixed\",\n collection: \"decisions\",\n },\n },\n summaryCapture: {\n createsPrimaryRecord: true,\n nameTemplate: \"Retro: {scope} — {date}\",\n descriptionField: \"rationale\",\n },\n },\n runtime: {\n kind: \"guided\",\n },\n\n errorRecovery: `If anything goes wrong during the retro:\n\n1. **MCP tool failure**: Skip the workflow finalization step. Summarize everything in the conversation instead. Suggest retrying \\`workflows action=checkpoint\\` later or capturing manually if needed.\n2. **AskQuestion not available**: Fall back to numbered options in plain text. \"Reply with 1, 2, or 3.\"\n3. **Plan creation fails**: Continue without the Plan. The conversation IS the record.\n4. **Participant goes off-topic**: Gently redirect: \"That's valuable — let's capture it. For now, let's stay with [current round].\"\n5. **Participant wants to stop**: Respect it. Summarize what you have so far. Offer to accept partial results onto the Chain.\n6. **Checkpoint failed (e.g. 400, superseded session)**: Say so in one line. **Start or refresh session** (\\`session action=start\\` / \\`pb session start\\`), then \\`workflows action=get-run\\` with the \\`runId\\` you were given. If the run is **incomplete**, retry \\`checkpoint\\` with that \\`runId\\`. If the run is **complete** or **missing**, treat server state as unreliable: run \\`workflows action=start workflowId=retro restart=true\\` and **paste the Facilitated workflow handoff block** from the prior chat into round 1 so scope and completed rounds are explicit — do not assume partial server progress exists.\n7. **Cross-agent resume (default expectation)**: Receiving agent reads the handoff block first. Prefer \\`get-run\\` to verify status; otherwise **restart** and continue from the **next round** named in the handoff. The conversation + handoff block are valid SSOT when ChainWork did not persist checkpoints (TEN-917).\n\nThe retro must never fail silently. Always communicate state.`,\n};\n\n// ── Shape Workflow ──────────────────────────────────────────────────────────\n\nconst SHAPE_WORKFLOW_DESCRIPTOR: WorkflowDescriptor = {\n id: \"shape\",\n name: \"Shape a Bet\",\n shortDescription:\n \"Integration-aware shaping: maps the system before designing, traces five paths per element, \" +\n \"surfaces governance conflicts at design time. Scoring is in the shaping skill; uses capture and session action=commit-constellation for Chain capture.\",\n template: {\n slug: \"shape-a-bet\",\n name: \"Shape a Bet\",\n },\n icon: \"◆\",\n facilitatorPreamble: `You are now in **Shaping Mode**. The shaping skill owns the facilitation loop end-to-end — read it for scoring rubrics, investigation patterns, and the capture flow.\n\nUse \\`capture\\` to create constellation entries (elements, risks, decisions, glossary terms) linked to the work package.\nUse \\`session action=commit-constellation\\` to atomically accept the work package and all linked entries when the shape is complete.\nUse \\`workflows action=checkpoint\\` after each round to persist progress to the durable run.`,\n\n rounds: [\n {\n id: \"context\",\n num: \"01\",\n label: \"Gather Context\",\n type: \"open\",\n instruction:\n \"Before shaping, let's see what the Chain already knows. Search for related entries, business rules, and existing decisions.\",\n facilitatorGuidance:\n \"**Investigate proactively.** Spawn sub-agents in parallel: \" +\n \"(1) `explore` agent to search the codebase for code related to the work package topic — find modules, patterns, and pain points. \" +\n \"(2) `generalPurpose` agent to search the Chain: call `orient`, use `entries action=search` with keywords, surface related tensions, active work packages, and applicable business rules. \" +\n \"Synthesize both into a 3-5 line context brief: what the codebase reveals, what the Chain knows, what governance applies. \" +\n \"Present with IDs and file paths. Build a system map: what modules, data flows, and contracts exist in this area today? \" +\n \"Check governance: do any principles, standards, or business rules constrain this design space? \" +\n \"Then transition: 'Here's what I found. Does this match the problem you're seeing?'\",\n outputSchema: {\n field: \"context\",\n description: \"System map, Chain context, governance constraints, related entries\",\n format: \"structured\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"framing\",\n num: \"02\",\n label: \"Frame the Problem\",\n type: \"open\",\n instruction:\n \"What's the problem? Who's affected? What's the workaround today? How much time is this worth?\",\n facilitatorGuidance:\n \"This round covers problem clarity AND appetite. \" +\n \"Search the codebase for workarounds, TODOs, and hacks related to the problem — cite what you find as evidence. \" +\n \"Push with evidence: 'I found 3 workaround patterns in the codebase — this suggests the problem is bigger than it looks.' \" +\n \"Use AskQuestion for appetite: Small Batch (1-2 weeks) or Big Batch (6 weeks). \" +\n \"When both dimensions are well-covered, present the frame and ask for Frame Go confirmation. \" +\n \"If new terms surfaced, capture them to the glossary via `capture`. If tensions surfaced, capture them too.\",\n questions: [\n {\n id: \"appetite\",\n prompt: \"How much time is this idea worth? Not how long it'll take — how much are you willing to invest?\",\n options: [\n { id: \"small\", label: \"Small Batch — 1-2 weeks, focused scope\" },\n { id: \"big\", label: \"Big Batch — 6 weeks, full treatment\" },\n ],\n },\n {\n id: \"frame-go\",\n prompt: \"Frame Go — the problem is tight enough to shape a solution. Proceed to elements?\",\n options: [\n { id: \"go\", label: \"Frame Go — move to elements\" },\n { id: \"refine\", label: \"Refine the frame — something's not right\" },\n ],\n },\n ],\n outputSchema: {\n field: \"framing\",\n description: \"Confirmed problem statement and appetite\",\n format: \"structured\",\n },\n kbCollection: \"work-packages\",\n maxDurationHint: \"10 min\",\n },\n {\n id: \"elements\",\n num: \"03\",\n label: \"Find the Elements\",\n type: \"open\",\n instruction:\n \"What are the solution elements? Think breadboard level — places, affordances, connections. What's the architecture?\",\n facilitatorGuidance:\n \"**Investigate first.** Spawn sub-agents to search the codebase for affected modules, existing architecture patterns, and API boundaries. \" +\n \"Synthesize findings into 3-5 proposed solution elements at breadboard level, citing specific files and modules. \" +\n \"**Five-path trace per element:** For each element, trace: (1) what data flows through it, (2) what contracts it relies on, \" +\n \"(3) what contracts it alters, (4) what second-order effects downstream, (5) what happens at boundaries (batch, error, empty, scale). \" +\n \"Present proposals for user reaction: 'Based on the codebase, here are the elements I'd suggest.' \" +\n \"For each confirmed element, use `capture` with collection='features' to create a features entry linked to the work package via part_of. \" +\n \"For Big Batch: also investigate architecture — search for layer boundaries and dependency directions, then propose architecture. \" +\n \"Check business rules: do any elements conflict with governance surfaced in Round 1? \" +\n \"Capture new glossary terms and decisions as they surface. \" +\n \"Aim for 3-5 elements. When elements and architecture are well-covered, present for confirmation.\",\n outputSchema: {\n field: \"elements\",\n description: \"Core solution elements and architecture\",\n format: \"structured\",\n },\n kbCollection: \"features\",\n maxDurationHint: \"15 min\",\n },\n {\n id: \"derisking\",\n num: \"04\",\n label: \"De-risk — Rabbit Holes & No-Gos\",\n type: \"open\",\n instruction:\n \"What could go wrong? What are we NOT building? Walk through the solution slowly and find the risks.\",\n facilitatorGuidance:\n \"**Investigate first.** Spawn sub-agents to search the codebase for fragile code, tight coupling, missing tests, performance-sensitive paths, and external dependencies near the affected modules. \" +\n \"Propose risks with evidence: 'I found that X module has no tests and is tightly coupled to Y — this is a rabbit hole.' \" +\n \"Every confirmed risk MUST be captured using `capture` with collection='tensions' — each becomes a tensions entry linked to the work package via constrains. \" +\n \"Push for mitigations — every risk needs a patch or explicit acceptance. \" +\n \"Then declare no-gos: 'Based on what I've seen, I'd suggest these no-gos.' Every no-go MUST also be captured. \" +\n \"**Counter-Metric Mandate (STD-19):** If the derisking references any quantitative gates or metrics (accuracy targets, performance budgets, adoption thresholds), \" +\n \"stress-test them: 'What's the denominator? What gets excluded? What counter-metric would expose a false positive?' \" +\n \"A metric gate that can be gamed by abstaining or cherry-picking the population is not a gate — name the compound metric that can't be gamed. \" +\n \"When risks and boundaries are well-covered, present Shape Go gate: 'Is this buildable within the appetite?'\",\n questions: [\n {\n id: \"shape-go\",\n prompt: \"Shape Go — the solution fits the appetite and risks are managed. Proceed to validation?\",\n options: [\n { id: \"go\", label: \"Shape Go — move to validation\" },\n { id: \"cut\", label: \"Cut scope — this grew beyond appetite\" },\n { id: \"refine\", label: \"Refine — more de-risking needed\" },\n ],\n },\n ],\n outputSchema: {\n field: \"derisking\",\n description: \"Rabbit holes with patches, explicit no-gos\",\n format: \"structured\",\n },\n kbCollection: \"tensions\",\n maxDurationHint: \"10 min\",\n },\n {\n id: \"validation\",\n num: \"05\",\n label: \"Validate & Build Contract\",\n type: \"synthesis\",\n instruction:\n \"Check completeness. Generate the build contract. Review the full scorecard.\",\n facilitatorGuidance:\n \"Review the scorecard from the shaping skill's scoring rubric. Present it as a table. \" +\n \"Verify the 5 core ingredients: Problem, Appetite, Solution elements, Rabbit Holes, No-Gos. \" +\n \"For Big Batch: also verify Architecture, narrative hook, and value-flow annotations. \" +\n \"**System coherence confirmation:** Were all five paths traced for each element? State which interaction risks remain unverified — \" +\n \"these become explicit risks in the work package, not surprises during implementation. \" +\n \"**Vision narrative (TEN-281):** Write one paragraph — how does this work package serve the product vision? \" +\n \"**Test plan (TEN-281):** How will we know this is done? Concrete scenarios, not 'when tests pass.' \" +\n \"**Counter-Metric Mandate (STD-19):** If the scorecard or build contract contains metrics or gates, verify each has a denominator, a coverage rate, \" +\n \"and a counter-metric. Flag any gate that can be satisfied by abstaining or excluding the hard cases. \" +\n \"Present the build contract. Ask: 'Anything to adjust before we capture to the Chain?'\",\n outputSchema: {\n field: \"validation\",\n description: \"Completeness check result and build contract\",\n format: \"structured\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"capture\",\n num: \"06\",\n label: \"Capture & Accept\",\n type: \"close\",\n instruction:\n \"Capture the pitch to the Chain. Accept draft entries. Connect the constellation.\",\n facilitatorGuidance:\n \"List all draft entries created during shaping (elements, risks, decisions, glossary terms). \" +\n \"Ask the user to confirm: 'Ready to accept these onto the Chain?' \" +\n \"Call `session action=commit-constellation` to atomically accept the work package and all linked entries. \" +\n \"Then `relations action=suggest entryId='<betId>'` to discover connections. \" +\n \"Create the top 3 suggested relations via `relations action=batch-create`. \" +\n \"Thank the user. State: what was shaped, how many constellation entries captured, what the implementer inherits.\",\n outputSchema: {\n field: \"capture\",\n description: \"Final capture summary — entries accepted, relations created\",\n format: \"structured\",\n },\n kbCollection: \"work-packages\",\n maxDurationHint: \"5 min\",\n },\n ],\n\n output: {\n primaryRecord: {\n routing: {\n // BET-145 E6 / FEAT-468: shape workflow outputs route to work-packages collection (DEC-245, BET-230 S5).\n mode: \"fixed\",\n collection: \"work-packages\",\n },\n },\n emits: [\n {\n kind: \"entry\",\n collection: \"features\",\n description: \"Solution elements captured during shaping.\",\n },\n {\n kind: \"entry\",\n collection: \"tensions\",\n description: \"Risks and rabbit holes captured during shaping.\",\n },\n {\n kind: \"entry\",\n collection: \"decisions\",\n description: \"Decisions captured inline when they surface.\",\n },\n {\n kind: \"entry\",\n collection: \"glossary\",\n description: \"Glossary terms captured inline when they surface.\",\n },\n {\n kind: \"update\",\n collection: \"work-packages\",\n description: \"Work package status and no-go updates during finalize.\",\n },\n ],\n },\n runtime: {\n kind: \"guided\",\n },\n\n errorRecovery: `If anything goes wrong during shaping:\n\n1. **facilitate tool failure**: Continue the conversation. The shaping knowledge is in the chat. Suggest retrying the tool call or capturing manually later.\n2. **Chain capture failure (duplicate)**: The tool handles duplicates by linking existing entries. If it still fails, note the entry name and move on — capture manually after the session.\n3. **Score seems wrong**: Scoring is local to the shaping skill — re-apply the scoring rubric from the shaping SKILL.md against the conversation context. Scores are heuristic; the agent's judgment matters more than the number.\n4. **User wants to stop mid-session**: Respect it. Everything captured so far is on the Chain as drafts. Use \\`session action=resume\\` to pick up later.\n5. **MCP server unreachable**: Run the shaping from conversation knowledge. Skip chain capture. Say: \"Product Brain is temporarily unavailable — I'll shape from our conversation and we can accept afterward.\"\n\nThe shaping must never fail silently. Always communicate state.`,\n};\n\n// ── Implementation Review Workflow ───────────────────────────────────────────\n//\n// Migration-ready: Same WorkflowDefinition structure as retro/shape.\n// When ChainBuilder/processTemplates Phase B adds facilitator workflows,\n// this becomes a built-in seed — no redesign needed (DEC-83, TEN-68).\n// PRI-5: Workspace-agnostic — uses generic tools (orient, quality, verify,\n// library docs via Context7 CLI) that work for any workspace. Not Product-OS-specific.\n\nconst IMPLEMENTATION_REVIEW_WORKFLOW_DESCRIPTOR: WorkflowDescriptor = {\n id: \"implementation-review\",\n name: \"Implementation Review\",\n shortDescription:\n \"Fix-as-you-go implementation review: finds issues, fixes them immediately, verifies, then proceeds. \" +\n \"Three expert lenses (Staff+ Engineer, CTO, Chain Coherence). Spawns sub-agents for code and test review. \" +\n \"Extracts learnings into standards/rules. Ends with BET/chain IDs. Accepts an insight onto the Chain.\",\n template: {\n slug: \"implementation-review\",\n name: \"Implementation Review\",\n },\n icon: \"✓\",\n facilitatorPreamble: `You are now in **Implementation Review Mode**. You orchestrate a structured review of work that was just built — not a conversation, but a tool-driven audit with sub-agent support.\n\n## Review scope (CRITICAL)\n\n- **Default scope is this conversation only.** Only the work discussed or produced in this conversation is in scope. Do not review or touch files, BETs, or work outside that scope unless the user explicitly expands it (e.g. \"also review the auth module\").\n- **Every file touched must be explicit.** Scope is not complete until you have listed every file that was touched (created, modified, or deleted) in the work under review. Use git status/diff and conversation context to enumerate them. The review then assesses holistic coherence: does this set of changes fit our system, bring us closer to our vision, and make our code and architecture cleaner?\n- **Infer scope first.** Use conversation context, git status/diff, and recent edits to determine which BET, feature, or files are in scope. Call orient/start and \\`context action=gather\\` with the inferred scope; do not ask the user to pick what to review unless it's ambiguous.\n- **Ask only to clarify boundaries.** If scope is ambiguous after inference, ask a single, focused question to clarify (e.g. \"Should this review include only the changes we just made, or the whole feature?\"). Do not ask open-ended \"what should we review?\" or \"which work area?\" unless inference failed.\n- **State scope explicitly in Round 01.** After orient and context gather, state in one sentence what is in scope (e.g. \"Scope: changes in this conversation for BET-72\" or \"Scope: files X, Y and BET-72\"). Confirm only if the user might reasonably expect something else.\n- **Sub-agents and tools are scope-bound.** When spawning sub-agents or calling verify/review-against-rules, restrict attention to the scoped work only. Do not audit or suggest changes to code outside the stated scope.\n\n## Your Behavior\n\n1. **Tool-heavy, not chat-heavy.** Each round calls specific tools: orient, quality, verify, chain-review, context action=gather, review-against-rules. Use Context7 **CLI** (\\`npx ctx7 library\\` then \\`npx ctx7 docs\\` — project-local after \\`npm install\\`; avoid cold \\`npx ctx7@latest\\` in short-timeout shells) for relevant testing and framework docs — not for Chain truth. Do not use Context7 MCP.\n2. **Spawn sub-agents** for parallel review: (a) code/architecture review, (b) test honesty (did we edit tests to pass or do they validate real behavior?). Max 2 agents in parallel, 30s budget each. **Constrain each sub-agent to the stated review scope only.**\n3. **Fix-as-you-go (FEAT-172).** When you find a HIGH or MEDIUM issue: fix it immediately, verify (lints, types), then proceed. The user sees clean work, not a list of issues. Only defer if estimated >5 min — capture deferred items as tensions. If user says \"skip\", capture as tension and continue.\n4. **Chain is SSOT.** Call orient or start first. Use entries action=search and context action=gather to load relevant BETs, DECs, BRs. If findings conflict with Chain entries, report the conflict and cite the entry ID.\n5. **One round at a time.** Complete each round before moving to the next. Checkpoint progress.\n6. **Extract learnings (FEAT-174).** After fixing issues, ask: is this a recurring pattern? Offer to capture structural patterns as standards or business rules so future reviews check automatically.\n7. **CRITICAL: End with BET/chain IDs.** The final output MUST include a single sentence: \"BET/feature IDs reviewed: [IDs]. [One-line summary of findings].\"\n8. **Never go silent.** If a tool fails, explain and continue. The conversation IS the backup.\n\n## Tool Usage\n\n- \\`orient\\` or \\`start\\` — governance, active work packages, stale entries\n- \\`quality action=check entryId=\"<BET-ID>\"\\` — score against collection criteria\n- \\`chain-review action=gate chainEntryId=\"<id>\"\\` — coherence gate for chains\n- \\`quality action=verify-chain\\` — glossary code mappings, cross-references vs codebase\n- \\`review-against-rules\\` (domain) — business rule compliance\n- \\`context action=gather task=\"implementation review for [BET-ID]\"\\` — related knowledge\n- Context7 CLI — \\`npx ctx7 library\\` then \\`npx ctx7 docs\\` for framework/testing docs (not Chain truth); prefer local \\`ctx7\\` from \\`node_modules\\` in this monorepo\n- \\`session action=wrapup-review\\` — before close\n\n## Sub-Agent Classification (for test failures)\n\nWhen reviewing test results: (a) test staleness — code changed, test not updated; (b) regression — code broke behavior; (c) flaky/bad test — harness or timing issue.\n\n## Structured Verdict (CRITICAL)\n\nRound 05 MUST end with a structured verdict block containing exactly these five items:\n1. **Verdict:** Y (ship) or N (do not ship) — one word, no hedging.\n2. **What shipped:** One sentence describing what was built.\n3. **Why it matters:** One sentence on the problem this solves.\n4. **User benefit:** One sentence on the value for users.\n5. **How to validate:** One sentence on how to verify it works as intended.\n\nThis block is the final deliverable of the review. Everything else is supporting evidence.`,\n\n rounds: [\n {\n id: \"orient\",\n num: \"01\",\n label: \"Orient & Scope\",\n type: \"open\",\n instruction:\n \"Apply the Review scope rules: infer scope from this conversation, git diff, and recent edits (default = work in this conversation only). Enumerate every file touched (created, modified, deleted). Call orient or start, then context action=gather for the inferred BET/feature. State scope in one explicit sentence and list all files in scope. Only ask the participant if scope is ambiguous. The review will assess: holistic coherence with our system, whether this brings us closer to our vision, and whether it makes our code and architecture cleaner.\",\n facilitatorGuidance:\n \"Infer scope from conversation context, git status/diff, and recent edits — default is work in this conversation only. \" +\n \"List every file touched (created, modified, or deleted) in the work under review; scope is not complete without this list. \" +\n \"Call orient or start to load governance and active work packages. \" +\n \"Use context action=gather task='implementation review for [inferred-BET-or-feature]' to load related entries. \" +\n \"State scope explicitly in one sentence (e.g. 'Scope: changes in this conversation for BET-72'). \" +\n \"Present: stated scope, the full list of files touched, relevant BETs/DECs/BRs, and any stale entries orient surfaces. \" +\n \"Frame the review: we will assess holistic coherence with our system, whether this brings us closer to our vision, and whether it makes our code and architecture cleaner. \" +\n \"Ask the participant only if scope is ambiguous (e.g. 'Only the files we changed, or the whole feature?'). \" +\n \"Note vision anchors (principles, strategy, active work-package constraints) — you will reference these in Rounds 02–05.\",\n outputSchema: {\n field: \"scope\",\n description: \"Explicit scope statement, every file touched, WP/feature IDs, related Chain context, vision anchors\",\n format: \"structured\",\n },\n maxDurationHint: \"2 min\",\n },\n {\n id: \"standards-review\",\n num: \"02\",\n label: \"Standards & Chain Coherence\",\n type: \"open\",\n instruction:\n \"Run quality check, chain-review gate (if applicable), review-against-rules, and codebase coherence gate. \" +\n \"Is the implementation coherent with the Chain SSOT? Did it introduce or fix registry drift?\",\n facilitatorGuidance:\n \"For the BET/entry: quality action=check entryId='<ID>'. \" +\n \"If the work produced a chain artifact: chain-review action=gate. \" +\n \"Call review-against-rules with the relevant domain (e.g. 'Governance & Decision-Making'). \" +\n \"**Codebase Coherence Gate (BET-99/FEAT-183):** Compare the Codebase Coherence section from Round 01's orient output \" +\n \"against the current state. If orient showed coherence gaps and this implementation touched registry files \" +\n \"(collection colors, routes, classification, renderers, etc.), check whether gaps increased or decreased. \" +\n \"Gaps increased → flag as 'Coherence: WARN — N new gaps introduced' and list them. \" +\n \"Gaps decreased → celebrate as 'Coherence: PASS — N gaps fixed.' \" +\n \"No change → note as 'Coherence: PASS — no change.' \" +\n \"If Round 01 did not show a coherence section, skip the gate — do not block on missing baseline. \" +\n \"Present: quality score, gate result, rule compliance, coherence gate verdict.\",\n outputSchema: {\n field: \"standards\",\n description:\n \"Quality score, gate result, rule compliance, coherence gate verdict (improved/degraded/unchanged)\",\n format: \"structured\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"code-and-tests\",\n num: \"03\",\n label: \"Code & Test Honesty\",\n type: \"open\",\n instruction:\n \"Spawn sub-agents to review implementation and tests for the stated scope only. Fix every HIGH/MEDIUM finding before proceeding. Did we meet high standards? Are tests validating real behavior or did we edit them just to pass?\",\n facilitatorGuidance:\n \"Restrict all review to the scope stated in Round 01 (by default, work in this conversation only). \" +\n \"Spawn 1–2 sub-agents in parallel: (1) explore agent — code review, architecture boundaries, type-safety for scoped files only. \" +\n \"(2) explore agent — test review for scoped code: are tests asserting real behavior or were they edited to pass? \" +\n \"Pass the scope (files/BET) explicitly to sub-agents so they do not touch other work. \" +\n \"Use Context7 CLI (npx ctx7 library/docs) for relevant testing and framework best practices if needed. \" +\n \"Classify any test failures: staleness, regression, or flaky. \" +\n \"**Fix-as-you-go (FEAT-172):** For every HIGH/MEDIUM finding: fix immediately, run lints, verify types. \" +\n \"Only defer fixes estimated >5 min — capture deferred items as tensions on the Chain. \" +\n \"After fixing, do a boy-scout pass on each scoped file: clean imports, improve naming, remove dead code. \" +\n \"**Counter-Metric Mandate (STD-19):** When reporting test coverage, accuracy, or any quantitative result, \" +\n \"include the denominator, what was excluded, and at least one counter-metric. \" +\n \"Never report accuracy without recall. Never report pass rate without coverage. \" +\n \"Synthesize: findings, fixes applied, implementation grade, test honesty verdict.\",\n outputSchema: {\n field: \"codeAndTests\",\n description: \"Implementation grade, test honesty, refactor suggestions\",\n format: \"structured\",\n },\n maxDurationHint: \"10 min\",\n },\n {\n id: \"chain-validation\",\n num: \"04\",\n label: \"Chain Validation & Learning Extraction\",\n type: \"synthesis\",\n instruction:\n \"Run verify. Check orient for stale entries. Is the Chain current with the codebase? \" +\n \"Then extract learnings: did this review surface structural patterns that should become standards or rules?\",\n facilitatorGuidance:\n \"**Chain validation:** Call quality action=verify-chain (report mode) — checks glossary code mappings and cross-references. \" +\n \"Orient surfaces stale entries (per workspace governance). Present trust score and any drift. \" +\n \"If drift found: fix immediately via entries action=update (with changeNote). \" +\n \"**Learning extraction (FEAT-174, TEN-272):** Review all findings from Rounds 02 and 03. \" +\n \"Ask: did this review surface a structural pattern that could recur? \" +\n \"For each pattern: could it be a standard ('We always do X this way'), a business rule ('The system must do X'), \" +\n \"or a lint rule (automated check)? Offer to capture. \" +\n \"Also offer to capture any decisions, tensions, or new terms surfaced during the review. \" +\n \"The goal: today's bug becomes tomorrow's automated check (TEN-272).\",\n outputSchema: {\n field: \"chainValidation\",\n description: \"Verify trust score, drift fixes, extracted learnings (patterns → standards/rules)\",\n format: \"structured\",\n },\n maxDurationHint: \"5 min\",\n },\n {\n id: \"synthesis\",\n num: \"05\",\n label: \"Synthesis & Sign-Off\",\n type: \"commit\",\n instruction:\n \"Synthesize the review. Answer: Does this bring us closer to our vision and make our code and architecture cleaner? \" +\n \"With fix-as-you-go, most issues are already resolved — summarize what was fixed, not what's left. End with BET/chain IDs.\",\n facilitatorGuidance:\n \"Present the full synthesis: standards pass/fail, code grade, test honesty, chain validation, fixes applied. \" +\n \"**Vision delta:** Cite specific principles/strategy entries from Round 01. Answer: does this bring us closer to [cited vision]? \" +\n \"**Counter-Metric Mandate (STD-19):** For EVERY quantitative result you present, you MUST include: \" +\n \"(1) the denominator — what is the total population measured, (2) the coverage/abstention rate — what was excluded, \" +\n \"(3) at least one counter-metric that tells the opposite story (recall vs precision, error rate vs success rate), \" +\n \"(4) the 'student exam' reframe — score on the full exam, not just questions answered. \" +\n \"**Red-team your own synthesis:** Before presenting, ask yourself: 'What's the worst honest interpretation of these numbers? \" +\n \"What metric looks good but hides a real problem? What would a skeptic challenge?' Present that alongside the headline. \" +\n \"Recommend: ship, ship with conditions, or do not ship. \" +\n \"CRITICAL: The output MUST end with one sentence: 'BET/feature IDs reviewed: [IDs]. [One-line summary].' \" +\n \"Example: 'BET-xxx, STD-xxx reviewed. Conditional ship — fix [specific issues] and add [missing tests].' \" +\n \"**Structured Verdict Block (REQUIRED):** After the full synthesis, present the verdict block with exactly 5 items: \" +\n \"(1) Verdict: Y or N — one word. (2) What shipped: one sentence. (3) Why it matters: one sentence on the problem solved. \" +\n \"(4) User benefit: one sentence on value for users. (5) How to validate: one sentence on verification. \" +\n \"This block is the final deliverable. Everything else is supporting evidence.\",\n outputSchema: {\n field: \"synthesis\",\n description: \"Full review synthesis with vision delta, fixes applied, WP/chain IDs, and structured verdict block\",\n format: \"structured\",\n },\n maxDurationHint: \"3 min\",\n },\n {\n id: \"capture\",\n num: \"06\",\n label: \"Capture & Close\",\n type: \"close\",\n instruction:\n \"Finalize the review as an insight draft. Connect new entries from learning extraction. Use session action=wrapup-review. Thank the participant.\",\n facilitatorGuidance:\n \"Summarize the review for finalization. Complete the terminal round through \\`workflows action=checkpoint\\` with \\`isFinal=true\\` so the workflow substrate creates the draft insight record. \" +\n \"Include: BET/feature IDs, verdict, key findings, fixes applied, and the structured verdict block from Round 05. \" +\n \"The insight description MUST include the 5-item verdict block (verdict Y/N, what shipped, why it matters, user benefit, how to validate). \" +\n \"If learnings were captured in Round 04: run relations action=suggest for each new entry, then relations action=batch-create. \" +\n \"Run session action=wrapup-review before closing. \" +\n \"Thank the participant. State what was fixed, what was captured, what was deferred.\",\n outputSchema: {\n field: \"capture\",\n description: \"Insight entry created, WP IDs referenced, learnings connected\",\n format: \"structured\",\n },\n kbCollection: \"insights\",\n maxDurationHint: \"3 min\",\n },\n ],\n\n output: {\n primaryRecord: {\n routing: {\n mode: \"fixed\",\n collection: \"insights\",\n },\n },\n summaryCapture: {\n createsPrimaryRecord: true,\n nameTemplate: \"Implementation Review — {date}\",\n descriptionField: \"description\",\n descriptionSource: {\n mode: \"step-output-field\",\n field: \"synthesis\",\n },\n },\n },\n runtime: {\n kind: \"guided\",\n },\n\n errorRecovery: `If anything goes wrong during implementation review:\n\n1. **Tool failure**: Explain what failed. Continue with what you have. The conversation is the record.\n2. **Sub-agent timeout**: Proceed without that agent's output. Note what wasn't checked.\n3. **Context7 CLI unavailable** (e.g. auth/network): Skip library doc validation. Rely on Chain and codebase review.\n4. **MCP unreachable**: Run from conversation knowledge. Summarize findings. Offer to capture manually later.\n\nThe review must never fail silently. Always end with BET/chain IDs.`,\n};\n\n// ── Process Change Workflow ──────────────────────────────────────────────────\n//\n// BET-84: The lightweight everyday workflow for work that isn't shaping.\n// Bug fixes, change requests, improvements, prerequisite tasks.\n// Captures why/who/when without a full shaping ceremony.\n//\n// Migration-ready: Same WorkflowDefinition structure (DEC-83 Phase A).\n// PRI-5: Workspace-agnostic — uses only generic tools (orient, capture,\n// checkpoint). No workspace-specific logic or entry IDs.\n// DEC-149: No facilitate dependency — generic tools only.\n\nconst PROCESS_CHANGE_WORKFLOW_DESCRIPTOR: WorkflowDescriptor = {\n id: \"process-change\",\n name: \"Process a Change\",\n shortDescription:\n \"Lightweight workflow for everyday changes — bug fixes, improvements, change requests. \" +\n \"Captures what changed, why, and what's affected without a full shaping ceremony. \" +\n \"Routes output to the right collection via the classifier.\",\n template: {\n slug: \"process-change\",\n name: \"Process a Change\",\n },\n icon: \"↻\",\n facilitatorPreamble: `You are now in **Change Processing Mode**. You are a lightweight facilitator helping the user capture the context around a change they're making or just made — a bug fix, improvement, change request, or prerequisite task.\n\n## Your Behavior\n\n1. **Be fast.** This is a 5-minute workflow, not a 45-minute ceremony. Respect the user's flow state.\n2. **Orient first.** Call orient to load workspace context — but present only what's relevant to the change, not the full briefing.\n3. **Capture the why.** The single most important thing: why is this change happening? The what is usually obvious from the code. The why is what evaporates.\n4. **Link to what exists.** Search the Chain for related entries. If this change was triggered by a tension, work package, or decision — link it. If it creates a new decision or surfaces a new tension — capture that too.\n5. **Finalize through the workflow substrate.** Complete the terminal round with \\`workflows action=checkpoint ... isFinal=true\\`. The substrate will classifier-route the primary record and attach it to the durable run.\n6. **Don't over-process.** If the user gives you everything in one message, move quickly through the required checkpoints in order, then finalize. Not every round needs a conversation.\n7. **End with the link.** Always finish by connecting the new entry to related Chain knowledge via graph suggest.\n\n## Tool Usage\n\n- \\`orient\\` — load workspace context (governance, active work packages, stale entries)\n- \\`entries action=search\\` — find related entries\n- \\`capture\\` — manual fallback only if workflow finalization cannot safely route the entry\n- \\`relations action=suggest\\` — discover connections\n- \\`relations action=create\\` or \\`relations action=batch-create\\` — link to related entries\n- \\`entries action=commit\\` — promote to SSOT (only on user confirmation)\n- \\`workflows action=checkpoint\\` — save progress if needed\n\n## Communication Style\n\n- **Conversational, not ceremonial.** No round headers needed unless the user wants structure.\n- **One question at a time.** Ask what you need, checkpoint, move on.\n- **If the user gives rich context upfront**, checkpoint the answered rounds in order, then finalize and link. Don't ask questions they already answered.\n- **Show what you captured.** Always confirm what went to the Chain before closing.`,\n\n rounds: [\n {\n id: \"orient\",\n num: \"01\",\n label: \"Quick Context\",\n type: \"open\",\n instruction:\n \"What are you working on? Orient to load relevant Chain context.\",\n facilitatorGuidance:\n \"Call orient to get workspace context. Ask what the user is changing — or infer from their initial message. \" +\n \"Search the Chain for related entries: entries action=search with keywords from their description. \" +\n \"Present only the 2-3 most relevant entries, not a full briefing. If the user already described the change, skip the question and confirm what you understood.\",\n outputSchema: {\n field: \"context\",\n description: \"What's being changed and relevant Chain context\",\n format: \"structured\",\n },\n maxDurationHint: \"1 min\",\n },\n {\n id: \"what-and-why\",\n num: \"02\",\n label: \"What & Why\",\n type: \"open\",\n instruction:\n \"What's changing and why? What triggered this — a bug, a request, an observation?\",\n facilitatorGuidance:\n \"This is the core capture moment. Get two things: (1) what changed or will change, (2) why — the trigger, the reasoning, the context that will evaporate. \" +\n \"If the user's initial message already contains both, reflect it back for confirmation rather than re-asking. \" +\n \"Classify the change type mentally: bug fix → tension, decision made → decision, new capability → feature, lesson learned → insight. \" +\n \"The classifier will handle routing, but understanding the type helps you ask the right follow-up.\",\n outputSchema: {\n field: \"whatAndWhy\",\n description: \"The change and its rationale\",\n format: \"freetext\",\n },\n maxDurationHint: \"2 min\",\n },\n {\n id: \"impact-and-links\",\n num: \"03\",\n label: \"Impact & Links\",\n type: \"synthesis\",\n instruction:\n \"What's affected? Are there existing Chain entries that relate to this change?\",\n facilitatorGuidance:\n \"Search the Chain for entries that should be linked: entries action=search with keywords from the change. \" +\n \"Check: does this change affect an active work package? Does it resolve a known tension? Does it supersede an existing decision? \" +\n \"If the change is small and self-contained, this round can be brief — just confirm there's nothing obvious to link. \" +\n \"If there are stale entries that this change invalidates, flag them for reconfirmation.\",\n outputSchema: {\n field: \"impact\",\n description: \"Affected entries and proposed links\",\n format: \"structured\",\n },\n maxDurationHint: \"1 min\",\n },\n {\n id: \"capture-and-close\",\n num: \"04\",\n label: \"Capture & Close\",\n type: \"close\",\n instruction:\n \"Capture to the Chain. Link to related entries. Confirm with the user.\",\n facilitatorGuidance:\n \"Finalize through workflows action=checkpoint with isFinal=true, passing a summaryName when you have a clean title. \" +\n \"The workflow substrate will create the primary record as a draft and attach it to the durable run. \" +\n \"After finalization, call relations action=suggest to find connections. Create the top 2-3 relevant relations. \" +\n \"Show the user what was captured: entry ID, collection it landed in, relations created. \" +\n \"Ask if they want to accept now or leave as draft. If they confirm, use entries action=commit. \" +\n \"If there are stale entries to reconfirm, mention them. \" +\n \"Thank the user briefly and exit — don't linger.\",\n outputSchema: {\n field: \"capture\",\n description: \"Entry captured, relations created, accept status\",\n format: \"structured\",\n },\n maxDurationHint: \"1 min\",\n },\n ],\n\n output: {\n primaryRecord: {\n routing: {\n mode: \"classifier\",\n },\n },\n summaryCapture: {\n createsPrimaryRecord: true,\n nameTemplate: \"{whatAndWhy}\",\n descriptionSource: {\n mode: \"step-output-field\",\n field: \"whatAndWhy\",\n },\n },\n },\n runtime: {\n kind: \"guided\",\n },\n\n errorRecovery: `If anything goes wrong during change processing:\n\n1. **Tool failure**: Explain briefly. Capture in the conversation. Offer to retry or accept manually later.\n2. **Classifier misroutes**: Use entries action=move to move the entry to the correct collection. Mention this to the user.\n3. **No related entries found**: That's fine — not every change connects to existing knowledge. Capture it standalone.\n4. **MCP unreachable**: Note the change in conversation. Offer to capture when PB is back.\n\nNever block the user's real work. This workflow serves the work — it doesn't replace it.`,\n};\n\n// ── Workflow Registry ───────────────────────────────────────────────────────\n\nconst WORKFLOW_DESCRIPTORS = new Map<string, WorkflowDescriptor>([\n [\"retro\", RETRO_WORKFLOW_DESCRIPTOR],\n [\"shape\", SHAPE_WORKFLOW_DESCRIPTOR],\n [\"implementation-review\", IMPLEMENTATION_REVIEW_WORKFLOW_DESCRIPTOR],\n [\"process-change\", PROCESS_CHANGE_WORKFLOW_DESCRIPTOR],\n]);\n\nconst WORKFLOWS = new Map<string, WorkflowDefinition>(\n Array.from(WORKFLOW_DESCRIPTORS.entries(), ([id, descriptor]) => [\n id,\n compileWorkflowDefinition(descriptor),\n ]),\n);\n\nexport function getWorkflow(id: string): WorkflowDefinition | undefined {\n const workflow = WORKFLOWS.get(id);\n return workflow ? cloneWorkflowDefinition(workflow) : undefined;\n}\n\nexport function listWorkflows(): WorkflowDefinition[] {\n return Array.from(WORKFLOWS.values(), (workflow) =>\n cloneWorkflowDefinition(workflow),\n );\n}\n\nexport function getWorkflowDescriptor(id: string): WorkflowDescriptor | undefined {\n const descriptor = WORKFLOW_DESCRIPTORS.get(id);\n return descriptor ? cloneWorkflowDescriptor(descriptor) : undefined;\n}\n\nexport function listWorkflowDescriptors(): WorkflowDescriptor[] {\n return Array.from(WORKFLOW_DESCRIPTORS.values(), (descriptor) =>\n cloneWorkflowDescriptor(descriptor),\n );\n}\n\nexport function getWorkflowIds(): string[] {\n return Array.from(WORKFLOWS.keys());\n}\n","/**\n * Synced from convex/chain/workflowRun.ts (TEN-174: MCP separate build, cannot\n * import Convex code — the prior header cited convex/lib/workflowRun.ts, a path\n * that no longer exists; fixed in WP-480 S4, FEAT-1361).\n *\n * Drift guard: scripts/check-mcp-lib-drift.mjs compares every declaration shared\n * with the canonical file after normalizing the two legitimate per-surface seams\n * (mcpGatewayClientError ↔ workflowClientError; './' ↔ '../lib/' import paths).\n * Canonical-only declarations are limited to an explicit allowlist (the TEN-678\n * helper extractions — coerceWorkflowRunOutput / parseListOutput /\n * findClosestRoundId / levenshteinDistance); this surface deliberately keeps its\n * own interactive variants in tools/workflows.ts (different coercion semantics:\n * numbered-list parsing + whole-string fallback). A new canonical declaration\n * outside that allowlist fails the check until a human dispositions it.\n */\n\nimport {\n\tunknownWorkflowRoundMessage,\n\tworkflowMustDefineStepMessage,\n\tworkflowOutputFormatMismatchMessage,\n\tworkflowRunNoActiveRoundMessage,\n\tworkflowRunNotActiveMessage,\n\tworkflowRunRoundMismatchMessage,\n\tworkflowRunRoundNotActiveMessage,\n} from './mcpGatewayClientMessages';\nimport { mcpGatewayClientError } from './errors';\n\n/**\n * BET-85 Slice 2 — canonical workflow run domain model.\n *\n * Pure domain state for workflow execution. Persistence belongs in Convex\n * feature modules; MCP and UI consumers should adapt to this model rather than\n * inventing parallel run contracts.\n */\n\nexport type WorkflowRoundType =\n | \"open\"\n | \"choice\"\n | \"synthesis\"\n | \"commit\"\n | \"close\";\n\nexport type WorkflowOutputFormat =\n | \"freetext\"\n | \"list\"\n | \"choice\"\n | \"structured\";\n\ntype JsonPrimitive = string | number | boolean | null;\nexport type JsonValue =\n | JsonPrimitive\n | JsonValue[]\n | { [key: string]: JsonValue };\n\nexport type WorkflowRunOutput =\n | { format: \"freetext\"; value: string }\n | { format: \"list\"; value: string[] }\n | { format: \"choice\"; value: string | string[] }\n | { format: \"structured\"; value: JsonValue };\n\nexport type WorkflowRunStatus = \"active\" | \"completed\";\nexport type WorkflowRunStepStatus = \"pending\" | \"active\" | \"completed\";\n\nexport interface WorkflowRunStepDefinition {\n roundId: string;\n num: string;\n label: string;\n type: WorkflowRoundType;\n outputField: string;\n outputFormat: WorkflowOutputFormat;\n}\n\nexport interface WorkflowRunCheckpoint {\n roundId: string;\n output: WorkflowRunOutput;\n recordedAt: string;\n}\n\nexport interface WorkflowRunStepState extends WorkflowRunStepDefinition {\n status: WorkflowRunStepStatus;\n output?: WorkflowRunOutput;\n lastCheckpointAt?: string;\n}\n\nexport interface WorkflowRunState {\n runSchemaVersion: 1;\n workflowId: string;\n workflowName: string;\n templateSlug: string;\n templateName: string;\n status: WorkflowRunStatus;\n startedAt: string;\n completedAt?: string;\n currentRoundId: string | null;\n steps: WorkflowRunStepState[];\n checkpoints: WorkflowRunCheckpoint[];\n}\n\n// BET-85 + STA-3: one shared mapping from persisted workflow run docs to the\n// canonical run-state contract used by tools, queries, and future UI surfaces.\nexport interface PersistedWorkflowRunRecord {\n runSchemaVersion: number;\n workflowId: string;\n workflowName: string;\n templateSlug?: string;\n templateName?: string;\n status: WorkflowRunStatus;\n startedAt: string;\n completedAt?: string;\n currentRoundId?: string;\n steps: WorkflowRunState[\"steps\"];\n checkpoints: WorkflowRunState[\"checkpoints\"];\n}\n\nexport interface WorkflowRunRenderProjection {\n workflowId: string;\n workflowName: string;\n templateSlug: string;\n templateName: string;\n status: WorkflowRunStatus;\n currentRoundId: string | null;\n completedCount: number;\n totalCount: number;\n steps: Array<{\n roundId: string;\n num: string;\n label: string;\n type: WorkflowRoundType;\n status: WorkflowRunStepStatus;\n outputField: string;\n outputFormat: WorkflowOutputFormat;\n output?: WorkflowRunOutput;\n }>;\n render: {\n title: string;\n subtitle: string;\n template: {\n slug: string;\n name: string;\n stratum: \"system\";\n stageMode: \"fixed\";\n stages: Array<{\n id: string;\n fieldKey: string;\n label: string;\n prompt: string;\n color?: string;\n }>;\n outputFormats: Array<{\n id: string;\n label: string;\n }>;\n audiencePresets: Array<{\n id: string;\n label: string;\n }>;\n };\n links: Record<string, string>;\n sections: Array<{\n key: string;\n fieldKey: string;\n label: string;\n color: string;\n content: string;\n status: WorkflowRunStepStatus;\n roundId: string;\n roundNum: string;\n roundType: WorkflowRoundType;\n outputFormat: WorkflowOutputFormat;\n output?: WorkflowRunOutput;\n }>;\n };\n}\n\nexport function createWorkflowRunState(args: {\n workflowId: string;\n workflowName: string;\n templateSlug?: string;\n templateName?: string;\n steps: WorkflowRunStepDefinition[];\n startedAt?: string;\n}): WorkflowRunState {\n if (args.steps.length === 0) {\n throw mcpGatewayClientError(workflowMustDefineStepMessage(args.workflowId));\n }\n\n return {\n runSchemaVersion: 1,\n workflowId: args.workflowId,\n workflowName: args.workflowName,\n templateSlug: args.templateSlug ?? args.workflowId,\n templateName: args.templateName ?? args.workflowName,\n status: \"active\",\n startedAt: args.startedAt ?? new Date().toISOString(),\n currentRoundId: args.steps[0]?.roundId ?? null,\n steps: args.steps.map((step, index) => ({\n ...step,\n status: index === 0 ? \"active\" : \"pending\",\n })),\n checkpoints: [],\n };\n}\n\nexport function applyWorkflowCheckpoint(\n run: WorkflowRunState,\n checkpoint: WorkflowRunCheckpoint,\n): WorkflowRunState {\n if (run.status !== \"active\") {\n throw mcpGatewayClientError(workflowRunNotActiveMessage(run.workflowId));\n }\n\n if (!run.currentRoundId) {\n throw mcpGatewayClientError(workflowRunNoActiveRoundMessage(run.workflowId));\n }\n\n if (checkpoint.roundId !== run.currentRoundId) {\n throw mcpGatewayClientError(\n workflowRunRoundMismatchMessage(\n run.workflowId,\n run.currentRoundId,\n checkpoint.roundId,\n ),\n );\n }\n\n const stepIndex = run.steps.findIndex((step) => step.roundId === checkpoint.roundId);\n if (stepIndex === -1) {\n throw mcpGatewayClientError(unknownWorkflowRoundMessage(checkpoint.roundId));\n }\n\n const step = run.steps[stepIndex];\n if (step.status !== \"active\") {\n throw mcpGatewayClientError(\n workflowRunRoundNotActiveMessage(run.workflowId, checkpoint.roundId),\n );\n }\n\n validateWorkflowRunOutput(step.outputFormat, checkpoint.output);\n\n const isLastStep = stepIndex === run.steps.length - 1;\n const willCompleteRun = isLastStep;\n\n const updatedSteps = run.steps.map((currentStep, index) => {\n if (index === stepIndex) {\n return {\n ...currentStep,\n status: \"completed\" as const,\n output: checkpoint.output,\n lastCheckpointAt: checkpoint.recordedAt,\n };\n }\n\n if (index === stepIndex + 1 && !willCompleteRun) {\n return {\n ...currentStep,\n status: \"active\" as const,\n };\n }\n\n return currentStep;\n });\n\n return {\n ...run,\n status: willCompleteRun ? \"completed\" : \"active\",\n completedAt: willCompleteRun ? checkpoint.recordedAt : run.completedAt,\n currentRoundId: willCompleteRun ? null : updatedSteps[stepIndex + 1]?.roundId ?? null,\n steps: updatedSteps,\n checkpoints: [...run.checkpoints, checkpoint],\n };\n}\n\nexport function replayWorkflowRunState(args: {\n workflowId: string;\n workflowName: string;\n templateSlug?: string;\n templateName?: string;\n steps: WorkflowRunStepDefinition[];\n checkpoints: WorkflowRunCheckpoint[];\n startedAt?: string;\n}): WorkflowRunState {\n let run = createWorkflowRunState({\n workflowId: args.workflowId,\n workflowName: args.workflowName,\n templateSlug: args.templateSlug,\n templateName: args.templateName,\n steps: args.steps,\n startedAt: args.startedAt,\n });\n\n for (const checkpoint of args.checkpoints) {\n run = applyWorkflowCheckpoint(run, checkpoint);\n }\n\n return run;\n}\n\nexport function buildWorkflowRunRenderProjection(\n run: WorkflowRunState,\n): WorkflowRunRenderProjection {\n const completedCount = run.steps.filter((step) => step.status === \"completed\").length;\n const renderSections = run.steps.map((step) => {\n const content = step.output ? workflowRunOutputToText(step.output) : \"\";\n\n return {\n key: step.roundId,\n fieldKey: step.outputField,\n label: step.label,\n color: getWorkflowRunStepColor(step.type),\n content,\n status: step.status,\n roundId: step.roundId,\n roundNum: step.num,\n roundType: step.type,\n outputFormat: step.outputFormat,\n output: step.output,\n };\n });\n const renderLinks = Object.fromEntries(\n renderSections\n .filter((section) => section.content.length > 0)\n .map((section) => [section.key, section.content]),\n );\n const subtitle =\n run.status === \"completed\"\n ? `${completedCount}/${run.steps.length} rounds completed`\n : `${completedCount}/${run.steps.length} rounds completed · current ${run.currentRoundId ?? \"none\"}`;\n\n return {\n workflowId: run.workflowId,\n workflowName: run.workflowName,\n templateSlug: run.templateSlug,\n templateName: run.templateName,\n status: run.status,\n currentRoundId: run.currentRoundId,\n completedCount,\n totalCount: run.steps.length,\n steps: run.steps.map((step) => ({\n roundId: step.roundId,\n num: step.num,\n label: step.label,\n type: step.type,\n status: step.status,\n outputField: step.outputField,\n outputFormat: step.outputFormat,\n output: step.output,\n })),\n render: {\n title: run.workflowName,\n subtitle,\n template: {\n slug: run.templateSlug,\n name: run.templateName,\n stratum: \"system\",\n stageMode: \"fixed\",\n stages: run.steps.map((step) => ({\n id: step.roundId,\n fieldKey: step.outputField,\n label: step.label,\n prompt: `Round ${step.num}: ${step.label}`,\n color: getWorkflowRunStepColor(step.type),\n })),\n outputFormats: [\n {\n id: \"workflow-run\",\n label: \"Workflow Run\",\n },\n ],\n audiencePresets: [],\n },\n links: renderLinks,\n sections: renderSections,\n },\n };\n}\n\nexport function toWorkflowRunState(\n run: PersistedWorkflowRunRecord,\n): WorkflowRunState {\n return {\n runSchemaVersion: run.runSchemaVersion as 1,\n workflowId: run.workflowId,\n workflowName: run.workflowName,\n templateSlug: run.templateSlug ?? run.workflowId,\n templateName: run.templateName ?? run.workflowName,\n status: run.status,\n startedAt: run.startedAt,\n completedAt: run.completedAt,\n currentRoundId: run.currentRoundId ?? null,\n steps: run.steps,\n checkpoints: run.checkpoints,\n };\n}\n\nexport function workflowRunOutputToText(output: WorkflowRunOutput): string {\n switch (output.format) {\n case \"freetext\":\n return output.value;\n case \"list\":\n return output.value.join(\", \");\n case \"choice\":\n return Array.isArray(output.value) ? output.value.join(\", \") : output.value;\n case \"structured\":\n if (output.value && typeof output.value === \"object\" && \"text\" in output.value) {\n const textValue = (output.value as { text?: unknown }).text;\n if (typeof textValue === \"string\") {\n return textValue;\n }\n }\n return JSON.stringify(output.value);\n }\n}\n\nexport function workflowRunOutputsEqual(\n left: WorkflowRunOutput,\n right: WorkflowRunOutput,\n): boolean {\n if (left.format !== right.format) {\n return false;\n }\n\n return stableSerializeJsonValue(left.value) === stableSerializeJsonValue(right.value);\n}\n\nfunction validateWorkflowRunOutput(\n expectedFormat: WorkflowOutputFormat,\n output: WorkflowRunOutput,\n): void {\n if (output.format !== expectedFormat) {\n throw mcpGatewayClientError(\n workflowOutputFormatMismatchMessage(expectedFormat, output.format),\n );\n }\n\n switch (output.format) {\n case \"freetext\":\n if (typeof output.value !== \"string\") {\n throw mcpGatewayClientError(\"Freetext workflow output must be a string.\");\n }\n return;\n case \"list\":\n if (!Array.isArray(output.value) || output.value.some((item) => typeof item !== \"string\")) {\n throw mcpGatewayClientError(\"List workflow output must be a string array.\");\n }\n return;\n case \"choice\":\n if (\n typeof output.value !== \"string\" &&\n (!Array.isArray(output.value) ||\n output.value.some((item) => typeof item !== \"string\"))\n ) {\n throw mcpGatewayClientError(\"Choice workflow output must be a string or string array.\");\n }\n return;\n case \"structured\":\n if (!isJsonValue(output.value)) {\n throw mcpGatewayClientError(\"Structured workflow output must be JSON-serializable.\");\n }\n return;\n }\n}\n\nfunction getWorkflowRunStepColor(type: WorkflowRoundType): string {\n switch (type) {\n case \"open\":\n return \"var(--link-problem)\";\n case \"choice\":\n return \"var(--link-choice)\";\n case \"synthesis\":\n return \"var(--link-insight)\";\n case \"commit\":\n return \"var(--link-action)\";\n case \"close\":\n return \"var(--link-outcome)\";\n }\n}\n\nfunction stableSerializeJsonValue(value: JsonValue): string {\n if (value === null || typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return JSON.stringify(value);\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableSerializeJsonValue(item)).join(\",\")}]`;\n }\n\n const entries = Object.entries(value).sort(([leftKey], [rightKey]) =>\n leftKey.localeCompare(rightKey),\n );\n\n return `{${entries\n .map(([key, entryValue]) =>\n `${JSON.stringify(key)}:${stableSerializeJsonValue(entryValue)}`,\n )\n .join(\",\")}}`;\n}\n\nfunction isJsonValue(value: unknown): value is JsonValue {\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return value.every((item) => isJsonValue(item));\n }\n\n if (typeof value === \"object\") {\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n return false;\n }\n\n return Object.values(value as Record<string, unknown>).every((item) =>\n isJsonValue(item),\n );\n }\n\n return false;\n}\n","/**\n * Quality compound tool — check, re-evaluate.\n * Consolidates quality-check and re-evaluate into one tool.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { thinWrapper, success, successResult, failureResult, parseOrFail, type ToolResult } from \"../envelope.js\";\nimport { kernelQuery, kernelMutation, getWorkspaceContext, requireWriteAccess, runWithToolContext } from \"../client.js\";\nimport { trackQualityCheck, trackQualityVerdict } from \"../analytics.js\";\nimport { formatRubricVerdictSection } from \"./smart-capture.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { handleVerifyChain } from \"./verify.js\";\nimport { handleAuditRun } from \"./audit.js\";\nimport { handleSpineCheck } from \"./spine-check.js\";\n\n// WP-484 S2 (§3): `quality` absorbs `verify` → verify-chain and `audit` →\n// audit. Legacy `verify`/`audit` tools stay registered alongside (§7\n// \"alongside\" mechanic) — both call the SAME handleVerifyChain/handleAuditRun\n// functions, one business-logic path.\nconst QUALITY_ACTIONS = [\"check\", \"re-evaluate\", \"verify-chain\", \"audit\", \"spine-check\"] as const;\ntype QualityAction = (typeof QUALITY_ACTIONS)[number];\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const qualitySchema = z.object({\n action: z.enum(QUALITY_ACTIONS).describe(\n \"'check': read the entry's server quality verdict (tier + criteria). 're-evaluate': trigger fresh evaluation. \" +\n \"'verify-chain': verify entries against the codebase (codeMapping drift, cross-references) — absorbs `verify`. \" +\n \"'audit': hygiene audit for a work package entry — absorbs `audit`. \" +\n \"'spine-check': structural completeness of the purpose+vision+strategy spine — story:true also runs the on-demand one-story judgment.\",\n ),\n entryId: z.string().max(200).optional().describe(\"For 'check'/'re-evaluate'/'audit': entry ID, e.g. 'TEN-graph-db', '<PREFIX>-<n>'.\"),\n context: z.enum([\"capture\", \"commit\", \"review\"]).default(\"review\").optional()\n .describe(\"For re-evaluate: evaluation context\"),\n collection: z.string().max(200).optional().describe(\"For 'verify-chain': collection slug to verify (default: glossary).\"),\n mode: z.enum([\"report\", \"fix\"]).optional().describe(\"For 'verify-chain': 'report' = read-only trust report (default). 'fix' = also update drifted codeMapping statuses.\"),\n phase: z.enum([\"shaping\", \"handoff\"]).optional().describe(\n \"For 'audit': 'shaping' checks shaping-phase fields only (default). 'handoff' checks all required fields including buildContract/buildSequence/exclusions/risks.\",\n ),\n story: z.boolean().optional().describe(\"For 'spine-check': also run the on-demand one-story LLM judgment (never scheduled; result labelled [unvalidated]).\"),\n refresh: z.boolean().optional().describe(\n \"For 'spine-check': force a new run even if a fresh verdict already exists. Default false — a plain call \" +\n \"NEVER re-triggers work just to read the last result; it auto-schedules only when no run is already in \" +\n \"flight AND the stored verdict is absent/stale/missing the requested story pass.\",\n ),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion.\nconst qualityCheckVariant = z.object({ action: z.literal(\"check\"), entryId: z.string().max(200) });\nconst qualityReEvaluateVariant = z.object({\n action: z.literal(\"re-evaluate\"),\n entryId: z.string().max(200),\n context: z.enum([\"capture\", \"commit\", \"review\"]).optional().default(\"review\"),\n});\nconst qualityVerifyChainVariant = z.object({\n action: z.literal(\"verify-chain\"),\n collection: z.string().max(200).optional().default(\"glossary\"),\n mode: z.enum([\"report\", \"fix\"]).optional().default(\"report\"),\n});\nconst qualityAuditVariant = z.object({\n action: z.literal(\"audit\"),\n entryId: z.string().max(200),\n phase: z.enum([\"shaping\", \"handoff\"]).optional().default(\"shaping\"),\n});\nconst qualitySpineCheckVariant = z.object({\n action: z.literal(\"spine-check\"),\n story: z.boolean().optional().default(false),\n refresh: z.boolean().optional().default(false),\n});\n\nexport const qualityActionUnion = z.discriminatedUnion(\"action\", [\n qualityCheckVariant,\n qualityReEvaluateVariant,\n qualityVerifyChainVariant,\n qualityAuditVariant,\n qualitySpineCheckVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const QUALITY_ACTION_SPECS: Record<QualityAction, ActionParamSpec> = {\n check: { params: [\"entryId\"], description: \"entryId is required.\" },\n \"re-evaluate\": { params: [\"entryId\", \"context\"], description: \"entryId is required.\" },\n \"verify-chain\": { params: [\"collection\", \"mode\"], description: \"All params optional; collection defaults to 'glossary'.\" },\n audit: { params: [\"entryId\", \"phase\"], description: \"entryId is required.\" },\n \"spine-check\": { params: [\"story\", \"refresh\"], description: \"All params optional; story and refresh default to false — a plain call never re-triggers work, it just reads back the latest verdict (auto-refreshing only when stale/absent).\" },\n};\n\n// WP-480 S1 (FEAT-1358): `check` reads the SERVER rubric verdict, not a client\n// scorecard — `score`/`maxScore` drop in favour of the verdict tier + criteria.\nexport const qualityCheckOutputSchema = z.object({\n entryId: z.string(),\n /** WP-480 S1: false = the ID does not resolve to an entry (typo/deleted) — distinct from \"no verdict yet\". */\n entryFound: z.boolean().optional(),\n hasVerdict: z.boolean(),\n /** WP-480 S1: the verdict was judged against content the entry no longer has — re-evaluate for a current one. */\n stale: z.boolean().optional(),\n tier: z.string().optional(),\n passed: z.boolean().optional(),\n criteria: z.array(z.object({\n id: z.string(),\n passed: z.boolean(),\n hint: z.string().optional(),\n })),\n});\n\nexport const qualityReevaluateOutputSchema = z.object({\n entryId: z.string(),\n context: z.string(),\n score: z.number(),\n maxScore: z.number(),\n improved: z.boolean(),\n});\n\nexport const qualitySpineCheckOutputSchema = z.object({\n hasVerdict: z.boolean(),\n noSpineEntries: z.boolean().optional(),\n structuralPassed: z.boolean().optional(),\n storyPassed: z.boolean().nullable().optional(),\n stale: z.boolean().optional(),\n});\n\nexport function registerQualityTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const qualityHandlers: Record<QualityAction, (data: any) => Promise<ToolResult>> = {\n check: (data) => handleCheck(data.entryId),\n \"re-evaluate\": (data) => handleReEvaluate(data.entryId, data.context ?? \"review\"),\n \"verify-chain\": (data) => handleVerifyChain(server, { collection: data.collection ?? \"glossary\", mode: data.mode ?? \"report\" }),\n audit: (data) => handleAuditRun(data.entryId, data.phase ?? \"shaping\"),\n \"spine-check\": (data) => handleSpineCheck(data.story ?? false, data.refresh ?? false),\n };\n\n server.registerTool(\n \"quality\",\n {\n title: \"Quality\",\n description:\n \"Assess, re-evaluate, and verify entry/work package quality. Five actions:\\n\\n\" +\n \"- **check**: Read the entry's server quality verdict (tier + criteria) — it does not re-score. \" +\n \"Suggests links when the entry has no relations.\\n\" +\n \"- **re-evaluate**: Trigger a fresh quality evaluation. Returns heuristic verdict immediately, \" +\n \"schedules LLM evaluation in background.\\n\" +\n \"- **verify-chain**: Verify knowledge entries against the actual codebase (codeMapping drift, \" +\n \"cross-references) — absorbs `verify`. Produces a trust report with a trust score.\\n\" +\n \"- **audit**: Run hygiene audit on a work package entry (13/18 gates) — absorbs `audit`.\\n\" +\n \"- **spine-check**: Structural completeness of the purpose+vision+strategy spine — duplicate \" +\n \"singletons, connectedness, per-strategy refusal heuristic; story:true also runs the on-demand \" +\n \"one-story LLM judgment (never scheduled, result labelled [unvalidated]). Async: a plain call reads \" +\n \"back the latest stored verdict and auto-schedules a new run ONLY when none is already in flight AND \" +\n \"the stored one is absent/stale/missing the requested story pass — repeated polling never re-triggers \" +\n \"work. Pass refresh:true to force a fresh run regardless.\",\n inputSchema: qualitySchema,\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(qualitySchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"quality\", action }, () =>\n dispatchDiscriminated(\"quality\", qualityActionUnion, parsed.data, QUALITY_ACTION_SPECS, qualityHandlers),\n );\n }),\n );\n}\n\n/**\n * Link-suggestion block — fires when the entry has zero relations. Runs for ANY\n * existing entry, INDEPENDENT of whether a verdict exists: `check`'s contract\n * promises \"suggests links when the entry has no relations\", and a missing/expired\n * verdict is exactly when an entry is most likely to be unlinked. (The deleted\n * client scorer ran this independently too; gating it behind a verdict silently\n * dropped the capability.)\n */\nasync function appendLinkSuggestions(entryId: string, lines: string[]): Promise<void> {\n let relationCount = -1;\n try {\n const relations = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntryRelations\">>(\"chain.listEntryRelations\", { entryId });\n relationCount = relations?.length ?? 0;\n } catch {\n // Relation count unavailable — skip the link suggestion; the verdict still renders.\n return;\n }\n if (relationCount !== 0) return;\n\n try {\n const suggestions = await kernelQuery<GatewayRouteReturnByName<\"chain.graphSuggestLinks\">>(\"chain.graphSuggestLinks\", {\n entryId,\n maxHops: 2,\n limit: 3,\n });\n\n if ((suggestions?.suggestions?.length ?? 0) > 0) {\n const linkHints = (suggestions.suggestions ?? [])\n .map((s) => ` → \\`relations action=create from=\"${entryId}\" to=\"${s.entryId}\" type=\"${s.recommendedRelationType}\"\\` — ${s.name} [${s.collectionSlug}] (${s.score}/100)`)\n .join(\"\\n\");\n\n lines.push(`\\n## Suggested Links to Improve Quality\\n${linkHints}`);\n }\n } catch {\n // Graph suggestions failed — quality check still works without them\n }\n}\n\nasync function handleCheck(entryId: string) {\n // WP-480 S1 (FEAT-1358, DEC-32 thin wrapper): READ the server verdict and format\n // it. `check` never recomputes quality and holds no write access — only\n // `handleReEvaluate` writes a qualityVerdicts row. The server classifies\n // (entryFound / verdict / stale); this renders that classification verbatim.\n const res = await kernelQuery<GatewayRouteReturnByName<\"quality.getLatestVerdictForEntry\">>(\"quality.getLatestVerdictForEntry\", { entryId });\n\n // The entry itself does not exist — a typo'd or deleted ID. Say so; do NOT send the\n // caller to `re-evaluate`, which cannot succeed and is a dead recovery path.\n if (!res || !res.entryFound) {\n return successResult(\n `# Quality Check: ${entryId}\\n\\nEntry \\`${entryId}\\` not found. Use \\`search\\` to find the right ID.`,\n `Entry ${entryId} not found — search for the correct ID.`,\n { entryId, entryFound: false, hasVerdict: false, criteria: [] as Array<{ id: string; passed: boolean; hint?: string }> },\n [{ tool: \"search\", description: \"Find the entry\", parameters: { query: entryId } }],\n );\n }\n\n const verdict = res.verdict;\n\n // Entry exists but has no verdict row (never evaluated, or the row expired) — stay\n // READ-ONLY and name the re-evaluate action. Do NOT silently trigger evaluation.\n // Link suggestions still run: they never depended on a verdict.\n if (!verdict) {\n const lines: string[] = [\n `# Quality Check: ${entryId}`,\n \"\",\n `No quality verdict yet for \\`${entryId}\\`. Run \\`quality action=re-evaluate entryId=\"${entryId}\"\\` to evaluate it.`,\n ];\n await appendLinkSuggestions(entryId, lines);\n return successResult(\n lines.join(\"\\n\"),\n `No quality verdict yet for ${entryId} — re-evaluate to produce one.`,\n { entryId, entryFound: true, hasVerdict: false, criteria: [] as Array<{ id: string; passed: boolean; hint?: string }> },\n [{ tool: \"quality\", description: \"Evaluate now\", parameters: { action: \"re-evaluate\", entryId } }],\n );\n }\n\n // `verdict.criteria`'s nested type resolves to `any[]` (a documented nested-any residual\n // class, same shape as the other `chain.*` entry-data cases — routeContract.test.ts's own\n // PROVISIONAL note on nested holes not caught by its top-level-only detector). Annotated\n // here to the fields this file actually reads (PR #395, Lane C S3b annotation pass).\n const criteria: Array<{ id: string; passed: boolean; hint?: string }> = verdict.criteria ?? [];\n const lines: string[] = [`# Quality Check: ${entryId}`, \"\"];\n // A verdict judged against content the entry no longer has is stale — label it as\n // such rather than presenting a pre-edit pass/fail as the entry's current quality.\n if (res.stale) {\n lines.push(\n `> STALE — this verdict was judged against an earlier version of \\`${entryId}\\`, which has been edited since. ` +\n `Run \\`quality action=re-evaluate entryId=\"${entryId}\"\\` for a current verdict.`,\n \"\",\n );\n }\n const verdictSection = formatRubricVerdictSection(verdict);\n lines.push(verdictSection || `Verdict tier \\`${verdict.tier ?? \"unknown\"}\\` for \\`${entryId}\\` — no rubric criteria to report.`);\n\n await appendLinkSuggestions(entryId, lines);\n\n try {\n const wsForTracking = await getWorkspaceContext();\n trackQualityCheck(wsForTracking.workspaceId, {\n entry_id: entryId,\n entry_type: verdict.canonicalKey ?? \"\",\n tier: verdict.tier ?? \"\",\n passed: verdict.passed ?? false,\n source: verdict.source ?? \"\",\n llm_status: verdict.llmStatus,\n llm_duration_ms: verdict.llmDurationMs,\n llm_error: verdict.llmError,\n has_roger_martin: !!verdict.rogerMartin,\n });\n } catch { /* tracking is advisory */ }\n\n const passedCount = criteria.filter((c) => c.passed).length;\n return successResult(\n lines.join(\"\\n\"),\n `Quality check for ${entryId}: ${verdict.tier ?? \"unknown\"} tier, ${passedCount}/${criteria.length} criteria pass.` +\n (res.stale ? \" STALE — the entry was edited after this verdict; re-evaluate for a current one.\" : \"\"),\n {\n entryId,\n entryFound: true,\n hasVerdict: true,\n stale: res.stale ?? false,\n tier: verdict.tier,\n passed: verdict.passed,\n criteria: criteria.map((c) => ({ id: c.id, passed: c.passed, hint: c.hint })),\n },\n [\n { tool: \"relations\", description: \"Suggest connections\", parameters: { action: \"suggest\", entryId } },\n ],\n );\n}\n\nasync function handleReEvaluate(entryId: string, context: \"capture\" | \"commit\" | \"review\") {\n requireWriteAccess();\n const ws = await getWorkspaceContext();\n const result = await kernelMutation<GatewayRouteReturnByName<\"quality.reEvaluateEntry\">>(\"quality.reEvaluateEntry\", {\n entryId,\n context,\n });\n\n if (!result) {\n return failureResult(\n `Entry '${entryId}' not found or has no rubric.`,\n \"NOT_FOUND\",\n `Entry '${entryId}' not found or has no rubric.`,\n \"Use entries action=search to find the correct ID.\",\n [{ tool: \"entries\", description: \"Search entries\", parameters: { action: \"search\", query: entryId } }],\n );\n }\n\n const llmScheduled = result.verdict.tier !== \"passive\";\n const lines: string[] = [`Re-evaluated \\`${entryId}\\` in \\`${context}\\` context.`];\n lines.push(\"\");\n lines.push(formatRubricVerdictSection({\n ...result.verdict,\n source: result.source,\n llmStatus: llmScheduled ? \"pending\" : \"skipped\",\n }));\n\n try {\n trackQualityVerdict(ws.workspaceId, {\n entry_id: entryId,\n entry_type: result.verdict.canonicalKey ?? \"\",\n tier: result.verdict.tier ?? \"\",\n context,\n passed: result.verdict.passed ?? false,\n source: \"heuristic\",\n criteria_total: result.verdict.criteria?.length ?? 0,\n criteria_failed: result.verdict.criteria?.filter((c) => !c.passed).length ?? 0,\n llm_scheduled: llmScheduled,\n methodology_version: result.verdict.methodologyVersion,\n });\n } catch { /* tracking is advisory */ }\n\n const criteria = result.verdict.criteria ?? [];\n const reEvalScore = criteria.filter((c) => c.passed).length;\n const reEvalMaxScore = criteria.length;\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Re-evaluated ${entryId} in ${context} context. Score: ${reEvalScore}/${reEvalMaxScore}.`,\n {\n entryId,\n context,\n score: reEvalScore,\n maxScore: reEvalMaxScore,\n improved: result.verdict.passed ?? false,\n },\n ),\n };\n}\n","/**\n * Audit tool — pb audit <BET-ID> as an MCP tool.\n *\n * BET-182 Slice 1: MCP tool wrapper around the auditBet Convex query.\n * Thin client — all gate logic lives in convex/agentKnowledge/audit.ts.\n *\n * Chain: BET-182, STD-113, STD-65 (structured output)\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery } from \"../client.js\";\nimport { success, failureResult } from \"../envelope.js\";\nimport { replaceVocabTokens, type WorkspaceVocabCtx } from \"../lib/canonicalRefs.js\";\nimport { getRequestApiKey } from \"../auth.js\";\n\n// ─── Vocab cache (WP-438 Slice 2) ────────────────────────────────────────────\n// Mirrors the 5-min TTL pattern from packages/cli/src/lib/workspaceVocabCache.ts.\n// Keyed by API key (stdio: env-derived single key; http: per-request bearer)\n// so multi-tenant MCP servers don't cross-contaminate vocab between workspaces.\n// Fail-open: if a fetch raises we cache nothing and the next call retries.\n// Bounded with MAX_VOCAB_KEYS + LRU/oldest-eviction to keep long-lived HTTP\n// MCP servers from leaking Map entries (mirrors auth.ts keyStateMap pattern).\nconst VOCAB_TTL_MS = 5 * 60 * 1000;\nconst MAX_VOCAB_KEYS = 100;\ninterface VocabCacheEntry {\n ctx: WorkspaceVocabCtx | undefined;\n expiresAt: number;\n}\nconst vocabCache = new Map<string, VocabCacheEntry>();\nfunction getCachedVocab(key: string): WorkspaceVocabCtx | undefined | \"miss\" {\n const entry = vocabCache.get(key);\n if (!entry) return \"miss\";\n if (Date.now() >= entry.expiresAt) {\n vocabCache.delete(key);\n return \"miss\";\n }\n return entry.ctx;\n}\nfunction setCachedVocab(key: string, ctx: WorkspaceVocabCtx | undefined): void {\n vocabCache.set(key, { ctx, expiresAt: Date.now() + VOCAB_TTL_MS });\n evictVocabIfFull();\n}\nfunction evictVocabIfFull(): void {\n if (vocabCache.size <= MAX_VOCAB_KEYS) return;\n // Drop expired entries first (sweep).\n const now = Date.now();\n for (const [k, v] of vocabCache) {\n if (now >= v.expiresAt) vocabCache.delete(k);\n }\n // Still over? Drop oldest by expiresAt (proxy for insertion order under fixed TTL).\n if (vocabCache.size > MAX_VOCAB_KEYS) {\n const sorted = [...vocabCache.entries()].sort((a, b) => a[1].expiresAt - b[1].expiresAt);\n const excess = vocabCache.size - MAX_VOCAB_KEYS;\n for (let i = 0; i < excess; i++) vocabCache.delete(sorted[i][0]);\n }\n}\n\n// ─── Schema ─────────────────────────────────────────────────────────────────\n\nconst AUDIT_ACTIONS = [\"run\"] as const;\n\nexport const auditSchema = z.object({\n action: z.enum(AUDIT_ACTIONS).describe(\n \"'run': run the hygiene audit for a work package entry.\",\n ),\n entryId: z.string().describe(\"Work package entry ID to audit, e.g. '<PREFIX>-<n>'\"),\n phase: z.enum([\"shaping\", \"handoff\"]).default(\"shaping\").optional()\n .describe(\n \"'shaping': check shaping-phase fields only. 'handoff': check all required fields including buildContract/buildSequence/exclusions/risks. Default: shaping.\",\n ),\n});\n\n// ─── Output types (mirrors AuditOutput from convex/agentKnowledge/audit.ts) ───\n\ninterface GateResult {\n gate: string;\n status: \"pass\" | \"fail\" | \"warn\";\n blocking: boolean;\n detail: string;\n fix?: string;\n fixType?: \"exact\" | \"template\" | \"manual\";\n hint?: string;\n /** WP-438 S1: per-field flags indicating unresolved {{vocab:...}} tokens. */\n tokens?: {\n detail: boolean;\n fix: boolean;\n hint: boolean;\n };\n}\n\ninterface AuditResult {\n entryId: string;\n entryName: string;\n phase: string;\n clean: boolean;\n verdict: \"pass\" | \"fail\" | \"warn\";\n gates: GateResult[];\n summary: {\n total: number;\n passed: number;\n failed: number;\n warned: number;\n };\n elapsed_ms: number;\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `audit` tool retired\n// here. handleAuditRun stays live — quality.ts (the `quality` compound,\n// action=audit) is its only remaining caller.\n\n// ─── Handler ─────────────────────────────────────────────────────────────────\n\nexport async function handleAuditRun(entryId: string, phase: \"shaping\" | \"handoff\") {\n let result: AuditResult;\n\n try {\n result = await kernelQuery<GatewayRouteReturnByName<\"chain.auditBet\">>(\"chain.auditBet\", { entryId, phase });\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n if (msg.includes(\"not found\") || msg.includes(\"NOT_FOUND\")) {\n return failureResult(\n `Entry '${entryId}' not found.`,\n \"NOT_FOUND\",\n `Entry '${entryId}' not found.`,\n \"Use entries action=search to find the correct ID.\",\n [{ tool: \"entries\", description: \"Search entries\", parameters: { action: \"search\", query: entryId } }],\n );\n }\n throw err;\n }\n\n // ── WP-438 S1: resolve {{vocab:...}} tokens before rendering. ──────────────\n // Fetch workspace vocab context (PAT-230, DEC-1021). Fail-open: if the\n // vocab fetch fails the resolver still works — it just falls back to the\n // canonicalKey literal per `getCollectionLabel` Layer 3.\n //\n // WP-438 Slice 2: per-API-key 5-min cache so successive audit calls in the\n // same MCP session skip the chain.getVocabulary round-trip. Mirrors the CLI\n // pattern in packages/cli/src/lib/workspaceVocabCache.ts.\n let vocabCtx: WorkspaceVocabCtx | undefined;\n const cacheKey = getRequestApiKey() ?? \"__stdio_default__\";\n const cached = getCachedVocab(cacheKey);\n if (cached !== \"miss\") {\n vocabCtx = cached;\n } else {\n try {\n type VocabResult = { collectionLabels?: Record<string, unknown>; collectionDefaults?: Record<string, unknown> };\n const vocab = await kernelQuery<GatewayRouteReturnByName<\"chain.getVocabulary\">>(\"chain.getVocabulary\", {});\n if (vocab?.collectionLabels || vocab?.collectionDefaults) {\n vocabCtx = {\n ...(vocab.collectionLabels ? { collectionLabels: vocab.collectionLabels as WorkspaceVocabCtx['collectionLabels'] } : {}),\n ...(vocab.collectionDefaults ? { collectionDefaults: vocab.collectionDefaults as WorkspaceVocabCtx['collectionDefaults'] } : {}),\n };\n }\n setCachedVocab(cacheKey, vocabCtx);\n } catch { /* fail-open — vocab labels are advisory; don't cache failures */ }\n }\n\n // Resolve every gate field flagged with tokens.* === true. The Convex\n // producer only flags strings that contain `{{vocab:`, so this is a cheap\n // per-field pass — fields without tokens are skipped.\n for (const gate of result.gates) {\n if (gate.tokens?.detail) gate.detail = replaceVocabTokens(gate.detail, vocabCtx);\n if (gate.tokens?.fix && gate.fix) gate.fix = replaceVocabTokens(gate.fix, vocabCtx);\n if (gate.tokens?.hint && gate.hint) gate.hint = replaceVocabTokens(gate.hint, vocabCtx);\n }\n\n const { verdict, gates, summary, entryName, elapsed_ms } = result;\n\n // ── Format human-readable text ───────────────────────────────────────────\n const verdictIcon = verdict === \"pass\" ? \"✓\" : verdict === \"fail\" ? \"✗\" : \"⚠\";\n const verdictLabel = verdict.toUpperCase();\n\n const lines: string[] = [\n `## Audit: ${entryId} — ${entryName}`,\n `Phase: ${phase} | Verdict: ${verdictIcon} ${verdictLabel} | ${elapsed_ms}ms`,\n `Gates: ${summary.passed}/${summary.total} passed · ${summary.failed} failed · ${summary.warned} warned`,\n \"\",\n ];\n\n // Group by status for readability\n const failed = gates.filter((g) => g.status === \"fail\");\n const warned = gates.filter((g) => g.status === \"warn\");\n const passed = gates.filter((g) => g.status === \"pass\");\n\n if (failed.length > 0) {\n lines.push(\"### ✗ Failed Gates (blocking)\");\n for (const gate of failed) {\n lines.push(`**${gate.gate}**: ${gate.detail}`);\n if (gate.fix) lines.push(` → Fix: ${gate.fix}`);\n if (gate.hint) lines.push(` → Note: ${gate.hint}`);\n }\n lines.push(\"\");\n }\n\n if (warned.length > 0) {\n lines.push(\"### ⚠ Warnings (non-blocking)\");\n for (const gate of warned) {\n lines.push(`**${gate.gate}**: ${gate.detail}`);\n if (gate.fix) lines.push(` → Fix: ${gate.fix}`);\n if (gate.hint) lines.push(` → Note: ${gate.hint}`);\n }\n lines.push(\"\");\n }\n\n if (passed.length > 0 && verdict === \"pass\") {\n lines.push(\"### ✓ All Gates Passed\");\n for (const gate of passed) {\n lines.push(` ${gate.gate}: ${gate.detail}`);\n }\n } else if (passed.length > 0) {\n lines.push(`### ✓ Passed (${passed.length}): ${passed.map((g) => g.gate).join(\", \")}`);\n }\n\n // Next actions\n const nextActions = [];\n if (verdict !== \"pass\") {\n nextActions.push({\n tool: \"entries\",\n description: \"View full entry details\",\n parameters: { action: \"get\", entryId },\n });\n nextActions.push({\n tool: \"relations\",\n description: \"Manage entry relations\",\n parameters: { action: \"list\", entryId },\n });\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Audit ${entryId} (${phase}): ${verdictLabel} — ${summary.passed}/${summary.total} gates passed.`,\n {\n entryId: result.entryId,\n entryName: result.entryName,\n phase: result.phase,\n clean: result.clean,\n verdict: result.verdict,\n gates: result.gates,\n summary: result.summary,\n elapsed_ms: result.elapsed_ms,\n },\n nextActions.length > 0 ? nextActions : undefined,\n ),\n };\n}\n","/**\n * Spine-check handler — MCP `quality` compound tool, action=spine-check\n * (A2, WP-581/FEAT-1402).\n *\n * Thin client: SCHEDULES the check (review fix, PR #530 P1 — the MCP gateway\n * enforces a 10s request budget; a spine check runs one sequential Roger\n * Martin LLM probe per strategy, each up to 25s, plus an optional one-story\n * pass on top — synchronously awaiting that inside an MCP request guarantees\n * a timeout). `quality.scheduleSpineCheck` returns immediately once the run\n * is queued; this handler then reads back whatever the LATEST persisted row\n * is (store-then-read-back — never the write call's own return value).\n *\n * NOUN-VERB CONTRACT (PR #530 round 2, P1): a poll-style read must never\n * itself re-trigger work — calling `scheduleSpineCheck` unconditionally on\n * every invocation re-scheduled a fresh run every time this tool was called,\n * even to just read the last result (the same \"read that writes\" violation\n * already fixed for direction.list/refresh). `scheduleSpineCheck` now decides\n * for itself whether to schedule (no run in flight AND the stored verdict is\n * stale/absent/missing the requested story pass), and this handler renders\n * strictly from that decision (`scheduled`/`reason`) — never infers \"still\n * running\" from a timestamp comparison the way round 1 did. Pass\n * `refresh:true` to force a new run even when a fresh verdict already exists.\n *\n * The CLI (`pb quality spine-check`, no MCP timeout) keeps calling\n * `quality.spineCheck` (runSpineCheck) directly and synchronously — it never\n * goes through this schedule/status split at all.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelQuery, kernelMutation } from \"../client.js\";\nimport { success } from \"../envelope.js\";\n\nexport async function handleSpineCheck(story: boolean, refresh = false) {\n const scheduleResult = await kernelMutation<GatewayRouteReturnByName<\"quality.scheduleSpineCheck\">>(\n \"quality.scheduleSpineCheck\",\n { includeStory: story, refresh },\n );\n const row = await kernelQuery<GatewayRouteReturnByName<\"quality.getLatestSpineVerdict\">>(\"quality.getLatestSpineVerdict\", {});\n\n // \"Still running\" is ONLY true when THIS call actually scheduled a new run —\n // never inferred from a timestamp (round 1's stillRunning := row.createdAt <\n // triggeredAt raced the very fix this round makes: most calls now schedule\n // nothing at all, so that comparison would be meaningless).\n const stillRunning = scheduleResult.scheduled;\n\n if (!row) {\n const text = stillRunning\n ? \"Spine check started — no prior result exists yet. It runs asynchronously (LLM calls can take 25s+ each); re-run this in a few seconds to read the result.\"\n : \"No spine check has been run yet, and none is currently running. Pass refresh:true to start one.\";\n return {\n content: [{ type: \"text\" as const, text }],\n structuredContent: success(text, { hasVerdict: false, checkStarted: stillRunning }),\n };\n }\n\n const { verdict } = row;\n if (verdict.noSpineEntries) {\n return {\n content: [{ type: \"text\" as const, text: \"No spine entries yet — nothing to check.\" }],\n structuredContent: success(\"No spine entries yet.\", { hasVerdict: true, noSpineEntries: true }),\n };\n }\n\n const lines: string[] = [\"## Spine Check\"];\n if (stillRunning) {\n lines.push(`> A new check was just triggered and is still running asynchronously — the result below is from the PREVIOUS run (${new Date(row.createdAt).toISOString()}). Re-run in a few seconds for the fresh result.`, \"\");\n } else if (scheduleResult.reason === \"already-in-flight\") {\n lines.push(`> A check is already running (started earlier, not by this call) — showing the best available result (${new Date(row.createdAt).toISOString()}). Re-run in a few seconds.`, \"\");\n } else if (row.stale) {\n lines.push(`> STALE — ${row.staleMemberIds.length} member entry(ies) changed since this was computed. Pass refresh:true to recompute.`, \"\");\n }\n\n const s = verdict.structural;\n lines.push(`Structural completeness: ${s.passed ? \"PASS\" : \"FAIL\"}`);\n if (s.missing.length > 0) lines.push(`Missing: ${s.missing.join(\", \")}`);\n if (s.duplicateSingletons.purpose) lines.push(`Duplicate purpose singletons (which is canonical?): ${s.duplicateSingletons.purpose.join(\", \")}`);\n if (s.duplicateSingletons.vision) lines.push(`Duplicate vision singletons (which is canonical?): ${s.duplicateSingletons.vision.join(\", \")}`);\n if (s.unconnectedStrategyIds.length > 0) lines.push(`Unconnected strategies (no informs edge to any vision): ${s.unconnectedStrategyIds.join(\", \")}`);\n // `verdict` is stored as v.any() and never migrated — a row persisted before this\n // PR's fields existed reads back with them undefined. Default rather than crash\n // (live-proof finding, PR #530 round-1 walk): a legacy row that can't disclose\n // truncation is still rendered, just without a disclosure it never recorded.\n if ((s.strategiesWithUnknownConnectivity ?? []).length > 0) {\n lines.push(`Connectivity unknown (relation set truncated — not confirmed disconnected): ${s.strategiesWithUnknownConnectivity.join(\", \")}`);\n }\n if (s.visionConnectedToPurpose === false) lines.push(\"No vision informs any purpose.\");\n if (s.visionPurposeConnectivityTruncated) lines.push(\"Vision→purpose connectivity unknown (relation set truncated).\");\n if (verdict.strategiesTruncated) lines.push(\"Strategy set truncated — not every strategy was graded this pass.\");\n if (verdict.perStrategyEvaluationTruncated) lines.push(\"Per-strategy evaluation stopped on the wall-clock budget — not every fetched strategy was graded this pass.\");\n\n if (verdict.perStrategy.length > 0) {\n lines.push(\"\", `Per-strategy refusal heuristic (${verdict.perStrategy.length}):`);\n for (const p of verdict.perStrategy) {\n const refusal = p.refusal.hasRefusalSignal ? \"names an explicit alternative it declines\" : \"no explicit refusal language detected\";\n // `runSpineCheck` ALWAYS attempts a Roger Martin probe per strategy — a null\n // result here is never \"not requested\", it's timeout/budget-reject/malformed-\n // response. Rendering it as an omission (round-1 gap) reads a failure as a\n // clean pass-through; say so explicitly (PR #530 round 2).\n const rm = p.rogerMartin\n ? `; Roger Martin test: ${p.rogerMartin.isStrategicChoice ? \"genuine strategic choice\" : \"NOT a genuine strategic choice\"}`\n : \"; Roger Martin test: FAILED TO EVALUATE (timeout, budget limit, or malformed response) — not scored\";\n lines.push(`- ${p.entryId}: ${refusal}${rm}`);\n }\n }\n\n if (verdict.story) {\n lines.push(\"\", `One-story judgment [unvalidated, on-demand]: ${verdict.story.passed ? \"PASS\" : \"FAIL\"}`);\n if (!verdict.story.passed && verdict.story.failedCriterion) lines.push(`Failed criterion: ${verdict.story.failedCriterion}`);\n } else if (row.includesStoryPass) {\n // The row that ran the story pass exists, but its story came back null —\n // that means the LLM pass FAILED (timeout/parse error), not \"never requested\".\n // Conflating the two (thread #4) reads a failure as a clean skip.\n //\n // Review fix (D1 residue — \"require refresh when retrying a failed story pass\"): a\n // plain `story:true` re-run does NOT actually retry — scheduleSpineCheck's\n // `satisfiesStory` check treats `includesStoryPass:true` (the pass was ATTEMPTED) as\n // already satisfying the request, regardless of whether it SUCCEEDED, so a bare re-run\n // is a silent no-op here. The message now says explicitly what to pass.\n lines.push(\"\", \"One-story judgment: requested, but the LLM pass did not return a usable result (timeout or parse failure). Pass refresh:true to retry — a plain re-run will not reschedule it.\");\n } else {\n lines.push(\"\", \"One-story judgment: not run this pass — pass story=true to run it.\");\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Spine check: structural ${s.passed ? \"PASS\" : \"FAIL\"}${verdict.story ? `, story ${verdict.story.passed ? \"PASS\" : \"FAIL\"} [unvalidated]` : \"\"}${stillRunning ? \" (new run still in progress — showing previous result)\" : \"\"}.`,\n {\n hasVerdict: true,\n noSpineEntries: false,\n structuralPassed: s.passed,\n storyPassed: verdict.story?.passed ?? null,\n stale: row.stale,\n stillRunning,\n scheduled: scheduleResult.scheduled,\n scheduleReason: scheduleResult.reason,\n },\n ),\n };\n}\n","/**\n * Session compound tool — start, close, status.\n * Consolidates agent-start, agent-close, agent-status into one tool.\n * Chain: PB-TEN-001 (AI starts from zero every session)\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport {\n getWorkspaceContext,\n startAgentSession,\n closeAgentSession,\n getAgentSessionId,\n isSessionOriented,\n kernelCall,\n runWithToolContext,\n} from \"../client.js\";\nimport { runWrapupReview, createWrapupHandler } from \"./wrapup.js\";\nimport { handleResume, handleCommitConstellation, facilitateSchema } from \"./facilitate.js\";\nimport { buildRitualsSurfaceLines, type RitualsSurfacePayload } from \"./orient-rituals.js\";\nimport { thinWrapper, success, failureResult, parseOrFail, type ToolResult } from \"../envelope.js\";\nimport { noticesToNextActions, formatNoticeLines, formatAdoptDiscoveryLine, FEEDBACK_SUBMIT_HINT } from \"../lib/sessionNotices.js\";\nimport { clearSessionGaps } from \"../gap-store.js\";\nimport { trackSessionCaptureRate } from \"../analytics.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\n\n// WP-484 S2 (§3): `session` absorbs `session-wrapup` → wrapup-review/wrapup-commit\n// and `facilitate` → resume/commit-constellation. Legacy tools stay registered\n// alongside (§7 \"alongside\" mechanic) — both call the SAME handler functions\n// (wrapupHandler from wrapup.ts, handleResume/handleCommitConstellation from\n// facilitate.ts), one business-logic path per action.\nconst SESSION_ACTIONS = [\n \"start\", \"close\", \"status\", \"wrapup-review\", \"wrapup-commit\", \"resume\", \"commit-constellation\",\n] as const;\ntype SessionAction = (typeof SESSION_ACTIONS)[number];\n\nconst coherencyAcknowledgementFlatSchema = z.object({\n response: z.string().max(200).describe(\"Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'.\"),\n entryId: z.string().max(200).optional().describe(\"Entry the acknowledgement links to.\"),\n reason: z.string().max(2000).optional().describe(\"Free-text justification, required for a 'diverged' response.\"),\n subjectEntryId: z.string().max(200).optional().describe(\"The refused entry this acknowledgement answers.\"),\n});\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const sessionSchema = z.object({\n action: z.enum(SESSION_ACTIONS).describe(\n \"'start': begin a tracked session. 'close': end the session and record activity. 'status': check current session state. \" +\n \"'wrapup-review': review uncommitted drafts before closing (absorbs session-wrapup action=review). \" +\n \"'wrapup-commit': accept all uncommitted drafts (absorbs session-wrapup action=commit-all). \" +\n \"'resume': load session state from an existing bet entry (absorbs facilitate action=resume). \" +\n \"'commit-constellation': atomically accept a bet and its linked drafts (absorbs facilitate action=commit-constellation).\",\n ),\n betEntryId: z.string().max(200).optional().describe(\"For 'resume'/'commit-constellation': bet entry ID. Required for both.\"),\n operationId: z.string().max(200).optional().describe(\"For 'commit-constellation': optional idempotency key for retries.\"),\n coherencyAcknowledgements: z.array(coherencyAcknowledgementFlatSchema).max(20).optional().describe(\n \"For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode.\",\n ),\n steeringOverrideReason: z.string().max(2000).optional().describe(\n \"For 'commit-constellation': typed override reason (>= 12 chars) to push past a coherency hold instead of acknowledging.\",\n ),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion, reusing existing\n// single-purpose schemas (Code Integrity — facilitateSchema already knows the\n// resume/commit-constellation shape; `.extend()` adds only the discriminant).\nconst sessionStartVariant = z.object({ action: z.literal(\"start\") });\nconst sessionCloseVariant = z.object({ action: z.literal(\"close\") });\nconst sessionStatusVariant = z.object({ action: z.literal(\"status\") });\nconst sessionWrapupReviewVariant = z.object({ action: z.literal(\"wrapup-review\") });\nconst sessionWrapupCommitVariant = z.object({ action: z.literal(\"wrapup-commit\") });\nconst sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z.literal(\"resume\") });\nconst sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z.literal(\"commit-constellation\") });\n\nexport const sessionActionUnion = z.discriminatedUnion(\"action\", [\n sessionStartVariant,\n sessionCloseVariant,\n sessionStatusVariant,\n sessionWrapupReviewVariant,\n sessionWrapupCommitVariant,\n sessionResumeVariant,\n sessionCommitConstellationVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const SESSION_ACTION_SPECS: Record<SessionAction, ActionParamSpec> = {\n start: { params: [], description: \"Begin a tracked session; no params.\" },\n close: { params: [], description: \"End the current session; no params.\" },\n status: { params: [], description: \"Check current session state; no params.\" },\n \"wrapup-review\": { params: [], description: \"Review uncommitted drafts; no params.\" },\n \"wrapup-commit\": { params: [], description: \"Accept all uncommitted drafts; no params.\" },\n resume: { params: [\"betEntryId\"], description: \"betEntryId is required.\" },\n \"commit-constellation\": {\n params: [\"betEntryId\", \"operationId\", \"coherencyAcknowledgements\", \"steeringOverrideReason\"],\n description: \"betEntryId is required; every other field is optional.\",\n },\n};\n\nexport function registerSessionTools(server: McpServer): void {\n // Own review-cache instance (createWrapupHandler factory) — independent of\n // the legacy `session-wrapup` tool's cache; see wrapup.ts's docstring.\n const wrapupHandler = createWrapupHandler();\n\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const sessionHandlers: Record<SessionAction, (data: any) => Promise<ToolResult>> = {\n start: () => handleStart(),\n close: () => handleClose(),\n status: () => handleStatus(),\n \"wrapup-review\": () => wrapupHandler({ action: \"review\" }),\n \"wrapup-commit\": () => wrapupHandler({ action: \"commit-all\" }),\n resume: (data) => handleResume(data),\n \"commit-constellation\": (data) => handleCommitConstellation(data),\n };\n\n server.registerTool(\n \"session\",\n {\n title: \"Session — Lifecycle & Facilitation\",\n description:\n \"Session lifecycle, wrapup review, and work package facilitation.\\n\\n\" +\n \"- **start**: Begin a tracked write session for attribution. **This is the ONLY call that creates a session** — \" +\n \"write tools (capture, entries action=update/commit, relations) require it. `orient action=start` orients an \" +\n \"existing session and loads stage-aware context, but does NOT create one: call `session action=start` first, \" +\n \"then `orient action=start`.\\n\" +\n \"- **close**: End the current session. Records structured data (entries created, modified, relations). \" +\n \"Run `session action=wrapup-review` before closing.\\n\" +\n \"- **status**: Check current session — active or not, oriented, activity counts.\\n\" +\n \"- **wrapup-review**: Review uncommitted drafts with quality scores, suggested links. Run before close.\\n\" +\n \"- **wrapup-commit**: Accept all uncommitted drafts and create suggested links.\\n\" +\n \"- **resume**: Load session state (work package data, constellation, drafts) from an existing work package entry.\\n\" +\n \"- **commit-constellation**: Atomically accept a work package and all its linked draft entries in one call.\",\n inputSchema: sessionSchema,\n // Mixed read/write noun (§3 R3): wrapup-commit/resume/commit-constellation write.\n annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(sessionSchema, args);\n if (!parsed.ok) return parsed.result;\n\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"session\", action }, () =>\n dispatchDiscriminated(\"session\", sessionActionUnion, parsed.data, SESSION_ACTION_SPECS, sessionHandlers),\n );\n }),\n );\n}\n\nasync function handleStart() {\n const result = await startAgentSession();\n\n const lines: string[] = [];\n\n lines.push(\n `Session ${result.sessionId} active. ` +\n `Initiated by ${result.initiatedBy}. ` +\n `Workspace ${result.workspaceName}. ` +\n `Scope: ${result.toolsScope}. ` +\n `Write tools available after orient.`,\n );\n\n // WP-584 S4 (FEAT-1412 / TEN-2971): the legacy plain-text \"Feedback queue: N new...\" line\n // used to render here — skipped by consuming agents (dogfood 2026-08-02). It is now the\n // `feedback-queue` spine notice (until-resolved, standing state), rendered structurally\n // through the SAME `notices` block below every other spine notice already uses. The raw\n // `feedbackQueueNew`/`feedbackOldestNewAt` fields stay on `structuredContent` (S1 contract\n // item 7, published clients) — only the bespoke rendered line is gone.\n lines.push(FEEDBACK_SUBMIT_HINT);\n\n // FEAT-1409 spine core: low-severity notices never take the headline (HARD CONSTRAINT 14) —\n // appended below the session banner, never a top-of-output interrupt.\n const noticeLines = formatNoticeLines(result.notices);\n if (noticeLines.length > 0) {\n lines.push(\"\", \"Notices:\", ...noticeLines);\n }\n\n // WP-638 S4 (§10.3) — the bounded adopt-discovery advisory: silent at zero (the server omits\n // the field entirely rather than sending a \"0\" line).\n const adoptLines = formatAdoptDiscoveryLine(result.adoptDiscoveryHint);\n if (adoptLines.length > 0) {\n lines.push(\"\", ...adoptLines);\n }\n\n const summary = `Session ${result.sessionId} active. Workspace ${result.workspaceName}. Write tools available after orient.`;\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(summary, {\n sessionId: result.sessionId,\n initiatedBy: result.initiatedBy,\n workspaceName: result.workspaceName,\n toolsScope: result.toolsScope,\n feedbackQueueNew: result.feedbackQueueNew,\n feedbackOldestNewAt: result.feedbackOldestNewAt,\n notices: result.notices ?? [],\n adoptDiscoveryHint: result.adoptDiscoveryHint,\n // Finding #16: bare `parameters: {}` lets orient's schema default kick in\n // (action defaults to \"task\", which requires a `task` string) — the suggested\n // next-action call failed validation instead of running. `action: \"start\"` is\n // the guided-setup entrypoint this session just opened write access for.\n // FEAT-1409 spine core: notice next-actions are appended through this SAME existing\n // `next` field (HARD CONSTRAINT 2) — never a parallel action list.\n }, [{ tool: \"orient\", description: \"Orient session\", parameters: { action: \"start\" } }, ...noticesToNextActions(result.notices)]),\n };\n}\n\nasync function handleClose() {\n const sessionId = getAgentSessionId();\n if (!sessionId) {\n return failureResult(\n \"No active agent session to close.\",\n \"SESSION_REQUIRED\",\n \"No active agent session to close.\",\n \"Start a session first.\",\n [{ tool: \"session\", description: \"Start a session\", parameters: { action: \"start\" } }],\n );\n }\n\n const session = await kernelCall<GatewayRouteReturnByName<\"agent.getSession\">>(\"agent.getSession\", {\n sessionId,\n });\n\n let wrapupNudge = \"\";\n if (session && !(session.wrapupCompletedAt as number)) {\n try {\n const { text, data } = await runWrapupReview();\n if (data && data.drafts.length > 0) {\n wrapupNudge = [\n \"## Session Wrapup\",\n \"\",\n text,\n \"\",\n `> **${data.drafts.length} uncommitted draft(s) remain.** ` +\n \"Run `session action=wrapup-commit` before closing next time.\",\n \"\",\n \"---\",\n \"\",\n ].join(\"\\n\");\n }\n } catch {\n // Non-critical — proceed with close even if wrapup review fails\n }\n }\n\n await closeAgentSession();\n clearSessionGaps();\n\n // WP-306 S3: Emit capture rate event for PostHog measurement (STD-155)\n const created = (session?.entriesCreated as string[])?.length ?? 0;\n const modified = (session?.entriesModified as string[])?.length ?? 0;\n const relations = (session?.relationsCreated as number) ?? 0;\n\n const wsCtx = await getWorkspaceContext();\n if (wsCtx) {\n trackSessionCaptureRate(wsCtx.workspaceId, {\n entries_created: created,\n entries_modified: modified,\n relations_created: relations,\n had_captures: created > 0,\n });\n }\n\n const lines: string[] = [\n `Session ${sessionId} closed.`,\n \"\",\n ];\n const gates = (session?.gateFailures as number) ?? 0;\n const warnings = (session?.contradictionWarnings as number) ?? 0;\n\n if (session) {\n lines.push(\n `| Metric | Count |`,\n `|--------|-------|`,\n `| Entries created | ${created} |`,\n `| Entries modified | ${modified} |`,\n `| Relations created | ${relations} |`,\n `| Gate failures | ${gates} |`,\n `| Contradiction warnings | ${warnings} |`,\n );\n }\n\n // WP-582 B2 round 1 (Codex P2 review, PR #532, T10): the same rituals surface orient renders,\n // fetched via the lightweight `chain.getRitualsSurface` route (workspaceId injected from the\n // bearer credential — never passed here). Best-effort: a fetch failure omits the block rather\n // than blocking close or rendering the no-row fallback (that fallback is for a genuine no-row\n // arm, not a read we chose not to attempt) — mirrors the CLI's identical posture\n // (commands/session.ts).\n let rituals: RitualsSurfacePayload | null = null;\n try {\n rituals = await kernelCall<GatewayRouteReturnByName<\"chain.getRitualsSurface\">>(\"chain.getRitualsSurface\", {});\n } catch {\n // Non-critical — the close output simply omits the rituals block.\n }\n if (rituals) lines.push(...buildRitualsSurfaceLines(rituals));\n\n lines.push(\"\", \"Write tools are now blocked. Session data saved for future orientation.\");\n\n const fullResponse = wrapupNudge + lines.join(\"\\n\");\n const summary = `Session ${sessionId} closed. ${created} created, ${modified} modified.`;\n return {\n content: [{ type: \"text\" as const, text: fullResponse }],\n structuredContent: success(summary, {\n sessionId,\n entriesCreated: created,\n entriesModified: modified,\n relationsCreated: relations,\n gateFailures: gates,\n contradictionWarnings: warnings,\n wrapupNudge: wrapupNudge.length > 0,\n // T1's undefined-vs-null distinction applies here too — omit the key entirely when the\n // fetch failed, rather than forcing a null a machine consumer can't distinguish from a\n // genuine no-row arm.\n ...(rituals?.directionLine !== undefined ? { directionLine: rituals.directionLine } : {}),\n ...(rituals?.verdictAskLine !== undefined ? { verdictAskLine: rituals.verdictAskLine } : {}),\n ...(rituals?.spineLine !== undefined ? { spineLine: rituals.spineLine } : {}),\n ...(rituals?.atCapLine !== undefined ? { atCapLine: rituals.atCapLine } : {}), // D1 residue fix (named item c)\n }),\n };\n}\n\nasync function handleStatus() {\n const sessionId = getAgentSessionId();\n if (!sessionId) {\n return failureResult(\n \"No active agent session. Call session action=start to begin.\",\n \"SESSION_REQUIRED\",\n \"No active agent session.\",\n \"Call session action=start to begin.\",\n [{ tool: \"session\", description: \"Start a session\", parameters: { action: \"start\" } }],\n );\n }\n\n const session = await kernelCall<GatewayRouteReturnByName<\"agent.getSession\">>(\"agent.getSession\", {\n sessionId,\n });\n\n if (!session) {\n return failureResult(\n \"Session not found in Convex. Call session action=start to create a new session.\",\n \"NOT_FOUND\",\n \"Session not found in Convex.\",\n \"Call session action=start to create a new session.\",\n [{ tool: \"session\", description: \"Start a session\", parameters: { action: \"start\" } }],\n );\n }\n\n const oriented = isSessionOriented();\n const created = (session.entriesCreated as string[])?.length ?? 0;\n const modified = (session.entriesModified as string[])?.length ?? 0;\n\n const lines = [\n `Session ${sessionId} ${session.status}.`,\n `Initiated by ${session.initiatedBy}.`,\n `Scope: ${session.toolsScope}.`,\n `Oriented: ${oriented ? \"yes\" : \"no\"}.`,\n \"\",\n `| Metric | Value |`,\n `|--------|-------|`,\n `| Entries created | ${created} |`,\n `| Entries modified | ${modified} |`,\n `| Relations created | ${session.relationsCreated ?? 0} |`,\n `| Started | ${new Date(session.startedAt as number).toISOString()} |`,\n `| Expires | ${new Date(session.expiresAt as number).toISOString()} |`,\n ];\n\n const summary = `Session ${sessionId} ${session.status}. ${created} created, ${modified} modified.`;\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(summary, {\n sessionId,\n status: session.status,\n initiatedBy: session.initiatedBy,\n toolsScope: session.toolsScope,\n oriented,\n entriesCreated: created,\n entriesModified: modified,\n relationsCreated: session.relationsCreated ?? 0,\n }),\n };\n}\n","/**\n * Session wrapup tools — the closing ceremony for agent sessions.\n * Chain: GLO-47 (Wrapup), GLO-48 (Draft Harvest), ENT-33 (Session Wrapup Ceremony)\n *\n * session-wrapup: Reviews session drafts, quality coaches, suggests links, offers batch commit.\n * Aliases wrapup/finish were removed — \"Also known as\" is in the description for discoverability.\n *\n * Wrapup must run BEFORE session action=close (BR-8: active session required for writes).\n * Commit-on-confirm: wrapup surfaces drafts but only commits when explicitly asked.\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\"; import { z } from \"zod/v3\"; // WP-660 S2: module-health shrink-only budget, same-line import-combine pattern\nimport { failureResult, successResult } from \"../envelope.js\";\nimport {\n getAgentSessionId,\n getApiKeyScope,\n getWorkspaceContext,\n kernelCall,\n kernelCallEnvelope,\n kernelQuery,\n kernelMutation,\n requireWriteAccess,\n recordSessionActivity,\n} from \"../client.js\";\nimport { trackChainEntryCommitted, trackZeroCaptureAuditFired } from \"../analytics.js\"; import { getTopGaps, getSessionGaps } from \"../gap-store.js\"; // WP-660 S2: module-health shrink-only budget, same-line import-combine pattern\nimport {\n detectTouchedRegistries,\n runCoherenceCheck,\n computeDelta,\n renderCoherenceDelta,\n findPersistentGaps,\n renderPersistentGapOffers,\n type CoherenceSnapshot,\n type CoherenceVerdict,\n type PersistentGap,\n} from \"../lib/coherence/index.js\";\nimport { resolveProjectRoot } from \"../lib/resolve-project-root.js\"; import { composeWrapupView } from \"../lib/compose-wrapup-view.js\"; // WP-660 S2: module-health shrink-only budget, same-line import-combine pattern\n\n/**\n * `agentKnowledge.wrapupEnvelope` is a self-enveloping action — its OWN declared return\n * type is `Envelope<WrapupData | CommitAllData>` (confirmed: `convex/agentKnowledge/\n * wrapup.ts`'s handler signature), and `convex/http.ts`'s action dispatch (WP-321 E2,\n * ~line 1203-1224) passes an already-enveloped action's result through WITHOUT a second\n * outer wrap — the raw HTTP response body literally IS that envelope. `kernelCallEnvelope<T>`\n * extracts `.data` from the (unwrapped) HTTP JSON body and returns `{ok, summary, data: T}`,\n * so the value callers actually receive at `.data` is ONE LEVEL INSIDE the route's own\n * declared return type — the success branch's `data` payload, not the envelope itself.\n * `GatewayRouteReturnByName<Name>` alone therefore over-wraps by one layer for THIS call\n * shape; this extracts the true payload type instead of guessing at a hand-written mirror.\n *\n * Narrowed further to `WrapupData` specifically (not the full `WrapupData | CommitAllData`\n * union the route's server-side handler can also return for a different caller): BOTH of\n * this file's `kernelCallEnvelope(\"agentKnowledge.wrapupEnvelope\", ...)` call sites pass\n * `action: \"review\"` literally (verified: lines below) — this file never sends `\"commit-all\"`\n * to this route at all (its own MCP-level `action === \"commit-all\"` branch commits via\n * individual `chain.commitEntry`/`chain.createEntryRelation(s)` calls instead, not this\n * route) — so `CommitAllData` is structurally impossible at either call site here.\n * `WrapupData` and `CommitAllData` share no clean discriminant field (both risk having a\n * `committed` key, with different types), so narrowing uses `drafts` — present only on\n * `WrapupData` — rather than a discriminant check.\n */\ntype WrapupEnvelopePayload = Extract<\n GatewayRouteReturnByName<\"agentKnowledge.wrapupEnvelope\">,\n { ok: true }\n>[\"data\"];\ntype WrapupEnvelopeData = Extract<WrapupEnvelopePayload, { drafts: unknown }>;\n\ninterface WrapupEntry {\n docId: string;\n entryId: string;\n name: string;\n collection: string;\n status: string;\n canonicalKey: string | null;\n wasCreated: boolean;\n}\n\ninterface WrapupVerdict {\n passed: boolean;\n tier: string;\n // Matches the server's own `WrapupVerdict.weakest: unknown` declaration (convex/\n // agentKnowledge/wrapup.ts) exactly — real construction sites (convex/intelligence/\n // qualityCoaching.ts) confirm the runtime shape genuinely is `{criterion, hint} | null`,\n // but the server's own type is imprecise, so a client-side mirror re-declaring a\n // narrower type would silently diverge again. Cast to the known shape at the one\n // consumption site below instead (PR #395, Lane C S3b annotation pass).\n weakest: unknown;\n source: string;\n}\n\ninterface LinkSuggestion {\n fromEntryId: string;\n toEntryId: string;\n type: string;\n label: string;\n // WP-474 E4-REWIRE: the graphSuggestLinks score (0-100), carried so wrapup-applied\n // auto-suggestions persist confidence instead of dropping it (matches smart-capture).\n confidence?: number;\n}\n\n/** Slim overflow element (TEN-2402) — NAMED beyond the review cap, sans per-entry enrichment. */\ninterface WrapupOverflowEntry {\n entryId: string;\n name: string;\n docId: string;\n}\n\nexport interface WrapupData {\n drafts: WrapupEntry[];\n committed: WrapupEntry[];\n qualityVerdicts: Record<string, WrapupVerdict>;\n connectionCounts: Record<string, number>;\n summary: { created: number; modified: number; uncommitted: number; totalReviewed: number };\n overflow: number;\n /** TEN-2390/2402: still-draft entries beyond the cap (slim shape). Optional: a cross-deploy cache may predate it. */\n overflowDrafts?: WrapupOverflowEntry[];\n /** TEN-2402: committed entries beyond the cap, NAMED. Optional for the same reason. */\n overflowCommitted?: WrapupOverflowEntry[];\n /** TEN-2390: entries past the scan cap, never enumerated (invariant under commit). */\n overflowUnscanned?: number;\n wrapupCompletedAt: number | null;\n closeNudge: string;\n captureAudit: {\n message: string;\n suggestions: Array<{ collectionSlug: string; hint: string }>;\n } | null;\n acceptIndependenceDigest?: { header: string; lines: string[] }; // WP-660 S2 review fix (Codex P1): was a query-side seed with zero consumers\n}\n\ninterface SuggestLinksResult {\n resolvedEntry: { entryId: string; name: string; docId: string };\n suggestions: {\n entryId: string;\n name: string;\n collectionSlug: string;\n score: number;\n recommendedRelationType: string;\n reasoning: string;\n }[];\n}\n\ninterface WrapupReviewResult {\n text: string;\n data: WrapupData | null;\n suggestions: LinkSuggestion[];\n /** Set on early exits so the caller doesn't need to derive codes from text. */\n failureCode?: string;\n /** BET-89: number of knowledge gaps detected this session. */\n gapCount?: number;\n /** FEAT-184: coherence verdict when registry files were touched. */\n coherenceVerdict?: CoherenceVerdict;\n /** BET-101: persistent gaps eligible for Chain capture as tensions. */\n persistentGaps?: PersistentGap[];\n /** WP-321: kernel envelope fields surfaced for thin passthrough. */\n kernelSummary?: string;\n kernelNext?: import(\"../envelope.js\").NextAction[];\n kernelMeta?: { durationMs?: number };\n}\n\n// ─── Concurrency helper ──────────────────────────────────────────────────────\n\nasync function mapWithConcurrency<T, U>(\n items: T[],\n mapper: (item: T) => Promise<U>,\n concurrency = 3,\n): Promise<PromiseSettledResult<U>[]> {\n const results: PromiseSettledResult<U>[] = new Array(items.length);\n let index = 0;\n\n async function runNext(): Promise<void> {\n while (index < items.length) {\n const i = index++;\n try {\n const value = await mapper(items[i]);\n results[i] = { status: \"fulfilled\", value };\n } catch (reason) {\n results[i] = { status: \"rejected\", reason };\n }\n }\n }\n\n await Promise.all(\n Array.from({ length: Math.min(concurrency, items.length) }, () => runNext()),\n );\n return results;\n}\n\n// ─── Coherence snapshot retrieval (FEAT-184) ────────────────────────────────\n\ninterface SessionResponse {\n status: string;\n oriented: boolean;\n coherenceSnapshot?: {\n checkedAt: unknown;\n totalGaps: unknown;\n topGaps: unknown;\n };\n}\n\nfunction isValidTopGap(g: unknown): g is { registry: string; slug: string; severity: string } {\n if (typeof g !== \"object\" || g === null) return false;\n const obj = g as Record<string, unknown>;\n return (\n typeof obj.registry === \"string\" &&\n typeof obj.slug === \"string\" &&\n typeof obj.severity === \"string\" &&\n (obj.severity === \"error\" || obj.severity === \"warning\" || obj.severity === \"info\")\n );\n}\n\nasync function fetchSessionCoherenceSnapshot(\n sessionId: string,\n): Promise<CoherenceSnapshot | null> {\n try {\n const session = await kernelCall<GatewayRouteReturnByName<\"agent.getSession\">>(\"agent.getSession\", {\n sessionId,\n });\n const raw = session?.coherenceSnapshot;\n if (\n raw &&\n typeof raw.checkedAt === \"number\" &&\n typeof raw.totalGaps === \"number\" &&\n Array.isArray(raw.topGaps) &&\n raw.topGaps.every(isValidTopGap)\n ) {\n return raw as unknown as CoherenceSnapshot;\n }\n } catch (err) {\n if (process.env.DEBUG_COHERENCE) {\n console.debug(\"[coherence] Snapshot fetch failed:\", err instanceof Error ? err.message : err);\n }\n }\n return null;\n}\n\n// ─── Suggest links with concurrency ──────────────────────────────────────────\n\nasync function suggestLinksForEntries(entries: WrapupEntry[]): Promise<LinkSuggestion[]> {\n const suggestions: LinkSuggestion[] = [];\n\n const results = await mapWithConcurrency(\n entries,\n async (entry) => {\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.graphSuggestLinks\">>(\"chain.graphSuggestLinks\", {\n entryId: entry.entryId,\n limit: 3,\n });\n return { entry, suggestions: result.suggestions ?? [] };\n },\n 3,\n );\n\n for (const result of results) {\n if (result.status !== \"fulfilled\") continue;\n const { entry, suggestions: entrySuggestions } = result.value;\n // `entryId` is optional at the schema level (convex/schema.ts entries table) — a\n // suggestion candidate with no assigned human-readable ID isn't a usable link target,\n // so it's filtered out here rather than cast past (PR #395, Lane C S3b annotation pass).\n for (const s of entrySuggestions.filter((x): x is typeof x & { entryId: string } => x.entryId != null).slice(0, 2)) {\n suggestions.push({\n fromEntryId: entry.entryId,\n toEntryId: s.entryId,\n type: s.recommendedRelationType,\n label: `${entry.entryId} → ${s.entryId} (${s.name}) [${s.recommendedRelationType}]`,\n // WP-474 E4-REWIRE: carry the suggestion score forward (was dropped here).\n confidence: s.score,\n });\n }\n }\n\n return suggestions;\n}\n\n// ─── Core review logic ───────────────────────────────────────────────────────\n\nasync function runWrapupReview(): Promise<WrapupReviewResult> {\n const sessionId = getAgentSessionId();\n if (!sessionId) {\n return { text: \"No active agent session. Call `session action=start` first.\", data: null, suggestions: [], failureCode: \"SESSION_REQUIRED\" };\n }\n\n if (getApiKeyScope() === \"read\") {\n return { text: \"Read-only session — nothing to review.\", data: null, suggestions: [], failureCode: \"READONLY_SCOPE\" };\n }\n\n const { workspaceId } = await getWorkspaceContext();\n // WP-321 E3: delegate to kernel action; auth injected server-side via injectSessionAuth in http.ts\n const kernelEnvelope = await kernelCallEnvelope<WrapupEnvelopeData>(\"agentKnowledge.wrapupEnvelope\", {\n workspaceId,\n sessionId,\n action: \"review\",\n });\n const data = kernelEnvelope.data;\n\n // TEN-2400: the ALREADY_COMPLETED short-circuit must be conditioned on the loop being\n // EMPTY, not merely on `wrapupCompletedAt` being set. A failed/partial batch (or drafts\n // captured after a clean wrapup) can leave `wrapupCompletedAt` set while drafts remain —\n // firing here would blind the surface forever. Loop-empty = no capped drafts, no overflow\n // drafts, nothing unscanned. (Distinct from the empty-session guard below.)\n const overflowDraftCount = (data.overflowDrafts ?? []).length;\n const overflowUnscanned = data.overflowUnscanned ?? 0;\n const loopEmpty = data.drafts.length === 0 && overflowDraftCount === 0 && overflowUnscanned === 0;\n if (data.wrapupCompletedAt && loopEmpty) {\n return { text: \"Wrapup already completed this session.\", data, suggestions: [], failureCode: \"ALREADY_COMPLETED\" };\n }\n\n if (\n data.drafts.length === 0 &&\n data.committed.length === 0 &&\n overflowDraftCount === 0 &&\n (data.overflowCommitted ?? []).length === 0\n ) {\n return { text: \"Empty session — no entries to review.\", data, suggestions: [], failureCode: \"NOT_FOUND\" };\n }\n\n const lines: string[] = [];\n\n lines.push(\n `**Session activity:** ${data.summary.created} created, ${data.summary.modified} modified, ` +\n `${data.summary.uncommitted} uncommitted drafts.`,\n );\n // TEN-2390: the truncation line is for entries the server could NOT enumerate at all\n // (past the scan cap) — NOT `overflow` (which now includes entries we DO name in the\n // beyond-cap group below). Using `overflow` would double-report named overflow entries.\n if (overflowUnscanned > 0) {\n lines.push(`_...and ${overflowUnscanned} more entr${overflowUnscanned === 1 ? \"y\" : \"ies\"} this session could not be enumerated (past the scan cap)._`);\n }\n lines.push(\"\");\n\n if (data.drafts.length > 0) {\n lines.push(\"### Uncommitted Drafts\", \"\");\n lines.push(\"| Entry | Collection | Quality | Connections | Coaching |\");\n lines.push(\"|-------|------------|---------|-------------|----------|\");\n\n for (const draft of data.drafts) {\n const verdict = data.qualityVerdicts[draft.entryId];\n const conns = data.connectionCounts[draft.entryId] ?? 0;\n const qualityStr = verdict\n ? `${verdict.passed ? \"Pass\" : \"Needs work\"} (${verdict.source})`\n : \"—\";\n // `weakest` is `unknown` server-side (imprecise type, real shape confirmed via\n // convex/intelligence/qualityCoaching.ts's construction sites); cast at use.\n const weakest = verdict?.weakest as { criterion: string; hint: string } | null | undefined;\n const coaching = weakest ? weakest.hint : \"—\";\n\n lines.push(`| \\`${draft.entryId}\\` ${draft.name} | ${draft.collection} | ${qualityStr} | ${conns} | ${coaching} |`);\n }\n lines.push(\"\");\n }\n\n if (data.committed.length > 0) {\n lines.push(`### Already Committed (${data.committed.length})`, \"\");\n for (const entry of data.committed) {\n const conns = data.connectionCounts[entry.entryId] ?? 0;\n lines.push(`- \\`${entry.entryId}\\` [${entry.collection}] ${entry.name} (${conns} connections)`);\n }\n lines.push(\"\");\n }\n\n // TEN-2402: entries beyond the review cap are NAMED here by `entryId — name` (the slim\n // shape carries no collection/quality enrichment — that is the cap window's job). Both\n // committed and still-draft overflow are listed so no entry past 15 is a bare count.\n const overflowDrafts = data.overflowDrafts ?? [];\n const overflowCommitted = data.overflowCommitted ?? [];\n if (overflowDrafts.length > 0 || overflowCommitted.length > 0) {\n lines.push(`### Beyond Review Cap (${overflowDrafts.length + overflowCommitted.length})`, \"\");\n lines.push(\"_Past the per-session enrichment cap — listed by id and name only._\", \"\");\n for (const e of overflowCommitted) {\n lines.push(`- \\`${e.entryId}\\` — ${e.name} (committed)`);\n }\n for (const e of overflowDrafts) {\n lines.push(`- \\`${e.entryId}\\` — ${e.name} (draft)`);\n }\n lines.push(\"\");\n }\n\n // Suggest links for low-connection entries (bounded concurrency)\n const lowConnEntries = [...data.drafts, ...data.committed].filter(\n (e) => (data.connectionCounts[e.entryId] ?? 0) < 2,\n );\n\n const suggestions = lowConnEntries.length > 0\n ? await suggestLinksForEntries(lowConnEntries.slice(0, 10))\n : [];\n\n if (suggestions.length > 0) {\n lines.push(\"### Suggested Links\", \"\");\n for (const s of suggestions) {\n lines.push(`- ${s.label}`);\n }\n lines.push(\"\");\n }\n\n const topGaps = getTopGaps(5);\n if (topGaps.length > 0) {\n lines.push(\"### Learning Opportunities\", \"\");\n lines.push(`This session, agents looked for ${topGaps.length} topic${topGaps.length === 1 ? \"\" : \"s\"} not yet on the Chain:`, \"\");\n for (const gap of topGaps) {\n const freq = gap.count > 1 ? ` _(${gap.count}x)_` : \"\";\n lines.push(`- **${gap.query}** — not yet captured${freq}`);\n }\n lines.push(\"\");\n lines.push(\"_Capturing these will make future sessions more effective._\");\n lines.push(\"\");\n }\n\n // ── FEAT-184 + BET-101: Coherence delta + persistent gap offers ─────────\n let coherenceVerdict: CoherenceVerdict | undefined;\n let persistentGaps: PersistentGap[] | undefined;\n try {\n const projectRoot = resolveProjectRoot();\n if (projectRoot) {\n const touchedFiles = detectTouchedRegistries(projectRoot);\n const sessionSnapshot = await fetchSessionCoherenceSnapshot(sessionId);\n const shouldCheck = touchedFiles.size > 0 || sessionSnapshot !== null;\n\n if (shouldCheck) {\n const outcome = await runCoherenceCheck(projectRoot);\n\n if (outcome.status === \"skipped\") {\n // TEN-2781 Design: VISIBLE fail-open — never a silent pass. The gateway was\n // unreachable, so drift was NOT evaluated this session; say so explicitly\n // rather than silently omitting the section. PR #405 review (Codex P2):\n // outcome.reason carries the CONCRETE failure (network error, or the\n // gateway's own code+message) instead of a one-size-fits-all message.\n lines.push(\"### Coherence Check\");\n lines.push(`_Coherence check skipped — gateway unreachable. Registry drift not evaluated this session. (Reason: ${outcome.reason})_`);\n lines.push(\"\");\n } else if (outcome.status === \"ok\") {\n const { report, snapshot: afterSnapshot } = outcome;\n\n if (sessionSnapshot) {\n const delta = computeDelta(sessionSnapshot, afterSnapshot);\n coherenceVerdict = delta.verdict;\n const deltaLines = renderCoherenceDelta(delta);\n lines.push(...deltaLines);\n\n if (touchedFiles.size > 0) {\n lines.push(\n `_This session touched ${touchedFiles.size} registry file${touchedFiles.size === 1 ? \"\" : \"s\"}: ` +\n `${[...touchedFiles].slice(0, 3).map((f) => `\\`${f}\\``).join(\", \")}` +\n `${touchedFiles.size > 3 ? ` and ${touchedFiles.size - 3} more` : \"\"}._`,\n );\n lines.push(\"\");\n }\n\n // BET-101: offer to capture persistent gaps as Chain tensions\n persistentGaps = findPersistentGaps(delta, report.violations);\n if (persistentGaps.length > 0) {\n lines.push(...renderPersistentGapOffers(persistentGaps));\n }\n } else if (touchedFiles.size > 0) {\n lines.push(\"### Coherence Check\");\n lines.push(\n `This session touched ${touchedFiles.size} registry file${touchedFiles.size === 1 ? \"\" : \"s\"} ` +\n `but no session-start snapshot exists — showing absolute state.`,\n );\n const { summary } = report;\n if (summary.total === 0) {\n lines.push(\"All registries aligned — no gaps.\");\n } else {\n lines.push(`**${summary.total} gap${summary.total === 1 ? \"\" : \"s\"}**: ${summary.errors} error${summary.errors === 1 ? \"\" : \"s\"}, ${summary.warnings} warning${summary.warnings === 1 ? \"\" : \"s\"}, ${summary.infos} info.`);\n }\n lines.push(\"\");\n }\n }\n // outcome.status === \"no-data\": too few registries resolved locally — nothing\n // to check, no section rendered (unchanged pre-Lane-D behavior).\n }\n }\n } catch (err) {\n if (process.env.DEBUG_COHERENCE) {\n console.debug(\"[coherence] Wrapup coherence check failed:\", err instanceof Error ? err.message : err);\n }\n }\n\n // TEN-2402: the actionable draft set is the FULL set (capped ∪ overflow), so the agent\n // sees every promotable id, not just the first 15.\n const allDraftEntries = [...data.drafts, ...overflowDrafts];\n if (allDraftEntries.length > 0) {\n const draftIds = allDraftEntries.map((d) => `\\`${d.entryId}\\``).join(\", \");\n lines.push(\"### Actions\", \"\");\n lines.push(`Uncommitted: ${draftIds}`);\n lines.push(\"- **Accept all:** call \\`session action=wrapup-commit\\`\");\n lines.push(\"- **Skip:** call \\`session action=close\\` — drafts remain for next session's orient recovery.\");\n }\n if (overflowUnscanned > 0) {\n lines.push(\"\");\n lines.push(\n `> _${overflowUnscanned} draft(s) beyond the scan cap can't be auto-committed here — ` +\n \"commit them individually via `entries action=commit`, or close via `session action=close`._\",\n );\n }\n\n // WP-306 S2: Render captureAudit (zero-capture sessions with activity) and closeNudge.\n if (data.captureAudit) {\n lines.push(\"\");\n lines.push(\"### Capture Audit\");\n lines.push(\"\");\n lines.push(`_${data.captureAudit.message}_`);\n if (data.captureAudit.suggestions.length > 0) {\n lines.push(\"\");\n lines.push(\"**What to consider capturing:**\");\n for (const s of data.captureAudit.suggestions) {\n lines.push(`- **${s.collectionSlug}**: ${s.hint}`);\n }\n }\n lines.push(\"\");\n }\n\n lines.push(...(data.acceptIndependenceDigest?.lines.length ? [\"\", \"### Accept Independence\", \"\", `_${data.acceptIndependenceDigest.header}_`, ...data.acceptIndependenceDigest.lines.map((l) => `- ${l}`), \"\"] : [])); // WP-660 S2 review fix (Codex P1): empty cohort renders nothing\n\n lines.push(\"\");\n lines.push(`> **${data.closeNudge}**`);\n\n // WP-306 S3: Emit zero_capture_audit_fired event (STD-155)\n if (data.captureAudit) {\n const wsCtx = await getWorkspaceContext();\n if (wsCtx) {\n trackZeroCaptureAuditFired(wsCtx.workspaceId, {\n suggestion_count: data.captureAudit.suggestions.length,\n });\n }\n }\n\n const gapCount = getSessionGaps().length;\n return {\n text: lines.join(\"\\n\"),\n data,\n suggestions,\n gapCount,\n coherenceVerdict,\n persistentGaps,\n kernelSummary: kernelEnvelope.summary,\n kernelNext: kernelEnvelope.next,\n kernelMeta: kernelEnvelope._meta,\n };\n}\n\n// ─── Commit flow ─────────────────────────────────────────────────────────────\n\nasync function runWrapupCommitAll(\n data: WrapupData,\n cachedSuggestions: LinkSuggestion[],\n): Promise<{ text: string; committed: number; proposalsCreated: number; linksCreated: number; linksFailed: number; failed: number; overflowUnscanned: number }> {\n requireWriteAccess();\n\n const sessionId = getAgentSessionId();\n if (!sessionId) {\n return { text: \"No active session.\", committed: 0, proposalsCreated: 0, linksCreated: 0, linksFailed: 0, failed: 0, overflowUnscanned: 0 };\n }\n\n const wsCtx = await getWorkspaceContext();\n\n const results: { entryId: string; ok: boolean; proposed?: boolean; error?: string }[] = [];\n let linksCreated = 0;\n let linksFailed = 0;\n // WP-474 E5: auto-links the judge advised but did NOT write (untypeable) — surfaced, never silently dropped.\n let linksAdvised = 0;\n const linkFailureDetails: string[] = [];\n let proposalsCreated = 0;\n\n // TEN-2402: commit the FULL promotable set = capped drafts ∪ overflow drafts. The `?? []`\n // coalesce keeps a cross-deploy cache object that predates `overflowDrafts` safe. Each\n // overflow element carries `docId` (S1) so recordSessionActivity below never throws on\n // an undefined docId.\n const allDrafts = [...data.drafts, ...(data.overflowDrafts ?? [])];\n const overflowUnscanned = data.overflowUnscanned ?? 0;\n\n for (const draft of allDrafts) {\n try {\n const result = await kernelMutation<GatewayRouteReturnByName<\"chain.commitEntry\">>(\"chain.commitEntry\", {\n entryId: draft.entryId,\n author: `agent:${sessionId}`,\n sessionId,\n });\n // WP-465 slice ⑤ (Option B): a refused accept RETURNS a structured payload — record it\n // as a non-committed draft so wrapup never counts/latches it as accepted (it persists).\n // `chain.commitEntry`'s real return is a discriminated union whose plain-success branch\n // has NO `status` field at all (not even `status: undefined`) — `'status' in result`\n // narrows safely before reading it (PR #395, Lane C S3b annotation pass).\n if (result && \"status\" in result && result.status === \"coherency_refused\") {\n const refusal = \"refusal\" in result ? result.refusal : undefined;\n results.push({\n entryId: draft.entryId,\n ok: false,\n error: `coherency gate refused this accept — ${(refusal as { reason?: string } | undefined)?.reason ?? \"refused by the coherency gate\"}`,\n });\n continue;\n }\n const proposed = !!(result && \"status\" in result && result.status === \"proposal_created\");\n if (!proposed) {\n await recordSessionActivity({ entryModified: draft.docId });\n trackChainEntryCommitted(wsCtx.workspaceId, {\n entry_id: draft.entryId,\n commit_method: \"manual\",\n surface: \"mcp_wrapup\",\n });\n }\n if (proposed) {\n proposalsCreated++;\n }\n results.push({ entryId: draft.entryId, ok: true, proposed });\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n results.push({ entryId: draft.entryId, ok: false, error: msg });\n }\n }\n\n // Use cached suggestions from review phase, or fetch fresh if none\n const suggestionsToApply = cachedSuggestions.length > 0\n ? cachedSuggestions\n : await suggestLinksForEntries(\n [...data.drafts, ...data.committed].filter(\n (e) => (data.connectionCounts[e.entryId] ?? 0) < 2,\n ).slice(0, 10),\n );\n const linkableSourceIds = new Set([\n ...data.committed.map((entry) => entry.entryId),\n ...results.filter((r) => r.ok && !r.proposed).map((r) => r.entryId),\n ]);\n\n const toApply = suggestionsToApply\n .filter((s) => linkableSourceIds.has(s.fromEntryId))\n .slice(0, 15);\n const governsRels = toApply.filter((s) => s.type === \"governs\");\n const batchRels = toApply.filter((s) => s.type !== \"governs\");\n\n if (batchRels.length > 0) {\n try {\n const batchResult = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelations\">>(\"chain.createEntryRelations\", {\n // WP-474 E4-REWIRE: wrapup-applied suggestions are auto-inferred (no one chose the\n // type) → mark \"auto-link\" + carry confidence (DEC-1399), matching smart-capture.\n relations: batchRels.map((s) => ({\n fromEntryId: s.fromEntryId,\n toEntryId: s.toEntryId,\n type: s.type,\n proposedBy: \"auto-link\",\n ...(s.confidence !== undefined ? { confidence: s.confidence } : {}),\n })),\n sessionId,\n });\n linksCreated += batchResult?.created ?? 0;\n // WP-474 E5: the judge may advise (not write) untypeable auto-link edges — those are\n // excluded from `failed` server-side (status:'advised'), so tally them separately.\n linksAdvised += batchResult?.advised ?? 0;\n\n // Surface per-relation failures so the user knows which links weren't created\n if (batchResult && batchResult.failed > 0) {\n linksFailed += batchResult.failed;\n const failedResults = batchResult.results\n .map((r, i) => ({ ...r, index: i }))\n .filter((r) => !r.ok && r.status !== 'advised');\n for (const fr of failedResults) {\n const rel = batchRels[fr.index];\n if (rel) {\n linkFailureDetails.push(\n `${rel.fromEntryId} → ${rel.toEntryId} [${rel.type}]: ${fr.error ?? \"unknown error\"}`,\n );\n }\n }\n }\n } catch (err) {\n // Total batch failure — count all as failed\n linksFailed += batchRels.length;\n const msg = err instanceof Error ? err.message : String(err);\n linkFailureDetails.push(`Batch creation failed (${batchRels.length} relations): ${msg}`);\n }\n }\n\n for (const s of governsRels) {\n try {\n const result = await kernelMutation<GatewayRouteReturnByName<\"chain.createEntryRelation\">>(\"chain.createEntryRelation\", {\n fromEntryId: s.fromEntryId,\n toEntryId: s.toEntryId,\n type: s.type,\n // WP-474 E4-REWIRE: wrapup-applied governs suggestion is auto-inferred → \"auto-link\".\n proposedBy: \"auto-link\",\n ...(s.confidence !== undefined ? { confidence: s.confidence } : {}),\n sessionId,\n });\n // WP-474 E5: the judge may advise (not write) an untypeable auto-link edge — that is\n // neither a proposal nor a created link, so it must not inflate linksCreated. Tally it as\n // advised (same as the batch path) so the advised-not-written message surfaces it rather\n // than the governs edge silently disappearing from the wrapup result.\n if (result?.status === \"proposal_created\") {\n // Consent proposal (governs requires async sign-off) — not a written link; left\n // uncounted here as before (pre-existing behavior, unchanged by this fix).\n } else if (result?.advised) {\n linksAdvised++;\n } else {\n linksCreated++;\n }\n } catch (err) {\n linksFailed++;\n const msg = err instanceof Error ? err.message : String(err);\n linkFailureDetails.push(`${s.fromEntryId} → ${s.toEntryId} [${s.type}]: ${msg}`);\n }\n }\n\n const committed = results.filter((r) => r.ok && !r.proposed).length;\n const failed = results.filter((r) => !r.ok);\n\n // TEN-2400: latch the wrapup (writes `wrapupCompletedAt` server-side) ONLY on a clean\n // drain — no failed commit AND nothing left unscanned. Latching on a failed/partial batch\n // would set `wrapupCompletedAt` and (combined with the review short-circuit) blind the\n // surface to the still-stranded drafts. A failed batch records no wrapup metrics, which is\n // intentional and consistent with the kernel envelope path.\n const cleanDrain = failed.length === 0 && overflowUnscanned === 0;\n if (cleanDrain) {\n await kernelCall<GatewayRouteReturnByName<\"agent.recordWrapup\">>(\"agent.recordWrapup\", {\n sessionId,\n draftsReviewed: allDrafts.length,\n draftsCommitted: committed,\n linksCreated,\n });\n }\n\n const lines: string[] = [\n \"## Wrapup Complete\",\n \"\",\n `**${committed}** drafts accepted, **${proposalsCreated}** proposals created, **${linksCreated}** links created.`,\n ];\n\n if (linksFailed > 0) {\n lines.push(`**${linksFailed}** link${linksFailed === 1 ? \"\" : \"s\"} failed to create.`);\n }\n\n // WP-474 E5: surface the advised-not-written cohort unconditionally — never gated on failures,\n // since an advised edge is neither a success nor a failure.\n if (linksAdvised > 0) {\n lines.push(`**${linksAdvised}** auto-link(s) advised, not written (untypeable) — accept with \\`relations action=create\\` to promote.`);\n }\n\n if (failed.length > 0) {\n lines.push(\"\");\n lines.push(\"### Failed to accept\");\n for (const f of failed) {\n lines.push(`- \\`${f.entryId}\\`: ${f.error}`);\n }\n lines.push(\"_These remain as drafts for next session._\");\n }\n\n if (linkFailureDetails.length > 0) {\n lines.push(\"\");\n lines.push(\"### Failed to create links\");\n for (const detail of linkFailureDetails) {\n lines.push(`- ${detail}`);\n }\n lines.push(\"_You can create these links manually with `entries action=create-relation`._\");\n }\n\n return {\n text: lines.join(\"\\n\"),\n committed,\n proposalsCreated,\n linksCreated,\n linksFailed,\n failed: failed.length,\n overflowUnscanned,\n };\n}\n\n// ─── Shared schema (still used by session.ts's discriminated variants + tests) ──\n\nexport const wrapupSchema = z.object({\n action: z.enum([\"review\", \"commit-all\"]).optional().describe(\n \"Action to perform. 'review' (default) shows the wrapup summary. 'commit-all' accepts all uncommitted drafts and creates suggested links.\",\n ),\n});\n\n/**\n * Factory for the wrapup handler (WP-484 S2, §3) — reused by the legacy\n * `session-wrapup` tool and the new `session action=wrapup-review` /\n * `session action=wrapup-commit`. One business-logic path (this function\n * body), but each registration gets its OWN review cache — a shared module\n * singleton would leak cached review state across unrelated tests AND across\n * unrelated tool registrations in the same process. The former\n * `registerWrapupTools`-closure-local cache is preserved exactly, just\n * factored out so a second caller (session.ts) can mint its own instance.\n */\nexport function createWrapupHandler() {\n let lastReviewData: WrapupData | null = null;\n let lastReviewSuggestions: LinkSuggestion[] = [];\n let lastReviewSessionId: string | null = null;\n\n return async ({ action }: { action?: \"review\" | \"commit-all\" }) => {\n if (action === \"commit-all\") {\n const sessionId = getAgentSessionId();\n if (!sessionId) {\n return failureResult(\n \"No active agent session.\",\n \"SESSION_REQUIRED\",\n \"No active agent session.\",\n \"Start a session first.\",\n [{ tool: \"session\", description: \"Start a session\", parameters: { action: \"start\" } }],\n );\n }\n\n const useCachedReview = lastReviewSessionId === sessionId;\n let data: WrapupData;\n if (useCachedReview && lastReviewData) {\n data = lastReviewData;\n } else {\n const { workspaceId } = await getWorkspaceContext();\n // WP-321 E3: delegate to kernel action; auth injected server-side via injectSessionAuth in http.ts\n data = (await kernelCallEnvelope<WrapupEnvelopeData>(\"agentKnowledge.wrapupEnvelope\", {\n workspaceId,\n sessionId,\n action: \"review\",\n })).data;\n }\n // TEN-2402: the early-exit guard must consider the FULL promotable set. Guarding on\n // `data.drafts.length === 0` alone dead-codes the overflow iteration for an\n // all-overflow-draft session (first 15 committed, drafts only past the cap).\n if (data.drafts.length === 0 && (data.overflowDrafts ?? []).length === 0) {\n return failureResult(\"No uncommitted drafts to accept.\", \"NOT_FOUND\", \"No uncommitted drafts to accept.\", \"Nothing to accept.\");\n }\n\n const result = await runWrapupCommitAll(data, useCachedReview ? lastReviewSuggestions : []);\n lastReviewData = null;\n lastReviewSuggestions = [];\n lastReviewSessionId = null;\n const linkWarnSuffix = result.linksFailed > 0 ? `, ${result.linksFailed} link(s) failed` : \"\";\n // TEN-2400: derive `next` from the commit results — never a static close.\n // - overflowUnscanned > 0 → terminal (committing can't shrink it).\n // - any failed commit → re-review/fix.\n // - clean drain → close.\n const commitNext =\n result.overflowUnscanned > 0\n ? [\n {\n tool: \"session\",\n description:\n `${result.overflowUnscanned} draft(s) beyond the scan cap can't be auto-committed here — ` +\n \"commit them individually via `entries action=commit`, or close via `session action=close`.\",\n parameters: { action: \"close\" },\n },\n ]\n : result.failed > 0\n ? [{ tool: \"session\", description: \"Re-review remaining drafts before closing\", parameters: { action: \"wrapup-review\" } }]\n : [{ tool: \"session\", description: \"Close the session now that drafts are committed\", parameters: { action: \"close\" } }];\n return successResult(\n result.text,\n `Wrapup processed: ${result.committed} accepted, ${result.proposalsCreated} proposals, ${result.linksCreated} links${linkWarnSuffix}.`,\n {\n committed: result.committed,\n proposalsCreated: result.proposalsCreated,\n linksCreated: result.linksCreated,\n linksFailed: result.linksFailed,\n failed: result.failed,\n },\n commitNext,\n );\n }\n\n const { text, data, suggestions, failureCode, gapCount, coherenceVerdict, persistentGaps, kernelSummary, kernelNext, kernelMeta } = await runWrapupReview();\n lastReviewData = data;\n lastReviewSuggestions = suggestions;\n lastReviewSessionId = getAgentSessionId();\n\n // TEN-2402: composeWrapupView merges capped ∪ overflow; the parity test pins this\n // helper against the CLI twin. Use it for the empty-session check and the local next\n // fallback so both honor the full set, not just the capped 15.\n const composed = data ? composeWrapupView(data) : null;\n const fullText = composed && (composed.drafts.length > 0 || composed.committed.length > 0)\n ? `## Session Wrapup\\n\\n${text}`\n : text;\n\n if (failureCode) {\n return failureResult(fullText, failureCode, text);\n }\n\n // TEN-2390/2400: local fallback next must derive from the merged remaining set + the\n // unscanned count, or it silently keeps the old capped-only logic when kernelNext is\n // absent. `canClose` already AND-s drafts-empty + unscanned-zero.\n const localNext =\n composed && !composed.canClose\n ? [{ tool: \"session\", description: \"Accept all drafts\", parameters: { action: \"wrapup-commit\" } }]\n : undefined;\n const next = kernelNext || localNext;\n\n const gapsSummary = gapCount ? `, ${gapCount} knowledge gaps detected` : \"\";\n const coherenceSummary = coherenceVerdict ? `, coherence: ${coherenceVerdict}` : \"\";\n const persistentSummary = persistentGaps?.length ? `, ${persistentGaps.length} persistent coherence gaps` : \"\";\n // TEN-2402: report the MERGED (capped ∪ overflow) counts, not the capped-only `data`\n // lists. The rendered text already names the full set (allDraftEntries / Beyond Review\n // Cap), so capped-only numbers here would make structuredContent under-report drafts a\n // machine caller can see listed above — the exact \"surface lies about state\" defect.\n const draftsCount = composed?.drafts.length ?? data!.drafts.length;\n const committedCount = composed?.committed.length ?? data!.committed.length;\n const summaryText = `Session review: ${draftsCount} uncommitted, ${committedCount} committed, ${suggestions.length} link suggestions${gapsSummary}${coherenceSummary}${persistentSummary}.`;\n return {\n content: [{ type: \"text\" as const, text: fullText }],\n structuredContent: {\n ok: true as const,\n summary: kernelSummary || summaryText,\n data: {\n drafts: draftsCount,\n committed: committedCount,\n uncommitted: data!.summary.uncommitted,\n suggestedLinks: suggestions.length,\n knowledgeGaps: gapCount ?? 0,\n ...(coherenceVerdict ? { coherenceVerdict } : {}),\n ...(persistentGaps?.length ? { persistentCoherenceGaps: persistentGaps.length } : {}),\n },\n next,\n _meta: kernelMeta,\n },\n };\n };\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `session-wrapup` tool\n// retired here. createWrapupHandler / runWrapupReview stay live — session.ts\n// (the `session` compound, action=wrapup-review / action=wrapup-commit) is\n// their only remaining caller.\n\nexport { runWrapupReview, type WrapupReviewResult };\n","/**\n * composeWrapupView — the single place TEN-2402 is fixed on the MCP surface.\n *\n * The kernel `getSessionWrapup` returns capped `committed`/`drafts` (≤15 each, with\n * per-entry enrichment) PLUS slim overflow lists beyond the cap: `overflowCommitted`,\n * `overflowDrafts` (each `{ entryId, name, docId }`), and a positional `overflowUnscanned`\n * count for entries past the scan cap that were never read.\n *\n * This helper MERGES the capped and overflow lists so every surface names the FULL set:\n * committed = committed ∪ overflowCommitted\n * drafts = drafts ∪ overflowDrafts\n *\n * The merge MUST live here (not at the call site) so the repo-level parity test can pin it\n * against the CLI's twin helper. `canClose` is the REVIEW predicate (the loop is empty);\n * the commit-all path AND-s its own post-commit `failed === 0` fact at the call site,\n * NOT here (that fact is absent from the raw kernel result).\n *\n * Every read of an overflow field coalesces `?? []` / `?? 0` so a cross-deploy cache object\n * predating the field shape can never throw (Staff+ MAJOR-1).\n */\n\n/** Minimal entry shape every surface can name. The capped entries carry more; the merge keeps it. */\nexport interface ComposedEntry {\n entryId: string;\n name: string;\n docId: string;\n}\n\n/** Slim overflow element from the kernel. */\ninterface OverflowEntry {\n entryId: string;\n name: string;\n docId: string;\n}\n\n/** The raw kernel wrapup result this helper consumes (only the fields it reads are required). */\nexport interface RawWrapupView {\n committed?: Array<{ entryId: string; name: string; docId: string }>;\n drafts?: Array<{ entryId: string; name: string; docId: string }>;\n overflowCommitted?: OverflowEntry[];\n overflowDrafts?: OverflowEntry[];\n overflowUnscanned?: number;\n}\n\nexport interface ComposedWrapupView {\n committed: ComposedEntry[];\n drafts: ComposedEntry[];\n overflowUnscanned: number;\n /** REVIEW predicate: the loop is empty. Commit-all AND-s `failed === 0` at the call site. */\n canClose: boolean;\n}\n\nfunction toComposed(e: { entryId: string; name: string; docId: string }): ComposedEntry {\n return { entryId: e.entryId, name: e.name, docId: e.docId };\n}\n\nexport function composeWrapupView(raw: RawWrapupView): ComposedWrapupView {\n const committed = [\n ...(raw.committed ?? []).map(toComposed),\n ...(raw.overflowCommitted ?? []).map(toComposed),\n ];\n const drafts = [\n ...(raw.drafts ?? []).map(toComposed),\n ...(raw.overflowDrafts ?? []).map(toComposed),\n ];\n const overflowUnscanned = raw.overflowUnscanned ?? 0;\n return {\n committed,\n drafts,\n overflowUnscanned,\n canClose: drafts.length === 0 && overflowUnscanned === 0,\n };\n}\n","/**\n * Facilitate compound tool — session resume and constellation commit.\n *\n * Actions: resume, commit-constellation\n *\n * Scoring, coaching, and facilitation loop moved to agent-side skills (BET-106).\n * This tool retains only session-state loading and atomic constellation commit.\n * WP-321 E3: Delegates to kernel actions (agentKnowledge.facilitateEnvelope) —\n * MCP layer is a thin passthrough with presentation-only enrichment (cortexUrl).\n *\n * Chain: ENT-37 (Facilitate v1), DEC-56 (PB judges, agents coach),\n * STA-1 (Constellation Capture Pattern)\n * Rules: BR-8 (session required), BR-22 (single impl), BR-25 (MCP layer),\n * BR-70 (audit trail)\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport {\n kernelCallEnvelope,\n getWorkspaceContext,\n requireWriteAccess,\n recordSessionActivity,\n getAgentSessionId,\n} from \"../client.js\";\nimport { runConflictPreflight } from \"./conflict-preflight.js\";\nimport { failure, validationResult } from \"../envelope.js\";\n\n// ── Schema ─────────────────────────────────────────────────────────────────\n\nconst FACILITATE_ACTIONS = [\"resume\", \"commit-constellation\"] as const;\n\n// WP-465 slice ⑤ (TEN-2439, §3.3): mirrors the kernel's coherencyAcknowledgementValidator\n// (convex/lib/gates/coherencyRecord.ts) — response is a free string here; the gate owns the\n// vocabulary check (validateCoherencyAcknowledgement), fail-closed, so the connector mirror\n// can never drift the SSOT.\nconst coherencyAcknowledgementSchema = z.object({\n response: z.string().max(200)\n .describe(\"Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'.\"),\n entryId: z.string().max(200).optional()\n .describe(\"Entry the acknowledgement links to (e.g. the strategic spine entry).\"),\n reason: z.string().max(2000).optional()\n .describe(\"Free-text justification, required for a 'diverged' response.\"),\n subjectEntryId: z.string().max(200).optional()\n .describe(\"The refused entry this acknowledgement answers.\"),\n});\n\nexport const facilitateSchema = z.object({\n action: z.enum(FACILITATE_ACTIONS).describe(\n \"'resume': load session state from an existing bet entry. \" +\n \"'commit-constellation': atomically accept a bet and all its linked draft entries in one call. Requires betEntryId.\",\n ),\n betEntryId: z.string().max(200).optional()\n .describe(\"Bet entry ID. Required for both actions.\"),\n operationId: z.string().max(200).optional()\n .describe(\"Optional idempotency key for commit-constellation retries.\"),\n // WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.\n // Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).\n coherencyAcknowledgements: z.array(coherencyAcknowledgementSchema).max(20).optional()\n .describe(\n \"Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. \" +\n \"Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}.\",\n ),\n steeringOverrideReason: z.string().max(2000).optional()\n .describe(\n \"Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging.\",\n ),\n});\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\ninterface SessionDraft {\n entryId: string;\n name: string;\n collection: string;\n relationType: string;\n status: string;\n}\n\ninterface ConstellationState {\n elementCount: number;\n riskCount: number;\n decisionCount: number;\n}\n\ninterface BetEntryData {\n betEntryId: string;\n name: string;\n status: string;\n data: Record<string, unknown>;\n}\n\ninterface ResumeData {\n betEntry: BetEntryData;\n constellation: ConstellationState;\n sessionDrafts: SessionDraft[];\n}\n\ninterface ConstellationCommitResult {\n operationId: string;\n committedIds: string[];\n alreadyCommittedIds: string[];\n proposedIds: string[];\n failedIds: Array<{ entryId: string; name: string; error: string }>;\n conflictIds: Array<{ entryId: string; name: string; reason: string }>;\n totalRelations: number;\n proposalCreated?: boolean;\n}\n\ninterface CommitConstellationData {\n result: ConstellationCommitResult;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nfunction buildCortexUrl(workspaceSlug: string, entryId: string): string {\n const appUrl = process.env.PRODUCTBRAIN_APP_URL ?? \"https://work.productbrain.io\";\n return `${appUrl}/${workspaceSlug}/legacy/entries/${entryId}`;\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `facilitate` tool\n// retired here. handleResume / handleCommitConstellation stay live —\n// session.ts (the `session` compound, action=resume / action=commit-constellation)\n// is their only remaining caller.\n\n// ── Action Handlers ────────────────────────────────────────────────────────\n\nexport async function handleResume(args: z.infer<typeof facilitateSchema>) {\n const betId = args.betEntryId;\n if (!betId) {\n return validationResult(\"`betEntryId` is required for resume action.\");\n }\n\n const { workspaceId, workspaceSlug } = await getWorkspaceContext();\n\n // `agentKnowledge.facilitateEnvelope` is self-enveloping (same shape as `agentKnowledge.\n // wrapupEnvelope`, see packages/mcp-server/src/tools/wrapup.ts's own doc comment) — its\n // declared return is `Envelope<ResumeData | CommitConstellationData>`, and the payload\n // this \"resume\" call receives is specifically `ResumeData` (has `betEntry`, unique to it;\n // `CommitConstellationData` has `result` instead). PR #395, Lane C S3b annotation pass.\n type FacilitateEnvelopePayload = Extract<\n GatewayRouteReturnByName<\"agentKnowledge.facilitateEnvelope\">,\n { ok: true }\n >[\"data\"];\n type ResumeEnvelopeData = Extract<FacilitateEnvelopePayload, { betEntry: unknown }>;\n\n // Delegate to kernel action\n const envelope = await kernelCallEnvelope<ResumeEnvelopeData>(\"agentKnowledge.facilitateEnvelope\", {\n workspaceId,\n action: \"resume\",\n betEntryId: betId,\n });\n\n // MCP-layer enrichment: add cortexUrl (kernel doesn't build Cortex URLs — that's MCP presentation)\n const enrichedData = {\n ...envelope.data,\n cortexUrl: buildCortexUrl(workspaceSlug, betId),\n };\n\n // Rebuild rich markdown briefing (presentation concern — kernel stays semantic)\n const bet = enrichedData.betEntry;\n const cx = enrichedData.constellation;\n const constellationParts: string[] = [];\n if (cx.elementCount > 0) constellationParts.push(`${cx.elementCount} element(s)`);\n if (cx.riskCount > 0) constellationParts.push(`${cx.riskCount} risk(s)`);\n if (cx.decisionCount > 0) constellationParts.push(`${cx.decisionCount} decision(s)`);\n const constellationSummary = constellationParts.length > 0\n ? constellationParts.join(\", \")\n : \"no entries captured yet\";\n\n const draftLines = enrichedData.sessionDrafts.slice(0, 10).map(\n (d: SessionDraft) => `- \\`${d.entryId}\\` ${d.name} [${d.collection}] (${d.status})`,\n );\n const textLines = [\n `# ${bet.name}`,\n \"\",\n `**ID:** \\`${bet.betEntryId}\\` · **Status:** ${bet.status}`,\n enrichedData.cortexUrl ? `**Cortex:** ${enrichedData.cortexUrl}` : \"\",\n \"\",\n `**Constellation:** ${constellationSummary}`,\n ...(draftLines.length > 0 ? [\"\", \"**Session drafts:**\", ...draftLines] : []),\n ].filter((l) => l !== undefined);\n\n return {\n content: [{ type: \"text\" as const, text: textLines.join(\"\\n\") }],\n structuredContent: {\n ok: true as const,\n summary: envelope.summary,\n data: enrichedData,\n next: envelope.next,\n _meta: envelope._meta,\n },\n };\n}\n\n// ── Commit Constellation ────────────────────────────────────────────────\n\nexport async function handleCommitConstellation(args: z.infer<typeof facilitateSchema>) {\n requireWriteAccess();\n\n const betId = args.betEntryId;\n if (!betId) {\n return validationResult(\"`betEntryId` is required for commit-constellation action.\");\n }\n\n const { workspaceId } = await getWorkspaceContext();\n const sessionId = getAgentSessionId();\n const operationId = args.operationId ?? `${betId}:${sessionId ?? \"sessionless\"}:${Date.now()}`;\n\n // ── MCP-layer conflict preflight (pre-condition check, stays in MCP layer) ──\n // We need the bet name and description for the conflict check. Load minimally.\n let betName = betId;\n let betDesc = \"\";\n let betCollectionHint: string | undefined;\n try {\n type BetEntryShape = {\n name: string;\n data?: Record<string, unknown>;\n collectionSlug?: string;\n collection?: { slug?: string; name?: string };\n };\n const betEnvelope = await kernelCallEnvelope<BetEntryShape>(\"chain.getEntry\", { entryId: betId });\n const entry = betEnvelope.data;\n if (entry) {\n betName = entry.name ?? betId;\n const d = entry.data ?? {};\n const links = d[\"links\"] as Record<string, unknown> | undefined;\n betDesc = (d.problem as string) ?? (links?.problem as string) ?? (d.description as string) ?? \"\";\n betCollectionHint = entry.collectionSlug ?? entry.collection?.slug ?? entry.collection?.name;\n }\n } catch {\n // If we can't load the bet entry, the kernel will handle the NOT_FOUND case\n }\n\n // WP-485 Slice 2b (R2, FEAT-1370): discovery only — the local\n // `blockingContradictions.length > 0` hard-block branch (a client-side\n // BLOCKING_CONTRADICTION_THRESHOLD comparison, one of three independent copies of the same\n // enforcement decision) is deleted. This tool discovers conflicts and keeps them visible as\n // advisory text below; it never decides to block a constellation accept.\n const preflight = await runConflictPreflight(betName, betDesc, betCollectionHint);\n\n if (preflight.source === \"semantic\" ? preflight.conflicts.length > 0 : preflight.advisoryWarnings.length > 0) {\n await recordSessionActivity({ contradictionWarning: true });\n }\n\n // WP-485 Slice 2b round 2 (Codex P1, FEAT-1370): forward discovered semantic conflicts as\n // evidence to batchCommitConstellation's PRE-EXISTING contradiction gate (TEN-1405 / BR-144)\n // via facilitateEnvelope's new `conflicts` arg — without this, that gate always evaluated an\n // empty set on this surface no matter what was discovered. Heuristic-source\n // `advisoryWarnings` are a different shape and never forwarded. Whitelist only the\n // validator-accepted fields — `chain.detectSemanticConflicts` also returns an internal\n // `chainEntryDocId` that fails the server's `conflicts` arg validator (Slice 2b round 1\n // live-proof finding).\n const conflictEvidence = preflight.source === \"semantic\"\n ? preflight.conflicts.map((c) => ({\n chainEntryId: c.chainEntryId,\n chainEntryName: c.chainEntryName,\n ...(c.chainEntryDescription ? { chainEntryDescription: c.chainEntryDescription } : {}),\n type: c.type,\n confidence: c.confidence,\n explanation: c.explanation,\n }))\n : [];\n\n // ── Delegate to kernel action ───────────────────────────────────────────\n let envelope: Awaited<ReturnType<typeof kernelCallEnvelope<CommitConstellationData>>>;\n try {\n // Matches the pre-declared `envelope` variable's own type above — see the \"resume\" call\n // site's doc comment for why this route's payload must be narrowed, not used as-is.\n envelope = await kernelCallEnvelope<CommitConstellationData>(\"agentKnowledge.facilitateEnvelope\", {\n workspaceId,\n action: \"commit-constellation\",\n betEntryId: betId,\n operationId,\n sessionId: sessionId ?? undefined,\n author: sessionId ? `agent:${sessionId}` : \"kernel:facilitate\",\n // WP-465 slice ⑤ (TEN-2439, §3.7): relay the coherency retry controls so a\n // COHERENCY_REFUSED constellation hold is actually retryable through MCP.\n ...(args.coherencyAcknowledgements ? { coherencyAcknowledgements: args.coherencyAcknowledgements } : {}),\n ...(args.steeringOverrideReason ? { steeringOverrideReason: args.steeringOverrideReason } : {}),\n ...(conflictEvidence.length > 0 ? { conflicts: conflictEvidence } : {}),\n });\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n const code = (err as { code?: string })?.code;\n const diagnostics = (err as { diagnostics?: Record<string, unknown> })?.diagnostics;\n\n // WP-465 slice ⑤ (TEN-2439, §3.7): a coherency HOLD is NOT a backend error. The\n // kernel returns an `ok:false` COHERENCY_REFUSED envelope naming each offender and\n // its routes; callGateway throws on `ok:false`, so detect the code here — BEFORE the\n // generic wrapper — and surface the structured `coherencyRefusals` (subject ids +\n // routes) so the agent can populate the retry controls (coherencyAcknowledgements /\n // steeringOverrideReason). Mirrors the kernel facilitate envelopeError shape and the\n // commit/update single-entry refusal tools — same code, same diagnostics key.\n if (code === \"COHERENCY_REFUSED\") {\n const coherencyRefusals = (Array.isArray(diagnostics?.coherencyRefusals)\n ? diagnostics.coherencyRefusals\n : []) as Array<{ entryId: string; name: string; refusal: Record<string, unknown> }>;\n const offenderLines = coherencyRefusals\n .map((r) => `- \\`${r.entryId}\\` ${r.name}: ${String((r.refusal as { reason?: string })?.reason ?? \"coherency challenge unsatisfied\")}`)\n .join(\"\\n\");\n const count = coherencyRefusals.length;\n return {\n content: [{\n type: \"text\" as const,\n text: [\n `# Constellation held by the coherency gate`,\n \"\",\n `\\`${betId}\\` was not accepted — ${count} entr${count === 1 ? \"y\" : \"ies\"} refused. Nothing was committed; drafts persist.`,\n ...(offenderLines ? [\"\", offenderLines] : []),\n ].join(\"\\n\"),\n }],\n structuredContent: failure(\n \"COHERENCY_REFUSED\",\n `Constellation held: ${count} entr${count === 1 ? \"y\" : \"ies\"} refused by the coherency gate — nothing was committed, drafts persist.`,\n \"Respond per offender and retry commit-constellation: link the entry to the strategic spine, pass coherencyAcknowledgements [{subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}], or supply a typed steeringOverrideReason (at least 12 characters).\",\n [{ tool: \"session\", description: \"Retry with coherency acknowledgements\", parameters: { action: \"commit-constellation\", betEntryId: betId } }],\n { coherencyRefusals },\n ),\n };\n }\n\n // WP-485 Slice 2b round 4 (Codex P2, FEAT-1370): DEAD-BUT-TYPED. `{graduated:false}`\n // (DEC-1321) means this never fires today, but a future policy graduation would otherwise\n // reach here as an unclassified BACKEND_ERROR — the exact code-loss the round-2 AKI gateway\n // registration fix exists to prevent, for this DIFFERENT (facilitateEnvelope, not AKI HTTP)\n // transport path. Preserve the code + message the kernel now returns.\n if (code === \"CONTRADICTION_BLOCKED\") {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Constellation accept blocked\\n\\n\\`${betId}\\` was not accepted: ${msg}\\n\\nNo constellation entries were accepted.`,\n }],\n structuredContent: failure(\n \"CONTRADICTION_BLOCKED\",\n msg,\n \"Resolve the contradiction before retrying commit-constellation.\",\n ),\n };\n }\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Work package accept failed\\n\\n\\`${betId}\\` could not be accepted: ${msg}\\n\\nNo constellation entries were accepted.`,\n }],\n structuredContent: failure(\n \"BACKEND_ERROR\",\n `Work package accept failed: ${msg}`,\n \"Retry or check for accept blockers.\",\n [{ tool: \"session\", description: \"Resume session\", parameters: { action: \"resume\", betEntryId: betId } }],\n diagnostics,\n ),\n };\n }\n\n // WP-485 Slice 2b round 2 (Codex P2, FEAT-1370): the discovery-time call above (line ~231)\n // already records `contradictionWarning` once per preflight — this second, post-commit call\n // used to record the SAME boolean again, double-counting every single discovered conflict as\n // two in session summaries and related instrumentation. Deleted, not moved: discovery-time is\n // the right moment (matches knowledge.ts's single recordSessionActivity call at discovery).\n // Per-entry audit trail — record each committed doc in session activity (BR-70)\n for (const docId of (envelope.data?.result?.committedIds ?? [])) {\n try {\n await recordSessionActivity({ entryModified: docId });\n } catch {\n // Advisory — non-blocking\n }\n }\n\n // Build text output from kernel result\n const result = envelope.data.result;\n // WP-485 Slice 2b round 3 (Codex P1, FEAT-1370): mirror the SAME discovered conflicts the\n // text below renders into the structured payload — before this fix, `suggestions` carried\n // only `conflictPreflightSource`, so a structured-content-only caller saw an unqualified\n // successful accept with no trace of a discovered contradiction. (batchCommitConstellation\n // does not attach a server-side `contradictionAdvisory` on success — unlike commitEntry,\n // Slice 2a never wired that for this surface — so this mirrors the discovery-level\n // evidence, the same data already forwarded to the gate as `conflicts`.)\n const suggestions = {\n conflictPreflightSource: preflight.source,\n ...(preflight.source === \"semantic\" && preflight.conflicts.length > 0\n ? { conflicts: preflight.conflicts }\n : {}),\n ...(preflight.source === \"heuristic\" && preflight.advisoryWarnings.length > 0\n ? { advisoryWarnings: preflight.advisoryWarnings }\n : {}),\n };\n\n const lines: string[] = [];\n const hasIssues = (result.failedIds?.length ?? 0) > 0 || (result.conflictIds?.length ?? 0) > 0;\n if (result.proposalCreated) {\n lines.push(\n hasIssues ? `# Proposal created with issues` : `# Proposal created`,\n \"\",\n `Workspace uses consent-based governance. \\`${betId}\\` was submitted as a proposal — it will be accepted when approved.`,\n `No linked entries were accepted because the work package itself is still awaiting approval.`,\n );\n } else {\n lines.push(\n hasIssues ? `# Accepted with issues` : `# Accepted`,\n \"\",\n `**${result.committedIds?.length ?? 0} entries** accepted onto the Chain, **${result.totalRelations} connections** preserved.`,\n hasIssues\n ? `\\`${betId}\\` was partially accepted. Review conflicts/failed entries below before considering the constellation complete.`\n : `\\`${betId}\\` and its full constellation are now source of truth.`,\n );\n }\n\n if (preflight.source === \"semantic\" && preflight.conflicts.length > 0) {\n lines.push(\n \"\",\n `⚠ **Semantic conflict preflight** (advisory):`,\n ...preflight.conflicts.map((c) => `- \\`${c.chainEntryId}\\` ${c.chainEntryName}: ${c.explanation}`),\n );\n } else if (preflight.source === \"heuristic\" && preflight.advisoryWarnings.length > 0) {\n lines.push(\n \"\",\n `⚠ **Contradiction warnings** (advisory):`,\n ...preflight.advisoryWarnings.map(\n (w) => `- \\`${w.entryId}\\` ${w.name} [${w.collection}] (${w.governsCount} governs relation${w.governsCount === 1 ? \"\" : \"s\"})`,\n ),\n );\n }\n\n if ((result.committedIds?.length ?? 0) > 0) {\n lines.push(\"\", `**Accepted:** ${result.committedIds.join(\", \")}`);\n }\n if ((result.alreadyCommittedIds?.length ?? 0) > 0) {\n lines.push(\"\", `**Already accepted:** ${result.alreadyCommittedIds.join(\", \")}`);\n }\n if ((result.proposedIds?.length ?? 0) > 0) {\n lines.push(\"\", `**Proposed (not yet accepted):** ${result.proposedIds.join(\", \")}`);\n }\n if ((result.conflictIds?.length ?? 0) > 0) {\n lines.push(\"\", `**${result.conflictIds.length} conflicts:**`);\n for (const c of result.conflictIds) {\n lines.push(`- \\`${c.entryId}\\` ${c.name}: ${c.reason}`);\n }\n }\n if ((result.failedIds?.length ?? 0) > 0) {\n lines.push(\"\", `**${result.failedIds.length} failed:**`);\n for (const f of result.failedIds) {\n lines.push(`- \\`${f.entryId}\\` ${f.name}: ${f.error}`);\n }\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: {\n ok: true as const,\n summary: envelope.summary,\n data: { result, suggestions },\n next: envelope.next,\n _meta: envelope._meta,\n },\n };\n}\n","/**\n * GitChain MCP tools — consolidated chain lifecycle operations.\n *\n * 2 tools (down from 14) covering CRUD, versioning, branching, and review —\n * `chain` and `chain-review` below (WP-687 S2 retired the map tool; the gitchain\n * module now covers exactly these 2 tools). Backend calls are unchanged — same\n * Convex `gitchain.*` namespace.\n *\n * Chain: GT-vaw0re (Git Chain), FEAT-CW-001 (ChainWork Engine)\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery, kernelMutation, getWorkspaceContext, runWithToolContext } from \"../client.js\";\nimport { thinWrapper, success, failure, validationResult, successResult, unknownAction, parseOrFail, type ToolResult } from \"../envelope.js\";\nimport { toVersionDisplay } from \"../lib/versionDisplay.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\n\nexport const chainSchema = z.object({\n action: z.enum([\"create\", \"get\", \"list\", \"edit\"]).describe(\"Action: create a process, get process details, list all processes, or edit a process link\"),\n chainEntryId: z.string().max(200).optional().describe(\"Chain entry ID (required for get/edit)\"),\n title: z.string().max(500).optional().describe(\"Process title (required for create)\"),\n chainTypeId: z.string().max(200).optional().default(\"strategy-coherence\")\n .describe(\"Process template slug for create: 'strategy-coherence', 'idm-proposal', or any custom template slug\"),\n description: z.string().max(20000).optional().describe(\"Description (for create)\"),\n linkId: z.string().max(200).optional().describe(\"Link to edit (for edit action): problem, insight, choice, action, outcome\"),\n content: z.string().max(50000).optional().describe(\"New content for the link (for edit action)\"),\n status: z.string().max(200).optional().describe(\"Filter by status for list: 'draft' or 'active'\"),\n author: z.string().max(200).optional().describe(\"Who is performing the action. Defaults to 'mcp'.\"),\n // WP-513 review round 3 (P1): team+role to create AS OWNER of (rung 2 only) — entry ID or entryId (e.g. \"TEAM-1\").\n ownerTeamEntryId: z.string().max(200).optional().describe(\"For 'create': owning team (rung-2 workspaces).\"),\n ownerRoleEntryId: z.string().max(200).optional().describe(\"For 'create': owning role (rung-2 workspaces).\"),\n});\n\nexport const chainVersionSchema = z.object({\n action: z.enum([\"commit\", \"list\", \"diff\", \"revert\", \"history\"])\n .describe(\"Action: commit a snapshot, list commits, diff two versions, revert to a version, or view history\"),\n chainEntryId: z.string().max(200).describe(\"The chain's entry ID\"),\n commitMessage: z.string().max(2000).optional()\n .describe(\"Commit message (required for commit). Convention: type(link): description\"),\n versionA: z.number().optional().describe(\"Earlier version for diff\"),\n versionB: z.number().optional().describe(\"Later version for diff\"),\n toVersion: z.number().optional().describe(\"Version number to revert to\"),\n author: z.string().max(200).optional().describe(\"Who is performing the action. Defaults to 'mcp'.\"),\n});\n\nexport const chainBranchSchema = z.object({\n action: z.enum([\"create\", \"list\", \"merge\", \"conflicts\"])\n .describe(\"Action: create a branch, list branches, merge a branch, or check for conflicts\"),\n chainEntryId: z.string().max(200).describe(\"The chain's entry ID\"),\n branchName: z.string().max(200).optional()\n .describe(\"Branch name (required for merge/conflicts, optional for create)\"),\n strategy: z.enum([\"merge_commit\", \"squash\"]).optional()\n .describe(\"Merge strategy: 'merge_commit' (default) or 'squash'\"),\n author: z.string().max(200).optional().describe(\"Who is performing the action. Defaults to 'mcp'.\"),\n});\n\nexport const chainReviewSchema = z.object({\n action: z.enum([\"gate\", \"comment\", \"resolve-comment\", \"list-comments\"])\n .describe(\"Action: run coherence gate, add a comment, resolve a comment, or list comments\"),\n // Finding #12: optional at the base (mirrors chainSchema's chainEntryId pattern at\n // line ~690) — resolve-comment resolves purely by commentId (handleChainReview never\n // reads chainEntryId in that branch) and the compound-tool's advertised schema\n // (chainReviewCompoundSchema below) already documents it as optional for that action.\n // Per-action variants that DO need it (gate/comment/list-comments) re-require it below,\n // same pattern as chainGetVariant/chainEditVariant re-requiring over chainSchema's base.\n chainEntryId: z.string().max(200).optional().describe(\"The chain's entry ID. Required for every action except 'resolve-comment'.\"),\n commitMessage: z.string().max(2000).optional()\n .describe(\"Commit message to lint (for gate action)\"),\n versionNumber: z.number().optional()\n .describe(\"Version to comment on or list comments for\"),\n linkId: z.string().max(200).optional()\n .describe(\"Link this comment targets (optional for comment)\"),\n body: z.string().max(20000).optional()\n .describe(\"Comment text (required for comment action)\"),\n commentId: z.string().max(200).optional()\n .describe(\"Comment ID (required for resolve-comment)\"),\n author: z.string().max(200).optional().describe(\"Who is performing the action. Defaults to 'mcp'.\"),\n});\n\n// Widened to `unknown` values — `gitchain.getChain`'s real `links` shape can carry a\n// structured `LinkData` object per slot, not just a plain string (PR #395, Lane C S3b\n// annotation pass). The body already guards with `typeof content === \"string\"`, so no\n// runtime behavior changes — only the parameter's declared type now matches reality.\nfunction linkSummary(links: Record<string, unknown>): string {\n return Object.entries(links)\n .map(([id, content]) => {\n const filled = typeof content === \"string\" && content.length > 0;\n const preview = filled\n ? content.substring(0, 80) + (content.length > 80 ? \"...\" : \"\")\n : \"(empty)\";\n return ` - **${id}**: ${preview}`;\n })\n .join(\"\\n\");\n}\n\n/**\n * WP-484 S2 (§3): extracted CRUD handler for the legacy `chain` tool —\n * reused by the legacy standalone registration AND the new module-gated\n * `chain` compound tool's unnamespaced create/get/list/edit actions\n * (absorbs chain-version/chain-branch/chain-review as namespaced actions,\n * §3 module-gated table). One business-logic path.\n */\nexport async function handleChainCrud({ action, chainEntryId, title, chainTypeId, description, linkId, content, status, author, ownerTeamEntryId, ownerRoleEntryId }: z.infer<typeof chainSchema>) {\n if (action === \"create\") {\n if (!title) {\n return validationResult(\"A `title` is required to create a process.\");\n }\n\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.createChain\">>(\n \"gitchain.createChain\",\n { title, chainTypeId, description, author, ownerTeamEntryId, ownerRoleEntryId }\n );\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Process Created\\n\\n` +\n `- **Entry ID:** \\`${result.entryId}\\`\\n` +\n `- **Title:** ${title}\\n` +\n `- **Type:** ${chainTypeId}\\n` +\n `- **Status:** draft\\n\\n` +\n `Use \\`chain action=edit chainEntryId=\"${result.entryId}\" linkId=\"problem\" content=\"...\"\\` to start filling in links.`,\n }],\n structuredContent: success(\n `Created process '${title}' (${result.entryId}), type: ${chainTypeId}.`,\n { entryId: result.entryId, title, chainTypeId, status: \"draft\" },\n [{ tool: \"chain\", description: \"Edit a link\", parameters: { action: \"edit\", chainEntryId: result.entryId, linkId: \"problem\" } }],\n ),\n };\n }\n\n if (action === \"get\") {\n if (!chainEntryId) {\n return validationResult(\"A `chainEntryId` is required.\");\n }\n\n const chain = await kernelQuery<GatewayRouteReturnByName<\"gitchain.getChain\">>(\"gitchain.getChain\", { chainEntryId });\n if (!chain) {\n return {\n content: [{ type: \"text\" as const, text: `Process \"${chainEntryId}\" not found.` }],\n structuredContent: failure(\n \"NOT_FOUND\",\n `Process \"${chainEntryId}\" not found.`,\n \"Use chain action=list to find available processes.\",\n [{ tool: \"chain\", description: \"List processes\", parameters: { action: \"list\" } }],\n ),\n };\n }\n\n const scoreSection = chain.scores\n ? `\\n## Coherence: ${chain.coherenceScore}%\\n\\n` +\n chain.scores.sections\n .map((s: any) => `- **${s.key}**: ${s.power}/100 (${\"★\".repeat(Math.min(s.stars ?? 0, 5))}${\"☆\".repeat(Math.max(0, 5 - (s.stars ?? 0)))})`)\n .join(\"\\n\")\n : \"\";\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# ${chain.name}\\n\\n` +\n `- **Entry ID:** \\`${chain.entryId}\\`\\n` +\n `- **Type:** ${chain.chainTypeName}\\n` +\n `- **Status:** ${chain.status}\\n` +\n `- **Links filled:** ${chain.filledCount}/${chain.totalCount}\\n` +\n `- **Version:** ${toVersionDisplay(chain.currentVersion)}\\n` +\n `- **Created by:** ${chain.createdBy ?? \"unknown\"}\\n` +\n `- **History events:** ${chain.historyCount}\\n` +\n scoreSection +\n `\\n\\n## Links\\n\\n` +\n linkSummary(chain.links),\n }],\n structuredContent: success(\n `${chain.name}: ${chain.filledCount}/${chain.totalCount} links, coherence ${chain.coherenceScore}%, ${toVersionDisplay(chain.currentVersion)}.`,\n { entryId: chain.entryId, name: chain.name, status: chain.status, filledCount: chain.filledCount, totalCount: chain.totalCount, coherenceScore: chain.coherenceScore, version: chain.currentVersion ?? null, versionDisplay: toVersionDisplay(chain.currentVersion) },\n ),\n };\n }\n\n if (action === \"list\") {\n const chains = await kernelQuery<any[]>(\"gitchain.listChains\", { chainTypeId, status });\n\n if (chains.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: \"No processes found. Use `chain action=create` to create one.\" }],\n structuredContent: success(\n \"No processes found.\",\n { chains: [], total: 0 },\n [{ tool: \"chain\", description: \"Create a process\", parameters: { action: \"create\" } }],\n ),\n };\n }\n\n const formatted = chains\n .map((c) =>\n `- **\\`${c.entryId}\\`** ${c.name} — ${c.chainTypeId} · ` +\n `${c.filledCount}/${c.totalCount} links · ` +\n `coherence: ${c.coherenceScore}% · status: ${c.status}`\n )\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text: `# Chains (${chains.length})\\n\\n${formatted}` }],\n structuredContent: success(\n `Found ${chains.length} process(es).`,\n { total: chains.length },\n ),\n };\n }\n\n if (action === \"edit\") {\n if (!chainEntryId) {\n return validationResult(\"A `chainEntryId` is required.\");\n }\n if (!linkId) {\n return validationResult(\"A `linkId` is required (e.g. problem, insight, choice, action, outcome).\");\n }\n if (!content) {\n return validationResult(\"The `content` for the link is required.\");\n }\n\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.editLink\">>(\"gitchain.editLink\", { chainEntryId, linkId, content, author });\n\n // Fix 3 (PR #605): a \"successful\" last-link save can silently stay 'draft' (strategy-link\n // hard floor, gitchain/mutations.ts's Fix C) — render the additive remedy so it's visible.\n const remedyBlock = result.strategyLinkRemedy ? `\\n\\n**Still draft:** ${result.strategyLinkRemedy}` : \"\";\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Link Updated\\n\\n- **Chain:** \\`${result.entryId}\\`\\n- **Link:** ${result.linkId}\\n- **Chain status:** ${result.status}\\n- **Content length:** ${content.length} chars${remedyBlock}\\n\\nUse \\`chain action=get\\` to see the full chain with updated scores.`,\n }],\n structuredContent: success(\n `Updated link \"${result.linkId}\" on ${result.entryId}. Status: ${result.status}.${result.strategyLinkRemedy ? ` ${result.strategyLinkRemedy}` : \"\"}`,\n { entryId: result.entryId, linkId: result.linkId, status: result.status, contentLength: content.length, ...(result.strategyLinkRemedy ? { strategyLinkRemedy: result.strategyLinkRemedy } : {}) },\n [{ tool: \"chain\", description: \"View full chain\", parameters: { action: \"get\", chainEntryId } }],\n ),\n };\n }\n\n return unknownAction(action, [\"create\", \"get\", \"list\", \"edit\"]);\n}\n\n/**\n * WP-484 S2 (§3): extracted version handler — reused by the legacy\n * `chain-version` tool AND the new `chain` compound tool's `version.*`\n * namespaced actions. One business-logic path.\n */\nexport async function handleChainVersion({ action, chainEntryId, commitMessage, versionA, versionB, toVersion, author }: z.infer<typeof chainVersionSchema>) {\n if (action === \"commit\") {\n if (!commitMessage) {\n return validationResult(\"A `commitMessage` is required.\");\n }\n\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.commitChain\">>(\"gitchain.commitChain\", { chainEntryId, commitMessage, author });\n\n const warning = result.commitLintWarning\n ? `\\n\\n> **Lint warning:** ${result.commitLintWarning}`\n : \"\";\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Committed v${result.version}\\n\\n` +\n `- **Chain:** \\`${result.entryId}\\`\\n` +\n `- **Version:** ${result.version}\\n` +\n `- **Message:** ${commitMessage}\\n` +\n `- **Coherence:** ${result.coherenceScore}%\\n` +\n `- **Links modified:** ${result.linksModified.length > 0 ? result.linksModified.join(\", \") : \"none\"}\\n` +\n warning,\n }],\n structuredContent: success(\n `Committed v${result.version} on ${result.entryId}. Coherence: ${result.coherenceScore}%.`,\n { entryId: result.entryId, version: result.version, versionDisplay: toVersionDisplay(result.version), coherenceScore: result.coherenceScore, linksModified: result.linksModified, lintWarning: result.commitLintWarning },\n ),\n };\n }\n\n if (action === \"list\") {\n const commits = await kernelQuery<any[]>(\"gitchain.listCommits\", { chainEntryId });\n\n if (commits.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: `No commits found for chain \"${chainEntryId}\". Use \\`chain action=version.commit\\` to create the first snapshot.` }],\n structuredContent: success(\n `No commits for ${chainEntryId}.`,\n { chainEntryId, commits: [], total: 0 },\n [{ tool: \"chain\", description: \"Commit chain\", parameters: { action: \"version.commit\", chainEntryId } }],\n ),\n };\n }\n\n const formatted = commits\n .map((c: any) => {\n const date = new Date(c.createdAt).toISOString().replace(\"T\", \" \").substring(0, 19);\n const msg = c.commitMessage ?? c.changeNote ?? \"(no message)\";\n const links = c.linksModified?.length > 0 ? ` [${c.linksModified.join(\", \")}]` : \"\";\n return `- **v${c.version}** ${date} by ${c.author} — ${msg}${links} (${c.versionStatus})`;\n })\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text: `# Commits for ${chainEntryId} (${commits.length})\\n\\n${formatted}` }],\n structuredContent: success(\n `${commits.length} commit(s) for ${chainEntryId}.`,\n { chainEntryId, total: commits.length },\n ),\n };\n }\n\n if (action === \"diff\") {\n if (versionA == null || versionB == null) {\n return validationResult(\"Both `versionA` and `versionB` are required for diff.\");\n }\n\n const diff = await kernelMutation<GatewayRouteReturnByName<\"gitchain.diffVersions\">>(\"gitchain.diffVersions\", { chainEntryId, versionA, versionB });\n\n let text =\n `# Diff: v${versionA} → v${versionB}\\n\\n` +\n `- **Chain:** \\`${diff.chainEntryId}\\`\\n` +\n `- **Coherence:** ${diff.coherenceBefore}% → ${diff.coherenceAfter}% (${diff.coherenceDelta >= 0 ? \"+\" : \"\"}${diff.coherenceDelta})\\n` +\n `- **Links changed:** ${diff.linksChanged.length > 0 ? diff.linksChanged.join(\", \") : \"none\"}\\n`;\n\n for (const ld of diff.linkDiffs) {\n if (ld.status === \"unchanged\") continue;\n text += `\\n## ${ld.linkId} (${ld.status})\\n\\n`;\n const wordDiff = diff.wordDiffs[ld.linkId];\n if (wordDiff?.length > 0) {\n for (const w of wordDiff) {\n if (w.type === \"delete\") text += `~~${w.value.substring(0, 200)}~~`;\n else if (w.type === \"insert\") text += `**${w.value.substring(0, 200)}**`;\n else text += w.value.substring(0, 200);\n }\n text += \"\\n\";\n }\n }\n\n return {\n content: [{ type: \"text\" as const, text }],\n structuredContent: success(\n `Diff v${versionA} → v${versionB}: coherence ${diff.coherenceBefore}% → ${diff.coherenceAfter}%, ${diff.linksChanged.length} link(s) changed.`,\n { chainEntryId: diff.chainEntryId, versionA, versionB, coherenceBefore: diff.coherenceBefore, coherenceAfter: diff.coherenceAfter, coherenceDelta: diff.coherenceDelta, linksChanged: diff.linksChanged },\n ),\n };\n }\n\n if (action === \"revert\") {\n if (toVersion == null) {\n return validationResult(\"A `toVersion` is required for revert.\");\n }\n\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.revertChain\">>(\"gitchain.revertChain\", { chainEntryId, toVersion, author });\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Reverted\\n\\n` +\n `- **Chain:** \\`${result.entryId}\\`\\n` +\n `- **Reverted to:** v${result.revertedTo}\\n` +\n `- **New version:** v${result.newVersion}\\n` +\n `- **Links affected:** ${result.linksModified.length > 0 ? result.linksModified.join(\", \") : \"none\"}\\n\\n` +\n `History is preserved — this created a new version, not a destructive reset.`,\n }],\n structuredContent: success(\n `Reverted ${result.entryId} to v${result.revertedTo}. New version: v${result.newVersion}.`,\n { entryId: result.entryId, revertedTo: result.revertedTo, revertedToDisplay: toVersionDisplay(result.revertedTo), newVersion: result.newVersion, newVersionDisplay: toVersionDisplay(result.newVersion), linksModified: result.linksModified },\n ),\n };\n }\n\n if (action === \"history\") {\n const history = await kernelQuery<any[]>(\"gitchain.getHistory\", { chainEntryId });\n\n if (history.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: `No history found for chain \"${chainEntryId}\".` }],\n structuredContent: success(\n `No history for ${chainEntryId}.`,\n { chainEntryId, events: [], total: 0 },\n ),\n };\n }\n\n const formatted = history\n .sort((a: any, b: any) => b.timestamp - a.timestamp)\n .map((h: any) => {\n const date = new Date(h.timestamp).toISOString().replace(\"T\", \" \").substring(0, 19);\n return `- **${date}** [${h.event}] by ${h.changedBy ?? \"unknown\"} — ${h.note ?? \"\"}`;\n })\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text: `# History for ${chainEntryId} (${history.length} events)\\n\\n${formatted}` }],\n structuredContent: success(\n `${history.length} history event(s) for ${chainEntryId}.`,\n { chainEntryId, total: history.length },\n ),\n };\n }\n\n return unknownAction(action, [\"commit\", \"list\", \"diff\", \"revert\", \"history\"]);\n}\n\n/**\n * WP-484 S2 (§3): extracted branch handler — reused by the legacy\n * `chain-branch` tool AND the new `chain` compound tool's `branch.*`\n * namespaced actions. One business-logic path.\n */\nexport async function handleChainBranch({ action, chainEntryId, branchName, strategy, author }: z.infer<typeof chainBranchSchema>) {\n if (action === \"create\") {\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.createBranch\">>(\"gitchain.createBranch\", { chainEntryId, name: branchName, author });\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Branch Created\\n\\n` +\n `- **Name:** ${result.name}\\n` +\n `- **Based on:** v${result.baseVersion}\\n` +\n `- **Chain:** \\`${chainEntryId}\\`\\n\\n` +\n `Edit links and commit on this branch, then use \\`chain-review action=branch.merge\\` to land changes.`,\n }],\n structuredContent: success(\n `Created branch \"${result.name}\" based on v${result.baseVersion}.`,\n { branchId: result.branchId, name: result.name, baseVersion: result.baseVersion, chainEntryId },\n [{ tool: \"chain-review\", description: \"Merge branch\", parameters: { action: \"branch.merge\", chainEntryId, branchName: result.name } }],\n ),\n };\n }\n\n if (action === \"list\") {\n const branches = await kernelMutation<any[]>(\"gitchain.listBranches\", { chainEntryId });\n\n if (branches.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: `No branches found for chain \"${chainEntryId}\".` }],\n structuredContent: success(\n `No branches for ${chainEntryId}.`,\n { chainEntryId, branches: [], total: 0 },\n [{ tool: \"chain-review\", description: \"Create a branch\", parameters: { action: \"branch.create\", chainEntryId } }],\n ),\n };\n }\n\n const formatted = branches\n .map((b: any) => `- **${b.name}** (${b.status}) — based on v${b.baseVersion}, by ${b.createdBy}`)\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text: `# Branches for ${chainEntryId} (${branches.length})\\n\\n${formatted}` }],\n structuredContent: success(\n `${branches.length} branch(es) for ${chainEntryId}.`,\n { chainEntryId, total: branches.length },\n ),\n };\n }\n\n if (action === \"merge\") {\n if (!branchName) {\n return validationResult(\"A `branchName` is required for merge.\");\n }\n\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.mergeBranch\">>(\"gitchain.mergeBranch\", { chainEntryId, branchName, strategy, author });\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Branch Merged\\n\\n` +\n `- **Chain:** \\`${result.entryId}\\`\\n` +\n `- **Branch:** ${result.branchName} (now closed)\\n` +\n `- **Version:** v${result.version}\\n` +\n `- **Strategy:** ${result.strategy}\\n\\n` +\n `Main is now at v${result.version}. The branch has been closed.`,\n }],\n structuredContent: success(\n `Merged branch \"${result.branchName}\" into ${result.entryId} at v${result.version}.`,\n { entryId: result.entryId, branchName: result.branchName, version: result.version, versionDisplay: toVersionDisplay(result.version), strategy: result.strategy },\n ),\n };\n }\n\n if (action === \"conflicts\") {\n if (!branchName) {\n return validationResult(\"A `branchName` is required for conflict check.\");\n }\n\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.checkConflicts\">>(\"gitchain.checkConflicts\", { chainEntryId, branchName });\n\n if (!result.hasConflicts) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# No Conflicts\\n\\nBranch \"${branchName}\" on \\`${chainEntryId}\\` has no conflicts. Safe to merge.`,\n }],\n structuredContent: success(\n `No conflicts on branch \"${branchName}\". Safe to merge.`,\n { chainEntryId, branchName, hasConflicts: false },\n [{ tool: \"chain-review\", description: \"Merge branch\", parameters: { action: \"branch.merge\", chainEntryId, branchName } }],\n ),\n };\n }\n\n const conflictLines = result.conflicts\n .map((c: any) =>\n `- **${c.linkId}** — modified by: ${c.branches.map((b: any) => `${b.branchName} (${b.author})`).join(\", \")}`\n )\n .join(\"\\n\");\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Conflicts Detected\\n\\n` +\n `Branch \"${branchName}\" conflicts with other branches on these links:\\n\\n` +\n conflictLines +\n `\\n\\nResolve conflicts before merging.`,\n }],\n structuredContent: failure(\n \"CONFLICT\",\n `Branch \"${branchName}\" has ${result.conflicts.length} conflict(s).`,\n \"Resolve conflicts on the conflicting links before merging.\",\n ),\n };\n }\n\n return unknownAction(action, [\"create\", \"list\", \"merge\", \"conflicts\"]);\n}\n\n/**\n * WP-484 S2 (§3): extracted review handler — reused by the legacy\n * `chain-review` tool AND the new `chain` compound tool's `review.*`\n * namespaced actions. One business-logic path.\n */\nexport async function handleChainReview({ action, chainEntryId, commitMessage, versionNumber, linkId, body, commentId, author }: z.infer<typeof chainReviewSchema>) {\n if (action === \"gate\") {\n const gate = await kernelQuery<GatewayRouteReturnByName<\"gitchain.runGate\">>(\"gitchain.runGate\", { chainEntryId, commitMessage });\n\n const checkLines = gate.checks\n .map((c: any) => `- ${c.pass ? \"PASS\" : \"FAIL\"} **${c.name}**: ${c.detail}`)\n .join(\"\\n\");\n\n const icon = gate.pass ? \"PASS\" : \"BLOCKED\";\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Gate: ${icon}\\n\\n` +\n `- **Score:** ${gate.score}%\\n` +\n `- **Threshold:** ${gate.threshold}%\\n\\n` +\n `## Checks\\n\\n${checkLines}`,\n }],\n structuredContent: success(\n `Gate ${icon}: ${gate.score}% (threshold ${gate.threshold}%).`,\n { pass: gate.pass, score: gate.score, threshold: gate.threshold, checks: gate.checks },\n ),\n };\n }\n\n if (action === \"comment\") {\n if (!versionNumber) {\n return validationResult(\"A `versionNumber` is required.\");\n }\n if (!body) {\n return validationResult(\"A `body` is required.\");\n }\n\n const result = await kernelMutation<GatewayRouteReturnByName<\"gitchain.addComment\">>(\"gitchain.addComment\", {\n chainEntryId, versionNumber, linkId, body, author,\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text:\n `# Comment Added\\n\\n` +\n `- **Chain:** \\`${result.chainEntryId}\\`\\n` +\n `- **Version:** v${result.versionNumber}\\n` +\n (result.linkId ? `- **Link:** ${result.linkId}\\n` : \"\") +\n `- **Body:** ${body.substring(0, 200)}`,\n }],\n structuredContent: success(\n `Comment added on ${result.chainEntryId} v${result.versionNumber}${result.linkId ? ` [${result.linkId}]` : \"\"}.`,\n { chainEntryId: result.chainEntryId, versionNumber: result.versionNumber, linkId: result.linkId },\n ),\n };\n }\n\n if (action === \"resolve-comment\") {\n if (!commentId) {\n return validationResult(\"A `commentId` is required.\");\n }\n await kernelMutation<GatewayRouteReturnByName<\"gitchain.resolveComment\">>(\"gitchain.resolveComment\", { commentId });\n return successResult(\"Comment resolved.\", `Comment ${commentId} resolved.`, { commentId, resolved: true });\n }\n\n if (action === \"list-comments\") {\n const comments = await kernelMutation<GatewayRouteReturnByName<\"gitchain.listComments\">>(\"gitchain.listComments\", {\n chainEntryId, versionNumber,\n });\n\n if (comments.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: `No comments found for chain \"${chainEntryId}\"${versionNumber ? ` v${versionNumber}` : \"\"}.` }],\n structuredContent: success(\n `No comments for ${chainEntryId}${versionNumber ? ` v${versionNumber}` : \"\"}.`,\n { chainEntryId, comments: [], total: 0, unresolved: 0 },\n ),\n };\n }\n\n const formatted = comments\n .map((c: any) => {\n const date = new Date(c.createdAt).toISOString().replace(\"T\", \" \").substring(0, 19);\n const resolved = c.resolved ? \" (RESOLVED)\" : \"\";\n const link = c.linkId ? ` [${c.linkId}]` : \"\";\n return `- **v${c.version}${link}** ${date} by ${c.author}${resolved}: ${c.body.substring(0, 150)}`;\n })\n .join(\"\\n\");\n\n const unresolvedCount = comments.filter((c: any) => !c.resolved).length;\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Comments for ${chainEntryId} (${comments.length}, ${unresolvedCount} unresolved)\\n\\n${formatted}`,\n }],\n structuredContent: success(\n `${comments.length} comment(s) for ${chainEntryId}, ${unresolvedCount} unresolved.`,\n { chainEntryId, total: comments.length, unresolved: unresolvedCount },\n ),\n };\n }\n\n return unknownAction(action, [\"gate\", \"comment\", \"resolve-comment\", \"list-comments\"]);\n}\n\n// ─── `chain` + `chain-review` compound tools (WP-484 S2, §3 module-gated\n// table — SPLIT per coordinator ruling 2026-07-15) ──────────────────────────\n// The §3 per-noun ≤12-action ceiling applies with NO module-gated carve-out\n// (\"a noun that would exceed 12 must split or shed scope\"). A single `chain`\n// noun absorbing everything would be 17 actions; the ruled fix is a split at\n// the namespace seam. The coordinator's first-preference seam (base+version+\n// branch in `chain`, review.* separate) still lands at 13 > 12, so the chosen\n// seam is the fewest-tools arrangement with every tool ≤12:\n// - `chain` = base CRUD (4) + version.* (5) → 9 actions\n// - `chain-review` = legacy review actions, unnamespaced (4)\n// + branch.* (4) → 8 actions\n// Both names are REUSED (not \"alongside\"-eligible); `chain-review` keeps its\n// legacy action vocabulary verbatim (gate/comment/resolve-comment/\n// list-comments), so pre-S2 `chain-review` calls keep working unchanged.\n// WP-484 S3 (clean break, TEN-2157): the legacy `chain-version` and\n// `chain-branch` standalone registrations retired below — their handlers\n// (handleChainVersion / handleChainBranch) stay live via `chain`\n// action=version.* and `chain-review` action=branch.*. Module-gated worst\n// case is therefore 15 registered tools (13 core + chain + chain-review) —\n// 11 core + feedback (DEC-1473) + shape (WP-559) + question (WP-638 S3).\nconst CHAIN_ACTIONS = [\n \"create\", \"get\", \"list\", \"edit\",\n \"version.commit\", \"version.list\", \"version.diff\", \"version.revert\", \"version.history\",\n] as const;\ntype ChainAction = (typeof CHAIN_ACTIONS)[number];\n\nconst CHAIN_REVIEW_ACTIONS = [\n \"gate\", \"comment\", \"resolve-comment\", \"list-comments\",\n \"branch.create\", \"branch.list\", \"branch.merge\", \"branch.conflicts\",\n] as const;\ntype ChainReviewAction = (typeof CHAIN_REVIEW_ACTIONS)[number];\n\n// §3a — the REGISTERED layer for `chain`: flat ZodObject, action enum +\n// superset of params (deduped across chainSchema/chainVersionSchema).\nexport const chainCompoundSchema = z.object({\n action: z.enum(CHAIN_ACTIONS).describe(\n \"Unnamespaced: 'create'/'get'/'list'/'edit' — process CRUD (the original `chain` tool). \" +\n \"'version.*' (commit/list/diff/revert/history) — versioning, absorbs `chain-version`. \" +\n \"Branching and review live on the sibling `chain-review` tool.\",\n ),\n chainEntryId: z.string().max(200).optional().describe(\"Chain entry ID. Required for get/edit and all version.* actions.\"),\n title: z.string().max(500).optional().describe(\"For 'create': process title (required).\"),\n chainTypeId: z.string().max(200).optional().default(\"strategy-coherence\").describe(\"For 'create'/'list': process template slug.\"),\n description: z.string().max(20000).optional().describe(\"For 'create': description.\"),\n linkId: z.string().max(200).optional().describe(\"For 'edit': link to edit (required).\"),\n content: z.string().max(50000).optional().describe(\"For 'edit': new content for the link (required).\"),\n status: z.string().max(200).optional().describe(\"For 'list': filter by status.\"),\n author: z.string().max(200).optional().describe(\"Who is performing the action. Defaults to 'mcp'.\"),\n commitMessage: z.string().max(2000).optional().describe(\"For 'version.commit': commit message (required).\"),\n versionA: z.number().optional().describe(\"For 'version.diff': earlier version (required).\"),\n versionB: z.number().optional().describe(\"For 'version.diff': later version (required).\"),\n toVersion: z.number().optional().describe(\"For 'version.revert': version number to revert to (required).\"),\n // WP-513 review round 3 (P1): team+role to create AS OWNER of (rung 2 only).\n ownerTeamEntryId: z.string().max(200).optional().describe(\"For 'create': owning team (rung-2 workspaces).\"),\n ownerRoleEntryId: z.string().max(200).optional().describe(\"For 'create': owning role (rung-2 workspaces).\"),\n});\n\n// §3a — the REGISTERED layer for `chain-review`: legacy review vocabulary\n// unnamespaced (pre-S2 call-shape preserved) + branch.* namespaced.\nexport const chainReviewCompoundSchema = z.object({\n action: z.enum(CHAIN_REVIEW_ACTIONS).describe(\n \"'gate'/'comment'/'resolve-comment'/'list-comments' — quality gate + comments (the original `chain-review` tool, unchanged call shape). \" +\n \"'branch.*' (create/list/merge/conflicts) — branching, absorbs `chain-branch`. \" +\n \"Process CRUD and versioning live on the sibling `chain` tool.\",\n ),\n chainEntryId: z.string().max(200).optional().describe(\"Chain entry ID. Required for every action except 'resolve-comment'.\"),\n commitMessage: z.string().max(2000).optional().describe(\"For 'gate': commit message to lint.\"),\n versionNumber: z.number().optional().describe(\"For 'comment'/'list-comments': version to comment on or list comments for.\"),\n linkId: z.string().max(200).optional().describe(\"For 'comment': optional link this comment targets.\"),\n body: z.string().max(20000).optional().describe(\"For 'comment': comment text (required).\"),\n commentId: z.string().max(200).optional().describe(\"For 'resolve-comment': comment ID (required).\"),\n branchName: z.string().max(200).optional().describe(\"For 'branch.merge'/'branch.conflicts': required. For 'branch.create': optional.\"),\n strategy: z.enum([\"merge_commit\", \"squash\"]).optional().describe(\"For 'branch.merge': merge strategy. Default 'merge_commit'.\"),\n author: z.string().max(200).optional().describe(\"Who is performing the action. Defaults to 'mcp'.\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnions, reusing the\n// existing legacy schemas (Code Integrity) via `.omit({action:true}).extend(...)`.\nconst chainCreateVariant = chainSchema.omit({ action: true }).extend({ action: z.literal(\"create\") });\nconst chainGetVariant = z.object({ action: z.literal(\"get\"), chainEntryId: z.string().max(200) });\nconst chainListVariant = z.object({ action: z.literal(\"list\"), chainTypeId: z.string().max(200).optional(), status: z.string().max(200).optional() });\nconst chainEditVariant = z.object({\n action: z.literal(\"edit\"),\n chainEntryId: z.string().max(200),\n linkId: z.string().max(200),\n content: z.string().max(50000),\n author: z.string().max(200).optional(),\n});\nconst versionBase = chainVersionSchema.omit({ action: true });\nconst chainVersionCommitVariant = versionBase.extend({ action: z.literal(\"version.commit\"), commitMessage: z.string().max(2000) });\nconst chainVersionListVariant = versionBase.extend({ action: z.literal(\"version.list\") });\nconst chainVersionDiffVariant = versionBase.extend({ action: z.literal(\"version.diff\"), versionA: z.number(), versionB: z.number() });\nconst chainVersionRevertVariant = versionBase.extend({ action: z.literal(\"version.revert\"), toVersion: z.number() });\nconst chainVersionHistoryVariant = versionBase.extend({ action: z.literal(\"version.history\") });\n\nexport const chainActionUnion = z.discriminatedUnion(\"action\", [\n chainCreateVariant,\n chainGetVariant,\n chainListVariant,\n chainEditVariant,\n chainVersionCommitVariant,\n chainVersionListVariant,\n chainVersionDiffVariant,\n chainVersionRevertVariant,\n chainVersionHistoryVariant,\n]);\n\nconst reviewBase = chainReviewSchema.omit({ action: true });\n// gate/comment/list-comments re-require chainEntryId over reviewBase's optional field\n// (finding #12) — only resolve-comment (handleChainReview's commentId-only branch)\n// leaves it optional.\nconst chainReviewGateVariant = reviewBase.extend({ action: z.literal(\"gate\"), chainEntryId: z.string().max(200) });\nconst chainReviewCommentVariant = reviewBase.extend({ action: z.literal(\"comment\"), chainEntryId: z.string().max(200), versionNumber: z.number(), body: z.string().max(20000) });\nconst chainReviewResolveCommentVariant = reviewBase.extend({ action: z.literal(\"resolve-comment\"), commentId: z.string().max(200) });\nconst chainReviewListCommentsVariant = reviewBase.extend({ action: z.literal(\"list-comments\"), chainEntryId: z.string().max(200) });\nconst branchBase = chainBranchSchema.omit({ action: true });\nconst chainBranchCreateVariant = branchBase.extend({ action: z.literal(\"branch.create\") });\nconst chainBranchListVariant = branchBase.extend({ action: z.literal(\"branch.list\") });\nconst chainBranchMergeVariant = branchBase.extend({ action: z.literal(\"branch.merge\"), branchName: z.string().max(200) });\nconst chainBranchConflictsVariant = branchBase.extend({ action: z.literal(\"branch.conflicts\"), branchName: z.string().max(200) });\n\nexport const chainReviewActionUnion = z.discriminatedUnion(\"action\", [\n chainReviewGateVariant,\n chainReviewCommentVariant,\n chainReviewResolveCommentVariant,\n chainReviewListCommentsVariant,\n chainBranchCreateVariant,\n chainBranchListVariant,\n chainBranchMergeVariant,\n chainBranchConflictsVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const CHAIN_ACTION_SPECS: Record<ChainAction, ActionParamSpec> = {\n create: { params: [\"title\", \"chainTypeId\", \"description\", \"author\", \"ownerTeamEntryId\", \"ownerRoleEntryId\"], description: \"title is required.\" },\n get: { params: [\"chainEntryId\"], description: \"chainEntryId is required.\" },\n list: { params: [\"chainTypeId\", \"status\"], description: \"All params optional.\" },\n edit: { params: [\"chainEntryId\", \"linkId\", \"content\", \"author\"], description: \"chainEntryId, linkId, and content are required.\" },\n \"version.commit\": { params: [\"chainEntryId\", \"commitMessage\", \"author\"], description: \"chainEntryId and commitMessage are required.\" },\n \"version.list\": { params: [\"chainEntryId\"], description: \"chainEntryId is required.\" },\n \"version.diff\": { params: [\"chainEntryId\", \"versionA\", \"versionB\"], description: \"chainEntryId, versionA, and versionB are required.\" },\n \"version.revert\": { params: [\"chainEntryId\", \"toVersion\", \"author\"], description: \"chainEntryId and toVersion are required.\" },\n \"version.history\": { params: [\"chainEntryId\"], description: \"chainEntryId is required.\" },\n};\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const CHAIN_REVIEW_ACTION_SPECS: Record<ChainReviewAction, ActionParamSpec> = {\n gate: { params: [\"chainEntryId\", \"commitMessage\"], description: \"chainEntryId is required.\" },\n comment: { params: [\"chainEntryId\", \"versionNumber\", \"linkId\", \"body\", \"author\"], description: \"chainEntryId, versionNumber, and body are required.\" },\n \"resolve-comment\": { params: [\"commentId\"], description: \"commentId is required.\" },\n \"list-comments\": { params: [\"chainEntryId\", \"versionNumber\"], description: \"chainEntryId is required.\" },\n \"branch.create\": { params: [\"chainEntryId\", \"branchName\", \"author\"], description: \"chainEntryId is required.\" },\n \"branch.list\": { params: [\"chainEntryId\"], description: \"chainEntryId is required.\" },\n \"branch.merge\": { params: [\"chainEntryId\", \"branchName\", \"strategy\", \"author\"], description: \"chainEntryId and branchName are required.\" },\n \"branch.conflicts\": { params: [\"chainEntryId\", \"branchName\"], description: \"chainEntryId and branchName are required.\" },\n};\n\nexport function registerGitChainTools(server: McpServer) {\n // §3b handler map for `chain` — strips the namespace prefix and\n // reconstructs the original legacy-schema action value before delegating\n // to the shared handler (handleChainCrud/handleChainVersion).\n const chainHandlers: Record<ChainAction, (data: any) => Promise<ToolResult>> = {\n create: (data) => handleChainCrud({ ...data, action: \"create\" }),\n get: (data) => handleChainCrud({ ...data, action: \"get\" }),\n list: (data) => handleChainCrud({ ...data, action: \"list\" }),\n edit: (data) => handleChainCrud({ ...data, action: \"edit\" }),\n \"version.commit\": (data) => handleChainVersion({ ...data, action: \"commit\" }),\n \"version.list\": (data) => handleChainVersion({ ...data, action: \"list\" }),\n \"version.diff\": (data) => handleChainVersion({ ...data, action: \"diff\" }),\n \"version.revert\": (data) => handleChainVersion({ ...data, action: \"revert\" }),\n \"version.history\": (data) => handleChainVersion({ ...data, action: \"history\" }),\n };\n\n // §3b handler map for `chain-review` — the four unnamespaced actions ARE\n // the legacy vocabulary (pass through verbatim); branch.* strips the prefix\n // before delegating to handleChainBranch.\n const chainReviewHandlers: Record<ChainReviewAction, (data: any) => Promise<ToolResult>> = {\n gate: (data) => handleChainReview({ ...data, action: \"gate\" }),\n comment: (data) => handleChainReview({ ...data, action: \"comment\" }),\n \"resolve-comment\": (data) => handleChainReview({ ...data, action: \"resolve-comment\" }),\n \"list-comments\": (data) => handleChainReview({ ...data, action: \"list-comments\" }),\n \"branch.create\": (data) => handleChainBranch({ ...data, action: \"create\" }),\n \"branch.list\": (data) => handleChainBranch({ ...data, action: \"list\" }),\n \"branch.merge\": (data) => handleChainBranch({ ...data, action: \"merge\" }),\n \"branch.conflicts\": (data) => handleChainBranch({ ...data, action: \"conflicts\" }),\n };\n\n server.registerTool(\n \"chain\",\n {\n title: \"Chain\",\n description:\n \"Manage processes — CRUD and versioning. Processes are versioned knowledge \" +\n \"artifacts that follow a process template (e.g. Strategy Coherence: Problem → Insight → Choice → \" +\n \"Action → Outcome). Module-gated (PB_MODULES=gitchain).\\n\\n\" +\n \"- **create/get/list/edit**: process CRUD.\\n\" +\n \"- **version.commit/version.list/version.diff/version.revert/version.history**: versioning (absorbs `chain-version`).\\n\\n\" +\n \"Branching and review live on the sibling `chain-review` tool.\",\n inputSchema: chainCompoundSchema,\n annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(chainCompoundSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"chain\", action }, () =>\n dispatchDiscriminated(\"chain\", chainActionUnion, parsed.data, CHAIN_ACTION_SPECS, chainHandlers),\n );\n }),\n );\n\n server.registerTool(\n \"chain-review\",\n {\n title: \"Chain Review\",\n description:\n \"Review process quality and manage branches. Module-gated (PB_MODULES=gitchain).\\n\\n\" +\n \"- **gate**: run the coherence gate — checks coherence score >= 70%, all links filled, commit message convention.\\n\" +\n \"- **comment/resolve-comment/list-comments**: manage comments on process versions.\\n\" +\n \"- **branch.create/branch.list/branch.merge/branch.conflicts**: branching (absorbs `chain-branch`).\\n\\n\" +\n \"Process CRUD and versioning live on the sibling `chain` tool.\",\n inputSchema: chainReviewCompoundSchema,\n annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(chainReviewCompoundSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"chain-review\", action }, () =>\n dispatchDiscriminated(\"chain-review\", chainReviewActionUnion, parsed.data, CHAIN_REVIEW_ACTION_SPECS, chainReviewHandlers),\n );\n }),\n );\n\n // WP-484 S3 (clean break, TEN-2157): the standalone `chain-version` and\n // `chain-branch` registrations retired here. handleChainVersion /\n // handleChainBranch stay live via `chain` action=version.* and\n // `chain-review` action=branch.* (chainHandlers / chainReviewHandlers,\n // above).\n}\n","/**\n * versionDisplay — human-readable version string for MCP responses (BET-112, FEAT-287, STD-60)\n *\n * Agents receive versionDisplay ('Draft' or 'vN') alongside raw version (number | null)\n * so they don't assume version is always a number. Drafts have no committed version.\n */\n\n/**\n * Returns 'Draft' when version is null, undefined, or 0 (no commits yet).\n * Returns 'vN' for committed versions (1, 2, 3, ...).\n */\nexport function toVersionDisplay(version: number | null | undefined): string {\n if (version == null || version === 0) return \"Draft\";\n return `v${version}`;\n}\n","/**\n * Workspace compound tool — WP-484 S2 (§3, new noun).\n *\n * Absorbs `health` (check/whoami/status/audit/self-test), `get-usage-summary`\n * → usage, and `governance-proposals` → proposals-list/proposals-respond/\n * proposals-count. This is the one genuinely NEW name in S2 — every other\n * core noun reuses an existing name (§7 S2 note). Legacy `health`,\n * `get-usage-summary`, and `governance-proposals` tools stay registered\n * alongside (§7 \"alongside\" mechanic) — all call the SAME handler functions,\n * one business-logic path per action.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { thinWrapper, parseOrFail, type ToolResult } from \"../envelope.js\";\nimport { runWithToolContext } from \"../client.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { handleHealthCheck, handleWhoami, handleWorkspaceStatus, handleAudit, handleSelfTest } from \"./health.js\";\nimport { handleUsageSummary } from \"./usage.js\";\nimport { handleProposalsList, handleProposalsCount, handleProposalsRespond } from \"./governance.js\";\n\nconst WORKSPACE_ACTIONS = [\n \"check\", \"whoami\", \"status\", \"audit\", \"self-test\",\n \"usage\", \"proposals-list\", \"proposals-respond\", \"proposals-count\",\n] as const;\ntype WorkspaceAction = (typeof WORKSPACE_ACTIONS)[number];\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const workspaceSchema = z.object({\n action: z.enum(WORKSPACE_ACTIONS).describe(\n \"'check': connectivity and workspace stats (absorbs health action=check). \" +\n \"'whoami': session identity (absorbs health action=whoami). \" +\n \"'status': workspace readiness (absorbs health action=status). \" +\n \"'audit': session audit log (absorbs health action=audit). \" +\n \"'self-test': validate all tool schemas (absorbs health action=self-test). \" +\n \"'usage': LLM usage and cost summary (absorbs get-usage-summary). \" +\n \"'proposals-list': list open consent proposals (absorbs governance-proposals action=list). \" +\n \"'proposals-respond': approve/reject a consent proposal (absorbs governance-proposals action=respond). \" +\n \"'proposals-count': count open consent proposals (absorbs governance-proposals action=count).\",\n ),\n limit: z.number().min(1).max(50).optional().describe(\"For 'audit': how many recent calls to show (max 50, default 20).\"),\n periodDays: z.number().min(1).max(90).optional().describe(\"For 'usage': number of days to look back (default 30, max 90).\"),\n status: z.enum([\"open\", \"approved\", \"objected\", \"expired\"]).optional().describe(\"For 'proposals-list': filter by status (default: open).\"),\n proposalId: z.string().max(200).optional().describe(\"For 'proposals-respond': proposal ID.\"),\n verdict: z.enum([\"approve\", \"reject\"]).optional().describe(\"For 'proposals-respond': approve or reject.\"),\n reason: z.string().max(2000).optional().describe(\"For 'proposals-respond': reason for the verdict (required when rejecting).\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion.\nconst workspaceCheckVariant = z.object({ action: z.literal(\"check\") });\nconst workspaceWhoamiVariant = z.object({ action: z.literal(\"whoami\") });\nconst workspaceStatusVariant = z.object({ action: z.literal(\"status\") });\nconst workspaceAuditVariant = z.object({ action: z.literal(\"audit\"), limit: z.number().min(1).max(50).optional().default(20) });\nconst workspaceSelfTestVariant = z.object({ action: z.literal(\"self-test\") });\nconst workspaceUsageVariant = z.object({ action: z.literal(\"usage\"), periodDays: z.number().min(1).max(90).optional() });\nconst workspaceProposalsListVariant = z.object({\n action: z.literal(\"proposals-list\"),\n status: z.enum([\"open\", \"approved\", \"objected\", \"expired\"]).optional(),\n});\nconst workspaceProposalsRespondVariant = z.object({\n action: z.literal(\"proposals-respond\"),\n proposalId: z.string().max(200),\n verdict: z.enum([\"approve\", \"reject\"]),\n reason: z.string().max(2000).optional(),\n});\nconst workspaceProposalsCountVariant = z.object({ action: z.literal(\"proposals-count\") });\n\nexport const workspaceActionUnion = z.discriminatedUnion(\"action\", [\n workspaceCheckVariant,\n workspaceWhoamiVariant,\n workspaceStatusVariant,\n workspaceAuditVariant,\n workspaceSelfTestVariant,\n workspaceUsageVariant,\n workspaceProposalsListVariant,\n workspaceProposalsRespondVariant,\n workspaceProposalsCountVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const WORKSPACE_ACTION_SPECS: Record<WorkspaceAction, ActionParamSpec> = {\n check: { params: [], description: \"Verify connectivity; no params.\" },\n whoami: { params: [], description: \"Session identity; no params.\" },\n status: { params: [], description: \"Workspace readiness; no params.\" },\n audit: { params: [\"limit\"], description: \"limit is optional (default 20, max 50).\" },\n \"self-test\": { params: [], description: \"Validate all tool schemas; no params.\" },\n usage: { params: [\"periodDays\"], description: \"periodDays is optional (default 30, max 90).\" },\n \"proposals-list\": { params: [\"status\"], description: \"status is optional (default 'open').\" },\n \"proposals-respond\": { params: [\"proposalId\", \"verdict\", \"reason\"], description: \"proposalId and verdict are required; reason is required when rejecting.\" },\n \"proposals-count\": { params: [], description: \"Count open proposals; no params.\" },\n};\n\nexport function registerWorkspaceTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const workspaceHandlers: Record<WorkspaceAction, (data: any) => Promise<ToolResult>> = {\n check: () => handleHealthCheck(),\n whoami: () => handleWhoami(),\n status: () => handleWorkspaceStatus(),\n audit: (data) => handleAudit(data.limit ?? 20),\n \"self-test\": () => Promise.resolve(handleSelfTest(server)),\n usage: (data) => handleUsageSummary(data.periodDays),\n \"proposals-list\": (data) => handleProposalsList(data.status),\n \"proposals-respond\": (data) => handleProposalsRespond(data.proposalId, data.verdict, data.reason),\n \"proposals-count\": () => handleProposalsCount(),\n };\n\n server.registerTool(\n \"workspace\",\n {\n title: \"Workspace\",\n description:\n \"Diagnostics, session identity, usage, and governance proposals for the current workspace. Nine actions:\\n\\n\" +\n \"- **check**: Verify connectivity — workspace, collections, entries, latency.\\n\" +\n \"- **whoami**: Session identity — workspace ID, slug, name.\\n\" +\n \"- **status**: Workspace readiness — score, gaps, stats (entries, relations, orphans).\\n\" +\n \"- **audit**: Session audit log — last N backend calls with summary.\\n\" +\n \"- **self-test**: Validate all registered tool schemas.\\n\" +\n \"- **usage**: LLM usage and cost summary — spend, tokens, model/feature breakdown (absorbs `get-usage-summary`).\\n\" +\n \"- **proposals-list**: List open consent proposals awaiting review (absorbs `governance-proposals` action=list).\\n\" +\n \"- **proposals-respond**: Approve or reject a consent proposal (absorbs `governance-proposals` action=respond).\\n\" +\n \"- **proposals-count**: Count open consent proposals for badge/notification display (absorbs `governance-proposals` action=count).\",\n inputSchema: workspaceSchema,\n // Mixed read/write noun (§3 R3): proposals-respond writes; every other action reads.\n annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(workspaceSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"workspace\", action }, () =>\n dispatchDiscriminated(\"workspace\", workspaceActionUnion, parsed.data, WORKSPACE_ACTION_SPECS, workspaceHandlers),\n );\n }),\n );\n}\n","import type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z, type ZodTypeAny } from \"zod/v3\";\nimport { kernelQuery, getWorkspaceId, getWorkspaceContext, getAgentSessionId, getApiKeyScope, isSessionOriented, type AuditEntry } from \"../client.js\";\nimport { success, successResult } from \"../envelope.js\";\nimport { buildTenantAuditView } from \"../lib/auditView.js\";\n\ntype CallCategory = \"read\" | \"search\" | \"write\" | \"label\" | \"meta\";\n\nconst CALL_CATEGORIES: Record<string, CallCategory> = {\n \"chain.getEntry\": \"read\",\n \"chain.batchGetEntries\": \"read\",\n \"chain.listEntries\": \"read\",\n \"chain.listEntryHistory\": \"read\",\n \"chain.listEntryRelations\": \"read\",\n \"chain.listEntriesByLabel\": \"read\",\n \"chain.searchEntries\": \"search\",\n \"chain.createEntry\": \"write\",\n \"chain.updateEntry\": \"write\",\n \"chain.moveToCollection\": \"write\",\n \"chain.createEntryRelation\": \"write\",\n \"chain.applyLabel\": \"label\",\n \"chain.removeLabel\": \"label\",\n \"chain.createLabel\": \"label\",\n \"chain.updateLabel\": \"label\",\n \"chain.deleteLabel\": \"label\",\n \"chain.createCollection\": \"write\",\n \"chain.updateCollection\": \"write\",\n \"chain.listCollections\": \"meta\",\n \"chain.getCollection\": \"meta\",\n \"chain.listLabels\": \"meta\",\n \"resolveWorkspace\": \"meta\",\n};\n\nfunction categorize(fn: string): CallCategory {\n return CALL_CATEGORIES[fn] ?? \"meta\";\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 60_000) return `${Math.round(ms / 1000)}s`;\n const mins = Math.floor(ms / 60_000);\n const secs = Math.round((ms % 60_000) / 1000);\n return `${mins}m ${secs}s`;\n}\n\nfunction buildSessionSummary(log: readonly AuditEntry[]): string {\n if (log.length === 0) return \"\";\n\n const byCategory = new Map<CallCategory, Map<string, number>>();\n let errorCount = 0;\n let writeCreates = 0;\n let writeUpdates = 0;\n\n for (const entry of log) {\n const cat = categorize(entry.fn);\n if (!byCategory.has(cat)) byCategory.set(cat, new Map());\n const fnCounts = byCategory.get(cat)!;\n fnCounts.set(entry.fn, (fnCounts.get(entry.fn) ?? 0) + 1);\n\n if (entry.status === \"error\") errorCount++;\n if (entry.fn === \"chain.createEntry\" && entry.status === \"ok\") writeCreates++;\n if (entry.fn === \"chain.updateEntry\" && entry.status === \"ok\") writeUpdates++;\n }\n\n const firstTs = new Date(log[0].ts).getTime();\n const lastTs = new Date(log[log.length - 1].ts).getTime();\n const duration = formatDuration(lastTs - firstTs);\n\n const lines: string[] = [`# Session Summary (${duration})\\n`];\n\n const categoryLabels: [CallCategory, string][] = [\n [\"read\", \"Reads\"],\n [\"search\", \"Searches\"],\n [\"write\", \"Writes\"],\n [\"label\", \"Labels\"],\n [\"meta\", \"Meta\"],\n ];\n\n for (const [cat, label] of categoryLabels) {\n const fnCounts = byCategory.get(cat);\n if (!fnCounts || fnCounts.size === 0) continue;\n const total = [...fnCounts.values()].reduce((a, b) => a + b, 0);\n const detail = [...fnCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([fn, count]) => `${fn.replace(\"chain.\", \"\")} x${count}`)\n .join(\", \");\n lines.push(`- **${label}:** ${total} call${total === 1 ? \"\" : \"s\"} (${detail})`);\n }\n\n lines.push(`- **Errors:** ${errorCount}`);\n\n if (writeCreates > 0 || writeUpdates > 0) {\n lines.push(\"\");\n lines.push(\"## Knowledge Contribution\");\n if (writeCreates > 0) lines.push(`- ${writeCreates} entr${writeCreates === 1 ? \"y\" : \"ies\"} created`);\n if (writeUpdates > 0) lines.push(`- ${writeUpdates} entr${writeUpdates === 1 ? \"y\" : \"ies\"} updated`);\n }\n\n return lines.join(\"\\n\");\n}\n\n// ─── Organisation Health (FEAT-129) ─────────────────────────────────────────\n\nexport type OrgHealthFlag = {\n collection: string;\n count: number;\n suggestedCollection: string;\n};\n\nexport type OrgHealthResult = {\n reviewed: number;\n agreements: number;\n disagreements: number;\n abstentions: number;\n agreementRate: number;\n flags: OrgHealthFlag[];\n};\n\n/**\n * Compute org health from pre-classified results (from Convex batch heuristic).\n * TEN-174 resolution: classification runs in Convex with DB-driven signals,\n * not locally with a stale copy. Zero drift risk.\n */\nexport function computeOrganisationHealth(\n entries: Array<{ collectionSlug?: string; collection?: string }>,\n classifications: Array<{ collection: string | null; confidence: number }>,\n): OrgHealthResult {\n let agreements = 0;\n let disagreements = 0;\n let abstentions = 0;\n const flagMap = new Map<string, Map<string, number>>();\n\n for (let i = 0; i < entries.length; i++) {\n const slug = entries[i].collectionSlug ?? entries[i].collection ?? \"unknown\";\n const result = classifications[i];\n\n if (!result?.collection) {\n abstentions++;\n continue;\n }\n\n if (result.collection === slug) {\n agreements++;\n } else {\n disagreements++;\n if (!flagMap.has(slug)) flagMap.set(slug, new Map());\n const suggestions = flagMap.get(slug)!;\n suggestions.set(result.collection, (suggestions.get(result.collection) ?? 0) + 1);\n }\n }\n\n const opinionated = agreements + disagreements;\n const agreementRate = opinionated > 0 ? Math.round((agreements / opinionated) * 100) : 100;\n\n const flags = [...flagMap.entries()]\n .map(([collection, suggestions]) => {\n const total = [...suggestions.values()].reduce((a, b) => a + b, 0);\n const topSuggested = [...suggestions.entries()].sort((a, b) => b[1] - a[1])[0];\n return { collection, count: total, suggestedCollection: topSuggested?.[0] ?? \"unknown\" };\n })\n .sort((a, b) => b.count - a.count)\n .slice(0, 3);\n\n return { reviewed: entries.length, agreements, disagreements, abstentions, agreementRate, flags };\n}\n\nexport function formatOrgHealthLines(orgHealth: OrgHealthResult, maxFlags = 3): string[] {\n const lines: string[] = [];\n if (orgHealth.disagreements > 0) {\n lines.push(\n `${orgHealth.disagreements} of ${orgHealth.reviewed} entries flagged for review (${orgHealth.agreementRate}% classifier agreement).`,\n );\n for (const flag of orgHealth.flags.slice(0, maxFlags)) {\n lines.push(`- **${flag.collection}**: ${flag.count} entries may belong in \\`${flag.suggestedCollection}\\``);\n }\n } else if (orgHealth.reviewed > 0) {\n lines.push(`All ${orgHealth.reviewed - orgHealth.abstentions} classified entries agree with stored collection (${orgHealth.abstentions} without coverage).`);\n }\n return lines;\n}\n\nasync function fetchOrganisationHealth(): Promise<OrgHealthResult | null> {\n try {\n const allEntries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\n \"chain.listEntries\",\n { fields: [\"name\", \"description\", \"collectionSlug\"] },\n );\n if (!allEntries || allEntries.length === 0) return null;\n\n // description is projected server-side from data.description (Task 3), so it\n // arrives top-level here — no e.data blob crosses the wire. `chain.listEntries`'s\n // return type is a union (raw EntryDoc[] when no `fields` requested, vs\n // Record<string, unknown>[] when they are, see wrapup.ts's doc comment on this\n // recurring residual) — this call DOES request `fields`, so runtime is provably the\n // projected branch, but property access still checks against the whole union\n // (PR #395, Lane C S3b annotation pass).\n const projectedEntries = allEntries as Array<{ name?: string; description?: unknown; collectionSlug?: string }>;\n const classifyInput = projectedEntries.map((e) => ({\n name: e.name ?? \"\",\n description: typeof e.description === \"string\" ? e.description : \"\",\n }));\n const classifications = await kernelQuery<GatewayRouteReturnByName<\"chain.batchClassifyHeuristic\">>(\n \"chain.batchClassifyHeuristic\",\n { entries: classifyInput },\n );\n\n return computeOrganisationHealth(projectedEntries, classifications);\n } catch (err) {\n process.stderr.write(`[MCP] fetchOrganisationHealth failed: ${(err as Error).message}\\n`);\n return null;\n }\n}\n\nexport async function handleHealthCheck() {\n const start = Date.now();\n const errors: string[] = [];\n\n let workspaceId: string | undefined;\n try {\n workspaceId = await getWorkspaceId();\n } catch (e: unknown) {\n errors.push(`Workspace resolution failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n let collections: unknown[] = [];\n try {\n collections = await kernelQuery<unknown[]>(\"chain.listCollections\");\n } catch (e: unknown) {\n errors.push(`Collection fetch failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n let totalEntries = 0;\n if (collections.length > 0) {\n try {\n const entries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\n \"chain.listEntries\",\n { fields: [\"entryId\"] },\n );\n totalEntries = (entries ?? []).length;\n } catch (e: unknown) {\n errors.push(`Entry count failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n let wsCtx: { workspaceSlug: string; workspaceName: string } | null = null;\n try {\n wsCtx = await getWorkspaceContext();\n } catch { /* already captured workspace error above */ }\n\n const durationMs = Date.now() - start;\n const healthy = errors.length === 0;\n\n const lines = [\n `# ${healthy ? \"Healthy\" : \"Degraded\"}`,\n \"\",\n `**Workspace:** ${workspaceId ?? \"unresolved\"}`,\n `**Workspace Slug:** ${wsCtx?.workspaceSlug ?? \"unknown\"}`,\n `**Workspace Name:** ${wsCtx?.workspaceName ?? \"unknown\"}`,\n `**Collections:** ${collections.length}`,\n `**Entries:** ${totalEntries}`,\n `**Latency:** ${durationMs}ms`,\n ];\n\n if (errors.length > 0) {\n lines.push(\"\", \"## Errors\");\n for (const err of errors) {\n lines.push(`- ${err}`);\n }\n }\n\n const healthData = {\n healthy,\n collections: collections.length,\n entries: totalEntries,\n latencyMs: durationMs,\n workspace: workspaceId ?? \"unresolved\",\n };\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n healthy ? `Healthy. ${collections.length} collections, ${totalEntries} entries, ${durationMs}ms.` : `Degraded. ${errors.length} error(s).`,\n healthData,\n ),\n };\n}\n\nexport async function handleWhoami() {\n const ctx = await getWorkspaceContext();\n const sessionId = getAgentSessionId();\n const scope = getApiKeyScope();\n const oriented = isSessionOriented();\n const lines = [\n `# Session Identity`,\n \"\",\n `**Workspace ID:** ${ctx.workspaceId}`,\n `**Workspace Slug:** ${ctx.workspaceSlug}`,\n `**Workspace Name:** ${ctx.workspaceName}`,\n ];\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Session: ${ctx.workspaceName} (${scope}). ${oriented ? \"Oriented.\" : \"Not oriented.\"}`,\n { workspaceId: ctx.workspaceId, workspaceName: ctx.workspaceName, scope, sessionId, oriented },\n ),\n };\n}\n\nconst STAGE_LABELS: Record<string, string> = {\n blank: \"Blank\",\n seeded: \"Seeded\",\n grounded: \"Grounded\",\n connected: \"Connected\",\n};\n\nconst STAGE_DESCRIPTIONS: Record<string, string> = {\n blank: \"No knowledge captured yet.\",\n seeded: \"Early knowledge is in place — keep building.\",\n grounded: \"Solid foundations — a few gaps remain.\",\n connected: \"Well-connected knowledge graph — your Brain is useful.\",\n};\n\nexport async function handleWorkspaceStatus() {\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.workspaceReadiness\">>(\"chain.workspaceReadiness\");\n\n const { score, totalChecks, passedChecks, checks, gaps, stats, governanceMode } = result;\n // Guard against older backends that predate v2 scoring.\n const scoringVersion: \"v1\" | \"v2\" = result.scoringVersion ?? \"v1\";\n const stage: \"blank\" | \"seeded\" | \"grounded\" | \"connected\" = result.stage ?? \"seeded\";\n\n const stageLabel = STAGE_LABELS[stage] ?? stage;\n const stageDescription = STAGE_DESCRIPTIONS[stage] ?? \"\";\n const scoreBar = \"█\".repeat(Math.round(score / 10)) + \"░\".repeat(10 - Math.round(score / 10));\n\n const lines = [\n `# Brain Status: ${stageLabel}`,\n `_${stageDescription}_`,\n \"\",\n `${scoreBar} ${stageLabel} · ${score}%`,\n `**Governance:** ${governanceMode ?? \"open\"}${(governanceMode ?? \"open\") !== \"open\" ? \" (accepts require proposal)\" : \"\"}`,\n \"\",\n \"## Stats\",\n `- **Entries:** ${stats.totalEntries} (${stats.activeCount} active, ${stats.draftCount} draft)`,\n `- **Relations:** ${stats.totalRelations}`,\n `- **Collections:** ${stats.collectionCount}`,\n `- **Orphaned:** ${stats.orphanedCount} committed entries with no relations`,\n \"\",\n ];\n\n if (gaps.length > 0) {\n lines.push(\"## Gaps\");\n for (const gap of gaps) {\n // capabilityGuidance is plain English (v2); fall back to guidance for backward compat\n const action = gap.capabilityGuidance ?? gap.guidance;\n lines.push(`- [ ] **${gap.label}**`);\n lines.push(` _${action}_`);\n }\n lines.push(\"\");\n }\n\n const passed = checks.filter((c) => c.passed);\n if (passed.length > 0) {\n lines.push(\"## Passing checks\");\n for (const check of passed) {\n lines.push(`- [x] ${check.label} (${check.current}/${check.required})`);\n }\n lines.push(\"\");\n }\n\n const orgHealth = await fetchOrganisationHealth();\n if (orgHealth && orgHealth.reviewed > 0) {\n lines.push(\"## Organisation Health\");\n lines.push(...formatOrgHealthLines(orgHealth));\n lines.push(\"\");\n }\n\n const statusData: Record<string, unknown> = {\n stage,\n scoringVersion,\n readinessScore: score,\n activeEntries: stats.activeCount,\n totalRelations: stats.totalRelations,\n orphanedEntries: stats.orphanedCount,\n gaps: gaps.map((g) => ({\n id: g.id,\n label: g.label,\n guidance: g.capabilityGuidance ?? g.guidance,\n })),\n ...(orgHealth && { organisationHealth: orgHealth }),\n };\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n `Brain: ${stageLabel} (${score}%). ${stats.activeCount} active entries, ${gaps.length} gap(s).`,\n statusData,\n ),\n };\n}\n\nexport async function handleAudit(limit: number) {\n // Tenant-scoped view assembly (resolve workspace, filter log, pull counter slice, format\n // summary) lives in lib/auditView.ts — PR #533 review, Codex P2 (WP-575, TEN-2917).\n const { log, recent, gatewaySeam, logLines, seamSummaryText } = await buildTenantAuditView(limit);\n\n // The buffer is bounded, the counters are not — \"no recent calls\" must still carry them (Codex P2).\n if (recent.length === 0) return successResult(`No calls recorded yet this session.${seamSummaryText}`, \"No calls recorded yet this session.\", { totalCalls: 0, calls: [], gatewaySeam });\n\n const summary = buildSessionSummary(log);\n\n const auditData = {\n totalCalls: log.length, gatewaySeam,\n calls: recent.map((entry) => ({\n tool: entry.fn,\n ...(entry.toolContext?.action && { action: entry.toolContext.action }),\n timestamp: entry.ts,\n ...(entry.durationMs != null && { durationMs: entry.durationMs }),\n ...(entry.budgetMs != null && { budgetMs: entry.budgetMs }), ...(entry.timedOut ? { timedOut: true } : {}),\n })),\n };\n\n return {\n content: [{ type: \"text\" as const, text: `${summary}\\n\\n---\\n\\n${logLines.join(\"\\n\")}${seamSummaryText}` }],\n structuredContent: success(\n `Audit: ${log.length} total calls, showing last ${recent.length}.`,\n auditData,\n ),\n };\n}\n\nconst HEALTH_ACTIONS = [\"check\", \"whoami\", \"status\", \"audit\", \"self-test\"] as const;\ntype HealthAction = (typeof HEALTH_ACTIONS)[number];\n\nexport const healthSchema = z.object({\n action: z.enum(HEALTH_ACTIONS).describe(\n \"'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas.\",\n ),\n limit: z.number().min(1).max(50).default(20).optional()\n .describe(\"For audit: how many recent calls to show (max 50)\"),\n});\n\nexport { orientSchema } from \"./orient.js\";\n\nexport const healthCheckOutputSchema = z.object({\n healthy: z.boolean(),\n collections: z.number(),\n entries: z.number(),\n latencyMs: z.number(),\n workspace: z.string(),\n});\n\nconst organisationHealthSchema = z.object({\n reviewed: z.number(),\n agreements: z.number(),\n disagreements: z.number(),\n abstentions: z.number(),\n agreementRate: z.number(),\n flags: z.array(z.object({\n collection: z.string(),\n count: z.number(),\n suggestedCollection: z.string(),\n })),\n});\n\nexport const healthStatusOutputSchema = z.object({\n stage: z.enum([\"blank\", \"seeded\", \"grounded\", \"connected\"]).optional().default(\"seeded\"),\n scoringVersion: z.enum([\"v1\", \"v2\"]).optional().default(\"v1\"),\n readinessScore: z.number(),\n activeEntries: z.number(),\n totalRelations: z.number(),\n orphanedEntries: z.number(),\n gaps: z.array(z.object({ id: z.string(), label: z.string(), guidance: z.string() })),\n organisationHealth: organisationHealthSchema.optional(),\n});\n\nexport const healthAuditOutputSchema = z.object({\n totalCalls: z.number(),\n calls: z.array(z.object({\n tool: z.string(),\n action: z.string().optional(),\n timestamp: z.string(),\n durationMs: z.number().optional(),\n })),\n});\n\nexport const healthWhoamiOutputSchema = z.object({\n workspaceId: z.string(),\n workspaceName: z.string(),\n scope: z.string(),\n sessionId: z.union([z.string(), z.null()]),\n oriented: z.boolean(),\n});\n\nexport const selfTestOutputSchema = z.object({\n passed: z.number(),\n failed: z.number(),\n total: z.number(),\n results: z.array(z.object({\n tool: z.string(),\n valid: z.boolean(),\n error: z.string().optional(),\n })),\n});\n\n/**\n * TEN-2032 (S3): derive the self-test list from the LIVE tool registry\n * instead of a hand-maintained array. The old `ALL_TOOL_SCHEMAS` const\n * drifted from actual registrations (stale at 31 tools while 37 were live,\n * per server.ts's pre-S3 comment) — deriving from `_registeredTools`\n * structurally can't drift, because it reads the same map `tools/list`\n * serves. `_registeredTools` is a private SDK field (mcp.d.ts); the narrow\n * cast is explicit so a future SDK rename fails loudly at compile time\n * instead of silently returning `undefined`.\n */\nexport function handleSelfTest(server: McpServer) {\n const registry = (server as unknown as {\n _registeredTools: Record<string, { inputSchema?: ZodTypeAny }>;\n })._registeredTools;\n\n const results: Array<{ tool: string; valid: boolean; error?: string }> = [];\n\n for (const [name, tool] of Object.entries(registry)) {\n const schema = tool.inputSchema;\n try {\n if (!schema || typeof schema.safeParse !== \"function\") {\n results.push({ tool: name, valid: false, error: \"Schema is not a valid Zod object\" });\n continue;\n }\n const test = schema.safeParse({});\n // Even if parse fails (expected for required fields), the schema itself is valid\n if (test.success || test.error) {\n results.push({ tool: name, valid: true });\n }\n } catch (e: unknown) {\n results.push({ tool: name, valid: false, error: e instanceof Error ? e.message : String(e) });\n }\n }\n\n const passed = results.filter((r) => r.valid).length;\n const failed = results.filter((r) => !r.valid).length;\n const total = results.length;\n\n const lines: string[] = [\n `# Self-Test: Tool Schema Validation`,\n `**Result:** ${failed === 0 ? \"ALL PASS\" : `${failed} FAILED`}`,\n `**Schemas validated:** ${passed}/${total}`,\n \"\",\n ];\n\n if (failed > 0) {\n lines.push(\"## Failures\");\n for (const r of results.filter((r) => !r.valid)) {\n lines.push(`- **${r.tool}**: ${r.error}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"## All Tools\");\n for (const r of results) {\n lines.push(`- ${r.valid ? \"PASS\" : \"FAIL\"} \\`${r.tool}\\``);\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n structuredContent: success(\n failed === 0 ? `Self-test: all ${total} schemas valid.` : `Self-test: ${failed}/${total} schemas failed.`,\n { passed, failed, total, results },\n ),\n };\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `health` tool retired\n// here. handleHealthCheck / handleWhoami / handleWorkspaceStatus /\n// handleAudit / handleSelfTest stay live — workspace.ts (the `workspace`\n// compound) is their only remaining caller. handleSelfTest now takes the\n// live `server` so it can read the registry directly (TEN-2032, above).\n","/**\n * Tenant-scoped audit view assembly (PR #533 review, Codex P2 — WP-575, TEN-2917).\n *\n * \"Resolve the calling workspace, filter the audit log to it, pull that workspace's counter\n * slice, and format the summary\" became a real responsibility of its own once the audit seam\n * had to be tenant-scoped: HTTP transport multiplexes many tenants through one MCP process\n * (client.ts's per-key `state()`), so `workspace action=audit` reading the log/counters\n * unfiltered would hand any authenticated caller every OTHER tenant's call history and failure\n * rates. That is a cohesive unit that does not belong in a tool-dispatch file — extracted out\n * of tools/health.ts (not inlined there) for the same reason lib/toolActionCounts.ts was pulled\n * out of client.ts: both files are grandfathered shrink-only under the module-health ratchet\n * (STD-2/DEC-1504), so a genuine new responsibility gets its own module instead of widening the\n * baseline.\n */\n// The seam owns the counters and the audit buffer, so take them from the seam directly rather\n// than through client.ts's re-export — client.ts is grandfathered shrink-only under the\n// module-health ratchet, and a re-export line added purely to route this import through it\n// would grow that file for no benefit.\nimport {\n formatGatewaySeamSummary,\n getAuditLog,\n getMergedGatewaySeamCounters,\n type AuditEntry,\n type GatewaySeamCounters,\n} from \"../gatewaySeam.js\";\n// Caller identity is client.ts's own state, not the seam's.\nimport { cacheScope, getWorkspaceId } from \"../client.js\";\n\nexport interface TenantAuditView {\n /** The resolved (or fail-closed fallback) workspace this view is scoped to. */\n workspace: string;\n /** This workspace's slice of the process-lifetime audit buffer, oldest first. */\n log: readonly AuditEntry[];\n /** The last `limit` entries of `log`. */\n recent: readonly AuditEntry[];\n /** This workspace's slice of the gateway seam counters. */\n gatewaySeam: GatewaySeamCounters;\n /** Pre-formatted `# Audit Log (last N of M total)` header + one line per `recent` entry. */\n logLines: string[];\n /** `formatGatewaySeamSummary(gatewaySeam)` — the human-readable seam section. */\n seamSummaryText: string;\n}\n\n/**\n * Resolve who's asking, then build their (and only their) audit view.\n *\n * Fail closed: if the workspace can't be resolved, fall back to `cacheScope()` (hashed\n * per-API-key in HTTP mode, \"stdio\" in stdio mode — client.ts) rather than a shared literal like\n * \"unresolved\", which would itself be a (narrower) cross-tenant collision between two different\n * not-yet-resolved callers. Either way, never fall through to the unfiltered global log/counters.\n */\nexport async function buildTenantAuditView(limit: number): Promise<TenantAuditView> {\n const scope = cacheScope();\n let workspace: string;\n try {\n workspace = await getWorkspaceId();\n } catch {\n workspace = scope;\n }\n\n // BOTH buckets, because this caller's calls are recorded under both. `audit()` attributes a\n // call to `state().workspaceId ?? cacheScope()` (client.ts), and `workspaceId` is only set\n // once `resolveWorkspace` RETURNS — so every session's FIRST call is filed under\n // `cacheScope()`. Scoping to the resolved workspaceId alone hid that call forever and\n // under-counted every tenant's view of ITSELF, in stdio mode too. Safe because `cacheScope()`\n // is derived from this caller's own API key: both buckets are the same tenant, so this widens\n // the caller's view of itself and still cannot reach another tenant's.\n const ownScopes = [workspace, scope];\n // Scoped at the SOURCE, not filtered after the fact (PR #533 review, Codex P2). Filtering a\n // shared buffer here was too late: it holds the last N calls made by ANY tenant, so a noisy\n // neighbour had already evicted this caller's entries before this line ran, and a tenant\n // with real recorded timeouts saw an empty log. The seam now keeps a bounded buffer per\n // workspace, so `limit` is a floor this caller can rely on rather than a share of a pool.\n const log = getAuditLog(ownScopes);\n const recent = log.slice(-limit);\n const gatewaySeam = getMergedGatewaySeamCounters(ownScopes);\n\n const logLines = [\n `# Audit Log (last ${recent.length} of ${log.length} total)\\n`,\n ...recent.map((entry) => {\n const toolPart = entry.toolContext\n ? ` [${entry.toolContext.tool}${entry.toolContext.action ? ` action=${entry.toolContext.action}` : \"\"}]`\n : \"\";\n const errPart = entry.error ? ` — ${entry.error}` : \"\";\n return `${entry.status === \"ok\" ? \"✓\" : \"✗\"} \\`${entry.fn}\\`${toolPart} ${entry.durationMs}ms ${entry.status}${errPart}`;\n }),\n ];\n\n return { workspace, log, recent, gatewaySeam, logLines, seamSummaryText: formatGatewaySeamSummary(gatewaySeam) };\n}\n","/**\n * LLM Usage MCP tools — STR-23 (MCP before UI)\n * Chain: DEC-61, TEN-65\n *\n * AI agents can query their own workspace spend, model breakdown,\n * and session economics before the Settings UI ships.\n */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { z } from \"zod/v3\";\nimport { success, failureResult } from \"../envelope.js\";\nimport { kernelQuery, getWorkspaceContext, getAgentSessionId } from \"../client.js\";\n\nexport const usageSummarySchema = z.object({\n periodDays: z\n .number()\n .min(1)\n .max(90)\n .optional()\n .describe(\"Number of days to look back (default 30, max 90)\"),\n});\n\n/**\n * WP-484 S2 (§3): extracted usage-summary handler — reused by the legacy\n * `get-usage-summary` standalone tool AND `workspace action=usage` (absorbed\n * per §3 core-nouns table). One business-logic path.\n */\nexport async function handleUsageSummary(periodDays?: number) {\n const ws = await getWorkspaceContext();\n const sessionId = getAgentSessionId();\n\n const summary = await kernelQuery<GatewayRouteReturnByName<\"usage.getWorkspaceSummary\">>(\"usage.getWorkspaceSummary\", {\n periodDays: periodDays ?? 30,\n });\n\n if (!summary) {\n return failureResult(\n \"No usage data available yet. LLM tracking may not be active or no calls have been made in this period.\",\n \"NOT_FOUND\",\n \"No usage data available yet.\",\n \"LLM tracking may not be active or no calls have been made in this period.\",\n );\n }\n\n const lines: string[] = [\n `## Usage Summary — ${ws.workspaceName}`,\n `Period: last ${summary.periodDays} days`,\n \"\",\n `**Total spend:** $${summary.totalCostUsd.toFixed(4)} USD (${summary.totalRequests} requests)`,\n `**Total tokens:** ${summary.totalTokens.toLocaleString()} (cached: ${summary.cachedTokens.toLocaleString()}, reasoning: ${summary.reasoningTokens.toLocaleString()})`,\n `**Cache hit rate:** ${(summary.cacheHitRate * 100).toFixed(1)}%`,\n ];\n\n if (summary.modelBreakdown.length > 0) {\n lines.push(\"\", \"### Model Breakdown\");\n for (const m of summary.modelBreakdown) {\n lines.push(`- **${m.model}**: $${m.costUsd.toFixed(4)} (${m.requests} requests)`);\n }\n }\n\n if (summary.featureBreakdown.length > 0) {\n lines.push(\"\", \"### Feature Breakdown\");\n for (const f of summary.featureBreakdown) {\n lines.push(`- **${f.feature}**: $${f.costUsd.toFixed(4)} (${f.requests} requests)`);\n }\n }\n\n if (sessionId) {\n lines.push(\"\", `_Current agent session: ${sessionId}_`);\n }\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: lines.join(\"\\n\"),\n },\n ],\n structuredContent: success(\n `Usage for ${ws.workspaceName}: $${summary.totalCostUsd.toFixed(4)} over ${summary.periodDays} days, ${summary.totalRequests} requests.`,\n {\n periodDays: summary.periodDays,\n totalTokens: summary.totalTokens,\n totalCostUsd: summary.totalCostUsd,\n totalRequests: summary.totalRequests,\n cacheHitRate: summary.cacheHitRate,\n modelBreakdown: summary.modelBreakdown,\n featureBreakdown: summary.featureBreakdown,\n },\n ),\n };\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `get-usage-summary` tool\n// retired here. handleUsageSummary stays live — workspace.ts (the `workspace`\n// compound, action=usage) is its only remaining caller.\n","/**\n * Governance Proposals Tool — MCP surface for consent proposal lifecycle.\n *\n * Chain: BET-221 (Governance at Scale), BR-7 (async consent required),\n * TEN-967 (consent proposals only)\n *\n * Actions:\n * list — List open consent proposals with expiry countdown\n * respond — Approve or reject a proposal (with reason for rejections)\n * count — Count open proposals (for badge/notification)\n */\n\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { kernelQuery, kernelMutation, requireWriteAccess } from \"../client.js\";\nimport { successResult, failureResult, validationResult } from \"../envelope.js\";\n\n/**\n * WP-484 S2 (§3): extracted governance-proposals handlers — reused by the\n * legacy `governance-proposals` standalone tool AND `workspace\n * action=proposals-list/respond/count` (absorbed per §3 core-nouns table).\n * One business-logic path per action.\n */\nexport async function handleProposalsList(status?: \"open\" | \"approved\" | \"objected\" | \"expired\") {\n const proposals = await kernelQuery<GatewayRouteReturnByName<\"governance.listProposals\">>(\"governance.listProposals\", {\n ...(status ? { status } : {}),\n });\n\n if (proposals.length === 0) {\n const statusLabel = status ?? \"open\";\n return successResult(\n `No ${statusLabel} consent proposals in this workspace.`,\n `No ${statusLabel} consent proposals found.`,\n { proposals: [], count: 0 },\n );\n }\n\n const lines: string[] = [\"# Consent Proposals\", \"\"];\n\n for (const p of proposals) {\n const urgency = p.isExpired\n ? \"EXPIRED\"\n : p.hoursRemaining < 1\n ? `< 1h remaining`\n : `${p.hoursRemaining}h remaining`;\n\n lines.push(`## ${p.targetEntryName} → ${p.toEntryName ?? \"unknown\"}`);\n lines.push(`- **ID:** \\`${p._id}\\``);\n lines.push(`- **Status:** ${p.status} (${urgency})`);\n lines.push(`- **Operation:** ${p.proposedOperation}`);\n lines.push(`- **Reasoning:** ${p.reasoning}`);\n lines.push(`- **Proposed by:** ${p.proposedBy}`);\n if (p.objectionReason) {\n lines.push(`- **Objection:** ${p.objectionReason}`);\n }\n lines.push(\"\");\n }\n\n return successResult(\n lines.join(\"\\n\"),\n `Found ${proposals.length} consent proposal(s).`,\n { proposals, count: proposals.length },\n [\n {\n tool: \"workspace\",\n description: \"Respond to a proposal\",\n parameters: { action: \"proposals-respond\" },\n },\n ],\n );\n}\n\nexport async function handleProposalsCount() {\n const result = await kernelQuery<GatewayRouteReturnByName<\"governance.countOpenProposals\">>(\"governance.countOpenProposals\");\n\n return successResult(\n result.count === 0\n ? \"No open consent proposals.\"\n : `${result.count} open consent proposal(s) awaiting review.`,\n `${result.count} open consent proposal(s).`,\n result,\n result.count > 0\n ? [{\n tool: \"workspace\",\n description: \"List open proposals\",\n parameters: { action: \"proposals-list\" },\n }]\n : undefined,\n );\n}\n\nexport async function handleProposalsRespond(proposalId: string, verdict: \"approve\" | \"reject\", reason?: string) {\n requireWriteAccess();\n if (verdict === \"reject\" && !reason) {\n return validationResult(\n \"A reason is required when rejecting a proposal. Explain what harm this change would cause.\",\n );\n }\n\n try {\n const result = await kernelMutation<GatewayRouteReturnByName<\"governance.respondToProposal\">>(\n \"governance.respondToProposal\",\n {\n proposalId,\n verdict,\n ...(reason ? { reason } : {}),\n },\n );\n\n return successResult(\n result.message,\n result.message,\n result,\n [\n {\n tool: \"workspace\",\n description: \"List remaining proposals\",\n parameters: { action: \"proposals-list\" },\n },\n ],\n );\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n return failureResult(\n msg,\n \"PROPOSAL_ERROR\",\n msg,\n \"Use workspace action=proposals-list to check proposal status.\",\n [\n {\n tool: \"workspace\",\n description: \"List proposals\",\n parameters: { action: \"proposals-list\" },\n },\n ],\n );\n }\n}\n\n// WP-484 S3 (clean break, TEN-2157): the standalone `governance-proposals`\n// tool retired here. handleProposals* stay live — workspace.ts (the\n// `workspace` compound, action=proposals-list/respond/count) is their only\n// remaining caller.\n","/** Compound feedback resource: open submission plus vendor-only triage verbs. */\nimport type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod/v3';\nimport { getAgentSessionId, kernelCall, requireVendorTriageAccess, runWithToolContext } from '../client.js';\nimport { thinWrapper, parseOrFail, failureResult, success, textContent, type ToolResult } from '../envelope.js';\nimport { dispatchDiscriminated, type ActionParamSpec } from '../compound-tool.js';\nimport { PRODUCT_FEEDBACK_CATEGORIES, PRODUCT_FEEDBACK_STATUSES, VENDOR_SETTABLE_STATUSES, type VendorSettableStatus } from '../lib/productFeedbackConstants.js';\n\nconst actions = ['submit', 'list', 'queue', 'note', 'group', 'status'] as const;\ntype FeedbackAction = (typeof actions)[number];\nconst category = z.enum(PRODUCT_FEEDBACK_CATEGORIES);\n/** list/queue FILTER value — the full status set, including the system-only 'screening'. */\nconst status = z.enum(PRODUCT_FEEDBACK_STATUSES);\n/**\n * status action TARGET value — review fix (Codex P2): 'screening' is system-only (stamped\n * by insertFeedback, cleared by releaseFromScreening). Setting a row BACK to 'screening' via\n * this verb would strand it with no screenFeedback scheduled, so it is excluded from what a\n * vendor may set the status TO (filtering by status='screening' via `status` above is fine).\n */\n// z.enum requires a non-empty tuple type; VENDOR_SETTABLE_STATUSES is derived via .filter()\n// over a `readonly [...]` tuple, which TS widens to a plain array — the cast restores the\n// tuple shape .filter() itself cannot express (the array's actual runtime content is still\n// the SSOT-derived, filtered set).\nconst vendorStatus = z.enum(VENDOR_SETTABLE_STATUSES as [VendorSettableStatus, ...VendorSettableStatus[]]);\n\n/**\n * The gateway (`validateArgLengths`, TEN-1146) rejects any string argument over\n * 10,240 UTF-8 BYTES. A characters-only client cap (10,000 chars) let multibyte text\n * pass the client and 4xx at the gateway (Codex P2, PR #372) — so the client contract\n * enforces the byte limit too, with an error that names bytes.\n */\nexport const GATEWAY_MAX_STRING_BYTES = 10_240;\nconst utf8Bytes = (value: string): number => new TextEncoder().encode(value).length;\nconst fitsGatewayBytes = (value: string): boolean => utf8Bytes(value) <= GATEWAY_MAX_STRING_BYTES;\nconst byteLimitMessage = (field: string) => ({\n message: `${field} exceeds the gateway limit of ${GATEWAY_MAX_STRING_BYTES.toLocaleString('en-US')} UTF-8 bytes — multibyte characters can hit the byte limit well below the 10,000-character cap; shorten the text.`,\n});\n\n/** Display cap for list rows: a 100-row page of 10,000-char messages approaches ~2MB (Codex P2, PR #372). */\nconst MESSAGE_DISPLAY_LIMIT = 1_000;\n/** `full: true` lifts truncation only for a small targeted fetch, never a whole page. */\nconst FULL_MESSAGE_MAX_LIMIT = 5;\n\nexport const feedbackSchema = z.object({\n action: z.enum(actions).describe('submit requires message; list returns your own workspace\\'s feedback (all statuses); queue is the vendor triage queue (system admins only) and accepts filters; note requires feedbackId+note; group requires feedbackIds+groupId (null clears); status requires feedbackId+status.'),\n message: z.string().max(10_000).optional().describe('Required for submit: the product feedback text (max 10,000 chars and 10,240 UTF-8 bytes).'),\n category: category.optional().describe('Submit/queue category; submit defaults to other.'),\n command: z.string().max(1_000).optional().describe('Optional submit command context; argument values are scrubbed server-side.'),\n route: z.string().max(500).optional().describe('Optional submit route context.'),\n client: z.string().max(100).optional().describe('Optional submit client label.'),\n feedbackId: z.string().max(200).optional().describe('Required for note/status: target feedback ID.'),\n feedbackIds: z.array(z.string().max(200)).max(100).optional().describe('Required for group: 1–100 target feedback IDs.'),\n note: z.string().max(4_000).optional().describe('Required for note: replacement triage note (max 10,240 UTF-8 bytes).'),\n status: status.optional().describe(\"list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only).\"),\n groupId: z.string().min(1).max(200).nullable().optional().describe('Group filter, or required group destination; null explicitly clears grouping.'),\n workspaceId: z.string().max(200).optional().describe('Queue-only filter (vendor cross-workspace triage); omitted means all workspaces. Has no effect on list — your own workspace is always injected server-side.'),\n since: z.number().optional().describe('Queue-only lower createdAt window bound (inclusive) in epoch milliseconds.'),\n before: z.number().optional().describe('Queue-only upper createdAt window bound (exclusive) in epoch milliseconds. A time-window FILTER, not the pager — use cursor to page.'),\n limit: z.number().int().min(1).max(100).optional().describe('list/queue row limit, default 50, maximum 100.'),\n cursor: z.string().max(2_000).optional().describe('Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page.'),\n full: z.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`),\n});\n\nconst union = z.discriminatedUnion('action', [\n z.object({ action: z.literal('submit'), message: z.string().min(1).max(10_000).refine(fitsGatewayBytes, byteLimitMessage('message')), category: category.optional(), command: z.string().max(1_000).optional(), route: z.string().max(500).optional(), client: z.string().max(100).optional() }),\n z.object({ action: z.literal('list'), status: status.optional(), limit: z.number().int().min(1).max(100).optional(), cursor: z.string().max(2_000).optional(), full: z.boolean().optional() }),\n z.object({ action: z.literal('queue'), status: status.optional(), category: category.optional(), groupId: z.string().min(1).max(200).optional(), workspaceId: z.string().max(200).optional(), since: z.number().optional(), before: z.number().optional(), limit: z.number().int().min(1).max(100).optional(), cursor: z.string().max(2_000).optional(), full: z.boolean().optional() }),\n z.object({ action: z.literal('note'), feedbackId: z.string().min(1).max(200), note: z.string().max(4_000).refine(fitsGatewayBytes, byteLimitMessage('note')) }),\n z.object({ action: z.literal('group'), feedbackIds: z.array(z.string().min(1).max(200)).min(1).max(100), groupId: z.string().min(1).max(200).nullable() }),\n z.object({ action: z.literal('status'), feedbackId: z.string().min(1).max(200), status: vendorStatus }),\n]);\n\nconst specs: Record<FeedbackAction, ActionParamSpec> = {\n submit: { params: ['message', 'category', 'command', 'route', 'client'], description: 'message is required; category defaults to other.' },\n // Own-workspace read-back (spec: WP-494 §5) — the member default; vendor queue is the `queue` action.\n list: { params: ['status', 'limit', 'cursor', 'full'], description: \"Your workspace's own feedback — all statuses by default (including screening); cursor pages, full lifts message truncation for limit <= 5. No vendor gate.\" },\n queue: { params: ['status', 'category', 'groupId', 'workspaceId', 'since', 'before', 'limit', 'cursor', 'full'], description: 'Vendor cross-workspace triage queue (system admins only); filters are optional, status defaults to new; cursor pages, full lifts message truncation for limit <= 5.' },\n note: { params: ['feedbackId', 'note'], description: 'feedbackId and note are required.' },\n group: { params: ['feedbackIds', 'groupId'], description: 'feedbackIds and groupId are required; null clears a group.' },\n status: { params: ['feedbackId', 'status'], description: \"feedbackId and status are required; status cannot be set to 'screening' (system-only).\" },\n};\n\nfunction result(action: FeedbackAction, data: unknown): ToolResult {\n const summary = action === 'submit' ? 'Feedback submitted.' : `Feedback ${action} complete.`;\n return { content: textContent(`${summary}\\n${JSON.stringify(data, null, 2)}`), structuredContent: success(summary, { action, result: data }) };\n}\n\ntype GroupRowResult = { feedbackId?: string; ok?: boolean; error?: string };\n\n/**\n * The server applies group rows independently and reports per-row `{ok, error?}` results —\n * a blanket \"Feedback group complete.\" hid partial failure (Codex, PR #372 round 5). The\n * summary is derived from the results: applied/failed counts with each failed row's reason,\n * and an MCP failure envelope when EVERY row failed. structuredContent always carries the\n * full per-row results.\n */\nfunction groupResult(data: unknown): ToolResult {\n const rows = (data as { results?: unknown } | null)?.results;\n if (!Array.isArray(rows)) return result('group', data); // Tolerate a non-per-row kernel shape.\n const results = rows as GroupRowResult[];\n const failed = results.filter((row) => row?.ok !== true);\n const applied = results.length - failed.length;\n const failedLines = failed.map((row) => `- ${row.feedbackId ?? 'unknown'}: ${row.error ?? 'unknown error'}`);\n if (results.length > 0 && applied === 0) {\n const message = `Feedback group failed for all ${failed.length} row(s).`;\n return failureResult(\n `${message}\\n${failedLines.join('\\n')}`,\n 'GROUP_FAILED',\n message,\n 'Check the per-row errors in diagnostics.results, fix the target IDs or group destination, and retry.',\n undefined,\n { action: 'group', results },\n );\n }\n const summary = failed.length === 0\n ? `Feedback group: ${applied} applied.`\n : `Feedback group: ${applied} applied, ${failed.length} failed.`;\n const text = failed.length === 0\n ? `${summary}\\n${JSON.stringify(data, null, 2)}`\n : `${summary}\\nFailed rows:\\n${failedLines.join('\\n')}\\n${JSON.stringify(data, null, 2)}`;\n return { content: textContent(text), structuredContent: success(summary, { action: 'group', result: data }) };\n}\n\ntype FeedbackListPage = { items: unknown[]; continueCursor: string | null; isDone: boolean };\n\n/** Tolerate a pre-cursor kernel that still answers with plain rows. */\nfunction normalizeListPage(raw: unknown): FeedbackListPage {\n if (Array.isArray(raw)) return { items: raw, continueCursor: null, isDone: true };\n const page = (raw ?? {}) as Partial<FeedbackListPage>;\n return {\n items: Array.isArray(page.items) ? page.items : [],\n continueCursor: typeof page.continueCursor === 'string' ? page.continueCursor : null,\n isDone: page.isDone !== false,\n };\n}\n\n/**\n * Truncate a row's message for DISPLAY (Codex P2, PR #372): a 100-row page of 10,000-char\n * messages approaches ~2MB. `structuredContent` carries the SAME truncated rows — full\n * bodies are never duplicated; `full: true` (limit <= 5) or a cursor-paged smaller fetch\n * is the path to a whole message.\n */\nfunction truncateListItems(items: unknown[], full: boolean): unknown[] {\n if (full) return items;\n return items.map((item) => {\n if (item === null || typeof item !== 'object') return item;\n const row = item as Record<string, unknown>;\n if (typeof row.message !== 'string' || row.message.length <= MESSAGE_DISPLAY_LIMIT) return item;\n return {\n ...row,\n message: `${row.message.slice(0, MESSAGE_DISPLAY_LIMIT)}… (truncated, ${row.message.length} chars total)`,\n };\n });\n}\n\nfunction requireTriageSessionId(): string {\n // Triage-specific gate, NOT requireWriteAccess: the server's validateVendorTriageSession\n // requires an active session and a readwrite key but deliberately omits requireOriented —\n // the session-start queue hint points at `feedback action=queue` before any orient call.\n // WP-494 §5 verb-rename sweep: this gate moved from `list` to `queue`; `list` (own-workspace\n // read-back via feedback.listOwn) is a member query and carries NO gate here.\n requireVendorTriageAccess();\n const sessionId = getAgentSessionId();\n if (!sessionId) throw new Error('Agent session required for feedback triage.');\n return sessionId;\n}\n\nexport function registerFeedbackTool(server: McpServer): void {\n const handlers: Record<FeedbackAction, (data: any) => Promise<ToolResult>> = {\n submit: async (data) => {\n const sessionId = getAgentSessionId();\n return result('submit', await kernelCall<GatewayRouteReturnByName<\"feedback.submit\">>('feedback.submit', {\n message: data.message,\n category: data.category ?? 'other',\n ...(sessionId ? { sessionId } : {}),\n context: { command: data.command, route: data.route, client: data.client ?? 'mcp' },\n }));\n },\n // WP-494 §5 (TEN-2742): own-workspace read-back — the default verb. NO vendor/triage\n // gate: it's a member query (`feedback.listOwn`), a read-scoped key passes, and the\n // gateway force-injects the caller's own workspaceId regardless of anything sent here.\n list: async ({ action: _action, full, cursor, ...data }) => {\n const wantFull = full === true;\n if (wantFull && (data.limit ?? 50) > FULL_MESSAGE_MAX_LIMIT) {\n throw new Error(`full=true returns untruncated messages and is only allowed with limit <= ${FULL_MESSAGE_MAX_LIMIT}; re-fetch the target rows with a smaller limit (page with cursor).`);\n }\n // cursor ?? null: always request the paged shape so continueCursor/isDone are served\n // even on the first page.\n const page = normalizeListPage(await kernelCall('feedback.listOwn', {\n ...data, cursor: cursor ?? null,\n }));\n return result('list', { ...page, items: truncateListItems(page.items, wantFull) });\n },\n // WP-494 §5: the vendor cross-workspace triage queue — takes over `list`'s old\n // behavior verbatim, including the triage-session gate and every existing filter.\n queue: async ({ action: _action, full, cursor, groupId, ...data }) => {\n const wantFull = full === true;\n if (wantFull && (data.limit ?? 50) > FULL_MESSAGE_MAX_LIMIT) {\n throw new Error(`full=true returns untruncated messages and is only allowed with limit <= ${FULL_MESSAGE_MAX_LIMIT}; re-fetch the target rows with a smaller limit (page with cursor).`);\n }\n // cursor ?? null: always request the paged shape so continueCursor/isDone are served\n // even on the first page — `before` stays a time-window filter, never the pager.\n const page = normalizeListPage(await kernelCall('feedback.list', {\n ...data, ...(groupId !== undefined ? { groupId } : {}), cursor: cursor ?? null, sessionId: requireTriageSessionId(),\n }));\n return result('queue', { ...page, items: truncateListItems(page.items, wantFull) });\n },\n note: async ({ action: _action, ...data }) => result('note', await kernelCall('feedback.note', { ...data, sessionId: requireTriageSessionId() })),\n group: async ({ action: _action, ...data }) => groupResult(await kernelCall<GatewayRouteReturnByName<\"feedback.group\">>('feedback.group', { ...data, sessionId: requireTriageSessionId() })),\n status: async ({ action: _action, ...data }) => result('status', await kernelCall('feedback.status', { ...data, sessionId: requireTriageSessionId() })),\n };\n\n server.registerTool('feedback', {\n title: 'Feedback — Submit & Triage',\n description: 'Submit Product Brain feedback from any agent, including with a read-only key and no session. list reads back your own workspace\\'s feedback (all statuses, no gate). Vendor operators can also queue (triage), note, group, and change queue status.',\n inputSchema: feedbackSchema,\n annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },\n }, thinWrapper(async (args) => {\n const parsed = parseOrFail(feedbackSchema, args);\n if (!parsed.ok) return parsed.result;\n return runWithToolContext({ tool: 'feedback', action: parsed.data.action }, () =>\n dispatchDiscriminated('feedback', union, parsed.data, specs, handlers));\n }));\n}\n","/**\n * Synced from convex/lib/productFeedbackConstants.ts (universal feedback wire contract).\n */\n\nexport const PRODUCT_FEEDBACK_SURFACES = ['cli', 'mcp', 'cortex', 'api', 'website'] as const;\nexport const PRODUCT_FEEDBACK_ACTORS = ['human', 'agent', 'human-via-agent'] as const;\nexport const PRODUCT_FEEDBACK_CATEGORIES = ['bug', 'friction', 'idea', 'praise', 'other'] as const;\n// WP-494 §4: 'screening' is the pre-queue quarantine status every insert stamps first —\n// added additively (schema union derives from this array).\nexport const PRODUCT_FEEDBACK_STATUSES = ['new', 'triaged', 'planned', 'resolved', 'dismissed', 'screening'] as const;\n// WP-494 §4 review fix (Codex P2): 'screening' is a SYSTEM-only status — it is stamped by\n// `insertFeedback` and cleared by `releaseFromScreening`; a vendor pushing a row BACK into\n// 'screening' via the status verb would strand it (no `screenFeedback` gets scheduled) until\n// another manual status change. Derived from the SSOT array (one place to keep them in sync)\n// so a future status addition is vendor-settable by default unless excluded here too.\n// Copilot review fix: the predicate is a TYPE GUARD, not a bare boolean. A plain\n// `.filter((s) => s !== 'screening')` does not narrow the element type, so\n// `VendorSettableStatus` below still included 'screening' at the TYPE level while runtime\n// validation rejected it — exactly the divergence the derive-from-SSOT comment above exists\n// to prevent. The guard + the explicit `Exclude<...>` alias keep types and runtime aligned.\nexport const VENDOR_SETTABLE_STATUSES = PRODUCT_FEEDBACK_STATUSES.filter(\n\t(status): status is VendorSettableStatus => status !== 'screening',\n);\n\n// Review fix (P1): `context.client` is a free-text label the CALLER supplies (MCP tool\n// arg, CLI flag) describing which specific tool submitted — NOT `PRODUCT_FEEDBACK_SURFACES`\n// (the system-derived, gateway-stamped `row.surface`). A structural allowlist of the\n// literal values every known caller sends today: packages/cli/src/commands/feedback.ts\n// ('pb-cli'), packages/mcp-server/src/tools/feedback.ts ('mcp' default), and\n// FeedbackDialog.svelte ('cortex'). `redactContext` (convex/productFeedback.ts) collapses\n// anything outside this set to 'unknown' — same fail-closed, hand-synced-allowlist posture\n// as `KNOWN_WORKSPACE_ROUTE_SEGMENTS`/`KNOWN_TOP_ROUTE_SEGMENTS`. Add a literal here ONLY\n// when a real caller starts sending it.\nexport const PRODUCT_FEEDBACK_KNOWN_CLIENTS = ['mcp', 'pb-cli', 'cortex'] as const;\n\nexport type ProductFeedbackSurface = (typeof PRODUCT_FEEDBACK_SURFACES)[number];\nexport type ProductFeedbackActor = (typeof PRODUCT_FEEDBACK_ACTORS)[number];\nexport type ProductFeedbackCategory = (typeof PRODUCT_FEEDBACK_CATEGORIES)[number];\nexport type ProductFeedbackStatus = (typeof PRODUCT_FEEDBACK_STATUSES)[number];\nexport type VendorSettableStatus = Exclude<ProductFeedbackStatus, 'screening'>;\nexport type ProductFeedbackKnownClient = (typeof PRODUCT_FEEDBACK_KNOWN_CLIENTS)[number];\n","/**\n * Shape compound tool — WP-559 (Slice 2 of WP-557, TEN-2532).\n *\n * A genuinely NEW noun (mirrors workspace.ts's own S2 precedent: \"the one genuinely NEW\n * name... every other core noun reuses an existing name\") — no existing compound tool owns\n * the shape-advisory disposition domain, and naming the actions `shape action=agree`/\n * `action=dismiss` (rather than a hypothetical `shape-agree` action on some unrelated tool)\n * avoids the noun-repeats-verb stutter the constitution's naming section flags. Mirrors the\n * CLI 1:1: `pb shape list/show/agree/dismiss` <-> `shape` tool `action=list/show/agree/dismiss`.\n *\n * Actions:\n * list — List shape advisories for this workspace, latest per subject\n * show — Show one shape advisory by id\n * agree — Agree with a compound advisory's split verdict\n * dismiss — Dismiss a compound advisory's split verdict\n *\n * agree/dismiss route through the SAME `chain.dispositionShapeAdvisory` mutation the CLI\n * calls — one business-logic path (convex/shape/disposition.ts), never a second hand-rolled\n * copy. The typed `dispositionBy` actor is derived server-side from the gateway-injected\n * `surface` (convex/http.ts's `injectSurface`, driven by the `x-pb-source` header this MCP\n * client already sends) — an MCP call's surface is always `'mcp'`, so it is always\n * classified `'agent'` (see disposition.ts's header for why credential type, which the CLI\n * and MCP share, can't be the signal here).\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { thinWrapper, parseOrFail, successResult, failureResult, type ToolResult } from \"../envelope.js\";\nimport { kernelQuery, kernelMutation, kernelCallEnvelope, getWorkspaceId, requireWriteAccess, runWithToolContext } from \"../client.js\";\nimport { dispatchDiscriminated, type ActionParamSpec } from \"../compound-tool.js\";\nimport { classifyError } from \"../errors.js\";\n\nconst SHAPE_ACTIONS = [\"list\", \"show\", \"agree\", \"dismiss\"] as const;\ntype ShapeAction = (typeof SHAPE_ACTIONS)[number];\n\nconst LIST_DISPOSITIONS = [\"pending\", \"agreed\", \"dismissed\", \"expired\"] as const;\nconst LIST_OUTCOMES = [\"not_candidate\", \"atomic\", \"compound\", \"unavailable\"] as const;\n\ninterface ShapeAdvisoryItem {\n id: string;\n outcome: string;\n disposition: string;\n subjectEntryId: string;\n collectionSlug: string;\n source: string;\n unavailableReason?: string;\n dispositionReason?: string;\n proposedAtoms?: Array<{ title: string; concern: string; bodyExcerpt: string; suggestedCollection?: string }>;\n proposedLinks?: Array<{ fromIdx: number; toIdx: number; relation: string }>;\n [key: string]: unknown;\n}\n\ninterface DispositionReceipt {\n rowId: string;\n disposition: \"agreed\" | \"dismissed\";\n dispositionBy: { kind: \"human\" | \"agent\"; personId?: string };\n}\n\n// §3a — the REGISTERED layer: flat ZodObject, action enum + superset of params.\nexport const shapeSchema = z.object({\n action: z.enum(SHAPE_ACTIONS).describe(\n \"'list': list shape advisories for this workspace, latest per subject. \" +\n \"'show': show one shape advisory by id. \" +\n \"'agree': agree with a compound advisory's split verdict. \" +\n \"'dismiss': dismiss a compound advisory's split verdict.\",\n ),\n disposition: z.enum(LIST_DISPOSITIONS).optional().describe(\n \"For 'list': filter by disposition. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound).\",\n ),\n outcome: z.enum(LIST_OUTCOMES).optional().describe(\n \"For 'list': filter by outcome. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound).\",\n ),\n limit: z.number().min(1).max(200).optional().describe(\"For 'list': max rows (default 50, max 200).\"),\n rowId: z.string().max(200).optional().describe(\"For 'show'/'agree'/'dismiss': the advisory row id.\"),\n reason: z.string().max(1000).optional().describe(\"For 'agree'/'dismiss': optional reason (capped at 1000 chars).\"),\n});\n\n// §3b — the HANDLER layer: per-action discriminatedUnion.\nconst shapeListVariant = z.object({\n action: z.literal(\"list\"),\n disposition: z.enum(LIST_DISPOSITIONS).optional(),\n outcome: z.enum(LIST_OUTCOMES).optional(),\n limit: z.number().min(1).max(200).optional(),\n});\nconst shapeShowVariant = z.object({ action: z.literal(\"show\"), rowId: z.string().max(200) });\nconst shapeAgreeVariant = z.object({ action: z.literal(\"agree\"), rowId: z.string().max(200), reason: z.string().max(1000).optional() });\nconst shapeDismissVariant = z.object({ action: z.literal(\"dismiss\"), rowId: z.string().max(200), reason: z.string().max(1000).optional() });\n\nexport const shapeActionUnion = z.discriminatedUnion(\"action\", [\n shapeListVariant,\n shapeShowVariant,\n shapeAgreeVariant,\n shapeDismissVariant,\n]);\n\n/** §4 backpressure text — one entry per action, never used for registration. */\nexport const SHAPE_ACTION_SPECS: Record<ShapeAction, ActionParamSpec> = {\n list: { params: [\"disposition\", \"outcome\", \"limit\"], description: \"All params optional; no filters defaults to disposition:pending + outcome:compound.\" },\n show: { params: [\"rowId\"], description: \"rowId is required.\" },\n agree: { params: [\"rowId\", \"reason\"], description: \"rowId is required; reason is optional.\" },\n dismiss: { params: [\"rowId\", \"reason\"], description: \"rowId is required; reason is optional.\" },\n};\n\nexport async function handleShapeList(disposition?: string, outcome?: string, limit?: number): Promise<ToolResult> {\n // Review round 4 (Codex P2): default the review queue to actionable advisories. The\n // documented list -> show -> agree/dismiss flow's normal first call passes no filters at\n // all, which requests every ledger outcome; because the backend returns only the newest 50\n // subjects, recent not_candidate/atomic/unavailable rows can push an older PENDING COMPOUND\n // row — the only outcome dispositionShapeAdvisory can actually act on — out of the page.\n // Default a fully-unfiltered call to the actionable set (disposition:pending,\n // outcome:compound); any explicitly requested filter is honored as-is, with no override.\n const noFiltersGiven = disposition === undefined && outcome === undefined;\n const effectiveDisposition = disposition ?? (noFiltersGiven ? \"pending\" : undefined);\n const effectiveOutcome = outcome ?? (noFiltersGiven ? \"compound\" : undefined);\n // WP-571 sweep fix (P1 review finding on PR #520): `chain.shapeAdvisories` was ALREADY\n // live (auto-deployed/published on every merge to main) returning a BARE ARRAY as `data` —\n // that shape must stay unchanged for already-installed clients. The LIST_SCAN_CAP\n // safety-bound signal rides `_meta.truncated` instead (convex/lib/envelopeContract.ts,\n // convex/http.ts's gateway-side unwrap for this one route), so `kernelCallEnvelope` is used\n // here (not `kernelQuery`, which strips to `.data` only) to read it back. workspaceId is\n // injected manually — kernelCallEnvelope, unlike kernelQuery, does not do this itself.\n const workspaceId = await getWorkspaceId();\n const envelope = await kernelCallEnvelope<ShapeAdvisoryItem[]>(\"chain.shapeAdvisories\", {\n ...(effectiveDisposition ? { disposition: effectiveDisposition } : {}),\n ...(effectiveOutcome ? { outcome: effectiveOutcome } : {}),\n ...(limit ? { limit } : {}),\n workspaceId,\n });\n const items = envelope.data;\n const truncated = Boolean((envelope._meta as { truncated?: boolean } | undefined)?.truncated);\n const truncationNote = \"Note: this list may be incomplete — the scan stopped at its safety bound before finding every match. Narrow disposition/outcome or raise limit and re-run.\";\n\n if (items.length === 0) {\n return successResult(\n truncated ? `No shape advisories match.\\n\\n${truncationNote}` : \"No shape advisories match.\",\n truncated ? \"No shape advisories found (result may be incomplete — safety bound reached).\" : \"No shape advisories found.\",\n { items: [], count: 0, truncated },\n );\n }\n\n const lines = [\"# Shape Advisories\", \"\"];\n for (const item of items) {\n const verdict = item.outcome === \"unavailable\" && item.unavailableReason ? `unavailable(${item.unavailableReason})` : item.outcome;\n lines.push(`- \\`${item.id}\\` — ${item.subjectEntryId} · ${verdict} · disposition:${item.disposition} · ${item.source}`);\n }\n if (truncated) lines.push(\"\", truncationNote);\n\n // Review round 3 (Codex P2): `next` must be an IMMEDIATELY actionable call — `action=show`\n // with no rowId fails shapeShowVariant's required param. Point at the first result's id\n // (a genuinely valid next step for an agent scanning the list) rather than an incomplete\n // recommendation; items.length > 0 is already guaranteed by the branch above.\n return successResult(\n lines.join(\"\\n\"),\n `Found ${items.length} shape advisor${items.length === 1 ? \"y\" : \"ies\"}.${truncated ? \" (list may be incomplete — safety bound reached)\" : \"\"}`,\n { items, count: items.length, truncated },\n [{ tool: \"shape\", description: \"Show one advisory in full\", parameters: { action: \"show\", rowId: items[0].id } }],\n );\n}\n\n/**\n * Review round 3 (Codex P2): text-content rendering of the proposed split + disposition\n * reason — MCP clients that consume only `content[0].text` (the documented backward-compatible\n * surface, envelope.ts's own header) would otherwise never see what the judge actually\n * proposed, same gap the CLI formatter (formatters/shape.ts) already closed for TTY output.\n */\nfunction renderShapeAdvisoryText(item: ShapeAdvisoryItem): string {\n const lines = [\n `# ${item.id}`,\n `- Subject: ${item.subjectEntryId} (${item.collectionSlug})`,\n `- Outcome: ${item.outcome}`,\n `- Disposition: ${item.disposition}`,\n `- Source: ${item.source}`,\n ];\n if (item.proposedAtoms?.length) {\n lines.push(\"\", `Proposed split (${item.proposedAtoms.length} atom(s)):`);\n item.proposedAtoms.forEach((atom, idx) => {\n lines.push(` [${idx}] ${atom.title} — ${atom.concern}`);\n lines.push(` \"${atom.bodyExcerpt}\"`);\n if (atom.suggestedCollection) lines.push(` suggested collection: ${atom.suggestedCollection}`);\n });\n }\n if (item.proposedLinks?.length) {\n lines.push(\"\", \"Proposed links:\");\n for (const link of item.proposedLinks) {\n const from = link.fromIdx === -1 ? \"original\" : `[${link.fromIdx}]`;\n lines.push(` ${from} --${link.relation}--> [${link.toIdx}]`);\n }\n }\n if (item.dispositionReason) lines.push(\"\", `- Disposition reason: ${item.dispositionReason}`);\n return lines.join(\"\\n\");\n}\n\nexport async function handleShapeShow(rowId: string): Promise<ToolResult> {\n const item = await kernelQuery<ShapeAdvisoryItem | null>(\"chain.showShapeAdvisory\", { rowId });\n if (!item) {\n return failureResult(\n `Advisory '${rowId}' not found (missing, or belongs to a different workspace).`,\n \"NOT_FOUND\",\n `Advisory '${rowId}' not found.`,\n \"Use action=list to find valid ids.\",\n [{ tool: \"shape\", description: \"List advisories\", parameters: { action: \"list\" } }],\n );\n }\n return successResult(\n renderShapeAdvisoryText(item),\n `Advisory ${item.id}: ${item.outcome}, disposition:${item.disposition}.`,\n item,\n );\n}\n\nexport async function handleShapeDisposition(\n disposition: \"agreed\" | \"dismissed\",\n rowId: string,\n reason?: string,\n): Promise<ToolResult> {\n requireWriteAccess();\n try {\n const result = await kernelMutation<DispositionReceipt>(\"chain.dispositionShapeAdvisory\", {\n rowId,\n disposition,\n ...(reason ? { dispositionReason: reason } : {}),\n });\n return successResult(\n `Advisory ${result.rowId} dispositioned: ${result.disposition}.`,\n `Advisory dispositioned: ${result.disposition}.`,\n result,\n );\n } catch (err: unknown) {\n // Review round 2 (Codex P2): classify via the SAME classifyError thinWrapper's own\n // catch boundary uses, instead of collapsing every backend failure into a generic\n // \"DISPOSITION_ERROR\" — preserves the real NOT_FOUND/VALIDATION_ERROR code\n // dispositionShapeAdvisory's structured ConvexError throws carry, so an agent can tell\n // \"already dispositioned\" apart from \"row doesn't exist\" instead of a bare 500-shaped blob.\n const classified = classifyError(err);\n // Review round 4 (Codex P2): classifyError's own NOT_FOUND branch always sets a generic\n // entries-oriented recovery + availableActions (\"Use entries action=search...\"), so the\n // `??` fallbacks below never select — an agent following that guidance can't discover a\n // shape-advisory row id via `entries action=search` at all. Override NOT_FOUND here with\n // `shape action=list`, the recovery that can actually locate a valid advisory.\n const isNotFound = classified.code === \"NOT_FOUND\";\n return failureResult(\n classified.message,\n classified.code,\n classified.message,\n isNotFound\n ? \"Use action=list to find valid ids.\"\n : (classified.recovery ?? \"Use action=show to check the advisory's current outcome/disposition.\"),\n isNotFound\n ? [{ tool: \"shape\", description: \"List advisories\", parameters: { action: \"list\" } }]\n : (classified.availableActions ?? [{ tool: \"shape\", description: \"Show the advisory\", parameters: { action: \"show\", rowId } }]),\n classified.diagnostics as Record<string, unknown> | undefined,\n );\n }\n}\n\nexport function registerShapeTools(server: McpServer): void {\n // §3b handler map — one entry per action, dispatched via dispatchDiscriminated.\n const shapeHandlers: Record<ShapeAction, (data: any) => Promise<ToolResult>> = {\n list: (data) => handleShapeList(data.disposition, data.outcome, data.limit),\n show: (data) => handleShapeShow(data.rowId),\n agree: (data) => handleShapeDisposition(\"agreed\", data.rowId, data.reason),\n dismiss: (data) => handleShapeDisposition(\"dismissed\", data.rowId, data.reason),\n };\n\n server.registerTool(\n \"shape\",\n {\n title: \"Shape\",\n description:\n \"Review and disposition shape-advisory (single-concern split) suggestions for this workspace. Four actions:\\n\\n\" +\n \"- **list**: List shape advisories, latest per subject (filter by disposition/outcome).\\n\" +\n \"- **show**: Show one shape advisory in full by id.\\n\" +\n \"- **agree**: Agree with a compound advisory's split verdict.\\n\" +\n \"- **dismiss**: Dismiss a compound advisory's split verdict.\",\n inputSchema: shapeSchema,\n // Mixed read/write noun (§3 R3, same as workspace's proposals-respond): agree/dismiss write;\n // list/show read.\n annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(shapeSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"shape\", action }, () =>\n dispatchDiscriminated(\"shape\", shapeActionUnion, parsed.data, SHAPE_ACTION_SPECS, shapeHandlers),\n );\n }),\n );\n}\n","/**\n * `question` — the dedicated 13th MCP tool (WP-638 S3, §4.3 of the routed-questions design\n * spec: docs/superpowers/specs/2026-08-10-routed-questions-design.md).\n *\n * `workspace` already carries 9 actions (§2); adding the eight question verbs would make 17 —\n * no per-noun ceiling in this codebase tolerates that (§4.3's own citation:\n * served-schema-shape.test.ts asserts `collections`/`map` sit exactly at the 12-action\n * ceiling). The real, already-shipped precedent for \"a noun's actions would overflow\" is to\n * split into a sibling tool (`chain`/`chain-review`), not overload the original — this file is\n * that split, same two-layer `z.discriminatedUnion('action', [...])` shape as the `shape` tool\n * (packages/mcp-server/src/tools/shape.ts).\n *\n * S3 ships SEVEN write actions — every one backed by a gateway route registered in the SAME\n * slice (convex/http.ts's `question.*` rows). `list` (the eighth action) ships in S4, in the\n * same vertical as its target read model (ackGateFacts.ts) — §4.1's slice-boundary fix.\n *\n * Confirmation/refusal strings quote §7.7 as closely as S3's available data allows. S3 has NO\n * read model yet (that ships in S4) — the write verbs (convex/questions/routingFacet.ts /\n * routingFacetVerbs.ts) were extended additively (WP-638 S3) to return the routing outcome\n * (status/suggestedRoleId/ownerRoleId/routingReason/domainSlugs/etc.) alongside `entryId` so\n * this tool can render an accurate confirmation without a second round-trip to a query that\n * does not exist yet. Role/team-lead/asker NAMES are resolved with one extra `chain.getEntry`\n * lookup (a real, already-registered read route) — never a private parser.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { thinWrapper, parseOrFail, successResult, failureResult, type ToolResult } from \"../envelope.js\";\nimport { kernelQuery, kernelMutation, requireWriteAccess, runWithToolContext } from \"../client.js\";\nimport { stripControlChars } from \"../lib/strip.js\";\nimport { dispatchDiscriminated, backpressureResult, type ActionParamSpec } from \"../compound-tool.js\";\nimport { classifyError } from \"../errors.js\";\n\n// WP-638 S4 (§4.1/§4.3's slice-boundary fix): 'list', the eighth action, joins the seven S3\n// shipped — same vertical as its target read model (ackGateFacts.ts / question.list route).\nconst QUESTION_ACTIONS = [\"create\", \"adopt\", \"assign\", \"snooze\", \"decline\", \"answer\", \"force-close\", \"list\"] as const;\ntype QuestionAction = (typeof QUESTION_ACTIONS)[number];\n\n// ─── §3a — REGISTERED layer: flat ZodObject, action enum + superset of params ──────────────\nexport const questionSchema = z.object({\n action: z.enum(QUESTION_ACTIONS).describe(\n \"'create': create a new routed question from text (domains come from `pb question --help` / this tool's own refusal — never hardcode a slug). \" +\n \"'adopt': attach routing to a tension already captured (e.g. via `pb capture \\\"TEN: ...\\\"`) — the pilot's real birth path; without adopt, captured tensions stay invisible to routing forever. \" +\n \"'assign': confirm ('take it', omit toRole/toPerson) or reassign (supply toRole and/or toPerson) ownership. \" +\n \"'snooze': defer a routed/escalated question (max 2, then it escalates). \" +\n \"'decline': pass on a suggested question, or (as owner/lead) decline an owned one — reason required. \" +\n \"'answer': close the loop — creates the answering entry itself unless --entry is given. \" +\n \"'force-close': Team-Lead-only escape hatch — reason required. \" +\n \"'list': the ack-gate read model — what you owe (or, with mine:true, every question you asked, including closed ones).\",\n ),\n entryId: z.string().max(200).optional().describe(\"Target question's id (human TEN-nnn form or a raw entry id). Required for every action except 'create'/'list'.\"),\n text: z.string().max(5000).optional().describe(\"'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars).\"),\n domain: z.string().max(200).optional().describe(\"'create'/'adopt': the domain slug (see this tool's refusal for the live list).\"),\n blocks: z.array(z.string().max(200)).max(50).optional().describe(\"'create'/'adopt': entry ids this question is blocking (repeatable).\"),\n toRole: z.string().max(200).optional().describe(\"'assign': reassign to this role (human ROL-nnn form or a raw entry id).\"),\n toPerson: z.string().max(200).optional().describe(\"'assign': reassign to this person (a raw person id).\"),\n reason: z.string().max(2000).optional().describe(\"'decline'/'force-close': required reason.\"),\n answerEntryId: z.string().max(200).optional().describe(\"'answer': point at an already-written entry instead of supplying text (mutually exclusive with text).\"),\n mine: z.boolean().optional().describe(\"'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).\"),\n});\n\n// ─── §3b — HANDLER layer: per-action discriminatedUnion ────────────────────────────────────\nconst createVariant = z.object({ action: z.literal(\"create\"), text: z.string().min(1).max(5000), domain: z.string().max(200).optional(), blocks: z.array(z.string().max(200)).max(50).optional() });\nconst adoptVariant = z.object({ action: z.literal(\"adopt\"), entryId: z.string().max(200), domain: z.string().max(200).optional(), blocks: z.array(z.string().max(200)).max(50).optional() });\nconst assignVariant = z.object({ action: z.literal(\"assign\"), entryId: z.string().max(200), toRole: z.string().max(200).optional(), toPerson: z.string().max(200).optional() });\nconst snoozeVariant = z.object({ action: z.literal(\"snooze\"), entryId: z.string().max(200) });\nconst declineVariant = z.object({ action: z.literal(\"decline\"), entryId: z.string().max(200), reason: z.string().min(1).max(2000) });\n// `text`/`answerEntryId` are both optional here — Zod's discriminatedUnion requires every\n// member to be a plain ZodObject (this file's own `questionActionUnion` type, and\n// compound-tool.ts's `ZodDiscriminatedUnion<\"action\", readonly [z.ZodObject<any>, ...]>` pin\n// it) so it can read the literal discriminator off `.shape`. A `.refine()` here would turn\n// this into a ZodEffects, which is not a ZodObject and cannot be a union member — Zod cannot\n// express \"exactly one of text/answerEntryId\" at this layer. The \"both or neither\" case is\n// therefore checked explicitly in handleQuestionAnswer via the same backpressureResult()\n// channel dispatchDiscriminated uses for every other wrong-param-combination failure.\nconst answerVariant = z.object({ action: z.literal(\"answer\"), entryId: z.string().max(200), text: z.string().max(2000).optional(), answerEntryId: z.string().max(200).optional() });\nconst forceCloseVariant = z.object({ action: z.literal(\"force-close\"), entryId: z.string().max(200), reason: z.string().min(1).max(2000) });\nconst listVariant = z.object({ action: z.literal(\"list\"), mine: z.boolean().optional() });\n\nexport const questionActionUnion = z.discriminatedUnion(\"action\", [\n createVariant, adoptVariant, assignVariant, snoozeVariant, declineVariant, answerVariant, forceCloseVariant, listVariant,\n]);\n\nexport const QUESTION_ACTION_SPECS: Record<QuestionAction, ActionParamSpec> = {\n create: { params: [\"text\", \"domain\", \"blocks\"], description: \"text is required; domain/blocks are optional.\" },\n adopt: { params: [\"entryId\", \"domain\", \"blocks\"], description: \"entryId is required (the already-captured tension); domain/blocks are optional.\" },\n assign: { params: [\"entryId\", \"toRole\", \"toPerson\"], description: \"entryId is required; omit toRole/toPerson to self-confirm, or supply one/both to reassign.\" },\n snooze: { params: [\"entryId\"], description: \"entryId is required.\" },\n decline: { params: [\"entryId\", \"reason\"], description: \"entryId and reason are both required.\" },\n answer: { params: [\"entryId\", \"text\", \"answerEntryId\"], description: \"entryId is required; supply exactly one of text or answerEntryId.\" },\n \"force-close\": { params: [\"entryId\", \"reason\"], description: \"entryId and reason are both required.\" },\n list: { params: [\"mine\"], description: \"mine is optional — omit/false for the ack-gate view, true for every question you asked.\" },\n};\n\n// ─── Human-id resolution (R43) ──────────────────────────────────────────────────────────────\n// The question write verbs declare entryId/toRoleId as v.id('entries') — a raw Convex doc id,\n// never a string parser of their own. `chain.getEntry` is the real, already-registered\n// gateway route that resolves either form (STD-102) — this tool routes through it instead of\n// inventing a private parser, satisfying R43 without touching the verbs' argument shapes.\nconst HUMAN_ID_PATTERN = /^[A-Za-z]+-\\d+$/;\n\nasync function resolveEntryRef(raw: string, label: string): Promise<string> {\n if (!HUMAN_ID_PATTERN.test(raw)) return raw;\n const entry = await kernelQuery<{ _id: string } | null>(\"chain.getEntry\", { entryId: raw });\n if (!entry) throw new Error(`${label} '${raw}' not found.`);\n return entry._id;\n}\n\n// `chain.getEntry`'s `id` param is `v.id('entries')` — it can resolve a role/domain id (both\n// live in `entries`) but NOT a `people`-table id (e.g. `askerPersonId`, `ownerPersonId`), which\n// throws an ArgumentValidationError. Caught here so a name-resolution failure (wrong table, or\n// any other lookup miss) never breaks the write confirmation it decorates — degrades to\n// undefined, never a crash. Bug found live (S3 build's own live-proof run against the seeded\n// preview): the first `answer` proof call surfaced exactly this cross-table mismatch.\nasync function displayName(id: string | undefined): Promise<string | undefined> {\n if (!id) return undefined;\n try {\n const entry = await kernelQuery<{ name?: string } | null>(\"chain.getEntry\", { id });\n // Late-merge follow-up (PR #635 review, PRRT_kwDORS4ils6YuypX, P1): every caller of this\n // helper interpolates the result straight into MCP text content — a single choke point here\n // covers every role/lead name confirmation in this file at once.\n return entry?.name ? stripControlChars(entry.name) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction domainListSuffix(domainSlugs?: string[]): string {\n if (!domainSlugs) return \"\";\n return domainSlugs.length > 0 ? ` Domains in this workspace: ${domainSlugs.join(\", \")}.` : \" No domains exist in this workspace yet.\";\n}\n\n// ─── Action handlers ─────────────────────────────────────────────────────────────────────────\n\ninterface CreateAdoptResult {\n entryId: string;\n facetId: string;\n status: \"unrouted\" | \"escalated\";\n suggestedRoleId?: string;\n ownerRoleId?: string;\n routingReason: string;\n domainSlugs: string[];\n nudge?: string;\n}\n\nasync function renderCreateAdoptConfirmation(result: CreateAdoptResult, isAdopt: boolean): Promise<string> {\n const lead = isAdopt ? `${result.entryId} is now a routed question,` : \"Question created and\";\n let base: string;\n if (result.status === \"unrouted\") {\n const roleName = (await displayName(result.suggestedRoleId)) ?? result.suggestedRoleId;\n base = isAdopt ? `${lead} suggested to ${roleName}.` : `${lead} suggested to ${roleName}. Confirm with: pb question assign ${result.entryId}`;\n } else {\n const leadName = (await displayName(result.ownerRoleId)) ?? result.ownerRoleId;\n base = isAdopt\n ? `${result.entryId} is now a routed question. Nothing here says who owns it, so it has gone to ${leadName}.`\n : `Question created. Nothing here says who owns it, so it has gone to ${leadName}.`;\n }\n const blocksHint = \" If something is blocked on this, add blocks:[<entry-id>...].\";\n const nudge = result.nudge ? ` ${result.nudge}` : \"\";\n return `${base}${domainListSuffix(result.domainSlugs)}${blocksHint}${nudge}`;\n}\n\nexport async function handleQuestionCreate(text: string, domain?: string, blocks?: string[]): Promise<ToolResult> {\n requireWriteAccess();\n try {\n const resolvedBlocks = blocks ? await Promise.all(blocks.map((b) => resolveEntryRef(b, \"Blocked entry\"))) : undefined;\n const result = await kernelMutation<CreateAdoptResult>(\"question.create\", { text, domainSlug: domain, blocks: resolvedBlocks });\n const message = await renderCreateAdoptConfirmation(result, false);\n // PRRT_kwDORS4ils6YnqKm (round 2): bare `assign` is legal ONLY from 'unrouted' (§3.9b) —\n // a born-'escalated' result (no domain, no suggestable role, ...) has no suggestion to\n // confirm, and following this next-action would hit \"already owned ... use --to-role/\n // --to-person to reassign.\" Offer it only when a suggestion actually exists.\n const next = result.status === \"unrouted\"\n ? [{ tool: \"question\", description: \"Confirm or reassign the suggestion\", parameters: { action: \"assign\", entryId: result.entryId } }]\n : undefined;\n return successResult(message, message, result, next);\n } catch (err) {\n return questionErrorResult(err, \"create\", { text, domain, blocks });\n }\n}\n\nexport async function handleQuestionAdopt(entryId: string, domain?: string, blocks?: string[]): Promise<ToolResult> {\n requireWriteAccess();\n try {\n const resolvedEntryId = await resolveEntryRef(entryId, \"Entry\");\n const resolvedBlocks = blocks ? await Promise.all(blocks.map((b) => resolveEntryRef(b, \"Blocked entry\"))) : undefined;\n const result = await kernelMutation<CreateAdoptResult>(\"question.adopt\", { entryId: resolvedEntryId, domainSlug: domain, blocks: resolvedBlocks });\n const message = await renderCreateAdoptConfirmation(result, true);\n return successResult(message, message, result);\n } catch (err) {\n return questionErrorResult(err, \"adopt\", { entryId, domain, blocks });\n }\n}\n\ninterface AssignResult { entryId: string; status: \"routed\" | \"unrouted\" | \"escalated\" | \"processed\"; ownerRoleId?: string; ownerPersonId?: string; ownerPersonName?: string }\n\nexport async function handleQuestionAssign(entryId: string, toRole?: string, toPerson?: string): Promise<ToolResult> {\n requireWriteAccess();\n try {\n const resolvedEntryId = await resolveEntryRef(entryId, \"Entry\");\n const resolvedToRoleId = toRole ? await resolveEntryRef(toRole, \"Role\") : undefined;\n const result = await kernelMutation<AssignResult>(\"question.assign\", { entryId: resolvedEntryId, toRoleId: resolvedToRoleId, toPersonId: toPerson });\n const isReassign = Boolean(toRole || toPerson);\n let message: string;\n if (isReassign) {\n // PRRT_kwDORS4ils6YnqKM (round 2): people are a separate table from entries —\n // displayName()/chain.getEntry cannot resolve a personId. Prefer the mutation's own\n // server-resolved ownerPersonName (a plain ctx.db.get, done where it can succeed) when\n // the caller named a person; only fall back to the role-name lookup otherwise.\n // Late-merge follow-up (PR #635 review, PRRT_kwDORS4ils6YuypX, P1): ownerPersonName is\n // server-resolved directly (ctx.db.get), never through displayName()'s own sanitizing\n // choke point above — sanitized here at the point of use.\n const who = toPerson ? (stripControlChars(result.ownerPersonName ?? \"\") || result.ownerPersonId || \"the target\") : ((await displayName(result.ownerRoleId)) ?? result.ownerRoleId ?? \"the target\");\n message = `${entryId} reassigned to ${who}. They'll see it at their next session.`;\n } else {\n message = `${entryId} is yours now.`;\n }\n return successResult(message, message, result);\n } catch (err) {\n return questionErrorResult(err, \"assign\", { entryId, toRole, toPerson });\n }\n}\n\ninterface SnoozeResult { entryId: string; status: \"routed\" | \"escalated\"; snoozeCount?: number; snoozeUntil?: number; ownerRoleId?: string }\n\nexport async function handleQuestionSnooze(entryId: string): Promise<ToolResult> {\n requireWriteAccess();\n try {\n const resolvedEntryId = await resolveEntryRef(entryId, \"Entry\");\n const result = await kernelMutation<SnoozeResult>(\"question.snooze\", { entryId: resolvedEntryId });\n let message: string;\n if (result.snoozeUntil) {\n message = `Snoozed until ${new Date(result.snoozeUntil).toISOString().slice(0, 10)}. ${result.snoozeCount ?? \"?\"} of 2 snoozes used.`;\n } else if (result.status === \"escalated\") {\n const leadName = (await displayName(result.ownerRoleId)) ?? \"the team lead\";\n message = `You have used both snoozes on this question — it has been escalated to ${leadName}.`;\n } else {\n message = \"No snoozes left — answer it or force-close it.\";\n }\n return successResult(message, message, result);\n } catch (err) {\n return questionErrorResult(err, \"snooze\", { entryId });\n }\n}\n\ninterface DeclineResult { entryId: string; status: \"unrouted\" | \"escalated\" | \"processed\"; suggestedRoleId?: string; ownerRoleId?: string; dependentsCount?: number; isRoot?: boolean }\n\nexport async function handleQuestionDecline(entryId: string, reason: string): Promise<ToolResult> {\n requireWriteAccess();\n try {\n const resolvedEntryId = await resolveEntryRef(entryId, \"Entry\");\n const result = await kernelMutation<DeclineResult>(\"question.decline\", { entryId: resolvedEntryId, reason });\n // `isRoot` disambiguates two branches sharing the identical {status:'escalated',\n // ownerRoleId} shape: a suggestee's PASS (§3.7a, never sets isRoot) vs an owner/lead's\n // decline (§3.7b, always sets it explicitly — true at the root, false below it).\n let message: string;\n if (result.status === \"processed\") {\n message = \"Declined and closed.\";\n } else if (result.isRoot === true) {\n message = `Declined — but ${result.dependentsCount ?? 0} item(s) still depend on it, so it stays with you. Answer it or force-close it.`;\n } else if (result.isRoot === false) {\n const leadName = (await displayName(result.ownerRoleId)) ?? result.ownerRoleId;\n message = `Declined and escalated to ${leadName}.`;\n } else if (result.suggestedRoleId) {\n const roleName = (await displayName(result.suggestedRoleId)) ?? result.suggestedRoleId;\n message = `Passed. ${entryId} is now suggested to ${roleName}.`;\n } else if (result.ownerRoleId) {\n const leadName = (await displayName(result.ownerRoleId)) ?? result.ownerRoleId;\n message = `Passed. Nobody else here owns this, so it has gone to ${leadName}.`;\n } else {\n message = \"Declined.\";\n }\n return successResult(message, message, result);\n } catch (err) {\n return questionErrorResult(err, \"decline\", { entryId, reason });\n }\n}\n\ninterface AnswerResult { entryId: string; status: \"processed\"; answerEntryId?: string; answerPending?: boolean; askerPersonId?: string; askerName?: string; idempotent?: boolean; processedVia?: \"answered\" | \"declined\" | \"force_closed\" }\n\nexport async function handleQuestionAnswer(entryId: string, text?: string, answerEntryId?: string): Promise<ToolResult> {\n // Tool-boundary check for the \"exactly one of text/answerEntryId\" rule the answerVariant\n // schema cannot express (see that variant's own comment) — structured backpressure BEFORE\n // requireWriteAccess/any write call, never a server round-trip. §7.7's declared strings.\n if (text === undefined && answerEntryId === undefined) {\n return backpressureResult(\"question\", \"answer\", QUESTION_ACTION_SPECS.answer, \"Give the answer as text, or point at an entry with --entry <id>.\");\n }\n if (text !== undefined && answerEntryId !== undefined) {\n return backpressureResult(\"question\", \"answer\", QUESTION_ACTION_SPECS.answer, \"Use either answer text or --entry, not both.\");\n }\n requireWriteAccess();\n try {\n const resolvedEntryId = await resolveEntryRef(entryId, \"Entry\");\n const resolvedAnswerEntryId = answerEntryId ? await resolveEntryRef(answerEntryId, \"Answer entry\") : undefined;\n const result = await kernelMutation<AnswerResult>(\"question.answer\", { entryId: resolvedEntryId, text, answerEntryId: resolvedAnswerEntryId });\n // PRRT_kwDORS4ils6YnqKM (round 2): people are a separate table from entries — the\n // mutation already resolves the asker's display name server-side (a plain ctx.db.get);\n // no client-side chain.getEntry lookup is attempted here, since it structurally cannot\n // reach the people table.\n // Late-merge follow-up (PR #635 review, PRRT_kwDORS4ils6YuypX, P1): server-resolved,\n // same as ownerPersonName above — sanitized at the point of use.\n const askerName = (result.askerName ? stripControlChars(result.askerName) : \"\") || \"The asker\";\n const pendingNote = result.answerPending ? \" The answer is a draft awaiting accept.\" : \"\";\n // S3's `list` action didn't exist yet (it's S4's own vertical, §4.1's slice-boundary fix),\n // so the confirmation couldn't point at it. Now that S4 has landed in this same PR (review\n // finding), restore §7.7's documented string (design spec line 1413).\n // Late #633 finding (PRRT_kwDORS4ils6YozQN): a question closed by decline/forceClose\n // reaches the SAME idempotent branch as a genuine re-answer — say \"already answered\" only\n // when it actually was; a decline/force-close reaches this same terminal `processed` state\n // via a different verb, and claiming it was \"answered\" is false. An older server response\n // that omits `processedVia` is treated as answered — the pre-fix behavior, so a caller that\n // has not yet threaded the new field never regresses.\n const message = result.idempotent\n ? result.processedVia === \"declined\" || result.processedVia === \"force_closed\"\n ? `${entryId} is already processed (${result.processedVia === \"declined\" ? \"declined\" : \"force-closed\"}) — no change.`\n : `${entryId} is already answered — no change.`\n : `Answered. ${askerName} will see the outcome at their next session (and in pb question list --mine).${pendingNote}`;\n return successResult(message, message, result);\n } catch (err) {\n return questionErrorResult(err, \"answer\", { entryId, text, answerEntryId });\n }\n}\n\ninterface ForceCloseResult { entryId: string; status: \"processed\"; idempotent?: boolean }\n\nexport async function handleQuestionForceClose(entryId: string, reason: string): Promise<ToolResult> {\n requireWriteAccess();\n try {\n const resolvedEntryId = await resolveEntryRef(entryId, \"Entry\");\n const result = await kernelMutation<ForceCloseResult>(\"question.forceClose\", { entryId: resolvedEntryId, reason });\n const message = result.idempotent ? `${entryId} is already closed — no change.` : \"Force-closed. Reason recorded.\";\n return successResult(message, message, result);\n } catch (err) {\n return questionErrorResult(err, \"force-close\", { entryId, reason });\n }\n}\n\n// ─── list (WP-638 S4, §4.1's slice-boundary fix) ────────────────────────────────────────────\n\ninterface QuestionListRow {\n entryId: string;\n question: string;\n status: string;\n stateLabel: string;\n routingReason?: string;\n why: string;\n domain: string;\n withLabel: string;\n ageDays: number;\n legalVerbs: string[];\n outcome?: string;\n /** §7.7's documented `dependents: { count, named }` MCP JSON field — pass-through from the\n * real read model (convex/questions/ackGateFacts.ts), not recomputed here. */\n dependents: { count: number; truncated?: boolean; named: { name: string; id: string }[] };\n}\ninterface ListResult { questions: QuestionListRow[]; viewerPersonId: string; truncated?: boolean }\n\n/** §7.7's `pb question list` columns, MCP-JSON twin — `state` carries the raw enum for machine\n * consumers, `stateLabel` the human string (§7.8: both, never a choice between parseable and\n * readable). Empty list: `No open questions.` / `--mine`: `You haven't asked any questions yet.` */\nexport async function handleQuestionList(mine?: boolean): Promise<ToolResult> {\n try {\n const result = await kernelQuery<ListResult>(\"question.list\", { mine });\n const rows = result.questions;\n if (rows.length === 0) {\n const message = mine ? \"You haven't asked any questions yet.\" : \"No open questions.\";\n return successResult(message, message, { ...result, action: \"list\" });\n }\n // Late-merge follow-up (PR #635 review, PRRT_kwDORS4ils6YuypX, P1): every one of these\n // fields is workspace-controlled (question text, domain/role/person names via `why`/\n // `withLabel`, an outcome string) and reaches MCP text content verbatim — an MCP client\n // that prints tool output to a terminal (many do) inherits the same ANSI/control-char\n // injection risk BET-269 C3 guards on the CLI side. Same sanitizer, synced (lib/strip.ts).\n const lines = rows.map((r) => {\n const outcomeSuffix = mine && r.outcome ? ` — ${stripControlChars(r.outcome)}` : \"\";\n return `[${stripControlChars(r.entryId)}] ${stripControlChars(r.question)} — ${stripControlChars(r.stateLabel)} — ${stripControlChars(r.why)} — ${stripControlChars(r.domain)} — ${stripControlChars(r.withLabel)} — ${r.ageDays}d${outcomeSuffix}`;\n });\n // Review finding: the scan is honestly capped — a caller past the cap must be told the list\n // isn't exhaustive (the machine `truncated` field already carried this; only the human-readable\n // text was silent about it).\n const truncationNote = result.truncated\n ? `\\n(${mine ? \"showing your most recent questions only — older ones exist but are not shown\" : \"this list may be incomplete — some obligations may not be shown\"})`\n : \"\";\n const message = `${rows.length} question${rows.length === 1 ? \"\" : \"s\"}:\\n${lines.join(\"\\n\")}${truncationNote}`;\n return successResult(message, message, { ...result, action: \"list\" });\n } catch (err) {\n return questionErrorResult(err, \"list\", { mine });\n }\n}\n\n/** Shared error->ToolResult mapping — preserves the structured code the Core functions throw\n * (VALIDATION_FAILED / AUTHZ_PERMISSION_DENIED / NOT_FOUND) rather than a generic 500 shape. */\nfunction questionErrorResult(err: unknown, action: QuestionAction, params: Record<string, unknown> = {}): ToolResult {\n const classified = classifyError(err);\n // PRRT_kwDORS4ils6YnqKu (round 2): `{action}` alone is missing every OTHER required field\n // the real schema declares (e.g. `text` for create, `entryId` for snooze, `entryId`+`reason`\n // for decline) — an MCP client following it would fail the tool's own registered-layer\n // validation before retrying anything. Preserve the caller's ORIGINAL params (minus\n // undefined values, so an omitted optional field doesn't get advertised as required).\n const definedParams = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== undefined));\n // Late #633 finding (PRRT_kwDORS4ils6YozQI): a VALIDATION_ERROR is a deterministic refusal —\n // the same arguments against the same server/facet state fail identically (an exhausted\n // snooze, an unknown domain slug), so offering \"retry unchanged\" as availableActions would\n // let an MCP agent loop on it forever. Omit the unchanged-retry fallback for this one code;\n // every other unclassified code here (BACKEND_UNAVAILABLE, GATEWAY_TIMEOUT, rate-limited's own\n // recovery text, a genuinely unmapped convexCode) can legitimately succeed on a bare retry.\n const fallbackActions = classified.code === \"VALIDATION_ERROR\"\n ? undefined\n : [{ tool: \"question\", description: `Retry ${action}`, parameters: { action, ...definedParams } }];\n return failureResult(\n classified.message,\n classified.code,\n classified.message,\n classified.recovery ?? \"Use action='create' with no --domain, or `pb question --help` / this tool's description, to find valid domains and next steps.\",\n classified.availableActions ?? fallbackActions,\n classified.diagnostics as Record<string, unknown> | undefined,\n );\n}\n\nexport function registerQuestionTools(server: McpServer): void {\n const questionHandlers: Record<QuestionAction, (data: any) => Promise<ToolResult>> = {\n create: (data) => handleQuestionCreate(data.text, data.domain, data.blocks),\n adopt: (data) => handleQuestionAdopt(data.entryId, data.domain, data.blocks),\n assign: (data) => handleQuestionAssign(data.entryId, data.toRole, data.toPerson),\n snooze: (data) => handleQuestionSnooze(data.entryId),\n decline: (data) => handleQuestionDecline(data.entryId, data.reason),\n answer: (data) => handleQuestionAnswer(data.entryId, data.text, data.answerEntryId),\n \"force-close\": (data) => handleQuestionForceClose(data.entryId, data.reason),\n list: (data) => handleQuestionList(data.mine),\n };\n\n server.registerTool(\n \"question\",\n {\n title: \"Question\",\n description:\n \"Routed questions — a question with no owner routes itself to the owning role, the team lead when ambiguous, and up the team-lead chain until someone owns it. Eight actions:\\n\\n\" +\n \"- **create**: create a new routed question from text. Domains are discovered by using this tool — an unresolvable `domain` refusal lists the workspace's real slugs; there is no fixed list to memorize.\\n\" +\n \"- **adopt**: attach routing to a tension already captured (e.g. via `capture` with `collection: tensions`) — the real birth path for most questions. Without adopt, a captured tension stays invisible to routing forever.\\n\" +\n \"- **assign**: confirm ('take it', no `toRole`/`toPerson`) or reassign (`toRole`/`toPerson`) ownership.\\n\" +\n \"- **snooze**: defer a routed/escalated question — max 2, then it escalates to the team lead.\\n\" +\n \"- **decline**: pass on a suggested question (never closes it), or — as the owner/team lead — decline an owned one (reason required; closes it, or escalates it, depending on dependents).\\n\" +\n \"- **answer**: close the loop. Creates the answering entry itself from `text`, or points at an existing one via `answerEntryId` — never both.\\n\" +\n \"- **force-close**: Team-Lead-only escape hatch (reason required) for a question that cannot otherwise be resolved.\\n\" +\n \"- **list**: the ack-gate read model — what you owe (`mine:false`, the default), or (`mine:true`) every question you asked, including closed ones, with its outcome.\\n\\n\" +\n \"`blocks` (repeatable, on create/adopt) records what a question is holding up — pass entry ids it blocks.\",\n inputSchema: questionSchema,\n annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false },\n },\n thinWrapper(async (args) => {\n const parsed = parseOrFail(questionSchema, args);\n if (!parsed.ok) return parsed.result;\n const { action } = parsed.data;\n\n return runWithToolContext({ tool: \"question\", action }, () =>\n dispatchDiscriminated(\"question\", questionActionUnion, parsed.data, QUESTION_ACTION_SPECS, questionHandlers),\n );\n }),\n );\n}\n","/**\n * Late-merge follow-up (PR #635 review, PRRT_kwDORS4ils6YuypX, P1) — synced from\n * packages/cli/src/lib/strip.ts's stripControlChars (BET-269 C3: terminal escaping). MCP is a\n * separate build target that cannot import packages/cli at build time (BR-25, this package's own\n * lib/README.md) — this is a same-name, same-regex sync, not an independent reimplementation.\n *\n * Strip ANSI escape sequences and control characters from workspace-controlled strings before\n * they reach MCP text content. A client that renders tool output in a terminal (many do)\n * inherits the same terminal-injection risk the CLI already guards against — a question,\n * domain, role/person name, or outcome string can carry cursor-movement/color/title-change\n * escape sequences the caller never typed.\n */\n\n// Note: the CSI/OSC alternatives MUST precede the bare control-char class — see\n// packages/cli/src/lib/strip.ts's own comment for why (regex alternation takes the first\n// matching alternative at a position, not the longest).\n// Late-fix consolidation round 1 (PRRT_kwDORS4ils6Y0pz3, P1): \\x0b-\\x1f is one contiguous\n// range so a bare carriage return (\\x0d) is stripped too — see packages/cli/src/lib/strip.ts's\n// own comment for the terminal-injection rationale (\\r moves the cursor to column zero and\n// can overwrite/spoof the start of a line; \\t/\\n are preserved for legitimate multiline use).\n// eslint-disable-next-line no-control-regex\nconst ANSI_AND_CONTROL_RE = /\\x1b\\[[0-9;]*[A-Za-z]|\\x1b\\][^\\x07]*\\x07|\\x1b[^[\\]0-9;A-Za-z]?|[\\x00-\\x08\\x0b-\\x1f\\x7f]/g;\n\nexport function stripControlChars(str: string): string {\n if (!str) return str;\n return str.replace(ANSI_AND_CONTROL_RE, \"\");\n}\n","import type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { kernelQuery, getWorkspaceContext } from \"../client.js\";\nimport { trackCaptureContractMiss } from \"../analytics.js\";\nimport { AGENT_CHEATSHEET } from \"./agentCheatsheet.js\";\n\nexport { AGENT_CHEATSHEET } from \"./agentCheatsheet.js\";\n\n/** MCP App View HTML bundles — served so Cursor/Claude can render tool UIs */\nconst UI_VIEWS: Record<string, string> = {\n \"ui://entries/entry-cards.html\": \"src/entry-cards/index.html\",\n \"ui://graph/constellation.html\": \"src/graph-constellation/index.html\",\n};\n\nexport const UI_RESOURCE_MIME_TYPE = \"text/html;profile=mcp-app\";\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\nconst UI_VIEW_BASE_CANDIDATES = [\n resolve(MODULE_DIR, \"views\"),\n resolve(MODULE_DIR, \"..\", \"views\"),\n resolve(MODULE_DIR, \"..\", \"..\", \"dist\", \"views\"),\n resolve(MODULE_DIR, \"..\", \"..\", \"..\", \"mcp-views\", \"dist\"),\n];\n\nexport function resolveUiViewPath(\n filePath: string,\n options?: {\n moduleDir?: string;\n pathExists?: (path: string) => boolean;\n },\n): string | null {\n const moduleDir = options?.moduleDir ?? MODULE_DIR;\n const pathExists = options?.pathExists ?? existsSync;\n const candidateBases = options?.moduleDir\n ? [\n resolve(moduleDir, \"views\"),\n resolve(moduleDir, \"..\", \"views\"),\n resolve(moduleDir, \"..\", \"..\", \"dist\", \"views\"),\n resolve(moduleDir, \"..\", \"..\", \"..\", \"mcp-views\", \"dist\"),\n ]\n : UI_VIEW_BASE_CANDIDATES;\n\n for (const candidateBase of candidateBases) {\n const candidatePath = join(candidateBase, filePath);\n if (pathExists(candidatePath)) {\n return candidatePath;\n }\n }\n\n return null;\n}\n\nfunction renderMissingUiView(uri: string): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Product Brain View Unavailable</title>\n <style>\n body {\n margin: 0;\n padding: 20px;\n font-family: system-ui, sans-serif;\n background: #0f172a;\n color: #e2e8f0;\n }\n .panel {\n max-width: 720px;\n margin: 0 auto;\n padding: 20px;\n border: 1px solid #334155;\n border-radius: 12px;\n background: #111827;\n }\n h1 {\n margin: 0 0 12px;\n font-size: 18px;\n }\n p {\n margin: 0 0 10px;\n line-height: 1.5;\n }\n code {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n color: #93c5fd;\n }\n </style>\n</head>\n<body>\n <main class=\"panel\">\n <h1>Product Brain view unavailable</h1>\n <p>The UI resource <code>${uri}</code> could not be loaded.</p>\n <p>If this is a local checkout, rebuild the MCP views bundle. If this is an installed package, the published package is missing its bundled views.</p>\n </main>\n</body>\n</html>`;\n}\n\n// ─── Response Types ──────────────────────────────────────────────────\n\ninterface EntryListItem {\n _id: string;\n entryId?: string;\n name: string;\n status: string;\n collectionName?: string;\n collectionSlug?: string;\n data?: Record<string, unknown>;\n}\n\ninterface EntryRelation {\n type: string;\n direction: \"outgoing\" | \"incoming\";\n otherEntryId: string | null;\n otherName: string | null;\n}\n\ninterface EntryDetail extends EntryListItem {\n relations?: EntryRelation[];\n labels?: Array<{ name: string; slug: string; color?: string }>;\n history?: Array<{ action: string; timestamp: number; actor?: string }>;\n}\n\ninterface Collection {\n _id: string;\n name: string;\n slug: string;\n description?: string;\n icon?: string;\n fields: Array<{ key: string; type: string; required?: boolean; searchable?: boolean }>;\n}\n\ninterface LabelRecord {\n _id: string;\n name: string;\n slug: string;\n color?: string;\n isGroup?: boolean;\n parentId?: string;\n}\n\ninterface CaptureContractField {\n key: string;\n required: boolean;\n type: string;\n helpText?: string;\n}\n\ninterface CaptureContractResult {\n collectionSlug: string;\n requiredFields: string[];\n allFields: CaptureContractField[];\n captureExpectation?: string;\n}\n\n// `ContextResult` (a hand-written local mirror) retired — PR #395, Lane C S3b annotation\n// pass. `result` below is typed via `GatewayRouteReturnByName<\"chain.gatherContext\">` (the\n// real server-derived shape); the one remaining consumer (`byCollection` below) derives\n// its Map value type from that route directly instead of a second, drifting mirror.\ntype GatherContextResult = GatewayRouteReturnByName<\"chain.gatherContext\">;\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\nfunction formatEntryMarkdown(entry: EntryListItem): string {\n const id = entry.entryId ? `${entry.entryId}: ` : \"\";\n const lines = [`## ${id}${entry.name} [${entry.status}]`];\n if (entry.data && typeof entry.data === \"object\") {\n for (const [key, val] of Object.entries(entry.data)) {\n if (val && key !== \"rawData\") {\n lines.push(`**${key}**: ${typeof val === \"string\" ? val : JSON.stringify(val)}`);\n }\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction buildOrientationMarkdown(\n collections: Collection[] | null,\n trackingEvents: EntryListItem[] | null,\n standards: EntryListItem[] | null,\n businessRules: EntryListItem[] | null,\n principles: EntryListItem[] | null,\n): string {\n const sections: string[] = [\"# Product Brain — Orientation\"];\n\n // About Product Brain (the tool)\n sections.push(\n \"## About Product Brain (PB)\\n\" +\n \"PB is a knowledge management system used by many product teams. \" +\n \"This section describes how PB works — not your product.\\n\\n\" +\n \"### How PB Organizes Its Tools\\n\" +\n \"- **Tools** = actions with side-effects or dynamic computation (capture, accept, search).\\n\" +\n \"- **Resources** = stable, read-only data (orientation, terminology, collection schemas).\\n\" +\n \"- **Prompts** = multi-step choreography (workflows, guided capture, deep dives).\\n\" +\n \"- Every tool, resource, and prompt works for ANY workspace — no bespoke logic.\\n\" +\n \"- Resource templates (URI params) serve workspace-specific data through generic patterns.\\n\" +\n \"- Compound tools with `action` enums keep the tool count minimal.\\n\\n\" +\n \"### How PB Handles Your Data\\n\" +\n \"- **Draft-first**: all writes create drafts. SSOT requires explicit user confirmation.\\n\" +\n \"- **Empty-workspace safe**: every operation handles zero entries and fresh workspaces.\\n\" +\n \"- **Advisory, not blocking**: quality scores, contradiction checks, and coaching never prevent operations.\\n\" +\n \"- **Workspace-agnostic**: PB is a product for many teams — no workspace-specific logic.\\n\" +\n \"- **Self-documenting**: orient and server instructions teach agents how PB works.\",\n );\n\n // Workspace principles, standards, and rules from the Chain\n const wsRules: Array<{ id: string; name: string; severity?: string; source: string }> = [];\n\n for (const p of (principles ?? []).filter((e) => e.status === \"active\" || e.status === \"verified\")) {\n wsRules.push({ id: p.entryId ?? \"\", name: p.name, severity: (p.data?.severity as string) ?? undefined, source: \"principles\" });\n }\n for (const s of (standards ?? []).filter((e) => e.status === \"active\" || e.status === \"verified\")) {\n wsRules.push({ id: s.entryId ?? \"\", name: s.name, severity: (s.data?.severity as string) ?? undefined, source: \"standards\" });\n }\n for (const r of (businessRules ?? []).filter((e) => e.status === \"active\" || e.status === \"verified\")) {\n wsRules.push({ id: r.entryId ?? \"\", name: r.name, severity: (r.data?.severity as string) ?? undefined, source: \"business-rules\" });\n }\n\n if (wsRules.length > 0) {\n const ruleLines = wsRules\n .map((r) => {\n const sev = r.severity ? ` [${r.severity}]` : \"\";\n return `- **${r.id}**: ${r.name}${sev}`;\n })\n .join(\"\\n\");\n sections.push(\n `## Your Workspace Principles & Rules (${wsRules.length} active)\\n` +\n \"These are principles, standards, and rules your team has accepted onto the Chain. \" +\n \"Respect them during implementation.\\n\\n\" +\n ruleLines + \"\\n\\n\" +\n 'Use `entries action=get entryId=\"<ID>\"` to drill into any rule before making changes in that area.',\n );\n } else {\n sections.push(\n \"## Your Workspace Principles & Rules\\n\" +\n \"No active principles, standards, or business rules on the Chain yet.\\n\" +\n \"Use `capture` with collection `principles`, `standards`, or `business-rules` to add your team's guardrails.\\n\" +\n \"Once accepted, they appear here at orient time — so every agent session starts with your rules visible.\",\n );\n }\n\n // Core Product Architecture (the three primitives)\n sections.push(\n \"## Core Product Architecture\\n\" +\n \"The Chain is a versioned, connected, compounding knowledge base — the SSOT for a product team.\\n\" +\n \"Everything on the Chain is one of **three primitives**:\\n\\n\" +\n \"- **Entry** (atom) — a discrete knowledge unit: target audience, business rule, glossary term, metric, tension. Lives in a collection.\\n\" +\n \"- **Process** (authored) — a narrative chain with named links (Strategy Coherence, IDM Proposal). Content is inline text. Collection: `chains`.\\n\" +\n \"- **Map** (composed) — a framework assembled by reference (Lean Canvas, Empathy Map). Slots point to ingredient entries. Collection: `maps`.\\n\\n\" +\n \"Entries are atoms. Processes author narrative from atoms. Maps compose frameworks from atoms.\\n\" +\n \"All three share the same versioning, branching, gating, and relation system.\\n\\n\" +\n \"The Chain compounds: each new relation makes entries discoverable from more starting points → \" +\n \"context gathering returns richer results → AI processes have more context → quality scores improve → \" +\n \"next accept is smarter than the last.\",\n );\n\n // Architecture\n sections.push(\n \"## Architecture\\n\" +\n \"```\\n\" +\n \"Cursor (stdio) → MCP Server (mcp-server/src/index.ts)\\n\" +\n \" → POST /api/aki with Bearer token\\n\" +\n \" → Convex HTTP Action (convex/http.ts)\\n\" +\n \" → internalQuery / internalMutation (convex/agentKnowledge/*)\\n\" +\n \" → Convex DB (workspace-scoped)\\n\" +\n \"```\\n\" +\n \"Security: API key auth on every request, workspace-scoped data, internal functions blocked from external clients.\\n\" +\n \"Key files: `packages/mcp-server/src/client.ts` (HTTP client + audit), `convex/schema.ts` (schema).\",\n );\n\n // Data model\n if (collections) {\n const collList = collections\n .map((c) => {\n const prefix = c.icon ? `${c.icon} ` : \"\";\n return `- ${prefix}**${c.name}** (\\`${c.slug}\\`) — ${c.description || \"no description\"}`;\n })\n .join(\"\\n\");\n sections.push(\n `## Data Model (${collections.length} collections)\\n` +\n \"Unified entries model: collections define field schemas, entries hold data in a flexible `data` field.\\n\" +\n \"The `data` field is polymorphic: plain fields for generic entries, `ChainData` (chainTypeId + links) for processes, `MapData` (templateId + slots) for maps.\\n\" +\n \"Tags for filtering (e.g. `severity:high`), relations via `entryRelations`, versions via `entryVersions`, labels via `labels` + `entryLabels`.\\n\\n\" +\n collList + \"\\n\\n\" +\n \"Use `collections action=list` for field schemas, `entries action=get` for full records.\",\n );\n } else {\n sections.push(\n \"## Data Model\\n\" +\n \"Could not load collections — use `collections action=list` to browse manually.\",\n );\n }\n\n // Business rules\n const rulesCount = businessRules ? `${businessRules.length} entries` : \"not loaded — collection may not exist yet\";\n sections.push(\n \"## Business Rules\\n\" +\n `Collection: \\`business-rules\\` (${rulesCount}).\\n` +\n \"Find rules: `entries action=search` for text search, `entries action=list collection=business-rules` to browse.\\n\" +\n \"Check compliance: use the `review-against-rules` prompt (pass a domain).\\n\" +\n \"Draft a new rule: use the `draft-rule-from-context` prompt.\",\n );\n\n // Analytics / tracking\n const eventsCount = trackingEvents ? `${trackingEvents.length} events` : \"not loaded — collection may not exist yet\";\n const conventionNote = standards\n ? \"Naming convention: `object_action` in snake_case with past-tense verbs (from standards collection).\"\n : \"Naming convention: `object_action` in snake_case with past-tense verbs.\";\n sections.push(\n \"## Analytics & Tracking\\n\" +\n `Event catalog: \\`tracking-events\\` collection (${eventsCount}).\\n` +\n `${conventionNote}\\n` +\n \"Implementation: `src/lib/analytics.ts`. Workspace-scoped events MUST use `withWorkspaceGroup()`.\\n\" +\n \"Browse: `entries action=list collection=tracking-events`.\",\n );\n\n // Knowledge Graph\n sections.push(\n \"## Knowledge Graph\\n\" +\n \"Entries are connected via typed relations (`entryRelations` table). Relations are bidirectional and collection-agnostic — any entry can link to any other entry.\\n\\n\" +\n \"**Recommended relation types** (extensible — any string accepted):\\n\" +\n \"- `governs` — a rule constrains behavior of a feature\\n\" +\n \"- `defines_term_for` — a glossary term is canonical vocabulary for a feature/area\\n\" +\n \"- `belongs_to` — a feature belongs to a product area or parent concept (WP-641 typed successors: `anchored_to`, `authority_domain`)\\n\" +\n \"- `informs` — a decision or insight informs a feature\\n\" +\n \"- `fills_slot` — an ingredient entry fills a slot in a map\\n\" +\n \"- `surfaces_tension_in` — a tension exists within a feature area\\n\" +\n \"- `related_to`, `depends_on`, `replaces`, `conflicts_with`, `references`, `confused_with`\\n\\n\" +\n \"Each relation type is defined as a glossary entry (prefix `GT-REL-*`) to prevent terminology drift. **Workflow-owned, NOT generic:** `domain_routed_to` (a question routed to a domain) — use the `question` tool (`action=create`/`adopt`, `domain=<slug>`), never `relations action=create`; the generic door has no replace/re-judge logic, so a raw write can leave duplicate routing edges and a stale suggested owner.\\n\\n\" +\n \"**Tools:**\\n\" +\n \"- `context action=gather` — get the full context around any entry (multi-hop graph traversal)\\n\" +\n \"- `relations action=suggest` — discover potential connections for an entry\\n\" +\n \"- `relations action=create` — create a typed link between two entries\\n\" +\n \"- `relations action=find` — list direct relations for an entry\\n\\n\" +\n \"**Convention:** When creating or updating entries in governed collections, always use `relations action=suggest` to discover and create relevant relations.\",\n );\n\n // Creating Knowledge\n sections.push(\n \"## Creating Knowledge\\n\" +\n \"**Entries:** Use `capture` as the primary tool for creating new entries. It handles the full workflow in one call:\\n\" +\n \"1. Creates the entry with collection-aware defaults (auto-fills dates, infers domains, sets priority)\\n\" +\n \"2. Auto-links related entries from across the chain (up to 5 confident matches)\\n\" +\n \"3. Returns a quality scorecard (X/10) with actionable improvement suggestions\\n\\n\" +\n \"**Smart profiles** exist for: `tensions`, `business-rules`, `glossary`, `decisions`, `features`, `audiences`, `strategy`, `standards`, `maps`, `chains`, `tracking-events`.\\n\" +\n \"All other collections use the `ENT-{random}` fallback profile.\\n\\n\" +\n \"**Processes:** Use `chain action=create` with a template (e.g., `strategy-coherence`, `idm-proposal`). Fill links with `chain action=edit`.\\n\\n\" +\n \"**Prompts** (invoke via MCP prompt protocol):\\n\" +\n \"- `name-check` — verify a name against glossary conventions\\n\" +\n \"- `draft-decision-record` — scaffold a decision entry\\n\" +\n \"- `review-against-rules` — check work against business rules for a domain\\n\" +\n \"- `draft-rule-from-context` — create a new business rule from context\\n\\n\" +\n \"Use `quality action=check` to score existing entries retroactively.\\n\" +\n \"Use `entries action=update` for post-creation adjustments (status changes, field updates, deprecation).\",\n );\n\n // Where to go next\n sections.push(\n \"## Where to Go Next\\n\" +\n \"- **Create entry** → `capture` tool (auto-links + quality score in one call)\\n\" +\n \"- **Full context** → `context action=gather` (by entry ID or task description)\\n\" +\n \"- **Discover links** → `relations action=suggest`\\n\" +\n \"- **Quality audit** → `quality action=check`\\n\" +\n \"- **Terminology** → `name-check` prompt or `productbrain://terminology` resource\\n\" +\n \"- **Schema details** → `productbrain://collections` resource or `collections action=list`\\n\" +\n \"- **Labels** → `productbrain://labels` resource or `collections action=label-list`\\n\" +\n \"- **Any collection** → `productbrain://{slug}/entries` resource\\n\" +\n \"- **Log a decision** → `draft-decision-record` prompt\\n\" +\n \"- **Growth funnel** → `productbrain://growth-funnel` resource or `entries action=list collection=strategy status=draft`\\n\" +\n \"- **Audiences** → `productbrain://audiences/entries` resource or `entries action=list collection=audiences`\\n\" +\n \"- **Session identity** → `workspace action=whoami`\\n\" +\n \"- **Health check** → `workspace action=check`\\n\" +\n \"- **Debug MCP calls** → `workspace action=audit`\",\n );\n\n return sections.join(\"\\n\\n---\\n\\n\");\n}\n\nexport function registerResources(server: McpServer) {\n // Agent cheatsheet: compact tool/schema reference (~500 tokens)\n server.resource(\n \"agent-cheatsheet\",\n \"productbrain://agent-cheatsheet\",\n async (uri) => ({\n contents: [{\n uri: uri.href,\n text: AGENT_CHEATSHEET,\n mimeType: \"text/markdown\",\n }],\n })\n );\n\n // Orientation: single-call system map for AI developers\n server.resource(\n \"chain-orientation\",\n \"productbrain://orientation\",\n async (uri) => {\n const [collectionsResult, eventsResult, standardsResult, rulesResult, principlesResult] = await Promise.allSettled([\n kernelQuery<Collection[]>(\"chain.listCollections\"),\n kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"tracking-events\" }),\n kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"standards\" }),\n kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"business-rules\" }),\n kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"principles\" }),\n ]);\n\n const collections = collectionsResult.status === \"fulfilled\" ? collectionsResult.value : null;\n const trackingEvents = eventsResult.status === \"fulfilled\" ? eventsResult.value : null;\n const standards = standardsResult.status === \"fulfilled\" ? standardsResult.value : null;\n const businessRules = rulesResult.status === \"fulfilled\" ? rulesResult.value : null;\n const principles = principlesResult.status === \"fulfilled\" ? principlesResult.value : null;\n\n return {\n contents: [{\n uri: uri.href,\n // `chain.listEntries`'s real return is a union (raw EntryDoc[] vs Record<string,\n // unknown>[] depending on field projection, see wrapup.ts's own doc comment on this\n // recurring residual) — `EntryListItem` only reads a documented subset of fields\n // present on both union branches; cast rather than widen the render helper's\n // signature to the full server union (PR #395, Lane C S3b annotation pass).\n text: buildOrientationMarkdown(\n collections,\n trackingEvents as EntryListItem[] | null,\n standards as EntryListItem[] | null,\n businessRules as EntryListItem[] | null,\n principles as EntryListItem[] | null,\n ),\n mimeType: \"text/markdown\",\n }],\n };\n }\n );\n\n // Terminology: glossary + standards summary for deep-dives\n server.resource(\n \"chain-terminology\",\n \"productbrain://terminology\",\n async (uri) => {\n const [glossaryResult, standardsResult] = await Promise.allSettled([\n kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"glossary\" }),\n kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"standards\" }),\n ]);\n\n const lines: string[] = [\"# Product Brain — Terminology\"];\n\n if (glossaryResult.status === \"fulfilled\") {\n const glossary = glossaryResult.value ?? [];\n if (glossary.length > 0) {\n const terms = glossary\n .map((t) => `- **${t.name}** (${t.entryId ?? \"—\"}) [${t.status}]: ${t.data?.canonical ?? t.data?.description ?? \"\"}`)\n .join(\"\\n\");\n lines.push(`## Glossary (${glossary.length} terms)\\n\\n${terms}`);\n } else {\n lines.push(\"## Glossary\\n\\nNo glossary terms yet. Use `capture` with collection `glossary` to add terms.\");\n }\n } else {\n lines.push(\"## Glossary\\n\\nCould not load glossary — use `entries action=list collection=glossary` to browse manually.\");\n }\n\n if (standardsResult.status === \"fulfilled\") {\n const standards = standardsResult.value ?? [];\n if (standards.length > 0) {\n const stds = standards\n .map((s) => `- **${s.name}** (${s.entryId ?? \"—\"}) [${s.status}]: ${s.data?.description ?? \"\"}`)\n .join(\"\\n\");\n lines.push(`## Standards (${standards.length} entries)\\n\\n${stds}`);\n } else {\n lines.push(\"## Standards\\n\\nNo standards yet. Use `capture` with collection `standards` to add standards.\");\n }\n } else {\n lines.push(\"## Standards\\n\\nCould not load standards — use `entries action=list collection=standards` to browse manually.\");\n }\n\n return {\n contents: [{ uri: uri.href, text: lines.join(\"\\n\\n---\\n\\n\"), mimeType: \"text/markdown\" }],\n };\n }\n );\n\n server.resource(\n \"chain-collections\",\n \"productbrain://collections\",\n async (uri) => {\n const collections = (await kernelQuery<Collection[]>(\"chain.listCollections\")) ?? [];\n\n if (collections.length === 0) {\n return { contents: [{ uri: uri.href, text: \"No collections in this workspace. Use `collections action=create` or `start` with a preset to get started.\", mimeType: \"text/markdown\" }] };\n }\n\n const formatted = collections\n .map((c) => {\n const fieldList = (c.fields ?? [])\n .map((f) => ` - \\`${f.key}\\` (${f.type}${f.required ? \", required\" : \"\"}${f.searchable ? \", searchable\" : \"\"})`)\n .join(\"\\n\");\n return `## ${c.icon ?? \"\"} ${c.name} (\\`${c.slug}\\`)\\n${c.description || \"\"}\\n\\n**Fields:**\\n${fieldList}`;\n })\n .join(\"\\n\\n---\\n\\n\");\n\n return {\n contents: [{ uri: uri.href, text: `# Knowledge Collections (${collections.length})\\n\\n${formatted}`, mimeType: \"text/markdown\" }],\n };\n }\n );\n\n server.resource(\n \"chain-collection-entries\",\n new ResourceTemplate(\"productbrain://{slug}/entries\", {\n list: async () => {\n const collections = (await kernelQuery<Collection[]>(\"chain.listCollections\")) ?? [];\n return {\n resources: collections.map((c) => ({\n uri: `productbrain://${c.slug}/entries`,\n name: `${c.icon ?? \"\"} ${c.name}`.trim(),\n })),\n };\n },\n }),\n async (uri, { slug }) => {\n // Same documented `chain.listEntries` union-vs-narrow-render-type cast as above.\n const entries = ((await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: slug as string })) ?? []) as EntryListItem[];\n const formatted = entries.map(formatEntryMarkdown).join(\"\\n\\n---\\n\\n\");\n\n return {\n contents: [{\n uri: uri.href,\n text: formatted || \"No entries in this collection.\",\n mimeType: \"text/markdown\",\n }],\n };\n }\n );\n\n server.resource(\n \"chain-labels\",\n \"productbrain://labels\",\n async (uri) => {\n const labels = (await kernelQuery<LabelRecord[]>(\"chain.listLabels\")) ?? [];\n\n if (labels.length === 0) {\n return { contents: [{ uri: uri.href, text: \"No labels in this workspace.\", mimeType: \"text/markdown\" }] };\n }\n\n const groups = labels.filter((l) => l.isGroup);\n const ungrouped = labels.filter((l) => !l.isGroup && !l.parentId);\n const children = (parentId: string) => labels.filter((l) => l.parentId === parentId);\n\n const lines: string[] = [];\n for (const group of groups) {\n lines.push(`## ${group.name}`);\n for (const child of children(group._id)) {\n lines.push(`- \\`${child.slug}\\` ${child.name}${child.color ? ` (${child.color})` : \"\"}`);\n }\n }\n if (ungrouped.length > 0) {\n lines.push(\"## Ungrouped\");\n for (const l of ungrouped) {\n lines.push(`- \\`${l.slug}\\` ${l.name}${l.color ? ` (${l.color})` : \"\"}`);\n }\n }\n\n return {\n contents: [{ uri: uri.href, text: `# Workspace Labels (${labels.length})\\n\\n${lines.join(\"\\n\")}`, mimeType: \"text/markdown\" }],\n };\n }\n );\n\n server.resource(\n \"chain-entry\",\n new ResourceTemplate(\"productbrain://entries/{entryId}\", {\n list: undefined,\n complete: {\n entryId: async (value) => {\n if (!value || value.length < 1) return [];\n const entries = (await kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: value })) ?? [];\n return entries.slice(0, 10).map((e) => e.entryId ?? e._id);\n },\n },\n }),\n async (uri, { entryId }) => {\n const [entry, collections] = await Promise.all([\n kernelQuery<EntryDetail | null>(\"chain.getEntry\", { entryId: entryId as string }),\n kernelQuery<Collection[]>(\"chain.listCollections\"),\n ]);\n if (!entry) {\n return { contents: [{ uri: uri.href, text: `Entry \"${entryId}\" not found.`, mimeType: \"text/markdown\" }] };\n }\n\n const collectionMap = new Map((collections ?? []).map((c) => [c._id, c]));\n const col = collectionMap.get((entry as any).collectionId);\n const collLabel = col?.name ?? entry.collectionName ?? entry.collectionSlug ?? \"unknown\";\n\n const lines: string[] = [\n `# ${entry.entryId}: ${entry.name}`,\n `**Collection:** ${collLabel}`,\n `**Status:** ${entry.status}`,\n \"\",\n ];\n\n if (entry.data && typeof entry.data === \"object\") {\n lines.push(\"## Data\");\n for (const [key, val] of Object.entries(entry.data)) {\n if (val && key !== \"rawData\") {\n const str = typeof val === \"string\" ? val : JSON.stringify(val, null, 2);\n lines.push(`**${key}:** ${str}`);\n }\n }\n lines.push(\"\");\n }\n\n if (entry.relations && entry.relations.length > 0) {\n lines.push(\"## Relations\");\n for (const rel of entry.relations) {\n const arrow = rel.direction === \"outgoing\" ? \"→\" : \"←\";\n const id = rel.otherEntryId ?? \"\";\n const name = rel.otherName ?? \"(unknown)\";\n lines.push(`- ${arrow} **${rel.type}** ${id}: ${name}`);\n }\n lines.push(\"\");\n }\n\n if (entry.labels && entry.labels.length > 0) {\n lines.push(`## Labels\\n${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join(\"\\n\")}`);\n }\n\n return {\n contents: [{ uri: uri.href, text: lines.join(\"\\n\"), mimeType: \"text/markdown\" }],\n };\n }\n );\n\n server.resource(\n \"chain-context\",\n new ResourceTemplate(\"productbrain://context/{entryId}\", {\n list: undefined,\n complete: {\n entryId: async (value) => {\n if (!value || value.length < 1) return [];\n const entries = (await kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: value })) ?? [];\n return entries.slice(0, 10).map((e) => e.entryId ?? e._id);\n },\n },\n }),\n async (uri, { entryId }) => {\n const result = await kernelQuery<GatewayRouteReturnByName<\"chain.gatherContext\">>(\"chain.gatherContext\", {\n entryId: entryId as string,\n maxHops: 2,\n });\n\n if (!result?.root) {\n return { contents: [{ uri: uri.href, text: `Entry \"${entryId}\" not found.`, mimeType: \"text/markdown\" }] };\n }\n\n const lines: string[] = [\n `# Context: ${result.root.entryId}: ${result.root.name}`,\n `_${result.totalRelations} related entries (${result.hopsTraversed} hops)_`,\n \"\",\n ];\n\n const byCollection = new Map<string, NonNullable<GatherContextResult[\"related\"]>>();\n for (const entry of result.related ?? []) {\n const key = entry.collectionName ?? \"Uncategorized\";\n if (!byCollection.has(key)) byCollection.set(key, []);\n byCollection.get(key)!.push(entry);\n }\n\n for (const [collName, entries] of byCollection) {\n lines.push(`## ${collName} (${entries.length})`);\n for (const e of entries) {\n const arrow = e.relationDirection === \"outgoing\" ? \"→\" : \"←\";\n const hopLabel = e.hop > 1 ? ` (hop ${e.hop})` : \"\";\n const id = e.entryId ? `${e.entryId}: ` : \"\";\n lines.push(`- ${arrow} **${e.relationType}** ${id}${e.name}${hopLabel}`);\n }\n lines.push(\"\");\n }\n\n return {\n contents: [{ uri: uri.href, text: lines.join(\"\\n\"), mimeType: \"text/markdown\" }],\n };\n }\n );\n\n // WP-316 S1b: Capture contract resource — returns required fields and guidance for a collection.\n // Calls chain.getCaptureContract (registered in http.ts by S1a as internal.agentKnowledge.captureContracts.getCaptureContract).\n server.resource(\n \"chain-collection-capture-contract\",\n new ResourceTemplate(\"productbrain://collections/{slug}/capture-contract\", {\n list: async () => {\n // Enumerate known collections so clients can auto-complete the slug\n const collections = (await kernelQuery<Collection[]>(\"chain.listCollections\")) ?? [];\n return {\n resources: collections.map((c) => ({\n uri: `productbrain://collections/${c.slug}/capture-contract`,\n name: `${c.icon ?? \"\"} ${c.name} — capture contract`.trim(),\n })),\n };\n },\n }),\n async (uri, { slug }) => {\n const collectionSlug = slug as string;\n\n // Resolve workspaceId for PostHog miss event; non-fatal if resolution fails\n let workspaceId: string | null = null;\n try {\n const ctx = await getWorkspaceContext();\n workspaceId = ctx.workspaceId;\n } catch {\n // Workspace resolution failure must not block the resource response\n }\n\n let contract: Omit<CaptureContractResult, \"collectionSlug\"> | null = null;\n try {\n contract = await kernelQuery<GatewayRouteReturnByName<\"chain.getCaptureContract\">>(\n \"chain.getCaptureContract\",\n { collectionSlug },\n );\n } catch {\n // Query error — fall through to not-found response\n contract = null;\n }\n\n if (!contract) {\n // WP-316 E5: emit capture_contract_miss event for observability\n if (workspaceId) {\n trackCaptureContractMiss(workspaceId, { slug: collectionSlug });\n }\n\n return {\n contents: [{\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify({\n ok: false,\n error: `Collection '${collectionSlug}' not found in this workspace.`,\n hint: \"Use `collections action=list` to see available collections and their slugs.\",\n }),\n }],\n };\n }\n\n const result: CaptureContractResult = {\n collectionSlug,\n requiredFields: contract.requiredFields,\n allFields: contract.allFields,\n captureExpectation: contract.captureExpectation,\n };\n\n return {\n contents: [{\n uri: uri.href,\n mimeType: \"application/json\",\n text: JSON.stringify(result),\n }],\n };\n }\n );\n\n server.resource(\n \"chain-search\",\n new ResourceTemplate(\"productbrain://search/{query}\", {\n list: undefined,\n complete: {\n query: async (value) => {\n if (!value) return [\"glossary:\", \"business-rules:\", \"decisions:\", \"tensions:\"];\n return [];\n },\n },\n }),\n async (uri, { query }) => {\n const results = await kernelQuery<GatewayRouteReturnByName<\"chain.searchEntries\">>(\"chain.searchEntries\", { query: query as string });\n\n if (!results || results.length === 0) {\n return { contents: [{ uri: uri.href, text: `No results for \"${query}\".`, mimeType: \"text/markdown\" }] };\n }\n\n const lines: string[] = [\n `# Search: \"${query}\"`,\n `_${results.length} results_`,\n \"\",\n ];\n\n for (const entry of results) {\n const id = entry.entryId ? `**${entry.entryId}:** ` : \"\";\n // `chain.searchEntries`'s real return (convex/agentKnowledge/entryReadQueries.ts's\n // searchEntriesReadModel: `EntryDoc & { collectionSlug: string | null }`) never had a\n // `collectionName` field — this fallback chain's first branch was always undefined at\n // runtime, silently falling through to `collectionSlug` (PR #395, Lane C S3b pass).\n const coll = entry.collectionSlug ?? \"\";\n lines.push(`- ${id}${entry.name} [${coll}] (${entry.status})`);\n }\n\n return {\n contents: [{ uri: uri.href, text: lines.join(\"\\n\"), mimeType: \"text/markdown\" }],\n };\n }\n );\n}\n","/** Served agent reference, kept separate from resource registration so its contract is testable. */\nexport const AGENT_CHEATSHEET = `# Product Brain — Agent Cheatsheet\n\n## Core Tools (Serves 13 default compound tools; 3 more (chain, chain-review, map) behind PB_MODULES=gitchain)\n| Tool | Purpose | Key params |\n|---|---|---|\n| \\`orient\\` | Workspace context, governance, active work packages, session start | \\`action\\`: start, task, record-activation |\n| \\`capture\\` | Create entry (draft), single or batch | \\`collection\\`, \\`name\\`, \\`description\\`, optional \\`data\\` / \\`items[]\\` |\n| \\`entries\\` | List / get / batch / search / update / commit / history / move / verify | \\`action\\` + \\`entryId\\` / \\`query\\` / \\`collection\\` |\n| \\`relations\\` | Create / batch-create / dismiss / delete / find / suggest links | \\`action\\` + \\`from\\`, \\`to\\`, \\`type\\` or \\`entryId\\` |\n| \\`context\\` | Gather related knowledge, last-verified brief | \\`action\\` + \\`entryId\\` or \\`task\\` |\n| \\`collections\\` | List / create / update collections, manage labels | \\`action\\` |\n| \\`quality\\` | Score an entry, verify the Chain, audit a work package | \\`action\\`: check, re-evaluate, verify-chain, audit |\n| \\`session\\` | Start / close, wrapup, resume, constellation accept | \\`action\\`: start, close, status, wrapup-review, wrapup-commit, resume, commit-constellation |\n| \\`workflows\\` | Run workflows, checkpoint, load a skill | \\`action\\`: list, start, checkpoint, get-run, load-skill |\n| \\`workspace\\` | Check / whoami / status / self-test, usage, governance proposals | \\`action\\`: check, whoami, status, audit, self-test, usage, proposals-* |\n| \\`feedback\\` | Submit product feedback (any key, no session required); \\`list\\` reads back your own workspace's feedback (no gate); vendor triage: queue / note / group / status | \\`action\\`: submit, list, queue, note, group, status |\n| \\`shape\\` | Review / disposition write-shape (single-concern split) advisories | \\`action\\`: list, show, agree, dismiss |\n| \\`question\\` | Routed questions — create/adopt, own, snooze, decline, answer, force-close | \\`action\\`: create, adopt, assign, snooze, decline, answer, force-close |\n\n## Collection Prefixes\nGLO (glossary), BR (business-rules), PRI (principles), STD (standards),\nDEC (decisions), STR (strategy), TEN (tensions), FEAT (features),\nBET (bets), INS (insights), ARCH (architecture), TEAM (teams),\nROL (roles), MAP (maps), MTRC (tracking-events), ST (semantic-types)\n\n## Valid Relation Types (24)\ninforms, governs, surfaces_tension_in, defines_term_for, belongs_to,\nreferences, related_to, fills_slot, commits_to, informed_by, depends_on,\nconflicts_with, confused_with, replaces, part_of, constrains,\ngoverned_by, alternative_to, has_proposal, requests_promotion_of, resolves,\nanchored_to, authority_domain, domain_routed_to\n\n## Lifecycle Status\nAll entries: \\`draft\\` | \\`active\\` | \\`deprecated\\` | \\`archived\\`\n\n## Workflow Status (per collection)\n- **tensions:** open → processing → decided → closed\n- **decisions:** pending → decided\n- **bets:** shaped → bet → building → shipped\n- **business-rules:** active | conflict | review\n\n## Key Patterns\n- **Capture flow:** \\`capture\\` → \\`relations action=suggest\\` → \\`relations action=batch-create\\` → \\`entries action=commit\\`\n- Use \\`workflowStatus\\` (not \\`status\\`) for domain workflow state\n- \\`data\\` param is merged (not replaced) — safe for partial updates\n`;\n","import type { GatewayRouteReturnByName } from \"@productbrain/kernel-client\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod/v3\";\nimport { kernelQuery } from \"../client.js\";\n\nexport function registerPrompts(server: McpServer) {\n server.prompt(\n \"review-against-rules\",\n \"Review code or a design decision against all business rules for a given domain. Fetches the rules and asks you to do a structured compliance review.\",\n { domain: z.string().describe(\"Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')\") },\n async ({ domain }) => {\n const entries = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"business-rules\" });\n // `data` is `v.any()` server-side (per-collection dynamic schema) — a documented,\n // already-accepted nested-any residual class (routeContract.test.ts's own PROVISIONAL\n // note), not caught by the route-contract's TOP-LEVEL-only soundness detector. `domain`\n // specifically isn't a member of the inferred union's narrower branch; other `.data`\n // fields below happen to structurally resolve, this one needs an explicit cast.\n const rules = entries.filter((e) => (e.data as Record<string, unknown> | undefined)?.domain === domain);\n\n if (rules.length === 0) {\n return {\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text: `No business rules found for domain \"${domain}\". Use \\`entries action=list collection=business-rules\\` to see available domains.`,\n },\n },\n ],\n };\n }\n\n const rulesText = rules\n .map(\n (r) =>\n `### ${r.entryId ?? \"\"}: ${r.name}\\n` +\n `Status: ${r.status} | Severity: ${r.data?.severity ?? \"unknown\"}\\n` +\n `Description: ${r.data?.description ?? \"\"}\\n` +\n `Data Impact: ${r.data?.dataImpact ?? \"\"}\\n` +\n `Platforms: ${(r.data?.platforms ?? []).join(\", \")}\\n` +\n (r.data?.conflictWith ? `CONFLICT: ${r.data.conflictWith.rule} — ${r.data.conflictWith.nature}\\n` : \"\")\n )\n .join(\"\\n---\\n\\n\");\n\n return {\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Review the current code or design against the following business rules for the \"${domain}\" domain.\\n\\n` +\n `For each rule, assess:\\n` +\n `1. Is the current implementation compliant?\\n` +\n `2. Are there potential violations or edge cases?\\n` +\n `3. What specific changes would be needed for compliance?\\n\\n` +\n `Business Rules:\\n\\n${rulesText}\\n\\n` +\n `Provide a structured review with a compliance status for each rule (COMPLIANT / AT RISK / VIOLATION / NOT APPLICABLE).`,\n },\n },\n ],\n };\n }\n );\n\n server.prompt(\n \"name-check\",\n \"Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.\",\n { names: z.string().describe(\"Comma-separated list of names to check (e.g. 'vendor_id, compliance_level, formulator_type')\") },\n async ({ names }) => {\n const terms = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"glossary\" });\n\n const glossaryContext = terms\n .map(\n (t) =>\n `${t.name} (${t.entryId ?? \"\"}) [${t.status}]: ${t.data?.canonical ?? \"\"}` +\n (t.data?.confusedWith?.length > 0 ? ` — Often confused with: ${t.data.confusedWith.join(\", \")}` : \"\") +\n (t.data?.codeMapping?.length > 0\n ? `\\n Code mappings: ${t.data.codeMapping.map((m: any) => `${m.platform}:${m.field}`).join(\", \")}`\n : \"\")\n )\n .join(\"\\n\");\n\n return {\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Check the following names against the glossary for terminology alignment:\\n\\n` +\n `Names to check: ${names}\\n\\n` +\n `Glossary (canonical terms):\\n${glossaryContext}\\n\\n` +\n `For each name:\\n` +\n `1. Does it match a canonical term? If so, which one?\\n` +\n `2. Is there terminology drift? (e.g. using \"vendor\" instead of \"supplier\", \"compliance\" instead of \"conformance\")\\n` +\n `3. Suggest the canonical alternative if drift is detected.\\n` +\n `4. Flag any names that don't have a corresponding glossary term (might need one).\\n\\n` +\n `Format as a table: Name | Status | Canonical Form | Action Needed`,\n },\n },\n ],\n };\n }\n );\n\n server.prompt(\n \"draft-decision-record\",\n \"Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.\",\n { context: z.string().describe(\"Description of the decision (e.g. 'We decided to use MRSL v3.1 as the conformance baseline because...')\") },\n async ({ context }) => {\n const recentDecisions = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"decisions\" });\n const sorted = [...recentDecisions]\n .sort((a, b) => ((b.data?.date ?? \"\") > (a.data?.date ?? \"\") ? 1 : -1))\n .slice(0, 5);\n\n const recentContext = sorted.length > 0\n ? sorted.map((d) => `- [${d.status}] ${d.name} (${d.data?.date ?? \"no date\"})`).join(\"\\n\")\n : \"No previous decisions recorded.\";\n\n return {\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Draft a structured decision record from the following context:\\n\\n` +\n `\"${context}\"\\n\\n` +\n `Recent decisions for reference:\\n${recentContext}\\n\\n` +\n `Structure the decision record with:\\n` +\n `1. **Title**: Concise decision statement\\n` +\n `2. **Decided by**: Who made or approved this decision\\n` +\n `3. **Date**: When it was decided\\n` +\n `4. **Status**: decided / proposed / revisited\\n` +\n `5. **Rationale**: Why this decision was made, including trade-offs considered\\n` +\n `6. **Alternatives considered**: What else was on the table\\n` +\n `7. **Related rules or tensions**: Any business rules or tensions this connects to\\n\\n` +\n `After drafting, I can log it using the capture tool with collection \"decisions\".`,\n },\n },\n ],\n };\n }\n );\n\n server.prompt(\n \"draft-rule-from-context\",\n \"Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.\",\n {\n observation: z.string().describe(\"What you observed or discovered (e.g. 'Suppliers can have multiple org types in Gateway')\"),\n domain: z.string().describe(\"Which domain this rule belongs to (e.g. 'Governance & Decision-Making')\"),\n },\n async ({ observation, domain }) => {\n const allRules = await kernelQuery<GatewayRouteReturnByName<\"chain.listEntries\">>(\"chain.listEntries\", { collectionSlug: \"business-rules\" });\n // Same documented nested-any residual as review-against-rules above.\n const existingRules = allRules.filter((r) => (r.data as Record<string, unknown> | undefined)?.domain === domain);\n\n const existingContext =\n existingRules.length > 0\n ? existingRules.map((r) => `${r.entryId ?? \"\"}: ${r.name} [${r.status}] — ${r.data?.description ?? \"\"}`).join(\"\\n\")\n : \"No existing rules for this domain.\";\n\n return {\n messages: [\n {\n role: \"user\" as const,\n content: {\n type: \"text\" as const,\n text:\n `Draft a business rule based on this observation:\\n\\n` +\n `\"${observation}\"\\n\\n` +\n `Domain: ${domain}\\n\\n` +\n `Existing rules in this domain:\\n${existingContext}\\n\\n` +\n `Draft the rule with these fields (do not specify entryId — Convex assigns sequential IDs automatically, e.g. <PREFIX>-<n>):\\n` +\n `1. **name**: Concise rule title\\n` +\n `2. **data.description**: What the rule states\\n` +\n `3. **data.rationale**: Why this rule matters\\n` +\n `4. **data.dataImpact**: How this affects data models, APIs, or storage\\n` +\n `5. **data.severity**: high / medium / low\\n` +\n `6. **data.platforms**: Which platforms are affected\\n` +\n `7. **data.relatedRules**: Any related existing rules\\n\\n` +\n `Make sure the rule is consistent with existing rules and doesn't contradict them. ` +\n `After drafting, I can create it using the capture tool with collection \"business-rules\".`,\n },\n },\n ],\n };\n }\n );\n}\n","// GENERATED by scripts/generate-mcp-embedded-copies.mjs from convex/lib/flags_core.ts.\n// DO NOT EDIT. Run `npm run mcp:embedded-copies` to regenerate.\n// WP-488 Slice 3 (FEAT-1377) / DEC-701: Railway's isolated Docker build for\n// packages/mcp-server cannot see convex/ — this file must physically exist here.\n// See scripts/generate-mcp-embedded-copies.mjs for the full rationale.\n\n// convex/lib/flags_core.ts — single source of truth for feature flags.\n// (Underscore path: Convex module names disallow hyphens in path segments.)\n// Chain: DEC-701 (pre-production flag simplification), STA-5 (amended),\n// BR-79 (kebab-case), BR-83 (amended), STD-35 (dead flag cleanup).\n//\n// This file lives in `convex/lib/` to keep the Convex tsconfig (which does\n// not include `src/`) and the SvelteKit tsconfig in the same type graph.\n// The MCP `prebuild` script copies this file into\n// `packages/mcp-server/src/flags.ts` so that the MCP package sees the\n// authoritative resolver without reaching across the monorepo boundary at\n// runtime.\n\nexport type FlagCtx = {\n\tworkspaceId?: string;\n\tclerkUserId?: string;\n};\n\nexport type FlagRule =\n\t| boolean\n\t| {\n\t\t\tdefault: boolean;\n\t\t\tworkspaceAllow?: readonly string[];\n\t\t\tworkspaceDeny?: readonly string[];\n\t\t\tuserAllow?: readonly string[];\n\t\t\tuserDeny?: readonly string[];\n\t\t\tposthog?: boolean;\n\t };\n\n/**\n * Kill switch — resolves flag-first in every environment.\n * - Vite/browser: `VITE_FEATURE_KILL_SWITCH=true`\n * - Node (MCP/Convex action/test): `FEATURE_KILL_SWITCH=true`\n *\n * Runtime-safe: both checks are guarded with typeof + optional chaining so\n * missing globals (Convex runtime lacks `import.meta.env`; browsers lack\n * `process`) do not throw.\n */\nfunction readViteEnvFlag(name: string): string | undefined {\n\ttry {\n\t\t// `import.meta` exists everywhere but `.env` is Vite-only.\n\t\tconst env = (import.meta as { env?: Record<string, string | undefined> }).env;\n\t\treturn env?.[name];\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction readProcessEnvFlag(name: string): string | undefined {\n\ttry {\n\t\tif (typeof process !== 'undefined' && process.env) {\n\t\t\treturn process.env[name];\n\t\t}\n\t} catch {\n\t\t// fall through\n\t}\n\treturn undefined;\n}\n\nconst KILL =\n\treadViteEnvFlag('VITE_FEATURE_KILL_SWITCH') === 'true' ||\n\treadProcessEnvFlag('FEATURE_KILL_SWITCH') === 'true';\n\n/**\n * FEAT-1139 — Query budget kill-switch.\n * When true, `cappedQuery` bypasses tiered row caps and returns full unbounded\n * result sets while preserving the `_budget` telemetry envelope.\n * - Vite/browser: `VITE_PB_QUERY_BUDGET_KILL=true`\n * - Node (MCP/Convex action/test): `PB_QUERY_BUDGET_KILL=true`\n */\nconst QUERY_BUDGET_KILL =\n\treadViteEnvFlag('VITE_PB_QUERY_BUDGET_KILL') === 'true' ||\n\treadProcessEnvFlag('PB_QUERY_BUDGET_KILL') === 'true';\n\n// Named IDs — dev + prod coexist per DEC-701. Convex deployment-prefix\n// namespacing (p57... dev, mx78... prod) makes the WS sets disjoint at runtime.\n// Clerk user IDs do NOT carry across envs: the dev/test instance (pk_test_) and\n// prod instance (pk_live_) have separate user pools, so the same human resolves\n// to different ids — USR.RANDY (prod) vs USR.RANDY_DEV (dev/preview). (TEN-2168)\nexport const WS = {\n\tRANDY_DEV_PRIMARY: 'p5796jhec0nhyp417ekrt8x4w181t41f',\n\tRANDY_DEV_SECONDARY: 'p5791wr86cj0thx2vxpqavj0mn82rssd',\n\tRANDY_PROD_PRIMARY: 'mx784e9jjdqhsk2r0098bpvtes84e792',\n\tRANDY_PROD_SECONDARY: 'mx74q0mkwn4r920q2837qk7dsx84pq60',\n} as const;\n\nexport const USR = {\n\t/** Randy — production Clerk instance id (pk_live_); used by prod mvp-unlock allowlists. NOT the id local dev / Convex previews resolve to — those use the test instance (see RANDY_DEV). */\n\tRANDY: 'user_3C31UK8CWugoDXUj2RGu1HDudas',\n\t/** Randy — development/test Clerk instance id (pk_test_). Local dev + Convex previews authenticate via the test instance, so preview seeding (linkSeedOwner) and preview MVP unlock MUST use this id. Clerk dev/prod instances have separate user pools, so the ids differ. (DEC-1097 / TEN-2168) */\n\tRANDY_DEV: 'user_39r6ItzbAkdFY6XZyYTz79ALSYN',\n\t/** Niels — full MVP unlock in any workspace (Clerk JWT `sub` / `FlagCtx.clerkUserId`). */\n\tNIELS: 'user_3DOKRUaiY9KS3RKtC7shak3nB0N',\n} as const;\n\n/**\n * DEC-701 Phase 3: registry stays empty after Phase 2 because pre-production\n * products have no users to protect. Add flags here when genuinely needed —\n * shape is `boolean` for trivial toggles, or the FlagRule object for the\n * allowlist precedence described in DEC-701 Clause 3.\n *\n * WP-355 (MVP Surface Lock): five mvp-unlock-* flags gate Spine, Bridge, Rail,\n * Import, and Brain Chat. Default off; `workspaceAllow` lists Randy's dev/prod\n * workspaces; optional `userAllow` can grant the same unlocks to specific\n * Clerk user ids in any workspace (see USR.NIELS).\n */\nexport const FLAGS = {\n\t// WP-355 — MVP unlock: full Spine navigation (all modes + access patterns visible)\n\t'mvp-unlock-spine': {\n\t\tdefault: false,\n\t\tworkspaceAllow: [\n\t\t\tWS.RANDY_DEV_PRIMARY,\n\t\t\tWS.RANDY_DEV_SECONDARY,\n\t\t\tWS.RANDY_PROD_PRIMARY,\n\t\t\tWS.RANDY_PROD_SECONDARY,\n\t\t],\n\t\tuserAllow: [USR.NIELS, USR.RANDY, USR.RANDY_DEV],\n\t},\n\t// WP-355 — MVP unlock: Bridge full view (beyond locked /bridge dashboard)\n\t'mvp-unlock-bridge-full': {\n\t\tdefault: false,\n\t\tworkspaceAllow: [\n\t\t\tWS.RANDY_DEV_PRIMARY,\n\t\t\tWS.RANDY_DEV_SECONDARY,\n\t\t\tWS.RANDY_PROD_PRIMARY,\n\t\t\tWS.RANDY_PROD_SECONDARY,\n\t\t],\n\t\tuserAllow: [USR.NIELS, USR.RANDY, USR.RANDY_DEV],\n\t},\n\t// WP-355 — MVP unlock: Rail full context (beyond Rail context-only mode)\n\t'mvp-unlock-rail-full': {\n\t\tdefault: false,\n\t\tworkspaceAllow: [\n\t\t\tWS.RANDY_DEV_PRIMARY,\n\t\t\tWS.RANDY_DEV_SECONDARY,\n\t\t\tWS.RANDY_PROD_PRIMARY,\n\t\t\tWS.RANDY_PROD_SECONDARY,\n\t\t],\n\t\tuserAllow: [USR.NIELS, USR.RANDY, USR.RANDY_DEV],\n\t},\n\t// WP-355 — MVP unlock: Import surface enabled\n\t'mvp-unlock-import': {\n\t\tdefault: false,\n\t\tworkspaceAllow: [\n\t\t\tWS.RANDY_DEV_PRIMARY,\n\t\t\tWS.RANDY_DEV_SECONDARY,\n\t\t\tWS.RANDY_PROD_PRIMARY,\n\t\t\tWS.RANDY_PROD_SECONDARY,\n\t\t],\n\t\tuserAllow: [USR.NIELS, USR.RANDY, USR.RANDY_DEV],\n\t},\n\t// WP-355 — Brain Chat: off by default; same workspace + user allowlists as other mvp-unlock flags.\n\t'mvp-unlock-brain-chat': {\n\t\tdefault: false,\n\t\tworkspaceAllow: [\n\t\t\tWS.RANDY_DEV_PRIMARY,\n\t\t\tWS.RANDY_DEV_SECONDARY,\n\t\t\tWS.RANDY_PROD_PRIMARY,\n\t\t\tWS.RANDY_PROD_SECONDARY,\n\t\t],\n\t\tuserAllow: [USR.NIELS, USR.RANDY, USR.RANDY_DEV],\n\t},\n\t// FLAG: advanced-governance-modes — remove at GA per DEC-96.\n\t// DEC-97 (intent) + DEC-1138 (plumbing migration). Gates Consensus + Role-based\n\t// governance mode switching on the workspace settings page. OFF: \"Coming soon\"\n\t// + Notify Me (STA-11 compliant). ON: both modes selectable; Role additionally\n\t// gated by getGovernanceModeReadiness (the GA precondition, not the flag).\n\t// Cohort matches the mvp-unlock-* convention (workspace + user belt-and-suspenders),\n\t// extending DEC-97's strict workspace-scoping so Randy can dogfood from any workspace.\n\t// Niels excluded — governance switching has sharp UX (Role preconditions, auto-commit\n\t// loss on Consensus), so dogfood stays narrow until validated.\n\t'advanced-governance-modes': {\n\t\tdefault: false,\n\t\tworkspaceAllow: [\n\t\t\tWS.RANDY_DEV_PRIMARY,\n\t\t\tWS.RANDY_DEV_SECONDARY,\n\t\t\tWS.RANDY_PROD_PRIMARY,\n\t\t\tWS.RANDY_PROD_SECONDARY,\n\t\t],\n\t\tuserAllow: [USR.RANDY, USR.RANDY_DEV],\n\t},\n\t// WP-373 E3 — Routing Resolver SSOT killswitch.\n\t// When true, the new pure resolver short-circuits and mount sites execute the\n\t// legacy inline redirect/error logic verbatim. Default false: resolver runs.\n\t// FEATURE_KILL_SWITCH env beats this flag (precedence per .claude/rules/feature-flags.md).\n\t'routing-resolver-killswitch': false,\n\t// WP-384 S3: Child-domain creation affordance. OFF by default — \"Coming soon\" tooltip per DEC-97 / STA-11.\n\t'custom-authority-domains': false,\n\t// FEAT-1139 — Query budget kill-switch.\n\t// When true, `cappedQuery` reverts to raw `.collect()` behavior (no row caps)\n\t// while still populating `_budget` for WP-380 telemetry. Default false.\n\t'query-budget-kill': {\n\t\tdefault: QUERY_BUDGET_KILL,\n\t},\n} as const satisfies Record<string, FlagRule>;\n\n// Keys removed from FLAGS but not yet swept from all call sites (STD-35).\nexport const DEPRECATED_FLAG_KEYS: readonly string[] = [];\n\nexport type FlagKey = keyof typeof FLAGS;\n\ntype PosthogResolver = (flag: string) => boolean | undefined;\n\n/**\n * @internal — exported for tests only. Do not consume from production code\n * (use `isFeatureEnabled` instead). Tests use this to exercise precedence\n * without mutating the real FLAGS registry.\n *\n * Precedence (DEC-701 Clause 3, top wins):\n * kill switch > userAllow > userDeny > workspaceDeny > workspaceAllow\n * > default > posthog fallback (opt-in)\n */\nexport function _resolve(\n\tflag: string,\n\trule: FlagRule | undefined,\n\tctx: FlagCtx,\n\tkill: boolean,\n\tposthog?: PosthogResolver,\n): boolean {\n\tif (kill) return false;\n\tif (rule === undefined) return false;\n\tif (typeof rule === 'boolean') return rule;\n\n\tconst { workspaceId, clerkUserId } = ctx;\n\tif (clerkUserId && rule.userAllow?.includes(clerkUserId)) return true;\n\tif (clerkUserId && rule.userDeny?.includes(clerkUserId)) return false;\n\tif (workspaceId && rule.workspaceDeny?.includes(workspaceId)) return false;\n\tif (workspaceId && rule.workspaceAllow?.includes(workspaceId)) return true;\n\n\tif (rule.posthog && posthog) {\n\t\ttry {\n\t\t\tconst hit = posthog(flag);\n\t\t\tif (typeof hit === 'boolean') return hit;\n\t\t} catch {\n\t\t\t// fall through to rule.default on any PostHog error\n\t\t}\n\t}\n\treturn rule.default;\n}\n\nfunction defaultPosthog(flag: string): boolean | undefined {\n\ttry {\n\t\ttype PosthogLike = { isFeatureEnabled(k: string): boolean | undefined };\n\t\tconst g = globalThis as unknown as { __posthog?: PosthogLike };\n\t\treturn g.__posthog?.isFeatureEnabled(flag);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function isFeatureEnabled(flag: FlagKey, ctx: FlagCtx = {}): boolean {\n\tconst rule = (FLAGS as Record<string, FlagRule>)[flag as string];\n\treturn _resolve(flag as string, rule, ctx, KILL, defaultPosthog);\n}\n","// packages/mcp-server/src/featureFlags.ts — thin wrapper over the\n// authoritative resolver in `./flags.ts` (byte copy of `convex/lib/flags_core.ts`\n// via `npm run prebuild`; file is committed for Railway package-scoped Docker).\n//\n// Chain: DEC-701.\n//\n// `initFeatureFlags` is retained as a no-op for compatibility with the\n// existing MCP bootstrap call sites (index.ts, http.ts). It used to create\n// a PostHog client; with the DEC-701 allowlist registry PostHog is a\n// per-flag opt-in via globalThis.__posthog, so no initialization is\n// required at startup.\nimport type { PostHog } from \"posthog-node\";\nimport { isFeatureEnabled as coreIsFeatureEnabled, type FlagKey } from \"./flags.js\";\n\nexport type { FlagKey };\n\nexport function initFeatureFlags(_posthogClient: PostHog | null): void {\n // no-op — DEC-701 registry does not require a PostHog client at startup.\n // Retained so existing MCP boot code (index.ts, http.ts) keeps working.\n}\n\nexport function isFeatureEnabled(\n flag: FlagKey,\n ctx: { workspaceId?: string; clerkUserId?: string } = {},\n): boolean {\n return coreIsFeatureEnabled(flag, ctx);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,SAAS,aAAAA,kBAAiB;;;ACY1B,SAAS,KAAAC,WAAS;;;ACNlB,SAAS,SAA0B;;;ACyBnC,IAAM,oBAAoB;AAO1B,SAAS,kBACP,KAOY;AACZ,MAAI,EAAE,eAAe,OAAQ,QAAO;AACpC,QAAM,IAAI;AAKV,MAAI,OAAO,EAAE,SAAS,SAAU,QAAO;AACvC,QAAM,QAAQ,kBAAkB,KAAK,EAAE,OAAO;AAC9C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO;AAAA,IACL,MAAM,EAAE;AAAA,IACR,IAAI,MAAM,CAAC;AAAA,IACX,cAAc,MAAM,CAAC;AAAA;AAAA,IACrB,uBAAuB,MAAM,QAAQ,EAAE,qBAAqB,IAAI,EAAE,wBAAwB;AAAA,IAC1F,aAAa,MAAM,QAAQ,EAAE,WAAW,IAAI,EAAE,cAAc;AAAA,EAC9D;AACF;AAIO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AA0BA,IAAM,gBAA+B;AAAA,EACnC;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,WAAW,aAAa,iBAAiB,YAAY,EAAE,QAAQ,QAAQ,EAAE;AAAA,EAC3F;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,WAAW,aAAa,qBAAqB,YAAY,EAAE,QAAQ,QAAQ,EAAE;AAAA,EAC/F;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,UAAU,aAAa,kBAAkB,YAAY,CAAC,EAAE;AAAA,EAC1E;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ,EAAE,MAAM,aAAa,aAAa,mBAAmB,YAAY,EAAE,QAAQ,SAAS,EAAE;AAAA,EAChG;AACF;AAaO,SAAS,cAAc,KAA+B;AAC3D,QAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAE/D,MAAI,eAAe,WAAW;AAC5B,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,UAAU;AAAA,MACV,kBAAkB,CAAC,EAAE,MAAM,aAAa,aAAa,mBAAmB,YAAY,EAAE,QAAQ,SAAS,EAAE,CAAC;AAAA,IAC5G;AAAA,EACF;AAEA,MAAI,eAAe,cAAc;AAC/B,WAAO,EAAE,MAAM,iBAAiB,SAAS,UAAU,+CAA+C;AAAA,EACpG;AAEA,MAAI,eAAe,iBAAiB;AAClC,WAAO,EAAE,MAAM,oBAAoB,QAAQ;AAAA,EAC7C;AAMA,QAAM,SAAS,kBAAkB,GAAG;AACpC,MAAI,QAAQ;AACV,UAAM,EAAE,MAAM,YAAY,IAAI,cAAc,uBAAuB,YAAY,IAAI;AACnF,QAAI,eAAe,qBAAqB;AACtC,YAAM,iBAAiB,uBAAuB,UAAU,aAAa;AACrE,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT,GAAI,iBAAiB;AAAA,UACnB,aAAa;AAAA,YACX,GAAI,uBAAuB,SAAS,EAAE,sBAAsB,IAAI,CAAC;AAAA,YACjE,GAAI,aAAa,SAAS,EAAE,YAAY,IAAI,CAAC;AAAA,UAC/C;AAAA,QACF,IAAI,CAAC;AAAA,MACP;AAAA,IACF;AACA,QAAI,eAAe,aAAa;AAC9B,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT,UAAU;AAAA,QACV,kBAAkB,CAAC,EAAE,MAAM,WAAW,aAAa,kBAAkB,YAAY,EAAE,QAAQ,SAAS,EAAE,CAAC;AAAA,MACzG;AAAA,IACF;AASA,QAAI,YAAY,WAAW,QAAQ,GAAG;AACpC,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT,UAAU;AAAA,QACV,kBAAkB,CAAC,EAAE,MAAM,aAAa,aAAa,mBAAmB,YAAY,EAAE,QAAQ,SAAS,EAAE,CAAC;AAAA,MAC5G;AAAA,IACF;AACA,QAAI,eAAe,0BAA0B,eAAe,yBAAyB;AACnF,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT,UAAU;AAAA,QACV,kBAAkB,CAAC,EAAE,MAAM,WAAW,aAAa,aAAa,YAAY,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,MACjG;AAAA,IACF;AAIA,QAAI,eAAe,gBAAgB;AACjC,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT,UACE;AAAA,MACJ;AAAA,IACF;AAEA,WAAO,EAAE,MAAM,YAAY,IAAI,SAAS,aAAa;AAAA,EACvD;AAEA,aAAW,EAAE,SAAS,MAAM,UAAU,OAAO,KAAK,eAAe;AAC/D,QAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,aAAO,EAAE,MAAM,SAAS,UAAU,kBAAkB,CAAC,MAAM,EAAE;AAAA,IAC/D;AAAA,EACF;AAUA,MAAK,KAA8C,SAAS,uBAAuB;AACjF,UAAM,gBAAiB,IAAoC,kBAAkB;AAC7E,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,UAAU,gBACN,oIACA;AAAA,IACN;AAAA,EACF;AAEA,MAAI,qDAAqD,KAAK,OAAO,GAAG;AACtE,WAAO,EAAE,MAAM,uBAAuB,SAAS,UAAU,0BAA0B;AAAA,EACrF;AAEA,SAAO,EAAE,MAAM,kBAAkB,SAAS,WAAW,gCAAgC;AACvF;;;ADzKO,SAAS,QACd,SACA,MACA,MACoB;AACpB,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS,WAAW;AAAA,IACpB;AAAA,IACA,GAAI,MAAM,SAAS,EAAE,KAAK,IAAI,CAAC;AAAA,EACjC;AACF;AAEO,SAAS,QACd,MACA,SACA,UACA,kBACA,aACe;AACf,SAAO;AAAA,IACL,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/B,GAAI,kBAAkB,SAAS,EAAE,iBAAiB,IAAI,CAAC;AAAA,IACvD,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,EACvC;AACF;AAGO,SAAS,SAAS,IAAY,MAA8B;AACjE,SAAO;AAAA,IACL;AAAA,IACA,UAAU,EAAE;AAAA,IACZ,QAAQ;AAAA,IACR,CAAC,EAAE,MAAM,WAAW,aAAa,kBAAkB,YAAY,EAAE,QAAQ,UAAU,OAAO,GAAG,EAAE,CAAC;AAAA,EAClG;AACF;AAGO,SAAS,gBAAgB,SAAgC;AAC9D,SAAO,QAAQ,oBAAoB,OAAO;AAC5C;AA0BO,SAAS,YAAY,MAA6B;AACvD,SAAO,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AACzC;AAMO,SAAS,YACd,QACA,MACoE;AACpE,QAAM,SAAS,OAAO,UAAU,IAAI;AACpC,MAAI,OAAO,QAAS,QAAO,EAAE,IAAI,MAAM,MAAM,OAAO,KAAK;AACzD,QAAM,SAAS,OAAO,MAAM,OACzB,IAAI,CAAC,MAAkB,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAC1D,KAAK,IAAI;AACZ,QAAM,MAAM,sBAAsB,MAAM;AACxC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ,EAAE,SAAS,YAAY,GAAG,GAAG,mBAAmB,gBAAgB,GAAG,EAAE;AAAA,EAC/E;AACF;AAGO,SAAS,cAAc,QAAgB,OAAsC;AAClF,QAAM,MAAM,mBAAmB,MAAM,qBAAqB,MAAM,KAAK,IAAI,CAAC;AAC1E,SAAO,EAAE,SAAS,YAAY,GAAG,GAAG,mBAAmB,gBAAgB,GAAG,EAAE;AAC9E;AAMO,SAAS,cACd,MACA,SACA,MACA,MACY;AACZ,SAAO,EAAE,SAAS,YAAY,IAAI,GAAG,mBAAmB,QAAQ,SAAS,MAAM,IAAI,EAAE;AACvF;AAGO,SAAS,cACd,MACA,MACA,SACA,UACA,kBACA,aACY;AACZ,SAAO,EAAE,SAAS,YAAY,IAAI,GAAG,mBAAmB,QAAQ,MAAM,SAAS,UAAU,kBAAkB,WAAW,EAAE;AAC1H;AAGO,SAAS,eAAe,IAAY,MAAe,MAA2B;AACnF,SAAO,EAAE,SAAS,YAAY,QAAQ,UAAU,EAAE,cAAc,GAAG,mBAAmB,SAAS,IAAI,IAAI,EAAE;AAC3G;AAGO,SAAS,iBAAiB,SAA6B;AAC5D,SAAO,EAAE,SAAS,YAAY,OAAO,GAAG,mBAAmB,gBAAgB,OAAO,EAAE;AACtF;AAIA,IAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,MAAM,EAAE,OAAO;AAAA,EACf,aAAa,EAAE,OAAO;AAAA,EACtB,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC;AAClC,CAAC;AAED,IAAM,aAAa,EAChB,OAAO;AAAA,EACN,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,QAAQ,EACL,OAAO;AAAA,IACN,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,IAChC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,IAChC,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,IACjC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,SAAS,EAAE,OAAO;AAAA,IAClB,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,CAAC,EACA,YAAY,EACZ,SAAS;AAAA;AAAA,EAEZ,KAAK,EAAE,OAAO,EAAE,SAAS;AAAA,EACzB,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS;AAC3C,CAAC,EACA,SAAS;AA+HL,SAAS,YACd,SACqC;AACrC,SAAO,OAAO,SAAoC;AAChD,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI;AACF,YAAMC,UAAS,MAAM,QAAQ,IAAI;AACjC,YAAM,aAAa,KAAK,IAAI,IAAI;AAEhC,YAAM,KAAKA,QAAO;AAClB,UAAI,MAAM,OAAO,OAAO,YAAY,QAAQ,IAAI;AAC9C,WAAG,QAAQ,EAAE,GAAG,GAAG,OAAO,WAAW;AACrC,eAAO;AAAA,UACL,SAASA,QAAO,WAAW,CAAC;AAAA,UAC5B,mBAAmB;AAAA,UACnB,GAAI,GAAG,OAAO,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,QAC7C;AAAA,MACF;AAEA,YAAM,IAAI,MAAM,0BAA0B,QAAQ,QAAQ,aAAa,gEAA2D;AAAA,IACpI,SAAS,KAAK;AACZ,YAAM,aAAa,KAAK,IAAI,IAAI;AAChC,YAAM,aAAa,cAAc,GAAG;AACpC,YAAM,WAA0B;AAAA,QAC9B,GAAG;AAAA,UACD,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA;AAAA,UAEX,WAAW;AAAA,QACb;AAAA,QACA,OAAO,EAAE,WAAW;AAAA,MACtB;AACA,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,WAAW,KACb,IAAI,WAAW,IAAI,IAAI,WAAW,EAAE,KAAK,WAAW,OAAO,KAC3D,IAAI,WAAW,IAAI,KAAK,WAAW,OAAO;AAAA,QAChD,CAAC;AAAA,QACD,mBAAmB;AAAA,QACnB,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;AE5aA,IAAM,wBAAwB,oBAAI,IAAI,CAAC,YAAY,aAAa,CAAC;AAY1D,SAAS,sBAAsB,OAIX;AACzB,QAAM,OAAO,MAAM,gBAAgB,YAAY;AAC/C,MAAI,CAAC,QAAQ,CAAC,sBAAsB,IAAI,IAAI,EAAG,QAAO;AAEtD,QAAM,YAAY,MAAM,aAAa,CAAC;AACtC,QAAM,eAAe,UAAU;AAAA,IAC7B,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,cAAc;AAAA,EACnD;AACA,QAAM,iBAAiB,UAAU;AAAA,IAC/B,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,cAAc;AAAA,EACrD;AACA,QAAM,gBAAgB,UAAU;AAAA,IAC9B,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,SAAS,kBAAkB,EAAE,cAAc;AAAA,EACjF,EAAE;AAEF,MAAI,SAAS,eAAe;AAC1B,UAAMC,MAAK,MAAM;AACjB,QAAIA,QAAO,iBAAiB,gBAAgB;AAC1C,aAAO,EAAE,OAAO,eAAe,QAAQ,uCAAuC;AAAA,IAChF;AACA,QAAIA,QAAO,eAAgB,gBAAgBA,QAAO,YAAa;AAC7D,aAAO,EAAE,OAAO,aAAa,QAAQ,GAAG,aAAa,iBAAiB,kBAAkB,IAAI,MAAM,EAAE,GAAG;AAAA,IACzG;AACA,QAAIA,QAAO,WAAW;AACpB,aAAO,EAAE,OAAO,WAAW,QAAQ,yBAAyB;AAAA,IAC9D;AACA,WAAO,EAAE,OAAO,YAAY,QAAQ,sBAAsB,QAAQ,+DAAiE;AAAA,EACrI;AAKA,QAAM,KAAK,MAAM;AACjB,MAAI,OAAO,eAAe,cAAc;AACtC,WAAO,EAAE,OAAO,aAAa,QAAQ,GAAG,aAAa,iBAAiB,kBAAkB,IAAI,MAAM,EAAE,GAAG;AAAA,EACzG;AACA,MAAI,OAAO,eAAe,cAAc;AACtC,WAAO,EAAE,OAAO,aAAa,QAAQ,GAAG,aAAa,iBAAiB,kBAAkB,IAAI,MAAM,EAAE,GAAG;AAAA,EACzG;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAGO,SAAS,oBAAoB,IAA6B;AAC/D,QAAM,OAAO,GAAG,UAAU,cAAc,WACpC,GAAG,UAAU,cAAc,WAC3B,GAAG,UAAU,eAAe,WAC5B,GAAG,UAAU,aAAa,MAC1B,GAAG,UAAU,YAAY,WACzB;AACJ,QAAM,SAAS,GAAG,SAAS,IAAI,GAAG,MAAM,KAAK;AAC7C,SAAO,mBAAmB,IAAI,IAAI,GAAG,KAAK,WAAM,GAAG,MAAM,IAAI,MAAM;AACrE;AAGO,SAAS,iBAAiB,OAAgC;AAC/D,SAAO;AAAA,IACL,gBAAgB,OAAO,MAAM,mBAAmB,WAAW,MAAM,iBAAiB;AAAA,IAClF,gBAAgB,OAAO,MAAM,mBAAmB,WAAW,MAAM,iBAAiB;AAAA,IAClF,WAAW,MAAM,QAAQ,MAAM,SAAS,IACnC,MAAM,UAA2D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,EAAE,UAAU,EAAE,IACvH;AAAA,EACN;AACF;AAgBO,SAAS,eAAe,MAAe,QAAwB;AACpE,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,IAAI;AACV,QAAM,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ;AAClE,MAAI,OAAO,QAAQ,YAAY,CAAC,IAAK,QAAO;AAC5C,SAAO,IAAI,SAAS,SAAS,IAAI,UAAU,GAAG,MAAM,IAAI,QAAQ;AAClE;AAkBO,IAAM,uBAAoD,oBAAI,IAAI;AAAA;AAAA,EAEvE,CAAC,gBAAgB,uBAAuB;AAAA,EACxC,CAAC,aAAa,sBAAsB;AAAA,EACpC,CAAC,aAAa,wBAAwB;AAAA,EACtC,CAAC,UAAU,yBAAyB;AAAA,EACpC,CAAC,kBAAkB,2BAA2B;AAAA,EAC9C,CAAC,gBAAgB,iCAAiC;AAAA,EAClD,CAAC,gBAAgB,yBAAyB;AAAA,EAC1C,CAAC,iBAAiB,4BAA4B;AAAA,EAC9C,CAAC,kBAAkB,yBAAyB;AAAA,EAC5C,CAAC,qBAAqB,wBAAwB;AAAA,EAC9C,CAAC,oBAAoB,2BAA2B;AAAA,EAChD,CAAC,qBAAqB,6BAA6B;AAAA,EACnD,CAAC,qBAAqB,6BAA6B;AAAA,EACnD,CAAC,eAAe,wBAAwB;AAAA,EACxC,CAAC,eAAe,wBAAwB;AAAA,EACxC,CAAC,gBAAgB,yBAAyB;AAAA,EAC1C,CAAC,oBAAoB,2BAA2B;AAAA,EAChD,CAAC,aAAa,0BAA0B;AAAA,EACxC,CAAC,iBAAiB,wBAAwB;AAAA,EAC1C,CAAC,eAAe,8BAA8B;AAAA,EAC9C,CAAC,kBAAkB,yBAAyB;AAAA,EAC5C,CAAC,uBAAuB,+BAA+B;AAAA,EACvD,CAAC,UAAU,gCAAgC;AAAA,EAC3C,CAAC,UAAU,gCAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3C,CAAC,gBAAgB,yBAAyB;AAAA,EAC1C,CAAC,eAAe,0BAA0B;AAAA,EAC1C,CAAC,gBAAgB,yBAAyB;AAAA,EAC1C,CAAC,cAAc,uBAAuB;AAAA,EACtC,CAAC,kBAAkB,6GAAmG;AAAA,EACtH,CAAC,cAAc,kEAAkE;AAAA,EACjF,CAAC,SAAS,qDAAqD;AAAA,EAC/D,CAAC,aAAa,sCAAsC;AAAA,EACpD,CAAC,UAAU,2FAAsF;AAAA,EACjG,CAAC,UAAU,4EAA4E;AAAA,EACvF,CAAC,UAAU,+BAA+B;AAAA,EAC1C,CAAC,gBAAgB,yBAAyB;AAAA,EAC1C,CAAC,iBAAiB,mDAA8C;AAAA,EAChE,CAAC,UAAU,+BAA+B;AAAA,EAC1C,CAAC,YAAY,uBAAuB;AAAA,EACpC,CAAC,qBAAqB,mCAAmC;AAAA,EACzD,CAAC,qBAAqB,0BAA0B;AAAA,EAChD,CAAC,SAAS,wBAAwB;AAAA,EAClC,CAAC,wBAAwB,kHAA6G;AAAA,EACtI,CAAC,iBAAiB,kFAA6E;AAAA,EAC/F,CAAC,gBAAgB,mFAA8E;AACjG,CAAC;AAMM,SAAS,wBAAwB,MAA6B;AACnE,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,OAAO,KAAK,sBAAsB;AACjD,UAAM,UAAU,IAAI,OAAO,MAAM,IAAI,QAAQ,uBAAuB,MAAM,CAAC,OAAO,GAAG;AACrF,QAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,YAAM,KAAK,KAAK,GAAG,eAAU,OAAO,IAAI;AAAA,IAC1C;AAAA,EACF;AACA,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,SAAO;AAAA;AAAA;AAAA;AAAA,EAA+E,MAAM,IAAI,OAAK,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAC3H;;;AC5KA,IAAM,kBAAkB;AACxB,IAAM,cAAc,oBAAI,IAA4B;AACpD,IAAM,kBAAkB;AAExB,SAAS,oBAA4B;AACnC,SAAO,kBAAkB,KAAK;AAChC;AAEA,SAAS,kBAAkB,YAAoC;AAC7D,MAAI,OAAO,YAAY,IAAI,UAAU;AACrC,MAAI,CAAC,MAAM;AACT,WAAO,CAAC;AACR,gBAAY,IAAI,YAAY,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAAsB,KAA4B;AACrE,QAAM,SAAS,IAAI,YAAY;AAC/B,SAAO,KAAK;AAAA,IACV,CAAC,aACC,SAAS,UAAU,IAAI,SACvB,SAAS,SAAS,IAAI,QACtB,SAAS,WAAW,IAAI,UACxB,SAAS,aAAa;AAAA,EAC1B;AACF;AAMO,SAAS,UAAU,KAA+C;AACvE,QAAM,cAA4B,EAAE,GAAG,KAAK,WAAW,KAAK,IAAI,EAAE;AAClE,QAAM,aAAa,kBAAkB;AACrC,QAAM,OAAO,kBAAkB,UAAU;AACzC,MAAI,YAAY,MAAM,WAAW,EAAG,QAAO;AAC3C,OAAK,KAAK,WAAW;AAErB,aAAW,GAAG;AACd,SAAO;AACT;AAEA,SAAS,WAAW,KAA4C;AAC9D,QAAM,YAAY,kBAAkB;AACpC,iBAAe,eAAe;AAAA,IAC5B,WAAW,aAAa;AAAA,IACxB,OAAO,IAAI;AAAA,IACX,MAAM,IAAI;AAAA,IACV,QAAQ,IAAI;AAAA,IACZ,SAAS,IAAI;AAAA,IACb,iBAAiB,IAAI;AAAA,EACvB,CAAC,EAAE,MAAM,MAAM;AAAA,EAEf,CAAC;AACH;AAEO,SAAS,iBAA0C;AACxD,SAAO,kBAAkB,kBAAkB,CAAC;AAC9C;AAGO,SAAS,WAAW,QAAQ,GAA8D;AAC/F,QAAM,OAAO,kBAAkB,kBAAkB,CAAC;AAClD,QAAM,SAAS,oBAAI,IAAiD;AACpE,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,IAAI,MAAM,YAAY,EAAE,KAAK;AACzC,UAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,QAAI,UAAU;AACZ,eAAS;AAAA,IACX,OAAO;AACL,aAAO,IAAI,KAAK,EAAE,OAAO,GAAG,SAAS,IAAI,QAAQ,CAAC;AAAA,IACpD;AAAA,EACF;AACA,SAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,EACxB,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,OAAO,OAAO,QAAQ,EAAE,EAChE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,MAAM,GAAG,KAAK;AACnB;AAEO,SAAS,mBAAyB;AACvC,QAAM,aAAa,kBAAkB;AACrC,cAAY,OAAO,UAAU;AAC/B;AAcO,SAAS,oBAAoB,WAAmB,SAAuB;AAC5E,iBAAyD,gBAAgB,EAAE,WAAW,QAAQ,CAAC,EAAE,MAAM,MAAM;AAAA,EAE7G,CAAC;AACH;;;ACpEO,SAAS,mBACd,UACA,QACA,MACA,QACY;AACZ,QAAM,YAAY,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO,KAAK,IAAI,IAAI;AACpE,QAAM,MAAM,WAAW,MAAM,YAAY,SAAS,KAAK,KAAK,WAAW;AACvE,QAAM,UAAU,GAAG,QAAQ,YAAY,MAAM,MAAM,MAAM;AACzD,SAAO;AAAA,IACL,SAAS,YAAY,OAAO;AAAA,IAC5B,mBAAmB;AAAA,MACjB,GAAG,gBAAgB,OAAO;AAAA,MAC1B,OAAO,EAAE,KAAK,UAAU,EAAE,QAAQ,gBAAgB,KAAK,QAAQ,QAAQ,OAAO,EAAE;AAAA,IAClF;AAAA,EACF;AACF;AAUA,eAAsB,sBAGpB,UACAC,QACA,UACA,aACA,UACqB;AACrB,QAAM,SAAS,OAAO,SAAS,UAAU,EAAE;AAC3C,QAAM,SAASA,OAAM,UAAU,QAAQ;AACvC,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,OAAO,YAAY,MAAM;AAC/B,UAAM,SAAS,OAAO,MAAM,OACzB,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,KAAK,MAAM,KAAK,EAAE,OAAO,EAAE,EACxD,KAAK,IAAI;AACZ,QAAI,CAAC,MAAM;AAGT,aAAO,mBAAmB,UAAU,QAAQ,EAAE,QAAQ,CAAC,GAAG,aAAa,iBAAiB,GAAG,MAAM;AAAA,IACnG;AACA,WAAO,mBAAmB,UAAU,QAAQ,MAAM,MAAM;AAAA,EAC1D;AACA,QAAM,UAAU,SAAS,MAAM;AAC/B,MAAI,CAAC,SAAS;AACZ,UAAM,OAAO,YAAY,MAAM,KAAK,EAAE,QAAQ,CAAC,GAAG,aAAa,iBAAiB;AAChF,WAAO,mBAAmB,UAAU,QAAQ,MAAM,qCAAqC,MAAM,GAAG;AAAA,EAClG;AACA,SAAO,QAAQ,OAAO,IAAI;AAC5B;;;AC1HA,SAAS,KAAAC,UAAS;;;ACOlB,SAAS,KAAAC,UAAS;;;AC2BX,SAAS,iBAAiB,OAA8C;AAC7E,SAAQ,OAAgD,SAAS;AACnE;AAeO,SAAS,iCACd,OACA,MACA,KACY;AACZ,MAAI,CAAC,MAAM,cAAe,QAAO,yBAAyB,OAAO,GAAG;AACpE,QAAM,WACJ,eAAe,IAAI;AAErB,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MACE;AAAA;AAAA,EAA6C,GAAG;AAAA;AAAA,0FAEvC,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAOH,QAAQ;AAAA,IACjC,CAAC;AAAA,IACD,mBAAmB;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,EAAE,MAAM,WAAW,aAAa,wCAAwC,YAAY,EAAE,QAAQ,UAAU,OAAO,KAAK,EAAE,CAAC;AAAA,MACxH;AAAA;AAAA;AAAA,QAGE,gBAAgB;AAAA,QAChB,eAAe,MAAM;AAAA,QACrB,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,wBAAwB,CAAC;AAAA;AAAA;AAAA;AAAA,QAIzB,WAAW,CAAC,WAAW;AAAA;AAAA;AAAA;AAAA,QAIvB,YAAY,CAAC,UAAU,UAAU;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACF;AAiBA,SAAS,yBAAyB,OAA4B,KAAyB;AACrF,QAAM,WAAW;AACjB,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MACE;AAAA;AAAA,EAAsD,GAAG;AAAA;AAAA,0FAEhD,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA,oBAIH,QAAQ;AAAA,IACjC,CAAC;AAAA,IACD,mBAAmB;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD;AAAA;AAAA,QAEE,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,wBAAwB,CAAC;AAAA,QACzB,WAAW,CAAC,SAAS,aAAa,UAAU,UAAU;AAAA,QACtD,YAAY,CAAC;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,wBAAwB,OAAgB,WAA2B;AACjF,QAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,MAAI,CAAC,iBAAiB,KAAK,EAAG,QAAO;AAGrC,SAAO,MAAM,gBACT,GAAG,GAAG,sDAAiD,SAAS,gEAChE,GAAG,GAAG;AACZ;;;ACjJO,IAAM,cAAN,MAAqB;AAAA,EAE1B,YACmB,OACA,YAAY,KAC7B;AAFiB;AACA;AAAA,EAChB;AAAA,EAJK,QAAQ,oBAAI,IAAsB;AAAA,EAM1C,IAAI,OAA8B;AAChC,UAAM,IAAI,KAAK,MAAM,IAAI,KAAK;AAC9B,QAAI,CAAC,EAAG,QAAO;AACf,QAAI,KAAK,IAAI,IAAI,EAAE,WAAW;AAC5B,WAAK,MAAM,OAAO,KAAK;AACvB,aAAO;AAAA,IACT;AACA,WAAO,EAAE;AAAA,EACX;AAAA,EAEA,IAAI,OAAe,OAAgB;AACjC,SAAK,MAAM,IAAI,OAAO,EAAE,OAAO,WAAW,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC;AACnE,QAAI,KAAK,MAAM,OAAO,KAAK,UAAW,MAAK,MAAM;AAAA,EACnD;AAAA,EAEA,OAAO,OAAqB;AAC1B,SAAK,MAAM,OAAO,KAAK;AAAA,EACzB;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,OAAe;AACb,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGQ,QAAc;AACpB,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,CAAC,GAAG,CAAC,KAAK,KAAK,OAAO;AAC/B,UAAI,MAAM,EAAE,UAAW,MAAK,MAAM,OAAO,CAAC;AAAA,IAC5C;AACA,QAAI,KAAK,MAAM,OAAO,KAAK,WAAW;AACpC,YAAM,SAAS,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS;AACvF,YAAM,SAAS,OAAO,SAAS,KAAK;AACpC,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,aAAK,MAAM,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,0BAA0B;;;ACvCvC,SAAS,cAAc,OAAoC;AACzD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,IAAM,wBACJ;AAWK,SAAS,uBACd,UACA,SACA,SACA,SACA;AACA,QAAM,eAAe,SAAS,gBAAgB;AAC9C,QAAM,UAAU,IAAI,OAAO,YAAY;AACvC,QAAM,QAAkB;AAAA,IACtB,GAAG,OAAO;AAAA,IACV;AAAA,IACA,QAAQ,UAAU,4CAA4C,OAAO;AAAA,EACvE;AAEA,MAAI,QAAQ,SAAS,MAAM;AACzB,UAAM,KAAK,OAAO,QAAQ,QAAQ,IAAI,EAAE;AAAA,EAC1C;AAEA,MAAI,QAAQ,MAAM;AAChB,UAAM,KAAK,IAAI,SAAS,QAAQ,IAAI,EAAE;AAAA,EACxC;AAEA,QAAM,SAAS,QAAQ;AACvB,QAAM,YAAY,SAAS,OAAO,KAAK,MAAM,IAAI,CAAC;AAClD,MAAI,UAAU,SAAS,GAAG;AAIxB,UAAM,KAAK,IAAI,GAAG,IAAI,OAAO,eAAe,CAAC,CAAC,kBAAkB;AAGhE,UAAM,eAAe,MAAM;AAC3B,QAAI,UAAU,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,MAAM;AACrE,YAAM,OAAO,OAAO;AACpB,YAAM,KAAK,eAAe,cAAc,KAAK,WAAW,KAAK,wCAAwC,EAAE;AAAA,IACzG;AACA,QAAI,UAAU,OAAO,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,MAAM;AACnF,YAAM,MAAM,OAAO;AACnB,YAAM,YAAY,IAAI,WAAW,KAAK,KAAK,KAAK;AAChD,YAAM;AAAA,QACJ,wBAAwB,IAAI,SAAS,0BAA0B,QAAQ,SAAS,GAAG,IAAI,iBAAiB,WAAM,IAAI,cAAc,yBAAyB,EAAE,KAAK,cAAc,IAAI,WAAW,KAAK,EAAE,GAAG,KAAK;AAAA,MAC9M;AAAA,IACF;AACA,QAAI,UAAU,OAAO,OAAO,aAAa,YAAY,OAAO,aAAa,MAAM;AAC7E,YAAM,KAAK,OAAO;AAClB,YAAM;AAAA,QACJ,qBAAqB,GAAG,SAAS,wBAAwB,cAAS,GAAG,YAAY,EAAE,WAAW,cAAc,GAAG,WAAW,KAAK,EAAE,GAAG,KAAK;AAAA,MAC3I;AAAA,IACF;AACA,QAAI,MAAM,WAAW,cAAc;AAGjC,YAAM,KAAK,qBAAqB;AAAA,IAClC;AAAA,EACF,OAAO;AACL,UAAM,KAAK,IAAI,qBAAqB;AAAA,EACtC;AAEA,SAAO;AAAA,IACL,MAAM,KAAK,IAAI;AAAA,IACf;AAAA,IACA,0BAA0B,QAAQ,OAAO,OAAO;AAAA,IAChD;AAAA,IACA;AAAA,IACA,EAAE,SAAS,QAAQ;AAAA,EACrB;AACF;;;ACzFA,eAAsB,kBAAkB,QAKD;AACrC,QAAM,EAAE,MAAM,aAAa,UAAU,mBAAmB,IAAI;AAE5D,QAAM,YAAY,kBAAkB;AACpC,QAAMC,UAAS,MAAM,WAAgE,2BAA2B;AAAA,IAC9G,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/B,GAAI,qBAAqB,EAAE,mBAAmB,IAAI,CAAC;AAAA,IACnD,GAAI,YAAY,EAAE,gBAAgB,UAAU,IAAI,CAAC;AAAA,EACnD,CAAC;AAED,SAAOA,WAAU;AACnB;;;ACVO,IAAM,sBAAkD;AAAA,EAC9D,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB,CAAC;AAAA,EACjB,SAAS,CAAC;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AACX;;;ACzBO,SAAS,oBAAoB,QAAqC;AACxE,QAAM,eAAe,OAAO,OAAO,CAAC,MAAM,EAAE,eAAe;AAC3D,MAAI,aAAa,WAAW,EAAG,QAAO;AAEtC,QAAM,QAAkB,CAAC,qBAAqB;AAC9C,aAAW,SAAS,cAAc;AACjC,UAAMC,eAAc,MAAM,SAAS,MAAM;AACzC,UAAM,KAAK,KAAKA,YAAW,KAAK,MAAM,eAAe,EAAE;AACvD,QAAI,MAAM,mBAAmB,MAAM,gBAAgB,SAAS,GAAG;AAC9D,YAAM,KAAK,eAAe,MAAM,gBAAgB,KAAK,KAAK,CAAC,EAAE;AAAA,IAC9D;AAAA,EACD;AAEA,SAAO,MAAM,KAAK,IAAI;AACvB;;;ACvBO,SAAS,mBAAmB,QAAuD;AACzF,QAAM,WAAW,OACf,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,CAAC,EACvF,KAAK,IAAI;AAEX,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,WAAW,SAAS,MAAM,2BAA2B;AAC3D,MAAI,SAAU,QAAO,SAAS,CAAC;AAE/B,QAAM,aAAa,SAAS;AAAA,IAC3B;AAAA,EACD;AACA,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,aAAa;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,EAAE,QAAQ,WAAW,CAAC,EAAE,YAAY,CAAC;AACrC,MAAI,aAAa,EAAG,QAAO;AAE3B,QAAM,eAAe,WAAW,CAAC,KAAK,SAAS,MAAM,eAAe,IAAI,CAAC,KAAK,QAAO,oBAAI,KAAK,GAAE,eAAe,CAAC;AAChH,QAAM,QAAQ,OAAO,aAAa,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,QAAM,MAAM,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACzC,SAAO,GAAG,YAAY,IAAI,KAAK,IAAI,GAAG;AACvC;;;ACiDA,IAAM,kBAAkB,IAAI,YAAkC,uBAAuB;AASrF,eAAsB,iBAA2C;AAC/D,QAAM,QAAQ,WAAW;AACzB,QAAM,MAAM,gBAAgB,IAAI,KAAK;AACrC,MAAI,IAAK,QAAO,IAAI;AACpB,QAAMC,UAAU,MAAM,YAA6B,uBAAuB,KAAM,CAAC;AACjF,QAAM,SAAS,IAAI,IAAIA,QAAO,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrD,kBAAgB,IAAI,OAAO,EAAE,aAAaA,SAAQ,OAAO,CAAC;AAC1D,SAAOA;AACT;AAKA,eAAsB,oBAAoB,MAAkD;AAC1F,QAAM,eAAe;AACrB,SAAO,gBAAgB,IAAI,WAAW,CAAC,GAAG,OAAO,IAAI,IAAI;AAC3D;AAQO,SAAS,oCAA0C;AACxD,kBAAgB,OAAO,WAAW,CAAC;AACrC;AA2BA,eAAsB,WAAW,MAAgC;AAC/D,QAAM,MAAM,MAAM,oBAAoB,IAAI;AAC1C,SAAO,CAAC,CAAC,KAAK;AAChB;;;ACzJO,IAAM,aAAa,oBAAI,IAAI;AAAA,EAChC;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACtE;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACtE;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACtE;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EACvE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EACxE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EACxE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EACrE;AAAA,EAAU;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAC3E,CAAC;AAEM,SAAS,aAAa,OAAyB;AACpD,SAAO,MACJ,YAAY,EACZ,QAAQ,sBAAsB,GAAG,EACjC,MAAM,KAAK,EACX,OAAO,OAAO;AACnB;;;ACDA,SAAS,KAAAC,UAAS;;;ACNlB,SAAS,KAAAC,UAAS;AAyBX,IAAM,4BAA4BC,GAAE,OAAO;AAAA,EAChD,OAAOA,GAAE,OAAO;AAAA,EAChB,YAAYA,GAAE,OAAO;AAAA,EACrB,MAAMA,GAAE,OAAO;AAAA,EACf,OAAOA,GAAE,OAAO;AAAA,EAChB,eAAeA,GAAE,QAAQ;AAAA,EACzB,UAAUA,GAAE,OAAO;AAAA,EACnB,WAAWA,GAAE,OAAO;AACtB,CAAC;AAOM,SAAS,qBAAqB,OAAiD;AACpF,SAAO,iBAAiB,KAAK,IACzB,EAAE,eAAe,MAAM,eAAe,UAAU,MAAM,UAAU,WAAW,MAAM,UAAU,IAC3F;AACN;AAGO,SAAS,0BAA0B,OAAgB,WAA4E;AACpI,SAAO,EAAE,OAAO,wBAAwB,OAAO,SAAS,GAAG,gBAAgB,qBAAqB,KAAK,EAAE;AACzG;AAOO,SAAS,gBAEd,OAA6E;AAC7E,SAAO;AAAA,IACL,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,cAAc;AAAA,IAC7C,gBAAgB,MAAM,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO;AAAA,MAChE,OAAO,EAAE;AAAA,MACT,YAAY,EAAE;AAAA,MACd,MAAM,EAAE;AAAA,MACR,OAAO,EAAE,SAAS;AAAA,MAClB,eAAe,EAAE,eAAgB;AAAA,MACjC,UAAU,EAAE,eAAgB;AAAA,MAC5B,WAAW,EAAE,eAAgB;AAAA,IAC/B,EAAE;AAAA,EACJ;AACF;AAGO,SAAS,0BAA0B,SAAqC;AAC7E,SAAO,QAAQ,SAAS,IAAI,KAAK,QAAQ,MAAM,qBAAqB;AACtE;AAQO,SAAS,4BAA4B,SAAmD;AAC7F,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAMlC,QAAM,mBAAmB,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa;AAC5D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAG,QAAQ,IAAI,CAAC,MAAM,KAAK,EAAE,IAAI,KAAK,EAAE,UAAU,OAAO,EAAE,KAAK,GAAG;AAAA,IACnE;AAAA,IACA,mBACI,sLACA;AAAA,EACN;AACF;;;ADvEO,IAAM,+BAA+BC,GAAE,OAAO;AAAA,EACnD,UAAUA,GAAE,MAAMA,GAAE,OAAO;AAAA,IACzB,SAASA,GAAE,OAAO;AAAA,IAClB,YAAYA,GAAE,OAAO;AAAA,IACrB,MAAMA,GAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKf,QAAQA,GAAE,KAAK,CAAC,SAAS,aAAa,YAAY,kBAAkB,CAAC;AAAA,IACrE,cAAcA,GAAE,KAAK,CAAC,OAAO,aAAa,UAAU,CAAC,EAAE,SAAS;AAAA,IAChE,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,IAChC,gBAAgBA,GAAE,KAAK,CAAC,QAAQ,UAAU,KAAK,CAAC,EAAE,SAAS;AAAA,IAC3D,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACvC,eAAeA,GAAE,OAAO;AAAA,MACtB,UAAUA,GAAE,OAAOA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MACxC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACzC,CAAC,EAAE,SAAS;AAAA;AAAA,IAEZ,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA,IAG5B,kBAAkBA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,IAIjD,uBAAuBA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACxD,CAAC,CAAC;AAAA,EACF,OAAOA,GAAE,OAAO;AAAA,EAChB,QAAQA,GAAE,OAAO;AAAA,EACjB,WAAWA,GAAE,OAAO;AAAA,EACpB,UAAUA,GAAE,OAAO;AAAA,EACnB,QAAQA,GAAE,OAAO;AAAA,EACjB,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAChC,mBAAmBA,GAAE,QAAQ;AAAA,EAC7B,sBAAsBA,GAAE,MAAMA,GAAE,OAAO;AAAA,IACrC,OAAOA,GAAE,OAAO;AAAA,IAChB,MAAMA,GAAE,OAAO;AAAA,IACf,qBAAqBA,GAAE,OAAO,EAAE,SAAS;AAAA,IACzC,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,IAChC,cAAcA,GAAE,MAAMA,GAAE,OAAO;AAAA,MAC7B,YAAYA,GAAE,OAAO;AAAA,MACrB,YAAYA,GAAE,OAAO;AAAA,IACvB,CAAC,CAAC,EAAE,SAAS;AAAA,EACf,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,eAAeA,GAAE,MAAMA,GAAE,OAAO;AAAA,IAC9B,OAAOA,GAAE,OAAO;AAAA,IAChB,YAAYA,GAAE,OAAO;AAAA,IACrB,MAAMA,GAAE,OAAO;AAAA,IACf,OAAOA,GAAE,OAAO;AAAA,EAClB,CAAC,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAIb,uBAAuBA,GAAE,MAAM,yBAAyB,EAAE,SAAS;AACrE,CAAC;AAQM,IAAM,kCAAkCA,GAAE,OAAO;AAAA,EACtD,SAASA,GAAE,QAAQ,SAAS;AAAA,EAC5B,cAAcA,GAAE,MAAMA,GAAE,OAAO;AAAA;AAAA;AAAA,IAG7B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,0BAA0BA,GAAE,QAAQ,IAAI,EAAE,SAAS;AAAA,IACnD,YAAYA,GAAE,OAAO;AAAA,IACrB,MAAMA,GAAE,OAAO;AAAA,IACf,cAAcA,GAAE,OAAO,EAAE,SAAS;AAAA,IAClC,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,IAChC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACzC,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKF,YAAYA,GAAE,MAAMA,GAAE,OAAO;AAAA,IAC3B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,0BAA0BA,GAAE,QAAQ,IAAI,EAAE,SAAS;AAAA,IACnD,YAAYA,GAAE,OAAO;AAAA,IACrB,MAAMA,GAAE,OAAO;AAAA,IACf,gBAAgBA,GAAE,OAAO,EAAE,SAAS;AAAA,IACpC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACzC,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,WAAWA,GAAE,OAAO;AAAA,EACpB,OAAOA,GAAE,OAAO;AAAA,EAChB,QAAQA,GAAE,OAAO;AAAA,EACjB,sBAAsBA,GAAE,MAAMA,GAAE,OAAO;AAAA,IACrC,OAAOA,GAAE,OAAO;AAAA,IAChB,MAAMA,GAAE,OAAO;AAAA,IACf,qBAAqBA,GAAE,OAAO,EAAE,SAAS;AAAA,IACzC,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,eAAeA,GAAE,MAAMA,GAAE,OAAO;AAAA,IAC9B,OAAOA,GAAE,OAAO;AAAA,IAChB,YAAYA,GAAE,OAAO;AAAA,IACrB,MAAMA,GAAE,OAAO;AAAA,IACf,OAAOA,GAAE,OAAO;AAAA,EAClB,CAAC,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAIb,uBAAuBA,GAAE,MAAM,yBAAyB,EAAE,SAAS;AACrE,CAAC;AAGM,IAAM,2BAA2BA,GAAE,MAAM;AAAA,EAC9C;AAAA,EACA;AACF,CAAC;AAqFM,SAAS,yBAAyB,EAAE,cAAc,aAAa,CAAC,GAAG,QAAQ,iBAAiB,CAAC,GAAG,SAAS,UAAU,GAA8B;AACtJ,QAAM,OAAO,cAAc,IAAI,UAAU;AACzC,QAAM,cAAc,WAAW,SAAS,IAAI,KAAK,WAAW,MAAM,sBAAsB;AACxF,QAAM,aAAa,OAAO,SAAS,IAAI,KAAK,OAAO,MAAM,gBAAgB;AACzE,QAAM,cAAc,0BAA0B,cAAc;AAC5D,QAAM,cAAc,QAAQ,SAAS,IAAI,KAAK,QAAQ,MAAM,8BAA8B;AAC1F,SAAO,0BAA0B,aAAa,MAAM,OAAO,SAAS,IAAI,IAAI,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW;AACrI;AAqDO,SAAS,uBAAuB,MAcpC;AACD,SAAO;AAAA,IACL,UAAU,KAAK;AAAA,IACf,MAAM,KAAK;AAAA,IACX,YAAY,KAAK;AAAA,IACjB,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,WAAW;AAAA,IACX,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,cAAc,KAAK;AAAA,IACnB,YAAY,KAAK;AAAA,IACjB,gBAAgB,KAAK;AAAA,IACrB,OAAO,KAAK;AAAA,IACZ,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,EACvE;AACF;AASO,SAAS,6BACd,SACA,QACA,SACA,WACA,eAGA,oBACA;AAMA,QAAM,sBAAsB,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU;AAC/D,QAAM,oBAAoB,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU;AAC5D,QAAM,EAAE,QAAQ,iBAAiB,gBAAgB,SAAS,IAAI,gBAAgB,MAAM;AACpF,SAAO,wBAAwB;AAAA;AAAA;AAAA;AAAA,IAI7B,cAAc,oBAAoB,IAAI,CAAC,OAAO;AAAA,MAC5C,GAAI,EAAE,2BAA2B,EAAE,0BAA0B,KAAc,IAAI,EAAE,SAAS,EAAE,QAAQ;AAAA,MACpG,YAAY,EAAE;AAAA,MACd,MAAM,EAAE;AAAA,MACR,GAAI,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;AAAA,MACzD,GAAI,EAAE,cAAc,OAAO,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,MAC3D,GAAI,EAAE,UAAU,SAAS,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,IACvD,EAAE;AAAA,IACF,YAAY,kBAAkB,IAAI,CAAC,OAAO;AAAA,MACxC,GAAI,EAAE,2BAA2B,EAAE,0BAA0B,KAAc,IAAI,EAAE,SAAS,EAAE,QAAQ;AAAA,MACpG,YAAY,EAAE;AAAA,MACd,MAAM,EAAE;AAAA,MACR,GAAI,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,IAAI,CAAC;AAAA,MAC/D,GAAI,EAAE,UAAU,SAAS,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,IACvD,EAAE;AAAA,IACF,QAAQ,gBAAgB,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,YAAY,EAAE,YAAY,MAAM,EAAE,MAAM,OAAO,EAAE,SAAS,gBAAgB,EAAE;AAAA,IACrI,gBAAgB;AAAA;AAAA,IAChB,SAAS,QAAQ,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,GAAI,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,oBAAoB,IAAI,CAAC,GAAI,GAAI,EAAE,cAAc,OAAO,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC,EAAG,EAAE;AAAA,IAC/M;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA;AAAA;AAAA,IAEA;AAAA,EACF,CAAC;AACH;AAEO,SAAS,wBAAwB,OAA0B;AAChE,QAAM,EAAE,cAAc,aAAa,CAAC,GAAG,QAAQ,iBAAiB,CAAC,GAAG,SAAS,WAAW,eAAe,mBAAmB,IAAI;AAC9H,QAAM,UAAU,yBAAyB,KAAK;AAE9C,QAAM,QAAkB,CAAC,6CAAwC,SAAS,EAAE;AAE5E,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,KAAK,kBAAkB;AAC7B,eAAW,KAAK,cAAc;AAC5B,YAAM,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,aAAa,KAAK,EAAE,YAAY,GAAG,EAAE,cAAc,OAAO,IAAI,EAAE,UAAU,MAAM,EAAE,MAAM;AAC/I,YAAM,WAAW,EAAE,UAAU,SAAS,WAAM,EAAE,SAAS,KAAK,IAAI,CAAC,KAAK;AAGtE,YAAM,SAAS,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAClD,YAAM,eAAe,EAAE,2BAA2B,8BAA8B;AAChF,YAAM,KAAK,KAAK,MAAM,KAAK,EAAE,IAAI,OAAO,EAAE,UAAU,IAAI,SAAS,GAAG,QAAQ,GAAG,YAAY,EAAE;AAAA,IAC/F;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,KAAK,qBAAqB;AAChC,eAAW,KAAK,YAAY;AAC1B,YAAM,aAAa,EAAE,iBAAiB,WAAM,EAAE,cAAc,KAAK;AACjE,YAAM,SAAS,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAClD,YAAM,eAAe,EAAE,2BAA2B,8BAA8B;AAChF,YAAM,KAAK,KAAK,MAAM,KAAK,EAAE,IAAI,OAAO,EAAE,UAAU,IAAI,UAAU,GAAG,YAAY,EAAE;AAAA,IACrF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,2CAAsC;AACjD,eAAW,KAAK,SAAS;AACvB,YAAM,aAAa,EAAE,sBAAsB,yBAAoB,EAAE,mBAAmB,KAAK,EAAE,cAAc,OAAO,KAAK,EAAE,UAAU,OAAO,EAAE,KAAK;AAC/I,YAAM,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,IAAI,GAAG,UAAU,EAAE;AAAA,IACxD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,eAAe;AAC1B,eAAW,KAAK,QAAQ;AACtB,YAAM,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,OAAO,EAAE,KAAK,GAAG;AAAA,IAC3E;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAIA,QAAM,KAAK,GAAG,4BAA4B,cAAc,CAAC;AAEzD,QAAM,KAAK,+FAA0F;AAErG,QAAM,OACJ,iBAAiB,cAAc,SAAS,IACpC,CAAC;AAAA,IACC,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,OAAO;AAAA;AAAA;AAAA;AAAA,MAIP,GAAI,uBAAuB,SAAY,EAAE,YAAY,mBAAmB,IAAI,CAAC;AAAA,IAC/E;AAAA,EACF,CAAC,IACD,CAAC;AAEP,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,GAAG;AAAA,QACD;AAAA,QACA;AAAA,UACE,SAAS;AAAA,UACT;AAAA,UACA,GAAI,WAAW,SAAS,IAAI,EAAE,WAAW,IAAI,CAAC;AAAA,UAC9C;AAAA,UACA,OAAO,aAAa;AAAA,UACpB,QAAQ,OAAO;AAAA,UACf,GAAI,QAAQ,SAAS,IAAI,EAAE,sBAAsB,QAAQ,IAAI,CAAC;AAAA,UAC9D,GAAI,OAAO,SAAS,IAAI,EAAE,eAAe,OAAO,IAAI,CAAC;AAAA;AAAA;AAAA,UAGrD,GAAI,eAAe,SAAS,IAAI,EAAE,uBAAuB,eAAe,IAAI,CAAC;AAAA,QAC/E;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AE3cO,SAAS,2BACdC,SACyC;AACzC,SAAO,aAAaA,WAAUA,QAAO,YAAY;AACnD;AAYO,SAAS,yBACdA,SACA,SAC8D;AAC9D,SAAO,WAAWA,WAAU,2BAA2BA,OAAM,IACzD,EAAE,YAAYA,QAAO,eAAe,MAAM,gBAAgBA,QAAO,eAAe,IAChF;AACN;AAgBO,SAAS,2BACdA,SACA,SACA,oBACQ;AACR,SAAO,WAAWA,WAAU,2BAA2BA,OAAM,IACzDA,QAAO,cAAc,qBACrB;AACN;;;AC/DO,SAAS,aAAa,GAAqB;AAChD,SAAO,KAAK,SAAS,MAAM,QAAQ,CAAC,IAAI,EAAE,WAAW,IAAI,OAAO,CAAC,EAAE,KAAK,MAAM;AAChF;AAGO,SAAS,gBAAgB,GAAqB;AACnD,SAAO,KAAK,SAAS,MAAM,QAAQ,CAAC,IAAI,EAAE,SAAS,IAAI,OAAO,CAAC,EAAE,KAAK,MAAM;AAC9E;AAGA,SAAS,YAAY,GAAW,GAAmB;AACjD,QAAM,IAAI,EAAE;AACZ,QAAM,IAAI,EAAE;AACZ,QAAM,KAAiB,MAAM,IAAI,CAAC,EAC/B,KAAK,IAAI,EACT,IAAI,MAAM,MAAM,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;AACjC,WAAS,IAAI,GAAG,KAAK,GAAG,IAAK,IAAG,CAAC,EAAE,CAAC,IAAI;AACxC,WAAS,IAAI,GAAG,KAAK,GAAG,IAAK,IAAG,CAAC,EAAE,CAAC,IAAI;AACxC,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,YAAM,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI;AACzC,SAAG,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI;AAAA,IACjF;AAAA,EACF;AACA,SAAO,GAAG,CAAC,EAAE,CAAC;AAChB;AAEA,IAAM,mBAAmB,CAAC,SAAS,UAAU,OAAO;AAEpD,SAAS,kBAAkB,OAAe,SAA2D;AACnG,QAAM,QAAQ,MAAM,YAAY;AAChC,QAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,KAAK;AAC3D,MAAI,MAAO,QAAO,EAAE,KAAK,OAAO,MAAM,EAAE;AACxC,SAAO,QAAQ;AAAA,IACb,CAAC,KAAK,QAAQ;AACZ,YAAM,IAAI,YAAY,OAAO,IAAI,YAAY,CAAC;AAC9C,aAAO,IAAI,IAAI,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI;AAAA,IAC3C;AAAA,IACA,EAAE,KAAK,QAAQ,CAAC,GAAG,MAAM,SAAS;AAAA,EACpC;AACF;AAOO,SAAS,oBACd,MACA,QACA,OACM;AACN,MAAI,SAAS,KAAK,YAAY,QAAQ,OAAO,KAAK,aAAa,UAAU;AACvE,UAAM,MAAM,KAAK,SAAS,KAAK;AAC/B,QAAI,KAAK;AACP,YAAM,EAAE,KAAK,KAAK,IAAI,kBAAkB,KAAK,gBAAgB;AAC7D,UAAI,QAAQ,EAAG,MAAK,WAAW;AAAA,IACjC;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,SAAS,YAAY,CAAC,MAAM,SAAS,OAAQ;AACvD,QAAI,MAAM,QAAQ,cAAc,MAAO;AACvC,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,QAAI,OAAO,QAAQ,OAAO,QAAQ,SAAU;AAC5C,UAAM,UAAU,IAAI,KAAK;AACzB,QAAI,CAAC,QAAS;AACd,UAAM,EAAE,KAAK,KAAK,IAAI,kBAAkB,SAAS,MAAM,OAAO;AAC9D,QAAI,QAAQ,EAAG,MAAK,MAAM,GAAG,IAAI;AAAA,EACnC;AACF;;;AC9BA,eAAsB,0BACpB,WACA,cACA,SACA,SACqC;AACrC,QAAMC,UAAqC;AAAA,IACzC,uBAAuB;AAAA,IACvB,wBAAwB;AAAA,IACxB,4BAA4B;AAAA,IAC5B,qBAAqB,CAAC;AAAA,EACxB;AACA,MAAI,CAAC,aAAa,UAAU,WAAW,EAAG,QAAOA;AAEjD,MAAI,SAAS;AAIX,IAAAA,QAAO,6BAA6B,UAAU;AAC9C,WAAOA;AAAA,EACT;AAEA,aAAW,OAAO,WAAW;AAC3B,QAAI;AAIF,YAAM,YAAY,MAAM;AAAA,QACtB;AAAA,QACA;AAAA,UACE,aAAa;AAAA,UACb,WAAW,IAAI;AAAA,UACf,MAAM,IAAI;AAAA,UACV,YAAY;AAAA,UACZ,WAAW,WAAW;AAAA,QACxB;AAAA,MACF;AACA,UAAI,WAAW,WAAW,0BAA0B;AAClD,QAAAA,QAAO;AAAA,MACT,OAAO;AACL,QAAAA,QAAO;AAAA,MACT;AAAA,IACF,SAAS,QAAiB;AACxB,YAAM,SAAS,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AACvE,MAAAA,QAAO,oBAAoB,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,IAAI,MAAM,MAAM,EAAE;AAAA,IACtE;AAAA,EACF;AACA,SAAOA;AACT;;;AChEO,SAAS,8BAA8B,SAA8C;AAC1F,QAAM;AAAA,IACJ;AAAA,IAAY;AAAA,IAAM;AAAA,IAAa;AAAA,IAAS;AAAA,IAAS;AAAA,IAAc;AAAA,IAAM;AAAA,IACrE;AAAA,IAAY;AAAA,IAAW;AAAA,IAAe;AAAA,IAAkB;AAAA,EAC1D,IAAI;AACJ,SAAO,CAAC;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC7B,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC7B,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,MACvC,GAAI,QAAQ,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,MACvD,GAAI,SAAS,MAAM,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC;AAAA,MAC7C,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,MACjD,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACjC,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,MACzC,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC/C,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,IACjD;AAAA,EACF,CAAC;AACH;;;AC3BO,SAAS,qBACdC,SACQ;AACR,QAAM,IAAIA,SAAQ;AAClB,QAAM,WAAW,GAAG,YAAY,CAAC;AAMjC,MAAI,CAAC,KAAK,SAAS,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,SAAS;AACvB,QAAM,SAAS,SAAS,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AAChD,SAAO,EAAE,SACL,gBAAgB,KAAK,2BACrB,YAAY,MAAM,IAAI,KAAK;AACjC;AAMO,SAAS,qBAAqBA,SAAqB;AACxD,QAAM,EAAE,SAAS,YAAY,IAAIA;AACjC,MAAI,CAAC,WAAW,QAAQ,SAAS,WAAW,EAAG,QAAO;AAEtD,QAAM,QAAkB,CAAC,qBAAqB;AAC9C,QAAM,UAAU,QAAQ,YAAY,CAAC,GAAG,OAAO,CAAC,MAAW,CAAC,EAAE,MAAM;AACpE,QAAM,QAAQ,QAAQ,UAAU,UAAU;AAC1C,QAAM,cAAc,QAAQ,OAAO;AAEnC,MAAI,QAAQ,QAAQ;AAClB,UAAM,KAAK,OAAO,KAAK,+BAA+B,QAAQ,YAAY,OAAO,QAAQ,IAAI,SAAS;AAAA,EACxG,OAAO;AACL,UAAM,KAAK,GAAG,WAAW,IAAI,KAAK,wBAAwB,QAAQ,YAAY,OAAO,QAAQ,IAAI,QAAQ;AACzG,UAAM,KAAK,EAAE;AACb,eAAW,KAAK,QAAQ,UAAU;AAChC,YAAM,OAAO,EAAE,SAAS,QAAQ;AAChC,YAAM,QAAQ,EAAE,SAAS,KAAK,WAAM,EAAE,IAAI;AAC1C,YAAM,KAAK,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG,KAAK,EAAE;AAAA,IACtC;AAEA,QAAI,QAAQ,SAAS;AACnB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,sBAAsB,QAAQ,QAAQ,IAAI,EAAE;AACvD,YAAM,KAAK,2BAA2B,QAAQ,QAAQ,gBAAgB,EAAE;AAAA,IAC1E;AAAA,EACF;AAEA,MAAI,aAAa;AACf,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,uBAAuB;AAClC,QAAI,YAAY,mBAAmB;AACjC,YAAM,KAAK,6EAAwE;AAAA,IACrF,OAAO;AACL,YAAM,KAAK,iDAAiD,YAAY,SAAS,EAAE;AACnF,UAAI,YAAY,YAAY;AAC1B,cAAM,KAAK,iBAAiB,YAAY,UAAU,EAAE;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAMO,SAAS,2BAA2B,SAAsB;AAC/D,MAAI,CAAC,WAAW,CAAC,QAAQ,YAAY,QAAQ,SAAS,WAAW,EAAG,QAAO;AAE3E,QAAM,QAAkB,CAAC,qBAAqB;AAC9C,QAAM,SAAS,QAAQ,SAAS,OAAO,CAAC,MAAW,CAAC,EAAE,MAAM;AAC5D,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,cAAc,QAAQ,OAAO;AAEnC,QAAM,iBAAiB,QAAQ,gBAAgB,QAAQ,QAAQ,gBAAgB,KAAM,QAAQ,CAAC,CAAC,MAAM;AACrG,QAAM,aAAa,QAAQ,cAAc,YACrC,0CACA,QAAQ,cAAc,WACpB,gCAA2B,QAAQ,WAAW,KAAK,QAAQ,QAAQ,KAAK,EAAE,gCAC1E,QAAQ,WAAW,SAAS,iBAC1B,oBAAe,cAAc,KAC7B;AAER,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,KAAK,OAAO,KAAK,+BAA+B,QAAQ,YAAY,OAAO,QAAQ,IAAI,UAAU,QAAQ,MAAM,gBAAgB,UAAU,EAAE;AAAA,EACnJ,OAAO;AACL,UAAM,KAAK,GAAG,WAAW,IAAI,KAAK,wBAAwB,QAAQ,YAAY,OAAO,QAAQ,IAAI,UAAU,QAAQ,MAAM,eAAe,UAAU,EAAE;AACpJ,UAAM,KAAK,EAAE;AACb,eAAW,KAAK,QAAQ,UAAU;AAChC,YAAM,OAAO,EAAE,SAAS,QAAQ;AAChC,YAAM,QAAQ,EAAE,SAAS,KAAK,WAAM,EAAE,IAAI;AAC1C,YAAM,KAAK,GAAG,IAAI,IAAI,EAAE,EAAE,GAAG,KAAK,EAAE;AAAA,IACtC;AAEA,QAAI,QAAQ,SAAS;AACnB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,wBAAwB,QAAQ,QAAQ,IAAI,EAAE;AAAA,IAC3D;AAAA,EACF;AAEA,MAAI,QAAQ,aAAa;AACvB,UAAM,KAAK,QAAQ;AACnB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,uBAAuB;AAClC,QAAI,GAAG,mBAAmB;AACxB,YAAM,KAAK,sEAAiE,GAAG,SAAS,EAAE;AAAA,IAC5F,OAAO;AACL,YAAM,KAAK,uCAAuC,GAAG,SAAS,EAAE;AAChE,UAAI,GAAG,YAAY;AACjB,cAAM,KAAK,iBAAiB,GAAG,UAAU,EAAE;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AClIA,SAAS,KAAAC,UAAS;AAGlB,IAAM,8BAA8BA,GAAE,OAAO;AAAA,EAC3C,SAASA,GAAE,OAAO;AAAA,EAClB,MAAMA,GAAE,OAAO;AAAA,EACf,gBAAgBA,GAAE,OAAO;AAAA,EACzB,cAAcA,GAAE,OAAO;AAAA,EACvB,yBAAyBA,GAAE,OAAO;AAAA,EAClC,WAAWA,GAAE,OAAO;AACtB,CAAC;AAGD,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EAC7C,SAASA,GAAE,OAAO;AAAA,EAClB,MAAMA,GAAE,OAAO;AAAA,EACf,gBAAgBA,GAAE,OAAO;AAAA,EACzB,WAAWA,GAAE,KAAK,CAAC,WAAW,oBAAoB,CAAC;AAAA,EACnD,cAAcA,GAAE,OAAO;AACzB,CAAC;AAGD,IAAM,iCAAiCA,GAAE,OAAO;AAAA,EAC9C,SAASA,GAAE,OAAO;AAAA,EAClB,MAAMA,GAAE,OAAO;AAAA,EACf,gBAAgBA,GAAE,OAAO;AAC3B,CAAC;AAQD,IAAM,wBAAwBA,GAAE,OAAO;AAAA,EACrC,SAASA,GAAE,MAAM,2BAA2B;AAAA,EAC5C,YAAYA,GAAE,MAAM,6BAA6B;AAAA,EACjD,YAAYA,GAAE,MAAM,8BAA8B;AACpD,CAAC;AASD,IAAM,sBAAsBA,GAAE,OAAOA,GAAE,QAAQ,CAAC;AASzC,IAAM,mCAAmCA,GAAE,OAAO;AAAA,EACvD,SAASA,GAAE,OAAO;AAAA,EAClB,MAAMA,GAAE,OAAO;AAAA,EACf,YAAYA,GAAE,OAAO;AAAA,EACrB,SAASA,GAAE,KAAK,CAAC,WAAW,SAAS,CAAC;AAAA;AAAA,EAEtC,gBAAgBA,GAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEpC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EAC5B,iBAAiB;AAAA;AAAA,EAEjB,eAAe,oBAAoB,SAAS;AAC9C,CAAC,EAAE,OAAO;;;AC5CH,SAAS,qCAAmE;AACjF,QAAM,mBAAmB,oBAAI,IAAyB;AACtD,QAAM,eAAe,oBAAI,IAAY;AACrC,SAAO;AAAA,IACL,gBAAgB,YAAY,MAAM;AAChC,aAAO,iBAAiB,IAAI,UAAU,GAAG,IAAI,IAAI,KAAK;AAAA,IACxD;AAAA,IACA,WAAW,YAAY,MAAM;AAC3B,UAAI,QAAQ,iBAAiB,IAAI,UAAU;AAC3C,UAAI,CAAC,OAAO;AACV,gBAAQ,oBAAI,IAAI;AAChB,yBAAiB,IAAI,YAAY,KAAK;AAAA,MACxC;AACA,YAAM,IAAI,IAAI;AAAA,IAChB;AAAA,IACA,mBAAmB,SAAS;AAC1B,aAAO,aAAa,IAAI,OAAO;AAAA,IACjC;AAAA,IACA,cAAc,SAAS;AACrB,mBAAa,IAAI,OAAO;AAAA,IAC1B;AAAA,EACF;AACF;AAwBO,SAAS,iCACd,UACA,MACA,YACA,cACA,YACA,gBAC6B;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,WAAW;AAAA,IACX,cAAc;AAAA,IACd,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,qBAAqB,IAAI,uDAAuD,UAAU;AAAA,EACnG;AACF;AAOO,SAAS,wCACd,UACA,MACA,YACA,SACA,cACA,YACA,gBAC6B;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,IAAI;AAAA,IACJ,WAAW;AAAA,IACX,cAAc;AAAA,IACd,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,wBAAwB,OAAO;AAAA,EACxC;AACF;AAQO,SAAS,2BACd,SACA,MAUoC;AACpC,MAAI,CAAC,KAAK,QAAS,QAAO;AAC1B,MAAI,KAAK,iBAAiB,QAAQ,mBAAmB,KAAK,aAAa,GAAG;AACxE,WAAO;AAAA,MACL,KAAK;AAAA,MAAU,KAAK;AAAA,MAAM,KAAK;AAAA,MAAY,KAAK;AAAA,MAChD,KAAK;AAAA,MAAc,KAAK;AAAA,MAAY,KAAK;AAAA,IAC3C;AAAA,EACF;AACA,MAAI,QAAQ,gBAAgB,KAAK,YAAY,KAAK,IAAI,GAAG;AACvD,WAAO;AAAA,MACL,KAAK;AAAA,MAAU,KAAK;AAAA,MAAM,KAAK;AAAA,MAAY,KAAK;AAAA,MAAc,KAAK;AAAA,MAAY,KAAK;AAAA,IACtF;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,8BACd,SACA,MACM;AACN,MAAI,CAAC,KAAK,aAAc;AACxB,UAAQ,WAAW,KAAK,qBAAqB,KAAK,IAAI;AACtD,MAAI,KAAK,cAAe,SAAQ,cAAc,KAAK,aAAa;AAClE;AAkBO,SAAS,+BACd,SACA,MAUoC;AACpC,MAAI,KAAK,gBAAgB,QAAQ,gBAAgB,KAAK,qBAAqB,KAAK,IAAI,GAAG;AACrF,WAAO;AAAA,MACL,KAAK;AAAA,MAAU,KAAK;AAAA,MAAM,KAAK;AAAA,MAAqB,KAAK;AAAA,MAAc,KAAK;AAAA,MAAY,KAAK;AAAA,IAC/F;AAAA,EACF;AACA,gCAA8B,SAAS;AAAA,IACrC,cAAc,KAAK;AAAA,IACnB,qBAAqB,KAAK;AAAA,IAC1B,MAAM,KAAK;AAAA,IACX,eAAe,KAAK;AAAA,EACtB,CAAC;AACD,SAAO;AACT;;;AlB/GA,IAAM,kBAAqC;AAAA,EACzC,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,UAAU,CAAC;AAAA,EACX,0BAA0B,CAAC,cAAc,YAAY;AACvD;AAUA,eAAe,oBAAoB,MAA0C;AAC3E,QAAM,MAAM,MAAM,oBAAoB,IAAI;AAC1C,MAAI,CAAC,IAAK,QAAO;AAEjB,QAAM,SAAS,IAAI,UAAU,CAAC;AAC9B,QAAM,yBAAyB,OAAO;AAAA,IACpC,CAAC,UAAU,MAAM,SAAS,UAAU,MAAM,gBAAgB,cAAc,MAAM,gBAAgB;AAAA,EAChG,GAAG;AACH,QAAM,mBAAmB,IAAI,uBAAuB,0BAA0B;AAE9E,SAAO;AAAA,IACL,eAAe,IAAI,aAAa;AAAA,IAChC;AAAA,IACA,UAAU,CAAC;AAAA,IACX,0BAA0B,gBAAgB;AAAA,EAC5C;AACF;AASA,IAAM,eAAe,IAAI,YAA4C,uBAAuB;AAK5F,eAAsB,WAAW,MAA0C;AACzE,QAAM,QAAQ,WAAW;AACzB,MAAI,MAAM,aAAa,IAAI,KAAK;AAChC,MAAI,CAAC,KAAK;AACR,UAAM,oBAAI,IAAI;AACd,iBAAa,IAAI,OAAO,GAAG;AAAA,EAC7B;AACA,QAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,MAAI,OAAQ,QAAO;AACnB,QAAM,UAAU,MAAM,oBAAoB,IAAI;AAC9C,MAAI,IAAI,MAAM,OAAO;AACrB,SAAO;AACT;AAYO,SAAS,iCAAuC;AACrD,eAAa,OAAO,WAAW,CAAC;AAClC;AAIA,SAAS,mBAAmB,MAAc,aAA6B;AACrE,QAAM,OAAO,GAAG,IAAI,IAAI,WAAW;AACnC,SAAO,KACJ,QAAQ,YAAY,GAAG,EACvB,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,MAAM,GAAG,CAAC,EACV,KAAK,GAAG;AACb;AAwCA,IAAM,WAAW,IAAI,YAAyB,uBAAuB;AAGrE,eAAsB,mBAAyC;AAC7D,QAAM,QAAQ,WAAW;AACzB,QAAM,MAAM,SAAS,IAAI,KAAK;AAC9B,MAAI,IAAK,QAAO;AAChB,QAAM,OAAO,MAAM,eAAe;AAClC,QAAM,MAAM,IAAI;AAAA,IACd,KACG,OAAO,CAAC,MAAM,EAAE,mBAAmB,cAAc,EAAE,kBAAkB,UAAU,EAC/E,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACtB;AACA,WAAS,IAAI,OAAO,GAAG;AACvB,SAAO;AACT;AAYO,SAAS,6BAAmC;AACjD,WAAS,OAAO,WAAW,CAAC;AAC9B;AAeA,SAAS,4BACP,YACA,YACA,mBACA,kBACc;AACd,SAAO;AAAA,IACL,YAAY,WAAW,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,EAAE,aAAa,EAAE;AAAA,IAClF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAkBA,IAAM,+BAA+B;AACrC,IAAM,6BAA6B;AAUnC,SAAS,iBAAiB,KAA2B;AACnD,SAAO,OAAO,WAAW,KAAK,UAAU,GAAG,GAAG,MAAM;AACtD;AAOA,SAAS,kBACP,mBACA,mBACA,SACoB;AACpB,QAAM,OAAO,QAAQ,yBAAyB,CAAC,KAAK;AACpD,QAAM,SAAS,oBAAoB,IAAI;AACvC,SAAO,EAAE,MAAM,OAAO;AACxB;AAQA,IAAM,iCAAiC;AACvC,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAGxB,IAAM,wBAAwB;AAC9B,IAAM,gBAAgBC,GAAE,OAAO,EAAE,MAAM,qBAAqB,EAAE,SAAS,EAAE,SAAS,oIAA+H;AAE1M,IAAM,gBAAgBA,GAAE,OAAO;AAAA,EACpC,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mIAA8H;AAAA,EACzK,MAAMA,GAAE,OAAO,EAAE,SAAS,gGAA2F;AAAA,EACrH,aAAaA,GAAE,OAAO,EAAE,SAAS,yEAAoE;AAAA,EACrG,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yFAAyF;AAAA,EACjI,SAAS;AAAA,EACT,cAAcA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iGAAiG;AAAA,EAC9I,MAAMA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,0JAA0J;AAAA,EAC1M,OAAOA,GAAE,MAAMA,GAAE,OAAO;AAAA,IACtB,IAAIA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,IAC/D,MAAMA,GAAE,OAAO,EAAE,SAAS,yDAAyD;AAAA,EACrF,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,6EAA6E;AAAA,EACrG,YAAYA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oKAAoK;AAAA,EAChN,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yJAAyJ;AAAA,EACnM,eAAeA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gHAAgH;AAAA;AAAA,EAE9J,SAASA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,2FAA2F;AAAA;AAAA,EAEpI,aAAaA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,0LAA0L;AAAA;AAAA,EAEvO,QAAQA,GAAE,KAAK,CAAC,SAAS,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,uJAAuJ;AAAA;AAAA,EAE9M,kBAAkBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,EAC9F,kBAAkBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAChG,CAAC;AAOD,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EAC1C,IAAIA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,4DAA4D;AAAA,EAC7F,MAAMA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,6DAA6D;AAClG,CAAC;AAEM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,SAASA,GAAE,MAAMA,GAAE,OAAO;AAAA;AAAA,IAExB,YAAYA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wEAAmE;AAAA,IACvH,MAAMA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,cAAc;AAAA,IACjD,aAAaA,GAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,2BAA2B;AAAA,IACvE,SAAS;AAAA,IACT,MAAMA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,0GAA0G;AAAA,IAC1J,cAAcA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,uIAAuI;AAAA,IAC7L,WAAWA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,yJAAyJ;AAAA,IAC7M,eAAeA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,gHAAgH;AAAA;AAAA,IAExK,WAAWA,GAAE,MAAM,0BAA0B,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,+HAA0H;AAAA;AAAA,IAErM,kBAAkBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,IAC9F,kBAAkBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,EAChG,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,6BAA6B;AAAA,EACzD,YAAYA,GACT,QAAQ,EACR,SAAS,EACT;AAAA,IACC;AAAA,EAEF;AAAA;AAAA,EAEF,SAASA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4FAA4F;AACvI,CAAC;AAEM,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,SAASA,GAAE,QAAQ;AAAA,EACnB,YAAYA,GAAE,QAAQ;AAAA,EACtB,QAAQA,GAAE,QAAQ;AAAA,EAClB,WAAWA,GAAE,QAAQ;AAAA,EACrB,eAAeA,GAAE,OAAO;AAAA,EACxB,YAAYA,GAAE,OAAO;AAAA,EACrB,SAASA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EAC3B,YAAYA,GAAE;AAAA,IACZA,GAAE,OAAO;AAAA,MACP,YAAYA,GAAE,OAAO;AAAA,MACrB,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,MACjC,YAAYA,GAAE,OAAO;AAAA;AAAA,MAErB,oBAAoBA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EACA,yBAAyBA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7C,iBAAiBA,GAAE,OAAO,EAAE,SAAS;AAAA,EACrC,cAAcA,GAAE,KAAK,CAAC,OAAO,aAAa,UAAU,CAAC,EAAE,SAAS;AAAA,EAChE,gBAAgBA,GAAE,KAAK,CAAC,QAAQ,UAAU,KAAK,CAAC,EAAE,SAAS;AAAA,EAC3D,WAAWA,GAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAiBD,SAAS,yBAAyB,QAQzB;AACP,QAAM,YAAY;AAAA,IAChB,sBAAsB,OAAO;AAAA,IAC7B,YAAY,OAAO;AAAA,IACnB,aAAa,OAAO;AAAA,IACpB,iBAAiB,OAAO;AAAA,IACxB,8BAA8B,OAAO;AAAA,EACvC;AAEA,kCAAgC,OAAO,aAAa,SAAS;AAC7D,MAAI,OAAO,YAAY,eAAe;AACpC,qCAAiC,OAAO,aAAa,SAAS;AAC9D;AAAA,EACF;AACA,iCAA+B,OAAO,aAAa,SAAS;AAC9D;AAEA,SAAS,+BAAkD;AACzD,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MACE;AAAA,IAEJ,CAAC;AAAA,IACD,mBAAmB;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,EAAE,MAAM,eAAe,aAAa,8BAA8B,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,MACnG,EAAE,YAAY,EAAE,SAAS,MAAM,YAAY,OAAO,QAAQ,OAAO,WAAW,MAAM,eAAe,GAAG,YAAY,GAAG,SAAS,CAAC,GAAG,YAAY,CAAC,EAAE,EAAE;AAAA,IACnJ;AAAA,EACF;AACF;AAYA,SAAS,yBACP,UACA,gBACmB;AACnB,QAAM,gBAAgB;AAAA,IACpB,EAAE,YAAY,SAAS,YAAY,YAAY,SAAS,WAAW;AAAA,IACnE,GAAG,SAAS;AAAA,EACd;AAEA,QAAM,uBAAuB,oBAAI,IAAoB;AACrD,aAAW,KAAK,eAAe,YAAY;AACzC,QAAI,EAAE,uBAAuB,QAAW;AACtC,2BAAqB,IAAI,EAAE,YAAY,EAAE,kBAAkB;AAAA,IAC7D;AAAA,EACF;AACA,QAAM,cAAc,cACjB,IAAI,CAAC,MAAM;AACV,UAAM,YAAY,qBAAqB,IAAI,EAAE,UAAU;AACvD,UAAM,YAAY,cAAc,SAAY,KAAK,SAAS,kBAAkB,cAAc,IAAI,KAAK,GAAG,KAAK;AAC3G,WAAO,OAAO,EAAE,UAAU,OAAO,EAAE,UAAU,eAAe,SAAS;AAAA,EACvE,CAAC,EACA,KAAK,IAAI;AACZ,QAAM,WACJ,kCAAkC,SAAS,UAAU,oBAAoB,SAAS,YAAY;AAAA;AAAA,eAC9E,SAAS,UAAU;AAAA,UACxB,SAAS,aAAa,YAAY;AAAA;AAAA;AAAA,EAE1C,WAAW;AAAA;AAAA;AAEhB,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,SAAS,CAAC;AAAA,IACnD,mBAAmB;AAAA,MACjB;AAAA,MACA,8BAA8B,SAAS,UAAU,MAAM,SAAS,UAAU,MAAM,SAAS,YAAY;AAAA,MACrG;AAAA,MACA,cAAc,IAAI,CAAC,OAAO;AAAA,QACxB,MAAM;AAAA,QACN,aAAa,cAAc,EAAE,UAAU;AAAA,QACvC,YAAY,EAAE,YAAY,EAAE,WAAW;AAAA,MACzC,EAAE;AAAA,MACF,EAAE,YAAY,eAAe;AAAA,IAC/B;AAAA,EACF;AACF;AAGA,SAAS,oBACP,UACA,YAAgD,CAAC,GACtB;AAC3B,SAAO;AAAA,IACL,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,eAAe,SAAS;AAAA,IACxB,YAAY,SAAS;AAAA,IACrB,SAAS,SAAS,YAAY,CAAC,SAAS,SAAS,IAAI,CAAC;AAAA,IACtD,YAAY;AAAA,MACV,EAAE,YAAY,SAAS,YAAY,YAAY,SAAS,WAAW;AAAA,MACnE,GAAG,SAAS,aAAa,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,YAAY,YAAY,EAAE,WAAW,EAAE;AAAA,IAC9F,EAAE,MAAM,GAAG,CAAC;AAAA,IACZ,cAAc,SAAS;AAAA,IACvB,gBAAgB,SAAS;AAAA,IACzB,WAAW,SAAS;AAAA,IACpB,GAAG;AAAA,EACL;AACF;AAOA,eAAe,gCAAgC,MAAgD;AAC7F,MAAI;AACF,UAAM,OAAO,MAAM,eAAe;AAClC,UAAM,YAAY,IAAI;AAAA,MACpB,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,MAA8B,EAAE,aAAa,IAAI,EAAE,MAAM,CAAC;AAAA,IAC9G;AACA,SAAK,aAAa,KAAK,WAAW,IAAI,CAAC,OAAO;AAAA,MAC5C,GAAG;AAAA,MACH,oBAAoB,UAAU,IAAI,EAAE,UAAU,KAAK;AAAA,IACrD,EAAE;AAAA,EACJ,QAAQ;AAAA,EAER;AACF;AAMA,SAAS,4BACP,UACA,aACA,MACM;AACN,QAAM,SAAS,SAAS,eAAe,CAAC,KAAK;AAC7C,4BAA0B,aAAa;AAAA,IACrC,iBAAiB,SAAS;AAAA,IAC1B,gBAAgB,SAAS,iBAAiB;AAAA,IAC1C,YAAY,SAAS;AAAA,IACrB,eAAe,SAAS;AAAA,IACxB,iBAAiB,SAAS;AAAA,IAC1B,kBAAkB,QAAQ,cAAc;AAAA,IACxC,wBAAwB,QAAQ,cAAc;AAAA,IAC9C,8BAA8B,KAAK;AAAA,IACnC,aAAa,KAAK;AAAA,EACpB,CAAC;AACH;AAEA,eAAe,yBAAyB,QAMN;AAChC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,YAAY;AACd,UAAMC,YAAW,MAAM,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC9D,QAAIA,WAAU;AACZ,YAAM,SAASA,UAAS,eAAe;AACvC,YAAMC,kBAAiB,oBAAoBD,WAAU;AAAA,QACnD,YAAY;AAAA,QACZ;AAAA,QACA,yBAAyB;AAAA,QACzB,GAAI,CAAC,UAAU;AAAA,UACb,iBAAiB,uBAAuBA,UAAS,UAAU;AAAA,QAC7D;AAAA,MACF,CAAC;AACD,YAAM,gCAAgCC,eAAc;AAEpD,kCAA4BD,WAAU,aAAa;AAAA,QACjD,4BAA4B;AAAA,QAC5B,YAAY;AAAA,MACd,CAAC;AACD,UAAI,CAAC,QAAQ;AACX,iCAAyB;AAAA,UACvB;AAAA,UACA,qBAAqBA,UAAS;AAAA,UAC9B,YAAYA,UAAS;AAAA,UACrB,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,4BAA4B;AAAA,UAC5B,SAAS;AAAA,QACX,CAAC;AAED,cAAM,oBACJA,UAAS,aAAa,KAAK,CAAC,MAAM,EAAE,eAAe,UAAU,KAC7DA,UAAS,eAAe;AAC1B,kCAA0B,aAAa;AAAA,UACrC,uBAAuBA,UAAS;AAAA,UAChC,kBAAkB;AAAA,UAClB,uBAAuBA,UAAS;AAAA,UAChC,iBAAiBA,UAAS;AAAA,UAC1B,qBAAqB;AAAA,QACvB,CAAC;AAAA,MACH;AACA,aAAO,EAAE,oBAAoB,YAAY,gBAAAC,gBAAe;AAAA,IAC1D;AACA,WAAO;AAAA,MACL,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,QACd,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,SAAS,CAAC;AAAA,QACV,YAAY,CAAC;AAAA,QACb,yBAAyB;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC9D,MAAI,CAAC,UAAU;AACb,6BAAyB;AAAA,MACvB;AAAA,MACA,qBAAqB;AAAA,MACrB,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AACD,WAAO,EAAE,aAAa,6BAA6B,EAAE;AAAA,EACvD;AAIA,QAAM,YAAY,SAAS,SAAS;AACpC,QAAM,iBAAiB,oBAAoB,UAAU,EAAE,YAAY,UAAU,CAAC;AAC9E,QAAM,gCAAgC,cAAc;AAGpD,8BAA4B,UAAU,aAAa;AAAA,IACjD;AAAA,IACA,YAAY;AAAA,EACd,CAAC;AAED,MAAI,CAAC,WAAW;AACd,6BAAyB;AAAA,MACvB;AAAA,MACA,qBAAqB,SAAS;AAAA,MAC9B,YAAY,SAAS;AAAA,MACrB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,aAAa,yBAAyB,UAAU,cAAc;AAAA,IAChE;AAAA,EACF;AAEA,2BAAyB;AAAA,IACvB;AAAA,IACA,qBAAqB,SAAS;AAAA,IAC9B,YAAY,SAAS;AAAA,IACrB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AAED,SAAO;AAAA,IACL,oBAAoB,SAAS;AAAA,IAC7B;AAAA,EACF;AACF;AAEA,IAAM,6BAA6BC,GAAE,OAAO;AAAA,EAC1C,SAASA,GAAE,OAAO;AAAA,EAClB,YAAYA,GAAE,OAAO;AAAA,EACrB,MAAMA,GAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,QAAQA,GAAE,KAAK,CAAC,SAAS,aAAa,YAAY,kBAAkB,CAAC;AAAA;AAAA;AAAA,EAGrE,gBAAgBA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAC/C,YAAY,wBAAwB,SAAS;AAAA,EAC7C,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvC,eAAeA,GAAE,OAAO;AAAA,IACtB,UAAUA,GAAE,OAAOA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,IACxC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACzC,CAAC,EAAE,SAAS;AAAA,EACZ,gBAAgBA,GAAE,MAAMA,GAAE,OAAO;AAAA,IAC/B,KAAKA,GAAE,OAAO;AAAA,IACd,MAAMA,GAAE,OAAO;AAAA,IACf,UAAUA,GAAE,QAAQ,EAAE,SAAS;AAAA,EACjC,CAAC,CAAC,EAAE,SAAS;AAAA;AAAA,EAEb,iBAAiBA,GAAE,OAAO;AAAA,IACxB,MAAMA,GAAE,OAAO;AAAA,IACf,QAAQA,GAAE,QAAQ,kBAAkB;AAAA,EACtC,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKZ,kBAAkBA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjD,uBAAuBA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS;AACxD,CAAC,EAAE,OAAO;AAEV,IAAM,oCAAoCA,GAAE,OAAO;AAAA,EACjD,YAAY;AACd,CAAC,EAAE,OAAO;AAMH,IAAM,sBAAsBA,GAAE,MAAM;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAcD,SAAS,wBACP,YACA,gBACS;AACT,MAAI,mBAAmB,OAAQ,QAAO;AACtC,SAAO,eAAe,QAAQ,eAAe;AAC/C;AAOA,SAAS,oBACP,QACA,kBACA,kBACyB;AACzB,QAAM,OAAgC,CAAC;AACvC,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,QAAQ,kBAAkB;AAClC,WAAK,MAAM,GAAG,IAAI;AAAA,IACpB,OAAO;AACL,WAAK,MAAM,GAAG,IAAI,oBAAoB,MAAM,IAAiB,KAAK;AAAA,IACpE;AAAA,EACF;AACA,SAAO;AACT;AAMA,IAAM,kBAAkB,CAAC,WAAW,OAAO;AAG3C,IAAM,oBAAoB,mBAAmB,MAAM,QAAQ;AAQpD,IAAM,wBAAwBA,GAAE,OAAO;AAAA,EAC5C,QAAQA,GAAE,KAAK,eAAe,EAAE,SAAS,EAAE,QAAQ,SAAS,EAAE,SAAS,yMAAyM;AAAA;AAAA,EAEhR,YAAYA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kJAA6I;AAAA,EACjM,MAAMA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,8DAAyD;AAAA,EACvG,aAAaA,GAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,8DAAyD;AAAA,EAChH,SAASA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,EAC/F,SAAS;AAAA,EACT,cAAcA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gHAAgH;AAAA,EACtK,MAAMA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,wFAAwF;AAAA,EACxI,OAAOA,GAAE,MAAMA,GAAE,OAAO;AAAA,IACtB,IAAIA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,uCAAuC;AAAA,IACxE,MAAMA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,yDAAyD;AAAA,EAC9F,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,4FAA4F;AAAA,EAC5H,YAAYA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,8EAA8E;AAAA,EAC1H,WAAWA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,EAC3H,eAAeA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,8EAA8E;AAAA,EACtI,SAASA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4DAA4D;AAAA,EACrG,aAAaA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4GAA4G;AAAA,EACzJ,QAAQA,GAAE,KAAK,CAAC,SAAS,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA;AAAA,EAE3G,OAAOA,GAAE,MAAM,iBAAiB,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,8EAA8E;AAAA;AAAA,EAEnJ,kBAAkBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,EAChG,kBAAkBA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAClG,CAAC;AAKD,IAAM,uBAAuB,cAAc,OAAO,EAAE,QAAQA,GAAE,QAAQ,SAAS,EAAE,CAAC;AAClF,IAAM,sBAAsBA,GAAE,OAAO;AAAA,EACnC,QAAQA,GAAE,QAAQ,OAAO;AAAA,EACzB,OAAOA,GAAE,MAAM,iBAAiB,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EAC/C,YAAYA,GAAE,QAAQ,EAAE,SAAS;AAAA,EACjC,SAASA,GAAE,QAAQ,EAAE,SAAS;AAChC,CAAC;AAEM,IAAM,qBAAqBA,GAAE,mBAAmB,UAAU;AAAA,EAC/D;AAAA,EACA;AACF,CAAC;AAGM,IAAM,uBAA+D;AAAA,EAC1E,SAAS;AAAA,IACP,QAAQ,CAAC,cAAc,QAAQ,eAAe,WAAW,WAAW,gBAAgB,QAAQ,SAAS,cAAc,aAAa,iBAAiB,WAAW,eAAe,QAAQ;AAAA,IACnL,aAAa;AAAA,EACf;AAAA,EACA,OAAO,EAAE,QAAQ,CAAC,SAAS,cAAc,SAAS,GAAG,aAAa,6DAA6D;AACjI;AAEO,SAAS,0BAA0B,QAAmB;AAE3D,QAAM,kBAA6E;AAAA,IACjF,SAAS,CAAC,SAAS,cAAc,QAAQ,IAAI;AAAA,IAC7C,OAAO,CAAC,SAAS,mBAAmB,QAAQ,EAAE,SAAS,KAAK,OAAO,YAAY,KAAK,YAAY,SAAS,KAAK,QAAQ,CAAC;AAAA,EACzH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAkBF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,eAAe,MAAM;AAAA,IACnF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,uBAAuB,IAAI;AACtD,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,WAAW,OAAO;AAAA,QAAG,MACrD,sBAAsB,WAAW,oBAAoB,OAAO,MAAM,sBAAsB,eAAe;AAAA,MACzG;AAAA,IACF,CAAC;AAAA,EACH;AAKF;AAQA,eAAsB,cACpB,QACA,EAAE,YAAY,MAAM,aAAa,SAAS,SAAS,cAAc,MAAM,UAAU,OAAO,YAAY,WAAW,eAAe,SAAS,aAAa,QAAQ,kBAAkB,iBAAiB,GAC/L;AACI,qBAAmB;AAEnB,QAAM,cAAc,KAAK,IAAI;AAE7B,QAAM,QAAQ,MAAM,oBAAoB;AACxC,QAAM,6BAA6B,OAAO,eAAe,YAAY,WAAW,KAAK,EAAE,SAAS;AAEhG,QAAM,aAAa,MAAM,yBAAyB;AAAA,IAChD;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,MAAM;AAAA,IACnB;AAAA,EACF,CAAC;AACD,MAAI,WAAW,aAAa;AAC1B,WAAO,WAAW;AAAA,EACpB;AACA,MAAI,qBAAqB,WAAW;AACpC,QAAM,iBAAiB,WAAW;AAClC,MAAI,CAAC,oBAAoB;AACvB,WAAO,6BAA6B;AAAA,EACtC;AAMA,MACE,uBAAuB,YACvB,CAAC,gBACD,CAAC,8BACD,gBAAgB,YAAY;AAAA,IAC1B,CAAC,MAA8B,EAAE,eAAe;AAAA,EAClD,GACA;AACA,mBAAe;AAAA,EACjB;AAEA,QAAM,iBAAiB,KAAK,IAAI;AAGhC,MAAI,WAAW,uBAAuB,oBAAoB,uBAAuB,aAAa;AAC5F,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA;AAAA,QAEN,MAAM;AAAA;AAAA,wFAAkH,kBAAkB;AAAA,MAC5I,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB;AAAA,QACA,sEAAsE,kBAAkB;AAAA,QACxF;AAAA,QACA,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,WAAW,kBAAkB;AAEnD,QAAM,MAAM,MAAM,YAAkC,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACvG,MAAI,CAAC,KAAK;AACR,UAAMC,eAAc,mBAAmB,MAAM,GAAG,EAAE,IAAI,CAAC,MAAc,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,GAAG;AACrH,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE,gBAAgB,kBAAkB;AAAA;AAAA;AAAA;AAAA,kCAES,kBAAkB,WAAWA,YAAW;AAAA;AAAA;AAAA;AAAA,MAEvF,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB;AAAA,QACA,eAAe,kBAAkB;AAAA,QACjC;AAAA,QACA;AAAA,UACE,EAAE,MAAM,eAAe,aAAa,qBAAqB,YAAY,EAAE,QAAQ,UAAU,MAAM,oBAAoB,MAAMA,aAAY,EAAE;AAAA,UACvI,EAAE,MAAM,eAAe,aAAa,oBAAoB,YAAY,EAAE,QAAQ,OAAO,EAAE;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAKA,QAAM,yBAAyB,SAAS,MAAM,SAAS;AACvD,QAAM,iBAAiB,KAAK,IAAI;AAChC,QAAM,mBAAoB,CAAC,2BAA2B,QAAQ,eAC1D,YAAsE,gCAAgC;AAAA,IACpG,SAAS,CAAC,EAAE,MAAM,aAAa,eAAe,IAAI,gBAAgB,mBAAmB,CAAC;AAAA,IACtF,OAAO;AAAA,IACP,WAAW;AAAA,EACb,CAAC,EAAE,MAAM,MAAM,IAAI,IACnB,QAAQ,QAAQ,IAAI;AAGxB,QAAM,eAAe,MAAM,QAAQ,KAAK;AAAA,IACtC;AAAA,IACA,IAAI,QAAc,CAAC,MAAM,WAAW,MAAM,EAAE,IAAI,GAAG,GAAG,CAAC;AAAA,EACzD,CAAC;AACD,QAAM,qBAAqB,KAAK,IAAI,IAAI;AACxC,QAAM,iBAAkB,eAAuB,CAAC,KAAK;AACrD,QAAM,mBAGD,gBAAgB,WAAW,CAAC;AACjC,QAAM,sBAGD,gBAAgB,cAAc,CAAC;AAKpC,QAAM,uBACH,gBAAgB,cAAc,CAAC,GAAG,IAAI,CAAC,OAAY;AAAA,IAClD,SAAS,EAAE;AAAA,IACX,MAAM,EAAE;AAAA,IACR,gBAAgB,EAAE;AAAA,EACpB,EAAE;AAEJ,QAAM,kBAAkB;AAAA,IACtB,SAAS,iBAAiB,IAAI,CAAC,OAAO;AAAA,MACpC,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,MACR,gBAAgB,EAAE;AAAA,MAClB,cAAc,EAAE;AAAA,MAChB,yBAAyB,EAAE;AAAA,MAC3B,WAAW,EAAE;AAAA,IACf,EAAE;AAAA,IACF,YAAY,oBAAoB,IAAI,CAAC,OAAO;AAAA,MAC1C,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,MACR,gBAAgB,EAAE;AAAA,MAClB,WAAW,EAAE;AAAA,MACb,cAAc,EAAE;AAAA,IAClB,EAAE;AAAA,IACF,YAAY;AAAA,EACd;AAGA,MAAI,aAAa;AACf,UAAM,iBAAiB,gBAAgB,QAAQ,SAAS,KAAK,gBAAgB,WAAW,SAAS;AACjG,UAAM,cAAc,iBAChB,0BAA0B,IAAI,MAAM,gBAAgB,QAAQ,MAAM,aAAa,gBAAgB,WAAW,MAAM,4CAChH,0BAA0B,IAAI;AAClC,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA;AAAA,EAA6C,WAAW;AAAA;AAAA,KAC3D,gBAAgB,QAAQ,SAAS,IAC9B;AAAA,EAAuB,gBAAgB,QAAQ,IAAI,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,cAAc,YAAO,EAAE,SAAS,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,IAC3I,OACH,gBAAgB,WAAW,SAAS,IACjC;AAAA,EAA2B,gBAAgB,WAAW,IAAI,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,cAAc,MAAM,EAAE,SAAS,cAAc,EAAE,YAAY,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,IAC9K,OACH,gBAAgB,WAAW,SAAS,IACjC;AAAA,EAAoC,gBAAgB,WAAW,IAAI,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,cAAc,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,IAC1I,MACJ;AAAA,MACJ,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,GAAG;AAAA,UACD;AAAA,UACA,EAAE,iBAAiB,SAAS,eAAwB;AAAA;AAAA;AAAA,UAGpD,8BAA8B;AAAA,YAC5B,YAAY;AAAA,YAAoB;AAAA,YAAM;AAAA,YAAa;AAAA,YAAS;AAAA,YAAS;AAAA,YACrE,MAAM;AAAA,YAAU;AAAA,YAAO;AAAA,YAAY;AAAA,YAAW;AAAA,YAAe;AAAA,YAAkB;AAAA,UACjF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,OAAO,oBAAoB,IAAI,UAAU,CAAC,GAAG,QAAQ,kBAAkB,WAAW;AAExF,aAAW,OAAO,QAAQ,UAAU;AAClC,QAAI,IAAI,UAAU,WAAW,IAAI,UAAU,SAAS;AAClD,WAAK,IAAI,GAAG,IAAI,IAAI;AAAA,IACtB;AAAA,EACF;AAEA,MAAI,QAAQ,YAAY;AACtB,UAAM,WAAW,QAAQ,WAAW;AAAA,MAClC,YAAY;AAAA,MAAoB;AAAA,MAAM;AAAA,MAAa;AAAA,MAAS;AAAA,MAAM,SAAS;AAAA,MAC3E,cAAc,CAAC;AAAA,MAAG,gBAAgB,CAAC;AAAA,MAAG,kBAAkB,IAAI,UAAU,CAAC;AAAA,IACzE,CAAC;AACD,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACjD,UAAI,QAAQ,UAAa,QAAQ,IAAI;AACnC,aAAK,GAAG,IAAI;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,IAAI,GAAG;AAC3B,UAAM,qBAAqB,gBAAgB,MAAM,aAAa,SAAS,WAAW,aAAa;AAC/F,QAAI,uBAAuB,IAAI,UAAU,CAAC,GAAG,KAAK,CAAC,UAAU,MAAM,QAAQ,MAAM,GAAG;AAClF,WAAK,OAAO;AAAA,IACd;AAAA,EACF;AAKA,MAAI,YAAY,OAAO,aAAa,SAAU,QAAO,OAAO,MAAM,QAAQ;AAG1E,OAAK,QAAQ,oBAAoB,aAAa,IAAI;AAGlD,QAAM,UAAU,MAAM,oBAAoB,kBAAkB;AAC5D,QAAM,uBAAuB,iBAAiB,kBAAkB,SAAS,wBAAwB;AAGjG,MAAI,gBAA0B,CAAC;AAE/B,QAAM,oBAAoB,SAAS,kBAAkB;AACrD,QAAM,mBACH,qBAAqB,yBACtB,YAAY,KAAK,EAAE,SAAS;AAC9B,MAAI,iBAAiB;AACnB,QAAI;AACF,YAAM,aAAa,MAAM;AAAA,QACvB;AAAA,QACA;AAAA,UACE,gBAAgB;AAAA,UAChB,WAAW;AAAA,UACX;AAAA,UACA,cAAc;AAAA,UACd,GAAI,uBAAuB,EAAE,cAAc,eAAe,IAAI,CAAC;AAAA,UAC/D,GAAI,SAAS,gBAAgB,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,QAC3E;AAAA,MACF;AACA,UAAI,YAAY,YAAY;AAC1B,mBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,WAAW,UAAU,GAAG;AAC9D,cAAI,aAAa,KAAK,GAAG,CAAC,KAAK,gBAAgB,GAAG,GAAG;AACnD,iBAAK,GAAG,IAAI;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAEN,oBAAc,KAAK,qFAAqF;AAAA,IAC1G;AAAA,EACF;AACA,sBAAoB,MAAM,IAAI,UAAU,CAAC,GAAG,oBAAoB;AAMhE,QAAM,UAAU,kBAAkB;AAGlC,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,iBAA+E,CAAC;AAEpF,MAAI,gCAAmJ,CAAC;AAExJ,MAAI;AAGJ,MAAI;AAEJ,MAAI,6BAA6B;AACjC,MAAI;AAKF,UAAMC,UAAS,MAAM,eAA8D,qBAAqB;AAAA,MACtG,gBAAgB;AAAA,MAChB,SAAS,WAAW;AAAA,MACpB;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA,WAAW,UAAU,SAAS,OAAO,KAAK;AAAA,MAC1C,WAAW,WAAW;AAAA,MACtB,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACjC,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,MACzC,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA;AAAA,MAEnC,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC/C,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAU/C,GAAI,SAAS,MAAM,SAAS,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAAA,IAChE,CAAC;AAGD,QAAIA,WAAU,2BAA2BA,OAAM,GAAG;AAChD,YAAM,eAAe,gBAAgB,QAAQ,SAAS,KAAK,gBAAgB,WAAW,SAAS,KAAK,gBAAgB,WAAW,SAAS;AACxI,YAAM,mBAAmB,eACrB;AAAA;AAAA,iBAAsB;AAAA,QACpB,gBAAgB,WAAW,SAAS,KAAK,GAAG,gBAAgB,WAAW,MAAM,sBAAsB,gBAAgB,WAAW,SAAS,IAAI,MAAM,EAAE;AAAA,QACnJ,gBAAgB,QAAQ,SAAS,KAAK,GAAG,gBAAgB,QAAQ,MAAM,gBAAgB,gBAAgB,QAAQ,SAAS,IAAI,QAAQ,GAAG;AAAA,QACvI,gBAAgB,WAAW,SAAS,KAAK,GAAG,gBAAgB,WAAW,CAAC,GAAG,OAAO;AAAA,MACpF,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,CAAC,MAC5B;AAIJ,YAAM,aAAaA,QAAO,eAAe;AACzC,YAAM,WAAW,aACb,qCAAgC,IAAI,MAAM,kBAAkB,MAC5D,2BAA2B,IAAI,MAAM,kBAAkB;AAC3D,YAAM,kBAAkB;AAAA,QACtB,aACI,qCAAgC,IAAI,0BACpC,2BAA2B,IAAI;AAAA,QACnC;AAAA,UACE,SAASA,QAAO;AAAA,UAChB;AAAA;AAAA;AAAA;AAAA,UAIA,YAAY,2BAA2BA,SAAQ,SAAS,kBAAkB;AAAA,UAC1E,SAAS,aAAc,YAAuB;AAAA,UAC9C,GAAI,cAAcA,QAAO,iBAAiB,EAAE,gBAAgBA,QAAO,eAAe,IAAI,CAAC;AAAA,UACvF,UAAUA,QAAO,YAAY,CAAC;AAAA,UAC9B;AAAA;AAAA,UAEA,GAAIA,QAAO,gBAAgB,EAAE,eAAeA,QAAO,cAAc,IAAI,CAAC;AAAA,QACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMA,8BAA8B;AAAA,UAC5B,YAAY;AAAA,UAAoB;AAAA,UAAM;AAAA,UAAa;AAAA,UAAS;AAAA,UAAS;AAAA,UACrE,MAAM;AAAA,UAAU;AAAA,UAAO;AAAA,UAAY;AAAA,UAAW;AAAA,UAAe;AAAA,UAAkB;AAAA,QACjF,CAAC;AAAA,MACH;AACA,UAAIA,QAAO,UAAU;AACnB,wBAAgB,WAAWA,QAAO;AAAA,MACpC;AACA,YAAM,oBAAoBA,QAAO,gBAC7B;AAAA;AAAA,sBAA2BA,QAAO,cAAc,OAAO,KACvD;AACJ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,QAAQ;AAAA;AAAA,wEAAwEA,QAAO,UAAU,SAAS;AAAA;AAAA,gBAAqBA,QAAO,SAAS,KAAK,IAAI,CAAC,KAAK,EAAE,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,CAAC;AAAA,QACzP,mBAAmB;AAAA,MACrB;AAAA,IACF;AAOA,UAAM,UAAUA;AAChB,iBAAa,QAAQ;AACrB,mBAAe,QAAQ;AACvB,kBAAc,KAAK,GAAI,QAAQ,YAAY,CAAC,CAAE;AAK9C,wBAAoB,QAAQ;AAI5B,oCAAgC,QAAQ,uBAAuB,CAAC;AAEhE,qBAAiB,QAAQ,gBAAgB,CAAC;AAE1C,gCAA4B,QAAQ;AAEpC,yBAAsB,QAAsE;AAC5F,wBAAoB,MAAM,QAAQ,OAAO;AAEzC,QAAK,QAAiD,WAAW,UAAU;AACzE,mCAA6B;AAAA,IAC/B;AAAA,EACF,SAAS,OAAgB;AACvB,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAEjE,QAAI,iBAAiB,KAAK,EAAG,QAAO,iCAAiC,OAAO,MAAM,GAAG;AACrF,QAAI,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,gBAAgB,GAAG;AAC/D,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA;AAAA,EAA4C,GAAG;AAAA;AAAA;AAAA,QACvD,CAAC;AAAA,QACD,mBAAmB;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,YACE,EAAE,MAAM,WAAW,aAAa,sBAAsB,YAAY,EAAE,QAAQ,OAAO,SAAS,WAAW,KAAK,EAAE;AAAA,YAC9G,EAAE,MAAM,WAAW,aAAa,yBAAyB,YAAY,EAAE,QAAQ,UAAU,SAAS,WAAW,GAAG,EAAE;AAAA,UACpH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,QAAM,eAAe,KAAK,IAAI;AAI9B,OAAK,eAAyE,gCAAgC;AAAA,IAC5G,SAAS;AAAA,IACT,aAAa,gBAAgB,WAAW,SAAS;AAAA,IACjD,cAAc,KAAK;AAAA,MACjB,GAAG,gBAAgB,WAAW,IAAI,CAAC,MAAW,EAAE,YAAY;AAAA,MAC5D,GAAG,gBAAgB,QAAQ,IAAI,CAAC,MAAW,EAAE,YAAY;AAAA,MACzD;AAAA,IACF;AAAA,IACA,eAAe,gBAAgB,WAAW,SAAS;AAAA,IACnD,cAAc;AAAA,EAChB,CAAC,EAAE,MAAM,MAAM,MAAS;AAGxB,QAAM,eAA6B,CAAC;AACpC,QAAM,iBAAmC,CAAC;AAC1C,QAAM,kBAAyD,CAAC;AAEhE,QAAM,eAA8F,CAAC;AAErG,MAAI,qBAAmF,CAAC;AASxF,QAAM,mBAAsC,CAAC;AAE7C,QAAM,oBAAoB,SAAS,MAAM,SAAS;AAClD,QAAM,cAAc,mBAAmB,MAAM,WAAW;AACxD,MAAI,eAAe,CAAC,mBAAmB;AAErC,UAAM,WAAW,MAAM,iBAAiB;AACxC,UAAM,CAAC,eAAe,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,MACxD,YAA6D,uBAAuB,EAAE,OAAO,YAAY,CAAC;AAAA,MAC1G,eAAe;AAAA,IACjB,CAAC;AAED,UAAM,UAAU,oBAAI,IAAoB;AACxC,eAAW,KAAK,eAAgB,SAAQ,IAAI,EAAE,KAAK,EAAE,IAAI;AASzD,UAAM,sBAAsB,iBAAiB,CAAC,GAC3C,OAAO,CAAC,MAAM,EAAE,YAAY,gBAAgB,EAAE,QAAQ,UAAU,EAChE,IAAI,CAAC,OAAO;AAAA,MACX,MAAM,EAAE;AAAA,MACR,SAAS,EAAE;AAAA,MACX,cAAc,EAAE;AAAA,MAChB,SAAS,eAAe,EAAE,MAAM,EAAE;AAAA,IACpC,EAAE;AAeJ,QAAI,SAA4B,CAAC;AACjC,QAAI,mBAAmB,SAAS,GAAG;AACjC,UAAI;AACF,cAAM,kBAAkB,MAAM,YAAmE,6BAA6B;AAAA,UAC5H,SAAS,OAAO,YAAY,OAAO;AAAA,UACnC,UAAU,CAAC,GAAG,QAAQ;AAAA,UACtB,MAAM;AAAA,YACJ;AAAA,cACE,mBAAmB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,EAAE,aAAa,EAAE;AAAA,cAC9E;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AACD,iBAAS,gBAAgB,CAAC,KAAK,CAAC;AAAA,MAClC,QAAQ;AAAA,MAAwE;AAAA,IAClF;AACA,UAAM,aAAa,OAAO,IAAI,CAAC,MAAM;AACnC,YAAM,IAAI,mBAAmB,EAAE,KAAK;AACpC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU,QAAQ,IAAI,EAAE,YAAY,KAAK;AAAA,QACzC,YAAY,EAAE;AAAA,QACd,kBAAkB,EAAE;AAAA,MACtB;AAAA,IACF,CAAC;AAED,QAAI,YAAY;AAChB,eAAW,KAAK,YAAY;AAC1B,UAAI,aAAa,eAAgB;AACjC,UAAI,EAAE,aAAa,+BAAgC;AACnD,UAAI,CAAC,EAAE,WAAW,CAAC,aAAc;AAEjC,YAAM,EAAE,MAAM,cAAc,QAAQ,eAAe,IAAI,kBAAkB,oBAAoB,EAAE,UAAU,OAAO;AAChH,uBAAiB,KAAK;AAAA,QACpB,aAAa;AAAA,QAAc,WAAW,EAAE;AAAA,QAAS,MAAM;AAAA;AAAA;AAAA,QAGvD,YAAY;AAAA,QAAa,YAAY,EAAE;AAAA,QACvC,MAAM;AAAA,UAAE,QAAQ;AAAA,UAAQ,YAAY,EAAE;AAAA,UAAM,kBAAkB,EAAE;AAAA,UAC9D,YAAY,cAAc,EAAE,UAAU,KAAK,EAAE,gBAAgB,OAAO,cAAc;AAAA,QAAG;AAAA,MACzF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,gBAAgB,IAAI,IAAI,iBAAiB,IAAI,OAAK,EAAE,SAAS,CAAC;AACpE,eAAW,KAAK,YAAY;AAC1B,UAAI,eAAe,UAAU,gBAAiB;AAC9C,UAAI,EAAE,YAAY,UAAa,cAAc,IAAI,EAAE,OAAO,EAAG;AAC7D,UAAI,EAAE,aAAa,GAAI;AAIvB,YAAM,SAAS,EAAE,cAAc,iCAC3B,oCACA,IAAI,EAAE,KAAK,YAAY,EAAE,MAAM,KAAK,EAAE,OAAO,CAAC,MAAc,GAAG,IAAI,IAAI,WAAW,GAAG,YAAY,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC;AAE5J,qBAAe,KAAK,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,MAAM,YAAY,EAAE,UAAU,QAAQ,SAAS,EAAE,QAAQ,CAAC;AAAA,IAC9G;AAIA,yBAAqB,WAClB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,YAAY,EACrD,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAmB,MAAM,EAAE,MAAgB,YAAY,EAAE,SAAmB,EAAE;AAAA,EAC5G;AAGA,MAAI,SAAS,MAAM,SAAS,KAAK,cAAc;AAC7C,eAAW,QAAQ,OAAO;AACxB,uBAAiB,KAAK;AAAA,QACpB,aAAa;AAAA,QAAc,WAAW,KAAK;AAAA,QAAI,MAAM,KAAK;AAAA;AAAA,QAE1D,YAAY;AAAA,QACZ,MAAM,EAAE,QAAQ,QAAQ,YAAY,KAAK,IAAI,kBAAkB,UAAU;AAAA,MAC3E,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,aAAa;AAEnB,QAAM,wBAAwB,iBAAiB,SAAS,IACpD;AAAA,IACE;AAAA,IAA8B;AAAA;AAAA,MAE5B,WAAW,iBAAiB,MAAM,GAAG,EAAE,EAAE,IAAI,QAAM;AAAA,QACjD,aAAa,EAAE;AAAA,QAAa,WAAW,EAAE;AAAA,QAAW,MAAM,EAAE;AAAA,QAC5D,GAAI,EAAE,eAAe,SAAY,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,QACjE,GAAI,EAAE,eAAe,SAAY,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,MACnE,EAAE;AAAA,MACF,WAAW,WAAW;AAAA,IACxB;AAAA,EACF,EAAE,MAAM,CAAC,QAAQ;AACf,kBAAc,KAAK,kCAAkC,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAC3G,WAAO;AAAA,EACT,CAAC,IACD,QAAQ,QAAQ,IAAI;AAExB,QAAM,qBAAqB,aACvB,YAAuE,iCAAiC,EAAE,cAAc,WAAW,CAAC,EAAE,MAAM,MAAM,IAAI,IACtJ,QAAQ,QAAQ,IAAI;AAExB,QAAM,uBAAuB,sBAAsB,MAAM,WAAW;AAOpE,QAAM,kBAAkB,uBAAuB,SAC3C,QAAQ,QAAQ,kBAAkB,IAClC,eAAiF,wCAAwC;AAAA,IACvH,SAAS;AAAA,IAAc,SAAS;AAAA,EAClC,CAAC,EAAE,MAAM,MAAM,IAAI;AAEvB,QAAM,CAAC,aAAa,kBAAkB,uBAAuB,gBAAgB,IAAI,MAAM,QAAQ,IAAI;AAAA,IACjG;AAAA,IAAuB;AAAA,IAAoB;AAAA,IAAsB;AAAA,EACnE,CAAC;AAQD,MAAI,gBAAgB;AACpB,OAAK,aAAa,WAAW,KAAK,GAAG;AACnC,UAAM,SAAS,MAAM,eAAiF,wCAAwC;AAAA,MAC5I,SAAS;AAAA,MAAc,SAAS;AAAA,IAClC,CAAC,EAAE,MAAM,MAAM,IAAI;AACnB,QAAI,QAAQ,QAAS,iBAAgB;AAAA,EACvC;AAEA,QAAM,kBAAkB,KAAK,IAAI;AAGjC,MAAI,aAAa;AACf,aAAS,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;AAChD,YAAM,UAAU,iBAAiB,CAAC;AAClC,YAAMA,UAAS,YAAY,QAAQ,CAAC;AACpC,UAAI,CAACA,QAAQ;AAEb,UAAI,QAAQ,KAAK,WAAW,QAAQ;AAClC,YAAIA,QAAO,IAAI;AACb,uBAAa,KAAK;AAAA,YAChB,eAAe,QAAQ;AAAA,YAAW,YAAY,QAAQ,KAAK;AAAA,YAC3D,kBAAkB,QAAQ,KAAK;AAAA,YAAkB,cAAc,QAAQ;AAAA,YACvE,YAAY,QAAQ,KAAK;AAAA,UAC3B,CAAC;AAAA,QACH,WAAWA,QAAO,WAAW,WAAW;AACtC,uBAAa,KAAK;AAAA,YAChB,YAAY,QAAQ,KAAK;AAAA,YAAY,kBAAkB,QAAQ,KAAK;AAAA,YACpE,cAAc,QAAQ;AAAA,UACxB,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,YAAIA,QAAO,IAAI;AACb,0BAAgB,KAAK,EAAE,OAAO,UAAK,QAAQ,IAAI,WAAM,QAAQ,SAAS,IAAI,IAAI,KAAK,CAAC;AACpF,uBAAa,KAAK;AAAA,YAChB,eAAe,QAAQ;AAAA,YAAW,YAAY,QAAQ,KAAK;AAAA,YAC3D,kBAAkB,QAAQ,KAAK;AAAA,YAAkB,cAAc,QAAQ;AAAA,UACzE,CAAC;AAAA,QACH,OAAO;AACL,0BAAgB,KAAK,EAAE,OAAO,UAAK,QAAQ,IAAI,WAAM,QAAQ,SAAS,KAAKA,QAAO,SAAS,QAAQ,IAAI,IAAI,MAAM,CAAC;AAAA,QACpH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,aAAa,SAAS,GAAG;AAC3B,kBAAc,KAAK,GAAG,aAAa,MAAM,4GAAuG;AAAA,EAClJ;AAKA,QAAM,gBAAgB,KAAK,IAAI;AAE/B,QAAM,qBAAoC,kBAAkB,WAAW;AAEvE,MAAI,sBAAsB,SAAS,GAAG;AACpC,UAAM,sBAAsB,EAAE,sBAAsB,KAAK,CAAC;AAAA,EAC5D;AAEA,MAAI,kBAAkB;AACtB,MAAI,eAAe,WAAW,cAAc,QAAQ,SAAS,aAAa,cAAc,QAAQ,SAAS,SAAS,GAAG;AACnH,sBAAkB,qBAAqB,aAAa;AAAA,EACtD;AAGA,MAAI,eAAe,SAAS;AAC1B,QAAI;AACF,YAAM,gBAAgB,MAAM,oBAAoB;AAChD,YAAM,IAAI,cAAc;AACxB,YAAM,eAAe,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,MAAW,CAAC,EAAE,MAAM,EAAE;AACrE,0BAAoB,cAAc,aAAa;AAAA,QAC7C,UAAU;AAAA,QACV,YAAY,EAAE,gBAAgB;AAAA,QAC9B,MAAM,EAAE;AAAA,QACR,SAAS;AAAA,QACT,QAAQ,EAAE;AAAA,QACV,QAAQ,cAAc,UAAU;AAAA,QAChC,gBAAgB,EAAE,UAAU,UAAU;AAAA,QACtC,iBAAiB;AAAA,QACjB,eAAe,EAAE,SAAS;AAAA,QAC1B,qBAAqB,EAAE;AAAA,MACzB,CAAC;AAAA,IACH,QAAQ;AAAA,IAA6B;AAAA,EACvC;AAMA,QAAM,sBAAsB,MAAM,+BAA+B;AACjE,QAAM,mBAAmB,wBAAwB,YAAY,mBAAmB;AAKhF,MAAI,oBAAoB,gBAAgB,mBAAmB,WAAW,GAAG;AACvE,QAAI;AACF,YAAM,kBAAkB,MAAM,YAA6D,uBAAuB,EAAE,OAAO,KAAK,CAAC;AACjI,4BAAsB,mBAAmB,CAAC,GACvC,OAAO,CAAC,MAAW,EAAE,WAAW,EAAE,YAAY,gBAAgB,EAAE,QAAQ,UAAU,EAClF,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,OAAY,EAAE,SAAS,EAAE,SAAmB,MAAM,EAAE,MAAgB,YAAY,EAAE,kBAAkB,UAAU,EAAE;AAAA,IAC1H,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI,cAAuE;AAC3E,MAAI,cAA6B;AAEjC,MAAI,gBAAgD;AAGpD,MAAI,wBAAsD;AAqB1D,MAAI,4BAA4B;AAC9B,kBAAc;AACd,UAAM,sBAAsB,EAAE,eAAe,WAAW,CAAC;AACzD,6BAAyB,MAAM,aAAa;AAAA,MAC1C,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,SAAS;AAAA,IACX,CAAC;AAAA,EACH,WAAW,oBAAoB,cAAc;AAC3C,QAAI;AAMF,YAAM,oBAAoB,MAAM,0BAA0B,MAAM,aAAa,kBAAkB;AAC/F,YAAM,eAAe,MAAM,eAA8D,qBAAqB;AAAA,QAC5G,SAAS;AAAA,QACT,QAAQ,UAAU,SAAS,OAAO,KAAK;AAAA,QACvC,WAAW,WAAW;AAAA,QACtB,GAAI,kBAAkB,SAAS,IAAI,EAAE,WAAW,kBAAkB,IAAI,CAAC;AAAA,MACzE,CAAC;AACD,YAAM,gBAAgB,uBAAuB,YAAY;AACzD,UAAI,eAAe;AAEjB,sBAAc,6CAAwC,aAAa;AAEnE,wBAAgB,kBAA2C,cAAc,SAAS,KAAK;AACvF,sBAAc;AAAA,MAChB,OAAO;AACL,sBAAc,kBAA0B,cAAc,QAAQ,MAAM,qBAAqB,aAAa;AACtG,gCAAwB,kBAAyC,cAAc,uBAAuB,KAAK;AAC3G,YAAI,gBAAgB,aAAa;AAC/B,gBAAM,sBAAsB,EAAE,eAAe,WAAW,CAAC;AACzD,mCAAyB,MAAM,aAAa;AAAA,YAC1C,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,eAAe;AAAA,YACf,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,SAAS,GAAY;AAEnB,oBAAc,aAAa,QAAQ,EAAE,UAAU;AAC/C,oBAAc;AACd,YAAM,oBAAoB,EAAE,SAAS,cAAc,OAAO,GAAG,WAAW,SAAS,OAAO,CAAC;AAAA,IAC3F;AAAA,EACF;AAGA,QAAM,QAAkB;AAAA,IACtB,eAAe,gBAAgB,IAAI;AAAA,IACnC,KAAK,IAAI,iBAAiB,kBAAkB,WAAW,WAAW;AAAA,IAClE,kBAAkB,MAAM,aAAa,KAAK,MAAM,WAAW;AAAA,EAC7D;AAEA,MAAI,gBAAgB;AAClB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mBAAmB;AAC9B,QAAI,eAAe,WAAW;AAC5B,YAAM,KAAK,gCAAgC,kBAAkB,iCAA4B;AAAA,IAC3F,WAAW,eAAe,YAAY;AACpC,YAAM,KAAK,oBAAoB,kBAAkB,OAAO,eAAe,aAAa,gBAAgB;AACpG,UAAI,eAAe,QAAQ,SAAS,GAAG;AACrC,cAAM,KAAK,WAAW,eAAe,QAAQ,KAAK,IAAI,CAAC,GAAG;AAAA,MAC5D;AACA,YAAM,KAAK,wDAAwD;AAAA,IACrE,WAAW,eAAe,QAAQ;AAChC,YAAM,KAAK,yBAAyB,kBAAkB,OAAO,eAAe,aAAa,gBAAgB;AAAA,IAC3G,OAAO;AACL,YAAM,YAAY,eAAe,WAAW,CAAC,GAAG,cAAc;AAC9D,YAAM,KAAK,yBAAyB,SAAS,OAAO,eAAe,aAAa,6CAAwC;AACxH,UAAI,eAAe,QAAQ,SAAS,GAAG;AACrC,cAAM,KAAK,WAAW,eAAe,QAAQ,KAAK,IAAI,CAAC,GAAG;AAAA,MAC5D;AACA,UAAI,eAAe,iBAAiB;AAClC,cAAM,KAAK,eAAe,eAAe,eAAe,IAAI;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,QAAQ,IAAI,wBAAwB;AACnD,QAAM,YACJ,uBAAuB,WACnB,GAAG,OAAO,QAAQ,OAAO,EAAE,CAAC,MAAM,MAAM,aAAa,WAAW,UAAU,KAC1E;AACN,MAAI,WAAW;AACb,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,uBAAuB,SAAS,EAAE;AAAA,EAC/C;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mBAAmB,aAAa,MAAM,GAAG;AACpD,eAAW,QAAQ,cAAc;AAC/B,YAAM,SAAU,KAAa,aAAa,mBAAe,KAAa,UAAU,KAAK;AACrF,YAAM,KAAK,UAAU,KAAK,YAAY,MAAM,KAAK,aAAa,KAAK,KAAK,UAAU,KAAK,KAAK,gBAAgB,IAAI,MAAM,EAAE;AAAA,IAC1H;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oBAAoB;AAC/B,eAAW,KAAK,gBAAiB,OAAM,KAAK,KAAK,EAAE,KAAK,EAAE;AAAA,EAC5D;AAEA,MAAI,gBAAgB,aAAa;AAC/B,UAAM,mBAAmB,eAAe,UAAa,wBAAwB;AAC7E,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,gBAAgB,YAAY,EAAE;AACzC,QAAI,kBAAkB;AACpB,YAAM,KAAK,KAAK,IAAI,kCAAkC;AAAA,IACxD,OAAO;AACL,YAAM,KAAK,KAAK,IAAI,mCAAmC;AAAA,IACzD;AACA,QAAI,MAAM,WAAW,kBAAkB,GAAG;AACxC,YAAM,KAAK,YAAY,kBAAkB,0EAAqE;AAAA,IAChH;AAGA,QAAI,uBAAuB;AACzB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,2BAA2B;AACtC,YAAM,KAAK,sBAAsB,MAAM;AACvC,iBAAW,KAAK,sBAAsB,iBAAiB;AACrD,cAAM,KAAK,OAAO,EAAE,YAAY,MAAM,EAAE,cAAc,KAAK,EAAE,WAAW,EAAE;AAAA,MAC5E;AAAA,IACF;AAAA,EACF,WAAW,gBAAgB,YAAY;AACrC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,wBAAwB,YAAY,EAAE;AACjD,UAAM,KAAK,KAAK,IAAI,yGAAyG;AAAA,EAC/H,WAAW,aAAa;AACtB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,kBAAkB;AAC7B,QAAI,eAAe;AAGjB,YAAM,cAAc,uBAAuB,WAAW,cAAc,eAAe,EAAE,cAAc,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE;AACnH,YAAM,KAAK,GAAG,YAAY,MAAM,IAAI,CAAC;AACrC,YAAM,KAAK,oEAA+D,YAAY,4BAA4B;AAAA,IACpH,OAAO;AACL,YAAM,KAAK,UAAU,WAAW,sEAAiE,YAAY,4BAA4B;AAAA,IAC3I;AAAA,EACF;AAGA,MAAI,oBAAoB,mBAAmB,SAAS,GAAG;AACrD,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,uBAAuB;AAClC,UAAM,KAAK,gCAAgC,mBAAmB,MAAM,YAAY,mBAAmB,WAAW,IAAI,UAAU,SAAS,SAAS;AAC9I,eAAW,KAAK,oBAAoB;AAClC,YAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,GAAG;AAAA,IAC9D;AACA,UAAM,KAAK,oCAAoC;AAAA,EACjD;AAEA,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,+DAA+D;AAC1E,aAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,YAAM,IAAI,eAAe,CAAC;AAC1B,YAAMC,WAAU,EAAE,UAAU,WAAM,EAAE,OAAO,KAAK;AAChD,YAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,SAAS,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,IAAIA,QAAO,EAAE;AAAA,IAC7F;AAAA,EACF;AAGA,MAAI,WAAW,SAAS;AACtB,UAAM,gBAAgB,gBAAgB,WAAW,SAAS;AAC1D,UAAM,aAAa,gBAAgB,QAAQ,SAAS;AACpD,UAAM,SAAS,gBAAgB,WAAW,SAAS;AACnD,QAAI,iBAAiB,cAAc,QAAQ;AACzC,YAAM,KAAK,EAAE;AACb,YAAM,QAAkB,CAAC;AACzB,UAAI,cAAe,OAAM,KAAK,GAAG,gBAAgB,WAAW,MAAM,sBAAsB,gBAAgB,WAAW,SAAS,IAAI,MAAM,EAAE,EAAE;AAC1I,UAAI,WAAY,OAAM,KAAK,GAAG,gBAAgB,QAAQ,MAAM,gBAAgB,gBAAgB,QAAQ,SAAS,IAAI,QAAQ,GAAG,EAAE;AAC9H,UAAI,OAAQ,OAAM,KAAK,GAAG,gBAAgB,WAAW,CAAC,GAAG,OAAO,kBAAkB;AAClF,YAAM,KAAK,eAAe,MAAM,KAAK,IAAI,CAAC,iCAAiC;AAAA,IAC7E;AAAA,EACF;AAGA,QAAM,uBAAuB,oBAAoB,IAAI,UAAU,CAAC,CAAC;AACjE,MAAI,sBAAsB;AACxB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oBAAoB;AAG/B,UAAM,oBAAoB,IAAI,UAAU,CAAC,GAAG,OAAO,CAAC,MAAoC,EAAE,eAAe,EAAE;AAC3G,8BAA0B,MAAM,aAAa;AAAA,MAC3C,YAAY;AAAA,MACZ,oBAAoB;AAAA,IACtB,CAAC;AAAA,EACH;AAGA,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,6BAA6B;AACxC,eAAW,QAAQ,gBAAgB;AACjC,YAAM,KAAK,OAAO,KAAK,KAAK,OAAO,KAAK,IAAI,EAAE;AAAA,IAChD;AACA,UAAM,KAAK,kGAA6F,YAAY,uBAAuB;AAAA,EAC7I;AAGA,MAAI,8BAA8B,SAAS,GAAG;AAC5C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mCAAmC;AAC9C,eAAW,MAAM,+BAA+B;AAC9C,YAAM,KAAK,OAAO,GAAG,YAAY,aAAQ,GAAG,aAAa,KAAK,GAAG,UAAU,kBAAkB,GAAG,UAAU,GAAG;AAAA,IAC/G;AACA,UAAM,KAAK,mDAAmD,YAAY,mCAAmC;AAAA,EAC/G;AAGA,MAAI,2BAA2B;AAC7B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW,0BAA0B,IAAI,oDAA+C;AAAA,EACrG;AAGA,MAAI,eAAe,SAAS,GAAG;AAC7B,6BAAyB,MAAM,aAAa;AAAA,MAC1C,YAAY;AAAA,MACZ,YAAY,eAAe;AAAA,MAC3B,aAAa,eAAe,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,IAChD,CAAC;AAAA,EACH;AACA,MAAI,8BAA8B,SAAS,GAAG;AAC5C,oCAAgC,MAAM,aAAa;AAAA,MACjD,YAAY;AAAA,MACZ,kBAAkB,8BAA8B;AAAA,MAChD,gBAAgB,8BAA8B,IAAI,CAAC,OAAO,GAAG,YAAY;AAAA,MACzE,gBAAgB,KAAK;AAAA,QACnB,8BAA8B,OAAO,CAAC,KAAK,OAAO,MAAM,GAAG,YAAY,CAAC,IACtE,8BAA8B;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,cACJ,wBACA,eAAe,SACf,eAAe;AACjB,QAAM,kBAAkB,aAAa,KAAK,CAAC,MAAM,EAAE,qBAAqB,UAAU;AAClF,MAAI,eAAe,CAAC,iBAAiB;AACnC,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJ,2BAA2B,uBAAuB,iBAAiB,MAAM,sHAAsH,YAAY;AAAA,IAC7M;AACA,UAAM,sBAAsB,EAAE,8BAA8B,WAAW,CAAC;AAAA,EAC1E;AAGA,MAAI,oBAAoB;AACtB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,4BAA4B,kBAAkB,EAAE;AAAA,EAC7D;AAGA,MAAI,sBAAsB,SAAS,GAAG;AACpC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,iFAA4E;AACvF,eAAW,KAAK,uBAAuB;AACrC,YAAM,KAAK,KAAK,EAAE,IAAI,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,sCAAiC,EAAE,YAAY,UAAU;AAAA,IAChH;AACA,UAAM,KAAK,gEAAgE;AAAA,EAC7E;AAGA,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,wBAAwB;AACnC,eAAW,KAAK,eAAe;AAC7B,YAAM,KAAK,KAAK,CAAC,EAAE;AAAA,IACrB;AAAA,EACF;AAGA,MAAI,iBAAiB;AACnB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,eAAe;AAAA,EAC5B;AAKA,QAAM,iBACH,eAAe,WAAW,QAAQ,cAAc,QAAQ,WAAW,SACpE,eAAe,SAAS;AAC1B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,eAAe;AAC1B,QAAM,MAAM,gBAAgB;AAC5B,MAAI,gBAAgB,aAAa;AAC/B,UAAM,KAAK,0DAA0D,GAAG,sCAAiC;AACzG,QAAI,gBAAgB;AAClB,YAAM,KAAK,4DAA4D,GAAG,gCAA2B;AAAA,IACvG;AAAA,EACF,WAAW,gBAAgB,YAAY;AACrC,UAAM,KAAK,0DAA0D,GAAG,8DAAyD;AACjI,QAAI,gBAAgB;AAClB,YAAM,KAAK,4DAA4D,GAAG,iDAA4C;AAAA,IACxH;AAAA,EACF,OAAO;AACL,QAAI,gBAAgB,WAAW,GAAG;AAChC,YAAM,KAAK,0DAA0D,GAAG,8CAAyC;AAAA,IACnH;AACA,UAAM,KAAK,GAAG,gBAAgB,WAAW,IAAI,MAAM,GAAG,qDAAqD,GAAG,oDAA+C;AAC7J,QAAI,gBAAgB;AAClB,YAAM,KAAK,GAAG,gBAAgB,WAAW,IAAI,MAAM,GAAG,2DAA2D,GAAG,gCAA2B;AAAA,IACjJ;AAAA,EACF;AAGA,MAAI;AACF,UAAM,YAAY,MAAM,YAAkE,0BAA0B;AACpH,QAAI,aAAa,UAAU,QAAQ,UAAU,KAAK,SAAS,GAAG;AAC5D,YAAM,UAAU,UAAU,KAAK,MAAM,GAAG,CAAC;AACzC,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,2BAA2B,UAAU,KAAK,GAAG;AACxD,iBAAW,OAAO,SAAS;AACzB,cAAM,KAAK,MAAM,IAAI,KAAK,MAAM,IAAI,QAAQ,EAAE;AAAA,MAChD;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,QAAM,OAAqB,CAAC;AAC5B,MAAI,gBAAgB,aAAa;AAC/B,SAAK,KAAK,EAAE,MAAM,aAAa,aAAa,wBAAwB,YAAY,EAAE,QAAQ,WAAW,SAAS,aAAa,EAAE,CAAC;AAAA,EAChI,WAAW,gBAAgB,YAAY;AACrC,SAAK,KAAK,EAAE,MAAM,aAAa,aAAa,wBAAwB,YAAY,EAAE,QAAQ,WAAW,SAAS,aAAa,EAAE,CAAC;AAAA,EAChI,OAAO;AACL,QAAI,gBAAgB,WAAW,GAAG;AAChC,WAAK,KAAK,EAAE,MAAM,aAAa,aAAa,kBAAkB,YAAY,EAAE,QAAQ,WAAW,SAAS,aAAa,EAAE,CAAC;AAAA,IAC1H;AACA,SAAK,KAAK,EAAE,MAAM,WAAW,aAAa,qBAAqB,YAAY,EAAE,QAAQ,UAAU,SAAS,aAAa,EAAE,CAAC;AAAA,EAC1H;AAIA,QAAM,gBAAgB,qBAAqB,aAAa;AACxD,QAAM,UAAU,gBAAgB,cAC5B,yBAAyB,YAAY,KAAK,IAAI,UAAU,kBAAkB,KAAK,aAAa,KAC5F,gBAAgB,aACd,YAAY,YAAY,KAAK,IAAI,QAAQ,kBAAkB,2CAA2C,aAAa,KACnH,YAAY,YAAY,KAAK,IAAI,iBAAiB,kBAAkB,KAAK,aAAa;AAE5F,QAAM,kBAAkB,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,OAAY;AAAA,IACzD,KAAK,EAAE;AAAA,IAAK,MAAM,EAAE;AAAA,IAAM,GAAI,EAAE,YAAY,EAAE,UAAU,KAAK;AAAA,EAC/D,EAAE;AAIF,QAAM,6BAA6B;AAAA,IACjC,iBAAiB,IAAI,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,aAAa,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,IACtF,YAAY,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,MACxC,KAAK,EAAE;AAAA,MACP,UAAU,EAAE,aAAa;AAAA,MACzB,MAAM,EAAE;AAAA,MACR,GAAI,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/C,EAAE;AAAA,IACF,GAAI,IAAI,qBAAqB,EAAE,oBAAoB,IAAI,mBAAmB,IAAI,CAAC;AAAA,EACjF;AAEA,QAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,QAAM,SAAS;AAAA,IACb,YAAY,iBAAiB;AAAA,IAC7B,UAAU,eAAe;AAAA,IACzB,YAAY,kBAAkB;AAAA,IAC9B,WAAW,gBAAgB;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,GAAG;AAAA,QACD;AAAA,QACA;AAAA,UACE,SAAS;AAAA,UACT,YAAY;AAAA,UACZ;AAAA,UACA,QAAQ;AAAA;AAAA,UAER,GAAI,gBAAgB,EAAE,kBAAkB,cAAc,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAM3D,GAAI,wBAAwB,EAAE,sBAAsB,IAAI,CAAC;AAAA;AAAA;AAAA,UAGzD,gBAAgB,eAAe,UAC3B,EAAE,GAAG,cAAc,SAAS,QAAQ,cAAc,UAAU,YAAY,IACxE;AAAA,UACJ,GAAI,kBAAkB,EAAE,YAAY,eAAe;AAAA,UACnD,GAAI,aAAa,EAAE,UAAU;AAAA,UAC7B,GAAI,cAAc,SAAS,KAAK,EAAE,UAAU,cAAc;AAAA,UAC1D,GAAI,sBAAsB,OAAO,KAAK,kBAAkB,QAAQ,EAAE,SAAS,KAAK,kBAAkB,SAAS,SAAS,MAAM;AAAA,YACxH,eAAe;AAAA,cACb,UAAU,kBAAkB;AAAA,cAC5B,UAAU,kBAAkB;AAAA,YAC9B;AAAA,UACF;AAAA,UACA;AAAA;AAAA,UAEA,cAAc;AAAA;AAAA,UAEd,qBAAqB;AAAA;AAAA,UAErB,GAAI,6BAA6B,EAAE,iBAAiB,0BAA0B;AAAA;AAAA,UAE9E;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA;AAAA,MAEA,UAAU;AAAA,MACV,OAAO,EAAE,OAAO;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACb;AAQA,eAAsB,mBACpB,QACA,EAAE,SAAS,YAAY,QAAQ,GAC/B;AACI,qBAAmB;AAEnB,QAAM,mBAAmB,KAAK,IAAI;AAElC,QAAM,UAAU,kBAAkB;AAClC,QAAM,YAAY,UAAU,SAAS,OAAO,KAAK;AACjD,QAAM,QAAQ,MAAM,oBAAoB;AAExC,QAAM,8BAA8B,MAAM,+BAA+B;AACzE,QAAM,oBAAoB,wBAAwB,YAAY,2BAA2B;AAGzF,QAAM,sBAAsB,QACzB,IAAI,CAAC,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAClC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU;AAE9B,MAAI,oBAAoB,oBAAI,IAAuC;AACnE,MAAI,oBAAoB,SAAS,GAAG;AAClC,UAAM,OAAO,mBAAmB;AAAA,MAC9B,OAAO;AAAA,MACP,MAAM,eAAe,oBAAoB,MAAM,IAAI,QAAQ,MAAM;AAAA,MACjE,QAAQ;AAAA,IACV,CAAC;AACD,UAAM,kBAAkB,MAAM,QAAQ;AAAA,MACpC,oBAAoB;AAAA,QAAI,CAAC,MACvB,kBAAkB,EAAE,MAAM,EAAE,MAAM,aAAa,EAAE,YAAY,CAAC,EAAE,MAAM,MAAM,IAAI;AAAA,MAClF;AAAA,IACF;AACA,aAAS,IAAI,GAAG,IAAI,oBAAoB,QAAQ,KAAK;AACnD,wBAAkB,IAAI,oBAAoB,CAAC,EAAE,OAAO,gBAAgB,CAAC,CAAC;AAAA,IACxE;AAAA,EACF;AAwDA,QAAM,UAA8B,CAAC;AAGrC,QAAM,oBAAoB,mCAAmC;AAQ7D,QAAM,uBAAuC,CAAC;AAE9C,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,mBAAmB,QAAQ,MAAM;AAAA,IACvC,QAAQ;AAAA,EACV,CAAC;AAGD,QAAM,iBAAiB,MAAM,eAAe;AAC5C,QAAM,WAAW,MAAM,iBAAiB;AACxC,QAAM,YAAY,oBAAI,IAA2B;AACjD,aAAW,KAAK,eAAgB,WAAU,IAAI,EAAE,MAAM,CAAC;AACvD,QAAM,eAAe,oBAAI,IAAoB;AAC7C,aAAW,KAAK,eAAgB,cAAa,IAAI,EAAE,KAAK,EAAE,IAAI;AAoC9D,iBAAe,kBAAkB,OAAuC;AACtE,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,cAAc,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,GAAmB;AACxF,QAAI,oBAAyC,CAAC;AAC9C,QAAI,YAAY,SAAS,GAAG;AAC1B,UAAI;AACF,4BAAoB,MAAM,YAAmE,6BAA6B;AAAA,UACxH,SAAS,OAAO,YAAY,YAAY;AAAA,UACxC,UAAU,CAAC,GAAG,QAAQ;AAAA,UACtB,MAAM;AAAA,QACR,CAAC;AAAA,MACH,QAAQ;AAIN,4BAAoB,YAAY,IAAI,MAAM,CAAC,CAAC;AAAA,MAC9C;AAAA,IACF;AACA,QAAI,cAAc;AAClB,eAAW,WAAW,OAAO;AAC3B,YAAM,SAAS,QAAQ,QAAQ,OAAQ,kBAAkB,aAAa,KAAK,CAAC,IAAK,CAAC;AAClF,UAAI;AACF,cAAM,QAAQ,OAAO,MAAM;AAAA,MAC7B,SAAS,OAAgB;AACvB,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,gBAAQ,KAAK,uBAAuB;AAAA,UAClC,UAAU,QAAQ;AAAA,UAAU,MAAM,QAAQ,MAAM;AAAA,UAAM,YAAY,QAAQ;AAAA,UAC1E,cAAc,QAAQ;AAAA,UAAc,YAAY,QAAQ;AAAA,UAAY,gBAAgB,QAAQ;AAAA,UAC5F,OAAO;AAAA,QACT,CAAC,CAAC;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,gBAAiC,CAAC;AACtC,MAAI,aAAa;AAEjB,WAAS,WAAW,GAAG,WAAW,QAAQ,QAAQ,YAAY;AAC5D,UAAM,QAAQ,QAAQ,QAAQ;AAE9B,QAAI,WAAW,KAAK,WAAW,MAAM,GAAG;AACtC,YAAM,OAAO,mBAAmB;AAAA,QAC9B,OAAO;AAAA,QACP,MAAM,YAAY,QAAQ,IAAI,QAAQ,MAAM;AAAA,QAC5C,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAGA,QAAI,eAAmC,MAAM;AAC7C,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI,cAAc;AAChB,qBAAe;AAAA,IACjB,OAAO;AACL,YAAM,WAAW,kBAAkB,IAAI,QAAQ;AAE/C,UAAI,UAAU;AACZ,oCAA4B,UAAU,MAAM,aAAa;AAAA,UACvD,4BAA4B;AAAA,UAC5B,YAAY,SAAS,SAAS;AAAA,QAChC,CAAC;AAAA,MACH;AACA,UAAI,CAAC,YAAY,SAAS,SAAS,OAAO;AACxC,6BAAqB,KAAK;AAAA,UACxB,OAAO;AAAA,UACP,MAAM,MAAM;AAAA,UACZ,qBAAqB,UAAU;AAAA,UAC/B,YAAY,UAAU;AAAA,UACtB,cAAc,UAAU,aAAa,MAAM,GAAG,CAAC;AAAA,QACjD,CAAC;AACD;AAAA,MACF;AACA,qBAAe,SAAS;AACxB,qBAAe,SAAS;AACxB,mBAAa,SAAS;AACtB,uBAAiB,SAAS;AAAA,IAC5B;AAEA,UAAM,UAAU,MAAM,WAAW,YAAY;AAC7C,UAAM,MAAM,UAAU,IAAI,YAAY;AAEtC,QAAI,CAAC,KAAK;AACR,cAAQ,KAAK,uBAAuB;AAAA,QAClC;AAAA,QAAU,MAAM,MAAM;AAAA,QAAM,YAAY;AAAA,QAAc;AAAA,QAAc;AAAA,QAAY;AAAA,QAChF,OAAO,eAAe,YAAY;AAAA,MACpC,CAAC,CAAC;AACF;AAAA,IACF;AAGA,QAAI,MAAM,WAAW,iBAAiB,oBAAoB,iBAAiB,aAAa;AACtF,cAAQ,KAAK,uBAAuB;AAAA,QAClC;AAAA,QAAU,MAAM,MAAM;AAAA,QAAM,YAAY;AAAA,QAAc;AAAA,QAAc;AAAA,QAAY;AAAA;AAAA,QAEhF,OAAO,mEAAmE,YAAY;AAAA,MACxF,CAAC,CAAC;AACF;AAAA,IACF;AAEA,UAAM,OAAO,oBAAoB,IAAI,UAAU,CAAC,GAAG,QAAQ,kBAAkB,MAAM,WAAW;AAE9F,eAAW,OAAO,QAAQ,UAAU;AAClC,UAAI,IAAI,UAAU,WAAW,IAAI,UAAU,QAAS,MAAK,IAAI,GAAG,IAAI,IAAI;AAAA,IAC1E;AAEA,QAAI,QAAQ,YAAY;AACtB,YAAM,WAAW,QAAQ,WAAW;AAAA,QAClC,YAAY;AAAA,QAAc,MAAM,MAAM;AAAA,QAAM,aAAa,MAAM;AAAA,QAC/D;AAAA,QAAM,SAAS;AAAA,QAAI,cAAc,CAAC;AAAA,QAAG,gBAAgB,CAAC;AAAA,QAAG,kBAAkB,IAAI,UAAU,CAAC;AAAA,MAC5F,CAAC;AACD,iBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACjD,YAAI,QAAQ,UAAa,QAAQ,GAAI,MAAK,GAAG,IAAI;AAAA,MACnD;AAAA,IACF;AAEA,QAAI,aAAa,KAAK,IAAI,GAAG;AAC3B,YAAM,qBAAqB,gBAAgB,MAAM,MAAM,MAAM,WAAW;AACxE,UAAI,uBAAuB,IAAI,UAAU,CAAC,GAAG,KAAK,CAAC,UAAU,MAAM,QAAQ,MAAM,GAAG;AAClF,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,QAAQ,gBAAgB,KAAK,CAAC,KAAK,eAAe,CAAC,KAAK,WAAW;AAC3E,WAAK,QAAQ,oBAAoB,aAAa,IAAI,MAAM;AAAA,IAC1D;AAEA,QAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,UAAU;AAChD,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,IAAI,GAAG;AAC/C,YAAI,MAAM,UAAa,MAAM,QAAQ,MAAM,GAAI,MAAK,CAAC,IAAI;AAAA,MAC3D;AAAA,IACF;AAIA,UAAM,aAAa,iBAAiB,mBAAmB,MAAM,iBAAiB;AAE9E,UAAM,kBAAkB,KAAK,kBAAkB;AAC/C,UAAM,wBACH,mBAAmB,eAAe,MAAM,aAAa,KAAK;AAC7D,QAAI;AACJ,QAAI,sBAAsB;AACxB,UAAI;AACF,cAAM,aAAa,MAAM;AAAA,UACvB;AAAA,UACA;AAAA,YACE,gBAAgB;AAAA,YAChB,WAAW,MAAM;AAAA,YACjB,aAAa,MAAM;AAAA,YACnB,cAAc;AAAA,YACd,GAAI,aAAa,EAAE,cAAc,eAAe,IAAI,CAAC;AAAA,YACrD,GAAI,KAAK,gBAAgB,EAAE,eAAe,IAAI,cAAc,IAAI,CAAC;AAAA,UACnE;AAAA,QACF;AACA,YAAI,YAAY,YAAY;AAC1B,qBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,WAAW,UAAU,GAAG;AAC9D,gBAAI,aAAa,KAAK,GAAG,CAAC,KAAK,gBAAgB,GAAG,GAAG;AACnD,mBAAK,GAAG,IAAI;AAAA,YACd;AAAA,UACF;AAAA,QACF;AAAA,MACF,QAAQ;AACN,gCAAwB;AAAA,MAC1B;AAAA,IACF;AACA,wBAAoB,MAAM,IAAI,UAAU,CAAC,GAAG,UAAU;AAKtD,UAAM,mBAAmB,2BAA2B,mBAAmB;AAAA,MACrE;AAAA,MAAS;AAAA,MAAU,MAAM,MAAM;AAAA,MAAM,YAAY;AAAA,MACjD,eAAe,MAAM;AAAA,MAAS;AAAA,MAAc;AAAA,MAAY;AAAA,IAC1D,CAAC;AACD,QAAI,kBAAkB;AAAE,cAAQ,KAAK,gBAAgB;AAAG;AAAA,IAAU;AAElE,QAAI;AACF,YAAM,YAAY,MAAM,eAA8D,qBAAqB;AAAA,QACzG,gBAAgB;AAAA,QAChB,SAAS,MAAM,WAAW;AAAA,QAC1B,MAAM,MAAM;AAAA;AAAA,QAEZ;AAAA,QACA;AAAA,QACA,WAAW,WAAW;AAAA,QACtB,cAAc,MAAM,gBAAgB;AAAA;AAAA,QAEpC,sBAAsB;AAAA,QACtB,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,QACxD,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,QACpE,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA;AAAA,QAEnC,GAAI,MAAM,mBAAmB,EAAE,kBAAkB,MAAM,iBAAiB,IAAI,CAAC;AAAA,QAC7E,GAAI,MAAM,mBAAmB,EAAE,kBAAkB,MAAM,iBAAiB,IAAI,CAAC;AAAA,MAC/E,CAAC;AAqBD,YAAM,oBAAoB,yBAAyB,WAAW,OAAO;AAIrE,YAAM,sBAAsB,2BAA2B,WAAW,SAAS,YAAY;AACvF,YAAMD,UAAS;AAEf,YAAM,uBAAuB,+BAA+B,mBAAmB;AAAA,QAC7E,cAAc,QAAQ,WAAW,qBAAqB,CAAC,kBAAkB,UAAU;AAAA,QACnF;AAAA,QAAqB;AAAA,QAAU,MAAM,MAAM;AAAA,QAAM,eAAe,MAAM;AAAA,QACtE;AAAA,QAAc;AAAA,QAAY;AAAA,MAC5B,CAAC;AACD,UAAI,sBAAsB;AAAE,gBAAQ,KAAK,oBAAoB;AAAG;AAAA,MAAU;AAE1E,YAAM,aAAaA,QAAO;AAC1B,YAAM,eAAeA,QAAO;AAC5B,YAAM,qBAAqB;AAAA,QACzB,GAAI,wBAAwB,CAAC,qBAAqB,IAAI,CAAC;AAAA,QACvD,GAAIA,QAAO,YAAY,CAAC;AAAA,MAC1B;AAKA,UAAI,CAAC,QAAS,qBAAoB,MAAM,MAAMA,QAAO,OAAO;AAK5D,YAAM,kCAAkCA,QAAO,WAAW;AAC1D,UAAI,cAAuE,kCAAkC,cAAc;AAC3H,UAAI;AAEJ,UAAI;AAGJ,UAAI;AACJ,UAAI,iCAAiC;AACnC,cAAM,sBAAsB,EAAE,eAAe,WAAW,CAAC;AACzD,iCAAyB,MAAM,aAAa;AAAA,UAC1C,UAAU;AAAA,UACV,YAAY,gBAAgB;AAAA,UAC5B,eAAe;AAAA,UACf,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAcA,UAAI,qBAAsF,CAAC;AAC3F,UAAI,MAA2B;AAC/B,YAAM,cAAc,mBAAmB,MAAM,MAAM,MAAM,WAAW;AACpE,UAAI,aAAa;AACf,YAAI;AACF,gBAAM,gBAAgB,MAAM,YAA6D,uBAAuB,EAAE,OAAO,YAAY,CAAC;AACtI,gCAAsB,iBAAiB,CAAC,GACrC,OAAO,CAAC,MAAM,EAAE,YAAY,YAAY,EACxC,IAAI,CAAC,OAAO;AAAA,YACX,MAAM,EAAE;AAAA,YACR,SAAS,EAAE;AAAA,YACX,cAAc,EAAE;AAAA,UAClB,EAAE;AACJ,cAAI,mBAAmB,SAAS,GAAG;AACjC,kBAAM;AAAA,cACJ,mBAAmB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,EAAE,aAAa,EAAE;AAAA,cAC9E,MAAM;AAAA,cACN,MAAM;AAAA,cACN;AAAA,YACF;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAA2E;AAAA,MACrF;AAmBA,YAAM,sBAAsB,MAAM,iBAAiB,GAAG,IAAI;AAC1D,UACE,cAAc,SAAS,MACtB,cAAc,UAAU,gCACvB,aAAa,sBAAsB,6BACrC;AACA,cAAM,kBAAkB,aAAa;AACrC,wBAAgB,CAAC;AACjB,qBAAa;AAAA,MACf;AAMA,oBAAc,KAAK;AAAA,QACjB;AAAA,QAAU;AAAA,QAAO;AAAA,QAAc;AAAA,QAAc;AAAA,QAAY;AAAA,QACzD;AAAA,QACA,QAAQ,OAAO,WAA8B;AAC3C,cAAI,gBAAgB;AAEpB,cAAI,mBAAmB;AAEvB,cAAI,oBAAoB;AAExB,cAAI,mBAAmB,SAAS,GAAG;AACjC,gBAAI;AAIF,oBAAM,aAAa,OAAO,IAAI,CAAC,MAAM;AACnC,sBAAM,IAAI,mBAAmB,EAAE,KAAK;AACpC,uBAAO,EAAE,GAAG,GAAG,UAAU,aAAa,IAAI,EAAE,YAAY,KAAK,WAAW,YAAY,EAAE,MAAM;AAAA,cAC9F,CAAC;AAGD,kCAAoB,WAAW,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAGxD,oBAAM,iBAA0H,CAAC;AACjI,yBAAW,KAAK,YAAY;AAC1B,oBAAI,eAAe,UAAU,eAAgB;AAC7C,oBAAI,EAAE,aAAa,+BAAgC;AACnD,oBAAI,CAAC,EAAE,QAAS;AAChB,sBAAM,EAAE,MAAM,aAAa,IAAI,kBAAkB,cAAe,EAAE,UAAU,OAAO;AACnF,+BAAe,KAAK,EAAE,aAAa,cAAc,WAAW,EAAE,SAAS,MAAM,cAAc,YAAY,aAAa,YAAY,EAAE,WAAW,CAAC;AAAA,cAChJ;AAEA,kBAAI,eAAe,SAAS,KAAK,SAAS;AAMxC,mCAAmB,KAAK,GAAG,eAAe,MAAM,+DAA0D;AAAA,cAC5G,WAAW,eAAe,SAAS,GAAG;AACpC,sBAAM,WAAW,MAAM,eAAuE,8BAA8B;AAAA,kBAC1H,WAAW;AAAA,kBAAgB,WAAW,WAAW;AAAA,gBACnD,CAAC;AACD,gCAAgB,SAAS;AAEzB,mCAAmB,SAAS,WAAW;AACvC,oBAAI,mBAAmB,GAAG;AACxB,qCAAmB,KAAK,GAAG,gBAAgB,4GAAuG;AAAA,gBACpJ;AAAA,cACF;AAAA,YACF,QAAQ;AAAA,YAA+C;AAAA,UACzD;AAWA,gBAAM;AAAA,YACJ;AAAA,YAAuB;AAAA,YAAwB;AAAA,YAA4B;AAAA,UAC7E,IAAI,MAAM,0BAA0B,MAAM,WAAW,cAAc,SAAS,OAAO;AACnF,cAAI,oBAAoB,SAAS,GAAG;AAClC,+BAAmB,KAAK,GAAG,oBAAoB,MAAM,+BAA+B,oBAAoB,KAAK,IAAI,CAAC,EAAE;AAAA,UACtH;AAIA,cAAI,6BAA6B,GAAG;AAClC,+BAAmB,KAAK,GAAG,0BAA0B,6GAA6G;AAAA,UACpK;AACA,cAAI,yBAAyB,GAAG;AAC9B,+BAAmB,KAAK,GAAG,sBAAsB,iGAA4F;AAAA,UAC/I;AAUA,cAAI,CAAC,WAAW,qBAAqB,CAAC,iCAAiC;AACrE,gBAAI;AAIF,oBAAM,oBAAoB,MAAM,0BAA0B,MAAM,MAAM,MAAM,aAAa,YAAY;AACrG,oBAAM,eAAe,MAAM,eAA8D,qBAAqB;AAAA,gBAC5G,SAAS;AAAA,gBACT,QAAQ,UAAU,SAAS,OAAO,KAAK;AAAA,gBACvC,WAAW,WAAW;AAAA,gBACtB,GAAI,kBAAkB,SAAS,IAAI,EAAE,WAAW,kBAAkB,IAAI,CAAC;AAAA,cACzE,CAAC;AACD,oBAAM,gBAAgB,uBAAuB,YAAY;AACzD,kBAAI,eAAe;AAEjB,8BAAc,6CAAwC,aAAa;AAEnE,gCAAgB,kBAA2C,cAAc,SAAS,KAAK;AACvF,8BAAc;AAAA,cAChB,OAAO;AACL,8BAAc,kBAA0B,cAAc,QAAQ,MAAM,qBAAqB,aAAa;AACtG,wCAAwB,kBAAyC,cAAc,uBAAuB,KAAK;AAC3G,oBAAI,gBAAgB,aAAa;AAC/B,wBAAM,sBAAsB,EAAE,eAAe,WAAW,CAAC;AACzD,2CAAyB,MAAM,aAAa;AAAA,oBAC1C,UAAU;AAAA,oBACV,YAAY,gBAAgB;AAAA,oBAC5B,eAAe;AAAA,oBACf,SAAS;AAAA,kBACX,CAAC;AAAA,gBACH;AAAA,cACF;AAAA,YACF,SAAS,OAAgB;AAEvB,4BAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACnE,4BAAc;AACd,oBAAM,oBAAoB,EAAE,SAAS,cAAc,OAAO,WAAW,SAAS,OAAO,CAAC;AAAA,YACxF;AAAA,UACF;AAKA,gBAAM,YAAYA,QAAO;AAIzB,kBAAQ,KAAK;AAAA,YACX;AAAA,YACA,MAAM,MAAM;AAAA;AAAA;AAAA,YAGZ,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,IAAI;AAAA,YACJ,WAAW;AAAA,YACX,cAAc;AAAA,YACd,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YACA,GAAI,oBAAoB,EAAE,YAAY,kBAAkB,WAAW,IAAI,CAAC;AAAA,YACxE,GAAI,mBAAmB,iBAAiB,EAAE,gBAAgB,kBAAkB,eAAe,IAAI,CAAC;AAAA;AAAA;AAAA,YAGhG,GAAI,CAAC,MAAM,UAAU,EAAE,0BAA0B,KAAK,IAAI,CAAC;AAAA,YAC3D,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA;AAAA,YAErC,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA;AAAA;AAAA,YAGzC,GAAI,wBAAwB,EAAE,sBAAsB,IAAI,CAAC;AAAA,YACzD,GAAI,mBAAmB,SAAS,IAAI,EAAE,UAAU,mBAAmB,IAAI,CAAC;AAAA,YACxE,GAAI,cAAc,OAAO,KAAK,UAAU,QAAQ,EAAE,SAAS,KAAK,UAAU,SAAS,SAAS,MAAM;AAAA,cAChG,eAAe,EAAE,UAAU,UAAU,UAAU,UAAU,UAAU,SAAS;AAAA,YAC9E;AAAA;AAAA,YAEA,GAAI,oBAAoB,IAAI,EAAE,cAAc,kBAAkB,IAAI,CAAC;AAAA;AAAA,YAEnE,GAAIA,QAAO,kBAAkB,EAAE,iBAAiBA,QAAO,gBAAgB,IAAI,CAAC;AAAA;AAAA,YAE5E,GAAI,wBAAwB,IAAI,EAAE,kBAAkB,sBAAsB,IAAI,CAAC;AAAA;AAAA,YAE/E,GAAI,yBAAyB,IAAI,EAAE,mBAAmB,uBAAuB,IAAI,CAAC;AAAA,UACpF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAQD,UAAI,IAAK,eAAc;AAAA,IACzB,SAAS,OAAgB;AACvB,cAAQ,KAAK,uBAAuB;AAAA,QAClC;AAAA,QAAU,MAAM,MAAM;AAAA,QAAM,YAAY;AAAA,QAAc;AAAA,QAAc;AAAA,QAAY;AAAA,QAChF,GAAG,0BAA0B,OAAO,MAAM,IAAI;AAAA;AAAA,MAChD,CAAC,CAAC;AAAA,IACJ;AAAA,EACF;AAIA,QAAM,kBAAkB,aAAa;AAErC,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,EAAE;AAC1C,QAAM,EAAE,QAAQ,gBAAgB,sBAAsB,IAAI,gBAAgB,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;AACtG,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,WAAW;AAChE,QAAM,WAAW,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU;AAC9D,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO;AACzD,QAAM,eAAe,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,kBAAkB;AAC1E,QAAM,kBAAkB,QAAQ,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,iBAAiB,UAAU,EAAE;AAE/F,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,mBAAmB,QAAQ,MAAM,eAAe,OAAO,MAAM,YAAY,qBAAqB,MAAM;AAAA,IAC1G,QAAQ;AAAA,EACV,CAAC;AAWD,MAAI,SAAS;AACX,WAAO,6BAA6B,SAAS,QAAQ,sBAAsB,QAAQ,QAAQ,SAAS,UAAU;AAAA,EAChH;AAEA,QAAM,iBAAiB,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,WAAW,CAAC;AAEtE,QAAM,oBAAoB,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,cAAc,CAAC;AAE5E,QAAM,eAAe,oBAAI,IAAoB;AAC7C,aAAW,KAAK,SAAS;AACvB,iBAAa,IAAI,EAAE,aAAa,aAAa,IAAI,EAAE,UAAU,KAAK,KAAK,CAAC;AAAA,EAC1E;AAEA,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA,KAAK,QAAQ,MAAM,iBAAiB,OAAO,MAAM,gBAAgB,qBAAqB,MAAM,qBAAqB,QAAQ,MAAM;AAAA,IAC/H,2BAA2B,cAAc,GAAG,oBAAoB,IAAI,KAAK,iBAAiB,aAAa,EAAE;AAAA,IACzG;AAAA,EACF;AAEA,MAAI,kBAAkB,GAAG;AACvB,UAAM,KAAK,wBAAwB,eAAe,mCAAmC;AACrF,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,sBAAsB,aAAa,SAAS,IAAI,KAAK,aAAa,MAAM,mBAAmB;AACjG,UAAM;AAAA,MACJ,iBAAiB,UAAU,MAAM,eAAe,SAAS,MAAM,cAAc,OAAO,MAAM,SAAS,mBAAmB;AAAA,IACxH;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,aAAa,OAAO,GAAG;AACzB,UAAM,KAAK,kBAAkB;AAC7B,eAAW,CAAC,KAAK,KAAK,KAAK,cAAc;AACvC,YAAM,KAAK,OAAO,GAAG,OAAO,KAAK,UAAU;AAAA,IAC7C;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,iBAAiB,QAAQ,OAAO,CAAC,MAAM,EAAE,mBAAmB,UAAU,EAAE,iBAAiB,UAAU;AACzG,UAAM,mBAAmB,QAAQ,OAAO,CAAC,MAAM,EAAE,mBAAmB,QAAQ;AAE5E,QAAI,eAAe,SAAS,GAAG;AAC7B,YAAM,KAAK,8CAAyC;AACpD,iBAAW,KAAK,gBAAgB;AAC9B,cAAM,WAAW,EAAE,YAAY,IAAI,KAAK,EAAE,SAAS,gBAAgB;AACnE,cAAM,YAAY,EAAE,iBAAiB,aAAa,KAAK,EAAE,YAAY,IAAI,EAAE,UAAU,OAAO;AAC5F,cAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,cAAS,EAAE,MAAM,KAAK,SAAS,GAAG,QAAQ,EAAE;AAAA,MACvG;AAAA,IACF;AAEA,QAAI,iBAAiB,SAAS,GAAG;AAC/B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,0DAAqD;AAChE,iBAAW,KAAK,kBAAkB;AAChC,cAAM,WAAW,EAAE,YAAY,IAAI,KAAK,EAAE,SAAS,gBAAgB;AACnE,cAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,cAAS,EAAE,MAAM,OAAO,EAAE,YAAY,IAAI,EAAE,UAAU,KAAK,QAAQ,EAAE;AAAA,MAChI;AACA,YAAM,KAAK;AAAA,oEAAuE;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,qBAAqB,SAAS,GAAG;AACnC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,8DAAyD;AACpE,eAAW,KAAK,sBAAsB;AACpC,YAAM,aAAa,EAAE,sBACjB,yBAAoB,EAAE,mBAAmB,OAAO,EAAE,UAAU,OAC5D;AACJ,YAAM,OAAO,EAAE,cAAc,SACzB,oBAAoB,EAAE,aAAa,IAAI,CAAC,MAAM,KAAK,EAAE,UAAU,OAAO,EAAE,UAAU,IAAI,EAAE,KAAK,IAAI,CAAC,KAClG;AACJ,YAAM,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,EAAE;AAAA,IAC/D;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mFAAmF;AAAA,EAChG;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mBAAmB;AAC9B,eAAW,KAAK,cAAc;AAC5B,UAAI,EAAE,eAAe;AAKnB,cAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,GAAG;AAC5D,cAAM,cAAc,uBAAuB,iBAAiB,EAAE,WAAW,IAAI,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE;AAC9H,cAAM,KAAK,GAAG,YAAY,MAAM,IAAI,CAAC;AAAA,MACvC,OAAO;AACL,cAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,YAAO,EAAE,WAAW,EAAE;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAMA,QAAM,mCAAmC,QAAQ,OAAO,CAAC,MAAM,EAAE,qBAAqB;AACtF,MAAI,iCAAiC,SAAS,GAAG;AAC/C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,6BAA6B;AACxC,eAAW,KAAK,kCAAkC;AAChD,YAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,WAAM,EAAE,sBAAuB,MAAM,EAAE;AAC/E,iBAAW,KAAK,EAAE,sBAAuB,iBAAiB;AACxD,cAAM,KAAK,SAAS,EAAE,YAAY,MAAM,EAAE,cAAc,KAAK,EAAE,WAAW,EAAE;AAAA,MAC9E;AAAA,IACF;AAAA,EACF;AAGA,MAAI,mBAAmB;AACrB,UAAM,sBAAsB,QAAQ,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,eAAe,CAAC;AACtF,QAAI,oBAAoB,SAAS,GAAG;AAClC,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,uBAAuB;AAClC,YAAM,KAAK,GAAG,oBAAoB,MAAM,IAAI,oBAAoB,WAAW,IAAI,cAAc,cAAc,+DAA+D;AAC1K,iBAAW,KAAK,qBAAqB;AACnC,cAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,WAAM,EAAE,YAAY,YAAY,EAAE,iBAAiB,IAAI,UAAU,SAAS,EAAE;AAAA,MACtH;AAAA,IACF;AAAA,EACF;AAEA,QAAM,sBAAsB,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,SAAS,CAAC;AACrF,MAAI,oBAAoB,SAAS,GAAG;AAClC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,wBAAwB;AACnC,eAAW,KAAK,qBAAqB;AACnC,YAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,MAAM,EAAE,SAAU,KAAK,IAAI,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW;AACtB,eAAW,KAAK,QAAQ;AACtB,YAAM,KAAK,KAAK,EAAE,IAAI,KAAK,EAAE,UAAU,OAAO,EAAE,KAAK,GAAG;AAAA,IAC1D;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,+FAA+F;AAAA,EAC5G;AACA,QAAM,KAAK,GAAG,4BAA4B,qBAAqB,CAAC;AAChE,QAAM,WAAW,QAAQ,IAAI,CAAC,MAAM,EAAE,OAAO;AAC7C,MAAI,SAAS,SAAS,KAAK,qBAAqB,SAAS,GAAG;AAC1D,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,eAAe;AAC1B,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,KAAK,6FAA6F;AAAA,IAC1G;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,KAAK,iFAAiF;AAAA,IAC9F;AACA,QAAI,qBAAqB,SAAS,GAAG;AACnC,YAAM,KAAK,8BAA8B,qBAAqB,MAAM,4CAA4C;AAAA,IAClH;AACA,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,KAAK,0FAA0F;AAAA,IACvG;AAAA,EACF;AAEA,QAAM,cAAc,qBAAqB,SAAS,IAAI,KAAK,qBAAqB,MAAM,8BAA8B;AACpH,QAAM,iBAAiB,kBAAkB,IAAI,KAAK,eAAe,qBAAqB;AACtF,QAAM,mBAAmB,aAAa,SAAS,IAAI,KAAK,aAAa,MAAM,mBAAmB;AAC9F,QAAM,UACJ,OAAO,SAAS,KAAK,sBAAsB,SAAS,KAAK,qBAAqB,SAAS,KAAK,aAAa,SAAS,IAC9G,kBAAkB,QAAQ,MAAM,IAAI,QAAQ,MAAM,aAAa,OAAO,MAAM,UAAU,0BAA0B,qBAAqB,CAAC,GAAG,WAAW,KAAK,UAAU,MAAM,eAAe,SAAS,MAAM,cAAc,OAAO,MAAM,SAAS,gBAAgB,GAAG,cAAc,OAC5Q,kBAAkB,QAAQ,MAAM,0BAA0B,UAAU,MAAM,eAAe,SAAS,MAAM,cAAc,OAAO,MAAM,SAAS,cAAc;AAEhK,QAAM,aAAa,OAAO,CAAC;AAE3B,QAAM,OAAqB,CAAC;AAC5B,MAAI,QAAQ,SAAS,GAAG;AACtB,SAAK,KAAK,EAAE,MAAM,aAAa,aAAa,wBAAwB,YAAY,EAAE,QAAQ,WAAW,SAAS,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;AAAA,EACtI;AACA,MAAI,YAAY;AACd,SAAK,KAAK,EAAE,MAAM,WAAoB,aAAa,sBAAsB,YAAY,EAAE,QAAQ,UAAU,SAAS,WAAW,QAAQ,EAAE,CAAC;AAAA,EAC1I;AACA,MAAI,qBAAqB,SAAS,GAAG;AACnC,SAAK,KAAK,EAAE,MAAM,WAAW,aAAa,kDAAkD,YAAY,EAAE,MAAM,qBAAqB,CAAC,EAAE,MAAM,YAAY,qBAAqB,CAAC,EAAE,uBAAuB,GAAG,EAAE,CAAC;AAAA,EACjN;AAEA,QAAM,eAAe,KAAK,IAAI,IAAI;AAClC,QAAM,cAAc;AAAA,IAClB,SAAS;AAAA,IACT,eAAe,QAAQ,SAAS,IAAI,KAAK,MAAM,eAAe,QAAQ,MAAM,IAAI;AAAA,EAClF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,GAAG;AAAA,QACD;AAAA,QACA;AAAA,UACE,UAAU,QAAQ,IAAI,CAAC,OAAO;AAAA,YAC9B,SAAS,EAAE;AAAA,YACX,YAAY,EAAE;AAAA,YACd,MAAM,EAAE;AAAA,YACR,QAAQ,EAAE;AAAA,YACV,GAAI,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;AAAA,YACzD,GAAI,EAAE,cAAc,OAAO,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,YAC3D,GAAI,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,IAAI,CAAC;AAAA,YAC/D,GAAI,EAAE,UAAU,SAAS,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,YACrD,GAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,IAAI,CAAC;AAAA,YAC5D,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA;AAAA,YAEtD,GAAI,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,IAAI,CAAC;AAAA,YAC/D,GAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAAA;AAAA,YAE9D,GAAI,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,IAAI,CAAC;AAAA;AAAA,YAErE,GAAI,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,kBAAkB,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,YAIxE,GAAI,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,sBAAsB,IAAI,CAAC;AAAA,UACtF,EAAE;AAAA,UACF,OAAO,QAAQ;AAAA,UACf,QAAQ,OAAO;AAAA,UACf,WAAW,UAAU;AAAA,UACrB,UAAU,SAAS;AAAA,UACnB,QAAQ,OAAO;AAAA,UACf,GAAI,aAAa,SAAS,IAAI,EAAE,cAAc,aAAa,OAAO,IAAI,CAAC;AAAA,UACvE,GAAI,kBAAkB,IAAI,EAAE,YAAY,gBAAgB,IAAI,CAAC;AAAA,UAC7D;AAAA,UACA,GAAI,qBAAqB,SAAS,KAAK;AAAA,YACrC,sBAAsB,qBAAqB,IAAI,CAAC,OAAO;AAAA,cACrD,OAAO,EAAE;AAAA,cACT,MAAM,EAAE;AAAA,cACR,GAAI,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,oBAAoB,IAAI,CAAC;AAAA,cAC9E,GAAI,EAAE,cAAc,OAAO,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,cAC3D,GAAI,EAAE,cAAc,SAAS,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;AAAA,YACnE,EAAE;AAAA,UACJ;AAAA,UACA,GAAI,OAAO,SAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAMvB,eAAe,OAAO,IAAI,CAAC,OAAO;AAAA,cAChC,OAAO,EAAE;AAAA,cACT,YAAY,EAAE;AAAA,cACd,MAAM,EAAE;AAAA,cACR,OAAO,EAAE,SAAS;AAAA,YACpB,EAAE;AAAA,UACJ;AAAA,UAAI,GAAI,sBAAsB,SAAS,KAAK,EAAE,sBAAsB;AAAA;AAAA,QACtE;AAAA,QACA;AAAA,MACF;AAAA,MACE,OAAO,EAAE,QAAQ,YAAY;AAAA,IAC/B;AAAA,EACF;AACN;AAUA,SAAS,uBAAuB,cAAsC;AAKpE,MACE,CAAC,gBACD,OAAO,iBAAiB,YACxB,EAAE,YAAY,iBACb,aAAsC,WAAW,qBAClD;AACA,WAAO;AAAA,EACT;AACA,QAAM,UACJ,aAAa,eAAgB,aAAmD,UAAU;AAC5F,SAAO,SAAS,UAAU;AAC5B;AAOA,SAAS,kBAAqB,cAAuB,OAA8B;AACjF,MAAI,CAAC,gBAAgB,OAAO,iBAAiB,YAAY,EAAE,SAAS,cAAe,QAAO;AAC1F,SAAQ,aAAyC,KAAK;AACxD;AAcA,eAAe,oBAAoB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKkB;AAChB,QAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,QAAM,UAAU,0BAA0B,OAAO,KAAK,YAAY,GAAG,YAAY,cAAc,SAAS,MAAM,EAAE;AAGhH,MAAI;AACF,UAAM,OAAO,mBAAmB,EAAE,OAAO,SAAS,MAAM,SAAS,QAAQ,gBAAgB,CAAC;AAAA,EAC5F,QAAQ;AAAA,EAER;AAGA,MAAI,WAAW;AACb,QAAI;AACF,YAAM,UAAU,0BAA0B,OAAO,WAAM,YAAY,GAAG,MAAM,GAAG,GAAG;AAClF,YAAM,eAA8D,qBAAqB;AAAA,QACvF,gBAAgB;AAAA,QAChB,MAAM;AAAA;AAAA;AAAA,QAGN,QAAQ;AAAA,QACR,MAAM,CAAC;AAAA,QACP,WAAW,SAAS,SAAS;AAAA,QAC7B;AAAA,MACF,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAkBA,eAAsB,sBACpB,MACA,aACiC;AACjC,QAAM,WAAmC,CAAC;AAC1C,MAAI;AACF,UAAM,WAAW,aAAa,GAAG,IAAI,IAAI,WAAW,EAAE,EACnD,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC,EACjD,MAAM,GAAG,CAAC;AAEb,QAAI,SAAS,WAAW,EAAG,QAAO;AAElC,UAAM,cAAc,SAAS,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AACjD,UAAM,CAAC,YAAY,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,MAClD,YAA6D,uBAAuB,EAAE,OAAO,aAAa,gBAAgB,iBAAiB,CAAC;AAAA,MAC5I,YAA6D,uBAAuB,EAAE,OAAO,aAAa,gBAAgB,eAAe,CAAC;AAAA,IAC5I,CAAC;AAED,UAAM,SAAS,CAAC,GAAI,cAAc,CAAC,GAAI,GAAI,eAAe,CAAC,CAAE,EAAE,MAAM,GAAG,CAAC;AAEzE,eAAW,SAAS,QAAQ;AAC1B,YAAM,cAAc,IAAI,IAAI,aAAa,GAAG,MAAM,IAAI,IAAI,MAAM,MAAM,eAAe,EAAE,EAAE,CAAC;AAC1F,YAAM,UAAU,SAAS,OAAO,CAAC,MAAM,YAAY,IAAI,CAAC,CAAC;AACzD,UAAI,QAAQ,SAAS,EAAG;AAGxB,UAAI,eAAe;AACnB,UAAI;AACF,cAAM,YAAY,MAAM,YAAkE,4BAA4B;AAAA,UACpH,SAAS,MAAM;AAAA,QACjB,CAAC;AACD,wBAAgB,aAAa,CAAC,GAAG,OAAO,CAAC,MAAW,EAAE,SAAS,SAAS,EAAE;AAAA,MAC5E,QAAQ;AAAA,MAAqB;AAE7B,eAAS,KAAK;AAAA,QACZ,SAAS,MAAM,WAAW;AAAA,QAC1B,MAAM,MAAM;AAAA,QACZ,YAAY,MAAM,kBAAkB;AAAA,QACpC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAgCA,eAAe,0BACb,MACA,aACA,gBACmC;AACnC,MAAI;AACF,UAAM,YAAY,MAAM,YAAuE,iCAAiC;AAAA,MAC9H;AAAA,MACA;AAAA,MACA,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;AAAA,IAC7C,CAAC;AAQD,YAAQ,aAAa,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,MACnC,cAAc,EAAE;AAAA,MAChB,gBAAgB,EAAE;AAAA,MAClB,GAAI,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,sBAAsB,IAAI,CAAC;AAAA,MACpF,MAAM,EAAE;AAAA,MACR,YAAY,EAAE;AAAA,MACd,aAAa,EAAE;AAAA,IACjB,EAAE;AAAA,EACJ,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;AmBzvGA,eAAsB,qBACpB,MACA,aACA,gBACkC;AAClC,MAAI;AASF,UAAM,YAAY,MAAM,YAAuE,iCAAiC;AAAA,MAC9H;AAAA,MACA;AAAA,MACA,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;AAAA,IAC7C,CAAC;AAED,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW,aAAa,CAAC;AAAA,MACzB,kBAAkB,CAAC;AAAA,IACrB;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,4FAA4F,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC1J,UAAM,mBAAmB,MAAM,sBAAsB,MAAM,WAAW;AACtE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW,CAAC;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;;;AC9DA,SAAS,KAAAE,UAAS;AAKX,IAAM,mBAAmBC,GAAE,OAAO;AAAA,EACvC,SAASA,GAAE,OAAO,EAAE,SAAS,6CAA6C;AAC5E,CAAC;AAED,eAAsB,iBAAiB,EAAE,QAAQ,GAA0D;AACrG,QAAM,UAAU,MAAM,YAAgE,0BAA0B,EAAE,QAAQ,CAAC;AAE3H,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,MACL,wBAAwB,OAAO;AAAA,MAC/B,kCAAkC,OAAO;AAAA,MACzC,EAAE,SAAS,YAAY,GAAG,QAAQ,CAAC,EAAE;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,YAAY,QACf,IAAI,CAAC,SAAS;AAOb,UAAM,IAAI;AACV,UAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY;AAC/C,UAAM,UAAU,EAAE,UAAU,WAAM,KAAK,UAAU,EAAE,OAAO,CAAC,KAAK;AAGhE,UAAM,YAAY,EAAE,kBAAkB,KAAK,EAAE,eAAe,MAAM;AAClE,WAAO,OAAO,IAAI,MAAM,EAAE,KAAK,GAAG,EAAE,YAAY,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,GAAG,SAAS;AAAA,EAClG,CAAC,EACA,KAAK,IAAI;AAEZ,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,mBAAmB,OAAO,OAAO,QAAQ,MAAM;AAAA;AAAA,EAAe,SAAS,GAAG,CAAC;AAAA,IACpH,mBAAmB;AAAA,MACjB,SAAS,QAAQ,MAAM,uBAAuB,OAAO;AAAA,MACrD,EAAE,SAAS,YAAY,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,IACzD;AAAA,EACF;AACN;;;ArB5BO,IAAM,oBAAoBC,GAAE,OAAO;AAAA,EACxC,SAASA,GAAE,OAAO,EAAE,SAAS,uDAAuD;AAAA,EACpF,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA;AAAA;AAAA,EAGvD,QAAQA,GAAE,KAAK,CAAC,SAAS,UAAU,cAAc,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,0KAAqK;AAAA,EACvP,gBAAgBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8OAAyO;AAAA,EACxR,MAAMA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,EAC9F,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gBAAgB;AAAA,EACtD,cAAcA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2FAA2F;AAAA,EACxI,aAAaA,GAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK,EAAE,SAAS,sHAAsH;AAAA,EAClL,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sPAAsP;AAAA,EACjS,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wGAAwG;AAAA,EAClJ,eAAeA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kHAAkH;AAAA;AAAA,EAEhK,wBAAwBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yJAA+I;AAAA,EACtM,0BAA0BA,GAAE,OAAO;AAAA,IACjC,UAAUA,GAAE,KAAK,CAAC,UAAU,gBAAgB,UAAU,CAAC,EAAE,SAAS,mEAAmE;AAAA,IACrI,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qFAAqF;AAAA,IAC7H,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iEAA4D;AAAA,EACrG,CAAC,EAAE,SAAS,EAAE,SAAS,wIAAwI;AACjK,CAAC;AAQM,IAAM,oBAAoBA,GAAE,OAAO;AAAA,EACxC,SAASA,GAAE,OAAO,EAAE,SAAS,uDAAuD;AAAA;AAAA,EAEpF,SAASA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,0FAA0F;AAAA;AAAA,EAEnI,wBAAwBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kJAAwI;AAAA,EAC/L,0BAA0BA,GAAE,OAAO;AAAA,IACjC,UAAUA,GAAE,KAAK,CAAC,UAAU,gBAAgB,UAAU,CAAC,EAAE,SAAS,mEAAmE;AAAA,IACrI,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qFAAqF;AAAA,IAC7H,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iEAA4D;AAAA,EACrG,CAAC,EAAE,SAAS,EAAE,SAAS,+EAA+E;AACxG,CAAC;AAYD,eAAsB,kBACpB,EAAE,SAAS,MAAM,QAAQ,WAAW,gBAAgB,mBAAmB,MAAM,OAAO,cAAc,aAAa,YAAY,WAAW,eAAe,wBAAwB,yBAAyB,GACtM,WAAsB,WACD;AACjB,qBAAmB;AAEnB,QAAM,iBAA2B,CAAC;AAClC,MAAI,SAAS,OAAW,gBAAe,KAAK,MAAM;AAClD,MAAI,cAAc,OAAW,gBAAe,KAAK,QAAQ;AACzD,MAAI,sBAAsB,OAAW,gBAAe,KAAK,gBAAgB;AACzE,MAAI,SAAS,OAAW,gBAAe,KAAK,MAAM;AAClD,MAAI,UAAU,OAAW,gBAAe,KAAK,OAAO;AACpD,MAAI,iBAAiB,OAAW,gBAAe,KAAK,cAAc;AAKlE,QAAMC,UAAsC;AAC5C,QAAM,iBAAqC;AAG3C,QAAM,eAAe,MAAM,eAA8D,qBAAqB;AAAA,IAC5G;AAAA,IACA;AAAA,IACA,QAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,kBAAkB,IAAI,SAAS,kBAAkB,CAAC,KAAK;AAAA,IAClE,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,IACzC,GAAI,yBAAyB,EAAE,uBAAuB,IAAI,CAAC;AAAA,IAC3D,GAAI,2BAA2B,EAAE,yBAAyB,IAAI,CAAC;AAAA,EACjE,CAAC;AAID,QAAM,eAAe;AACrB,MAAI,aAAa,YAAY,aAAa,aAAa,SAAS;AAC9D,WAAO,uBAAuB,GAAG,QAAQ,kBAAkB,SAAS,aAAa,OAAO;AAAA,EAC1F;AAEA,QAAM,KAAK,aAAa;AACxB,QAAM,sBAAsB,EAAE,eAAe,GAAG,CAAC;AAEjD,QAAM,QAAQ,MAAM,oBAAoB;AACxC,QAAM,UAAU,MAAM,YAAiB,kBAAkB,EAAE,QAAQ,CAAC;AACpE,QAAM,cAAgC,SAAS,UAAU;AACzD,QAAM,cAAc,gBAAgB,WAAW,cAAc,YAAY,WAAW;AACpF,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA;AAAA,IACA,KAAK,OAAO,aAAQ,WAAW;AAAA,IAC/B;AAAA,IACA,gBAAgB,EAAE;AAAA,IAClB,kBAAkB,MAAM,aAAa,KAAK,MAAM,WAAW;AAAA,EAC7D;AAEA,MAAI,eAAe,SAAS,GAAG;AAC7B,kBAAc,KAAK,wBAAwB,eAAe,KAAK,IAAI,CAAC,EAAE;AAAA,EACxE,OAAO;AACL,kBAAc,KAAK,EAAE;AACrB,kBAAc,KAAK,+EAAgE;AAAA,EACrF;AAGA,OAAK,aAAa,yBAAyB,CAAC,GAAG,SAAS,GAAG;AACzD,kBAAc,KAAK,EAAE;AACrB,kBAAc,KAAK,0CAAgC;AACnD,eAAW,WAAW,aAAa,yBAAyB,CAAC,GAAG;AAC9D,oBAAc,KAAK,OAAO,OAAO,EAAE;AAAA,IACrC;AAAA,EACF;AAGA,OAAK,aAAa,sBAAsB,CAAC,GAAG,SAAS,GAAG;AACtD,kBAAc,KAAK,EAAE;AACrB,kBAAc,KAAK,uCAA6B;AAChD,eAAW,WAAW,aAAa,sBAAsB,CAAC,GAAG;AAC3D,oBAAc,KAAK,OAAO,OAAO,EAAE;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,UAAU,WAAW,OAAO,WAAM,WAAW,aAAa,eAAe,KAAK,IAAI,KAAK,MAAM;AACnG,QAAM,OAAqB;AAAA,IACzB,EAAE,MAAM,UAAU,aAAa,sBAAsB,YAAY,EAAE,QAAQ,OAAO,QAAQ,EAAE;AAAA,IAC5F,EAAE,MAAM,UAAU,aAAa,qBAAqB,YAAY,EAAE,QAAQ,UAAU,QAAQ,EAAE;AAAA,EAChG;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,cAAc,KAAK,IAAI,EAAE,CAAC;AAAA,IACnE,mBAAmB,QAAQ,SAAS;AAAA,MAClC,SAAS;AAAA,MACT;AAAA,MACA;AAAA;AAAA,MAEA,GAAI,aAAa,kBAAkB,OAAO,KAAK,aAAa,cAAc,QAAQ,EAAE,SAAS,KAAK,aAAa,cAAc,SAAS,SAAS,MAAM;AAAA,QACnJ,eAAe;AAAA,UACb,UAAU,aAAa,cAAc;AAAA,UACrC,UAAU,aAAa,cAAc;AAAA,QACvC;AAAA,MACF;AAAA,MACA,IAAK,aAAa,yBAAyB,CAAC,GAAG,SAAS,KAAK;AAAA,QAC3D,uBAAuB,aAAa;AAAA,MACtC;AAAA,MACA,IAAK,aAAa,sBAAsB,CAAC,GAAG,SAAS,KAAK;AAAA,QACxD,oBAAoB,aAAa;AAAA,MACnC;AAAA,IACF,GAAG,IAAI;AAAA,EACT;AACN;AAQA,eAAsB,kBACpB,EAAE,SAAS,SAAS,wBAAwB,yBAAyB,GACrE,WAAsB,WACD;AACjB,qBAAmB;AAEnB,QAAM,QAAQ,MAAM,YAAiB,kBAAkB,EAAE,QAAQ,CAAC;AAClE,MAAI,CAAC,OAAO;AACV,WAAO,eAAe,SAAS,UAAU,OAAO,+CAA+C;AAAA,EACjG;AAEA,QAAM,YAAY,MAAM,MAAM,eAAe,MAAM,MAAM,aAAa,MAAM,MAAM,aAAa;AAC/F,QAAM,YAAY,MAAM;AAAA,IACtB,MAAM;AAAA,IACN;AAAA,IACA,MAAM,kBAAkB,MAAM,YAAY,QAAQ,MAAM,YAAY;AAAA,EACtE;AAOA,QAAM,mBAAmB,UAAU,WAAW,aAC1C,UAAU,UAAU,IAAI,CAAC,cAAc;AAAA,IACrC,MAAM;AAAA,IACN,SAAS,SAAS;AAAA,IAClB,MAAM,SAAS;AAAA,IACf,aAAa,SAAS;AAAA,EACxB,EAAE,IACF,UAAU,iBAAiB,IAAI,CAAC,aAAa;AAAA,IAC3C,MAAM;AAAA,IACN,SAAS,QAAQ;AAAA,IACjB,MAAM,QAAQ;AAAA,IACd,YAAY,QAAQ;AAAA,IACpB,cAAc,QAAQ;AAAA,EACxB,EAAE;AAEN,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,sBAAsB,EAAE,sBAAsB,KAAK,CAAC;AAAA,EAC5D;AAWA,QAAM,mBAAmB,UAAU,WAAW,aAC1C,UAAU,UAAU,IAAI,CAAC,OAAO;AAAA,IAC9B,cAAc,EAAE;AAAA,IAChB,gBAAgB,EAAE;AAAA,IAClB,GAAI,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,sBAAsB,IAAI,CAAC;AAAA,IACpF,MAAM,EAAE;AAAA,IACR,YAAY,EAAE;AAAA,IACd,aAAa,EAAE;AAAA,EACjB,EAAE,IACF,CAAC;AAEL,MAAI,iBAAsB;AAY1B,MAAI,CAAC,SAAS;AACZ,QAAI;AACF,uBAAiB,MAAM,eAAiF,wCAAwC;AAAA,QAC9I;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAIC;AACJ,MAAI;AACF,IAAAA,UAAS,MAAM,eAA8D,qBAAqB;AAAA,MAChG;AAAA,MACA,QAAQ,kBAAkB,IAAI,SAAS,kBAAkB,CAAC,KAAK;AAAA,MAC/D,WAAW,kBAAkB,KAAK;AAAA,MAClC,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,MACnC,GAAI,yBAAyB,EAAE,uBAAuB,IAAI,CAAC;AAAA,MAC3D,GAAI,2BAA2B,EAAE,yBAAyB,IAAI,CAAC;AAAA,MAC/D,GAAI,iBAAiB,SAAS,IAAI,EAAE,WAAW,iBAAiB,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH,SAAS,WAAoB;AAG3B,UAAM,UAAW,WAAiC;AAClD,QAAI,YAAY,qBAAqB;AACnC,UAAI;AACF,cAAMC,SAAQ,MAAM,oBAAoB;AACxC,cAAM,IAAI;AACV,+BAAuBA,OAAM,aAAa;AAAA,UACxC,YAAY;AAAA,UACZ,qBAAqB,EAAE,uBAAuB,UAAU;AAAA,UACxD,mBAAmB,EAAE,aAAa,UAAU;AAAA,UAC5C,UAAU;AAAA,QACZ,CAAC;AAAA,MACH,QAAQ;AAAA,MAAkD;AAAA,IAC5D;AACA,UAAM;AAAA,EACR;AAIA,MAAID,SAAQ,WAAW,uBAAuBA,SAAQ,SAAS;AAC7D,WAAO,uBAAuB,GAAG,QAAQ,kBAAkB,SAASA,QAAO,OAAkC;AAAA,EAC/G;AAGA,MAAIA,SAAQ,SAAS;AACnB,UAAM,aAAaA,QAAO,eAAe;AAMzC,UAAM,+BAA+BA,SAAQ;AAG7C,UAAM,kBAAkB;AAAA,MACtB,YAAY,aAAa,uBAAuB,cAAc,IAAI,OAAO;AAAA,MACzE;AAAA,QACE;AAAA,QACA,MAAM,MAAM;AAAA,QACZ,SAAS,aAAc,YAAuB;AAAA,QAC9C,eAAeA,QAAO;AAAA,QACtB,gBAAgBA,QAAO;AAAA,QACvB;AAAA,QACA,GAAI,cAAcA,QAAO,iBAAiB,EAAE,gBAAgBA,QAAO,eAAe,IAAI,CAAC;AAAA,QACvF,GAAI,+BAA+B,EAAE,uBAAuB,6BAA6B,IAAI,CAAC;AAAA,MAChG;AAAA,MACA,CAAC,EAAE,MAAM,UAAU,aAAa,mBAAmB,YAAY,EAAE,QAAQ,UAAU,QAAQ,EAAE,CAAC;AAAA,IAChG;AACA,QAAIA,QAAO,UAAU;AACnB,sBAAgB,WAAWA,QAAO;AAAA,IACpC;AACA,UAAM,eAAe,cAAcA,QAAO,iBACtC;AAAA;AAAA,wBAA6BA,QAAO,cAAc,KAClD,aACE;AAAA;AAAA,yDACA;AACN,UAAM,eAAe,+BACjB;AAAA;AAAA,oEAAoE,6BAA6B,MAAM;AAAA,EAAK,6BAA6B,gBAAgB,IAAI,CAAC,MAAM,OAAO,EAAE,YAAY,MAAM,EAAE,cAAc,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,IAAI,CAAC,KAC/O;AACJ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,oBAAoB,aAAa,iBAAiB,QAAQ,IAAI,OAAO;AAAA;AAAA,oBAAyBA,QAAO,aAAa,4BAAuBA,QAAO,cAAc,MAAM,YAAY,GAAG,YAAY;AAAA;AAAA,uEAAuE,CAAC;AAAA,MAChT,mBAAmB;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,QAAQA,SAAQ,OAAO,MAAM;AACnC,QAAM,QAAQ,MAAM,oBAAoB;AACxC,QAAM,aAAaA,SAAQ,WAAW;AACtC,MAAI,CAAC,YAAY;AACf,UAAM,sBAAsB,EAAE,eAAe,MAAM,CAAC;AACpD,UAAM,OACH,MAAM,kBACN,MAAM,YAAY;AACrB,6BAAyB,MAAM,aAAa;AAAA,MAC1C,UAAU,MAAM,WAAW;AAAA,MAC3B,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,MAAI;AAEJ,MAAI,YAAY;AACd,YAAQ;AAAA,MACN,uBAAuBA,QAAO,WAAW,OAAO;AAAA,MAChD,KAAKA,QAAO,QAAQ,MAAM,IAAI;AAAA,MAC9B,kBAAkB,MAAM,aAAa,KAAK,MAAM,WAAW;AAAA,MAC3D;AAAA,MACAA,QAAO,WACH,oDACA;AAAA,IACN;AAAA,EACF,OAAO;AACL,YAAQ;AAAA,MACN,eAAe,OAAO;AAAA,MACtB,KAAK,MAAM,IAAI;AAAA,MACf,kBAAkB,MAAM,aAAa,KAAK,MAAM,WAAW;AAAA,IAC7D;AAGA,UAAM,eAAeA,SAAQ;AAC7B,QAAI,cAAc,UAAU;AAC1B,YAAM,MAAM,aAAa,aAAa,KAAK,aAAa,UAAU,MAAM;AACxE,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,4CAAuC,aAAa,QAAQ,GAAG,GAAG,IAAI;AAAA,IACnF;AAAA,EACF;AAEA,MAAI,iBAAiB,SAAS,GAAG;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,UAAU,WAAW,aAC5B,oEACA,iFAA4E;AAChF,eAAW,KAAK,kBAAkB;AAChC,YAAM,KAAK,EAAE,SAAS,aAClB,KAAK,EAAE,IAAI,KAAK,EAAE,OAAO,YAAO,EAAE,WAAW,KAC7C,KAAK,EAAE,IAAI,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,sCAAiC,EAAE,YAAY,UAAU;AAAA,IACzG;AAKA,UAAM,KAAK,UAAU,WAAW,aAC5B,2LACA,8KAA8K;AAAA,EACpL;AAEA,MAAI,gBAAgB,SAAS;AAC3B,QAAI;AACF,YAAM,IAAI,eAAe;AACzB,YAAM,eAAe,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,MAAW,CAAC,EAAE,MAAM,EAAE;AACrE,0BAAoB,MAAM,aAAa;AAAA,QACrC,UAAU;AAAA,QACV,YAAY,EAAE,gBAAgB,MAAM,gBAAgB;AAAA,QACpD,MAAM,EAAE;AAAA,QACR,SAAS;AAAA,QACT,QAAQ,EAAE;AAAA,QACV,QAAQ,eAAe,UAAU;AAAA,QACjC,gBAAgB,EAAE,UAAU,UAAU;AAAA,QACtC,iBAAiB;AAAA,QACjB,eAAe,EAAE,SAAS;AAAA,QAC1B,qBAAqB,EAAE;AAAA,MACzB,CAAC;AAAA,IACH,QAAQ;AAAA,IAA6B;AAAA,EACvC;AAEA,MAAI,gBAAgB,WAAW,eAAe,QAAQ,SAAS,aAAa,eAAe,QAAQ,SAAS,SAAS,GAAG;AACtH,UAAM,WAAW,qBAAqB,cAAc;AACpD,QAAI,UAAU;AACZ,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,QAAQ;AACnB,UAAI,CAAC,eAAe,QAAQ,UAAU,eAAe,QAAQ,SAAS,aAAa;AACjF,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,qFAAqF;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AAGA,QAAM,mBAAmBA,SAAQ;AACjC,MAAI,oBAAoB,iBAAiB,SAAS,GAAG;AACnD,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,uCAAuC;AAClD,eAAW,KAAK,kBAAkB;AAChC,YAAM,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE;AAAA,IAC7C;AACA,UAAM,KAAK,2FAAsF,OAAO,uBAAuB;AAE/H,UAAM,cAAc,CAAC,GAAG,IAAI,IAAI,iBAAiB,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC3E,6BAAyB,MAAM,aAAa;AAAA,MAC1C,eAAe,iBAAiB;AAAA,MAChC,eAAe;AAAA,IACjB,CAAC;AAAA,EACH;AAKA,QAAM,mBACJ,OAAOA,SAAQ,qBAAqB,YAAYA,QAAO,iBAAiB,KAAK,IACxEA,QAAO,mBACR;AACN,MAAI,kBAAkB;AACpB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,+CAA0C,gBAAgB,EAAE;AAAA,EACzE;AAMA,QAAM,wBAAwBA,SAAQ;AAGtC,MAAI,uBAAuB;AACzB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oDAA+C,sBAAsB,MAAM,EAAE;AACxF,eAAW,KAAK,sBAAsB,iBAAiB;AACrD,YAAM,KAAK,OAAO,EAAE,YAAY,MAAM,EAAE,cAAc,KAAK,EAAE,WAAW,EAAE;AAAA,IAC5E;AAAA,EACF;AAGA,QAAM,oBAAoB,MAAM,QAAQA,SAAQ,iBAAiB,IAC5DA,QAAO,kBAAgC,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IACxF;AACJ,MAAI,qBAAqB,kBAAkB,SAAS,GAAG;AACrD,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,8CAAyC;AACpD,eAAW,YAAY,mBAAmB;AACxC,YAAM,KAAK,KAAK,QAAQ,EAAE;AAAA,IAC5B;AAAA,EACF;AAGA,QAAM,YAAY,sBAAsB,iBAAiB,KAAgC,CAAC;AAE1F,MAAI,cAAc,UAAU,UAAU,gBAAgB,UAAU,UAAU,aAAa;AACrF,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,UAAK,oBAAoB,SAAS,CAAC,EAAE;AAChD,QAAI,UAAU,QAAQ;AACpB,YAAM,KAAK,YAAO,UAAU,MAAM,EAAE;AAAA,IACtC;AAAA,EACF;AAIA,MAAI;AACJ,MAAI;AACF,UAAM,WACH,MAAM,kBACN,MAAM,YAAY;AACrB,QAAI,UAAU;AACZ,wBAAkB,MAAM;AAAA,QACtB;AAAA,QACA,EAAE,gBAAgB,SAAS;AAAA,MAC7B,KAAK;AAAA,IACP;AAAA,EACF,QAAQ;AAAA,EAAmC;AAG3C,QAAM,OAAqB,aACvB;AAAA,IACE,EAAE,MAAM,WAAW,aAAa,cAAc,YAAY,EAAE,QAAQ,OAAO,QAAQ,EAAE;AAAA,EACvF,IACA;AAAA,IACE,EAAE,MAAM,aAAa,aAAa,wBAAwB,YAAY,EAAE,QAAQ,WAAW,QAAQ,EAAE;AAAA,IACrG,EAAE,MAAM,WAAW,aAAa,uBAAuB,YAAY,EAAE,QAAQ,OAAO,QAAQ,EAAE;AAAA,EAChG;AAEJ,QAAM,UAAU,aACZ,wBAAwB,OAAO,KAAK,MAAM,IAAI,yBAC9C,YAAY,OAAO,KAAK,MAAM,IAAI;AAEtC,QAAM,wBAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,MACE;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,SAAS,aAAa,qBAA8B;AAAA,MACpD,gBAAgB,gBAAgB,WAAW;AAAA,MAC3C,QAAQ,gBAAgB,UAAU;AAAA,MAClC,gBAAgB,iBAAiB;AAAA,MACjC,GAAI,YAAY,EAAE,iBAAiB,UAAU,IAAI,CAAC;AAAA,MAClD,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA;AAAA;AAAA,MAG/C,GAAI,wBAAwB,EAAE,sBAAsB,IAAI,CAAC;AAAA;AAAA,MAEzD,GAAI,qBAAqB,kBAAkB,SAAS,IAAI,EAAE,kBAAkB,IAAI,CAAC;AAAA;AAAA;AAAA,MAGjF,GAAIA,SAAQ,eAAe,EAAE,cAAcA,QAAO,aAAa,IAAI,CAAC;AAAA,IACtE;AAAA,IACA;AAAA,EACF;AAEA,MAAI,iBAAiB;AACnB,0BAAsB,WAAW;AAAA,EACnC;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,EACrB;AACN;;;AsBlkBA,SAAS,cAAAE,aAAY,oBAAoB;AACzC,SAAS,WAAAC,gBAAe;AAExB,SAAS,KAAAC,UAAS;;;ACGlB,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAEjB,SAAS,qBAAoC;AAClD,QAAM,aAAa;AAAA,IACjB,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA;AAAA;AAAA,IAGZ,QAAQ,QAAQ,IAAI,GAAG,IAAI;AAAA,EAC7B,EAAE,OAAO,OAAO;AAEhB,aAAW,OAAO,YAAY;AAC5B,UAAM,WAAW,QAAQ,GAAG;AAC5B,QAAI,WAAW,QAAQ,UAAU,kBAAkB,CAAC,EAAG,QAAO;AAAA,EAChE;AACA,SAAO;AACT;;;ADSA,SAAS,kBAAkB,YAA8C;AACvE,QAAM,UAAU,aAAa,YAAY,OAAO;AAChD,QAAM,SAAS,oBAAI,IAAyB;AAC5C,MAAI,eAA8B;AAElC,aAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,UAAM,aAAa,KAAK,MAAM,2BAA2B;AACzD,QAAI,YAAY;AACd,qBAAe,WAAW,CAAC;AAC3B,aAAO,IAAI,cAAc,oBAAI,IAAI,CAAC;AAClC;AAAA,IACF;AAEA,QAAI,gBAAgB,WAAW,KAAK,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,GAAG;AAChE,qBAAe;AACf;AAAA,IACF;AAEA,QAAI,cAAc;AAChB,YAAM,aAAa,KAAK,MAAM,mBAAmB;AACjD,UAAI,WAAY,QAAO,IAAI,YAAY,EAAG,IAAI,WAAW,CAAC,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,cAAc,OAAuB;AAC5C,SAAO,MACJ,QAAQ,iBAAiB,EAAE,EAC3B,QAAQ,cAAc,EAAE,EACxB,KAAK;AACV;AAEA,SAAS,eAAe,OAAyB;AAC/C,MAAI,MAAM,SAAS,KAAK,EAAG,QAAO,MAAM,MAAM,UAAU;AACxD,SAAO,CAAC,KAAK;AACf;AAEA,IAAM,cAAc;AAEpB,SAAS,YAAY,SAA8B;AACjD,MAAI,QAAQ,SAAS,GAAG,KAAK,YAAY,KAAK,OAAO,KAAK,SAAS,KAAK,OAAO,GAAG;AAChF,WAAO;AAAA,EACT;AACA,MAAI,aAAa,KAAK,OAAO,EAAG,QAAO;AACvC,MAAI,iBAAiB,KAAK,OAAO,EAAG,QAAO;AAC3C,SAAO;AACT;AAIA,SAAS,aAAa,KAAa,MAAuD;AACxF,QAAM,WAAW,IAAI,MAAM,KAAK,EAAE,CAAC;AACnC,QAAM,WAAWC,SAAQ,MAAM,QAAQ;AACvC,MAAIC,YAAW,QAAQ,EAAG,QAAO,EAAE,QAAQ,YAAY,QAAQ,SAAS;AACxE,SAAO,EAAE,QAAQ,WAAW,QAAQ,cAAc,QAAQ,GAAG;AAC/D;AAEA,SAAS,eACP,KACA,QACyC;AACzC,QAAM,iBAAiB,IAAI,MAAM,kBAAkB;AACnD,MAAI,gBAAgB;AAClB,UAAM,QAAQ,eAAe,CAAC;AAC9B,QAAI,OAAO,IAAI,KAAK,EAAG,QAAO,EAAE,QAAQ,YAAY,QAAQ,UAAU,KAAK,WAAW;AACtF,WAAO,EAAE,QAAQ,WAAW,QAAQ,UAAU,KAAK,wBAAwB;AAAA,EAC7E;AAEA,QAAM,SAAS,IAAI,QAAQ,GAAG;AAC9B,MAAI,SAAS,GAAG;AACd,UAAM,QAAQ,IAAI,MAAM,GAAG,MAAM;AACjC,UAAM,QAAQ,IAAI,MAAM,SAAS,CAAC;AAClC,QAAI,CAAC,OAAO,IAAI,KAAK,EAAG,QAAO,EAAE,QAAQ,WAAW,QAAQ,UAAU,KAAK,wBAAwB;AACnG,QAAI,CAAC,OAAO,IAAI,KAAK,EAAG,IAAI,KAAK,EAAG,QAAO,EAAE,QAAQ,WAAW,QAAQ,UAAU,KAAK,yBAAyB,KAAK,IAAI;AACzH,WAAO,EAAE,QAAQ,YAAY,QAAQ,GAAG,KAAK,IAAI,KAAK,UAAU;AAAA,EAClE;AAEA,SAAO,EAAE,QAAQ,gBAAgB,QAAQ,mCAAmC;AAC9E;AAIA,SAAS,kBACP,YACA,YACA,UACA,MACA,OACA,MACA,kBACA,aACQ;AACR,QAAM,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU,EAAE;AACjE,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AAC/D,QAAM,eAAe,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,cAAc,EAAE;AAEzE,QAAM,YAAY,KAAK,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;AAC9C,QAAM,aAAa,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE;AAEhD,QAAM,cAAc,SAAS,SAAS,KAAK;AAC3C,QAAM,cAAc,WAAW;AAC/B,QAAM,aAAa,cAAc,IAAI,KAAK,MAAO,cAAc,cAAe,GAAG,IAAI;AAErF,QAAM,QAAkB;AAAA,IACtB,mBAAmB,UAAU,KAAK,UAAU;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM;AAAA,MACJ;AAAA,MACA,KAAK,SAAS,MAAM;AAAA,MACpB,KAAK,QAAQ,cAAc,KAAK,MAAO,WAAW,SAAS,SAAU,GAAG,CAAC;AAAA,MACzE,KAAK,OAAO;AAAA,MACZ,KAAK,YAAY;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU,GAAG;AACf,UAAM,KAAK,sBAAsB;AACjC,eAAW,MAAM,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,GAAG;AAC/D,YAAM,KAAK,OAAO,GAAG,OAAO,OAAO,GAAG,SAAS,QAAQ,GAAG,KAAK,aAAQ,GAAG,MAAM,EAAE;AAAA,IACpF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,eAAe,GAAG;AACpB,UAAM,KAAK,+BAA+B;AAC1C,eAAW,MAAM,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,cAAc,GAAG;AACpE,YAAM,KAAK,OAAO,GAAG,OAAO,OAAO,GAAG,SAAS,QAAQ,GAAG,KAAK,IAAI;AAAA,IACrE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM;AAAA,MACJ;AAAA,MACA,KAAK,KAAK,MAAM;AAAA,MAChB,KAAK,SAAS,WAAW,KAAK,SAAS,IAAI,KAAK,MAAO,YAAY,KAAK,SAAU,GAAG,IAAI,CAAC;AAAA,MAC1F,KAAK,UAAU;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,GAAG;AAClB,UAAM,KAAK,uBAAuB;AAClC,eAAW,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG;AAC7C,YAAM,KAAK,OAAO,GAAG,OAAO,OAAO,GAAG,SAAS,qBAAqB,GAAG,QAAQ,2BAAsB;AAAA,IACvG;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,mBAAmB,UAAU,MAAM,WAAW,OAAO,WAAW,iBAAiB;AAE5F,MAAI,SAAS,SAAS,MAAM,SAAS,GAAG;AACtC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,qEAAgE,MAAM,MAAM,QAAQ,MAAM,WAAW,IAAI,MAAM,KAAK;AAAA,IACtH;AACA,eAAW,OAAO,MAAO,OAAM,KAAK,KAAK,GAAG,EAAE;AAAA,EAChD,WAAW,SAAS,YAAY,UAAU,GAAG;AAC3C,UAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,aAAa,EAAE,kBAAkB,SAAS,EAAE;AAChG,QAAI,UAAU,GAAG;AACf,YAAM,KAAK,IAAI,IAAI,OAAO,oFAAoF;AAAA,IAChH;AAAA,EACF;AAEA,QAAM,KAAK,IAAI,OAAO,YAAY,gBAAgB,uDAAuD,WAAW,GAAG;AAEvH,SAAO,MAAM,KAAK,IAAI;AACxB;AAIO,IAAM,eAAeC,GAAE,OAAO;AAAA,EACnC,YAAYA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,QAAQ,UAAU,EAC/C,SAAS,+CAA+C;AAAA,EAC3D,MAAMA,GAAE,KAAK,CAAC,UAAU,KAAK,CAAC,EAAE,QAAQ,QAAQ,EAC7C,SAAS,sFAAsF;AACpG,CAAC;AAEM,IAAM,oBAAoBA,GAAE,OAAO;AAAA,EACxC,SAASA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,0DAA0D;AAClG,CAAC;AAOD,eAAsB,kBACpB,QACA,EAAE,YAAY,KAAK,GACnB;AACI,QAAM,cAAc,mBAAmB;AACvC,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,MACL;AAAA,MAGA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,kBAAkBF,SAAQ,aAAa,kBAAkB,CAAC;AAEzE,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,cAAc,UAAU,aAAa,OAAO,IAAI,qBAAqB,WAAW;AAAA,IACtF,QAAQ;AAAA,EACV,CAAC;AAED,QAAM,gBAAgB,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,WAAW,CAAC;AAE1I,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO;AAAA,MACL,wBAAwB,UAAU;AAAA,MAClC;AAAA,MACA,wBAAwB,UAAU;AAAA,MAClC;AAAA,MACA,CAAC,EAAE,MAAM,WAAW,aAAa,oBAAoB,YAAY,CAAC,EAAE,CAAC;AAAA,IACvE;AAAA,EACF;AAEA,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,YAAY,cAAc,MAAM,eAAe,UAAU;AAAA,IAC/D,QAAQ;AAAA,EACV,CAAC;AAGD,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,MAAM;AAAA,MACvB;AAAA,MACA,EAAE,QAAQ,CAAC,SAAS,EAAE;AAAA,IACxB;AACA,kBAAc,IAAI,KAAK,cAAc,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,OAAO,CAAa;AAAA,EAC5F,QAAQ;AACN,kBAAc,IAAI,IAAI,cAAc,IAAI,CAAC,MAAW,EAAE,OAAO,EAAE,OAAO,OAAO,CAAC;AAAA,EAChF;AAEA,QAAM,gBAAgC,CAAC;AACvC,QAAM,YAAwB,CAAC;AAE/B,WAAS,MAAM,GAAG,MAAM,cAAc,QAAQ,OAAO;AACnD,UAAM,QAAQ,cAAc,GAAG;AAE/B,QAAI,MAAM,KAAK,MAAM,OAAO,GAAG;AAC7B,YAAM,OAAO,mBAAmB;AAAA,QAC9B,OAAO;AAAA,QACP,MAAM,WAAW,GAAG,IAAI,cAAc,MAAM;AAAA,QAC5C,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAOA,UAAM,MAAO,MAAM,WAAmC,MAAM;AAC5D,UAAM,QAAQ,MAAM;AAGpB,UAAM,eAAsB,MAAM,MAAM,eAAe,CAAC;AACxD,eAAW,MAAM,cAAc;AAC7B,YAAM,WAAmB,GAAG,SAAS;AACrC,iBAAW,UAAU,eAAe,QAAQ,GAAG;AAC7C,cAAM,UAAU,cAAc,MAAM;AACpC,YAAI,CAAC,QAAS;AAEd,cAAM,OAAO,YAAY,OAAO;AAChC,YAAIG;AACJ,YAAI;AAEJ,YAAI,SAAS,QAAQ;AACnB,WAAC,EAAE,QAAAA,SAAQ,OAAO,IAAI,aAAa,SAAS,WAAW;AAAA,QACzD,WAAW,SAAS,UAAU;AAC5B,WAAC,EAAE,QAAAA,SAAQ,OAAO,IAAI,eAAe,SAAS,MAAM;AAAA,QACtD,OAAO;AACL,UAAAA,UAAS;AACT,mBAAS;AAAA,QACX;AAEA,sBAAc,KAAK;AAAA,UACjB,SAAS;AAAA,UAAK,WAAW;AAAA,UAAO,OAAO,OAAO,KAAK;AAAA,UACnD;AAAA,UAAM,QAAAA;AAAA,UAAQ;AAAA,UAAQ,eAAe,GAAG,UAAU;AAAA,QACpD,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,iBAAiB;AACvB,UAAM,eAAyB,MAAM,MAAM,gBAAgB,CAAC;AAC5D,eAAW,UAAU,cAAc;AACjC,UAAI,UAAU,UAAU,eAAgB;AACxC,gBAAU,KAAK;AAAA,QACb,SAAS;AAAA,QAAK,WAAW;AAAA,QAAO,UAAU;AAAA,QAC1C,OAAO,YAAY,IAAI,MAAM;AAAA,MAC/B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AAGD,QAAM,QAAkB,CAAC;AACzB,QAAM,oBAA+G,CAAC;AAGtH,QAAM,cAA0D,CAAC;AACjE,MAAI,SAAS,OAAO;AAClB,UAAM,iBAAiB,oBAAI,IAAyB;AACpD,eAAW,MAAM,eAAe;AAC9B,UAAI,GAAG,WAAW,aAAa,GAAG,kBAAkB,WAAW;AAC7D,YAAI,CAAC,eAAe,IAAI,GAAG,OAAO,EAAG,gBAAe,IAAI,GAAG,SAAS,oBAAI,IAAI,CAAC;AAC7E,uBAAe,IAAI,GAAG,OAAO,EAAG,IAAI,GAAG,KAAK;AAAA,MAC9C;AAAA,IACF;AAEA,eAAW,CAAC,KAAK,aAAa,KAAK,gBAAgB;AACjD,YAAM,QAAQ,cAAc,KAAK,CAAC,OAAY,EAAE,WAAW,EAAE,UAAU,GAAG;AAC1E,UAAI,CAAC,OAAO,QAAS;AAGrB,YAAM,gBAAgB,MAAM;AAE5B,YAAM,WAAW,MAAM,MAAM,eAAe,CAAC,GAAG;AAAA,QAAI,CAAC,OACnD,GAAG,WAAW,aAAa,cAAc,IAAI,GAAG,KAAK,IACjD,EAAE,GAAG,IAAI,QAAQ,UAAU,IAC3B;AAAA,MACN;AAEA,YAAM,eAAe,MAAM,eAA8D,qBAAqB;AAAA,QAC5G,SAAS;AAAA,QACT,MAAM,EAAE,aAAa,QAAQ;AAAA,MAC/B,CAAC;AAGD,UAAI,aAAa,YAAY,WAAW;AACtC,oBAAY,KAAK;AAAA,UACf,SAAS;AAAA,UACT,QAAQ,aAAa,SAAS,UAAU;AAAA,QAC1C,CAAC;AACD;AAAA,MACF;AACA,UAAI,aAAa,sBAAsB,SAAS,KAAK,aAAa,mBAAmB,SAAS,GAAG;AAC/F,0BAAkB,KAAK;AAAA,UACrB,SAAS;AAAA,UACT,uBAAuB,aAAa;AAAA,UACpC,oBAAoB,aAAa;AAAA,QACnC,CAAC;AAAA,MACH;AACA,YAAM,KAAK,aAAa;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,WAAW,cAAc,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU,EAAE;AACtE,QAAM,UAAU,cAAc,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AACpE,QAAM,eAAe,cAAc,OAAO,CAAC,MAAM,EAAE,WAAW,cAAc,EAAE;AAC9E,QAAM,YAAY,UAAU,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;AACnD,QAAM,aAAa,UAAU,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE;AACrD,QAAM,cAAc,cAAc,SAAS,UAAU;AACrD,QAAM,cAAc,WAAW;AAC/B,QAAM,aAAa,cAAc,IAAI,KAAK,MAAO,cAAc,cAAe,GAAG,IAAI;AAErF,QAAM,SAAS;AAAA,IACb;AAAA,IAAY,cAAc;AAAA,IAC1B;AAAA,IAAe;AAAA,IAAW;AAAA,IAAO;AAAA,IACjC,OAAO;AAAA,IAAM;AAAA,EACf;AAEA,MAAI,aAAa;AACjB,MAAI,YAAY,SAAS,GAAG;AAC1B,kBAAc;AACd,eAAW,KAAK,aAAa;AAC3B,oBAAc;AAAA,QAAW,EAAE,OAAO,OAAO,EAAE,MAAM;AAAA,IACnD;AAAA,EACF;AACA,MAAI,kBAAkB,SAAS,GAAG;AAChC,kBAAc;AACd,eAAW,KAAK,mBAAmB;AACjC,iBAAW,MAAM,EAAE,uBAAuB;AACxC,sBAAc;AAAA,QAAW,EAAE,OAAO,uBAAuB,EAAE;AAAA,MAC7D;AACA,iBAAW,MAAM,EAAE,oBAAoB;AACrC,sBAAc;AAAA,QAAW,EAAE,OAAO,oBAAoB,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,CAAC;AAAA,IACrD,mBAAmB;AAAA,MACjB,oBAAoB,UAAU,KAAK,WAAW,IAAI,WAAW,mBAAmB,UAAU;AAAA,MAC1F;AAAA,QACE;AAAA,QACA,YAAY,cAAc;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,MAAM;AAAA,QACpB,GAAI,YAAY,SAAS,IAAI,EAAE,cAAc,YAAY,QAAQ,mBAAmB,YAAY,IAAI,CAAC;AAAA,QACrG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACN;AAWA,eAAsB,kBAAkB,EAAE,QAAQ,GAA2D;AAC3G,QAAM,iBAAiB,kBAAkB;AACzC,QAAMA,UAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,MACE;AAAA,MACA,GAAI,iBAAiB,EAAE,WAAW,eAAe,IAAI,CAAC;AAAA,IACxD;AAAA,EACF;AAaA,QAAM,QAAQA,QAAO,aAAa;AAClC,QAAM,WAAWA,QAAO,aAAa;AACrC,QAAM,mBAAmBA,QAAO,aAC5B,SAAS,UAAU,aACjB,KAAKA,QAAO,UAAU,MACtB,cAASA,QAAO,UAAU,GAAG,WAAW,KAAK,QAAQ,MAAM,EAAE,KAC/D;AACJ,QAAM,UAAUA,QAAO,kBACnB,SAAS,OAAO,uBAAuB,gBAAgB,MACvD,SAAS,OAAO,YAAY,gBAAgB;AAKhD,SAAO,cAAc,SAAS,SAASA,OAAM;AAC/C;;;AEtfA,SAAS,KAAAC,UAAS;AAIX,IAAM,kBAAkBC,GAAE,OAAO;AAAA,EACtC,SAASA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,EACpE,cAAcA,GAAE,OAAO,EAAE,SAAS,0DAA0D;AAC9F,CAAC;AAED,eAAsB,gBAAgB,SAAiB,cAAsB;AAC3E,MAAI;AACF,UAAM,YAAY,kBAAkB;AACpC,UAAMC,UAAS,MAAM,eAAmE,0BAA0B;AAAA,MAChH;AAAA,MACA,kBAAkB;AAAA,MAClB,WAAW,YAAY,SAAS,SAAS,KAAK;AAAA,IAChD,CAAC;AACD,QAAIA,QAAO,YAAY,WAAW;AAChC,YAAM,WAAWA,QAAO,QAAQ,kBAAkB;AAClD,aAAO;AAAA,QACL,sBAAsB,OAAO;AAAA;AAAA,EAAUA,QAAO,QAAQ,MAAM;AAAA;AAAA,EAAO,QAAQ;AAAA,QAC3E;AAAA,QACAA,QAAO,QAAQ;AAAA,QACf;AAAA,QACA;AAAA,QACA,EAAE,SAAS,cAAc,SAASA,QAAO,QAAQ;AAAA,MACnD;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA,WAAWA,QAAO,OAAO,aAAaA,QAAO,cAAc,eAAUA,QAAO,YAAY;AAAA,IAC1F;AACA,QAAIA,QAAO,qBAAqB;AAC9B,YAAM,KAAK,IAAI,kCAAwBA,QAAO,sBAAsB,qDAAqD;AAAA,IAC3H;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC3D,mBAAmB;AAAA,QACjB,SAASA,QAAO,OAAO,SAASA,QAAO,cAAc,OAAOA,QAAO,YAAY;AAAA,QAC/EA;AAAA,QACA;AAAA,UACE,EAAE,MAAM,WAAW,aAAa,sBAAsB,YAAY,EAAE,QAAQ,OAAO,QAAQ,EAAE;AAAA,UAC7F,EAAE,MAAM,WAAW,aAAa,oBAAoB,YAAY,EAAE,QAAQ,SAAS,QAAQ,EAAE;AAAA,QAC/F;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAgB;AACvB,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,QAAI,IAAI,SAAS,WAAW,GAAG;AAC7B,aAAO,eAAe,SAAS,yBAAyB,GAAG,EAAE;AAAA,IAC/D;AACA,WAAO;AAAA,MACL,oBAAoB,OAAO,WAAW,YAAY,OAAO,GAAG;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,EAAE,MAAM,WAAW,aAAa,oBAAoB,YAAY,EAAE,QAAQ,UAAU,OAAO,QAAQ,EAAE,CAAC;AAAA,IACzG;AAAA,EACF;AACF;;;A9BpCA,SAAS,kBAAkB,MAAoD;AAC7E,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,WAAW,OAAO;AAAA,IACtB,OAAO,QAAQ,IAA+B,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,WAAW,GAAG,CAAC;AAAA,EACxF;AACA,SAAO,OAAO,KAAK,QAAQ,EAAE,SAAS,IAAI,WAAW;AACvD;AAyBO,SAAS,cAAc,GAI5B;AACA,QAAM,MAAM,OAAO,EAAE,QAAQ,WAAW,EAAE,MAAM;AAChD,MAAI,EAAE,eAAe,WAAW;AAC9B,WAAO,EAAE,MAAM,2CAAsC,KAAK,cAAc,KAAK;AAAA,EAC/E;AACA,MAAI,IAAI,SAAS,GAAG;AAClB,UAAM,SAAS,EAAE,eAAe,aAAa,gBAAgB;AAC7D,UAAM,IAAK,EAAE,QAAQ,CAAC;AAGtB,QAAI,eAA8B;AAClC,UAAM,KAAK,EAAE;AACb,SAAK,OAAO,eAAe,OAAO,kBAAkB,OAAO,EAAE,EAAE,MAAM,YAAa,EAAE,EAAE,EAAa,KAAK,EAAE,SAAS,GAAG;AACpH,qBAAe;AAAA,IACjB,WAAW,OAAO,EAAE,cAAc,YAAY,EAAE,UAAU,KAAK,EAAE,SAAS,GAAG;AAC3E,qBAAe;AAAA,IACjB;AACA,WAAO,EAAE,MAAM,YAAY,GAAG,GAAG,MAAM,IAAI,KAAK,aAAa;AAAA,EAC/D;AACA,SAAO,EAAE,MAAM,MAAM,KAAK,cAAc,KAAK;AAC/C;AAUO,SAAS,uBAAuB,GAA2C;AAChF,MAAI,CAAC,EAAE,mBAAoB,QAAO;AAClC,QAAM,aAAa,OAAO,EAAE,eAAe,WAAW,EAAE,aAAa;AACrE,QAAM,cAAc,EAAE,eAAe,OAAO,EAAE,gBAAgB,WACzD,EAAE,cACH;AACJ,QAAM,WAAW,eAAe,OAAO,YAAY,aAAa,WAAW,YAAY,WAAW;AAClG,QAAM,QAAQ,eAAe,OAAO,YAAY,UAAU,WAAW,YAAY,QAAQ;AAEzF,MAAI;AACJ,MAAI,SAAS,UAAU,YAAY;AACjC,UAAM,aAAa,KAAK,UAAU,MAAM;AAAA,EAC1C,OAAO;AACL,UAAM,aAAa,cAAS,UAAU,GAAG,WAAW,KAAK,QAAQ,MAAM,EAAE,KAAK;AAAA,EAChF;AACA,SAAO,qBAAqB,OAAO,EAAE,kBAAkB,CAAC,GAAG,GAAG;AAChE;AAMA,IAAM,kBAAkB;AAAA,EACtB;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EAAU;AAAA,EAAW;AAAA,EAAQ;AAC3E;AAGA,IAAM,4BAA4BC,IAAE,MAAM,CAACA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAGA,IAAE,MAAMA,IAAE,KAAK,CAAC,SAAS,UAAU,YAAY,cAAc,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAClJ,IAAM,qCAAqCA,IAAE,OAAO;AAAA,EAClD,UAAUA,IAAE,KAAK,CAAC,UAAU,gBAAgB,UAAU,CAAC,EAAE,SAAS,mEAAmE;AAAA,EACrI,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,qFAAqF;AAAA,EACtI,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,iEAA4D;AAC/G,CAAC;AAYM,IAAM,gBAAgBA,IAAE,OAAO;AAAA,EACpC,QAAQA,IAAE,KAAK,eAAe,EAAE;AAAA,IAC9B;AAAA,EAKF;AAAA,EACA,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EACA,UAAUA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAC5D,SAAS,6DAA6D;AAAA,EACzE,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACtC,SAAS,+FAA0F;AAAA,EACtG,QAAQ,0BAA0B,SAAS,EACxC;AAAA,IACC;AAAA,EAEwG;AAAA,EAC5G,KAAKA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EAClF,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,iFAA4E;AAAA,EAC3H,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,EACrG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,EAC/E,gBAAgBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IAC7C;AAAA,EAEF;AAAA,EACA,MAAMA,IAAE,OAAOA,IAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,EAC7G,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EACrE,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IAC3C;AAAA,EACF;AAAA,EACA,aAAaA,IAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK,EAAE;AAAA,IACjD;AAAA,EACF;AAAA,EACA,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE;AAAA,IAC1C;AAAA,EACF;AAAA,EACA,WAAWA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE;AAAA,IACzC;AAAA,EACF;AAAA,EACA,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE;AAAA,IAC7C;AAAA,EACF;AAAA,EACA,wBAAwBA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE;AAAA,IACtD;AAAA,EACF;AAAA,EACA,0BAA0B,mCAAmC,SAAS,EAAE;AAAA,IACtE;AAAA,EACF;AAAA,EACA,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE;AAAA,IAC9B;AAAA,EACF;AAAA,EACA,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAC/H,CAAC;AAOD,IAAM,qBAAqBA,IAAE,OAAO;AAAA,EAClC,QAAQA,IAAE,QAAQ,MAAM;AAAA,EACxB,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACrC,KAAKA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAClC,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACtC,CAAC;AACD,IAAM,oBAAoBA,IAAE,OAAO;AAAA,EACjC,QAAQA,IAAE,QAAQ,KAAK;AAAA,EACvB,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAC7B,CAAC;AACD,IAAM,sBAAsBA,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,QAAQ,OAAO;AAAA,EACzB,UAAUA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AACtD,CAAC;AACD,IAAM,uBAAuBA,IAAE,OAAO;AAAA,EACpC,QAAQA,IAAE,QAAQ,QAAQ;AAAA,EAC1B,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAChC,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,QAAQ,0BAA0B,SAAS;AAAA;AAC7C,CAAC;AACD,IAAM,uBAAuB,kBAAkB,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AACrF,IAAM,uBAAuB,kBAAkB,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AACrF,IAAM,wBAAwB,iBAAiB,OAAO,EAAE,QAAQA,IAAE,QAAQ,SAAS,EAAE,CAAC;AACtF,IAAM,qBAAqBA,IAAE,OAAO;AAAA,EAClC,QAAQA,IAAE,QAAQ,MAAM;AAAA,EACxB,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG;AAClC,CAAC;AACD,IAAM,uBAAuB,kBAAkB,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AAE9E,IAAM,qBAAqBA,IAAE,mBAAmB,UAAU;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,uBAA+D;AAAA,EAC1E,MAAM,EAAE,QAAQ,CAAC,cAAc,UAAU,OAAO,OAAO,GAAG,aAAa,uCAAuC;AAAA,EAC9G,KAAK,EAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,yBAAyB;AAAA,EAClE,OAAO,EAAE,QAAQ,CAAC,UAAU,GAAG,aAAa,gCAAgC;AAAA,EAC5E,QAAQ,EAAE,QAAQ,CAAC,SAAS,cAAc,QAAQ,GAAG,aAAa,qDAAqD;AAAA,EACvH,QAAQ,EAAE,QAAQ,CAAC,WAAW,QAAQ,UAAU,kBAAkB,QAAQ,SAAS,gBAAgB,eAAe,cAAc,aAAa,iBAAiB,0BAA0B,0BAA0B,GAAG,aAAa,sDAAsD;AAAA,EACxR,QAAQ,EAAE,QAAQ,CAAC,WAAW,WAAW,0BAA0B,0BAA0B,GAAG,aAAa,uBAAuB;AAAA,EACpI,SAAS,EAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,uBAAuB;AAAA,EACpE,MAAM,EAAE,QAAQ,CAAC,WAAW,cAAc,GAAG,aAAa,8CAA8C;AAAA,EACxG,QAAQ,EAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,uBAAuB;AACrE;AAEO,IAAM,yBAAyBA,IAAE,OAAO;AAAA,EAC7C,SAASA,IAAE,OAAO;AAAA,EAClB,MAAMA,IAAE,OAAO;AAAA,EACf,YAAYA,IAAE,OAAO;AAAA,EACrB,QAAQA,IAAE,OAAO;AAAA,EACjB,YAAYA,IAAE,OAAO,EAAE,SAAS;AAAA,EAChC,QAAQA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,cAAcA,IAAE,OAAO,EAAE,SAAS;AAAA,EAClC,oBAAoBA,IAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASxC,YAAYA,IAAE,OAAO,EAAE,SAAS;AAAA,EAChC,aAAaA,IAAE,OAAO;AAAA,IACpB,UAAUA,IAAE,KAAK,CAAC,gBAAgB,aAAa,UAAU,YAAY,CAAC;AAAA,IACtE,OAAOA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,CAAC,EAAE,SAAS;AAAA,EACZ,WAAWA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,eAAeA,IAAE,OAAO,EAAE,SAAS;AAAA,EACnC,KAAKA,IAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAEzB,YAAYA,IAAE,KAAK,CAAC,aAAa,WAAW,UAAU,CAAC,EAAE,SAAS;AAAA,EAClE,MAAMA,IAAE,OAAOA,IAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrC,WAAWA,IAAE,MAAMA,IAAE,OAAO;AAAA,IAC1B,SAASA,IAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,MAAMA,IAAE,OAAO;AAAA,IACf,MAAMA,IAAE,OAAO;AAAA,IACf,WAAWA,IAAE,OAAO;AAAA,EACtB,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,QAAQA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,SAAS;AACvC,CAAC,EAAE,YAAY;AAER,IAAM,0BAA0BA,IAAE,OAAO;AAAA,EAC9C,SAASA,IAAE,MAAMA,IAAE,OAAO;AAAA,IACxB,SAASA,IAAE,OAAO;AAAA,IAClB,MAAMA,IAAE,OAAO;AAAA,IACf,YAAYA,IAAE,OAAO;AAAA,IACrB,QAAQA,IAAE,OAAO;AAAA,EACnB,CAAC,CAAC;AAAA,EACF,OAAOA,IAAE,OAAO;AAClB,CAAC;AAEM,IAAM,4BAA4BA,IAAE,OAAO;AAAA,EAChD,SAASA,IAAE,MAAMA,IAAE,OAAO;AAAA,IACxB,SAASA,IAAE,OAAO;AAAA,IAClB,MAAMA,IAAE,OAAO;AAAA,IACf,YAAYA,IAAE,OAAO;AAAA,IACrB,QAAQA,IAAE,OAAO;AAAA,IACjB,OAAOA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,CAAC,CAAC;AAAA,EACF,OAAOA,IAAE,OAAO;AAAA,EAChB,OAAOA,IAAE,OAAO;AAClB,CAAC;AAEM,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EAC/C,SAASA,IAAE,MAAMA,IAAE,OAAO;AAAA,IACxB,SAASA,IAAE,OAAO;AAAA,IAClB,MAAMA,IAAE,OAAO;AAAA,IACf,YAAYA,IAAE,OAAO;AAAA,IACrB,QAAQA,IAAE,OAAO;AAAA,IACjB,YAAYA,IAAE,OAAO,EAAE,SAAS;AAAA,IAChC,QAAQA,IAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,cAAcA,IAAE,OAAO,EAAE,SAAS;AAAA,IAClC,oBAAoBA,IAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,IAKxC,YAAYA,IAAE,OAAO,EAAE,SAAS;AAAA,IAChC,aAAaA,IAAE,OAAO;AAAA,MACpB,UAAUA,IAAE,KAAK,CAAC,gBAAgB,aAAa,UAAU,YAAY,CAAC;AAAA,MACtE,OAAOA,IAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,CAAC,EAAE,SAAS;AAAA,IACZ,WAAWA,IAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,eAAeA,IAAE,OAAO,EAAE,SAAS;AAAA;AAAA,IAEnC,KAAKA,IAAE,OAAO,EAAE,SAAS;AAAA,IACzB,YAAYA,IAAE,KAAK,CAAC,aAAa,WAAW,UAAU,CAAC,EAAE,SAAS;AAAA,IAClE,MAAMA,IAAE,OAAOA,IAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACvC,CAAC,EAAE,YAAY,CAAC;AAAA,EAChB,OAAOA,IAAE,OAAO;AAClB,CAAC;AAEM,SAAS,qBAAqB,QAAyB;AAM5D,QAAM,kBAA6E;AAAA,IACjF,MAAM,CAAC,SAAS,WAAW,KAAK,YAAY,KAAK,QAAQ,KAAK,KAAK,KAAK,KAAK;AAAA,IAC7E,KAAK,CAAC,SAAS,UAAU,KAAK,OAAO;AAAA,IACrC,OAAO,CAAC,SAAS,YAAY,KAAK,QAAQ;AAAA,IAC1C,QAAQ,CAAC,SAAS,aAAa,QAAQ,KAAK,OAAO,KAAK,YAAY,KAAK,MAAM;AAAA;AAAA;AAAA,IAG/E,QAAQ,CAAC,SAAS,kBAAkB,MAAM,SAAS;AAAA,IACnD,QAAQ,CAAC,SAAS,kBAAkB,MAAM,SAAS;AAAA,IACnD,SAAS,CAAC,SAAS,iBAAiB,IAAI;AAAA,IACxC,MAAM,CAAC,SAAS,gBAAgB,KAAK,SAAS,KAAK,YAAY;AAAA,IAC/D,QAAQ,CAAC,SAAS,kBAAkB,IAAI;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAWF,aAAa;AAAA;AAAA;AAAA,MAGb,aAAa,EAAE,cAAc,OAAO,iBAAiB,MAAM,gBAAgB,OAAO,eAAe,MAAM;AAAA,IACzG;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,eAAe,IAAI;AAC9C,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,WAAW,OAAO;AAAA,QAAG,MACrD,sBAAsB,WAAW,oBAAoB,OAAO,MAAM,sBAAsB,eAAe;AAAA,MACzG;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,UAAU,SAAiB;AACxC,QAAM,QAAQ,MAAM,YAAqB,kBAAkB,EAAE,QAAQ,CAAC;AAEtE,MAAI,CAAC,OAAO;AACV,WAAO,eAAe,SAAS,UAAU,OAAO,+CAA+C;AAAA,EACjG;AAEA,QAAM,IAAI;AACV,QAAM,YAAY,sBAAsB,iBAAiB,CAAC,CAAC;AAE3D,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,KAAK,EAAE,UAAU,GAAG,EAAE,OAAO,OAAO,EAAE,GAAG,EAAE,IAAI;AAAA,IAC/C;AAAA,IACA,eAAe,EAAE,MAAM,GAAG,EAAE,iBAAiB,MAAM,EAAE,cAAc,KAAK,EAAE;AAAA,IAC1E,aAAa,EAAE,gBAAgB,SAAS;AAAA,EAC1C;AAGA,MAAI,OAAO,EAAE,eAAe,SAAU,OAAM,KAAK,oBAAoB,IAAI,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE;AAC3G,MAAI,EAAE,QAAQ;AACZ,UAAM,SAAS,EAAE,eAAe,KAAK,EAAE,YAAY,MAAM;AACzD,UAAM,KAAK,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE;AAAA,EAC/C;AACA,QAAM,mBAAmB,uBAAuB,CAAC;AACjD,MAAI,iBAAkB,OAAM,KAAK,gBAAgB;AACjD,MAAI,EAAE,UAAW,OAAM,KAAK,mBAAmB,EAAE,SAAS,EAAE;AAC5D,MAAI,EAAE,cAAe,OAAM,KAAK,uBAAuB,EAAE,aAAa,EAAE;AAExE,MAAI,WAAW;AACb,UAAM,KAAK,oBAAoB,SAAS,CAAC;AAAA,EAC3C;AAKA,QAAM,EAAE,MAAM,SAAS,KAAK,aAAa,IAAI,cAAc,CAAC;AAC5D,MAAI,YAAY,KAAM,OAAM,KAAK,OAAO;AAExC,QAAM,cAAc,kBAAkB,EAAE,IAAI;AAS5C,QAAM,eAAe,eAAe,eAC/B,OAAO,KAAK,WAAW,EAAE,OAAO,CAAC,MAAM,MAAM,YAAY,EAAE,SAAS,IACjE,OAAO,YAAY,OAAO,QAAQ,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,YAAY,CAAC,IAClF,SACJ;AACJ,MAAI,cAAc;AAChB,UAAM,KAAK,EAAE;AACb,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,YAAY,GAAG;AACrD,YAAM,UAAU,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG;AAClE,YAAM,KAAK,KAAK,GAAG,OAAO,OAAO,EAAE;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,EAAE,IAAI,KAAK,EAAE,KAAK,SAAS,GAAG;AAC9C,UAAM,KAAK,IAAI,aAAc,EAAE,KAAkB,KAAK,IAAI,CAAC,EAAE;AAAA,EAC/D;AAEA,MAAI,MAAM,QAAQ,EAAE,MAAM,KAAM,EAAE,OAAqB,SAAS,GAAG;AACjE,UAAM,SAAS,EAAE;AACjB,UAAM,KAAK,IAAI,eAAe,OAAO,IAAI,CAAC,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACzF;AAEA,MAAI,MAAM,QAAQ,EAAE,SAAS,KAAM,EAAE,UAAwB,SAAS,GAAG;AACvE,UAAM,KAAK,IAAI,cAAc;AAC7B,eAAW,KAAK,EAAE,WAAiG;AACjH,YAAM,QAAQ,EAAE,cAAc,aAAa,WAAW;AACtD,YAAM,QAAQ,EAAE,eAAe,GAAG,EAAE,YAAY,KAAK,EAAE,SAAS,KAAM,EAAE,aAAa;AACrF,YAAM,KAAK,KAAK,KAAK,MAAM,EAAE,IAAI,MAAM,KAAK,EAAE;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,EAAE,OAAO,KAAM,EAAE,QAAsB,SAAS,GAAG;AACnE,UAAM,KAAK,IAAI,sBAAsB;AAGrC,eAAW,KAAM,EAAE,QAAiG,MAAM,GAAG,GAAG;AAC9H,YAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7D,YAAM,YAAY,EAAE,kBAAkB,KAAK,EAAE,eAAe,MAAM;AAClE,YAAM,KAAK,KAAK,IAAI,KAAK,EAAE,KAAK,GAAG,EAAE,YAAY,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,EAAE;AAAA,IAC3F;AAAA,EACF;AAEA,QAAM,YAAY;AAAA,IAChB,SAAS,OAAO,EAAE,WAAW,EAAE;AAAA,IAC/B,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,IACzB,YAAY,OAAO,EAAE,gBAAgB,EAAE;AAAA,IACvC,QAAQ,OAAO,EAAE,UAAU,EAAE;AAAA,IAC7B,GAAI,OAAO,EAAE,eAAe,WAAW,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACvE,GAAI,EAAE,iBAAiB,EAAE,gBAAgB,OAAO,EAAE,cAAc,EAAE,IAAI,CAAC;AAAA,IACvE,GAAI,YAAY,EAAE,iBAAiB,UAAU,IAAI,CAAC;AAAA;AAAA,IAElD,GAAI,EAAE,SAAS,EAAE,QAAQ,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC;AAAA,IAC/C,GAAI,EAAE,eAAe,EAAE,cAAc,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC;AAAA,IACjE,GAAI,EAAE,qBAAqB,EAAE,oBAAoB,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,IAInF,GAAI,OAAO,EAAE,eAAe,WAAW,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACvE,GAAI,EAAE,eAAe,OAAO,EAAE,gBAAgB,WAAW,EAAE,aAAa,EAAE,YAAoD,IAAI,CAAC;AAAA,IACnI,GAAI,EAAE,YAAY,EAAE,WAAW,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC;AAAA,IACxD,GAAI,EAAE,gBAAgB,EAAE,eAAe,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC;AAAA;AAAA,IAEpE,GAAI,IAAI,SAAS,IAAI,EAAE,IAAI,IAAI,CAAC;AAAA,IAChC,GAAI,EAAE,aAAa,EAAE,YAAY,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC;AAAA,IAC3D,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,GAAI,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,IAAI,CAAC,GAAI,gBAAgB,OAAQ,EAAkC,kBAAkB,EAAE,gBAAgB,QAAG,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOvO,GAAI,eAAe,EAAE,MAAM,aAAa,IAAI,CAAC;AAAA,IAC7C,GAAI,MAAM,QAAQ,EAAE,SAAS,KAAM,EAAE,UAAwB,SAAS,IAClE;AAAA,MACE,WAAY,EAAE,UAAiG,IAAI,CAAC,OAAO;AAAA,QACzH,GAAI,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,IAAI,CAAC;AAAA,QACpD,MAAM,EAAE,aAAa;AAAA,QACrB,MAAM,EAAE,QAAQ;AAAA,QAChB,WAAW,EAAE,aAAa;AAAA,MAC5B,EAAE;AAAA,IACJ,IACA,CAAC;AAAA,IACL,GAAI,MAAM,QAAQ,EAAE,MAAM,KAAM,EAAE,OAAqB,SAAS,IAC5D,EAAE,QAAS,EAAE,OAA8C,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,IAC9F,CAAC;AAAA,EACP;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,SAAS,OAAO,KAAK,OAAO,EAAE,IAAI,CAAC,KAAK,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAAA,MACpE;AAAA,MACA;AAAA,QACE,EAAE,MAAM,aAAa,aAAa,uBAAuB,YAAY,EAAE,QAAQ,WAAW,QAAQ,EAAE;AAAA,QACpG,EAAE,MAAM,WAAW,aAAa,0BAA0B,YAAY,EAAE,QAAQ,UAAU,QAAQ,EAAE;AAAA,MACtG;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,YAAY,UAAoB;AAC7C,QAAM,UAAU,MAAM,YAA+D,yBAAyB,EAAE,SAAS,CAAC;AAE1H,QAAM,QAAkB,CAAC,mBAAmB,IAAI,gBAAgB,QAAQ,MAAM,eAAe,EAAE;AAE/F,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,IAAI,QAAQ,CAAC;AACnB,UAAM,cAAc,SAAS,CAAC;AAC9B,QAAI,EAAE,OAAO;AACX,YAAM,KAAK,MAAM,WAAW;AAAA;AAAA,aAAkB,EAAE,KAAK;AAAA,CAAI;AACzD;AAAA,IACF;AACA,UAAM,QAAQ,EAAE;AAChB,UAAM,KAAK,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,OAAO,EAAE,GAAG,MAAM,IAAI,EAAE;AACzE,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,eAAe,MAAM,MAAM,GAAG,MAAM,iBAAiB,MAAM,MAAM,cAAc,KAAK,EAAE,EAAE;AACnG,UAAM,KAAK,aAAa,MAAM,gBAAgB,SAAS,EAAE;AACzD,QAAI,OAAO,MAAM,eAAe,UAAU;AACxC,YAAM,KAAK,oBAAoB,IAAI,KAAK,MAAM,UAAU,EAAE,YAAY,CAAC,EAAE;AAAA,IAC3E;AACA,QAAI,MAAM,QAAQ;AAChB,YAAM,SAAS,MAAM,eAAe,KAAK,MAAM,YAAY,MAAM;AACjE,YAAM,KAAK,eAAe,MAAM,MAAM,GAAG,MAAM,EAAE;AAAA,IACnD;AACA,UAAM,wBAAwB,uBAAuB,KAAK;AAC1D,QAAI,sBAAuB,OAAM,KAAK,qBAAqB;AAC3D,QAAI,MAAM,WAAW;AACnB,YAAM,KAAK,mBAAmB,MAAM,SAAS,EAAE;AAAA,IACjD;AACA,QAAI,MAAM,eAAe;AACvB,YAAM,KAAK,uBAAuB,MAAM,aAAa,EAAE;AAAA,IACzD;AAMA,UAAM,EAAE,MAAM,SAAS,aAAa,IAAI,cAAc,KAAK;AAC3D,QAAI,YAAY,KAAM,OAAM,KAAK,OAAO;AAExC,UAAM,cAAc,kBAAkB,MAAM,IAAI;AAGhD,UAAM,eAAe,eAAe,eAC/B,OAAO,KAAK,WAAW,EAAE,OAAO,CAAC,MAAM,MAAM,YAAY,EAAE,SAAS,IACjE,OAAO,YAAY,OAAO,QAAQ,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,YAAY,CAAC,IAClF,SACJ;AACJ,QAAI,cAAc;AAChB,YAAM,KAAK,EAAE;AACb,iBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,YAAY,GAAG;AACrD,cAAM,UAAU,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG;AAClE,cAAM,KAAK,KAAK,GAAG,OAAO,OAAO,EAAE;AAAA,MACrC;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,SAAS,GAAG;AACtD,YAAM,KAAK,IAAI,aAAc,MAAM,KAAkB,KAAK,IAAI,CAAC,EAAE;AAAA,IACnE;AAEA,QAAI,MAAM,QAAQ,MAAM,MAAM,KAAM,MAAM,OAAqB,SAAS,GAAG;AACzE,YAAM,SAAS,MAAM;AACrB,YAAM,KAAK,IAAI,eAAe,OAAO,IAAI,CAAC,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,IACzF;AAEA,QAAI,MAAM,QAAQ,MAAM,SAAS,KAAM,MAAM,UAAwB,SAAS,GAAG;AAC/E,YAAM,KAAK,IAAI,gBAAgB;AAC/B,iBAAW,OAAO,MAAM,WAAiG;AACvH,cAAM,MAAM,IAAI,cAAc,aAAa,WAAM;AACjD,cAAM,QAAQ,IAAI,gBAAgB,IAAI,aAAa;AACnD,cAAM,KAAK,KAAK,GAAG,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;AAAA,MAC9C;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,MAAM,OAAO,KAAM,MAAM,QAAsB,SAAS,GAAG;AAC3E,YAAM,KAAK,IAAI,uBAAuB;AACtC,iBAAW,KAAM,MAAM,QAAmD,MAAM,EAAE,GAAG;AACnF,cAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7D,cAAM,KAAK,KAAK,IAAI,KAAK,EAAE,KAAK,EAAE;AAAA,MACpC;AAAA,IACF;AAEA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,oBAAoB,QACvB,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EACjC,IAAI,CAAC,MAAM;AACV,UAAM,QAAQ,EAAE;AAGhB,UAAM,EAAE,KAAK,UAAU,cAAc,kBAAkB,IAAI,cAAc,KAAK;AAC9E,UAAM,mBAAmB,kBAAkB,MAAM,IAAI;AACrD,UAAM,oBAAoB,oBAAoB,oBACzC,OAAO,KAAK,gBAAgB,EAAE,OAAO,CAAC,MAAM,MAAM,iBAAiB,EAAE,SAAS,IAC3E,OAAO,YAAY,OAAO,QAAQ,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,iBAAiB,CAAC,IAC5F,SACJ;AACJ,WAAO;AAAA,MACL,SAAS,OAAO,MAAM,WAAW,EAAE;AAAA,MACnC,MAAM,OAAO,MAAM,QAAQ,EAAE;AAAA,MAC7B,YAAY,OAAO,MAAM,gBAAgB,EAAE;AAAA,MAC3C,QAAQ,OAAO,MAAM,UAAU,EAAE;AAAA,MACjC,GAAI,OAAO,MAAM,eAAe,WAAW,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,MAC/E,GAAI,MAAM,SAAS,EAAE,QAAQ,OAAO,MAAM,MAAM,EAAE,IAAI,CAAC;AAAA,MACvD,GAAI,MAAM,eAAe,EAAE,cAAc,OAAO,MAAM,YAAY,EAAE,IAAI,CAAC;AAAA,MACzE,GAAI,MAAM,qBAAqB,EAAE,oBAAoB,OAAO,MAAM,kBAAkB,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA,MAG3F,GAAI,OAAO,MAAM,eAAe,WAAW,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,MAC/E,GAAI,MAAM,eAAe,OAAO,MAAM,gBAAgB,WAAW,EAAE,aAAa,MAAM,YAAoD,IAAI,CAAC;AAAA,MAC/I,GAAI,MAAM,YAAY,EAAE,WAAW,OAAO,MAAM,SAAS,EAAE,IAAI,CAAC;AAAA,MAChE,GAAI,MAAM,gBAAgB,EAAE,eAAe,OAAO,MAAM,aAAa,EAAE,IAAI,CAAC;AAAA,MAC5E,GAAI,MAAM,iBAAiB,EAAE,gBAAgB,OAAO,MAAM,cAAc,EAAE,IAAI,CAAC;AAAA;AAAA,MAE/E,GAAI,SAAS,SAAS,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC;AAAA,MAC/C,GAAI,MAAM,aAAa,EAAE,YAAY,OAAO,MAAM,UAAU,EAAE,IAAI,CAAC;AAAA,MACnE,GAAI,oBAAoB,EAAE,MAAM,kBAAkB,IAAI,CAAC;AAAA,IACzD;AAAA,EACF,CAAC;AAEH,QAAM,QAAQ,kBAAkB;AAChC,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB,QAAQ,WAAW,KAAK,sBAAsB,EAAE,SAAS,mBAAmB,MAAM,CAAC;AAAA,EACxG;AACF;AAEA,eAAe,WAAW,YAAqBC,SAAiB,KAAc,OAAgB;AAC5F,MAAI;AAEJ,MAAI,OAAO;AACT,cAAU,MAAM,YAAkE,4BAA4B,EAAE,WAAW,MAAM,CAAC;AAClI,QAAIA,SAAQ;AACV,gBAAW,QAAkC,OAAO,CAAC,MAAM,EAAE,WAAWA,OAAM;AAAA,IAChF;AAAA,EACF,OAAO;AACL,cAAU,MAAM,YAA2D,qBAAqB;AAAA,MAC9F,gBAAgB;AAAA,MAChB,QAAAA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sCAAsC,CAAC;AAAA,MAChF,mBAAmB;AAAA,QACjB;AAAA,QACA,EAAE,SAAS,CAAC,GAAG,OAAO,EAAE;AAAA,QACxB,CAAC,EAAE,MAAM,eAAe,aAAa,oBAAoB,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,MAC3F;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAa,QAChB,IAAI,CAAC,MAAM;AACV,UAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,UAAM,gBAAgB,EAAE,iBAAiB,GAAG,EAAE,MAAM,MAAM,EAAE,cAAc,KAAK,EAAE;AACjF,UAAM,cAAc,kBAAkB,EAAE,IAAI;AAC5C,UAAM,cAAc,cAChB,OAAO,QAAQ,WAAW,EACvB,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,OAAO,MAAM,WAAW,EAAE,UAAU,GAAG,GAAG,IAAI,KAAK,UAAU,CAAC,CAAC,EAAE,EAC5F,KAAK,IAAI,IACZ;AACJ,WAAO,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,aAAa,KAAK,cAAc;AAAA,EAAK,WAAW,KAAK,EAAE;AAAA,EACtF,CAAC,EACA,KAAK,MAAM;AAEd,QAAM,QAAQ,aAAa,SAAS,UAAU,OAAO;AAErD,QAAM,oBAAqB,QAAmH,IAAI,CAAC,OAAO;AAAA,IACxJ,SAAS,OAAO,EAAE,WAAW,EAAE;AAAA,IAC/B,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,IACzB,YAAY,OAAO,EAAE,gBAAgB,cAAc,EAAE;AAAA,IACrD,QAAQ,OAAO,EAAE,UAAU,EAAE;AAAA,IAC7B,GAAI,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,IAAI,CAAC;AAAA,EACjE,EAAE;AAEF,QAAM,QAAQ,kBAAkB;AAChC,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA,WAA8B,KAAK,KAAK,QAAQ,MAAM;AAAA;AAAA,EAAQ,SAAS,GAAG,CAAC;AAAA,IACpH,mBAAmB,QAAQ,SAAS,KAAK,WAAW,KAAK,KAAK,EAAE,SAAS,mBAAmB,MAAM,CAAC;AAAA,EACrG;AACF;AAEA,eAAe,aACb,QACA,OACA,YACAA,SACA;AACA,QAAM,QAAQ,aAAa,SAAS,UAAU,OAAO;AACrD,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,YAAY,KAAK,SAAS,KAAK;AAAA,IACrC,QAAQ;AAAA,EACV,CAAC;AAED,QAAM,CAAC,SAAS,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC/C,YAA6D,uBAAuB,EAAE,OAAO,gBAAgB,YAAY,QAAAA,QAAO,CAAC;AAAA,IACjI,YAAuB,uBAAuB;AAAA,EAChD,CAAC;AAED,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,WAAW,UAAU,EAAE,OAAO,MAAM,WAAW,QAAQ,UAAU,SAAS,eAAe,iBAAiB,WAAW,CAAC;AAC5H,QAAI,UAAU;AACZ,qBAAe,EACZ,KAAK,CAAC,SAAS,kBAAkB,MAAM,EAAE,OAAO,MAAM,WAAW,QAAQ,UAAU,UAAU,eAAe,kBAAkB,WAAW,CAAC,CAAC,EAC3I,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,IAAI,KAAK,4BAA4B,KAAK;AAAA,MAClD,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,IAAI,KAAK,4BAA4B,KAAK;AAAA,QAC1C,EAAE,SAAS,CAAC,GAAG,OAAO,GAAG,MAAM;AAAA,QAC/B;AAAA,UACE,EAAE,MAAM,WAAW,aAAa,wBAAwB,YAAY,EAAE,QAAQ,UAAU,OAAO,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,EAAE;AAAA,UACrH,EAAE,MAAM,eAAe,aAAa,gCAAgC,YAAY,EAAE,QAAQ,OAAO,EAAE;AAAA,QACrG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,oBAAI,IAA4C;AAChE,aAAW,KAAK,aAA8D;AAC5E,YAAQ,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,CAAC;AAAA,EACnD;AAEA,QAAM,eAAe,oBAAI,IAAoB;AAC7C,aAAW,KAAK,SAAuC;AACrD,UAAM,MAAM,QAAQ,IAAI,EAAE,YAAY;AACtC,UAAM,OAAO,KAAK,QAAQ;AAC1B,iBAAa,IAAI,OAAO,aAAa,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EAC1D;AACA,QAAM,cAAc,CAAC,GAAG,aAAa,QAAQ,CAAC,EAC3C,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,GAAG,KAAK,IAAI,IAAI,EAAE,EACzC,KAAK,IAAI;AAEZ,QAAM,YAAa,QAShB,IAAI,CAAC,MAAM;AACV,UAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,UAAM,gBAAgB,EAAE,iBAAiB,GAAG,EAAE,MAAM,MAAM,EAAE,cAAc,KAAK,EAAE;AACjF,UAAM,MAAM,QAAQ,IAAI,EAAE,gBAAgB,EAAE;AAC5C,UAAM,SAAS,MAAM,KAAK,IAAI,IAAI,MAAM;AACxC,UAAM,UAAU,EAAE,eAAe,KAAK,EAAE,YAAY,MAAM;AAC1D,UAAM,OAAO,eAAe,EAAE,MAAM,GAAG;AACvC,UAAM,UAAU,OAAO;AAAA,IAAO,IAAI,KAAK;AACvC,WAAO,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,aAAa,KAAK,MAAM,GAAG,OAAO,GAAG,OAAO;AAAA,EAC3E,CAAC,EACA,KAAK,IAAI;AAEZ,QAAM,SAAS;AAAA;AAAA,wBAA6C,KAAK,IAAI,KAAK,KAAK,QAAQ,MAAM,SAAS,QAAQ,WAAW,IAAI,KAAK,IAAI;AAAA;AAAA,qBAA2B,WAAW;AAC5K,QAAM,SAAS;AAEf,QAAM,oBAAqB,QAOtB,IAAI,CAAC,OAAO;AAAA,IACf,SAAS,OAAO,EAAE,WAAW,EAAE;AAAA,IAC/B,MAAM,OAAO,EAAE,QAAQ,EAAE;AAAA,IACzB,YAAY,QAAQ,IAAI,EAAE,gBAAgB,EAAE,GAAG,QAAQ;AAAA,IACvD,QAAQ,OAAO,EAAE,UAAU,EAAE;AAAA,IAC7B,GAAI,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,IAAI,CAAC;AAAA,IAC/D,GAAI,EAAE,SAAS,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAAA,EAC9C,EAAE;AAEF,QAAM,iBAAiB,kBAAkB,IAAI,CAAC,OAAO;AAAA,IACnD,SAAS,EAAE;AAAA,IACX,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,gBAAgB,EAAE;AAAA,EACpB,EAAE;AAEF,QAAM,QAAQ,kBAAkB;AAChC,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,MAAM;AAAA;AAAA,EAAO,SAAS;AAAA;AAAA,EAAO,MAAM,GAAG,CAAC;AAAA,IACnF,mBAAmB,QAAQ,SAAS,KAAK,sBAAsB,KAAK,MAAM;AAAA,MACxE,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;A+Bx0BA,SAAS,KAAAC,WAAS;;;ACClB,SAAS,KAAAC,WAAS;AAIlB,IAAM,gBAAgB,CAAC,QAAQ,SAAS;AAEjC,IAAM,cAAcC,IAAE,OAAO;AAAA,EAClC,QAAQA,IAAE,KAAK,aAAa,EAAE;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,+BAA+B;AAAA,EACrE,WAAWA,IAAE,KAAK,CAAC,YAAY,YAAY,MAAM,CAAC,EAAE,QAAQ,MAAM,EAAE,SAAS,EAC1E,SAAS,gFAAgF;AAAA,EAC5F,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,EACnD,SAAS,wCAAwC;AAAA,EACpD,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,EACjD,SAAS,oCAAoC;AAClD,CAAC;AAEM,IAAM,wBAAwBA,IAAE,OAAO;AAAA,EAC5C,SAASA,IAAE,OAAO;AAAA,EAClB,WAAWA,IAAE,MAAMA,IAAE,OAAO;AAAA,IAC1B,SAASA,IAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,MAAMA,IAAE,OAAO;AAAA,IACf,MAAMA,IAAE,OAAO;AAAA,IACf,WAAWA,IAAE,KAAK,CAAC,YAAY,UAAU,CAAC;AAAA,EAC5C,CAAC,CAAC;AAAA,EACF,OAAOA,IAAE,OAAO;AAClB,CAAC;AAEM,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EAC/C,SAASA,IAAE,OAAO;AAAA,EAClB,aAAaA,IAAE,MAAMA,IAAE,OAAO;AAAA,IAC5B,eAAeA,IAAE,OAAO,EAAE,SAAS;AAAA,IACnC,YAAYA,IAAE,OAAO;AAAA,IACrB,cAAcA,IAAE,OAAO;AAAA,IACvB,WAAWA,IAAE,OAAO;AAAA,IACpB,YAAYA,IAAE,OAAO;AAAA,IACrB,QAAQA,IAAE,OAAO;AAAA,EACnB,CAAC,CAAC;AAAA,EACF,OAAOA,IAAE,OAAO;AAClB,CAAC;AAMD,eAAsB,WAAW,SAAiB,WAA6C;AAC7F,QAAM,YAAY,MAAM,YAAkE,4BAA4B,EAAE,QAAQ,CAAC;AAEjI,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,4BAA4B,OAAO,yDAAyD,CAAC;AAAA,MACtI,mBAAmB;AAAA,QACjB,2BAA2B,OAAO;AAAA,QAClC,EAAE,SAAS,WAAW,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,EAAE;AAAA,QACzD;AAAA,UACE,EAAE,MAAM,aAAa,aAAa,qBAAqB,YAAY,EAAE,QAAQ,UAAU,MAAM,QAAQ,EAAE;AAAA,UACvG,EAAE,MAAM,aAAa,aAAa,mBAAmB,YAAY,EAAE,QAAQ,WAAW,QAAQ,EAAE;AAAA,QAClG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,YAAkD,kBAAkB,EAAE,QAAQ,CAAC;AACzG,MAAI,CAAC,aAAa;AAChB,WAAO,eAAe,SAAS,UAAU,OAAO,8DAA8D;AAAA,EAChH;AACA,QAAM,mBAAmB,YAAY;AAErC,QAAM,gBAAgB;AACtB,QAAM,YAAY,UAAU,SAAS;AACrC,QAAM,SAAS,UAAU,MAAM,GAAG,aAAa;AAE/C,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,KAAK,QAAQ;AACtB,UAAM,UAAU,EAAE,WAAW,mBAAmB,EAAE,OAAO,EAAE;AAC3D,aAAS,IAAI,OAAO;AAAA,EACtB;AAEA,QAAM,eAAe,oBAAI,IAAsE;AAC/F,aAAW,MAAM,UAAU;AACzB,UAAM,QAAQ,MAAM,YAA0F,kBAAkB,EAAE,GAAG,CAAC;AACtI,QAAI,OAAO;AACT,mBAAa,IAAI,MAAM,KAAK,EAAE,SAAS,MAAM,SAAS,MAAM,MAAM,MAAM,cAAc,MAAM,aAAa,CAAC;AAAA,IAC5G;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,YAAkD,uBAAuB;AACnG,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,KAAK,YAAa,SAAQ,IAAI,EAAE,KAAK,EAAE,IAAI;AAEtD,QAAM,QAAkB,CAAC,kBAAkB,IAAI,mBAAmB,OAAO,KAAK,YAAY,IAAI,IAAI,EAAE;AAEpG,QAAM,WAAW,OAAO,IAAI,CAAC,MAAM;AACjC,UAAM,aAAa,EAAE,WAAW;AAChC,UAAM,UAAU,aAAa,EAAE,OAAO,EAAE;AACxC,UAAM,QAAQ,aAAa,IAAI,OAAO;AACtC,UAAM,aAAa,OAAO,UAAU,GAAG,MAAM,OAAO,KAAK,MAAM,IAAI,KAAM,OAAO,QAAQ;AACxF,UAAM,UAAU,QAAS,QAAQ,IAAI,MAAM,YAAY,KAAK,YAAa;AACzE,WAAO,EAAE,YAAY,MAAM,EAAE,MAAM,YAAY,SAAS,cAAc,OAAO,SAAS,WAAW,OAAO,QAAQ,YAAY;AAAA,EAC9H,CAAC;AAED,QAAM,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,UAAU;AACpD,QAAM,WAAW,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU;AAErD,OAAK,cAAc,cAAc,cAAc,WAAW,SAAS,SAAS,GAAG;AAC7E,UAAM,KAAK,gBAAgB,SAAS,MAAM,GAAG;AAC7C,eAAW,KAAK,UAAU;AACxB,YAAM,KAAK,cAAS,EAAE,IAAI,MAAM,EAAE,UAAU,KAAK,EAAE,OAAO,GAAG;AAAA,IAC/D;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,OAAK,cAAc,cAAc,cAAc,WAAW,SAAS,SAAS,GAAG;AAC7E,UAAM,KAAK,gBAAgB,SAAS,MAAM,GAAG;AAC7C,eAAW,KAAK,UAAU;AACxB,YAAM,KAAK,cAAS,EAAE,IAAI,MAAM,EAAE,UAAU,KAAK,EAAE,OAAO,GAAG;AAAA,IAC/D;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,QAAQ,cAAc,aAAa,WAAW,cAAc,aAAa,WAAW;AAC1F,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,KAAK,MAAM,SAAS,0BAA0B,OAAO,KAAK;AAAA,EAClE;AAEA,MAAI,WAAW;AACb,UAAM,KAAK,kBAAkB,aAAa,OAAO,UAAU,MAAM,2DAA2D;AAAA,EAC9H;AAEA,QAAM,sBAAsB,MAAM,IAAI,CAAC,OAAO;AAAA,IAC5C,SAAS,EAAE;AAAA,IACX,MAAM,EAAE;AAAA,IACR,MAAM,EAAE;AAAA,IACR,WAAY,EAAE,aAAa,aAAa;AAAA,EAC1C,EAAE;AAEF,QAAM,QAAQ;AAAA,IACZ,EAAE,IAAI,SAAS,MAAM,YAAY,MAAM,gBAAgB,GAAG;AAAA,IAC1D,GAAG,MAAM,IAAI,CAAC,OAAO;AAAA,MACnB,IAAI,EAAE,gBAAgB,OAAO,KAAK,OAAO,CAAC;AAAA,MAC1C,MAAM,EAAE;AAAA,MACR,gBAAgB,EAAE;AAAA,IACpB,EAAE;AAAA,EACJ;AACA,QAAM,QAAQ,MACX,OAAO,CAAC,MAAM,EAAE,YAAY,EAC5B,IAAI,CAAC,OAAO;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,MAAM,EAAE;AAAA,EACV,EAAE;AAEJ,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,SAAS,UAAU,MAAM,kBAAkB,OAAO;AAAA,MAClD,EAAE,SAAS,WAAW,qBAAqB,OAAO,OAAO,OAAO,UAAU,OAAO;AAAA,MACjF,CAAC,EAAE,MAAM,WAAW,aAAa,sBAAsB,YAAY,EAAE,QAAQ,OAAO,QAAQ,EAAE,CAAC;AAAA,IACjG;AAAA,EACF;AACF;AAEA,eAAsB,cAAc,SAAiB,OAAe,OAAe;AACjF,QAAMC,UAAS,MAAM,YAAiE,2BAA2B;AAAA,IAC/G;AAAA,IACA,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI,CAACA,SAAQ,eAAeA,QAAO,YAAY,WAAW,GAAG;AAC3D,WAAO;AAAA,MACL,6BAA6B,OAAO;AAAA,MACpC;AAAA,MACA,6BAA6B,OAAO;AAAA,MACpC;AAAA,MACA,CAAC,EAAE,MAAM,aAAa,aAAa,4BAA4B,YAAY,EAAE,QAAQ,QAAQ,QAAQ,EAAE,CAAC;AAAA,IAC1G;AAAA,EACF;AAEA,QAAM,WAAWA,QAAO;AACxB,QAAM,gBAAgB,WAClB,KAAK,SAAS,WAAW,SAAS,IAAI,OAAO,SAAS,IAAI,MAC1D,KAAK,OAAO;AAEhB,QAAM,cAAcA,QAAO;AAC3B,QAAM,aAAa,YAAY,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE;AAClE,QAAM,YAAY,YAAY,OAAO,CAAC,MAAM,EAAE,kBAAkB,EAAE,EAAE;AACpE,QAAM,WAAW,UAAU,WAAW;AAEtC,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,0BAA0B,aAAa;AAAA,IACvC,IAAI,YAAY,MAAM,2BAA2B,UAAU,eAAe,SAAS;AAAA,IACnF;AAAA,EACF;AAEA,QAAM,OAAO,YAAY,MAAM,GAAG,CAAC;AACnC,QAAM,KAAK,uBAAuB;AAClC,QAAM,YAAsB,CAAC;AAC7B,aAAW,KAAK,MAAM;AACpB,UAAM,MAAM,EAAE,WAAW;AACzB,UAAM,UAAU,EAAE,2BAA2B;AAC7C,UAAM,KAAK,OAAO,GAAG,OAAO,EAAE,IAAI,KAAK,EAAE,cAAc,YAAO,EAAE,KAAK,iBAAY,OAAO,IAAI;AAC5F,QAAI,EAAE,QAAS,WAAU,KAAK,UAAU,QAAQ,SAAS,GAAG,WAAW,OAAO,IAAI;AAAA,EACpF;AACA,QAAM,KAAK,EAAE;AACb,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,KAAK,8DAA8D,UAAU,KAAK,GAAG,CAAC,KAAK;AACjG,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,KAAK,oBAAoB;AAC/B,aAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,YAAM,IAAI,YAAY,CAAC;AACvB,YAAM,WAAW,SAAI,OAAO,KAAK,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,SAAI,OAAO,KAAK,KAAK,MAAM,EAAE,QAAQ,EAAE,CAAC;AAChG,YAAM,WAAW,EAAE,gBAAgB,IAAI,GAAG,EAAE,aAAa,SAAS;AAClE,YAAM,UAAU,EAAE,4BAA4B,eAAe,aAAQ,EAAE,uBAAuB,OAAO;AACrG,YAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,SAAS,OAAO,EAAE,IAAI,KAAK,EAAE,cAAc,MAAM,QAAQ,GAAG;AACnG,YAAM,KAAK,MAAM,QAAQ,IAAI,EAAE,KAAK,OAAO,OAAO,EAAE;AACpD,UAAI,EAAE,QAAS,OAAM,KAAK,MAAM,EAAE,OAAO,EAAE;AAC3C,YAAM,KAAK,OAAO,EAAE,SAAS,GAAG;AAAA,IAClC;AAAA,EACF;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,oDAAoD,QAAQ,oCAAoC;AAC3G,QAAM,KAAK,oDAAoD,QAAQ,oCAAoC;AAE3G,QAAM,wBAAwB,YAAY,IAAI,CAAC,OAAO;AAAA,IACpD,eAAe,EAAE;AAAA,IACjB,YAAY,EAAE;AAAA,IACd,cAAc,EAAE,2BAA2B;AAAA,IAC3C,WAAW;AAAA,IACX,YAAY,EAAE;AAAA,IACd,QAAQ,EAAE;AAAA,EACZ,EAAE;AAEF,QAAM,QAAQ;AAAA,IACZ,EAAE,IAAI,UAAU,MAAM,UAAU,QAAQ,SAAS,gBAAgB,GAAG;AAAA,IACpE,GAAG,YAAY,IAAI,CAAC,OAAO;AAAA,MACzB,IAAI,EAAE,WAAW,OAAO,KAAK,OAAO,CAAC;AAAA,MACrC,MAAM,EAAE;AAAA,MACR,gBAAgB,EAAE;AAAA,IACpB,EAAE;AAAA,EACJ;AACA,QAAM,QAAQ,YACX,OAAO,CAAC,MAAM,EAAE,OAAO,EACvB,IAAI,CAAC,OAAO;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,MAAM,EAAE,2BAA2B;AAAA,EACrC,EAAE;AAEJ,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,SAAS,YAAY,MAAM,yBAAyB,aAAa;AAAA,MACjE,EAAE,SAAS,UAAU,aAAa,uBAAuB,OAAO,OAAO,OAAO,YAAY,OAAO;AAAA,MACjG,CAAC,EAAE,MAAM,aAAa,aAAa,gBAAgB,YAAY,EAAE,QAAQ,eAAe,EAAE,CAAC;AAAA,IAC7F;AAAA,EACF;AACF;;;ADjQA,IAAM,oBAAoB,CAAC,UAAU,gBAAgB,WAAW,UAAU,QAAQ,SAAS;AAG3F,IAAM,qBAAqBC,IAAE,OAAO;AAAA,EAClC,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,IAAIA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACtB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAC1B,CAAC;AAGM,IAAM,kBAAkBA,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,KAAK,iBAAiB,EAAE;AAAA,IAChC;AAAA,EAIF;AAAA,EACA,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,EACjG,IAAIA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,EAC/F,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,EAC/F,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,EAC5F,WAAWA,IAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA;AAAA,EAE1H,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,0GAA0G;AAAA,EACnJ,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,EACvG,WAAWA,IAAE,KAAK,CAAC,YAAY,YAAY,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,mGAAmG;AAAA,EAC3K,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,uDAAuD;AAAA,EAC5G,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,kDAAkD;AACxG,CAAC;AAGD,IAAM,yBAAyBA,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,QAAQ,QAAQ;AAAA,EAC1B,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,IAAIA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACtB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,OAAOA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,SAASA,IAAE,QAAQ,EAAE,SAAS;AAChC,CAAC;AACD,IAAM,8BAA8BA,IAAE,OAAO;AAAA,EAC3C,QAAQA,IAAE,QAAQ,cAAc;AAAA,EAChC,WAAWA,IAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AACtD,CAAC;AACD,IAAM,0BAA0BA,IAAE,OAAO;AAAA,EACvC,QAAQA,IAAE,QAAQ,SAAS;AAAA,EAC3B,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,IAAIA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACtB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACnC,OAAOA,IAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AACD,IAAM,yBAAyBA,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,QAAQ,QAAQ;AAAA,EAC1B,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,IAAIA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACtB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAC1B,CAAC;AACD,IAAM,uBAAuBA,IAAE,OAAO;AAAA,EACpC,QAAQA,IAAE,QAAQ,MAAM;AAAA,EACxB,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,WAAWA,IAAE,KAAK,CAAC,YAAY,YAAY,MAAM,CAAC,EAAE,SAAS,EAAE,QAAQ,MAAM;AAC/E,CAAC;AACD,IAAM,0BAA0BA,IAAE,OAAO;AAAA,EACvC,QAAQA,IAAE,QAAQ,SAAS;AAAA,EAC3B,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EACtD,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC;AACtD,CAAC;AAEM,IAAM,uBAAuBA,IAAE,mBAAmB,UAAU;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,yBAAmE;AAAA,EAC9E,QAAQ,EAAE,QAAQ,CAAC,QAAQ,MAAM,QAAQ,SAAS,SAAS,GAAG,aAAa,mCAAmC;AAAA,EAC9G,gBAAgB,EAAE,QAAQ,CAAC,WAAW,GAAG,aAAa,sCAAsC;AAAA,EAC5F,SAAS,EAAE,QAAQ,CAAC,QAAQ,MAAM,QAAQ,OAAO,GAAG,aAAa,4BAA4B;AAAA,EAC7F,QAAQ,EAAE,QAAQ,CAAC,QAAQ,MAAM,MAAM,GAAG,aAAa,mCAAmC;AAAA,EAC1F,MAAM,EAAE,QAAQ,CAAC,WAAW,WAAW,GAAG,aAAa,uBAAuB;AAAA,EAC9E,SAAS,EAAE,QAAQ,CAAC,WAAW,SAAS,OAAO,GAAG,aAAa,uBAAuB;AACxF;AAEO,SAAS,uBAAuB,QAAyB;AAE9D,QAAM,oBAAiF;AAAA,IACrF,QAAQ,CAAC,SAAS,aAAa,KAAK,MAAM,KAAK,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK,OAAO;AAAA,IACtF,gBAAgB,CAAC,SAAS,kBAAkB,KAAK,SAAS;AAAA,IAC1D,SAAS,CAAC,SAAS,cAAc,KAAK,MAAM,KAAK,IAAI,KAAK,QAAQ,cAAc,KAAK,KAAK;AAAA,IAC1F,QAAQ,CAAC,SAAS,aAAa,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI;AAAA,IAC5D,MAAM,CAAC,SAAS,WAAW,KAAK,SAAS,KAAK,aAAa,MAAM;AAAA,IACjE,SAAS,CAAC,SAAS,cAAc,KAAK,SAAS,KAAK,SAAS,IAAI,KAAK,SAAS,CAAC;AAAA,EAClF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAOF,aAAa;AAAA;AAAA,MAEb,aAAa,EAAE,cAAc,OAAO,iBAAiB,MAAM,eAAe,MAAM;AAAA,IAClF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,iBAAiB,IAAI;AAChD,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,aAAa,OAAO;AAAA,QAAG,MACvD,sBAAsB,aAAa,sBAAsB,OAAO,MAAM,wBAAwB,iBAAiB;AAAA,MACjH;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,aAAa,MAAc,IAAY,MAAc,OAAgB,SAAmB;AACrG,qBAAmB;AACnB,QAAM,iBAAiB,kBAAkB;AAyBzC,QAAMC,UAAS,MAAM,eAAsE,6BAA6B;AAAA,IACtH,aAAa;AAAA,IACb,WAAW;AAAA,IACX;AAAA,IACA,iBAAiB,SAAS;AAAA;AAAA;AAAA,IAG1B,YAAY;AAAA,IACZ,WAAW,kBAAkB;AAAA,IAC7B,GAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,EACrC,CAAC;AAGD,MAAIA,SAAQ,oBAAoB;AAC9B,UAAM,OAAOA,QAAO,yBAAyB,CAAC;AAC9C,UAAM,UAAU,KAAK,IAAI,CAAC,MAAM,cAAS,EAAE,IAAI,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,IAAI;AAC3E,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA;AAAA,KAAgCA,QAAO,gBAAgB,IAAI;AAAA;AAAA,qBAAiIA,QAAO,UAAU;AAAA;AAAA;AAAA,EAAsC,OAAO;AAAA;AAAA;AAAA,MAClQ,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,0BAA0BA,QAAO,gBAAgB,IAAI;AAAA,QACrD;AAAA,UACE,oBAAoB;AAAA,UACpB,YAAYA,QAAO;AAAA,UACnB,cAAcA,QAAO,gBAAgB;AAAA,UACrC,uBAAuBA,QAAO;AAAA,QAChC;AAAA,QACA;AAAA,UACE,EAAE,MAAM,aAAa,aAAa,uCAAuC,YAAY,EAAE,QAAQ,UAAU,MAAM,IAAI,MAAM,KAAK,CAAC,GAAG,QAAQ,cAAc,EAAE;AAAA,QAC5J;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAIA,SAAQ,SAAS;AAGnB,QAAIA,QAAO,YAAY;AACrB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,2BAA2B,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA;AAAA,EAAkBA,QAAO,kBAAkB,kCAAkC,GAAG,CAAC;AAAA,QAC1K,mBAAmB;AAAA,UACjB,qBAAqB,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA,UAC1C,EAAE,QAAQ,mBAA4B,MAAM,IAAI,MAAM,gBAAgBA,QAAO,kBAAkB,KAAK;AAAA,UACpG,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,UAAMC,aAAYD,QAAO;AAEzB,UAAME,wBAAuBD,aACzB,EAAE,GAAGA,YAAW,mBAAmBA,WAAU,SAAS,YAAY,qBAAqB,SAAS,IAChG;AAGJ,UAAM,gBAAgBD,QAAO,cAAc,CAAC,GAAG,IAAI,CAAC,MAAM;AAAA;AAAA,WAAW,EAAE,MAAM,kBAAkB,EAAE,KAAK,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE;AACjI,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,2BAA2B,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA;AAAA,uEAAwEE,wBAAuB;AAAA;AAAA,yBAA8BA,sBAAqB,IAAI,2BAA2BA,sBAAqB,UAAU,8BAA8BA,sBAAqB,iBAAiB,MAAM,EAAE,GAAG,YAAY,GAAG,CAAC;AAAA,MACxY,mBAAmB;AAAA,QACjB,yBAAyB,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA,QAC9C;AAAA,UACE,QAAQ;AAAA,UAAoB;AAAA,UAAM;AAAA,UAAI;AAAA,UACtC,GAAIA,yBAAwB,EAAE,eAAeA,sBAAqB;AAAA,UAClE,GAAIF,QAAO,cAAcA,QAAO,WAAW,SAAS,KAAK,EAAE,YAAYA,QAAO,WAAW;AAAA,QAC3F;AAAA,QACA,CAAC,EAAE,MAAM,aAAa,aAAa,mBAAmB,YAAY,EAAE,QAAQ,UAAU,MAAM,IAAI,KAAK,EAAE,CAAC;AAAA,MAC1G;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,oBAAoB;AACxC,MAAIA,SAAQ,WAAW,oBAAoB;AACzC,UAAM,eAAeA,QAAO,WAAW,gCAAgC;AACvE,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA;AAAA,IAA8CA,QAAO,eAAe,IAAI,aAAQ,IAAI,aAAQA,QAAO,aAAa,EAAE;AAAA;AAAA,EAASA,QAAO,WAAW,6EAA6E;AAAA;AAAA,qBAA0BA,QAAO,UAAU,KAAK,YAAY;AAAA,iBAAoB,MAAM,aAAa,KAAK,MAAM,WAAW;AAAA;AAAA;AAAA,MAC3V,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,wBAAwB,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA,QAC7C,EAAE,QAAQ,oBAA6B,MAAM,IAAI,MAAM,YAAYA,QAAO,WAAW;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,KAAK,IAAI,aAAQ,IAAI,aAAQ,EAAE;AAAA,IAC/B,kBAAkB,MAAM,aAAa,KAAK,MAAM,WAAW;AAAA,EAC7D;AAEA,QAAM,YAAYA,SAAQ;AAE1B,QAAM,uBAAuB,YACzB,EAAE,GAAG,WAAW,mBAAmB,UAAU,SAAS,YAAY,qBAAqB,SAAS,IAChG;AACJ,MAAI,sBAAsB;AACxB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,0BAA0B,qBAAqB,IAAI,2BAA2B,qBAAqB,UAAU,8BAA8B,qBAAqB,iBAAiB,GAAG;AAC/L,UAAM,KAAK,IAAI,qBAAqB,SAAS,GAAG;AAChD,UAAM,KAAK,mDAAmD,IAAI,SAAS,EAAE,WAAW,qBAAqB,IAAI,KAAK;AAAA,EACxH;AAGA,aAAW,KAAKA,SAAQ,cAAc,CAAC,GAAG;AACxC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,YAAO,EAAE,MAAM,kBAAkB,EAAE,KAAK,MAAM,EAAE,QAAQ,EAAE;AAAA,EACvE;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,oBAAoB,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA,MACzC;AAAA,QACE,QAAQ;AAAA,QAAoB;AAAA,QAAM;AAAA,QAAI;AAAA,QACtC,GAAI,wBAAwB,EAAE,eAAe,qBAAqB;AAAA,QAClE,GAAIA,SAAQ,cAAcA,QAAO,WAAW,SAAS,KAAK,EAAE,YAAYA,QAAO,WAAW;AAAA,MAC5F;AAAA,MACA,CAAC,EAAE,MAAM,aAAa,aAAa,mBAAmB,YAAY,EAAE,QAAQ,QAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,IACvG;AAAA,EACF;AACF;AAEA,eAAe,kBAAkB,WAA8D;AAC7F,qBAAmB;AACnB,QAAM,iBAAiB,kBAAkB;AAGzC,QAAM,UAAuB,CAAC;AAG9B,QAAM,cAAc,UAAU,OAAO,OAAK,EAAE,SAAS,SAAS;AAC9D,QAAM,YAAY,UAAU,OAAO,OAAK,EAAE,SAAS,SAAS;AAG5D,MAAI,UAAU,SAAS,GAAG;AACxB,QAAI;AACF,YAAM,cAAc,MAAM,eAAuE,8BAA8B;AAAA;AAAA;AAAA,QAG7H,WAAW,UAAU,IAAI,QAAM,EAAE,aAAa,EAAE,MAAM,WAAW,EAAE,IAAI,MAAM,EAAE,MAAM,YAAY,OAAO,EAAE;AAAA,QAC1G,WAAW,kBAAkB;AAAA,MAC/B,CAAC;AACD,eAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,cAAM,MAAM,UAAU,CAAC;AACvB,cAAM,MAAM,YAAY,QAAQ,CAAC;AACjC,gBAAQ,KAAK,EAAE,GAAG,KAAK,IAAI,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,CAAC;AAAA,MAClE;AAAA,IACF,SAAS,GAAY;AACnB,iBAAW,OAAO,WAAW;AAC3B,gBAAQ,KAAK,EAAE,GAAG,KAAK,IAAI,OAAO,OAAO,aAAa,QAAQ,EAAE,UAAU,eAAe,CAAC;AAAA,MAC5F;AAAA,IACF;AAAA,EACF;AAGA,aAAW,OAAO,aAAa;AAC7B,QAAI;AACF,YAAMA,UAAS,MAAM,eAAsE,6BAA6B;AAAA,QACtH,aAAa,IAAI;AAAA,QACjB,WAAW,IAAI;AAAA,QACf,MAAM,IAAI;AAAA;AAAA,QAEV,YAAY;AAAA,QACZ,WAAW,kBAAkB;AAAA,MAC/B,CAAC;AACD,cAAQ,KAAK;AAAA,QACX,GAAG;AAAA,QACH,IAAI;AAAA,QACJ,iBAAiBA,SAAQ,WAAW;AAAA,QACpC,YAAYA,SAAQ;AAAA,MACtB,CAAC;AAAA,IACH,SAAS,GAAY;AACnB,cAAQ,KAAK,EAAE,GAAG,KAAK,IAAI,OAAO,OAAO,aAAa,QAAQ,EAAE,UAAU,gBAAgB,CAAC;AAAA,IAC7F;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe;AAChE,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe;AACjE,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE;AAE1C,QAAM,QAAQ,CAAC;AAAA,CAAwB;AACvC,QAAM,KAAK,KAAK,QAAQ,MAAM,iBAAiB,UAAU,MAAM,mBAAmB,OAAO,MAAM,oBAAoB,UAAU,MAAM;AAAA,CAAW;AAE9I,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,YAAY;AACvB,eAAW,KAAK,SAAS;AACvB,YAAM,KAAK,OAAO,EAAE,IAAI,aAAQ,EAAE,IAAI,aAAQ,EAAE,EAAE,IAAI;AAAA,IACxD;AAAA,EACF;AAEA,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,+CAA0C;AACrD,eAAW,KAAK,WAAW;AACzB,YAAM,KAAK,OAAO,EAAE,IAAI,aAAQ,EAAE,IAAI,aAAQ,EAAE,EAAE,wBAAmB,EAAE,UAAU,IAAI;AAAA,IACvF;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW;AACtB,eAAW,KAAK,QAAQ;AACtB,YAAM,KAAK,OAAO,EAAE,IAAI,eAAU,EAAE,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,KAAK,GAAG;AAAA,IACtE;AAAA,EACF;AAEA,QAAM,OAAqB,OAAO,WAAW,IACzC,CAAC,EAAE,MAAM,aAAa,aAAa,qBAAqB,YAAY,EAAE,QAAQ,QAAQ,SAAS,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,IACpH,CAAC;AAEL,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,UAAU,QAAQ,MAAM,aAAa,UAAU,MAAM,eAAe,OAAO,MAAM,cAAc,UAAU,MAAM;AAAA,MAC/G,EAAE,SAAS,QAAQ,QAAQ,WAAW,UAAU,QAAQ,QAAQ,OAAO,QAAQ,OAAO,UAAU,QAAQ,QAAQ;AAAA,MAChH,KAAK,SAAS,OAAO;AAAA,IACvB;AAAA,EACF;AACF;AAEA,eAAe,cAAc,MAAc,IAAY,MAAc,OAAgB;AACnF,qBAAmB;AAEnB,QAAM,YAAY,MAAM,YAAoC,kBAAkB,EAAE,SAAS,KAAK,CAAC;AAC/F,MAAI,CAAC,WAAW;AACd,WAAO,eAAe,IAAI;AAAA,EAC5B;AACA,QAAM,UAAU,MAAM,YAAoC,kBAAkB,EAAE,SAAS,GAAG,CAAC;AAC3F,MAAI,CAAC,SAAS;AACZ,WAAO,eAAe,EAAE;AAAA,EAC1B;AAEA,QAAM,eAAe,2BAA2B;AAAA,IAC9C,aAAa,UAAU;AAAA,IACvB,kBAAkB,QAAQ;AAAA,IAC1B,iBAAiB;AAAA,IACjB,OAAO,SAAS;AAAA,EAClB,CAAC;AAED,SAAO;AAAA,IACL,yBAAyB,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA,IAC9C,wBAAwB,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA,IAC7C,EAAE,MAAM,IAAI,KAAK;AAAA,EACnB;AACF;AAEA,eAAe,aAAa,MAAc,IAAY,MAAc;AAClE,qBAAmB;AAEnB,QAAM,eAAsE,6BAA6B;AAAA,IACvG,aAAa;AAAA,IACb,WAAW;AAAA,IACX;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,qBAAqB,IAAI,WAAM,IAAI,WAAM,EAAE;AAAA,IAC3C,YAAY,IAAI,WAAM,EAAE,KAAK,IAAI;AAAA,IACjC,EAAE,MAAM,IAAI,KAAK;AAAA,IACjB,CAAC,EAAE,MAAM,aAAa,aAAa,+BAA+B,YAAY,EAAE,QAAQ,QAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,EACnH;AACF;;;AEzaA,SAAS,KAAAG,WAAS;;;ACWlB,SAAS,KAAAC,WAAS;AAMlB,IAAM,oBAAoB,CAAC,yBAAyB;AAE7C,IAAM,kBAAkBC,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,KAAK,iBAAiB,EAAE;AAAA,IAChC;AAAA,EACF;AAAA,EACA,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE;AAAA,IAC9B;AAAA,EACF;AAAA,EACA,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE;AAAA,IAC5B;AAAA,EACF;AACF,CAAC;AAwCD,eAAsB,2BACpB,YACA,UACA;AAEA,QAAMC,UAAS,MAAM;AAAA,IACnB;AAAA,IACA,EAAE,YAAY,SAAS;AAAA,EACzB;AAEA,MAAI,CAACA,QAAO,QAAQ;AAClB,UAAM,OACJ,yCAAyC,UAAU,aAAa,QAAQ;AAAA;AAAA;AAI1E,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MACzC,mBAAmB;AAAA,QACjB,+BAA+B,UAAU,MAAM,QAAQ;AAAA,QACvD,EAAE,QAAQ,MAAM;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB,IAAI,KAAKA,QAAO,UAAU,EAAE,YAAY;AAE9D,MAAIA,QAAO,YAAY,QAAW;AAEhC,UAAM,OACJ,sCAAsC,UAAU,aAAa,QAAQ,kBACtD,aAAa;AAAA;AAAA;AAI9B,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MACzC,mBAAmB;AAAA,QACjB,4BAA4B,aAAa;AAAA,QACzC,EAAE,QAAQ,MAAM,SAAS,QAAW,YAAYA,QAAO,WAAW;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UAAUA,QAAO;AACvB,QAAM,QAAkB;AAAA,IACtB,iCAA4B,UAAU,MAAM,QAAQ;AAAA,IACpD,gBAAgB,aAAa,OAAO,QAAQ,UAAU;AAAA,IACtD,oBAAoB,IAAI,KAAK,QAAQ,aAAa,EAAE,YAAY,CAAC;AAAA,IACjE;AAAA,IACA;AAAA,IACA,QAAQ,oBAAoB;AAAA,IAC5B;AAAA,IACA,oCAAoC,QAAQ,oBAAoB,MAAM;AAAA,EACxE;AACA,aAAW,MAAM,QAAQ,qBAAqB;AAC5C,UAAM;AAAA,MACJ,OAAO,GAAG,OAAO,MAAM,GAAG,IAAI,mBAAc,GAAG,MAAM,MAClD,GAAG,cAAc,WAAM,GAAG,WAAW,KAAK;AAAA,IAC/C;AAAA,EACF;AACA,MAAI,QAAQ,cAAc,SAAS,GAAG;AACpC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,sBAAsB,QAAQ,cAAc,MAAM,GAAG;AAChE,UAAM,KAAK,QAAQ,cAAc,KAAK,IAAI,CAAC;AAAA,EAC7C;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,2BAA2B,aAAa,SAAS,QAAQ,oBAAoB,MAAM;AAAA,MACnF;AAAA,QACE,QAAQ;AAAA,QACR;AAAA,QACA,YAAYA,QAAO;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;;;AD3IA,SAAS,mBAAmB,MAAsB;AAChD,QAAM,WAAW,wBAAwB,IAAI;AAC7C,SAAO,WAAW,OAAO,WAAW;AACtC;AAQA,SAAS,wBAAwB,gBAAgC;AAC/D,QAAM,KAAK,eAAe,YAAY;AACtC,MAAI,OAAO,WAAY,QAAO;AAC9B,MAAI,OAAO,cAAe,QAAO;AACjC,SAAO;AACT;AAsGA,IAAM,kBAAkB,CAAC,UAAU,SAAS,gBAAgB,WAAW,SAAS,aAAa,eAAe,SAAS,qBAAqB;AAInI,IAAM,gBAAgBC,IAAE,OAAO;AAAA;AAAA,EAEpC,QAAQA,IAAE,KAAK,eAAe,EAAE;AAAA,IAC9B;AAAA,EASF;AAAA,EACA,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,0HAA0H;AAAA,EAC3K,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IACzC;AAAA,EAEF;AAAA,EACA,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,oIAAoI;AAAA,EACnL,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IACpC;AAAA,EAEF;AAAA,EACA,WAAWA,IAAE,KAAK,CAAC,YAAY,UAAU,CAAC,EAAE,QAAQ,UAAU,EAAE,SAAS,EACtE,SAAS,+IAA+I;AAAA,EAC3J,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IAC3C;AAAA,EAGF;AAAA,EACA,MAAMA,IAAE,KAAK,CAAC,UAAU,OAAO,CAAC,EAAE,QAAQ,QAAQ,EAAE,SAAS,EAC1D,SAAS,kHAAkH;AAAA,EAC9H,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EACxC,SAAS,oFAAoF;AAAA,EAChG,YAAYA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,EACxD,SAAS,wDAAwD;AAAA,EACpE,UAAUA,IAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS,EAAE,SAAS,EACjE,SAAS,wHAAwH;AAAA,EACpI,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IACpC;AAAA,EAEF;AAAA,EACA,WAAWA,IAAE,KAAK,CAAC,YAAY,cAAc,OAAO,CAAC,EAAE,SAAS,EAAE;AAAA,IAChE;AAAA,EAKF;AAAA,EACA,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IACzC;AAAA,EACF;AAAA,EACA,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE;AAAA,IACvC;AAAA,EACF;AACF,CAAC;AAGD,IAAM,uBAAuBA,IAAE,OAAO;AAAA,EACpC,QAAQA,IAAE,QAAQ,QAAQ;AAAA,EAC1B,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACtC,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EACpC,MAAMA,IAAE,KAAK,CAAC,UAAU,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,QAAQ;AAAA,EAC7D,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC;AAAA,EACtD,YAAYA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE;AAAA,EAC3D,UAAUA,IAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,SAAS,EAAE,QAAQ,SAAS;AACtE,CAAC;AACD,IAAM,sBAAsBA,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,QAAQ,OAAO;AAAA,EACzB,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC;AACxD,CAAC;AACD,IAAM,6BAA6BA,IAAE,OAAO;AAAA,EAC1C,QAAQA,IAAE,QAAQ,cAAc;AAAA,EAChC,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAC7B,CAAC;AACD,IAAM,wBAAwBA,IAAE,OAAO;AAAA,EACrC,QAAQA,IAAE,QAAQ,SAAS;AAAA,EAC3B,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG;AAC3B,CAAC;AACD,IAAM,sBAAsBA,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,QAAQ,OAAO;AAAA,EACzB,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,WAAWA,IAAE,KAAK,CAAC,YAAY,UAAU,CAAC,EAAE,SAAS,EAAE,QAAQ,UAAU;AAAA,EACzE,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC;AAAA,EACtD,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAC7C,CAAC;AACD,IAAM,yBAAyBA,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,QAAQ,WAAW;AAAA,EAC7B,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG;AAClC,CAAC;AACD,IAAM,4BAA4BA,IAAE,OAAO;AAAA,EACzC,QAAQA,IAAE,QAAQ,aAAa;AAAA,EAC/B,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG;AAC3B,CAAC;AACD,IAAM,sBAAsBA,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,QAAQ,OAAO;AAAA,EACzB,WAAWA,IAAE,KAAK,CAAC,YAAY,cAAc,OAAO,CAAC;AAAA,EACrD,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACtC,CAAC;AACD,IAAM,kCAAkCA,IAAE,OAAO;AAAA,EAC/C,QAAQA,IAAE,QAAQ,qBAAqB;AAAA,EACvC,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC9B,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAG;AAC9B,CAAC;AAEM,IAAM,qBAAqBA,IAAE,mBAAmB,UAAU;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,uBAA+D;AAAA,EAC1E,QAAQ,EAAE,QAAQ,CAAC,WAAW,cAAc,QAAQ,QAAQ,WAAW,cAAc,UAAU,GAAG,aAAa,gEAAgE;AAAA,EAC/K,OAAO,EAAE,QAAQ,CAAC,WAAW,SAAS,GAAG,aAAa,uBAAuB;AAAA,EAC7E,cAAc,EAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,uBAAuB;AAAA,EACzE,SAAS,EAAE,QAAQ,CAAC,OAAO,GAAG,aAAa,gCAAgC;AAAA,EAC3E,OAAO,EAAE,QAAQ,CAAC,WAAW,aAAa,WAAW,cAAc,GAAG,aAAa,uBAAuB;AAAA,EAC1G,aAAa,EAAE,QAAQ,CAAC,cAAc,GAAG,aAAa,4BAA4B;AAAA,EAClF,aAAa,EAAE,QAAQ,CAAC,OAAO,GAAG,aAAa,qBAAqB;AAAA,EACpE,OAAO,EAAE,QAAQ,CAAC,aAAa,OAAO,GAAG,aAAa,yBAAyB;AAAA,EAC/E,uBAAuB,EAAE,QAAQ,CAAC,cAAc,UAAU,GAAG,aAAa,6CAA6C;AACzH;AAEO,SAAS,qBAAqB,QAAyB;AAE5D,QAAM,kBAA6E;AAAA,IACjF,QAAQ,CAAC,SAAS,KAAK,aACnB,oBAAoB,QAAQ,KAAK,YAAY,KAAK,WAAW,GAAG,KAAK,cAAc,EAAE,IACrF,aAAa,QAAQ,KAAK,SAAS,KAAK,MAAM,KAAK,QAAQ,UAAU,KAAK,WAAW,GAAG,KAAK,cAAc,IAAI,KAAK,YAAY,SAAS;AAAA,IAC7I,OAAO,CAAC,SAAS,YAAY,QAAQ,KAAK,SAAS,KAAK,WAAW,CAAC;AAAA,IACpE,cAAc,CAAC,SAAS,mBAAmB,KAAK,OAAO;AAAA,IACvD,SAAS,CAAC,SAAS,cAAc,KAAK,KAAK;AAAA,IAC3C,OAAO,CAAC,SAAS,gBAAgB,KAAK,SAAS,KAAK,aAAa,YAAY,KAAK,WAAW,GAAG,KAAK,YAAY;AAAA,IACjH,aAAa,CAAC,SAAS,eAAe,KAAK,YAAY;AAAA,IACvD,aAAa,CAAC,SAAS,kBAAkB,KAAK,KAAK;AAAA,IACnD,OAAO,CAAC,SAAS;AACf,YAAM,UAAU,KAAK,cAAc,WAAW,KAAK,QAAQ,KAAK,MAAM,KAAK,KAAK,IAAI;AACpF,UAAI,KAAK,cAAc,WAAW,KAAK,UAAU,YAAY,UAAa,MAAM,OAAO,IAAI;AACzF,eAAO,QAAQ,QAAQ;AAAA,UACrB,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,+BAA+B,KAAK,KAAK,wDAAwD,CAAC;AAAA,UAC3I,mBAAmB,QAAQ,oBAAoB,+BAA+B,KAAK,KAAK,IAAI;AAAA,QAC9F,CAAC;AAAA,MACH;AACA,aAAO,YAAY,KAAK,WAAW,OAAO;AAAA,IAC5C;AAAA,IACA,uBAAuB,CAAC,SAAS,2BAA2B,KAAK,YAAY,KAAK,QAAQ;AAAA,EAC5F;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAgCF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,MAAM,gBAAgB,MAAM,eAAe,MAAM;AAAA,IAChF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,eAAe,IAAI;AAC9C,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,WAAW,OAAO;AAAA,QAAG,MACrD,sBAAsB,WAAW,oBAAoB,OAAO,MAAM,sBAAsB,eAAe;AAAA,MACzG;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAe,aACb,QACA,SACA,MACA,MACA,SACA,YACA,WAAiC,WACjC;AACA,MAAI,CAAC,WAAW,CAAC,MAAM;AACrB,WAAO,iBAAiB,uEAAuE;AAAA,EACjG;AAGA,MAAI,WAAW,SAAS,SAAS;AAC/B,UAAM,OAAO,mBAAmB;AAAA,MAC9B,OAAO;AAAA,MACP,MAAM,uBAAuB,OAAO,YAAY,OAAO;AAAA,MACvD,QAAQ;AAAA,IACV,CAAC;AAED,UAAMC,UAAS,MAAM,YAAkE,4BAA4B;AAAA,MACjH;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,CAACA,SAAQ,MAAM;AACjB,aAAO,eAAe,SAAU,UAAU,OAAO,+CAA+C;AAAA,IAClG;AACA,UAAMC,QAAOD,QAAO;AAEpB,QAAIA,QAAO,QAAQ,WAAW,GAAG;AAC/B,YAAM,WAAW,UAAU,EAAE,OAAOC,MAAK,SAAS,MAAM,WAAW,QAAQ,UAAU,SAAS,sBAAsB,CAAC;AACrH,UAAI,UAAU;AACZ,uBAAe,EACZ,KAAK,CAAC,SAAS,kBAAkB,MAAM,EAAE,OAAOA,MAAK,SAAS,MAAM,WAAW,QAAQ,UAAU,UAAU,sBAAsB,CAAC,CAAC,EACnI,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACnB;AAEA,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,iBAAiBA,MAAK,OAAO,KAAKA,MAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,QAGnD,CAAC;AAAA,QACD,mBAAmB;AAAA,UACjB,0BAA0BA,MAAK,OAAO;AAAA,UACtC,EAAE,MAAAA,OAAM,SAAS,CAAC,GAAG,YAAY,EAAE;AAAA,UACnC,CAAC,EAAE,MAAM,aAAa,aAAa,wBAAwB,YAAY,EAAE,QAAQ,WAAW,SAASA,MAAK,QAAQ,EAAE,CAAC;AAAA,QACvH;AAAA,MACF;AAAA,IACF;AAEA,UAAMC,gBAAe,oBAAI,IAA4B;AACrD,eAAW,SAASF,QAAO,SAAS;AAClC,YAAM,MAAM,MAAM,kBAAkB;AACpC,UAAI,CAACE,cAAa,IAAI,GAAG,EAAG,CAAAA,cAAa,IAAI,KAAK,CAAC,CAAC;AACpD,MAAAA,cAAa,IAAI,GAAG,EAAG,KAAK,KAAK;AAAA,IACnC;AAEA,UAAMC,SAAkB;AAAA,MACtB,iBAAiBF,MAAK,OAAO,KAAKA,MAAK,IAAI;AAAA,MAC3C,IAAID,QAAO,UAAU,2BAA2BE,cAAa,IAAI,iBAAiBF,QAAO,aAAa;AAAA,MACtG;AAAA,IACF;AAEA,eAAW,CAAC,UAAU,OAAO,KAAKE,eAAc;AAC9C,MAAAC,OAAM,KAAK,MAAM,QAAQ,KAAK,QAAQ,MAAM,IAAI,wBAAwB,QAAQ,CAAC,EAAE;AACnF,iBAAW,KAAK,SAAS;AACvB,cAAM,QAAQ,EAAE,sBAAsB,aAAa,WAAM;AACzD,cAAM,KAAK,EAAE,UAAU,GAAG,EAAE,OAAO,OAAO;AAC1C,cAAM,WAAW,EAAE,MAAM,IAAI,SAAS,EAAE,GAAG,MAAM;AACjD,cAAM,aAAa,OAAO,EAAE,UAAU,WAAW,KAAK,EAAE,KAAK,KAAK;AAClE,cAAM,aAAa,EAAE,YAAY,SAAS,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,MAAM;AAC5E,cAAM,cAAc,EAAE,SAAS,aAAa,EAAE,MAAM,MAAM;AAC1D,cAAM,iBAAiB,EAAE,cAAc,EAAE,WAAW,SAAS,IACzD;AAAA,WAAc,EAAE,WAAW,IAAI,CAAC,MAAM,GAAG,EAAE,WAAW,EAAE,IAAI,KAAK,EAAE,YAAY,GAAG,EAAE,KAAK,UAAK,CAAC,MAC/F;AACJ,cAAM,UAAU,EAAE,UAAU;AAAA,IAAO,EAAE,QAAQ,UAAU,GAAG,GAAG,CAAC,KAAK;AACnE,QAAAA,OAAM,KAAK,KAAK,KAAK,MAAM,EAAE,YAAY,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,OAAO,EAAE;AAAA,MAC5I;AACA,MAAAA,OAAM,KAAK,EAAE;AAAA,IACf;AAEA,UAAMC,UAASH,MAAK,WAAW;AAC/B,UAAMI,SAAQ;AAAA,MACZ,EAAE,IAAID,SAAQ,MAAMH,MAAK,MAAM,gBAAgB,GAAG;AAAA,MAClD,GAAGD,QAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,QAC5B,IAAI,EAAE,WAAW,OAAO,KAAK,OAAO,CAAC;AAAA,QACrC,MAAM,EAAE;AAAA,QACR,gBAAgB,EAAE;AAAA,MACpB,EAAE;AAAA,IACJ;AACA,UAAMM,SAAQN,QAAO,QAClB,OAAO,CAAC,MAAM,EAAE,OAAO,EACvB,IAAI,CAAC,OAAO;AAAA,MACX,QAAQI;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,MAAM,EAAE;AAAA,IACV,EAAE;AAEJ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAMD,OAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC3D,mBAAmB;AAAA,QACjB,YAAYH,QAAO,UAAU,wBAAwBC,MAAK,OAAO,KAAKD,QAAO,aAAa;AAAA,QAC1F,EAAE,OAAAK,QAAO,OAAAC,QAAO,MAAAL,OAAM,YAAYD,QAAO,WAAW;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAIA,MAAI,QAAQ,CAAC,SAAS;AACpB,UAAM,gBAAgB,aAAa,WAAW,0BAA0B;AACxE,UAAM,OAAO,mBAAmB;AAAA,MAC9B,OAAO;AAAA,MACP,MAAM,8BAA8B,KAAK,UAAU,GAAG,EAAE,CAAC,mBAAmB,aAAa;AAAA,MACzF,QAAQ;AAAA,IACV,CAAC;AAED,UAAMA,UAAS,aAAa,WACxB,MAAM,YAAwE,kCAAkC;AAAA,MAC9G;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC,IACD,MAAM,YAAkE,4BAA4B;AAAA,MAClG;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAEL,QAAI,CAACA,WAAUA,QAAO,eAAe,GAAG;AACtC,YAAM,YAAY,KAAK,MAAM,GAAG,GAAG;AACnC,YAAM,WAAW,UAAU,EAAE,OAAO,WAAW,MAAM,WAAW,QAAQ,UAAU,SAAS,qBAAqB,CAAC;AACjH,UAAI,UAAU;AACZ,uBAAe,EACZ,KAAK,CAAC,SAAS,kBAAkB,MAAM,EAAE,OAAO,WAAW,MAAM,WAAW,QAAQ,UAAU,UAAU,qBAAqB,CAAC,CAAC,EAC/H,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACnB;AAEA,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAIR,CAAC;AAAA,QACD,mBAAmB;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UACA,CAAC,EAAE,MAAM,WAAW,aAAa,4BAA4B,YAAY,EAAE,QAAQ,UAAU,OAAO,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,CAAC;AAAA,QAC/I;AAAA,MACF;AAAA,IACF;AAEA,UAAM,+BAA+BA,QAAO,kBAAkB,gBAAgB,CAAC;AAC/E,UAAM,uBACJ,6BAA6B,KAAK,CAAC,WAAW,OAAO,QAAQ,SAAS,CAAC,KACvEA,QAAO,kBAAkB,WAAW,SAAS,KAC7CA,QAAO,kBAAkB,UAAU,SAAS,KAC5CA,QAAO,kBAAkB,cAAc,SAAS;AAElD,UAAME,gBAAe,oBAAI,IAA4B;AACrD,eAAW,SAASF,QAAO,mBAAmB;AAC5C,YAAM,MAAM,MAAM,kBAAkB;AACpC,UAAI,CAACE,cAAa,IAAI,GAAG,EAAG,CAAAA,cAAa,IAAI,KAAK,CAAC,CAAC;AACpD,MAAAA,cAAa,IAAI,GAAG,EAAG,KAAK,KAAK;AAAA,IACnC;AACA,UAAM,gBAAgBF,QAAO,gBAAgB;AAC7C,UAAM,kBAAkB,IAAI;AAAA,MAC1B,CAAC,GAAGA,QAAO,iBAAiB,GAAGA,QAAO,iBAAiB,EAAE,IAAI,CAAC,UAAU,MAAM,cAAc;AAAA,IAC9F,EAAE;AAGF,UAAM,cAAcA,QAAO,OAAO,IAAI,CAAC,MAAW;AAChD,YAAM,KAAK,EAAE,WAAW,EAAE;AAC1B,aAAO,EAAE,SAAS,GAAG,EAAE,KAAK,EAAE,MAAM,MAAM;AAAA,IAC5C,CAAC,EAAE,KAAK,IAAI,KAAK;AAEjB,UAAMG,SAAkB;AAAA,MACtB;AAAA,MACA,mBAAmBH,QAAO,WAAW,OAAO,CAAC,EAAE,YAAY,IAAIA,QAAO,WAAW,MAAM,CAAC,CAAC;AAAA,MACzF,kBAAkBA,QAAO,eAAe;AAAA,MACxC,iBAAiB,aAAa;AAAA,MAC9B,gBAAgBA,QAAO,UAAU,mBAAmB,eAAe,cAAc,oBAAoB,IAAI,KAAK,GAAG;AAAA,MACjH,cAAc,WAAW;AAAA,MACzB;AAAA,IACF;AAEA,IAAAG,OAAM,KAAK,oIAAoI;AAC/I,IAAAA,OAAM,KAAK,EAAE;AAEb,QAAI,sBAAsB;AACxB,MAAAA,OAAM,KAAK,uBAAuB;AAClC,MAAAA,OAAM,KAAK,yEAAyE;AACpF,MAAAA,OAAM,KAAK,EAAE;AAEb,YAAM,0BAA0B,CAAC,YAAsC;AACrE,mBAAW,SAAS,SAAS;AAC3B,gBAAM,KAAK,MAAM,UAAU,KAAK,MAAM,OAAO,SAAS;AACtD,gBAAM,aAAa,OAAO,MAAM,UAAU,WAAW,KAAK,MAAM,KAAK,KAAK;AAC1E,gBAAM,aAAa,MAAM,YAAY,SAAS,KAAK,MAAM,WAAW,KAAK,IAAI,CAAC,MAAM;AACpF,gBAAM,cAAc,MAAM,SAAS,aAAa,MAAM,MAAM,MAAM;AAGlE,gBAAM,YAAY,MAAM,SAAS,IAAI,gBAAgB,MAAM,SAAS,IAAI,gBAAgB,MAAM,SAAS,IAAI,aAAa;AACxH,UAAAA,OAAM,KAAK,KAAK,EAAE,GAAG,MAAM,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,EAAE;AACrF,cAAI,MAAM,QAAS,CAAAA,OAAM,KAAK,MAAM,MAAM,OAAO,GAAG;AAAA,QACtD;AAAA,MACF;AAEA,YAAM,2BAA2B,6BAA6B,OAAO,CAAC,WAAW,OAAO,QAAQ,SAAS,CAAC;AAC1G,UAAI,yBAAyB,SAAS,GAAG;AACvC,mBAAW,UAAU,0BAA0B;AAC7C,gBAAM,QAAQ,OAAO,kBAAkB,OAAO,kBAAkB;AAChE,UAAAA,OAAM,KAAK,OAAO,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACpD,kCAAwB,OAAO,OAAO;AACtC,UAAAA,OAAM,KAAK,EAAE;AAAA,QACf;AAAA,MACF,OAAO;AACL,cAAM,qBAAgE;AAAA,UACpE,CAAC,cAAcH,QAAO,kBAAkB,UAAU;AAAA,UAClD,CAAC,aAAaA,QAAO,kBAAkB,SAAS;AAAA,UAChD,CAAC,kBAAkBA,QAAO,kBAAkB,aAAa;AAAA,QAC3D;AAEA,mBAAW,CAAC,OAAO,OAAO,KAAK,oBAAoB;AACjD,cAAI,QAAQ,WAAW,EAAG;AAC1B,UAAAG,OAAM,KAAK,OAAO,KAAK,KAAK,QAAQ,MAAM,GAAG;AAC7C,kCAAwB,OAAO;AAC/B,UAAAA,OAAM,KAAK,EAAE;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,IAAAA,OAAM,KAAK,qBAAqB;AAChC,IAAAA,OAAM,KAAK,4FAA4F;AACvG,IAAAA,OAAM,KAAK,EAAE;AACb,QAAI,kBAAkB,GAAG;AACvB,MAAAA,OAAM,KAAK,oCAAoC;AAC/C,MAAAA,OAAM,KAAK,EAAE;AAAA,IACf,OAAO;AACL,iBAAW,SAASH,QAAO,iBAAiB;AAC1C,cAAM,KAAK,MAAM,UAAU,KAAK,MAAM,OAAO,SAAS;AACtD,cAAM,aAAa,OAAO,MAAM,UAAU,WAAW,KAAK,MAAM,KAAK,KAAK;AAC1E,cAAM,aAAa,MAAM,YAAY,SAAS,KAAK,MAAM,WAAW,KAAK,IAAI,CAAC,MAAM;AACpF,cAAM,cAAc,MAAM,SAAS,aAAa,MAAM,MAAM,MAAM;AAClE,cAAM,WAAW,MAAM,MAAM,IAAI,UAAU,MAAM,GAAG,KAAK,MAAM,sBAAsB,aAAa,WAAM,QAAG,IAAI,MAAM,YAAY,OAAO;AACxI,QAAAG,OAAM,KAAK,KAAK,EAAE,GAAG,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,EAAE;AAAA,MACtF;AACA,MAAAA,OAAM,KAAK,EAAE;AAAA,IACf;AAEA,IAAAA,OAAM,KAAK,uBAAuB;AAClC,IAAAA,OAAM,KAAK,qFAAqF;AAChG,IAAAA,OAAM,KAAK,EAAE;AAEb,QAAID,cAAa,SAAS,GAAG;AAC3B,MAAAC,OAAM,KAAK,iFAAiF;AAC5F,MAAAA,OAAM,KAAK,EAAE;AAAA,IACf,OAAO;AACL,iBAAW,CAAC,UAAU,OAAO,KAAKD,eAAc;AAC9C,QAAAC,OAAM,KAAK,OAAO,QAAQ,KAAK,QAAQ,MAAM,IAAI,wBAAwB,QAAQ,CAAC,EAAE;AACpF,mBAAW,KAAK,SAAS;AACvB,gBAAM,QAAQ,EAAE,sBAAsB,aAAa,WAAM;AACzD,gBAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,gBAAM,aAAa,OAAO,EAAE,UAAU,WAAW,KAAK,EAAE,KAAK,KAAK;AAClE,gBAAM,aAAa,EAAE,YAAY,SAAS,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,MAAM;AAC5E,gBAAM,cAAc,EAAE,SAAS,aAAa,EAAE,MAAM,MAAM;AAC1D,gBAAM,WAAW,EAAE,MAAM,IAAI,UAAU,EAAE,GAAG,KAAK,KAAK,IAAI,EAAE,YAAY,OAAO;AAC/E,UAAAA,OAAM,KAAK,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,EAAE;AAAA,QAClF;AACA,QAAAA,OAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AAEA,IAAAA,OAAM,KAAK,6DAA6D;AAExE,UAAM,cAAc,CAAC,GAAGH,QAAO,iBAAiB,GAAGA,QAAO,iBAAiB,EAAE,IAAI,CAAC,OAAO;AAAA,MACvF,SAAS,EAAE,WAAW,OAAO,KAAK,OAAO,CAAC;AAAA,MAC1C,MAAM,EAAE;AAAA,MACR,gBAAgB,EAAE;AAAA,IACpB,EAAE;AAEF,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAMG,OAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC3D,mBAAmB;AAAA,QACjB,UAAUH,QAAO,UAAU,0CAA0CA,QAAO,UAAU,gBAAgB,QAAQ;AAAA,QAC9G;AAAA,UACE,SAAS;AAAA,UACT,YAAYA,QAAO;AAAA,UACnB,YAAYA,QAAO;AAAA,UACnB,iBAAiBA,QAAO;AAAA,UACxB;AAAA,UACA,mBAAmBA,QAAO;AAAA,UAC1B,iBAAiBA,QAAO,gBAAgB,IAAI,CAAC,WAAW;AAAA,YACtD,SAAS,MAAM,WAAW;AAAA,YAC1B,MAAM,MAAM;AAAA,YACZ,gBAAgB,MAAM;AAAA,YACtB,cAAc,MAAM;AAAA,YACpB,mBAAmB,MAAM;AAAA,YACzB,KAAK,MAAM;AAAA,YACX,OAAO,MAAM;AAAA,YACb,YAAY,MAAM;AAAA,YAClB,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,UAChB,EAAE;AAAA,UACF,mBAAmBA,QAAO,kBAAkB,IAAI,CAAC,WAAW;AAAA,YAC1D,SAAS,MAAM,WAAW;AAAA,YAC1B,MAAM,MAAM;AAAA,YACZ,gBAAgB,MAAM;AAAA,YACtB,cAAc,MAAM;AAAA,YACpB,mBAAmB,MAAM;AAAA,YACzB,KAAK,MAAM;AAAA,YACX,OAAO,MAAM;AAAA,YACb,YAAY,MAAM;AAAA,YAClB,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,UAChB,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,yBAAyB,OAAO,YAAY,OAAO;AAAA,IACzD,QAAQ;AAAA,EACV,CAAC;AAED,QAAMA,UAAS,MAAM,YAA6D,uBAAuB,EAAE,SAAS,QAAQ,CAAC;AAE7H,MAAI,CAACA,SAAQ,MAAM;AACjB,WAAO,eAAe,SAAU,UAAU,OAAO,+CAA+C;AAAA,EAClG;AACA,QAAM,OAAOA,QAAO;AAEpB,MAAIA,QAAO,QAAQ,WAAW,GAAG;AAC/B,UAAM,WAAW,UAAU,EAAE,OAAO,KAAK,SAAS,MAAM,WAAW,QAAQ,UAAU,SAAS,yBAAyB,CAAC;AACxH,QAAI,UAAU;AACZ,qBAAe,EACZ,KAAK,CAAC,SAAS,kBAAkB,MAAM,EAAE,OAAO,KAAK,SAAS,MAAM,WAAW,QAAQ,UAAU,UAAU,yBAAyB,CAAC,CAAC,EACtI,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACnB;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,iBAAiB,KAAK,OAAO,KAAK,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,MAGnD,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,0BAA0B,KAAK,OAAO;AAAA,QACtC,EAAE,MAAM,SAAS,CAAC,GAAG,gBAAgB,EAAE;AAAA,QACvC,CAAC,EAAE,MAAM,aAAa,aAAa,wBAAwB,YAAY,EAAE,QAAQ,WAAW,SAAS,KAAK,QAAQ,EAAE,CAAC;AAAA,MACvH;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,oBAAI,IAAmC;AAC5D,aAAW,SAASA,QAAO,SAAS;AAClC,UAAM,MAAM,MAAM,kBAAkB;AACpC,QAAI,CAAC,aAAa,IAAI,GAAG,EAAG,cAAa,IAAI,KAAK,CAAC,CAAC;AACpD,iBAAa,IAAI,GAAG,EAAG,KAAK,KAAK;AAAA,EACnC;AAEA,QAAM,QAAkB;AAAA,IACtB,iBAAiB,KAAK,OAAO,KAAK,KAAK,IAAI;AAAA,IAC3C,IAAIA,QAAO,cAAc,2BAA2B,aAAa,IAAI,iBAAiBA,QAAO,aAAa;AAAA,IAC1G;AAAA,EACF;AAEA,aAAW,CAAC,UAAU,OAAO,KAAK,cAAc;AAC9C,UAAM,KAAK,MAAM,QAAQ,KAAK,QAAQ,MAAM,IAAI,wBAAwB,QAAQ,CAAC,EAAE;AACnF,eAAW,KAAK,SAAS;AACvB,YAAM,QAAQ,EAAE,sBAAsB,aAAa,WAAW;AAC9D,YAAM,WAAW,EAAE,MAAM,IAAI,SAAS,EAAE,GAAG,MAAM;AACjD,YAAM,KAAK,EAAE,UAAU,GAAG,EAAE,OAAO,OAAO;AAC1C,YAAM,KAAK,KAAK,KAAK,MAAM,EAAE,YAAY,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,QAAQ,EAAE;AAAA,IACzE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,SAAS,KAAK,WAAW;AAC/B,QAAM,QAAQ;AAAA,IACZ,EAAE,IAAI,QAAQ,MAAM,KAAK,MAAM,gBAAgB,GAAG;AAAA,IAClD,GAAGA,QAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,MAC5B,IAAI,EAAE,WAAW,OAAO,KAAK,OAAO,CAAC;AAAA,MACrC,MAAM,EAAE;AAAA,MACR,gBAAgB,EAAE;AAAA,IACpB,EAAE;AAAA,EACJ;AACA,QAAM,QAAQA,QAAO,QAClB,OAAO,CAAC,MAAM,EAAE,OAAO,EACvB,IAAI,CAAC,OAAO;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,MAAM,EAAE;AAAA,EACV,EAAE;AAEJ,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,YAAYA,QAAO,cAAc,wBAAwB,KAAK,OAAO,KAAKA,QAAO,aAAa;AAAA,MAC9F,EAAE,OAAO,OAAO,MAAM,gBAAgBA,QAAO,eAAe;AAAA,IAC9D;AAAA,EACF;AACF;AAEA,eAAe,oBACb,QACA,YACA,SACA,YACA;AACA,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,mCAAmC,UAAU;AAAA,IACnD,QAAQ;AAAA,EACV,CAAC;AAED,QAAMA,UAAS,MAAM,YAAyE,mCAAmC;AAAA,IAC/H;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,CAACA,SAAQ;AACX,WAAO;AAAA,MACL;AAAA,MACA,gBAAgB,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,MAAIA,QAAO,OAAO,WAAW,KAAKA,QAAO,cAAc,GAAG;AACxD,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,sBAAsBA,QAAO,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,MAG7C,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,eAAeA,QAAO,IAAI,IAAI;AAAA,QAC9B,EAAE,KAAKA,QAAO,KAAK,QAAQA,QAAO,QAAQ,SAAS,CAAC,EAAE;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB;AAAA,IACtB,sBAAsBA,QAAO,IAAI,IAAI;AAAA,IACrC,iBAAiBA,QAAO,IAAI,YAAY,oBAAoBA,QAAO,IAAI,OAAO;AAAA,IAC9E,sBAAsBA,QAAO,SAAS,GAAGA,QAAO,YAAY,yBAAoBA,QAAO,OAAO,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,wBAAwB,EAAE;AAAA,IAC5J,0BAA0BA,QAAO,UAAU;AAAA,IAC3C;AAAA,IACA;AAAA,EACF;AAEA,aAAW,SAASA,QAAO,QAAQ;AACjC,UAAM,iBAAiB,MAAM,YAAY,WAAW,IAChD,YACA,MAAM,YAAY,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI;AACrE,UAAM,KAAK,OAAO,MAAM,KAAK,OAAO,cAAc,EAAE;AAAA,EACtD;AAEA,MAAIA,QAAO,QAAQ,SAAS,GAAG;AAC7B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,8BAA8B;AACzC,UAAM,KAAK,gEAAgE;AAC3E,UAAM,KAAK,EAAE;AAEb,UAAM,eAAe,oBAAI,IAA4B;AACrD,eAAW,SAASA,QAAO,SAAS;AAClC,YAAM,MAAM,MAAM,kBAAkB;AACpC,UAAI,CAAC,aAAa,IAAI,GAAG,EAAG,cAAa,IAAI,KAAK,CAAC,CAAC;AACpD,mBAAa,IAAI,GAAG,EAAG,KAAK,KAAK;AAAA,IACnC;AAEA,eAAW,CAAC,UAAU,OAAO,KAAK,cAAc;AAC9C,YAAM,KAAK,OAAO,QAAQ,KAAK,QAAQ,MAAM,GAAG;AAChD,iBAAW,KAAK,SAAS;AACvB,cAAM,QAAQ,EAAE,sBAAsB,aAAa,WAAM;AACzD,cAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,cAAM,aAAa,OAAO,EAAE,UAAU,WAAW,KAAK,EAAE,KAAK,KAAK;AAClE,cAAM,KAAK,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,UAAU,EAAE;AAAA,MACrD;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,QAAM,KAAK,uGAAuG;AAElH,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,uBAAuBA,QAAO,IAAI,IAAI,KAAKA,QAAO,UAAU,2BAA2BA,QAAO,OAAO,MAAM;AAAA,MAC3G;AAAA,QACE,KAAKA,QAAO;AAAA,QACZ,QAAQA,QAAO;AAAA,QACf,SAASA,QAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,UAClC,SAAS,EAAE,WAAW;AAAA,UACtB,MAAM,EAAE;AAAA,UACR,gBAAgB,EAAE;AAAA,QACpB,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,mBAAmB,SAAiB;AACjD,QAAMA,UAAS,MAAM,YAAoE,8BAA8B,EAAE,SAAS,KAAK,KAAK,IAAI,EAAE,CAAC;AAEnJ,QAAM,QAAkB,CAAC,mBAAmB,OAAO,IAAI,EAAE;AAEzD,MAAIA,QAAO,cAAc,SAAS,GAAG;AACnC,UAAM,KAAK,sBAAsBA,QAAO,cAAc,MAAM,GAAG;AAC/D,UAAM,KAAK,qDAAqD;AAChE,eAAW,QAAQA,QAAO,eAAe;AACvC,YAAM,KAAK,KAAK,UAAU,KAAK,KAAK,OAAO,SAAS;AACpD,YAAM,KAAK,KAAK,EAAE,GAAG,KAAK,IAAI,aAAa,KAAK,UAAU,SAAS,SAAS,KAAK,GAAG,GAAG;AAAA,IACzF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAIA,QAAO,gBAAgB,SAAS,GAAG;AACrC,UAAM,KAAK,wBAAwBA,QAAO,gBAAgB,MAAM,GAAG;AACnE,UAAM,KAAK,iDAAiD;AAC5D,eAAW,QAAQA,QAAO,iBAAiB;AACzC,YAAM,KAAK,KAAK,UAAU,KAAK,KAAK,OAAO,SAAS;AACpD,YAAM,aAAa,KAAK,iBAAiB,uBAAkB;AAC3D,YAAM,KAAK,KAAK,EAAE,GAAG,KAAK,IAAI,KAAK,KAAK,gBAAgB,EAAE,GAAG,UAAU,GAAG;AAAA,IAC5E;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAIA,QAAO,eAAe;AACxB,UAAM,IAAIA,QAAO;AACjB,UAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,UAAM,KAAK,mBAAmB;AAC9B,UAAM,KAAK,KAAK,EAAE,GAAG,EAAE,IAAI,WAAM,EAAE,SAAS,UAAU,EAAE,YAAY,qBAAqB;AACzF,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAIA,QAAO,gBAAgB,SAAS,GAAG;AACrC,UAAM,KAAK,wBAAwBA,QAAO,gBAAgB,MAAM,GAAG;AACnE,eAAW,QAAQA,QAAO,iBAAiB;AACzC,YAAM,KAAK,KAAK,UAAU,KAAK,KAAK,OAAO,SAAS;AACpD,YAAM,KAAK,KAAK,EAAE,GAAG,KAAK,IAAI,KAAK,KAAK,gBAAgB,EAAE,GAAG;AAAA,IAC/D;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,UAAoB,CAAC;AAC3B,MAAIA,QAAO,gBAAiB,SAAQ,KAAK,iCAA4B;AACrE,MAAIA,QAAO,iBAAiB,SAAS;AACnC,YAAQ,KAAK,iBAAYA,QAAO,gBAAgB,eAAe,qBAAqB;AAAA,EACtF;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,YAAY;AACvB,eAAW,KAAK,QAAS,OAAM,KAAK,KAAK,CAAC,EAAE;AAC5C,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,UAAUA,QAAO,cAAc,WAAW,KAAKA,QAAO,gBAAgB,WAAW,KAClF,CAACA,QAAO,iBAAiBA,QAAO,gBAAgB,WAAW;AAEhE,MAAI,SAAS;AACX,UAAM,KAAK,gFAAgF;AAC3F,UAAM,KAAK,qEAAqE;AAAA,EAClF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,oBAAoB,OAAO,KAAKA,QAAO,cAAc,MAAM,cAAcA,QAAO,gBAAgB,MAAM,kBAAkBA,QAAO,gBAAgB,MAAM;AAAA,MACrJA;AAAA,MACA,UAAU,CAAC,EAAE,MAAM,aAAa,aAAa,wBAAwB,YAAY,EAAE,QAAQ,WAAW,QAAQ,EAAE,CAAC,IAAI;AAAA,IACvH;AAAA,EACF;AACF;AAEA,eAAe,YAAY,QAAmB,SAAiB,SAAiB;AAC9E,uBAAqB;AAErB,QAAM,OAAO,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,MAAM,gCAAgC,OAAO;AAAA,IAC7C,QAAQ;AAAA,EACV,CAAC;AAED,QAAMA,UAAS,MAAM,YAAoE,8BAA8B;AAAA,IACrH;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,EAAE,OAAO,qBAAqB,eAAe,eAAe,WAAW,iBAAiB,IAAIA;AAElG,QAAM,QAAkB;AAAA,IACtB,oBAAoB,MAAM,IAAI;AAAA,IAC9B,cAAc,MAAM,WAAW,MAAM,IAAI,KAAK,MAAM,cAAc;AAAA,IAClE,eAAe,MAAM,MAAM;AAAA,IAC3B;AAAA,EACF;AAEA,MAAI,OAAO,KAAK,MAAM,IAAI,EAAE,SAAS,GAAG;AACtC,UAAM,KAAK,eAAe;AAC1B,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,IAAI,GAAG;AACnD,YAAM,MAAM,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG;AAC9D,UAAI,IAAI,SAAS,KAAK;AACpB,cAAM,KAAK,OAAO,GAAG,OAAO,IAAI,MAAM,GAAG,GAAG,CAAC,KAAK;AAAA,MACpD,OAAO;AACL,cAAM,KAAK,OAAO,GAAG,OAAO,GAAG,EAAE;AAAA,MACnC;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,KAAK,4BAA4B;AACvC,eAAW,KAAK,eAAe;AAC7B,YAAM,KAAK,EAAE,WAAW,EAAE;AAC1B,YAAM,KAAK,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;AACnC,UAAI,EAAE,YAAa,OAAM,KAAK,KAAK,EAAE,YAAY,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,YAAY,SAAS,MAAM,QAAQ,EAAE,EAAE;AAAA,IAC5G;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,KAAK,mBAAmB;AAC9B,eAAW,KAAK,cAAc,MAAM,GAAG,EAAE,GAAG;AAC1C,YAAM,KAAK,EAAE,WAAW,EAAE;AAC1B,YAAM,KAAK,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;AACnC,UAAI,EAAE,WAAY,OAAM,KAAK,KAAK,EAAE,WAAW,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,WAAW,SAAS,MAAM,QAAQ,EAAE,EAAE;AAAA,IACzG;AACA,QAAI,cAAc,SAAS,GAAI,OAAM,KAAK,aAAa,cAAc,SAAS,EAAE,QAAQ;AACxF,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,eAAe,OAAO,OAAO,mBAAmB,EAAE,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,QAAQ,CAAC;AAChG,MAAI,eAAe,GAAG;AACpB,UAAM,KAAK,oBAAoB;AAC/B,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,mBAAmB,GAAG;AACjE,YAAM,KAAK,OAAO,IAAI,KAAK,QAAQ,MAAM,GAAG;AAC5C,iBAAW,KAAK,QAAQ,MAAM,GAAG,CAAC,GAAG;AACnC,cAAM,KAAK,KAAK,EAAE,WAAW,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,YAAY,GAAG;AAAA,MACtE;AACA,UAAI,QAAQ,SAAS,EAAG,OAAM,KAAK,aAAa,QAAQ,SAAS,CAAC,QAAQ;AAAA,IAC5E;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,0BAA0B;AACrC,QAAM,KAAK,UAAU,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,MAAc,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAEzE,MAAI,kBAAkB;AACpB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,+GAA+G;AAAA,EAC5H;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,mBAAmB,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,IAC/E,mBAAmB;AAAA,MACjB,qBAAqB,MAAM,IAAI,KAAK,YAAY,aAAa,cAAc,MAAM,WAAW,cAAc,MAAM;AAAA,MAChH,EAAE,OAAO,qBAAqB,oBAAoB,cAAc,QAAQ,oBAAoB,cAAc,QAAQ,iBAAiB;AAAA,IACrI;AAAA,EACF;AACF;AAkBA,eAAe,eAAe,cAAsB;AAClD,QAAMA,UAAS,MAAM,YAAqE,+BAA+B;AAAA,IACvH;AAAA,EACF,CAAC;AAED,QAAM,YAAY,OAAO,KAAKA,QAAO,MAAM;AAE3C,MAAIA,QAAO,eAAe,GAAG;AAC3B,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,gBAAgB,YAAY;AAAA;AAAA,wBAA6B,YAAY;AAAA,MAC7E,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,OAAO,YAAY;AAAA,QACnB,EAAE,QAAQ,CAAC,GAAG,YAAY,GAAG,WAAW,MAAM;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB;AAAA,IACtB,gBAAgB,YAAY;AAAA,IAC5B,IAAIA,QAAO,UAAU,qBAAqB,UAAU,MAAM,qBAAqB,UAAU,WAAW,IAAI,KAAK,GAAG,GAAGA,QAAO,YAAY,6CAAwC,EAAE;AAAA,IAChL;AAAA,EACF;AAEA,aAAW,CAAC,YAAY,KAAK,KAAK,OAAO,QAAQA,QAAO,MAAM,GAAG;AAC/D,UAAM,KAAK,MAAM,UAAU,KAAK,MAAM,MAAM,GAAG;AAC/C,eAAW,QAAQ,OAAO;AACxB,YAAM,SAAS,KAAK,UAAU,KAAK,KAAK,OAAO,SAAS;AACxD,YAAM,OAAO,KAAK,kBAAkB,KAAK;AACzC,YAAM,KAAK,KAAK,MAAM,GAAG,KAAK,IAAI,WAAM,IAAI,KAAK,KAAK,qBAAqB,GAAG;AAAA,IAChF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAIA,QAAO,WAAW;AACpB,UAAM,KAAK,kGAAkG;AAAA,EAC/G;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,GAAGA,QAAO,UAAU,KAAK,YAAY,sBAAsB,UAAU,MAAM,gBAAgBA,QAAO,YAAY,gBAAgB,EAAE;AAAA,MAChIA;AAAA,IACF;AAAA,EACF;AACF;AAgCA,eAAe,gBACb,SACA,WACA,SACA,cACA;AAEA,QAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC;AAEpD,QAAMA,UAAS,MAAM,YAA6D,uBAAuB;AAAA,IACvG;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,EACzC,CAAC;AAED,MAAIA,QAAO,OAAO;AAChB,WAAO,eAAe,SAASA,QAAO,KAAK;AAAA,EAC7C;AAEA,MAAIA,QAAO,cAAc,GAAG;AAC1B,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,iBAAiB,OAAO;AAAA;AAAA,MACrB,SAAS,mBAAmB,eAAe,aAAa,YAAY,MAAM,EAAE;AAAA;AAAA,sCAC5C,OAAO,gBAAgB,cAAc,aAAa,aAAa,UAAU;AAAA,MAEpH,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,MAAM,SAAS,wBAAwB,OAAO;AAAA,QAC9CA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB;AAAA,IACtB,iBAAiB,OAAO;AAAA,IACxB,kBAAkB,SAAS,mBAAmB,WAAW,GAAG,eAAe,yBAAyB,YAAY,KAAK,EAAE;AAAA,IACvH,cAAcA,QAAO,UAAU,GAAGA,QAAO,YAAY,wBAAwB,EAAE,mBAAmBA,QAAO,MAAM,MAAM,oBAAoBA,QAAO,OAAO,MAAM;AAAA,IAC7J;AAAA,EACF;AAGA,QAAM,WAAW,KAAK,IAAI,GAAGA,QAAO,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAC7D,WAAS,IAAI,GAAG,KAAK,UAAU,KAAK;AAClC,UAAM,UAAUA,QAAO,MAAM,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC;AACxD,QAAI,QAAQ,WAAW,EAAG;AAE1B,UAAM,QAAQ,MAAM,IAAI,SAAS,SAAS,CAAC;AAC3C,UAAM,KAAK,MAAM,KAAK,KAAK,QAAQ,MAAM,GAAG;AAC5C,eAAW,QAAQ,SAAS;AAC1B,YAAM,SAAS,KAAK,OAAO,CAAC;AAC5B,YAAM,KAAK,KAAK,UAAU,KAAK,KAAK,OAAO,SAAS;AACpD,YAAM,aAAa,KAAK,iBAAiB,KAAK,KAAK,cAAc,MAAM;AACvE,YAAM,SAAS,KAAK,gBAAgB,SAAS,KAAK,aAAa,MAAM;AACrE,YAAM,KAAK,GAAG,MAAM,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,UAAU,GAAG,MAAM,EAAE;AAAA,IACjE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAIA,QAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,KAAK,oBAAoB;AAC/B,eAAW,SAASA,QAAO,QAAQ;AACjC,YAAM,KAAK,KAAK,MAAM,KAAK,KAAK,MAAM,CAAC,EAAE;AAAA,IAC3C;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAIA,QAAO,iBAAiB;AAC1B,UAAM,KAAK,yHAAyH;AAAA,EACtI;AAEA,MAAIA,QAAO,WAAW;AACpB,UAAM,KAAK,sFAAsF;AAAA,EACnG;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,kBAAkB,OAAO,KAAKA,QAAO,UAAU,WAAWA,QAAO,MAAM,MAAM,WAAWA,QAAO,OAAO,MAAM,YAAY,SAAS,WAAW,WAAW;AAAA,MACvJA;AAAA,IACF;AAAA,EACF;AACF;AAWA,eAAe,cAAc,OAAe;AAC1C,QAAM,UAAU,KAAK,MAAM,KAAK;AAChC,MAAI,MAAM,OAAO,GAAG;AAClB,WAAO,iBAAiB,+BAA+B,KAAK,uDAAuD;AAAA,EACrH;AAEA,QAAMA,UAAS,MAAM,YAA+D,yBAAyB,EAAE,OAAO,QAAQ,CAAC;AAE/H,QAAM,eAAeA,QAAO,QAAQ;AACpC,QAAM,iBAAiBA,QAAO,UAAU;AAExC,MAAI,iBAAiB,KAAK,mBAAmB,GAAG;AAC9C,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,mBAAmB,KAAK;AAAA;AAAA;AAAA,MAChC,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,6BAA6B,KAAK;AAAA,QAClC,EAAE,SAAS,CAAC,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC,GAAG,WAAW,MAAM;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB;AAAA,IACtB,mBAAmB,KAAK;AAAA,IACxB,IAAI,YAAY,sBAAsB,cAAc,qBAAqBA,QAAO,YAAY,2CAAsC,EAAE;AAAA,IACpI;AAAA,EACF;AAGA,MAAI,eAAe,GAAG;AACpB,UAAM,KAAK,qBAAqB;AAChC,UAAM,eAAe,OAAO,QAAQA,QAAO,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7E,eAAW,CAAC,MAAM,KAAK,KAAK,cAAc;AACxC,YAAM,KAAK,OAAO,IAAI,KAAK,KAAK,GAAG;AACnC,YAAM,cAAcA,QAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,mBAAmB,IAAI;AAC1E,iBAAW,KAAK,aAAa;AAC3B,cAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,cAAM,MAAM,cAAc,EAAE,SAAS;AACrC,cAAM,KAAK,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,GAAG,IAAI;AAAA,MAC1C;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAGA,MAAI,iBAAiB,GAAG;AACtB,UAAM,KAAK,kBAAkB;AAC7B,eAAW,KAAKA,QAAO,WAAW;AAChC,YAAM,OAAO,EAAE,eAAe;AAC9B,YAAM,KAAK,EAAE,aAAa;AAC1B,YAAM,MAAM,cAAc,EAAE,SAAS;AACrC,YAAM,KAAK,KAAK,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,MAAM,GAAG,IAAI;AAAA,IACvD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAIA,QAAO,WAAW;AACpB,UAAM,KAAK,uFAAuF;AAAA,EACpG;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,GAAG,YAAY,sBAAsB,cAAc,4BAA4B,KAAK,IAAIA,QAAO,YAAY,gBAAgB,EAAE;AAAA,MAC7HA;AAAA,IACF;AAAA,EACF;AACF;AAaA,eAAe,kBAAkB,OAAe;AAC9C,QAAMA,UAAS,MAAM,YAAkE,4BAA4B,EAAE,MAAM,CAAC;AAE5H,QAAM,eAAeA,QAAO,WAAW;AAIvC,QAAM,cAAcA,QAAO,WACxB,IAAI,CAAC,MAAM,EAAE,OAAO,EACpB,OAAO,CAAC,OAAqB,OAAO,IAAI;AAC3C,iBAAiE,wBAAwB;AAAA,IACvF;AAAA,IACA,iBAAiB;AAAA,IACjB,WAAW,KAAK,IAAI;AAAA,EACtB,CAAC,EAAE,MAAM,MAAM;AAAA,EAGf,CAAC;AAED,MAAI,iBAAiB,KAAK,CAACA,QAAO,YAAY;AAC5C,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,8BAAyB,KAAK;AAAA;AAAA,uCAA4C,cAAcA,QAAO,oBAAqB,CAAC;AAAA,MAC7H,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,6BAA6B,KAAK;AAAA,QAClCA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB;AAAA,IACtB,8BAAyB,KAAK;AAAA,EAChC;AAEA,MAAIA,QAAO,YAAY;AACrB,UAAM,KAAK,gDAA2C;AAAA,EACxD,OAAO;AACL,UAAM,KAAK,4BAA4B,cAAcA,QAAO,oBAAqB,CAAC,IAAI;AAAA,EACxF;AAEA,QAAM,KAAK,IAAI,YAAY,eAAeA,QAAO,YAAY,iBAAiB,EAAE,GAAG;AACnF,QAAM,KAAK,EAAE;AAEb,MAAI,eAAe,GAAG;AACpB,UAAM,KAAK,gBAAgB;AAG3B,UAAM,eAAyD,CAAC;AAChE,eAAW,KAAKA,QAAO,YAAY;AACjC,YAAM,OAAO,EAAE;AACf,UAAI,CAAC,aAAa,IAAI,EAAG,cAAa,IAAI,IAAI,CAAC;AAC/C,mBAAa,IAAI,EAAE,KAAK,CAAC;AAAA,IAC3B;AAEA,UAAM,cAAc,OAAO,QAAQ,YAAY,EAC5C,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EACxC,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AAEvB,eAAW,QAAQ,aAAa;AAC9B,YAAM,UAAU,aAAa,IAAI;AACjC,YAAM,KAAK,OAAO,IAAI,KAAK,QAAQ,MAAM,GAAG;AAC5C,iBAAW,KAAK,SAAS;AACvB,cAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,cAAM,MAAM,cAAc,EAAE,SAAS;AACrC,cAAM,KAAK,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,GAAG,IAAI;AAAA,MAC1C;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAIA,QAAO,WAAW;AACpB,UAAM,KAAK,iFAAiF;AAAA,EAC9F;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,GAAG,YAAY,2BAA2B,KAAK,IAAIA,QAAO,aAAa,iBAAiB,EAAE,IAAIA,QAAO,YAAY,gBAAgB,EAAE;AAAA,MACnIA;AAAA,IACF;AAAA,EACF;AACF;AAIA,eAAe,YAAY,WAAgD,SAAkB;AAC3F,QAAM,OAAgC,EAAE,MAAM,UAAU;AACxD,MAAI,YAAY,OAAW,MAAK,QAAQ;AAExC,QAAMA,UAAS,MAAM,YAA6D,uBAAuB,IAAI;AAE7G,MAAI,cAAc,YAAY;AAC5B,WAAO,oBAAoBA,OAAM;AAAA,EACnC;AAEA,MAAI,cAAc,cAAc;AAC9B,WAAO,qBAAqBA,OAAM;AAAA,EACpC;AAEA,MAAI,cAAc,SAAS;AACzB,WAAO,gBAAgBA,OAAM;AAAA,EAC/B;AAEA,SAAO,iBAAiB,sBAAsB,SAAS,EAAE;AAC3D;AAEA,SAAS,oBAAoBA,SAAa;AACxC,QAAM,UAAUA,QAAO;AACvB,QAAM,QAAQA,QAAO;AACrB,QAAM,YAAYA,QAAO;AAEzB,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,QAAQ,QAAQ,MAAM,sBAAsB,QAAQ,UAAU,MAAM,qBAAqB,QAAQ,YAAY,iBAAiB,EAAE;AAAA,IACpI;AAAA,EACF;AAGA,MAAI,OAAO,KAAK,QAAQ,MAAM,EAAE,SAAS,GAAG;AAC1C,UAAM,eAAe,OAAO,QAAQ,QAAQ,MAAgC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AACxG,eAAW,CAAC,MAAM,KAAK,KAAK,cAAc;AACxC,YAAM,KAAK,OAAO,IAAI,OAAO,KAAK,EAAE;AAAA,IACtC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,QAAM,KAAK,cAAc;AACzB,aAAW,CAAC,SAAS,GAAG,KAAK,OAAO,QAAQA,QAAO,SAAgC,GAAG;AACpF,UAAM,aAAa,OAAO,KAAK,IAAI,MAAM,EAAE;AAC3C,UAAM,KAAK,OAAO,OAAO,OAAO,IAAI,UAAU,qBAAqB,UAAU,qBAAqB,IAAI,YAAY,iBAAiB,EAAE,EAAE;AAAA,EACzI;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,uCAAuC;AAClD,MAAI,MAAM,YAAY;AACpB,UAAM,KAAK,iDAA4C;AAAA,EACzD;AACA,QAAM,KAAK,GAAG,MAAM,WAAW,MAAM,yCAAyC,MAAM,YAAY,iBAAiB,EAAE,EAAE;AACrH,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,wBAAwB;AACnC,QAAM,KAAK,YAAY,UAAU,KAAK,QAAQ,UAAU,YAAY,IAAI,UAAU,WAAW,iBAAiB;AAC9G,MAAI,UAAU,KAAK,SAAS,GAAG;AAC7B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW;AACtB,eAAW,OAAO,UAAU,KAAK,MAAM,GAAG,CAAC,GAAG;AAC5C,YAAM,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,OAAO,IAAI,IAAI,QAAQ,GAAG,IAAI,WAAW,WAAM,IAAI,QAAQ,KAAK,EAAE,EAAE;AAAA,IACxG;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,UAAU;AACrB,QAAM,KAAK,+MAA+M;AAC1N,QAAM,KAAK,EAAE;AAEb,MAAIA,QAAO,iBAAiB;AAC1B,UAAM,KAAK,+GAA+G;AAAA,EAC5H;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,mBAAmB,QAAQ,QAAQ,MAAM,aAAa,MAAM,WAAW,MAAM,iBAAiB,UAAU,KAAK;AAAA,MAC7G,EAAE,GAAGA,SAAQ,mBAAmB,KAAK;AAAA,IACvC;AAAA,EACF;AACF;AAEA,SAAS,qBAAqBA,SAAa;AACzC,QAAM,UAAUA,QAAO;AAEvB,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,QAAQ,QAAQ,MAAM,oBAAoB,QAAQ,YAAY,iBAAiB,EAAE;AAAA,IACrF;AAAA,EACF;AAGA,QAAM,KAAK,4BAA4BA,QAAO,gBAAgB,GAAG;AACjE,MAAIA,QAAO,WAAW,SAAS,GAAG;AAChC,eAAW,OAAOA,QAAO,YAAY;AACnC,YAAM,KAAK,IAAI,UAAU,KAAK,IAAI,OAAO,SAAS;AAClD,YAAM,KAAK,KAAK,EAAE,GAAG,IAAI,IAAI,KAAK,IAAI,MAAM,GAAG;AAAA,IACjD;AAAA,EACF,OAAO;AACL,UAAM,KAAK,4BAA4B;AAAA,EACzC;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,uBAAuBA,QAAO,YAAY,GAAG;AACxD,MAAIA,QAAO,eAAe,SAAS,GAAG;AACpC,eAAW,WAAWA,QAAO,gBAAgB;AAC3C,YAAM,KAAK,QAAQ,UAAU,KAAK,QAAQ,OAAO,SAAS;AAC1D,YAAM,KAAK,KAAK,EAAE,GAAG,QAAQ,IAAI,EAAE;AAAA,IACrC;AAAA,EACF,OAAO;AACL,UAAM,KAAK,uBAAuB;AAAA,EACpC;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,UAAU;AACrB,QAAM,KAAK,qRAAqR;AAChS,QAAM,KAAK,EAAE;AAEb,MAAIA,QAAO,iBAAiB;AAC1B,UAAM,KAAK,+GAA+G;AAAA,EAC5H;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,oBAAoB,QAAQ,QAAQ,MAAM,aAAaA,QAAO,gBAAgB,0BAA0BA,QAAO,YAAY;AAAA,MAC3H,EAAE,GAAGA,SAAQ,mBAAmB,KAAK;AAAA,IACvC;AAAA,EACF;AACF;AAEA,SAAS,gBAAgBA,SAAa;AACpC,QAAM,UAAUA,QAAO;AACvB,QAAM,YAAY,IAAI,KAAKA,QAAO,KAAK,EAAE,YAAY;AAErD,QAAM,QAAkB;AAAA,IACtB,sBAAsB,SAAS;AAAA,IAC/B,IAAI,QAAQ,QAAQ,MAAM,sBAAsB,QAAQ,UAAU,MAAM,qBAAqB,QAAQ,YAAY,iBAAiB,EAAE;AAAA,IACpI;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ,SAAS,GAAG;AAC9B,UAAM,KAAK,qBAAqB;AAChC,UAAM,eAAe,OAAO,QAAQ,QAAQ,MAAgC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AACxG,eAAW,CAAC,MAAM,KAAK,KAAK,cAAc;AACxC,YAAM,KAAK,OAAO,IAAI,KAAK,KAAK,GAAG;AACnC,YAAM,cAAc,QAAQ,QAAQ,OAAO,CAAC,MAAW,EAAE,mBAAmB,IAAI;AAChF,iBAAW,KAAK,aAAa;AAC3B,cAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,cAAM,MAAM,cAAc,EAAE,SAAS;AACrC,cAAM,KAAK,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,GAAG,IAAI;AAAA,MAC1C;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAI,QAAQ,UAAU,SAAS,GAAG;AAChC,UAAM,KAAK,kBAAkB;AAC7B,eAAW,KAAK,QAAQ,WAAW;AACjC,YAAM,OAAO,EAAE,eAAe;AAC9B,YAAM,KAAK,EAAE,aAAa;AAC1B,YAAM,MAAM,cAAc,EAAE,SAAS;AACrC,YAAM,KAAK,KAAK,IAAI,MAAM,EAAE,IAAI,MAAM,EAAE,MAAM,GAAG,IAAI;AAAA,IACvD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAIA,QAAO,iBAAiB;AAC1B,UAAM,KAAK,+GAA+G;AAAA,EAC5H;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,oBAAoB,SAAS,KAAK,QAAQ,QAAQ,MAAM,aAAa,QAAQ,UAAU,MAAM,cAAc,QAAQ,YAAY,gBAAgB,EAAE;AAAA,MACjJA;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,cAAc,IAAoB;AACzC,QAAM,OAAO,KAAK,IAAI,IAAI;AAC1B,MAAI,OAAO,IAAQ,QAAO;AAC1B,MAAI,OAAO,KAAW,QAAO,GAAG,KAAK,MAAM,OAAO,GAAM,CAAC;AACzD,MAAI,OAAO,MAAY,QAAO,GAAG,KAAK,MAAM,OAAO,IAAS,CAAC;AAC7D,SAAO,GAAG,KAAK,MAAM,OAAO,KAAU,CAAC;AACzC;;;AExiDA,SAAS,KAAAO,WAAS;;;ACNlB,SAAS,KAAAC,WAAS;AAIX,IAAM,eAAeC,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,KAAK,CAAC,QAAQ,UAAU,UAAU,UAAU,SAAS,QAAQ,CAAC,EACrE,SAAS,4FAA4F;AAAA,EACxG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,EAC3G,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,EAClF,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,EACzE,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,EAC7E,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,EAC3F,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,EAClG,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EACnE,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mCAAmC;AACtF,CAAC;AAOD,eAAsB,mBAAmB;AACvC,QAAM,SAAS,MAAM,YAAmB,kBAAkB;AAE1D,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,QAAQ,CAAC,GAAG,OAAO,EAAE;AAAA,MACvB,CAAC,EAAE,MAAM,eAAe,aAAa,kBAAkB,YAAY,EAAE,QAAQ,eAAe,EAAE,CAAC;AAAA,IACjG;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO;AAC7C,QAAM,YAAY,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE,QAAQ;AAChE,QAAM,WAAW,CAAC,aAAqB,OAAO,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AAEnF,QAAM,QAAkB,CAAC,oBAAoB;AAE7C,aAAW,SAAS,QAAQ;AAC1B,UAAM,KAAK;AAAA,KAAQ,MAAM,IAAI,EAAE;AAC/B,QAAI,MAAM,YAAa,OAAM,KAAK,IAAI,MAAM,WAAW,GAAG;AAC1D,eAAW,SAAS,SAAS,MAAM,GAAG,GAAG;AACvC,YAAM,IAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAK;AAC5C,YAAM,KAAK,SAAS,MAAM,IAAI,MAAM,MAAM,IAAI,GAAG,CAAC,EAAE;AAAA,IACtD;AAAA,EACF;AAEA,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,KAAK,gBAAgB;AAC3B,eAAW,SAAS,WAAW;AAC7B,YAAM,IAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAK;AAC5C,YAAM,KAAK,OAAO,MAAM,IAAI,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,cAAc,YAAO,MAAM,WAAW,MAAM,EAAE,EAAE;AAAA,IAC3G;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,SAAS,OAAO,MAAM,cAAc,OAAO,MAAM;AAAA,MACjD,EAAE,QAAQ,OAAO,OAAO,OAAO;AAAA,IACjC;AAAA,EACF;AACF;AAEA,eAAsB,mBACpB,MACA,MACA,OACA,aACA,YACA,SACA,OACA;AACA,MAAI;AACJ,MAAI,YAAY;AACd,UAAM,SAAS,MAAM,YAAmB,kBAAkB;AAC1D,UAAM,SAAS,OAAO,KAAK,CAAC,MAAW,EAAE,SAAS,UAAU;AAC5D,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,QACL,iBAAiB,UAAU;AAAA,QAC3B;AAAA,QACA,iBAAiB,UAAU;AAAA,QAC3B;AAAA,QACA,CAAC,EAAE,MAAM,eAAe,aAAa,eAAe,YAAY,EAAE,QAAQ,aAAa,EAAE,CAAC;AAAA,MAC5F;AAAA,IACF;AACA,eAAW,OAAO;AAAA,EACpB;AAEA,QAAM,eAAe,qBAAqB,EAAE,MAAM,MAAM,OAAO,aAAa,UAAU,SAAS,MAAM,CAAC;AACtG,SAAO;AAAA,IACL,UAAU,IAAI,MAAM,IAAI;AAAA,IACxB,kBAAkB,IAAI,MAAM,IAAI;AAAA,IAChC,EAAE,MAAM,MAAM,OAAO,WAAW;AAAA,IAChC,CAAC,EAAE,MAAM,eAAe,aAAa,eAAe,YAAY,EAAE,QAAQ,aAAa,EAAE,CAAC;AAAA,EAC5F;AACF;AAEA,eAAsB,mBACpB,MACA,MACA,OACA,aACA,SACA,OACA;AACA,QAAM,eAAe,qBAAqB,EAAE,MAAM,MAAM,OAAO,aAAa,SAAS,MAAM,CAAC;AAC5F,SAAO;AAAA,IACL,UAAU,IAAI;AAAA,IACd,kBAAkB,IAAI;AAAA,IACtB,EAAE,KAAK;AAAA,IACP,CAAC,EAAE,MAAM,eAAe,aAAa,eAAe,YAAY,EAAE,QAAQ,aAAa,EAAE,CAAC;AAAA,EAC5F;AACF;AAEA,eAAsB,mBAAmB,MAAc;AACrD,QAAM,eAA8D,qBAAqB,EAAE,KAAK,CAAC;AACjG,SAAO;AAAA,IACL,UAAU,IAAI;AAAA,IACd,kBAAkB,IAAI;AAAA,IACtB,EAAE,KAAK;AAAA,EACT;AACF;AAEA,eAAsB,kBAAkB,MAAc,SAAiB;AACrE,QAAM,eAAe,oBAAoB,EAAE,SAAS,WAAW,KAAK,CAAC;AACrE,SAAO,cAAc,UAAU,IAAI,gBAAgB,OAAO,KAAK,kBAAkB,IAAI,QAAQ,OAAO,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5H;AAEA,eAAsB,mBAAmB,MAAc,SAAiB;AACtE,QAAM,eAA8D,qBAAqB,EAAE,SAAS,WAAW,KAAK,CAAC;AACrH,SAAO,cAAc,UAAU,IAAI,kBAAkB,OAAO,KAAK,kBAAkB,IAAI,UAAU,OAAO,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChI;;;ADxFA,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAU;AAAA,EAAY;AAAA,EAAS;AAAA,EACjD;AAAA,EAAc;AAAA,EAAgB;AAAA,EAAgB;AAAA,EAAgB;AAAA,EAAe;AAC/E;AAGA,IAAM,yBAAyBC,IAAE,OAAO;AAAA,EACtC,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,6EAA6E;AAAA;AAAA;AAAA,EAGjH,MAAMA,IAAE,KAAK,CAAC,YAAY,cAAc,cAAc,SAAS,CAAC,EAC7D,SAAS,gLAAgL;AAAA,EAC5L,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACjC,SAAS,wHAAwH;AACtI,CAAC;AAED,IAAM,cAAcA,IAAE,OAAO;AAAA,EAC3B,KAAKA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,qDAAqD;AAAA,EACvF,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,+CAA+C;AAAA,EACnF,MAAMA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,8DAA8D;AAAA,EAChG,UAAUA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC1E,SAASA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EACrG,YAAYA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,EAChG,aAAaA,IAAE,KAAK,CAAC,QAAQ,SAAS,QAAQ,WAAW,UAAU,aAAa,CAAC,EAAE,SAAS,EACzF,SAAS,gEAAgE;AAAA,EAC5E,MAAMA,IAAE,KAAK,CAAC,UAAU,QAAQ,MAAM,CAAC,EAAE,SAAS,EAC/C,SAAS,2DAA2D;AAAA,EACvE,UAAUA,IAAE,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAC7C,SAAS,iFAAiF;AAAA;AAAA,EAE7F,cAAcA,IAAE,QAAQ,EAAE,SAAS,EAChC,SAAS,6EAA6E;AAAA;AAAA,EAEzF,SAASA,IAAE,OAAOA,IAAE,OAAO,GAAGA,IAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EACxD,SAAS,oEAAoE;AAAA,EAChF,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EACrC,SAAS,gDAAgD;AAAA,EAC5D,oBAAoBA,IAAE,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS,EACxD,SAAS,uCAAuC;AAAA;AAAA,EAEnD,cAAcA,IAAE,KAAK,CAAC,WAAW,YAAY,YAAY,gBAAgB,aAAa,SAAS,YAAY,CAAC,EAAE,SAAS,EACpH,SAAS,yGAAoG;AAAA;AAAA,EAEhH,WAAWA,IAAE,OAAO,EAAE,SAAS,EAC5B,SAAS,2GAA2G;AAAA;AAAA,EAEvH,WAAWA,IAAE,OAAO,EAAE,SAAS,EAC5B,SAAS,8EAAyE;AACvF,CAAC;AAGM,IAAM,oBAAoBA,IAAE,OAAO;AAAA,EACxC,QAAQA,IAAE,KAAK,mBAAmB,EAAE;AAAA,IAClC;AAAA,EAEF;AAAA,EACA,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+FAA+F;AAAA,EAC7I,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wFAAwF;AAAA,EACtI,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,mFAAmF;AAAA,EAC1I,SAASA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,oDAA+C;AAAA,EACjG,MAAMA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAC5E,UAAUA,IAAE,KAAK,CAAC,SAAS,aAAa,cAAc,aAAa,aAAa,CAAC,EAAE,SAAS,EACzF,SAAS,mFAAmF;AAAA,EAC/F,QAAQA,IAAE,MAAM,WAAW,EAAE,IAAI,GAAG,EAAE,SAAS,EAC5C,SAAS,sFAAsF;AAAA,EAClG,MAAMA,IAAE,KAAK,CAAC,QAAQ,QAAQ,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,wPAAmP;AAAA,EACjT,eAAeA,IAAE,OAAOA,IAAE,OAAO,GAAGA,IAAE,KAAK,CAAC,QAAQ,eAAe,QAAQ,WAAW,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,oFAAoF;AAAA;AAAA,EAEvM,qBAAqBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAC/C,SAAS,iJAAiJ;AAAA;AAAA,EAE7J,uBAAuBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACjD,SAAS,qHAAqH;AAAA;AAAA,EAEjI,uBAAuBA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAClE,SAAS,iJAAiJ;AAAA;AAAA,EAE7J,qBAAqBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAC/C,SAAS,gHAA2G;AAAA;AAAA,EAEvH,wBAAwBA,IAAE,OAAO,EAAE,SAAS,EACzC,SAAS,oHAA+G;AAAA;AAAA;AAAA,EAG3H,iBAAiBA,IAAE,MAAM,sBAAsB,EAAE,IAAI,EAAE,EAAE,SAAS,EAC/D,SAAS,sKAAsK;AAAA,EAClL,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAC3C,SAAS,uHAAuH;AAAA;AAAA,EAEnI,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,2DAA2D;AAAA,EACzG,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,0DAA0D;AAAA,EAC9G,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yFAAyF;AAAA,EAClI,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,EACnG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAC5F,CAAC;AAGD,IAAM,yBAAyBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,EAAE,CAAC;AACrE,IAAM,6BAA6BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,UAAU,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AACxG,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EACxC,QAAQA,IAAE,QAAQ,QAAQ;AAAA,EAC1B,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS;AAAA,EAC5C,SAASA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EACvC,MAAMA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAClC,UAAUA,IAAE,KAAK,CAAC,SAAS,aAAa,cAAc,aAAa,aAAa,CAAC,EAAE,SAAS;AAAA,EAC5F,QAAQA,IAAE,MAAM,WAAW,EAAE,IAAI,CAAC;AAAA,EAClC,MAAMA,IAAE,KAAK,CAAC,QAAQ,QAAQ,SAAS,CAAC;AAAA;AAAA,EACxC,eAAeA,IAAE,OAAOA,IAAE,OAAO,GAAGA,IAAE,KAAK,CAAC,QAAQ,eAAe,QAAQ,WAAW,KAAK,CAAC,CAAC,EAAE,SAAS;AAAA,EACxG,qBAAqBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAClD,uBAAuBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACpD,uBAAuBA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS;AAAA,EAC7D,qBAAqBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAClD,wBAAwBA,IAAE,OAAO,EAAE,SAAS;AAC9C,CAAC;AACD,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EACxC,QAAQA,IAAE,QAAQ,QAAQ;AAAA,EAC1B,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACnC,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS;AAAA,EAC5C,SAASA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EACvC,MAAMA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EAClC,UAAUA,IAAE,KAAK,CAAC,SAAS,aAAa,cAAc,aAAa,aAAa,CAAC,EAAE,SAAS;AAAA,EAC5F,QAAQA,IAAE,MAAM,WAAW,EAAE,SAAS;AAAA,EAAG,MAAMA,IAAE,KAAK,CAAC,QAAQ,QAAQ,SAAS,CAAC,EAAE,SAAS;AAAA,EAAG,eAAeA,IAAE,OAAOA,IAAE,OAAO,GAAGA,IAAE,KAAK,CAAC,QAAQ,eAAe,QAAQ,WAAW,KAAK,CAAC,CAAC,EAAE,SAAS;AAAA;AAAA,EACvM,qBAAqBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAClD,uBAAuBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACpD,uBAAuBA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS;AAAA,EAC7D,qBAAqBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAClD,wBAAwBA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC5C,iBAAiBA,IAAE,MAAM,sBAAsB,EAAE,SAAS;AAAA,EAC1D,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS;AAChD,CAAC;AACD,IAAM,0BAA0BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,EAAE,CAAC;AACvE,IAAM,2BAA2BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AACzE,IAAM,8BAA8BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,YAAY,EAAE,CAAC;AAChF,IAAM,gCAAgCA,IAAE,OAAO;AAAA,EAC7C,QAAQA,IAAE,QAAQ,cAAc;AAAA,EAChC,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACnC,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EAC3C,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzC,SAASA,IAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,OAAOA,IAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AACD,IAAM,gCAAgCA,IAAE,OAAO;AAAA,EAC7C,QAAQA,IAAE,QAAQ,cAAc;AAAA,EAChC,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACxB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACnC,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACnC,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EAC3C,SAASA,IAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,OAAOA,IAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AACD,IAAM,gCAAgCA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,cAAc,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAC/G,IAAM,+BAA+BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,aAAa,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAC3I,IAAM,gCAAgCA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,cAAc,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAEtI,IAAM,yBAAyBA,IAAE,mBAAmB,UAAU;AAAA,EACnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,2BAAuE;AAAA,EAClF,MAAM,EAAE,QAAQ,CAAC,GAAG,aAAa,qCAAqC;AAAA,EACtE,UAAU,EAAE,QAAQ,CAAC,MAAM,GAAG,aAAa,oBAAoB;AAAA,EAC/D,QAAQ,EAAE,QAAQ,CAAC,QAAQ,QAAQ,eAAe,WAAW,QAAQ,YAAY,UAAU,QAAQ,iBAAiB,uBAAuB,yBAAyB,yBAAyB,uBAAuB,wBAAwB,GAAG,aAAa,8GAA8G;AAAA,EAC1W,QAAQ,EAAE,QAAQ,CAAC,QAAQ,QAAQ,eAAe,WAAW,QAAQ,YAAY,UAAU,QAAQ,iBAAiB,uBAAuB,yBAAyB,yBAAyB,uBAAuB,0BAA0B,mBAAmB,eAAe,GAAG,aAAa,sNAAsN;AAAA,EACtf,OAAO,EAAE,QAAQ,CAAC,GAAG,aAAa,gDAAgD;AAAA,EAClF,QAAQ,EAAE,QAAQ,CAAC,GAAG,aAAa,oEAAoE;AAAA,EACvG,cAAc,EAAE,QAAQ,CAAC,GAAG,aAAa,8BAA8B;AAAA,EACvE,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,QAAQ,SAAS,eAAe,cAAc,WAAW,OAAO,GAAG,aAAa,8BAA8B;AAAA,EACjJ,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,QAAQ,SAAS,eAAe,WAAW,OAAO,GAAG,aAAa,oBAAoB;AAAA,EACzH,gBAAgB,EAAE,QAAQ,CAAC,MAAM,GAAG,aAAa,oBAAoB;AAAA,EACrE,eAAe,EAAE,QAAQ,CAAC,QAAQ,SAAS,GAAG,aAAa,iCAAiC;AAAA,EAC5F,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,SAAS,GAAG,aAAa,iCAAiC;AAC/F;AAEO,SAAS,yBAAyB,QAAyB;AAEhE,QAAM,sBAAqF;AAAA,IACzF,MAAM,MAAMC,YAAW;AAAA,IACvB,UAAU,CAAC,SAAS,eAAe,KAAK,IAAI;AAAA,IAC5C,QAAQ,CAAC,SAASC;AAAA,MAChB,KAAK;AAAA,MAAM,KAAK;AAAA,MAAM,KAAK;AAAA,MAAa,KAAK;AAAA,MAAS,KAAK;AAAA,MAAM,KAAK,YAAY;AAAA,MAAe,KAAK;AAAA,MACtG,EAAE,MAAM,KAAK,MAAM,eAAe,KAAK,eAAe,qBAAqB,KAAK,qBAAqB,uBAAuB,KAAK,uBAAuB,uBAAuB,KAAK,uBAAuB,qBAAqB,KAAK,qBAAqB,wBAAwB,KAAK,uBAAuB;AAAA,IAChT;AAAA,IACA,QAAQ,CAAC,SAAS;AAChB,YAAM,aAAa,KAAK,QAAQ,KAAK,eAAe,KAAK,WAAW,KAAK,QAAQ,KAAK,YAAY,KAAK,UAClG,KAAK,SAAS,UAAa,KAAK,kBAAkB,UAAa,KAAK,wBAAwB,UAAa,KAAK,0BAA0B,UAAa,KAAK,0BAA0B,UACpL,KAAK,wBAAwB,UAAa,KAAK,2BAA2B,UAAa,KAAK,oBAAoB,UAAa,KAAK,kBAAkB;AACzJ,UAAI,CAAC,YAAY;AACf,eAAO,QAAQ,QAAQ,iBAAiB,oQAAoQ,CAAC;AAAA,MAC/S;AACA,aAAO;AAAA,QACL,KAAK;AAAA,QAAM,KAAK;AAAA,QAAM,KAAK;AAAA,QAAa,KAAK;AAAA,QAAS,KAAK;AAAA,QAAM,KAAK;AAAA,QAAU,KAAK;AAAA,QACrF,EAAE,MAAM,KAAK,MAAM,eAAe,KAAK,eAAe,qBAAqB,KAAK,qBAAqB,uBAAuB,KAAK,uBAAuB,uBAAuB,KAAK,uBAAuB,qBAAqB,KAAK,qBAAqB,wBAAwB,KAAK,wBAAwB,iBAAiB,KAAK,iBAAiB,eAAe,KAAK,cAAc;AAAA,MAC1X;AAAA,IACF;AAAA,IACA,OAAO,MAAM,YAAY;AAAA,IACzB,QAAQ,MAAM,aAAa;AAAA,IAC3B,cAAc,MAAM,iBAAiB;AAAA,IACrC,gBAAgB,CAAC,SAAS,mBAAmB,KAAK,MAAM,KAAK,MAAM,KAAK,OAAO,KAAK,aAAa,KAAK,YAAY,KAAK,SAAS,KAAK,KAAK;AAAA,IAC1I,gBAAgB,CAAC,SAAS,mBAAmB,KAAK,MAAM,KAAK,MAAM,KAAK,OAAO,KAAK,aAAa,KAAK,SAAS,KAAK,KAAK;AAAA,IACzH,gBAAgB,CAAC,SAAS,mBAAmB,KAAK,IAAI;AAAA,IACtD,eAAe,CAAC,SAAS,kBAAkB,KAAK,MAAM,KAAK,OAAO;AAAA,IAClE,gBAAgB,CAAC,SAAS,mBAAmB,KAAK,MAAM,KAAK,OAAO;AAAA,EACtE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAkBF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,OAAO,iBAAiB,MAAM,eAAe,MAAM;AAAA,IAClF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,mBAAmB,IAAI;AAClD,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,eAAe,OAAO;AAAA,QAAG,MACzD,sBAAsB,eAAe,wBAAwB,OAAO,MAAM,0BAA0B,mBAAmB;AAAA,MACzH;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAyBA,eAAe,eAAe,MAAc;AAC1C,QAAM,MAAM,MAAM,YAA6C,uBAAuB,EAAE,KAAK,CAAC;AAE9F,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,MACL,eAAe,IAAI;AAAA,MACnB;AAAA,MACA,4BAA4B,IAAI;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAqB,CAAC;AAE5B,WAAS,KAAK,KAAK,IAAI,IAAI,OAAO,IAAI,IAAI,KAAK;AAC/C,MAAI,IAAI,YAAa,UAAS,KAAK,IAAI,WAAW;AAElD,QAAM,OAAO;AAAA,IACX,IAAI,WAAW,iBAAiB;AAAA,IAChC,IAAI,WAAW,kBAAkB,IAAI,QAAQ,KAAK;AAAA,IAClD,IAAI,WAAW,eAAe,IAAI,QAAQ,OAAO;AAAA,IACjD,IAAI,UAAU,gBAAgB,IAAI,OAAO,KAAK;AAAA,EAChD,EAAE,OAAO,OAAO,EAAE,KAAK,QAAK;AAC5B,MAAI,KAAM,UAAS,KAAK,IAAI;AAE5B,MAAI,IAAI,eAAe;AACrB,aAAS,KAAK;AAAA;AAAA;AAAA,EAAuB,IAAI,aAAa,EAAE;AAAA,EAC1D,WAAW,IAAI,SAAS;AACtB,aAAS,KAAK;AAAA;AAAA;AAAA,EAAmB,IAAI,OAAO,EAAE;AAAA,EAChD;AAKA,MAAI,IAAI,yBAAyB,IAAI,sBAAsB,SAAS,GAAG;AACrE,aAAS;AAAA,MACP;AAAA;AAAA;AAAA;AAAA,EAA8F,IAAI,sBAAsB,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,IACzJ;AAAA,EACF;AAEA,MAAI,IAAI,OAAO,SAAS,GAAG;AACzB,UAAM,YAAY,IAAI,OAAO,IAAI,CAAC,MAAM;AACtC,YAAM,QAAkB,CAAC;AACzB,YAAM,WAAW,GAAG,EAAE,IAAI,GAAG,EAAE,WAAW,eAAe,EAAE;AAC3D,YAAM,KAAK,SAAS,EAAE,GAAG,aAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG;AACjE,UAAI,EAAE,SAAU,OAAM,KAAK,EAAE,QAAQ;AACrC,UAAI,EAAE,WAAW,EAAE,QAAQ,SAAS,GAAG;AACrC,cAAM,WAAW,EAAE,QAAQ,IAAI,CAAC,QAAQ;AACtC,gBAAM,OAAO,EAAE,qBAAqB,GAAG;AACvC,iBAAO,OAAO,SAAS,GAAG,OAAO,IAAI,KAAK,OAAO,GAAG;AAAA,QACtD,CAAC;AACD,cAAM,KAAK;AAAA;AAAA,EAAe,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,MACjD;AACA,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB,CAAC;AACD,aAAS,KAAK;AAAA;AAAA;AAAA,EAAkB,UAAU,KAAK,MAAM,CAAC,EAAE;AAAA,EAC1D;AAEA,MAAI,IAAI,YAAY,IAAI,SAAS,SAAS,GAAG;AAC3C,UAAM,SAAS,IAAI,SAAS,IAAI,CAAC,OAAO,OAAO,GAAG,IAAI,aAAQ,GAAG,WAAW,EAAE,EAAE,KAAK,IAAI;AACzF,aAAS,KAAK;AAAA;AAAA;AAAA,EAAoB,MAAM,EAAE;AAAA,EAC5C;AAEA,MAAI,IAAI,mBAAmB,IAAI,gBAAgB,SAAS,GAAG;AACzD,UAAM,UAAU,IAAI,gBAAgB;AAAA,MAAI,CAAC,MACvC,OAAO,EAAE,IAAI,OAAO,EAAE,YAAY,MAAM,EAAE,QAAQ;AAAA,IACpD,EAAE,KAAK,IAAI;AACX,aAAS,KAAK;AAAA;AAAA;AAAA,EAA+B,OAAO,EAAE;AAAA,EACxD;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;AAAA,IAChE,mBAAmB;AAAA,MACjB,iCAAiC,IAAI,IAAI,MAAM,IAAI,IAAI;AAAA,MACvD;AAAA,QACE,MAAM,IAAI;AAAA,QACV,MAAM,IAAI;AAAA,QACV,aAAa,IAAI;AAAA,QACjB,eAAe,IAAI,iBAAiB;AAAA;AAAA,QAEpC,uBACE,IAAI,yBAAyB,IAAI,sBAAsB,SAAS,IAC5D,IAAI,wBACJ;AAAA,QACN,YAAY,IAAI,OAAO;AAAA,QACvB,QAAQ,IAAI,OAAO,IAAI,CAAC,OAAO;AAAA,UAC7B,KAAK,EAAE;AAAA,UACP,MAAM,EAAE;AAAA,UACR,UAAU,EAAE;AAAA,UACZ,UAAU,EAAE,YAAY;AAAA,UACxB,SAAS,EAAE,WAAW;AAAA,UACtB,oBAAoB,EAAE,sBAAsB;AAAA,QAC9C,EAAE;AAAA,QACF,UAAU,IAAI,YAAY,CAAC;AAAA,QAC3B,iBAAiB,IAAI,mBAAmB,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAeD,cAAa;AAC1B,QAAM,cAAc,MAAM,YAAgC,uBAAuB;AAEjF,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,aAAa,CAAC,GAAG,OAAO,EAAE;AAAA,MAC5B,CAAC,EAAE,MAAM,eAAe,aAAa,qBAAqB,YAAY,EAAE,QAAQ,SAAS,EAAE,CAAC;AAAA,IAC9F;AAAA,EACF;AAEA,QAAM,YAAY,YACf,IAAI,CAAC,MAAM;AACV,UAAM,YAAY,EAAE,OACjB,IAAI,CAAC,MAAM,SAAS,EAAE,GAAG,OAAO,EAAE,IAAI,GAAG,EAAE,WAAW,eAAe,EAAE,GAAG,EAAE,aAAa,iBAAiB,EAAE,GAAG,EAC/G,KAAK,IAAI;AACZ,UAAM,OAAO;AAAA,MACX,EAAE,eAAe;AAAA,MACjB,EAAE,UAAU,gBAAgB,EAAE,OAAO,KAAK;AAAA,MAC1C,EAAE,WAAW,kBAAkB,EAAE,QAAQ,KAAK;AAAA,IAChD,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAC3B,WAAO,MAAM,EAAE,IAAI,OAAO,EAAE,IAAI;AAAA,EAAQ,IAAI;AAAA;AAAA;AAAA,EAAoB,SAAS;AAAA,EAC3E,CAAC,EACA,KAAK,aAAa;AAErB,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,4BAA4B,YAAY,MAAM;AAAA;AAAA,EAAQ,SAAS,GAAG,CAAC;AAAA,IAC5G,mBAAmB;AAAA,MACjB,SAAS,YAAY,MAAM;AAAA,MAC3B;AAAA,QACE,aAAa,YAAY,IAAI,CAAC,OAAO;AAAA,UACnC,MAAM,EAAE;AAAA,UACR,MAAM,EAAE;AAAA,UACR,aAAa,EAAE;AAAA,UACf,YAAY,EAAE,OAAO;AAAA,QACvB,EAAE;AAAA,QACF,OAAO,YAAY;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAgBA,SAAS,WAAW,GAAoD;AAAE,SAAO,OAAO,YAAY,OAAO,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,CAAC;AAAkC;AAE1L,eAAeC,cACb,MACA,MACA,aACA,SACA,MACA,UACA,QACA,OAA2B,CAAC,GAC5B;AACA,qBAAmB;AAEnB,MAAI;AACF,UAAM,eAAe,0BAA0B;AAAA,MAC7C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,WAAW,IAAI;AAAA,MAClB,WAAW,kBAAkB,IAAI,SAAS,kBAAkB,CAAC,KAAK;AAAA,IACpE,CAAC;AAMD,sCAAkC;AAClC,mCAA+B;AAC/B,+BAA2B;AAE3B,UAAM,YAAY,OACf,IAAI,CAAC,MAAM,SAAS,EAAE,GAAG,OAAO,EAAE,IAAI,GAAG,EAAE,WAAW,eAAe,EAAE,GAAG,EAAE,aAAa,iBAAiB,EAAE,GAAG,EAC/G,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,yBAAyB,IAAI;AAAA;AAAA,cAClB,IAAI;AAAA,KAClB,cAAc,oBAAoB,WAAW;AAAA,IAAO,OACpD,UAAU,gBAAgB,OAAO;AAAA,IAAO,MACzC,kBAAkB,QAAQ;AAAA;AAAA;AAAA,EACR,SAAS;AAAA;AAAA,qDAC2B,IAAI;AAAA,MAC9D,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,uBAAuB,IAAI,MAAM,IAAI,UAAU,OAAO,MAAM;AAAA,QAC5D,EAAE,MAAM,MAAM,aAAa,SAAS,UAAU,YAAY,OAAO,OAAO;AAAA,QACxE,CAAC,EAAE,MAAM,WAAW,aAAa,oBAAoB,YAAY,EAAE,YAAY,KAAK,EAAE,CAAC;AAAA,MACzF;AAAA,IACF;AAAA,EACF,SAAS,OAAgB;AACvB,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,QAAI,IAAI,SAAS,gBAAgB,GAAG;AAClC,aAAO;AAAA,QACL,eAAe,IAAI;AAAA,QACnB;AAAA,QACA,eAAe,IAAI;AAAA,QACnB;AAAA,QACA,CAAC,EAAE,MAAM,eAAe,aAAa,qBAAqB,YAAY,EAAE,QAAQ,UAAU,KAAK,EAAE,CAAC;AAAA,MACpG;AAAA,IACF;AACA,UAAM,OAAQ,MAA4B,QAAS,MAAuC,MAAM;AAChG,QAAI,SAAS,6BAA6B,IAAI,SAAS,4BAA4B,GAAG;AACpF,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,EAAE,MAAM,eAAe,aAAa,0CAA0C,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,MACjH;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,aACb,MACA,MACA,aACA,SACA,MACA,UACA,QACA,OAA2B,CAAC,GAC5B;AACA,qBAAmB;AAEnB,QAAM,eAAe,0BAA0B;AAAA,IAC7C;AAAA,IACA,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,IACjC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,IAC/C,GAAI,YAAY,UAAa,EAAE,QAAQ;AAAA,IACvC,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,IACjC,GAAI,aAAa,UAAa,EAAE,SAAS;AAAA,IACzC,GAAI,WAAW,UAAa,EAAE,OAAO;AAAA,IACrC,GAAG,WAAW,IAAI;AAAA,EACpB,CAAC;AAMD,oCAAkC;AAClC,iCAA+B;AAC/B,6BAA2B;AAE3B,QAAM,UAAU,CAAC,QAAQ,QAAQ,eAAe,eAAe,WAAW,WAAW,QAAQ,QAAQ,YAAY,YAAY,UAAU,UAAU,KAAK,SAAS,UAAa,QAAQ,KAAK,kBAAkB,UAAa,iBAAiB,KAAK,wBAAwB,UAAa,uBAAuB,KAAK,0BAA0B,UAAa,yBAAyB,KAAK,0BAA0B,UAAa,yBAAyB,KAAK,wBAAwB,UAAa,uBAAuB,KAAK,2BAA2B,UAAa,0BAA0B,KAAK,oBAAoB,UAAa,mBAAmB,KAAK,kBAAkB,UAAa,eAAe,EACrqB,OAAO,OAAO,EAAE,KAAK,IAAI;AAE5B,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MAAM,2BAA2B,IAAI;AAAA;AAAA,WAAkB,WAAW,YAAY;AAAA;AAAA;AAAA,IAEhF,CAAC;AAAA,IACD,mBAAmB;AAAA,MACjB,uBAAuB,IAAI,eAAe,WAAW,YAAY;AAAA,MACjE,EAAE,MAAM,QAAQ;AAAA,IAClB;AAAA,EACF;AACF;AAuBA,eAAe,cAAc;AAC3B,QAAM,OAAO,MAAM,YAAgE,wBAAwB;AAE3G,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,2BAA2B;AACtC,QAAM,KAAK;AAAA,aAAgB,KAAK,KAAK,sBAAmB,KAAK,OAAO,0BAAuB,KAAK,UAAU,EAAE;AAE5G,MAAI,KAAK,eAAe,GAAG;AACzB,UAAM,KAAK;AAAA,6BAAgC;AAAA,EAC7C,OAAO;AACL,UAAM,cAAc,KAAK,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,CAAC;AACtE,UAAM,KAAK;AAAA;AAAA,CAAgC;AAC3C,eAAW,OAAO,aAAa;AAC7B,YAAM,OAAO,IAAI,QAAQ;AACzB,YAAM,KAAK,OAAO,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,cAAS,IAAI,OAAO,MAAM,WAAW;AACtF,iBAAW,SAAS,IAAI,QAAQ;AAC9B,cAAM,KAAK,QAAQ,MAAM,IAAI,OAAO,MAAM,OAAO,EAAE;AAAA,MACrD;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,QAAM,qBAAqB,KAAK,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO,WAAW,CAAC;AAC/E,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,KAAK;AAAA;AAAA,CAA4B;AACvC,UAAM,KAAK,mBAAmB,IAAI,CAAC,MAAM,KAAK,EAAE,QAAQ,QAAG,MAAM,EAAE,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,EACzF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,mBAAmB,KAAK,KAAK,iBAAiB,KAAK,OAAO,aAAa,KAAK,UAAU;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AACF;AASA,eAAe,eAAe;AAC5B,QAAM,cAAc,MAAM,YAAuC,yBAAyB;AAE1F,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,aAAa,MAAM,CAAC,EAAE,CAAC;AAAA,IAC/E,mBAAmB;AAAA,MACjB,YAAY,YAAY,MAAM;AAAA,MAC9B,EAAE,aAAa,OAAO,YAAY,OAAO;AAAA,IAC3C;AAAA,EACF;AACF;;;AE9qBA,SAAS,KAAAC,WAAS;;;ACqBX,SAAS,iBAAiB,YAAgC;AAC/D,QAAMC,UAAsB;AAAA,IAC1B,mBAAmB,CAAC;AAAA,IACpB,mBAAmB,CAAC;AAAA,IACpB,cAAc,CAAC;AAAA,EACjB;AAEA,aAAW,SAAS,YAAY;AAC9B,QAAI,MAAM,YAAY,SAAU;AAEhC,UAAM,aAAa,MAAM,kBAAkB,MAAM,cAAc;AAE/D,QAAI,MAAM,WAAW,SAAS;AAC5B,MAAAA,QAAO,kBAAkB,KAAK,EAAE,MAAM,MAAM,MAAM,WAAW,CAAC;AAAA,IAChE;AAIA,UAAM,YAAY,MAAM,iBAAiB,aAAa,eAAe;AACrE,QAAI,aAAa,MAAM,mBAAmB,QAAQ;AAChD,MAAAA,QAAO,aAAa,KAAK,EAAE,MAAM,MAAM,MAAM,SAAS,MAAM,WAAW,MAAM,IAAI,CAAC;AAAA,IACpF;AAEA,QAAI,MAAM,mBAAmB,eAAe;AAC1C,MAAAA,QAAO,kBAAkB,KAAK;AAAA,QAC5B,MAAM,MAAM;AAAA,QACZ;AAAA,QACA,SAAS,MAAM,WAAW,MAAM;AAAA,MAClC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAOA;AACT;AAEA,eAAsB,mBAAyC;AAC7D,MAAI;AACF,UAAM,aAAa,MAAM,YAA2D,qBAAqB;AAAA,MACvG,QAAQ,CAAC,OAAO,WAAW,QAAQ,UAAU,kBAAkB,kBAAkB,WAAW,cAAc;AAAA,IAC5G,CAAC;AACD,QAAI,CAAC,WAAY,QAAO,EAAE,mBAAmB,CAAC,GAAG,mBAAmB,CAAC,GAAG,cAAc,CAAC,EAAE;AACzF,WAAO,iBAAiB,UAAU;AAAA,EACpC,QAAQ;AACN,WAAO,EAAE,mBAAmB,CAAC,GAAG,mBAAmB,CAAC,GAAG,cAAc,CAAC,EAAE;AAAA,EAC1E;AACF;AAEO,SAAS,eAAe,MAA4B;AACzD,SACE,KAAK,kBAAkB,SAAS,KAChC,KAAK,kBAAkB,SAAS,KAChC,KAAK,aAAa,SAAS;AAE/B;AAGO,SAAS,oBAAoB,OAYvB;AACX,QAAM,MAAM,CAAC,OAAgE,aAC3E,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,KAAK,EAAE,UAAU,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,KACrE,YAAY,WAAW,IAAI,MAAM,QAAQ,WAAW;AAEvD,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,2BAAsB,MAAM,IAAI,KAAK,MAAM,QAAQ,aAAa,MAAM,MAAM;AAAA,IAC5E,YAAY,MAAM,QAAQ,UAAU,MAAM,mBAAmB,EAAE,MAAM,IAAI,MAAM,SAAS,MAAM,eAAe,CAAC;AAAA,IAC9G,aAAa,MAAM,SAAS,UAAU,MAAM,oBAAoB,EAAE,MAAM,IAAI,MAAM,UAAU,MAAM,gBAAgB,CAAC;AAAA,IACnH,yBAAyB,MAAM,uBAAuB,UAAU,MAAM,kBAAkB,EAAE,MAAM,IAAI,MAAM,wBAAwB,MAAM,cAAc,CAAC;AAAA,IACvJ,sBAAsB,MAAM,gBAAgB;AAAA,IAC5C;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,wBACd,MACA,eACA,eACU;AACV,MAAI,CAAC,eAAe,IAAI,KAAK,cAAc,WAAW,EAAG,QAAO,CAAC;AAEjE,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,qCAAqC;AAChD,QAAM,KAAK,EAAE;AAEb,MAAI,KAAK,kBAAkB,SAAS,GAAG;AACrC,UAAM,MAAM,KAAK,kBAAkB,CAAC;AACpC,UAAM,KAAK,eAAe,IAAI,IAAI,OAAO,IAAI,UAAU,4BAAuB;AAC9E,eAAW,SAAS,KAAK,kBAAkB,MAAM,GAAG,CAAC,GAAG;AACtD,YAAM,KAAK,KAAK,MAAM,IAAI,KAAK,MAAM,UAAU,GAAG;AAAA,IACpD;AACA,QAAI,KAAK,kBAAkB,SAAS,GAAG;AACrC,YAAM,KAAK,aAAa,KAAK,kBAAkB,SAAS,CAAC,oBAAoB;AAAA,IAC/E;AAAA,EACF;AAEA,MAAI,KAAK,kBAAkB,SAAS,GAAG;AACrC,UAAM,QAAQ,KAAK,kBAAkB;AACrC,UAAM,QAAQ,UAAU,IAAI,mBAAmB,GAAG,KAAK;AACvD,UAAM,WAAW,KAAK,kBACnB,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AACZ,UAAM,KAAK,OAAO,KAAK,aAAQ,QAAQ,GAAG,QAAQ,IAAI,UAAU,EAAE,EAAE;AAAA,EACtE;AAEA,MAAI,KAAK,aAAa,SAAS,GAAG;AAChC,UAAM,MAAM,KAAK,aAAa,CAAC;AAC/B,UAAM,QAAQ,KAAK,aAAa;AAChC,QAAI,UAAU,GAAG;AACf,YAAM,KAAK,qBAAqB,IAAI,IAAI,0CAAqC;AAAA,IAC/E,OAAO;AACL,YAAM,KAAK,OAAO,KAAK,gCAA2B,IAAI,IAAI,EAAE;AAAA,IAC9D;AAAA,EACF;AAEA,MAAI,cAAc,SAAS,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,eAAe;AACvE,UAAM,OAAO,cAAc,CAAC;AAG5B,UAAM,OAAO,KAAK,cAAc,SAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IACnD;AACJ,UAAM,UAAU,MAAM,QAAQ,KAAK,cAAc,IAAI,KAAK,eAAe,SAAS,KAAK,kBAAkB;AACzG,UAAM,WAAW,MAAM,QAAQ,KAAK,eAAe,IAAI,KAAK,gBAAgB,SAAS,KAAK,mBAAmB;AAC7G,QAAI,UAAU,KAAK,WAAW,GAAG;AAC/B,YAAM,KAAK,uBAAuB,IAAI,MAAM,OAAO,aAAa,QAAQ,WAAW;AAAA,IACrF;AAAA,EACF;AAEA,MAAI,eAAe;AACjB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,GAAG,oBAAoB,aAAa,CAAC;AAAA,EAClD;AAEA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;;;ACrJO,IAAM,oBAA4C;AAAA;AAAA;AAAA,EAGvD;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,eAAe;AAAA,EACjB;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,eAAe;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,eAAe;AAAA,EACjB;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,YAAY;AAAA;AAAA,IAEZ,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,eAAe;AAAA,EACjB;AAAA;AAEF;AAEO,IAAM,4BAAsD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjE;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AACF;;;ACrEA,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,WAAAC,gBAAe;AAOjB,SAAS,kBACd,aACA,UACoB;AACpB,MAAI,CAAC,YAAa,QAAO,CAAC;AAE1B,QAAM,WAAgD,CAAC;AAEvD,aAAW,OAAO,UAAU;AAC1B,QAAI;AACF,YAAM,WAAWA,SAAQ,aAAa,IAAI,IAAI;AAC9C,YAAM,UAAUD,cAAa,UAAU,OAAO;AAC9C,YAAM,QAAQ,aAAa,SAAS,IAAI,UAAU;AAClD,UAAI,CAAC,MAAO;AAEZ,YAAM,OAAO,YAAY,OAAO,IAAI,aAAa;AACjD,UAAI,KAAK,OAAO,GAAG;AACjB,iBAAS,IAAI,EAAE,IAAI;AAAA,MACrB;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,QAAQ,IAAI,iBAAiB;AAC/B,gBAAQ,MAAM,wBAAwB,IAAI,EAAE,KAAK,IAAI,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,MACzG;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,aAAa,SAAiB,YAAmC;AACxE,QAAM,UAAU,WAAW,QAAQ,uBAAuB,MAAM;AAChE,QAAM,UAAU,IAAI;AAAA,IAClB,uCAAuC,OAAO;AAAA,EAChD;AACA,QAAM,QAAQ,QAAQ,KAAK,OAAO;AAClC,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,MAAM,MAAM,QAAQ,MAAM,CAAC,EAAE;AACjC,SAAO,MAAM,QAAQ,UAAU,KAAK,KAAK,QAAQ,GAAG,CAAE,EAAG;AAEzD,QAAM,KAAK,QAAQ,GAAG;AAEtB,MAAI,OAAO,OAAO,OAAO,KAAK;AAC5B,WAAO,gBAAgB,SAAS,KAAK,IAAI,OAAO,MAAM,MAAM,GAAG;AAAA,EACjE;AAGA,MAAI,QAAQ,MAAM,GAAG,EAAE,WAAW,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,WAAW,UAAU,KAAK,QAAQ,MAAM,GAAG,EAAE,WAAW,WAAY,GAAG;AACxI,UAAM,WAAW,QAAQ,MAAM,GAAG,EAAE,MAAM,sBAAsB;AAChE,QAAI,UAAU;AACZ,aAAO,gBAAgB,SAAS,MAAM,SAAS,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG;AAAA,IACxE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,gBACP,SACA,SACA,UACA,WACe;AACf,MAAI,QAAQ;AACZ,MAAI,IAAI,UAAU;AAElB,SAAO,IAAI,QAAQ,UAAU,QAAQ,GAAG;AACtC,UAAM,KAAK,QAAQ,CAAC;AAEpB,QAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC1C,UAAI,WAAW,SAAS,GAAG,EAAE;AAC7B;AAAA,IACF;AACA,QAAI,OAAO,OAAO,IAAI,IAAI,QAAQ,UAAU,QAAQ,IAAI,CAAC,MAAM,KAAK;AAClE,aAAO,IAAI,QAAQ,UAAU,QAAQ,CAAC,MAAM,KAAM;AAClD;AAAA,IACF;AACA,QAAI,OAAO,OAAO,IAAI,IAAI,QAAQ,UAAU,QAAQ,IAAI,CAAC,MAAM,KAAK;AAClE,WAAK;AACL,aAAO,IAAI,QAAQ,QAAQ;AACzB,YAAI,QAAQ,CAAC,MAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,KAAK;AAAE;AAAK;AAAA,QAAO;AACzE;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,OAAO,SAAU;AAAA,aACZ,OAAO,UAAW;AAC3B;AAAA,EACF;AAEA,MAAI,UAAU,EAAG,QAAO;AACxB,SAAO,QAAQ,MAAM,UAAU,GAAG,IAAI,CAAC;AACzC;AAQA,SAAS,WAAW,SAAiB,OAAe,OAAuB;AACzE,MAAI,IAAI,QAAQ;AAChB,SAAO,IAAI,QAAQ,QAAQ;AACzB,UAAM,KAAK,QAAQ,CAAC;AACpB,QAAI,OAAO,MAAM;AACf,WAAK;AACL;AAAA,IACF;AACA,QAAI,OAAO,MAAO,QAAO,IAAI;AAC7B;AAAA,EACF;AACA,SAAO;AACT;AAIA,SAAS,YAAY,OAAe,YAAwC;AAC1E,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,aAAO,kBAAkB,KAAK;AAAA,IAChC,KAAK;AACH,aAAO,kBAAkB,KAAK;AAAA,IAChC,KAAK;AACH,aAAO,iBAAiB,KAAK;AAAA,EACjC;AACF;AAMA,SAAS,kBAAkB,OAA4B;AACrD,QAAM,OAAO,oBAAI,IAAY;AAC7B,MAAI,QAAQ;AACZ,MAAI,IAAI;AAER,SAAO,IAAI,MAAM,QAAQ;AACvB,UAAM,KAAK,MAAM,CAAC;AAElB,QAAI,OAAO,OAAO,IAAI,IAAI,MAAM,UAAU,MAAM,IAAI,CAAC,MAAM,KAAK;AAC9D,aAAO,IAAI,MAAM,UAAU,MAAM,CAAC,MAAM,KAAM;AAC9C;AAAA,IACF;AACA,QAAI,OAAO,OAAO,IAAI,IAAI,MAAM,UAAU,MAAM,IAAI,CAAC,MAAM,KAAK;AAC9D,WAAK;AACL,aAAO,IAAI,MAAM,QAAQ;AACvB,YAAI,MAAM,CAAC,MAAM,OAAO,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM,KAAK;AAAE;AAAK;AAAA,QAAO;AACrE;AAAA,MACF;AACA;AAAA,IACF;AAGA,QAAI,UAAU,GAAG;AACf,YAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,YAAM,SAAS,KAAK,MAAM,uBAAuB;AACjD,UAAI,QAAQ;AACV,aAAK,IAAI,OAAO,CAAC,CAAE;AACnB,aAAK,OAAO,CAAC,EAAE;AACf;AAAA,MACF;AACA,YAAM,QAAQ,KAAK,MAAM,eAAe;AACxC,UAAI,OAAO;AACT,aAAK,IAAI,MAAM,CAAC,CAAE;AAClB,aAAK,MAAM,CAAC,EAAE;AACd;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC1C,UAAI,WAAW,OAAO,GAAG,EAAE;AAC3B;AAAA,IACF;AAEA,QAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAAE;AAAS;AAAK;AAAA,IAAU;AACtE,QAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAAE;AAAS;AAAK;AAAA,IAAU;AAEtE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAA4B;AACrD,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,KAAK,MAAM,SAAS,6BAA6B,GAAG;AAC7D,UAAM,IAAI,EAAE,CAAC,CAAE;AAAA,EACjB;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,OAA4B;AACpD,QAAM,SAAS,oBAAI,IAAY;AAC/B,aAAW,KAAK,MAAM,SAAS,qBAAqB,GAAG;AACrD,WAAO,IAAI,EAAE,CAAC,CAAE;AAAA,EAClB;AACA,SAAO;AACT;;;ACrNA,SAAS,gBAAgB;AAQlB,SAAS,wBAAwB,aAAkC;AACxE,MAAI,CAAC,YAAa,QAAO,oBAAI,IAAI;AAEjC,QAAM,gBAAgB,IAAI,IAAI,kBAAkB,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAClE,QAAM,UAAU,oBAAI,IAAY;AAEhC,MAAI;AACF,UAAM,MAAM,SAAS,iEAAiE;AAAA,MACpF,KAAK;AAAA,MACL,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AAED,eAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,WAAW,cAAc,IAAI,OAAO,GAAG;AACzC,gBAAQ,IAAI,OAAO;AAAA,MACrB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,QAAQ,IAAI,iBAAiB;AAC/B,cAAQ,MAAM,qCAAqC,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,IAC7F;AAAA,EACF;AAEA,SAAO;AACT;;;ACmBA,SAAS,uBAAuB,KAAsB;AACpD,MAAI,eAAe,iBAAiB;AAClC,WAAO,IAAI,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI;AAAA,EACxD;AACA,MAAI,eAAe,MAAO,QAAO,IAAI;AACrC,SAAO,OAAO,GAAG;AACnB;AA6BA,eAAsB,kBAAkB,aAAqD;AAC3F,QAAM,WAAW,kBAAkB,aAAa,iBAAiB;AAIjE,MAAI,OAAO,KAAK,QAAQ,EAAE,SAAS,EAAG,QAAO,EAAE,QAAQ,UAAU;AAEjE,QAAM,eAAe,OAAO,QAAQ,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,IAAI,OAAO,CAAC,GAAG,KAAK,EAAE,EAAE;AAE9F,MAAI;AACF,UAAME,UAAS,MAAM,YAAqC,2BAA2B;AAAA,MACnF,UAAU;AAAA,MACV,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AACD,WAAO,EAAE,QAAQ,MAAM,QAAQA,QAAO,QAAQ,UAAUA,QAAO,SAAS;AAAA,EAC1E,SAAS,KAAK;AACZ,UAAM,SAAS,uBAAuB,GAAG;AACzC,QAAI,QAAQ,IAAI,iBAAiB;AAC/B,cAAQ,MAAM,4DAA4D,MAAM;AAAA,IAClF;AACA,WAAO,EAAE,QAAQ,WAAW,OAAO;AAAA,EACrC;AACF;AAIO,SAAS,qBAAqB,QAAmC;AACtE,QAAM,QAAkB,CAAC,uBAAuB;AAEhD,MAAI,OAAO,QAAQ,UAAU,GAAG;AAC9B,UAAM,KAAK,iDAA4C;AACvD,UAAM,KAAK,EAAE;AACb,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,QAAQ,SAAS,EAAG,OAAM,KAAK,GAAG,OAAO,QAAQ,MAAM,SAAS,OAAO,QAAQ,WAAW,IAAI,KAAK,GAAG,EAAE;AACnH,MAAI,OAAO,QAAQ,WAAW,EAAG,OAAM,KAAK,GAAG,OAAO,QAAQ,QAAQ,WAAW,OAAO,QAAQ,aAAa,IAAI,KAAK,GAAG,EAAE;AAC3H,MAAI,OAAO,QAAQ,QAAQ,EAAG,OAAM,KAAK,GAAG,OAAO,QAAQ,KAAK,OAAO;AACvE,QAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,IAAI,KAAK,GAAG,aAAa,OAAO,eAAe,gBAAgB,MAAM,KAAK,IAAI,CAAC,GAAG;AAEtJ,QAAM,SAAS,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACrE,QAAM,WAAW,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,aAAa,SAAS;AAEzE,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,wBAAwB;AACnC,eAAW,KAAK,OAAO,MAAM,GAAG,CAAC,GAAG;AAClC,YAAM,KAAK,KAAK,EAAE,OAAO,EAAE;AAAA,IAC7B;AACA,QAAI,OAAO,SAAS,EAAG,OAAM,KAAK,YAAY,OAAO,SAAS,CAAC,OAAO;AAAA,EACxE;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,eAAe;AAC1B,eAAW,KAAK,SAAS,MAAM,GAAG,CAAC,GAAG;AACpC,YAAM,KAAK,KAAK,EAAE,OAAO,EAAE;AAAA,IAC7B;AACA,QAAI,SAAS,SAAS,EAAG,OAAM,KAAK,YAAY,SAAS,SAAS,CAAC,OAAO;AAAA,EAC5E;AAEA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AASA,eAAsB,eAAe,aAG3B;AACR,QAAM,UAAU,MAAM,kBAAkB,WAAW;AACnD,MAAI,QAAQ,WAAW,UAAW,QAAO;AAEzC,MAAI,QAAQ,WAAW,WAAW;AAChC,WAAO;AAAA,MACL,OAAO;AAAA,QACL;AAAA,QACA,4GAAuG,QAAQ,MAAM;AAAA,QACrH;AAAA,MACF;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,qBAAqB,QAAQ,MAAM;AAAA,IAC1C,UAAU,QAAQ;AAAA,EACpB;AACF;AAuBO,SAAS,aAAa,QAA2B,OAA0C;AAChG,QAAM,YAAY,IAAI,IAAI,OAAO,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,KAAK,EAAE,IAAI,EAAE,CAAC;AAC/E,QAAM,WAAW,IAAI,IAAI,MAAM,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,KAAK,EAAE,IAAI,EAAE,CAAC;AAE7E,MAAI,YAAY;AAChB,aAAW,OAAO,WAAW;AAC3B,QAAI,CAAC,SAAS,IAAI,GAAG,EAAG;AAAA,EAC1B;AACA,MAAI,iBAAiB;AACrB,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,UAAU,IAAI,GAAG,EAAG;AAAA,EAC3B;AAEA,QAAM,YAAY,MAAM,YAAY,OAAO;AAC3C,QAAM,UACJ,YAAY,IAAI,aAAa,YAAY,IAAI,aAAa;AAE5D,SAAO,EAAE,QAAQ,OAAO,WAAW,gBAAgB,WAAW,QAAQ;AACxE;AAMO,SAAS,qBAAqB,OAAiC;AACpE,QAAM,QAAkB,CAAC,qBAAqB;AAE9C,QAAM,IAAI,CAAC,MAAc,MAAM,IAAI,KAAK;AACxC,QAAM,SAAS,KAAK,IAAI,MAAM,SAAS;AACvC,QAAM,SAAS,SAAS,MAAM,YAAY,MAAM;AAChD,QAAM,SAAS,SAAS,cAAc;AAEtC,MAAI,MAAM,YAAY,YAAY;AAChC,UAAM;AAAA,MACJ,oCAAoC,MAAM,GAAG,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,CAAC,YACpF,MAAM,iBAAiB,IAAI,KAAK,MAAM,cAAc,gBAAgB,MACrE,SAAS,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,OAAO,EAAE,MAAM,MAAM,SAAS,CAAC,UAAU,MAAM,MAAM,cAAc,IAAI,MAAM,EAAE;AAAA,IACpI;AAAA,EACF,WAAW,MAAM,YAAY,YAAY;AACvC,UAAM;AAAA,MACJ,oCAAoC,MAAM,GAAG,MAAM,cAAc,WAAW,EAAE,MAAM,cAAc,CAAC,iBAClG,MAAM,YAAY,IAAI,KAAK,MAAM,SAAS,WAAW,MACtD,UAAU,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,OAAO,EAAE,MAAM,MAAM,SAAS,CAAC;AAAA,IACrF;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ,iCAAiC,MAAM,MAAM,SAAS,OAAO,EAAE,MAAM,MAAM,SAAS,CAAC,UAAU,MAAM,MAAM,cAAc,IAAI,MAAM,EAAE,MACpI,MAAM,YAAY,IAAI,KAAK,MAAM,SAAS,WAAW,MAAM,cAAc,iBAAiB,MAC3F;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AA+FO,SAAS,mBACd,OACA,mBACiB;AACjB,QAAM,YAAY,IAAI,IAAI,MAAM,OAAO,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,KAAK,EAAE,IAAI,EAAE,CAAC;AACrF,QAAM,WAAW,IAAI,IAAI,MAAM,MAAM,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,KAAK,EAAE,IAAI,EAAE,CAAC;AAEnF,QAAM,iBAAiB,oBAAI,IAAY;AACvC,aAAW,OAAO,WAAW;AAC3B,QAAI,SAAS,IAAI,GAAG,EAAG,gBAAe,IAAI,GAAG;AAAA,EAC/C;AAEA,MAAI,eAAe,SAAS,EAAG,QAAO,CAAC;AAEvC,QAAM,eAAe,oBAAI,IAAgC;AACzD,aAAW,KAAK,mBAAmB;AACjC,iBAAa,IAAI,GAAG,EAAE,UAAU,KAAK,EAAE,cAAc,IAAI,CAAC;AAAA,EAC5D;AAEA,SAAO,CAAC,GAAG,cAAc,EAAE,IAAI,CAAC,QAAQ;AACtC,UAAM,CAAC,WAAW,IAAI,OAAO,EAAE,IAAI,IAAI,MAAM,MAAM,CAAC;AACpD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAW,MAAM,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa,YAAY,EAAE,SAAS,IAAI,GAAG,YAAY;AAAA,MACpG,WAAW,aAAa,IAAI,GAAG,KAAK;AAAA,IACtC;AAAA,EACF,CAAC;AACH;AAOO,SAAS,0BAA0B,MAAiC;AACzE,MAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAE/B,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,gBAA8C,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,EAAE;AACpF,QAAM,cAAc,CAAC,GAAG,IAAI,EAAE;AAAA,IAAK,CAAC,GAAG,MACrC,cAAc,EAAE,QAAQ,IAAI,cAAc,EAAE,QAAQ;AAAA,EACtD;AAEA,aAAW,OAAO,YAAY,MAAM,GAAG,CAAC,GAAG;AACzC,UAAM,IAAI,IAAI;AACd,UAAM,UAAU,GAAG,MAAM,WAAM,EAAE,GAAG,KAAK;AACzC,UAAM;AAAA,MACJ,SAAS,IAAI,IAAI,uBAAuB,IAAI,QAAQ,OAAO,IAAI,QAAQ,IAAI,OAAO;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,KAAK,YAAY,YAAY,SAAS,CAAC,OAAO;AAAA,EACtD;AAEA,QAAM,KAAK,EAAE;AACb,QAAM;AAAA,IACJ;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,SAAO;AACT;;;AC1YO,SAAS,qBACd,aACA,WACuB;AACvB,QAAM,aAAyC,CAAC;AAEhD,aAAW,OAAO,aAAa;AAC7B,UAAM,EAAE,KAAK,IAAI;AAGjB,QAAI,IAAI,aAAa,UAAa,IAAI,aAAa,MAAM;AACvD,iBAAW,KAAK;AAAA,QACd;AAAA,QACA,OAAO;AAAA,QACP,SAAS,IAAI,IAAI;AAAA,QACjB,UAAU;AAAA,QACV,KAAK,wBAAwB,IAAI;AAAA,MACnC,CAAC;AAAA,IACH;AAGA,QAAI,CAAC,IAAI,UAAU;AACjB,iBAAW,KAAK;AAAA,QACd;AAAA,QACA,OAAO;AAAA,QACP,SAAS,IAAI,IAAI;AAAA,QACjB,UAAU;AAAA,QACV,KAAK,wBAAwB,IAAI;AAAA,MACnC,CAAC;AAAA,IACH;AAGA,UAAM,WAAW,OAAO,IAAI,wBAAwB,YAAY,IAAI,oBAAoB,UAAU;AAClG,UAAM,cAAc,IAAI,0BAA0B;AAElD,QAAI,YAAY,CAAC,aAAa;AAC5B,iBAAW,KAAK;AAAA,QACd;AAAA,QACA,OAAO;AAAA,QACP,SAAS,IAAI,IAAI;AAAA,QACjB,UAAU;AAAA,QACV,KAAK,iDAA4C,IAAI;AAAA,MACvD,CAAC;AAAA,IACH;AAEA,QAAI,eAAe,CAAC,UAAU;AAC5B,iBAAW,KAAK;AAAA,QACd;AAAA,QACA,OAAO;AAAA,QACP,SAAS,IAAI,IAAI;AAAA,QACjB,UAAU;AAAA,QACV,KAAK,sDAAiD,IAAI;AAAA,MAC5D,CAAC;AAAA,IACH;AAGA,QAAI,MAAM,QAAQ,IAAI,qBAAqB,KAAK,IAAI,sBAAsB,WAAW,GAAG;AACtF,iBAAW,KAAK;AAAA,QACd;AAAA,QACA,OAAO;AAAA,QACP,SAAS,IAAI,IAAI;AAAA,QACjB,UAAU;AAAA,QACV,KAAK,wDAAwD,IAAI;AAAA,MACnE,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,SAAS,WAAW,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO,EAAE;AAChE,QAAM,WAAW,WAAW,OAAO,CAAC,MAAM,EAAE,aAAa,SAAS,EAAE;AAEpE,SAAO;AAAA,IACL,WAAW,aAAa,KAAK,IAAI;AAAA,IACjC,cAAc,YAAY;AAAA,IAC1B;AAAA,IACA,SAAS,EAAE,QAAQ,UAAU,OAAO,WAAW,OAAO;AAAA,EACxD;AACF;AAMO,SAAS,2BAA2B,QAAyC;AAElF,QAAM,QAAkB,CAAC,kCAAkC;AAE3D,MAAI,OAAO,QAAQ,UAAU,GAAG;AAC9B,UAAM,KAAK,OAAO,OAAO,YAAY,kDAAkD;AACvF,UAAM,KAAK,EAAE;AACb,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,QAAQ,SAAS,EAAG,OAAM,KAAK,GAAG,OAAO,QAAQ,MAAM,SAAS,OAAO,QAAQ,WAAW,IAAI,KAAK,GAAG,EAAE;AACnH,MAAI,OAAO,QAAQ,WAAW,EAAG,OAAM,KAAK,GAAG,OAAO,QAAQ,QAAQ,WAAW,OAAO,QAAQ,aAAa,IAAI,KAAK,GAAG,EAAE;AAC3H,QAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,OAAO,OAAO,QAAQ,UAAU,IAAI,KAAK,GAAG,aAAa,OAAO,YAAY,iBAAiB,MAAM,KAAK,IAAI,CAAC,GAAG;AAEpJ,QAAM,SAAS,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACrE,QAAM,WAAW,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,aAAa,SAAS;AAMzE,QAAM,eAAe;AACrB,QAAM,iBAAiB;AAEvB,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,wBAAwB;AACnC,eAAW,KAAK,OAAO,MAAM,GAAG,YAAY,GAAG;AAC7C,YAAM,KAAK,KAAK,EAAE,OAAO,WAAM,EAAE,GAAG,EAAE;AAAA,IACxC;AACA,QAAI,OAAO,SAAS,aAAc,OAAM,KAAK,YAAY,OAAO,SAAS,YAAY,OAAO;AAAA,EAC9F;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,eAAe;AAC1B,eAAW,KAAK,SAAS,MAAM,GAAG,cAAc,GAAG;AACjD,YAAM,KAAK,KAAK,EAAE,OAAO,EAAE;AAAA,IAC7B;AACA,QAAI,SAAS,SAAS,eAAgB,OAAM,KAAK,YAAY,SAAS,SAAS,cAAc,OAAO;AAAA,EACtG;AAEA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;;;ACjJA,eAAsB,sBAAsB,aAAuD;AACjG,MAAI;AACF,UAAM,OAAO,eAAe,mBAAmB,KAAK,QAAQ,IAAI;AAChE,WAAO,MAAM,eAAe,IAAI;AAAA,EAClC,SAAS,KAAK;AACZ,QAAI,QAAQ,IAAI,iBAAiB;AAC/B,cAAQ,MAAM,6CAA6C,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,IACrG;AACA,WAAO;AAAA,EACT;AACF;AAcO,SAAS,4BACd,aACuB;AACvB,QAAM,SAAS,qBAAqB,WAAW;AAC/C,QAAM,QAAQ,2BAA2B,MAAM;AAC/C,SAAO,EAAE,OAAO,YAAY,OAAO,QAAQ,QAAQ,cAAc,OAAO,QAAQ,SAAS;AAC3F;AA0BO,SAAS,wBACd,IACU;AACV,MAAI,CAAC,GAAI,QAAO,CAAC;AACjB,QAAM,QAAkB,CAAC,oBAAoB;AAC7C,QAAM,KAAK,GAAG,OAAO;AAErB,MAAI,GAAG,WAAW,SAAS,GAAG;AAC5B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oCAAoC;AAC/C,eAAW,KAAK,GAAG,YAAY;AAC7B,YAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,cAAc,KAAK,EAAE,IAAI,KAAK,KAAK,MAAM,EAAE,eAAe,GAAG,CAAC,YAAY;AAAA,IAChH;AAAA,EACF;AAEA,MAAI,GAAG,aAAa,SAAS,GAAG;AAC9B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,kBAAkB;AAC7B,aAAS,IAAI,GAAG,IAAI,GAAG,aAAa,QAAQ,KAAK;AAC/C,YAAM,KAAK,GAAG,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,EAAE,IAAI,aAAQ,GAAG,aAAa,CAAC,EAAE,WAAW,EAAE;AAAA,IAC3F;AAAA,EACF;AAEA,OAAK,GAAG,YAAY,gBAAgB,GAAG,YAAY,cAAc,GAAG,WAAW;AAC7E,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,sBAAsB,GAAG,UAAU,WAAW,EAAE,MAAM,GAAG,UAAU,IAAI,IAAI;AAAA,EACxF;AAEA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AAEA,IAAM,qBAAqB;AAAA,EACzB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAEF;AAEA,IAAM,wBACJ;AAIF,IAAM,gBACJ;AAuBK,SAAS,eAAe,GAAoB;AACjD,MAAI,MAAM,gBAAiB,QAAO;AAClC,MAAI,MAAM,cAAe,QAAO;AAChC,MAAI,MAAM,QAAS,QAAO;AAC1B,SAAO;AACT;AAcA,IAAM,sBAAsB;AAC5B,IAAM,wBAAwB;AAK9B,SAAS,sBAAsB,OAA8B;AAC3D,QAAM,KAAK,MAAM,WAAW,MAAM;AAClC,QAAM,OAAO,MAAM,cACf,WAAM,MAAM,YAAY,MAAM,GAAG,GAAG,CAAC,GAAG,MAAM,YAAY,SAAS,MAAM,QAAQ,EAAE,KACnF;AAKJ,QAAM,YAAY,MAAM,SAAS,IAAI,gBAAgB,MAAM,SAAS,IAAI,gBAAgB,MAAM,SAAS,IAAI,aAAa;AAExH,QAAM,OAAO,eAAe,MAAM,UAAU;AAC5C,QAAM,eAAe,MAAM,aAAa,KAAK,MAAM,UAAU,MAAM;AACnE,SAAO,KAAK,IAAI,MAAM,EAAE,OAAO,MAAM,IAAI,GAAG,YAAY,GAAG,SAAS,GAAG,IAAI;AAC7E;AAOO,SAAS,uBACd,uBACA,MACU;AACV,QAAM,aAAgC,MAAM,QAAQ,qBAAqB,IACrE,EAAE,WAAW,sBAAsB,IACnC,yBAAyB,CAAC;AAE9B,QAAM,EAAE,aAAa,CAAC,GAAG,YAAY,CAAC,GAAG,gBAAgB,CAAC,EAAE,IAAI;AAChE,QAAM,gBACJ,WAAW,SAAS,KAAK,UAAU,SAAS,KAAK,cAAc,SAAS;AAE1E,QAAM,QAAQ,gBAAgB,wBAAwB;AACtD,QAAM,WAAW,CAAC,GAAG,oBAAoB,KAAK;AAE9C,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,KAAK,GAAG,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,EAAE;AAAA,EACvC;AAEA,MAAI,eAAe;AACjB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,qCAAqC;AAEhD,UAAM,QAGD;AAAA,MACH,EAAE,QAAQ,0BAA0B,SAAS,WAAW;AAAA,MACxD,EAAE,QAAQ,8BAA8B,SAAS,cAAc;AAAA,MAC/D,EAAE,QAAQ,yBAAyB,SAAS,UAAU;AAAA,IACxD;AAEA,QAAI,MAAM;AAIR,UAAI,aAAa;AACjB,UAAI,kBAAkB;AACtB,UAAI,iBAAiB;AAErB,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,QAAQ,WAAW,EAAG;AAC/B,2BAAmB,KAAK,QAAQ;AAIhC,cAAM,iBAAiB,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,MAAS;AACpE,YAAI,eAAgB,kBAAiB;AACrC,cAAM,SAAS,iBACX,CAAC,GAAG,KAAK,OAAO,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE,QAAQ,OAAO,EAAE,QAAQ,GAAG,IAChE,CAAC,GAAG,KAAK,OAAO;AAEpB,cAAM,SAAS,OAAO,MAAM,GAAG,qBAAqB;AACpD,YAAI,OAAO,SAAS,GAAG;AACrB,wBAAc,OAAO;AACrB,gBAAM,KAAK,KAAK,MAAM;AACtB,qBAAW,KAAK,QAAQ;AACtB,kBAAM,KAAK,sBAAsB,CAAC,CAAC;AAAA,UACrC;AACA,gBAAM,KAAK,EAAE;AAAA,QACf;AAAA,MACF;AAMA,YAAM,aAAa,iBAAiB,wBAAwB;AAC5D,YAAM;AAAA,QACJ,IAAI,UAAU,OAAO,eAAe,8BAA8B,UAAU;AAAA,MAC9E;AAAA,IACF,OAAO;AACL,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,QAAQ,WAAW,EAAG;AAC/B,cAAM,KAAK,KAAK,MAAM;AACtB,mBAAW,KAAK,KAAK,QAAQ,MAAM,GAAG,mBAAmB,GAAG;AAC1D,gBAAM,KAAK,sBAAsB,CAAC,CAAC;AAAA,QACrC;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AACA,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AAiDO,SAAS,4BACd,sBACA,sBACU;AACV,MAAI,CAAC,sBAAsB,OAAQ,QAAO,CAAC;AAC3C,QAAM,UAAU,wBAAwB;AACxC,QAAM,QAAkB;AAAA,IACtB,wCAAmC,OAAO;AAAA,IAC1C;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAS,oBAAI,IAAsC;AACzD,aAAW,KAAK,sBAAsB;AACpC,UAAM,OAAO,OAAO,IAAI,EAAE,cAAc,KAAK,CAAC;AAC9C,SAAK,KAAK,CAAC;AACX,WAAO,IAAI,EAAE,gBAAgB,IAAI;AAAA,EACnC;AACA,QAAM,QAAQ,CAAC,aAAa,YAAY,UAAU;AAClD,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,OAAO,IAAI,IAAI;AAC/B,QAAI,CAAC,SAAS,OAAQ;AACtB,UAAM,QAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AACzD,UAAM,KAAK,KAAK,KAAK,KAAK;AAC1B,eAAW,KAAK,SAAS;AACvB,YAAM,KAAK,OAAO,EAAE,OAAO,aAAQ,EAAE,IAAI,EAAE;AAAA,IAC7C;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO;AACT;AAGO,SAAS,4BACd,aACU;AACV,MAAI,CAAC,aAAa,OAAQ,QAAO,CAAC;AAClC,QAAM,QAAkB,CAAC,wBAAwB,EAAE;AACnD,aAAW,KAAK,aAAa;AAC3B,UAAM,UACJ,EAAE,cAAc,OACZ,IAAI,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IACjD;AACN,UAAM,WACJ,EAAE,iBAAiB,QAAQ,UACvB,GAAG,EAAE,aAAa,YAAY,OAAO,KACrC,UACE,WAAW,OAAO,KAClB;AACR,UAAM,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,GAAG,WAAW,WAAM,QAAQ,KAAK,EAAE,EAAE;AAAA,EAC9E;AACA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AAGO,SAAS,4BACd,aACU;AACV,MAAI,CAAC,aAAa,OAAQ,QAAO,CAAC;AAClC,QAAM,QAAkB,CAAC,wBAAwB,EAAE;AACnD,aAAW,MAAM,aAAa;AAC5B,UAAM,YAAY,GAAG,gBAAgB,SACjC,GAAG,eAAe,KAAK,IAAI,IAC3B,GAAG,GAAG,QAAQ;AAClB,UAAM,KAAK,KAAK,GAAG,IAAI,WAAM,SAAS,EAAE;AAAA,EAC1C;AACA,QAAM,KAAK,EAAE;AACb,SAAO;AACT;AAGO,SAAS,8BACd,KACU;AACV,MAAI,CAAC,IAAK,QAAO,CAAC;AAClB,QAAM,cAAc,IAAI,aAAa,UAAU,KAAK;AACpD,QAAM,cAAc,IAAI,aAAa,UAAU,KAAK;AACpD,QAAM,eAAe,IAAI,kBAAkB,UAAU,KAAK;AAC1D,QAAM,sBAAsB,IAAI,wBAAwB,UAAU,KAAK;AACvE,MAAI,CAAC,cAAc,CAAC,cAAc,CAAC,eAAe,CAAC,mBAAoB,QAAO,CAAC;AAC/E,QAAM,QAAkB,CAAC,2BAA2B,EAAE;AACtD,MAAI,YAAY;AACd,UAAM,KAAK,cAAc;AACzB,eAAW,MAAM,IAAI,eAAe,CAAC,EAAG,OAAM,KAAK,OAAO,EAAE,IAAI;AAChE,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,YAAY;AACd,UAAM,KAAK,cAAc;AACzB,eAAW,MAAM,IAAI,eAAe,CAAC,EAAG,OAAM,KAAK,OAAO,EAAE,IAAI;AAChE,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,aAAa;AACf,UAAM,KAAK,oBAAoB;AAC/B,eAAW,MAAM,IAAI,oBAAoB,CAAC,EAAG,OAAM,KAAK,OAAO,EAAE,IAAI;AACrE,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,oBAAoB;AACtB,UAAM,KAAK,+CAA+C;AAC1D,eAAW,KAAK,IAAI,0BAA0B,CAAC,GAAG;AAChD,YAAM,KAAK,OAAO,EAAE,KAAK,eAAU,EAAE,IAAI,OAAO,EAAE,WAAW,oBAAe,EAAE,yBAAyB,GAAG;AAAA,IAC5G;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO;AACT;AAMO,SAAS,8BACd,KACU;AACV,MAAI,CAAC,IAAK,QAAO,CAAC;AAClB,QAAM,UAAU,IAAI,eAAe,CAAC;AACpC,QAAM,UAAU,IAAI,eAAe,CAAC;AACpC,QAAM,WAAW,IAAI,oBAAoB,CAAC;AAC1C,QAAM,kBAAkB,IAAI,0BAA0B,CAAC;AACvD,MAAI,QAAQ,WAAW,KAAK,QAAQ,WAAW,KAAK,SAAS,WAAW,KAAK,gBAAgB,WAAW,EAAG,QAAO,CAAC;AACnH,QAAM,UAAoB;AAAA,IACxB,GAAG,QAAQ,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,KAAK,EAAE,cAAc;AAAA,IACxD,GAAG,QAAQ,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,KAAK,EAAE,cAAc;AAAA,IACxD,GAAG,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,KAAK,EAAE,oBAAoB;AAAA,IAC/D,GAAI,gBAAgB,SAAS,IACzB,CAAC,GAAG,gBAAgB,MAAM,OAAO,gBAAgB,SAAS,IAAI,MAAM,EAAE,oCAAoC,IAC1G,CAAC;AAAA,EACP,EAAE,MAAM,GAAG,CAAC;AACZ,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,QAAM,QAAkB,CAAC,6BAA6B,GAAG,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE;AACzF,SAAO;AACT;AAiBO,SAAS,+BAA+B,KAAoD;AACjG,QAAM,gBAAgB,MAAM,OAAO,QAAQ,IAAI,yBAAyB,CAAC,CAAC,IAAI,CAAC;AAC/E,MAAI,CAAC,OAAQ,IAAI,kBAAkB,KAAK,cAAc,WAAW,EAAI,QAAO;AAG5E,QAAM,SAAS,KAAK,0BAA0B,CAAC;AAC/C,QAAM,gBAAgB,cAAc,SAAS,IACzC,2BAA2B,cAAc,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,GAAG,GAAG,IAAI,SAAS,OAAO,GAAG,KAAK,MAAM,OAAO,GAAG,CAAC,MAAM,KAAK,GAAG,OAAO,GAAG,MAAM,SAAY,OAAO,OAAO,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,MACnM;AAEJ,QAAM,gBAAgB,IAAI,gBAAgB,yEAAoE;AAC9G,MAAI,IAAI,kBAAkB,GAAG;AAC3B,WAAO,qBAAqB,IAAI,UAAU,kBAAkB,aAAa,GAAG,aAAa;AAAA,EAC3F;AACA,QAAM,YAAY,GAAG,IAAI,mBAAmB,OAAO,GAAG,KAAK,MAAM,IAAI,iBAAiB,GAAG,CAAC,MAAM,KAAK,OAAO,IAAI,eAAe;AAC/H,QAAM,YAAY,IAAI,kBAAkB,IAAI,GAAG,KAAK,OAAO,IAAI,kBAAkB,KAAK,GAAG,CAAC,QAAQ,IAAI,eAAe,MAAO,IAAI,sBAAsB;AAEtJ,QAAM,kBAAkB,IAAI,gBAAgB,OAAO,KAAK,KAAK,MAAM,IAAI,cAAc,GAAG,CAAC,eAAe;AACxG,SAAO,qBAAqB,IAAI,UAAU,OAAO,IAAI,YAAY,cAAc,IAAI,aAAa,YAAY,eAAe,0BAAqB,SAAS,oBAAoB,SAAS,IAAI,aAAa,GAAG,aAAa;AACzN;;;AC1dO,SAAS,yBACd,MACA,MACU;AACV,QAAM,QAAkB,CAAC,EAAE;AAC3B,MAAI,MAAM,aAAa;AACrB,UAAM,KAAK,mEAA8D;AACzE,UAAM,KAAK,qEAAgE;AAC3E,WAAO;AAAA,EACT;AACA,QAAM,KAAK,MAAM,iBAAiB,2DAAsD;AACxF,MAAI,MAAM,eAAgB,OAAM,KAAK,KAAK,cAAc;AACxD,QAAM,KAAK,MAAM,aAAa,+DAA0D;AACxF,MAAI,MAAM,UAAW,OAAM,KAAK,KAAK,SAAS;AAC9C,SAAO;AACT;AAUA,eAAsB,2BACpBC,cACA,gBACAC,4BACqB;AACrB,MAAI,qBAAqB;AACzB,MAAI,UAAwC;AAC5C,MAAI;AAIF,cAAU,MAAMD,aAAiE,2BAA2B;AAAA,MAC1G,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,GAAM,IAAI;AAAA,IACzC,CAAC;AAAA,EACH,QAAQ;AACN,yBAAqB;AAAA,EACvB;AACA,QAAM,eAAe,yBAAyB,SAAS,EAAE,aAAa,mBAAmB,CAAC;AAC1F,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MACE,yDACA,aAAa,KAAK,IAAI,IAAI,SAC1BC,2BAA0B,KAAK,IAAI,IACnC;AAAA,IACJ,CAAC;AAAA,IACD,mBAAmB;AAAA,MACjB;AAAA,MACA;AAAA,QACE,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,qBAAqB;AAAA,QACrB,uBAAuB;AAAA,QACvB,UAAU;AAAA;AAAA;AAAA,QAGV,GAAI,SAAS,kBAAkB,SAAY,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,QACvF,GAAI,SAAS,mBAAmB,SAAY,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC;AAAA,QAC1F,GAAI,SAAS,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,QAK3E,GAAI,SAAS,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AACF;;;ACpFO,SAAS,yBACd,YACA,WACA,MACA,cACM;AACN,MAAI;AACF,UAAM,iBAAiB,KAAK,UAAU,EAAE,SAAS,WAAW,WAAW,CAAC,EAAE,CAAC;AAC3E,UAAM,QAAQ,OAAO,WAAW,gBAAgB,MAAM;AAEtD,UAAM,YAAY,kBAAkB;AACpC,UAAM,iBAAiB,kBAAkB;AACzC,SAAK,eAAqE,4BAA4B;AAAA,MACpG;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACjC,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;AAAA,IAC7C,CAAC,EAAE,MAAM,MAAM;AAAA,IAEf,CAAC;AAAA,EACH,QAAQ;AAAA,EAGR;AACF;;;ACzCO,SAAS,0BAA0B,UAAoD;AAC5F,MAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO;AAC/C,SAAO,mCAAyB,SAAS,KAAK,IAAI,CAAC;AACrD;AAYO,SAAS,kBAAkBC,SAA0E;AAC1G,MAAIA,YAAW,cAAe,QAAO;AACrC,MAAIA,YAAW,mBAAoB,QAAO;AAC1C,MAAIA,YAAW,QAAS,QAAO;AAC/B,SAAO;AACT;;;ACKA,SAAS,WAAW,OAAuB;AACzC,SAAO,MACJ,QAAQ,kBAAkB,EAAE,EAC5B,QAAQ,eAAe,EAAE,EACzB,QAAQ,iBAAiB,EAAE;AAChC;AAKA,SAAS,cAAc,KAAyB;AAC9C,MAAI,IAAI,iBAAiB,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,IAAI,iBAAiB,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,IAAI,SAAS,IAAI;AACnB,WAAO,qBAAqB,IAAI,YAAY;AAAA,EAC9C;AACA,SAAO,qBAAqB,IAAI,YAAY,OAAO,IAAI,WAAW;AACpE;AAQO,SAAS,mBACd,KACA,WACA,KACQ;AACR,QAAM,SAAS,IAAI,sBAAsB,IAAI;AAC7C,QAAM,QAAQ,WAAW,IAAI,KAAK;AAElC,QAAM,QAAQ;AAAA,IACZ,cAAc,GAAG;AAAA,IACjB,YAAY,IACR,gCAAgC,KAAK,QACrC,mCAAmC,KAAK;AAAA,IAC5C;AAAA,IACA;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAoCO,SAAS,kBAAkB,KAA8C;AAC9E,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,SAAS,IAAI,sBAAsB,IAAI;AAC7C,SAAO,aAAa,MAAM;AAC5B;;;AC6EO,IAAM,oBAAoB;AAkB1B,SAAS,mBACf,cACA,MACA,cACA,eACS;AAET,QAAM,WAAW,cAAc,mBAAmB,YAAY;AAC9D,MAAI,UAAU;AACb,UAAM,QAAS,SAAgD,IAAI;AACnE,QAAI,UAAU,UAAa,MAAM,SAAS,EAAG,QAAO;AAAA,EACrD;AAGA,QAAM,YAAY,eAAe;AACjC,MAAI,WAAW;AACd,UAAM,SAAU,UAAiD,IAAI;AACrE,QAAI,WAAW,UAAa,OAAO,SAAS,EAAG,QAAO;AAAA,EACvD;AAIA,QAAM,gBAAgB,cAAc,qBAAqB,YAAY;AACrE,MAAI,eAAe;AAClB,UAAM,SAAU,cAAqD,IAAI;AACzE,QAAI,WAAW,UAAa,OAAO,SAAS,EAAG,QAAO;AAAA,EACvD;AAGA,SAAO;AACR;AAQO,SAAS,mBACf,MACA,cACA,kBACS;AACT,MAAI,CAAC,QAAQ,KAAK,WAAW,EAAG,QAAO;AAEvC,QAAM,QAAQ,IAAI,OAAO,kBAAkB,QAAQ,GAAG;AAEtD,SAAO,KAAK,QAAQ,OAAO,CAAC,QAAQ,cAAsB,SAAiB;AAC1E,UAAM,gBAAgB,kBAAkB,IAAI,YAAY;AACxD,WAAO,mBAAmB,cAAc,MAAM,cAAc,aAAa;AAAA,EAC1E,CAAC;AACF;;;AC3PA,SAAS,KAAAC,WAAS;;;ACFlB,SAAS,KAAAC,WAAS;AAGX,IAAM,eAAeC,IAAE,OAAO;AAAA,EACnC,SAASA,IACN,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EAEF;AACJ,CAAC;AAeD,eAAsB,cAAc,SAA2C;AAC7E,QAAM,cAAc,MAAM,eAAe;AACzC,SAAO,MAAM,YAA4D,sBAAsB;AAAA,IAC7F;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;AC5BA,IAAM,sBAAsB;AAC5B,SAAS,KAAK,KAAiC;AAC7C,SAAO,MAAM,IAAI,QAAQ,qBAAqB,EAAE,IAAI;AACtD;AAeO,IAAM,uBACX;AA6DF,SAAS,kBAAkB,MAAc,MAA2E;AAClH,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,qDAAqD,YAAY,EAAE,QAAQ,OAAO,EAAE;AAAA,IAC9H,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,qDAAqD,YAAY,EAAE,QAAQ,QAAQ,EAAE;AAAA,IAC/H,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,4BAA4B,YAAY,EAAE,QAAQ,SAAS,EAAE;AAAA,IACvG,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,wCAAwC,YAAY,EAAE,QAAQ,QAAQ,EAAE;AAAA,IAClH,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,kCAAkC,YAAY,EAAE,QAAQ,SAAS,EAAE;AAAA,IAC7G,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,sCAAsC,YAAY,EAAE,QAAQ,SAAS,EAAE;AAAA,IACjH,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,iCAAiC,YAAY,EAAE,QAAQ,UAAU,EAAE;AAAA,IAC7G,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,qBAAqB,YAAY,EAAE,QAAQ,SAAS,EAAE;AAAA,IAChG,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,aAAa,8BAA8B,YAAY,EAAE,QAAQ,cAAc,EAAE;AAAA,IAC9G,KAAK;AAIH,aAAO,EAAE,MAAM,YAAY,aAAa,KAAK,SAAS,OAAO,kCAAkC,uBAAuB,YAAY,EAAE,QAAQ,QAAQ,GAAI,KAAK,SAAS,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,EAAG,EAAE;AAAA,IACtM;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,qBAAqB,SAAuE;AAC1G,MAAI,CAAC,WAAW,QAAQ,WAAW,EAAG,QAAO,CAAC;AAC9C,QAAMC,WAAU,QACb,IAAI,CAAC,MAAM,kBAAkB,EAAE,OAAO,MAAM,EAAE,OAAO,IAAI,CAAC,EAC1D,OAAO,CAAC,MAAuB,MAAM,IAAI;AAI5C,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAOA,SAAQ,OAAO,CAAC,MAAM;AAC3B,UAAM,MAAM,GAAG,EAAE,IAAI,IAAI,KAAK,UAAU,EAAE,UAAU,CAAC;AACrD,QAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,SAAK,IAAI,GAAG;AACZ,WAAO;AAAA,EACT,CAAC;AACH;AAEA,IAAM,8BAA8B;AASpC,SAAS,qBAAqB,OAAuB;AACnD,UAAQ,OAAO;AAAA,IACb,KAAK;AAAmB,aAAO;AAAA,IAC/B,KAAK;AAAoB,aAAO;AAAA,IAChC,KAAK;AAAuB,aAAO;AAAA,IACnC;AAAS,aAAO,MAAM,QAAQ,eAAe,EAAE;AAAA,EACjD;AACF;AAEA,SAAS,oBAAoB,GAA6C;AACxE,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,MAAM,KAAK,EAAE,aAAa,CAAC,KAAK,KAAK,EAAE,IAAI,CAAC,WAAM,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG;AAC5F,QAAM,KAAK,QAAQ,KAAK,EAAE,QAAQ,CAAC,qBAAgB,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,KAAK,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,EAAE;AACjH,MAAI,EAAE,WAAW,QAAQ,GAAG;AAC1B,UAAM,QAAQ,EAAE,WAAW,MAAM,IAAI,CAAC,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,IAAI;AACxF,UAAM,aAAa,EAAE,WAAW,YAAY,GAAG,EAAE,WAAW,KAAK,MAAM,OAAO,EAAE,WAAW,KAAK;AAChG,UAAM,KAAK,cAAc,UAAU,WAAW,QAAQ,KAAK,KAAK,KAAK,EAAE,EAAE;AAAA,EAC3E;AACA,MAAI,EAAE,eAAgB,OAAM,KAAK,iBAAiB,KAAK,EAAE,cAAc,CAAC,EAAE;AAC1E,MAAI,EAAE,cAAe,OAAM,KAAK,OAAO,KAAK,EAAE,aAAa,CAAC,EAAE;AAG9D,QAAM,WAAW,CAAC,GAAG,IAAI,IAAI,EAAE,QAAQ,IAAI,CAAC,MAAM,KAAK,EAAE,KAAK,KAAK,qBAAqB,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,QAAK,KAAK;AAClH,QAAM,KAAK,OAAO,QAAQ,wCAAwC,KAAK,EAAE,aAAa,CAAC,uBAAuB;AAC9G,SAAO;AACT;AAEA,SAAS,2BAA2B,QAA2C;AAC7E,QAAM,YAAY,OAAO,SAAS,aAAa,CAAC;AAChD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,UAAU,MAAM,iBAAiB,UAAU,WAAW,IAAI,KAAK,GAAG,gCAAgC;AAClH,aAAW,KAAK,UAAW,OAAM,KAAK,GAAG,oBAAoB,CAAC,CAAC;AAC/D,QAAM,KAAK,oDAAoD;AAC/D,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAM,KAAK,qFAAgF;AAAA,EAC7F;AACA,SAAO;AACT;AAKO,SAAS,kBAAkB,SAAmE;AACnG,MAAI,CAAC,WAAW,QAAQ,WAAW,EAAG,QAAO,CAAC;AAC9C,SAAO,QAAQ;AAAA,IAAQ,CAAC,MACtB,EAAE,WAAW,+BAA+B,EAAE,UAC1C,2BAA2B,CAAC,IAC5B,CAAC,KAAK,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,EAAE,MAAM,CAAC,GAAG;AAAA,EACjD;AACF;AAKO,SAAS,yBAAyB,SAAuC;AAC9E,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,SAAO,CAAC,KAAK,OAAO,iBAAiB,YAAY,MAAM,KAAK,GAAG,kFAA6E;AAC9I;;;AFjLO,IAAM,gBAAgBC,IAAE,OAAO;AAAA,EACpC,MAAMA,IACH,OAAO,EACP,IAAI,GAAI,EACR,SAAS,EACT;AAAA,IACC;AAAA,EAGF;AAAA;AAAA;AAGJ,CAAC;AAED,IAAM,0BAA0B;AAgDhC,eAAe,gBACb,gBACA,mBAIC;AACD,MAAI,CAAC,eAAgB,QAAO,EAAE,UAAU,OAAO,mBAAmB,aAAa;AAC/E,MAAI;AACF,UAAM,WAA2D,sBAAsB;AAAA,MACrF,WAAW;AAAA,MACX,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;AAAA,IACnD,CAAC;AACD,uBAAmB,IAAI;AACvB,WAAO,EAAE,UAAU,MAAM,mBAAmB,WAAW;AAAA,EACzD,QAAQ;AACN,QAAI,CAAC,mBAAmB;AACtB,aAAO,EAAE,UAAU,OAAO,mBAAmB,SAAS;AAAA,IACxD;AACA,QAAI;AACF,YAAM,WAA2D,sBAAsB,EAAE,WAAW,eAAe,CAAC;AACpH,yBAAmB,IAAI;AACvB,aAAO,EAAE,UAAU,MAAM,mBAAmB,WAAW;AAAA,IACzD,QAAQ;AACN,aAAO,EAAE,UAAU,OAAO,mBAAmB,SAAS;AAAA,IACxD;AAAA,EACF;AACF;AAGA,SAAS,eAAe,GAAiE;AACvF,QAAMC,UAAS,EAAE,UAAW,EAAE,MAA0C;AACxE,QAAM,UAAW,EAAE,MAA2C;AAC9D,SAAOA,YAAW,YAAY,YAAY;AAC5C;AAEA,SAAS,oBAAoB,WAAqE;AAChG,MAAI,CAAC,UAAW,QAAO,EAAE,SAAS,GAAG,aAAa,MAAM;AACxD,QAAM,UAAU,KAAK,OAAO,KAAK,IAAI,IAAI,cAAc,MAAO,KAAK,KAAK,GAAG;AAC3E,SAAO,EAAE,SAAS,aAAa,WAAW,GAAG;AAC/C;AAEA,SAAS,sBACP,cACwC;AACxC,MAAI,aAAa,WAAW,EAAG,QAAO;AACtC,QAAM,IAAI,aAAa,CAAC;AACxB,SAAO;AAAA,IACL,QAAQ,iBAAiB,EAAE,IAAI;AAAA,IAC/B,KAAK;AAAA,EACP;AACF;AAWA,eAAe,mBACb,gBACuE;AAEvE,QAAM;AAAA,IACJ;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,QAAyB,MAAM,cAAc,uBAAuB;AAE1E,QAAM,EAAE,UAAU,kBAAkB,IAAI,MAAM,gBAAgB,cAAc;AAE5E,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,mBAAmB;AAAA,MACjB,mDAAmD,MAAM,KAAK,MAAM;AAAA,MACpE;AAAA,QACE,WAAW;AAAA,QACX,cAAc,MAAM;AAAA,QACpB,WAAW,MAAM;AAAA,QACjB,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,GAAI,iBAAiB,EAAE,WAAW,eAAe,IAAI,CAAC;AAAA,QACtD,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;AAoBA,eAAe,oBACb,OACA,gBACA,QACA,MACuE;AACvE,QAAM,EAAE,SAAS,YAAY,IAAI,oBAAoB,MAAM,aAAa,IAAI;AAE5E,MAAI,gBAAgC,CAAC;AACrC,MAAI,gBAA0C;AAC9C,MAAI;AAMF,UAAM,uBAAuB,kBAAkB;AAC/C,UAAM,iBAAiB,MAAM;AAAA,MAC3B;AAAA,MACA,uBAAuB,EAAE,OAAO,GAAG,gBAAgB,qBAAqB,IAAI,EAAE,OAAO,EAAE;AAAA,IACzF;AACA,oBAAgB,gBAAgB,YAAY,CAAC;AAC7C,oBAAgB,gBAAgB,iBAAiB;AAAA,EACnD,QAAQ;AAAA,EAAqB;AAE7B,MAAI,eAA0D,CAAC;AAC/D,MAAI;AAGF,UAAM,WAAW,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,WAAW,CAAC;AACrI,oBAAiB,YAAY,CAAC,GAA0E;AAAA,MACtG,CAAC,MAAM,EAAE,mBAAmB;AAAA,IAC9B;AAAA,EACF,QAAQ;AAAA,EAAqB;AAE7B,MAAI,YAAuC;AAC3C,MAAI;AACF,gBAAY,MAAM,YAAkE,0BAA0B;AAAA,EAChH,SAAS,GAAY;AACnB,WAAO,KAAK,cAAc,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EACxE;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,iBAAiB,cAAc,QAAQ,UAAU,QAAQ;AAC/D,QAAM,kBAAkB,cAAc,QAAQ,UAAU,SAAS;AACjE,QAAM,QAAuB,WAAW,SAAS;AACjD,QAAM,sBACJ,MAAM,mBAAmB,SACrB,8GACA;AAEN,QAAM,YAAY,MAAM,sBAAsB;AAE9C,MAAI,iBAAwC,CAAC;AAC7C,MAAI;AACF,qBAAkB,MAAM,YAAmC,uBAAuB,KAAM,CAAC;AAAA,EAC3F,QAAQ;AAAA,EAAqB;AAK7B,MAAI;AACJ,MAAI;AACF,2BAAuB,MAAM,YAAsC,4BAA4B;AAAA,EACjG,QAAQ;AAAA,EAAqB;AAE7B,QAAM,KAAK,KAAK,MAAM,aAAa,EAAE;AACrC,QAAM,KAAK,2BAA2B;AACtC,QAAM,KAAK,EAAE;AACb,QAAM,iBAAiB,+BAA+B,oBAAoB;AAC1E,MAAI,eAAgB,OAAM,KAAK,gBAAgB,EAAE;AAEjD,MAAI,kBAAkB,aAAa;AACjC,UAAM,YAAY,QAAQ,0BAA0B,KAAK,aAAa;AACtE,UAAM,KAAK,sCAAsC,OAAO,QAAQ,SAAS,GAAG;AAC5E,UAAM,KAAK,yFAAoF;AAC/F,UAAM,KAAK,EAAE;AAAA,EACf,WAAW,gBAAgB;AACzB,UAAM,KAAK,kCAAkC;AAC7C,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,kBAAkB,WAAW;AAC/B,UAAM,OAAuB,UAAU,QAAQ,CAAC;AAChD,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,SAAqB;AAAA,QACzB,OAAO,SAAS;AAAA,QAChB,cAAc,UAAU,gBAAgB;AAAA,QACxC,aAAa,UAAU,eAAe;AAAA,QACtC,OAAO,UAAU,SAAS;AAAA,MAC5B;AAEA,YAAM,KAAK,mBAAmB,KAAK,CAAC,GAAG,KAAK,SAAS,GAAG,MAAM,CAAC;AAC/D,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,mBAAmB;AAC9B,YAAM,KAAK,EAAE;AAEb,YAAM,gBAAgB,KAAK,SAAS;AACpC,UAAI,gBAAgB,KAAK,aAAa,SAAS,GAAG;AAChD,cAAM,QAAkB,CAAC;AACzB,YAAI,gBAAgB,EAAG,OAAM,KAAK,GAAG,aAAa,aAAa,kBAAkB,IAAI,KAAK,GAAG,WAAW;AACxG,YAAI,aAAa,SAAS,EAAG,OAAM,KAAK,GAAG,aAAa,MAAM,gBAAgB,aAAa,WAAW,IAAI,KAAK,GAAG,EAAE;AACpH,cAAM,KAAK,IAAI,MAAM,KAAK,OAAO,CAAC,iDAA4C;AAC9E,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF,OAAO;AACL,YAAM,gBAAgB,sBAAsB,YAAY;AACxD,UAAI,eAAe;AACjB,cAAM,KAAK,KAAK,cAAc,MAAM,IAAI;AACxC,cAAM,KAAK,cAAc,GAAG;AAC5B,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AAEA,UAAM,KAAK,6EAAwE;AACnF,UAAM,KAAK,EAAE;AAAA,EACf,WAAW,iBAAiB;AAC1B,QAAI,aAA0B,CAAC;AAC/B,QAAI;AAEF,YAAM,cAAe,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,gBAAgB,CAAC;AAI9I,oBAAc,eAAe,CAAC,GAC3B,OAAO,CAAC,MAAM,eAAe,CAAC,CAAC,EAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,WAAW,KAAK,EAAE,EACzD,MAAM,GAAG,CAAC;AAAA,IACf,QAAQ;AAAA,IAAqB;AAQ7B,QAAI,oBAAuC,EAAE,YAAY,CAAC,GAAG,WAAW,CAAC,GAAG,eAAe,CAAC,EAAE;AAC9F,QAAI,MAAM;AACR,UAAI;AACF,cAAM,OAAO,MAAM,YAAwE,kCAAkC,EAAE,KAAK,CAAC;AACrI,cAAM,KAAK,MAAM;AACjB,YAAI,IAAI;AAKN,gBAAM,cAAc,CAAC,OAA8C;AAAA,YACjE,SAAS,EAAE,WAAW;AAAA,YACtB,MAAM,EAAE;AAAA,YACR,aAAa,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,YACzD,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA,UAC9C;AACA,8BAAoB;AAAA,YAClB,aAAa,GAAG,cAAc,CAAC,GAAG,IAAI,WAAW;AAAA,YACjD,YAAY,GAAG,aAAa,CAAC,GAAG,IAAI,WAAW;AAAA,YAC/C,gBAAgB,GAAG,iBAAiB,CAAC,GAAG,IAAI,WAAW;AAAA,UACzD;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAAqB;AAAA,IAC/B;AAEA,QAAI,MAAM;AACR,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,8CAAyC;AACpD,cAAM,KAAK,yEAAyE;AACpF,cAAM,KAAK,EAAE;AACb,mBAAW,KAAK,YAAY;AAC1B,gBAAM,KAAK,OAAO,EAAE,WAAW,EAAE,IAAI,MAAM,EAAE,IAAI,EAAE;AAAA,QACrD;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAIA,YAAM,KAAK,GAAG,uBAAuB,mBAAmB,IAAI,CAAC;AAE7D,UAAI,WAAW;AACb,cAAM,KAAK,GAAG,UAAU,KAAK;AAAA,MAC/B;AAEA,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,kBAAkB,4BAA4B,cAAc;AAClE,YAAI,gBAAgB,aAAa,KAAK,gBAAgB,eAAe,GAAG;AACtE,gBAAM,KAAK,GAAG,gBAAgB,KAAK;AAAA,QACrC;AAAA,MACF;AAEA,YAAM,cAAc,MAAM,iBAAiB;AAE3C,UAAI,eAAe,WAAW,GAAG;AAC/B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,GAAG,wBAAwB,aAAa,eAAe,aAAa,CAAC;AAAA,MAClF,WAAW,eAAe;AACxB,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,GAAG,oBAAoB,aAAa,CAAC;AAAA,MAClD;AAEA,UAAI;AAKF,cAAM,aAAa,MAAM;AAAA,UACvB;AAAA,UACA,EAAE,QAAQ,CAAC,oBAAoB,cAAc,EAAE;AAAA,QACjD;AACA,cAAM,aAAa,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,gBAAgB;AACtE,cAAM,uBAAuB,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAEzE,YAAI,UAAU,UAAU,MAAM,qBAAqB,QAAQ,GAAG;AAC5D,gBAAM,KAAK,EAAE;AACb,gBAAM,KAAK,IAAI,UAAU,MAAM,mBAAmB,qBAAqB,IAAI,6BAA6B;AAAA,QAC1G;AAAA,MACF,QAAQ;AAAA,MAAqB;AAE7B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,iBAAiB,IAAI,IAAI;AACpC,YAAM,KAAK,EAAE;AAAA,IACf,OAAO;AACL,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,8CAAyC;AACpD,cAAM,KAAK,yEAAyE;AACpF,cAAM,KAAK,EAAE;AACb,mBAAW,KAAK,YAAY;AAC1B,gBAAM,KAAK,OAAO,EAAE,WAAW,EAAE,IAAI,MAAM,EAAE,IAAI,EAAE;AAAA,QACrD;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,YAAM,KAAK,GAAG,uBAAuB,CAAC;AAEtC,UAAI,WAAW;AACb,cAAM,KAAK,GAAG,UAAU,KAAK;AAAA,MAC/B;AAEA,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,kBAAkB,4BAA4B,cAAc;AAClE,YAAI,gBAAgB,aAAa,KAAK,gBAAgB,eAAe,GAAG;AACtE,gBAAM,KAAK,GAAG,gBAAgB,KAAK;AAAA,QACrC;AAAA,MACF;AAEA,UAAI,cAAc,SAAS,KAAK,CAAC,eAAe;AAC9C,cAAM,OAAO,cAAc,CAAC;AAC5B,cAAM,OAAO,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI;AACrF,cAAM,UAAU,MAAM,QAAQ,KAAK,cAAc,IAAI,KAAK,eAAe,SAAS,KAAK,kBAAkB;AACzG,cAAM,WAAW,MAAM,QAAQ,KAAK,eAAe,IAAI,KAAK,gBAAgB,SAAS,KAAK,mBAAmB;AAC7G,cAAM,KAAK,kBAAkB,IAAI,MAAM,OAAO,aAAa,QAAQ,aAAa;AAChF,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,eAAe;AACjB,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,GAAG,oBAAoB,aAAa,CAAC;AAAA,MAClD;AAEA,YAAM,KAAK,qFAAqF;AAChG,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,WAAW;AACtB,eAAW,OAAO,OAAQ,OAAM,KAAK,KAAK,GAAG,EAAE;AAC/C,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,EAAE,UAAU,kBAAkB,IAAI,MAAM,gBAAgB,gBAAgB,WAAW,YAAY,MAAS;AAE9G,QAAM,aAAa,SAAS;AAC5B,QAAM,WAAW,WAAW,MAAM,UAAU;AAC5C,QAAM,eAAe,CAAC,+BAA+B,UAAU,GAAG;AAClE,MAAI,WAAW,EAAG,cAAa,KAAK,GAAG,QAAQ,OAAO,aAAa,IAAI,KAAK,GAAG,GAAG;AAClF,MAAI,aAAa,SAAS,EAAG,cAAa,KAAK,GAAG,aAAa,MAAM,gBAAgB,aAAa,WAAW,IAAI,KAAK,GAAG,GAAG;AAE5H,QAAM,OAAqB,CAAC;AAC5B,MAAI,WAAW,GAAG;AAChB,SAAK,KAAK,EAAE,MAAM,WAAW,aAAa,cAAc,YAAY,CAAC,EAAE,CAAC;AAAA,EAC1E;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,SAAK,KAAK,EAAE,MAAM,WAAW,aAAa,sBAAsB,YAAY,EAAE,QAAQ,QAAQ,YAAY,WAAW,EAAE,CAAC;AAAA,EAC1H;AAEA,SAAO;AAAA,IACL,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,mBAAmB;AAAA,MACjB,aAAa,KAAK,GAAG;AAAA,MACrB;AAAA,QACE;AAAA,QACA,gBAAgB,WAAW,SAAS;AAAA,QACpC,WAAW;AAAA,QACX,cAAc,aAAa;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,GAAI,iBAAiB,EAAE,WAAW,eAAe,IAAI,CAAC;AAAA;AAAA;AAAA,QAGtD,GAAI,uBAAuB,EAAE,qBAAqB,IAAI,CAAC;AAAA,MACzD;AAAA,MACA,KAAK,SAAS,IAAI,OAAO;AAAA,IAC3B;AAAA,EACF;AACF;AAOA,eAAsB,cAAc,EAAE,KAAK,GAAsB;AAC/D,QAAM,SAAmB,CAAC;AAC1B,QAAM,iBAAiB,kBAAkB;AAEzC,MAAI,QAAgE;AACpE,MAAI;AACF,YAAQ,MAAM,oBAAoB;AAAA,EACpC,SAAS,GAAY;AACnB,WAAO,KAAK,cAAc,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EACxE;AAEA,MAAI,CAAC,OAAO;AACV,UAAM,OACJ,8CACC,OAAO,SAAS,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI;AAChE,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MACzC,mBAAmB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAKA,MAAI,QAAuB;AAC3B,MAAI;AACF,UAAM,YAAY,MAAM,YAAkE,0BAA0B;AACpH,YAAQ,WAAW,SAAS;AAAA,EAC9B,QAAQ;AACN,WAAO,KAAK,+DAA0D;AAAA,EACxE;AAEA,MAAI,UAAU,WAAW,UAAU,UAAU;AAG3C,UAAMC,UAAS,MAAM,mBAAmB,cAAc;AACtD,WAAO;AAAA,MACL,SAAS,YAAY,GAAGA,QAAO,IAAI;AAAA;AAAA,EAAO,oBAAoB,EAAE;AAAA,MAChE,mBAAmBA,QAAO;AAAA,IAC5B;AAAA,EACF;AAGA,MAAI,UAAU,cAAc,UAAU,aAAa;AACjD,SAAK,eAAyE,gCAAgC,CAAC,CAAC,EAAE,MAAM,MAAM;AAAA,IAAqB,CAAC;AAAA,EACtJ;AAEA,QAAM,eAAe,MAAM,oBAAoB,OAAO,gBAAgB,QAAQ,IAAI;AAClF,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,aAAa,IAAI;AAAA;AAAA,EAAO,oBAAoB,GAAG,CAAC;AAAA,IAC5F,mBAAmB,aAAa;AAAA,EAClC;AACF;;;AG/hBA,SAAS,KAAAC,WAAS;AAIX,IAAM,yBAAyBC,IAAE,OAAO;AAAA,EAC7C,qBAAqBA,IAClB,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EAEL;AAAA,IACC;AAAA,EACF;AAAA,EACF,0BAA0BA,IACvB,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EAEL;AAAA,IACC;AAAA,EACF;AAAA,EACF,wBAAwBA,IACrB,QAAQ,EAER;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAmBD,eAAsB,uBAAuB;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,iBAAiB,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,MACE,mBAAmB;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAMC,UAAiC;AAAA,IACrC,WAAW;AAAA,IACX,kBAAkB,eAAe;AAAA,IACjC,WAAW,eAAe,aAAa;AAAA,EACzC;AAEA,QAAM,UAAU,eAAe,mBAC3B,8EACA;AAEJ,SAAO;AAAA,IACL,SAAS,YAAY,OAAO;AAAA,IAC5B,mBAAmB,QAAQ,SAASA,OAAM;AAAA,EAC5C;AACF;;;AhBxEA,IAAM,qBAAqB;AAwDpB,SAAS,yBAAyB,SAAsB,QAAgC;AAC7F,QAAM,QAAkB,CAAC;AACzB,MAAI,QAAQ,WAAW,MAAM;AAC3B,QAAI,QAAQ,WAAW,QAAQ;AAC7B,YAAM,KAAK,gCAAsB,QAAQ,QAAQ,SAAS,EAAE;AAAA,IAC9D,OAAO;AACL,YAAM,KAAK,iCAA8B,QAAQ,aAAa,MAAM,QAAQ,QAAQ,MAAM,EAAE;AAAA,IAC9F;AAAA,EACF;AACA,MAAI,QAAQ,OAAQ,OAAM,KAAK,aAAa,OAAO,MAAM,EAAE;AAC3D,MAAI,QAAQ,WAAY,OAAM,KAAK,kBAAkB,OAAO,UAAU,EAAE;AACxE,MAAI,QAAQ,YAAa,OAAM,KAAK,mBAAmB,OAAO,WAAW,EAAE;AAC3E,SAAO;AACT;AAEA,SAAS,0BAA0B,WAA8D;AAC/F,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,SAAS,OAAO,UAAU,mBAAmB,WAAW,UAAU,iBAAiB;AACzF,QAAM,aAAa,OAAO,UAAU,mBAAmB,WAAW,UAAU,iBAAiB;AAC7F,QAAM,cAAc,OAAO,UAAU,gBAAgB,WAAW,UAAU,cAAc;AACxF,SAAO,UAAU,cAAc,cAAc,EAAE,QAAQ,YAAY,YAAY,IAAI;AACrF;AASA,eAAe,iCACb,gBACA,mBACkB;AAClB,MAAI;AACF,UAAM,WAA2D,sBAAsB;AAAA,MACrF,WAAW;AAAA,MACX,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;AAAA,IACnD,CAAC;AACD,uBAAmB,IAAI;AACvB,WAAO;AAAA,EACT,QAAQ;AACN,QAAI,CAAC,kBAAmB,QAAO;AAC/B,QAAI;AACF,YAAM,WAA2D,sBAAsB,EAAE,WAAW,eAAe,CAAC;AACpH,yBAAmB,IAAI;AACvB,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAsCA,IAAM,iBAAiB,CAAC,SAAS,QAAQ,mBAAmB;AAGrD,IAAM,eAAeC,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,KAAK,cAAc,EAAE,SAAS,EAAE,QAAQ,MAAM,EAAE;AAAA,IACxD;AAAA,EAGF;AAAA,EACA,MAAMA,IAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,MAAM,EAAE,SAAS,qJAAqJ;AAAA,EACzN,MAAMA,IAAE,KAAK,CAAC,WAAW,YAAY,MAAM,CAAC,EAAE,SAAS,EAAE;AAAA,IACvD;AAAA,EACF;AAAA,EACA,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE;AAAA,IACpC;AAAA,EACF;AAAA,EACA,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oJAAoJ;AAAA;AAAA;AAAA;AAAA,EAInM,gBAAgBA,IAAE,OAAO;AAAA,IACvB,cAAcA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,oGAAoG;AAAA,IAClK,sBAAsBA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,2EAA2E;AAAA,IACjJ,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,IACxF,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,EACpG,CAAC,EAAE,SAAS,EAAE,SAAS,2KAAsK;AAAA,EAC7L,gBAAgBA,IAAE,KAAK,CAAC,iBAAiB,iBAAiB,iBAAiB,aAAa,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,8HAA8H;AAAA,EACtP,qBAAqBA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE;AAAA,IACtD;AAAA,EACF;AAAA,EACA,0BAA0BA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE;AAAA,IAC3D;AAAA,EACF;AAAA,EACA,wBAAwBA,IAAE,QAAQ,EAAE,SAAS,EAAE;AAAA,IAC7C;AAAA,EACF;AACF,CAAC;AAGD,IAAM,qBAAqBA,IAAE,OAAO;AAAA,EAClC,QAAQA,IAAE,QAAQ,OAAO;AAAA,EACzB,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AACtC,CAAC;AACD,IAAM,oBAAoBA,IAAE,OAAO;AAAA,EACjC,QAAQA,IAAE,QAAQ,MAAM;AAAA,EACxB,MAAMA,IAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,MAAM;AAAA,EACzD,MAAMA,IAAE,KAAK,CAAC,WAAW,YAAY,MAAM,CAAC,EAAE,SAAS;AAAA,EACvD,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EACpC,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA;AAAA;AAAA,EAGpC,gBAAgBA,IAAE,OAAO;AAAA,IACvB,cAAcA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,IACnD,sBAAsBA,IAAE,MAAMA,IAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,IAC3D,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,IACzC,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC7C,CAAC,EAAE,SAAS;AAAA,EACZ,gBAAgBA,IAAE,KAAK,CAAC,iBAAiB,iBAAiB,iBAAiB,aAAa,SAAS,CAAC,EAAE,SAAS;AAC/G,CAAC;AACD,IAAM,gCAAgCA,IAAE,OAAO;AAAA,EAC7C,QAAQA,IAAE,QAAQ,mBAAmB;AAAA,EACrC,qBAAqBA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AAAA,EAC3C,0BAA0BA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AAAA,EAChD,wBAAwBA,IAAE,QAAQ;AACpC,CAAC;AAEM,IAAM,oBAAoBA,IAAE,mBAAmB,UAAU;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,sBAA6D;AAAA,EACxE,OAAO,EAAE,QAAQ,CAAC,MAAM,GAAG,aAAa,8CAA8C;AAAA,EACtF,MAAM,EAAE,QAAQ,CAAC,QAAQ,QAAQ,QAAQ,OAAO,GAAG,aAAa,qDAAqD;AAAA,EACrH,qBAAqB;AAAA,IACnB,QAAQ,CAAC,uBAAuB,4BAA4B,wBAAwB;AAAA,IACpF,aAAa;AAAA,EACf;AACF;AAMA,SAAS,0BAA0B,MAAe,mBAAmB,OAAiB;AACpF,MAAI,iBAAkB,QAAO,CAAC;AAC9B,MAAI,MAAM;AACR,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,mBAAmB,QAAmB;AAEpD,QAAM,iBAA2E;AAAA,IAC/E,OAAO,CAAC,SAAS,cAAc,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,IAClD,MAAM,CAAC,SAAS,cAAc;AAAA,MAC5B,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,gBAAgB,KAAK;AAAA,MACrB,gBAAgB,KAAK;AAAA,IACvB,CAAC;AAAA,IACD,qBAAqB,CAAC,SAAS,uBAAuB;AAAA,MACpD,qBAAqB,KAAK;AAAA,MAC1B,0BAA0B,KAAK;AAAA,MAC/B,wBAAwB,KAAK;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAkBF,aAAa;AAAA;AAAA,MAEb,aAAa,EAAE,cAAc,OAAO,gBAAgB,MAAM,eAAe,MAAM;AAAA,IACjF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,cAAc,IAAI;AAC7C,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,UAAU,OAAO;AAAA,QAAG,MACpD,sBAAsB,UAAU,mBAAmB,OAAO,MAAM,qBAAqB,cAAc;AAAA,MACrG;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGA,eAAsB,cAAc,EAAE,OAAO,QAAQ,MAAM,MAAM,OAAO,gBAAgB,eAAe,GAepG;AACG,QAAM,SAAmB,CAAC;AAI1B,QAAM,WACJ,SAAS,SAAS,UAAU,YAAY;AAM1C,MAAI,SAAS,CAAC,MAAM;AAClB,WAAO,KAAK,kEAAkE;AAAA,EAChF;AACA,QAAM,iBAAiB,kBAAkB;AAMzC,MAAI,kBAAkB,KAAK,SAAS,WAAW,CAAC,MAAM;AACpD,WAAO,2BAA2B,aAAa,gBAAgB,0BAA0B,CAAC;AAAA,EAC5F;AAEA,MAAI,QAAiC;AACrC,MAAI;AACF,YAAQ,MAAM,oBAAoB;AAAA,EACpC,SAAS,GAAY;AACnB,WAAO,KAAK,cAAc,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EACxE;AAEA,MAAI,gBAAgC,CAAC;AACrC,MAAI,gBAA0C;AAqD9C,MAAI,aAAmC;AAIvC,MAAI,oBAAoB;AACxB,MAAI;AACF,UAAM,aAcF,CAAC;AACL,QAAI,KAAM,YAAW,OAAO;AAC5B,QAAI,MAAO,YAAW,QAAQ;AAI9B,QAAI,kBAAkB,OAAO,KAAK,cAAc,EAAE,SAAS,EAAG,YAAW,iBAAiB;AAC1F,QAAI,gBAAgB;AAClB,iBAAW,iBAAiB;AAAA,IAC9B,WAAW,MAAM;AACf,iBAAW,iBAAiB;AAAA,IAC9B;AAEA,QAAI,SAAU,YAAW,OAAO;AAGhC,eAAW,aAAa;AACxB,QAAI,eAAgB,YAAW,YAAY;AAE3C,UAAM,uBAAuB,kBAAkB;AAC/C,QAAI,qBAAsB,YAAW,iBAAiB;AAGtD,iBAAc,MAAM,YAA6D,uBAAuB,UAAU;AAAA,EACpH,QAAQ;AAAE,wBAAoB;AAAA,EAAmG;AAKjI,QAAM,eACJ,YAAY,gBAAgB,YAAY;AAC1C,QAAM,iBAA0B,YAAY,kBAAkB;AAI9D,MAAI;AACJ,MAAI;AAEF,UAAM,QAAQ,MAAM,YAA6D,uBAAuB,CAAC,CAAC;AAC1G,QAAI,OAAO,oBAAoB,OAAO,oBAAoB;AACxD,iBAAW;AAAA,QACT,GAAI,MAAM,mBAAmB,EAAE,kBAAkB,MAAM,iBAA0D,IAAI,CAAC;AAAA,QACtH,GAAI,MAAM,qBAAqB,EAAE,oBAAoB,MAAM,mBAA8D,IAAI,CAAC;AAAA,MAChI;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAA8C;AAEtD,MAAI,YAAY;AACd,oBAAgB,WAAW,iBAAiB,CAAC;AAC7C,oBAAgB,WAAW,iBAAiB;AAAA,EAC9C;AACA,QAAM,mBAAmB,QAAQ,SAAS,YAAY,aAAa,SAAS,UAAU,KAAK,CAAC;AAG5F,MAAI,SAAS,oBAAoB,YAAY,gBAAgB;AAC3D,UAAM,QAAQ,MAAM,QAAQ,WAAW,cAAc,IAAI,WAAW,iBAAiB,CAAC;AACtF,QAAI,MAAM,SAAS,GAAG;AACpB,+BAAyB,MAAM,aAAa;AAAA,QAC1C,YAAY,MAAM;AAAA,QAClB,UAAU,CAAC,CAAC;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,eAAsB,CAAC;AAC3B,MAAI;AACF,UAAM,WAAW,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,WAAW,CAAC;AACrI,oBAAgB,YAAY,CAAC,GAAG,OAAO,CAAC,MAAmC,EAAE,mBAAmB,MAAM;AAAA,EACxG,QAAQ;AAAA,EAAqB;AAE7B,MAAI,iBAAwC,CAAC;AAC7C,MAAI;AACF,qBAAkB,MAAM,YAAmC,uBAAuB,KAAM,CAAC;AAAA,EAC3F,QAAQ;AAAA,EAA4D;AAEpE,MAAI,YAAiB;AACrB,MAAI;AACF,gBAAY,MAAM,YAAkE,0BAA0B;AAAA,EAChH,SAAS,GAAY;AACnB,WAAO,KAAK,cAAc,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EACxE;AAGA,MAAI,WAAW,UAAU,SAAS;AAChC,UAAM,YAAY;AAAA,MAChB,gBAAgB,OAAO,iBAAiB,gBAAgB;AAAA,MACxD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,cAAU,KAAK,GAAG,yBAAyB,YAAY,EAAE,aAAa,qBAAqB,YAAY,gBAAgB,KAAK,CAAC,CAAC;AAG9H,QAAI,WAAW;AACf,QAAIC,qBAA0D;AAC9D,QAAI,gBAAgB;AAClB,UAAI;AACF,cAAM,WAA2D,sBAAsB,EAAE,WAAW,eAAe,CAAC;AACpH,2BAAmB,IAAI;AACvB,mBAAW;AACX,QAAAA,qBAAoB;AAAA,MACtB,QAAQ;AACN,QAAAA,qBAAoB;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,cAAc;AAAA,MAClB,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,UAAU,KAAK,IAAI,EAAE,CAAC;AAAA,MAC/D,mBAAmB;AAAA,QACjB;AAAA,QACA,EAAE,OAAO,SAAS,gBAAgB,WAAW,SAAS,GAAG,UAAU,mBAAAA,oBAAmB,cAAc,kEAAkE;AAAA,QACtK,CAAC,EAAE,MAAM,UAAU,aAAa,0BAA0B,YAAY,EAAE,QAAQ,QAAQ,EAAE,CAAC;AAAA,MAC7F;AAAA,IACF;AAEA,6BAAyB,aAAa,OAAO,cAAc,cAAc;AACzE,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,iBAAiB,aAAa,UAAU,QAAQ;AAGtD,MAAI,OAAO;AACT,UAAM,KAAK,KAAK,MAAM,aAAa,EAAE;AACrC,UAAM,KAAK,gBAAgB,MAAM,aAAa,sCAAiC;AAAA,EACjF,OAAO;AACL,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,gCAAgC;AAAA,EAC7C;AACA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,GAAG,0BAA0B,MAAM,gBAAgB,CAAC;AAC/D,QAAM,qBAAqB,YAAY,gBACnC;AAAA,IACE,WAAW;AAAA,IACX,0BAA0B,WAAW,SAAS,eAAe;AAAA,EAC/D,IACA,CAAC;AACL,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,KAAK,GAAG,kBAAkB;AAChC,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,SAAS,SAAS;AACpB,UAAM,aAAa,WAAW,UAAU,WAAW,SAAS,OAAQ,UAAU,QAAQ,KAAK,WAAW,aAAc;AACpH,UAAM,KAAK,gBAAgB,UAAU,EAAE;AACvC,QAAI,YAAY,kBAAkB;AAChC,YAAM,KAAK,WAAW;AACtB,UAAI,GAAG,OAAQ,OAAM,KAAK,WAAW,GAAG,MAAM,EAAE;AAChD,UAAI,GAAG,QAAS,OAAM,KAAK,YAAY,GAAG,OAAO,EAAE;AACnD,UAAI,GAAG,oBAAoB,QAAQ,GAAG,mBAAmB,GAAG;AAC1D,cAAM,KAAK,kBAAkB,GAAG,gBAAgB,OAAO,GAAG,gBAAgB,CAAC,GAAG,KAAK,IAAI,CAAC,EAAE;AAAA,MAC5F;AACA,UAAI,GAAG,qBAAqB,QAAQ,GAAG,oBAAoB,GAAG;AAC5D,cAAM,KAAK,kBAAkB,GAAG,iBAAiB,OAAO,GAAG,gBAAgB,CAAC,GAAG,KAAK,IAAI,CAAC,EAAE;AAAA,MAC7F;AAEA,YAAM,WAAW,mBAAmB,gBAAgB,UAAU,QAAQ;AACtE,YAAM,KAAK,GAAG,GAAG,cAAc,WAAW,QAAQ,KAAK,GAAG,kBAAkB,cAAc;AAAA,IAC5F;AAEA,UAAM,2BAA2B,YAAY,sBAAsB,CAAC,GAAG,OAAO,CAAC,MAAW,KAAK,QAAQ,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,CAAC;AACtJ,QAAI,wBAAwB,SAAS,GAAG;AACtC,YAAM,KAAK,aAAa,wBAAwB,IAAI,CAAC,MAAW,EAAE,QAAQ,OAAO,EAAE,YAAY,YAAY,EAAE,UAAU,WAAM,EAAE,OAAO,KAAK,GAAG,EAAE,KAAK,KAAK,CAAC,EAAE;AAAA,IAC/J;AACA,QAAI,YAAY,eAAe,WAAW,YAAY,QAAQ,SAAS,GAAG;AACxE,YAAM,KAAK,iBAAiB,WAAW,YAAY,UAAU,sBAAsB,WAAW,YAAY,UAAU,eAAe;AAEnI,UAAI,WAAW,YAAY,mBAAmB,WAAW,YAAY,eAAe;AAClF,cAAM,KAAK,gBAAM,WAAW,YAAY,aAAa,EAAE;AAAA,MACzD;AAAA,IACF;AAGA,QAAI,YAAY,eAAe;AAC7B,YAAM,KAAK,mBAAmB,WAAW,cAAc,OAAO,WAAM,WAAW,cAAc,QAAQ,QAAQ,SAAS,EAAE,CAAC,EAAE;AAAA,IAC7H;AACA,UAAM,oBAAoB,0BAA0B,YAAY,gBAAgB;AAChF,QAAI,kBAAmB,OAAM,KAAK,iBAAiB;AAEnD,UAAM,KAAK,GAAG,yBAAyB,YAAY,EAAE,aAAa,qBAAqB,YAAY,gBAAgB,KAAK,CAAC,CAAC;AAC1H,QAAI,YAAY,SAAS,iBAAiB;AACxC,YAAM,YAAY,WAAW,QAAQ;AACrC,YAAM,WAAW,UAAU,qBAAqB,KAAK,UAAU,kBAAkB,MAAM;AACvF,YAAM,KAAK,qBAAqB,UAAU,KAAK,GAAG,QAAQ,EAAE;AAC5D,UAAI,UAAU,aAAc,OAAM,KAAK,kBAAkB,UAAU,YAAY,EAAE;AACjF,UAAI,UAAU,uBAAuB,QAAQ,UAAU,0BAA0B,QAAQ,UAAU,oBAAoB,MAAM;AAC3H,cAAM,KAAK,6BAA6B,UAAU,uBAAuB,CAAC,YAAY,UAAU,0BAA0B,CAAC,eAAe,UAAU,oBAAoB,CAAC,eAAe;AAAA,MAC1L;AAAA,IACF;AACA,QAAI,YAAY,kBAAkB,WAAW,eAAe,SAAS,GAAG;AACtE,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,kDAAkD;AAC7D,iBAAW,KAAK,WAAW,gBAAgB;AACzC,cAAM,KAAK,KAAK,EAAE,cAAc,KAAK,EAAE,IAAI,EAAE;AAAA,MAC/C;AAAA,IACF;AACA,UAAM,iBAAiB,YAAY,sBAAsB,CAAC;AAC1D,QAAI,eAAe,SAAS,GAAG;AAC7B,iBAAW,KAAK,gBAAgB;AAC9B,cAAM,WAAW,EAAE;AACnB,cAAM,cAAc,UAAU,SAC1B,WAAM,SAAS,IAAI,CAAC,MAAM,GAAG,EAAE,WAAW,EAAE,IAAI,KAAK,EAAE,YAAY,QAAG,GAAG,EAAE,KAAK,IAAI,CAAC,KACrF;AACJ,cAAM,aAAa,EAAE,SAAS,aAAa,EAAE,MAAM,MAAM;AACzD,cAAM,KAAK,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,WAAW,GAAG,kBAAkB,EAAE,oBAAoB,CAAC,EAAE;AAAA,MAC3H;AAAA,IACF;AAEA,QAAI,YAAY,cAAc;AAC5B,YAAM,KAAK,WAAW;AACtB,UAAI,GAAG,aAAa,KAAK,GAAG,WAAW,GAAG;AACxC,cAAM,UAAU,GAAG,aAAa,MAAM;AACtC,cAAM,KAAK,UAAU,GAAG,QAAQ,cAAc,GAAG,UAAU,gBAAgB,GAAG,QAAQ,eAAe,GAAG,KAAK,GAAG,OAAO,YAAY;AAAA,MACrI;AAAA,IACF;AAEA,UAAM,iBAAiB,+BAA+B,YAAY,oBAAoB;AACtF,QAAI,eAAgB,OAAM,KAAK,cAAc;AAE7C,UAAM,WAAW,8BAA8B,YAAY,kBAAkB;AAC7E,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,GAAG,QAAQ;AAAA,IACxB;AAEA,UAAM,YAA4B,WAAW,QAAQ,CAAC;AACtD,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,WAAW,kBAAkB,UAAU,CAAC,CAAC;AAC/C,UAAI,SAAU,OAAM,KAAK,QAAQ;AAAA,IACnC;AACA,UAAM,0BAA0B,UAAU,OAAO,CAAC,MAAM,EAAE,IAAI,aAAa,kBAAkB,CAAC;AAC9F,QAAI,wBAAwB,SAAS,GAAG;AACtC,YAAM,KAAK,GAAG,wBAAwB,MAAM,2EAAsE;AAAA,IACpH;AACA,QAAI,eAAe;AACjB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,GAAG,oBAAoB,aAAa,CAAC;AAAA,IAClD,WAAW,cAAc,SAAS,GAAG;AACnC,YAAM,OAAO,cAAc,CAAC;AAC5B,YAAM,OAAO,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI;AACrF,YAAM,UAAU,MAAM,QAAQ,KAAK,cAAc,IAAI,KAAK,eAAe,SAAS,KAAK,kBAAkB;AACzG,YAAM,WAAW,MAAM,QAAQ,KAAK,eAAe,IAAI,KAAK,gBAAgB,SAAS,KAAK,mBAAmB;AAC7G,YAAM,KAAK,iBAAiB,IAAI,MAAM,OAAO,aAAa,QAAQ,WAAW;AAAA,IAC/E;AACA,QAAI;AACJ,UAAM,YAAY,MAAM,sBAAsB;AAC9C,QAAI,WAAW;AACb,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,GAAG,UAAU,KAAK;AAC7B,0BAAoB,UAAU,YAAY;AAAA,IAC5C;AAEA,QAAI,eAAe,SAAS,GAAG;AAC7B,YAAM,kBAAkB,4BAA4B,cAAc;AAClE,UAAI,gBAAgB,aAAa,KAAK,gBAAgB,eAAe,GAAG;AACtE,cAAM,KAAK,GAAG,gBAAgB,KAAK;AAAA,MACrC;AAAA,IACF;AAEA,QAAI,YAAY;AACd,YAAM,KAAK,EAAE;AACb,UAAI,MAAM;AACR,cAAM,qBAAqB,CAAC,OAAY;AAAA,UACtC,SAAS,EAAE;AAAA,UACX,MAAM,EAAE;AAAA,UACR,aAAa,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,UACzD,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA;AAAA,UAE5C,YAAY,EAAE;AAAA,UACd,YAAY,OAAO,EAAE,eAAe,WAAW,EAAE,aAAa;AAAA,QAChE;AACA,cAAM,MAAM,WAAW,cAAc,EAAE,YAAY,CAAC,GAAG,WAAW,CAAC,GAAG,eAAe,CAAC,EAAE;AACxF,cAAM,KAAK,GAAG,uBAAuB;AAAA,UACnC,aAAa,IAAI,cAAc,CAAC,GAAG,IAAI,kBAAkB;AAAA,UACzD,YAAY,IAAI,aAAa,CAAC,GAAG,IAAI,kBAAkB;AAAA,UACvD,gBAAgB,IAAI,iBAAiB,CAAC,GAAG,IAAI,kBAAkB;AAAA,QACjE,GAAG,IAAI,CAAC;AAAA,MACV,OAAO;AACL,cAAM,KAAK,GAAG,uBAAuB,CAAC;AAAA,MACxC;AAAA,IACF;AAEA,QAAIA,qBAA4E;AAChF,QAAI,kBAAkB,kBAAkB;AACtC,YAAM,aAAa,MAAM,iCAAiC,gBAAgB,iBAAiB;AAC3F,UAAI,YAAY;AACd,QAAAA,qBAAoB;AACpB,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,iCAAiC,cAAc,0BAA0B;AAAA,MACtF,OAAO;AACL,QAAAA,qBAAoB;AACpB,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,+EAA+E;AAAA,MAC5F;AAAA,IACF,WAAW,gBAAgB;AACzB,MAAAA,qBAAoB;AACpB,YAAM,KAAK,KAAK;AAChB,YAAM,KAAK,wGAAwG;AAAA,IACrH,OAAO;AACL,YAAM,KAAK,KAAK;AAChB,YAAM,KAAK,kEAAkE;AAAA,IAC/E;AAEA,UAAM,iBAAiB,YAAY,SAAS,aAAa,YAAY,cAAc;AACnF,QAAI,gBAAgB;AAClB,YAAM,UAAU,YAAY,SAAS;AACrC,YAAM,KAAK,EAAE;AACb,UAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,cAAM,KAAK,0CAA0C,QAAQ,KAAK,IAAI,CAAC,wCAAwC;AAAA,MACjH,OAAO;AACL,cAAM,KAAK,6EAA6E;AAAA,MAC1F;AAAA,IACF;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,KAAK,EAAE;AACb,iBAAW,OAAO,OAAQ,OAAM,KAAK,KAAK,GAAG,EAAE;AAAA,IACjD;AACA,UAAM,cAAc;AAAA,MAClB,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC3D,mBAAmB;AAAA,QACjB,4BAA4B,WAAW,SAAS,SAAS;AAAA,QACzD;AAAA,UACE,MAAM;AAAA,UACN,OAAO,WAAW,SAAS;AAAA,UAC3B,UAAU,mBAAmB,kBAAkB,IAAI;AAAA,UACnD,WAAW;AAAA,UACX,qBAAqB,mBAAmB,gBAAgB,OAAO,yBAAyB;AAAA,UACxF,uBAAuB,CAAC;AAAA;AAAA,UAExB,GAAI,YAAY,aAAa,kBAAkB,EAAE,eAAe,KAAK,IAAI,CAAC;AAAA;AAAA,UAE1E,GAAI,YAAY,gBAAgB,EAAE,eAAe,WAAW,cAAc,IAAI,CAAC;AAAA,UAC/E,GAAI,YAAY,kBAAkB,SAAS,EAAE,kBAAkB,WAAW,iBAAiB,IAAI,CAAC;AAAA;AAAA;AAAA,UAEhG,GAAI,YAAY,kBAAkB,SAAY,EAAE,eAAe,WAAW,cAAc,IAAI,CAAC;AAAA,UAC7F,GAAI,YAAY,mBAAmB,SAAY,EAAE,gBAAgB,WAAW,eAAe,IAAI,CAAC;AAAA,UAChG,GAAI,YAAY,cAAc,SAAY,EAAE,WAAW,WAAW,UAAU,IAAI,CAAC;AAAA,UACjF,GAAI,YAAY,cAAc,SAAY,EAAE,WAAW,WAAW,UAAU,IAAI,CAAC;AAAA;AAAA,UACjF,GAAI,YAAY,gBAAgB,SAAY,EAAE,aAAa,WAAW,YAAY,IAAI,CAAC;AAAA;AAAA;AAAA,UAEvF,GAAI,YAAY,gBAAgB,EAAE,eAAe,WAAW,cAAc,IAAI,CAAC;AAAA,UAC/E,mBAAAA;AAAA,UACA,UAAU,mBAAmB,SAAY;AAAA,UACzC,GAAI,YAAY,UAAU,EAAE,SAAS,WAAW,QAAQ,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,UAI7D,GAAI,YAAY,uBAAuB,EAAE,sBAAsB,WAAW,qBAAqB,IAAI,CAAC;AAAA;AAAA,UAEpG,GAAI,YAAY,oBAAoB,SAAS,EAAE,oBAAoB,WAAW,mBAAmB,IAAI,CAAC;AAAA,QACxG;AAAA,MACF;AAAA,IACF;AAEA,6BAAyB,aAAa,gBAAgB,cAAc,cAAc;AAClF,WAAO;AAAA,EACT;AAEA,QAAM,cAAsB,WAAW,SAAS;AAGhD,MAAI,kBAAkB,OAAO,WAAW;AACtC,UAAM,UAAU,KAAK,OAAO,KAAK,IAAI,IAAI,MAAM,cAAc,MAAO,KAAK,KAAK,GAAG;AACjF,QAAI,WAAW,IAAI;AACjB,YAAM,KAAK,sCAAsC,OAAO,+BAA+B,WAAW,WAAW;AAC7G,YAAM,KAAK,yFAAoF;AAC/F,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAI;AACJ,MAAI,gBAAgB;AAElB,UAAM,OAAO,CAAC,OAAO,YAAY,mBAAmB;AACpD,UAAM,YAAY,OAAO,CAAC,KAAK,UAAU,eAAe,KAAK,MAAM,IAAI,KAAK,WAAW,gBAAgB,KAAK,OAAO,EAAE,EAAE,OAAO,CAAC,MAAmB,QAAQ,CAAC,CAAC,IAAI,CAAC;AACjK,QAAI,UAAU,SAAS,EAAG,OAAM,KAAK,wBAAwB,GAAG,WAAW,EAAE;AAC7E,UAAM,uBACH,WAAW,kBAAkB,OAAO,kBAAkB,YAAY,SAC/D,kGACA;AAEN,UAAM,OAAuB,UAAU,QAAQ,CAAC;AAChD,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,SAAqB;AAAA,QACzB,OAAO;AAAA,QACP,cAAc,UAAU,gBAAgB;AAAA,QACxC,aAAa,UAAU,eAAe;AAAA,QACtC,OAAO,UAAU,SAAS;AAAA,MAC5B;AAEA,YAAM,KAAK,mBAAmB,KAAK,CAAC,GAAG,KAAK,SAAS,GAAG,MAAM,CAAC;AAC/D,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,mBAAmB;AAC9B,YAAM,KAAK,EAAE;AAEb,YAAM,gBAAgB,KAAK,SAAS;AACpC,UAAI,gBAAgB,KAAK,aAAa,SAAS,GAAG;AAChD,cAAM,QAAkB,CAAC;AACzB,YAAI,gBAAgB,EAAG,OAAM,KAAK,GAAG,aAAa,aAAa,kBAAkB,IAAI,KAAK,GAAG,WAAW;AACxG,YAAI,aAAa,SAAS,EAAG,OAAM,KAAK,GAAG,aAAa,MAAM,gBAAgB,aAAa,WAAW,IAAI,KAAK,GAAG,EAAE;AACpH,cAAM,KAAK,IAAI,MAAM,KAAK,OAAO,CAAC,iDAA4C;AAC9E,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AAEA,UAAM,KAAK,6EAAwE;AACnF,UAAM,KAAK,EAAE;AAAA,EACf,WAAW,WAAW;AACpB,UAAM,MAAM,CAAC,MAAW;AACtB,YAAM,OAAO,EAAE,gBAAgB;AAC/B,YAAM,UAAU,EAAE,WAAW;AAE7B,YAAM,iBAAiB,EAAE,aAAa,iBAAiB,EAAE,UAAU,MAAM;AACzE,YAAM,gBAAgB,EAAE,YAAY,IAAI,KAAK,EAAE,QAAQ,EAAE,QAAQ,IAAI,KAAK,IAAI;AAC9E,YAAM,cAAc,gBAAgB,sBAAsB;AAE1D,YAAM,aAAa,EAAE,SAAS,aAAa,EAAE,MAAM,MAAM;AAEzD,YAAM,OAAO,eAAe,EAAE,UAAU;AACxC,YAAM,eAAe,EAAE,aAAa,KAAK,EAAE,UAAU,MAAM;AAG3D,YAAM,gBAAgB,kBAAkB,EAAE,oBAAoB;AAC9D,aAAO,KAAK,IAAI,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,IAAI,SAAM,OAAO,KAAK,EAAE,IAAI,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,WAAW,GAAG,aAAa;AAAA,IACvJ;AAGA,UAAM,gBAAgB,MAAM,sBAAsB;AAClD,QAAI,eAAe;AACjB,8BAAwB,cAAc,YAAY;AAAA,IACpD;AAEA,QAAI,MAAM;AAER,YAAM,KAAK,kBAAkB,WAAW,qBAAqB,IAAI,IAAI;AACrE,YAAM,KAAK,EAAE;AAEb,UAAI,YAAY,kBAAkB;AAChC,cAAM,KAAK,WAAW;AACtB,cAAM,KAAK,sBAAsB;AACjC,YAAI,GAAG,OAAQ,OAAM,KAAK,eAAe,GAAG,MAAM,EAAE;AACpD,YAAI,GAAG,QAAS,OAAM,KAAK,gBAAgB,GAAG,OAAO,EAAE;AACvD,YAAI,GAAG,oBAAoB,QAAQ,GAAG,mBAAmB,EAAG,OAAM,KAAK,oBAAoB,GAAG,gBAAgB,SAAS,GAAG,gBAAgB,CAAC,GAAG,KAAK,IAAI,CAAC,EAAE;AAC1J,YAAI,GAAG,qBAAqB,QAAQ,GAAG,oBAAoB,EAAG,OAAM,KAAK,oBAAoB,GAAG,iBAAiB,SAAS,GAAG,gBAAgB,CAAC,GAAG,KAAK,IAAI,CAAC,EAAE;AAE7J,cAAM,YAAY,GAAG;AACrB,cAAM,iBAAiB,mBAAmB,gBAAgB,YAAY,QAAQ;AAC9E,cAAM,eAAe,mBAAmB,gBAAgB,UAAU,QAAQ;AAC1E,cAAM,UAAU,YACZ,aAAa,cAAc,OAAO,SAAS,KAAK,GAAG,cAAc,WAAW,YAAY,MACxF,aAAa,YAAY;AAC7B,cAAM,KAAK,GAAG,OAAO,IAAI,GAAG,kBAAkB,mBAAmB;AACjE,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,YAAY,kBAAkB,WAAW,eAAe,SAAS,GAAG;AACtE,cAAM,KAAK,oBAAoB;AAC/B,cAAM,KAAK,qDAAqD;AAChE,cAAM,KAAK,EAAE;AACb,mBAAW,KAAK,WAAW,gBAAgB;AACzC,gBAAM,KAAK,EAAE,WAAW,EAAE;AAC1B,gBAAM,OAAO,EAAE,gBAAgB;AAC/B,gBAAM,OAAO,EAAE,iBAAiB,KAAK,EAAE,cAAc,MAAM;AAC3D,gBAAM,KAAK,OAAO,EAAE,aAAa,EAAE,KAAK,MAAM,IAAI,IAAI,IAAI,WAAM,EAAE,IAAI,EAAE;AACxE,cAAI,EAAE,UAAW,OAAM,KAAK,MAAM,EAAE,SAAS,GAAG;AAChD,cAAI,YAAY,KAAK,OAAO,EAAE,WAAW,YAAY,EAAE,OAAO,SAAS,GAAG;AACxE,kBAAM,aAAa;AACnB,kBAAM,aAAa,EAAE,OAAO,SAAS,aACjC,EAAE,OAAO,MAAM,GAAG,UAAU,IAAI,uEAChC,EAAE;AACN,kBAAM,KAAK,EAAE;AACb,kBAAM,KAAK,oDAAoD;AAC/D,kBAAM,KAAK,OAAO;AAClB,uBAAW,QAAQ,WAAW,MAAM,IAAI,EAAG,OAAM,KAAK,OAAO,IAAI;AACjE,kBAAM,KAAK,OAAO;AAClB,kBAAM,KAAK,EAAE;AAAA,UACf;AAAA,QACF;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,YAAY,sBAAsB,WAAW,mBAAmB,SAAS,GAAG;AAC9E,cAAM,KAAK,yBAAyB;AACpC,cAAM,KAAK,4DAA4D;AACvE,cAAM,KAAK,EAAE;AACb,mBAAW,KAAK,WAAW,oBAAoB;AAC7C,gBAAM,KAAK,EAAE,WAAW,EAAE;AAC1B,gBAAM,OAAO,EAAE,gBAAgB;AAC/B,gBAAM,OAAO,EAAE,iBAAiB,KAAK,EAAE,cAAc,MAAM;AAC3D,gBAAM,KAAK,OAAO,EAAE,OAAO,IAAI,IAAI,IAAI,WAAM,EAAE,IAAI,EAAE;AACrD,cAAI,YAAY,KAAK,OAAO,EAAE,WAAW,YAAY,EAAE,OAAO,SAAS,GAAG;AACxE,kBAAM,aAAa;AACnB,kBAAM,aAAa,EAAE,OAAO,SAAS,aACjC,EAAE,OAAO,MAAM,GAAG,UAAU,IAAI,uEAChC,EAAE;AACN,kBAAM,KAAK,EAAE;AACb,kBAAM,KAAK,eAAe;AAC1B,kBAAM,KAAK,OAAO;AAClB,uBAAW,QAAQ,WAAW,MAAM,IAAI,EAAG,OAAM,KAAK,OAAO,IAAI;AACjE,kBAAM,KAAK,OAAO;AAClB,kBAAM,KAAK,EAAE;AAAA,UACf;AAAA,QACF;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,YAAY,eAAe,WAAW,YAAY,QAAQ,SAAS,GAAG;AACxE,cAAM,KAAK,WAAW;AACtB,cAAM,KAAK,iBAAiB;AAG5B,YAAI,GAAG,mBAAmB,GAAG,eAAe;AAC1C,gBAAM,KAAK,kBAAQ,GAAG,aAAa,EAAE;AACrC,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,YAAI,WAAW,SAAS,iBAAiB;AACvC,gBAAM,YAAY,WAAW,QAAQ;AACrC,gBAAM,WAAW,UAAU,qBAAqB,KAAK,UAAU,kBAAkB,MAAM;AACvF,gBAAM,KAAK,sBAAsB,UAAU,KAAK,GAAG,QAAQ,GAAG;AAC9D,cAAI,UAAU,aAAc,OAAM,KAAK,mBAAmB,UAAU,YAAY,GAAG;AACnF,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,KAAK,yBAAyB,GAAG,UAAU,gBAAgB,GAAG,UAAU,YAAY;AAC1F,cAAM,KAAK,EAAE;AACb,mBAAW,KAAK,GAAG,SAAS;AAC1B,gBAAM,KAAK,EAAE,WAAW,EAAE;AAC1B,gBAAM,OAAO,EAAE,iBAAiB,KAAK,EAAE,cAAc,MAAM;AAC3D,gBAAM,YAAY,EAAE,SAAS,aAAa,EAAE,MAAM,MAAM;AACxD,gBAAM,KAAK,OAAO,EAAE,aAAa,EAAE,KAAK,IAAI,IAAI,GAAG,SAAS,GAAG,EAAE,SAAS,KAAK,WAAM,EAAE,IAAI,KAAK,EAAE,EAAE;AAAA,QAItG;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,YAAY,aAAa,wBAAwB,WAAW,YAAY,qBAAqB,SAAS,GAAG;AAI3G,cAAM,uBAAiD,WAAW,YAAY,qBAAqB,IAAI,CAAC,OAAO;AAAA,UAC7G,SAAS,EAAE,WAAW,EAAE;AAAA,UACxB,MAAM,EAAE;AAAA,UACR,gBAAgB,EAAE,kBAAkB;AAAA,UACpC,cAAc,EAAE;AAAA,QAClB,EAAE;AACF,cAAM,KAAK,GAAG;AAAA,UACZ;AAAA,UACA,WAAW,YAAY;AAAA,QACzB,CAAC;AAAA,MACH;AAEA,UAAI,YAAY,kBAAkB,WAAW,eAAe,SAAS,GAAG;AACtE,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,qBAAqB;AAChC,cAAM,KAAK,6DAA6D;AACxE,cAAM,KAAK,EAAE;AACb,mBAAW,KAAK,WAAW,gBAAgB;AACzC,gBAAM,KAAK,OAAO,EAAE,cAAc,OAAO,EAAE,IAAI,EAAE;AAAA,QACnD;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,YAAY;AAId,cAAM,KAAK,GAAG,wBAAwB,WAAW,aAAa,CAAC;AAC/D,cAAM,mBAAmB,0BAA0B,WAAW,gBAAgB;AAC9E,YAAI,iBAAkB,OAAM,KAAK,gBAAgB;AAEjD,cAAM,KAAK,GAAG,yBAAyB,YAAY,EAAE,aAAa,qBAAqB,YAAY,gBAAgB,KAAK,CAAC,CAAC;AAE1H,cAAM,KAAK,GAAG,4BAA4B,WAAW,gBAAgB,CAAC;AACtE,cAAM,KAAK,GAAG,4BAA4B,WAAW,gBAAgB,CAAC;AACtE,cAAM,KAAK,GAAG,8BAA8B,WAAW,kBAAkB,CAAC;AAE1E,YAAI,WAAW,cAAc;AAC3B,gBAAM,KAAK,WAAW;AACtB,cAAI,GAAG,WAAW,KAAK,GAAG,aAAa,GAAG;AACxC,kBAAM,UAAU,GAAG,aAAa,qBAAqB;AACrD,kBAAM,KAAK,kBAAkB;AAC7B,kBAAM,KAAK,8CAA8C,OAAO,IAAI;AACpE,kBAAM,KAAK,EAAE;AACb,kBAAM,KAAK,mBAAmB,GAAG,QAAQ,EAAE;AAC3C,kBAAM,KAAK,qBAAqB,GAAG,UAAU,EAAE;AAC/C,kBAAM,KAAK,kCAAkC,GAAG,QAAQ,EAAE;AAC1D,kBAAM,KAAK,wBAAwB,GAAG,KAAK,EAAE;AAC7C,kBAAM,KAAK,EAAE;AAAA,UACf;AAAA,QACF;AAEA,cAAM,gBAAgB,+BAA+B,WAAW,oBAAoB;AACpF,YAAI,cAAe,OAAM,KAAK,eAAe,EAAE;AAAA,MACjD;AAEA,UAAI,eAAe;AACjB,cAAM,KAAK,GAAG,cAAc,KAAK;AAAA,MACnC;AAEA,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,kBAAkB,4BAA4B,cAAc;AAClE,YAAI,gBAAgB,aAAa,KAAK,gBAAgB,eAAe,GAAG;AACtE,gBAAM,KAAK,GAAG,gBAAgB,KAAK;AAAA,QACrC;AAAA,MACF;AAEA,UAAI,YAAY;AACd,cAAM,gBAAgB,WAAW,sBAAsB,CAAC;AACxD,YAAI,cAAc,SAAS,GAAG;AAC5B,gBAAM,KAAK,8CAAyC;AACpD,gBAAM,KAAK,yEAAyE;AACpF,gBAAM,KAAK,EAAE;AACb,qBAAW,KAAK,eAAe;AAC7B,kBAAM,KAAK,IAAI,CAAC,CAAC;AACjB,kBAAM,WAAW,EAAE;AACnB,gBAAI,UAAU,QAAQ;AACpB,oBAAM,eAAe,SAAS,IAAI,CAAC,MAAM;AACvC,sBAAM,OAAO,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAC/D,uBAAO,KAAK,EAAE,WAAW,EAAE,IAAI,OAAO,EAAE,IAAI,GAAG,OAAO,KAAK,IAAI,KAAK,EAAE;AAAA,cACxE,CAAC;AACD,oBAAM,KAAK,eAAe,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,YACrD;AAAA,UACF;AACA,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,kBAAkB,WAAW,eAAe,CAAC;AACnD,YAAI,gBAAgB,SAAS,GAAG;AAC9B,gBAAM,KAAK,iBAAiB;AAC5B,0BAAgB,QAAQ,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;AACjD,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,yBAAyB,WAAW,sBAAsB,CAAC;AACjE,YAAI,uBAAuB,SAAS,GAAG;AACrC,gBAAM,KAAK,wBAAwB;AACnC,gBAAM,KAAK,sGAAiG;AAC5G,gBAAM,KAAK,EAAE;AAEb,iCAAuB,QAAQ,CAAC,MAAW,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,UAAU,WAAM,EAAE,OAAO,KAAK,GAAG,CAAC;AACpG,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,mBAAmB,WAAW,gBAAgB,CAAC;AACrD,YAAI,iBAAiB,SAAS,GAAG;AAC/B,gBAAM,KAAK,kBAAkB;AAC7B,gBAAM,KAAK,0DAA0D;AACrE,gBAAM,KAAK,EAAE;AACb,2BAAiB,QAAQ,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;AAClD,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,sBAAsB,WAAW,mBAAmB,CAAC;AAC3D,YAAI,oBAAoB,SAAS,GAAG;AAClC,gBAAM,KAAK,qBAAqB;AAChC,8BAAoB,QAAQ,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;AACrD,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,yBAAyB,WAAW,sBAAsB,CAAC;AACjE,YAAI,uBAAuB,SAAS,GAAG;AACrC,gBAAM,KAAK,wBAAwB;AACnC,iCAAuB,QAAQ,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;AACxD,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,mBAAmB,WAAW,gBAAgB,CAAC;AACrD,YAAI,iBAAiB,SAAS,GAAG;AAC/B,gBAAM,KAAK,uBAAuB;AAClC,gBAAM,KAAK,4CAA4C,WAAW,sBAAsB,SAAS;AACjG,2BAAiB,QAAQ,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;AAClD,gBAAM,KAAK,EAAE;AAAA,QACf;AACA,cAAM,wBAAwB,WAAW,qBAAqB,CAAC;AAC/D,YAAI,sBAAsB,SAAS,GAAG;AACpC,gBAAM,KAAK,uBAAuB;AAClC,gCAAsB,QAAQ,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;AACvD,gBAAM,KAAK,EAAE;AAAA,QACf;AAEA,cAAM,qBAAqB,CAAC,OAAY;AAAA,UACtC,SAAS,EAAE;AAAA,UACX,MAAM,EAAE;AAAA,UACR,aAAa,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,UACzD,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA;AAAA,UAE5C,YAAY,EAAE;AAAA,UACd,YAAY,OAAO,EAAE,eAAe,WAAW,EAAE,aAAa;AAAA,QAChE;AACA,cAAM,MAAM,WAAW,cAAc,EAAE,YAAY,CAAC,GAAG,WAAW,CAAC,GAAG,eAAe,CAAC,EAAE;AACxF,cAAM,KAAK,GAAG,uBAAuB;AAAA,UACnC,aAAa,IAAI,cAAc,CAAC,GAAG,IAAI,kBAAkB;AAAA,UACzD,YAAY,IAAI,aAAa,CAAC,GAAG,IAAI,kBAAkB;AAAA,UACvD,gBAAgB,IAAI,iBAAiB,CAAC,GAAG,IAAI,kBAAkB;AAAA,QACjE,GAAG,IAAI,CAAC;AAAA,MACV;AAEA,UAAI,aAAoB,CAAC;AACzB,UAAI;AACF,qBAAa,MAAM,YAA2D,qBAAqB;AAAA,UACjG,QAAQ,CAAC,OAAO,WAAW,QAAQ,UAAU,kBAAkB,kBAAkB,WAAW,cAAc;AAAA,QAC5G,CAAC,KAAK,CAAC;AAAA,MACT,QAAQ;AAAA,MAAqB;AAE7B,YAAM,cAAc,iBAAiB,UAAU;AAE/C,UAAI,eAAe,WAAW,GAAG;AAC/B,cAAM,KAAK,GAAG,wBAAwB,aAAa,eAAe,aAAa,CAAC;AAAA,MAClF,WAAW,eAAe;AACxB,cAAM,KAAK,GAAG,oBAAoB,aAAa,CAAC;AAAA,MAClD;AAAA,IACF,OAAO;AAEL,YAAM,KAAK,kBAAkB,WAAW,KAAK;AAC7C,YAAM,KAAK,EAAE;AAEb,YAAM,WAAW,YAAY;AAC7B,YAAM,gBAAgB,WAAW,CAAC,SAAS,UAAU,eAAe,SAAS,MAAM,IAAI,SAAS,WAAW,gBAAgB,SAAS,OAAO,EAAE,EAAE,OAAO,CAAC,MAAmB,QAAQ,CAAC,CAAC,IAAI,CAAC;AACzL,UAAI,cAAc,SAAS,EAAG,OAAM,KAAK,wBAAwB,GAAG,eAAe,EAAE;AAErF,YAAM,KAAK,GAAG,yBAAyB,YAAY,EAAE,aAAa,qBAAqB,YAAY,gBAAgB,KAAK,CAAC,CAAC;AAE1H,UAAI,YAAY,oBAAoB,QAAQ;AAC1C,cAAM,KAAK,8CAAyC;AACpD,cAAM,KAAK,yEAAyE;AACpF,cAAM,KAAK,EAAE;AACb,mBAAW,KAAK,WAAW,oBAAoB;AAC7C,gBAAM,KAAK,IAAI,CAAC,CAAC;AAAA,QACnB;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAGA,YAAM,KAAK,GAAG,4BAA4B,YAAY,gBAAgB,CAAC;AACvE,YAAM,KAAK,GAAG,4BAA4B,YAAY,gBAAgB,CAAC;AACvE,YAAM,KAAK,GAAG,8BAA8B,YAAY,kBAAkB,CAAC;AAG3E,UAAI,YAAY,cAAc;AAC5B,cAAM,KAAK,WAAW;AACtB,YAAI,GAAG,WAAW,KAAK,GAAG,aAAa,GAAG;AACxC,gBAAM,UAAU,GAAG,aAAa,qBAAqB;AACrD,gBAAM,KAAK,kBAAkB;AAC7B,gBAAM,KAAK,8CAA8C,OAAO,IAAI;AACpE,gBAAM,KAAK,EAAE;AACb,gBAAM,KAAK,mBAAmB,GAAG,QAAQ,EAAE;AAC3C,gBAAM,KAAK,qBAAqB,GAAG,UAAU,EAAE;AAC/C,gBAAM,KAAK,kCAAkC,GAAG,QAAQ,EAAE;AAC1D,gBAAM,KAAK,wBAAwB,GAAG,KAAK,EAAE;AAC7C,gBAAM,KAAK,EAAE;AAAA,QACf;AAAA,MACF;AAEA,YAAM,kBAAkB,+BAA+B,YAAY,oBAAoB;AACvF,UAAI,gBAAiB,OAAM,KAAK,iBAAiB,EAAE;AAEnD,YAAM,KAAK,GAAG,uBAAuB,CAAC;AAEtC,UAAI,eAAe;AACjB,cAAM,KAAK,GAAG,cAAc,KAAK;AAAA,MACnC;AAEA,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,kBAAkB,4BAA4B,cAAc;AAClE,YAAI,gBAAgB,aAAa,KAAK,gBAAgB,eAAe,GAAG;AACtE,gBAAM,KAAK,GAAG,gBAAgB,KAAK;AAAA,QACrC;AAAA,MACF;AAEA,UAAI,cAAc,SAAS,KAAK,CAAC,eAAe;AAC9C,cAAM,OAAO,cAAc,CAAC;AAC5B,cAAM,OAAO,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI;AACrF,cAAM,UAAU,MAAM,QAAQ,KAAK,cAAc,IAAI,KAAK,eAAe,SAAS,KAAK,kBAAkB;AACzG,cAAM,WAAW,MAAM,QAAQ,KAAK,eAAe,IAAI,KAAK,gBAAgB,SAAS,KAAK,mBAAmB;AAC7G,cAAM,KAAK,kBAAkB,IAAI,MAAM,OAAO,aAAa,QAAQ,aAAa;AAChF,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,eAAe;AACjB,cAAM,KAAK,GAAG,oBAAoB,aAAa,CAAC;AAAA,MAClD;AAEA,YAAM,KAAK,qFAAqF;AAChG,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAGA,QAAM,qBAAqB,WAAW,MAAM,OAAO,CAAC,MAAuB,EAAE,IAAI,aAAa,kBAAkB,CAAC,KAAK,CAAC;AACvH,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,KAAK,wBAAwB;AACnC,UAAM,KAAK,gFAA2E;AACtF,UAAM,KAAK,EAAE;AACb,eAAW,KAAK,oBAAoB;AAClC,YAAM,KAAK,KAAM,EAAyB,SAAS,EAAE,IAAI,UAAU,gBAAgB,EAAE,KAAK,SAAS,EAAE;AAAA,IACvG;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,WAAW;AACtB,eAAW,OAAO,OAAQ,OAAM,KAAK,KAAK,GAAG,EAAE;AAC/C,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,oBAA4E;AAChF,MAAI,kBAAkB,kBAAkB;AACtC,UAAM,aAAa,MAAM,iCAAiC,gBAAgB,qBAAqB;AAC/F,QAAI,YAAY;AACd,0BAAoB;AAEpB,YAAM,KAAK,KAAK;AAChB,YAAM,KAAK,iCAAiC,cAAc,0BAA0B;AAAA,IACtF,OAAO;AACL,0BAAoB;AACpB,YAAM,KAAK,KAAK;AAChB,YAAM,KAAK,+EAA+E;AAAA,IAC5F;AAGA,QAAI;AACF,YAAM,eAAe,6BAA6B;AAAA,QAChD,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,UAAU,EAAE,QAAQ,SAAS;AAAA,MAC/B,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,cAAQ,OAAO,MAAM,qCAAsC,IAAc,OAAO;AAAA,CAAI;AAAA,IAEtF;AAAA,EACF,WAAW,gBAAgB;AACzB,wBAAoB;AACpB,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,wGAAwG;AAAA,EACrH,OAAO;AACL,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,oFAAoF;AAAA,EACjG;AAGA,QAAM,gBAAgB,YAAY,SAAS,aAAa,YAAY,cAAc;AAClF,MAAI,eAAe;AACjB,UAAM,UAAU,YAAY,SAAS;AACrC,UAAM,KAAK,EAAE;AACb,QAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,YAAM,KAAK,0CAA0C,QAAQ,KAAK,IAAI,CAAC,wCAAwC;AAAA,IACjH,OAAO;AACL,YAAM,KAAK,6EAA6E;AAAA,IAC1F;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,2BAA2B,WAAW,KAAK,iBAAiB,sCAAiC,QAAQ;AAAA,MACrG;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU,mBAAmB,kBAAkB,IAAI;AAAA,QACnD,WAAW;AAAA,QACX,qBAAqB,mBAAmB,gBAAgB,OAAO,yBAAyB;AAAA,QACxF,uBAAuB,CAAC;AAAA;AAAA,QAExB,GAAI,YAAY,aAAa,kBAAkB,EAAE,eAAe,KAAK,IAAI,CAAC;AAAA;AAAA,QAE1E,GAAI,YAAY,gBAAgB,EAAE,eAAe,WAAW,cAAc,IAAI,CAAC;AAAA,QAC/E,GAAI,YAAY,kBAAkB,SAAS,EAAE,kBAAkB,WAAW,iBAAiB,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,QAIhG,GAAI,YAAY,kBAAkB,SAAY,EAAE,eAAe,WAAW,cAAc,IAAI,CAAC;AAAA,QAC7F,GAAI,YAAY,mBAAmB,SAAY,EAAE,gBAAgB,WAAW,eAAe,IAAI,CAAC;AAAA,QAChG,GAAI,YAAY,cAAc,SAAY,EAAE,WAAW,WAAW,UAAU,IAAI,CAAC;AAAA,QACjF,GAAI,YAAY,cAAc,SAAY,EAAE,WAAW,WAAW,UAAU,IAAI,CAAC;AAAA;AAAA,QACjF,GAAI,YAAY,gBAAgB,SAAY,EAAE,aAAa,WAAW,YAAY,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,QAGvF,GAAI,YAAY,gBAAgB,EAAE,eAAe,WAAW,cAAc,IAAI,CAAC;AAAA,QAC/E,iBAAiB,YAAY,SAAS;AAAA,QACtC;AAAA,QACA,UAAU,mBAAmB,SAAY;AAAA,QACzC,GAAI,YAAY,UAAU,EAAE,SAAS,WAAW,QAAQ,IAAI,CAAC;AAAA;AAAA;AAAA,QAG7D,GAAI,YAAY,uBAAuB,EAAE,sBAAsB,WAAW,qBAAqB,IAAI,CAAC;AAAA;AAAA,QAEpG,GAAI,YAAY,oBAAoB,SAAS,EAAE,oBAAoB,WAAW,mBAAmB,IAAI,CAAC;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AAEA,2BAAyB,YAAY,eAAe,cAAc,cAAc;AAChF,SAAO;AACb;;;AiB50CA,SAAS,KAAAC,WAAS;;;AC6FlB,SAAS,sBAAsB,UAA8C;AAC3E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,SAAS,SAAS,IAAI,CAAC,YAAY,EAAE,GAAG,OAAO,EAAE;AAAA,EAC5D;AACF;AAEA,SAAS,mBAAmB,OAAqC;AAC/D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,MAAM,WAAW,IAAI,qBAAqB;AAAA,IACrD,cAAc,EAAE,GAAG,MAAM,aAAa;AAAA,EACxC;AACF;AAEO,SAAS,wBACd,YACoB;AACpB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,WAAW,OAAO,IAAI,kBAAkB;AAAA,IAChD,UAAU,EAAE,GAAG,WAAW,SAAS;AAAA,IACnC,QAAQ;AAAA,MACN,eAAe;AAAA,QACb,SACE,WAAW,OAAO,cAAc,QAAQ,SAAS,UAC7C;AAAA,UACE,MAAM;AAAA,UACN,YAAY,WAAW,OAAO,cAAc,QAAQ;AAAA,QACtD,IACA,EAAE,MAAM,aAAa;AAAA,MAC7B;AAAA,MACA,gBAAgB,WAAW,OAAO,iBAC9B,EAAE,GAAG,WAAW,OAAO,eAAe,IACtC;AAAA,MACJ,OAAO,WAAW,OAAO,OAAO,IAAI,CAAC,aAAa,EAAE,GAAG,QAAQ,EAAE;AAAA,IACnE;AAAA,IACA,SAAS,EAAE,GAAG,WAAW,QAAQ;AAAA,EACnC;AACF;AAEO,SAAS,wBACd,YACoB;AACpB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,WAAW,OAAO,IAAI,kBAAkB;AAAA,IAChD,kBAAkB,WAAW,mBACzB,EAAE,GAAG,WAAW,iBAAiB,IACjC;AAAA,EACN;AACF;AAEO,SAAS,2BACd,YACM;AACN,MAAI,WAAW,OAAO,WAAW,GAAG;AAClC,UAAM,IAAI,MAAM,aAAa,WAAW,EAAE,mCAAmC;AAAA,EAC/E;AAEA,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,CAAC,OAAO,KAAK,KAAK,WAAW,OAAO,QAAQ,GAAG;AACxD,QAAI,SAAS,IAAI,MAAM,EAAE,GAAG;AAC1B,YAAM,IAAI,MAAM,aAAa,WAAW,EAAE,6BAA6B,MAAM,EAAE,IAAI;AAAA,IACrF;AACA,aAAS,IAAI,MAAM,EAAE;AAErB,UAAM,cAAc,OAAO,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AACrD,QAAI,MAAM,QAAQ,aAAa;AAC7B,YAAM,IAAI;AAAA,QACR,aAAa,WAAW,EAAE,YAAY,MAAM,EAAE,cAAc,MAAM,GAAG,gBAAgB,WAAW;AAAA,MAClG;AAAA,IACF;AAEA,UAAM,cAAc,oBAAI,IAAY;AACpC,eAAW,YAAY,MAAM,aAAa,CAAC,GAAG;AAC5C,UAAI,YAAY,IAAI,SAAS,EAAE,GAAG;AAChC,cAAM,IAAI;AAAA,UACR,aAAa,WAAW,EAAE,YAAY,MAAM,EAAE,gCAAgC,SAAS,EAAE;AAAA,QAC3F;AAAA,MACF;AACA,kBAAY,IAAI,SAAS,EAAE;AAAA,IAC7B;AAAA,EACF;AAEA,MACE,WAAW,QAAQ,SAAS,iBAC5B,CAAC,WAAW,QAAQ,aACpB;AACA,UAAM,IAAI;AAAA,MACR,aAAa,WAAW,EAAE;AAAA,IAC5B;AAAA,EACF;AAEA,MACE,WAAW,OAAO,gBAAgB,wBAClC,WAAW,OAAO,cAAc,QAAQ,SAAS,WACjD,WAAW,OAAO,eAAe,qBAAqB,IACtD;AACA,UAAM,IAAI;AAAA,MACR,aAAa,WAAW,EAAE;AAAA,IAC5B;AAAA,EACF;AACF;AAEO,SAAS,oCACd,YAMO;AACP,QAAM,EAAE,eAAe,IAAI,WAAW;AACtC,QAAM,EAAE,QAAQ,IAAI,WAAW,OAAO;AAEtC,MAAI,CAAC,kBAAkB,CAAC,eAAe,sBAAsB;AAC3D,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,SACE,QAAQ,SAAS,UACb,EAAE,MAAM,SAAS,YAAY,QAAQ,WAAW,IAChD,EAAE,MAAM,aAAa;AAAA,IAC3B,cAAc,eAAe;AAAA,IAC7B,kBAAkB,eAAe;AAAA,IACjC,mBAAmB,eAAe,qBAAqB;AAAA,EACzD;AACF;AAEO,SAAS,mCACd,YACe;AACf,QAAM,EAAE,QAAQ,IAAI,WAAW,OAAO;AACtC,SAAO,QAAQ,SAAS,UAAU,QAAQ,aAAa;AACzD;AAEO,SAAS,4BACd,YACgC;AAChC,SAAO;AAAA,IACL,MAAM,WAAW,SAAS;AAAA,IAC1B,MAAM,WAAW,SAAS;AAAA,EAC5B;AACF;AAQO,SAAS,8BACd,YACQ;AACR,QAAM,EAAE,QAAQ,IAAI,WAAW,OAAO;AAEtC,MAAI,QAAQ,SAAS,SAAS;AAC5B,WAAO,8BAA8B,QAAQ,UAAU;AAAA,EACzD;AAEA,SAAO;AACT;AAEO,SAAS,0BACd,YACoB;AACpB,6BAA2B,UAAU;AACrC,QAAM,mBAAmB,wBAAwB,UAAU;AAC3D,QAAM,0BAA0B;AAAA,IAC9B;AAAA,EACF;AACA,QAAM,iBAAiB,oCAAoC,gBAAgB;AAE3E,SAAO;AAAA,IACL,IAAI,iBAAiB;AAAA,IACrB,MAAM,iBAAiB;AAAA,IACvB,kBAAkB,iBAAiB;AAAA,IACnC,MAAM,iBAAiB;AAAA,IACvB,qBAAqB,iBAAiB;AAAA,IACtC,QAAQ,iBAAiB;AAAA,IACzB,oBAAoB,2BAA2B;AAAA,IAC/C,kBACE,kBAAkB,eAAe,QAAQ,SAAS,UAChD;AAAA,MACE,cAAc,eAAe;AAAA,MAC7B,kBAAkB,eAAe,oBAAoB;AAAA,IACvD,IACA;AAAA,IACJ,eAAe,iBAAiB;AAAA,EAClC;AACF;;;AC3QA,IAAM,4BAAgD;AAAA,EACpD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,kBACE;AAAA,EACF,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,EACN,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoCrB,QAAQ;AAAA,IACN;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MACF,WAAW;AAAA,QACT;AAAA,UACE,IAAI;AAAA,UACJ,QACE;AAAA,UACF,SAAS;AAAA,YACP,EAAE,IAAI,aAAa,OAAO,mBAAmB;AAAA,YAC7C,EAAE,IAAI,eAAe,OAAO,oBAAoB;AAAA,YAChD,EAAE,IAAI,oBAAoB,OAAO,gCAAgC;AAAA,YACjE,EAAE,IAAI,WAAW,OAAO,wBAAwB;AAAA,YAChD,EAAE,IAAI,UAAU,OAAO,2CAAsC;AAAA,UAC/D;AAAA,QACF;AAAA,MACF;AAAA,MACA,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MACF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MACF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MACF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MACF,WAAW;AAAA,QACT;AAAA,UACE,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,EAAE,IAAI,OAAO,OAAO,4CAAuC;AAAA,YAC3D,EAAE,IAAI,UAAU,OAAO,8BAA8B;AAAA,YACrD,EAAE,IAAI,OAAO,OAAO,qBAAqB;AAAA,UAC3C;AAAA,QACF;AAAA,MACF;AAAA,MACA,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MACF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,QAAQ;AAAA,IACN,eAAe;AAAA,MACb,SAAS;AAAA,QACP,MAAM;AAAA,QACN,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd,sBAAsB;AAAA,MACtB,cAAc;AAAA,MACd,kBAAkB;AAAA,IACpB;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EAEA,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWjB;AAIA,IAAM,4BAAgD;AAAA,EACpD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,kBACE;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,EACN,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrB,QAAQ;AAAA,IACN;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAOF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAMF,WAAW;AAAA,QACT;AAAA,UACE,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,EAAE,IAAI,SAAS,OAAO,8CAAyC;AAAA,YAC/D,EAAE,IAAI,OAAO,OAAO,2CAAsC;AAAA,UAC5D;AAAA,QACF;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,EAAE,IAAI,MAAM,OAAO,mCAA8B;AAAA,YACjD,EAAE,IAAI,UAAU,OAAO,gDAA2C;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,MACA,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAUF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MASF,WAAW;AAAA,QACT;AAAA,UACE,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,EAAE,IAAI,MAAM,OAAO,qCAAgC;AAAA,YACnD,EAAE,IAAI,OAAO,OAAO,6CAAwC;AAAA,YAC5D,EAAE,IAAI,UAAU,OAAO,uCAAkC;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA,MACA,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAUF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAMF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,QAAQ;AAAA,IACN,eAAe;AAAA,MACb,SAAS;AAAA;AAAA,QAEP,MAAM;AAAA,QACN,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EAEA,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASjB;AAUA,IAAM,4CAAgE;AAAA,EACpE,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,kBACE;AAAA,EAGF,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,EACN,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgDrB,QAAQ;AAAA,IACN;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MASF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MAEF,qBACE;AAAA,MAWF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aACE;AAAA,QACF,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAaF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MAEF,qBACE;AAAA,MASF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MAEF,qBACE;AAAA,MAeF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAMF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,QAAQ;AAAA,IACN,eAAe;AAAA,MACb,SAAS;AAAA,QACP,MAAM;AAAA,QACN,YAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd,sBAAsB;AAAA,MACtB,cAAc;AAAA,MACd,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,QACjB,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EAEA,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQjB;AAaA,IAAM,qCAAyD;AAAA,EAC7D,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,kBACE;AAAA,EAGF,UAAU;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,EACN,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BrB,QAAQ;AAAA,IACN;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAGF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAIF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAIF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aACE;AAAA,MACF,qBACE;AAAA,MAOF,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,QAAQ;AAAA,IACN,eAAe;AAAA,MACb,SAAS;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd,sBAAsB;AAAA,MACtB,cAAc;AAAA,MACd,mBAAmB;AAAA,QACjB,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EAEA,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQjB;AAIA,IAAM,uBAAuB,oBAAI,IAAgC;AAAA,EAC/D,CAAC,SAAS,yBAAyB;AAAA,EACnC,CAAC,SAAS,yBAAyB;AAAA,EACnC,CAAC,yBAAyB,yCAAyC;AAAA,EACnE,CAAC,kBAAkB,kCAAkC;AACvD,CAAC;AAED,IAAM,YAAY,IAAI;AAAA,EACpB,MAAM,KAAK,qBAAqB,QAAQ,GAAG,CAAC,CAAC,IAAI,UAAU,MAAM;AAAA,IAC/D;AAAA,IACA,0BAA0B,UAAU;AAAA,EACtC,CAAC;AACH;AAEO,SAAS,YAAY,IAA4C;AACtE,QAAM,WAAW,UAAU,IAAI,EAAE;AACjC,SAAO,WAAW,wBAAwB,QAAQ,IAAI;AACxD;AAEO,SAAS,gBAAsC;AACpD,SAAO,MAAM;AAAA,IAAK,UAAU,OAAO;AAAA,IAAG,CAAC,aACrC,wBAAwB,QAAQ;AAAA,EAClC;AACF;AAEO,SAAS,sBAAsB,IAA4C;AAChF,QAAM,aAAa,qBAAqB,IAAI,EAAE;AAC9C,SAAO,aAAa,wBAAwB,UAAU,IAAI;AAC5D;;;ACjhBO,SAAS,wBAAwB,QAAmC;AACzE,UAAQ,OAAO,QAAQ;AAAA,IACrB,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO,MAAM,KAAK,IAAI;AAAA,IAC/B,KAAK;AACH,aAAO,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,MAAM,KAAK,IAAI,IAAI,OAAO;AAAA,IACxE,KAAK;AACH,UAAI,OAAO,SAAS,OAAO,OAAO,UAAU,YAAY,UAAU,OAAO,OAAO;AAC9E,cAAM,YAAa,OAAO,MAA6B;AACvD,YAAI,OAAO,cAAc,UAAU;AACjC,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO,KAAK,UAAU,OAAO,KAAK;AAAA,EACtC;AACF;;;AHjXA,IAAM,oBAAoB,CAAC,QAAQ,SAAS,cAAc,WAAW,YAAY;AAIjF,IAAM,kBAAwCC,IAAE;AAAA,EAAK,MACnDA,IAAE,MAAM;AAAA,IACNA,IAAE,OAAO;AAAA,IACTA,IAAE,OAAO;AAAA,IACTA,IAAE,QAAQ;AAAA,IACVA,IAAE,KAAK;AAAA,IACPA,IAAE,MAAM,eAAe;AAAA,IACvBA,IAAE,OAAO,eAAe;AAAA,EAC1B,CAAC;AACH;AAEA,IAAM,+BAA6DA,IAAE,MAAM;AAAA,EACzEA,IAAE,OAAO;AAAA,IACP,QAAQA,IAAE,QAAQ,UAAU;AAAA,IAC5B,OAAOA,IAAE,OAAO;AAAA,EAClB,CAAC;AAAA,EACDA,IAAE,OAAO;AAAA,IACP,QAAQA,IAAE,QAAQ,MAAM;AAAA,IACxB,OAAOA,IAAE,MAAMA,IAAE,OAAO,CAAC;AAAA,EAC3B,CAAC;AAAA,EACDA,IAAE,OAAO;AAAA,IACP,QAAQA,IAAE,QAAQ,QAAQ;AAAA,IAC1B,OAAOA,IAAE,MAAM,CAACA,IAAE,OAAO,GAAGA,IAAE,MAAMA,IAAE,OAAO,CAAC,CAAC,CAAC;AAAA,EAClD,CAAC;AAAA,EACDA,IAAE,OAAO;AAAA,IACP,QAAQA,IAAE,QAAQ,YAAY;AAAA,IAC9B,OAAO;AAAA,EACT,CAAC;AACH,CAAC;AAGM,IAAM,kBAAkBA,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,KAAK,iBAAiB,EAAE;AAAA,IAChC;AAAA,EAEF;AAAA,EACA,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,sFAAsF;AAAA,EAC1I,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,yIAAoI;AAAA,EACnL,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,EACjG,QAAQA,IAAE,MAAM,CAACA,IAAE,OAAO,GAAG,4BAA4B,CAAC,EAAE,SAAS,EAAE,SAAS,2FAAsF;AAAA,EACtK,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,gHAAgH;AAAA,EACzJ,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,0FAA0F;AAAA,EACnI,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,yFAAyF;AAAA,EAC9I,oBAAoBA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,mGAAmG;AAAA,EACjK,gBAAgBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,8KAA8K;AAAA,EACtO,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oJAAoJ;AAAA;AAAA,EAErM,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,EAC7G,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAC/G,CAAC;AAGD,IAAM,uBAAuBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,EAAE,CAAC;AAKnE,IAAM,yBAAyBA,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,QAAQ,SAAS;AAAA,EAC3B,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACpC,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAC3C,CAAC;AACD,IAAM,wBAAwBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AACtG,IAAM,6BAA6BA,IAAE,OAAO;AAAA,EAC1C,QAAQA,IAAE,QAAQ,YAAY;AAAA,EAC9B,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC9B,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,QAAQA,IAAE,MAAM,CAACA,IAAE,OAAO,GAAG,4BAA4B,CAAC;AAAA,EAC1D,SAASA,IAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,SAASA,IAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1C,oBAAoBA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS;AAAA,EACnD,gBAAgBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC7C,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACpC,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAAG,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACnG,CAAC;AACD,IAAM,4BAA4BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,YAAY,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;AAE5G,IAAM,uBAAuBA,IAAE,mBAAmB,UAAU;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,yBAAmE;AAAA,EAC9E,MAAM,EAAE,QAAQ,CAAC,GAAG,aAAa,yCAAyC;AAAA,EAC1E,WAAW,EAAE,QAAQ,CAAC,SAAS,YAAY,GAAG,aAAa,mCAAmC;AAAA,EAC9F,OAAO,EAAE,QAAQ,CAAC,YAAY,GAAG,aAAa,0BAA0B;AAAA,EACxE,YAAY,EAAE,QAAQ,CAAC,cAAc,WAAW,UAAU,WAAW,WAAW,eAAe,sBAAsB,kBAAkB,SAAS,oBAAoB,kBAAkB,GAAG,aAAa,gDAAgD;AAAA,EACtP,cAAc,EAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,uBAAuB;AAC3E;AAEA,SAAS,mBAAmB,IAAgC;AAC1D,QAAM,YAAY,GAAG,OAClB,IAAI,CAAC,MAAM,KAAK,EAAE,GAAG,KAAK,EAAE,KAAK,KAAK,EAAE,IAAI,MAAM,EAAE,mBAAmB,GAAG,GAAG,EAC7E,KAAK,IAAI;AACZ,QAAM,aAAa,sBAAsB,GAAG,EAAE;AAC9C,QAAM,oBAAoB,aACtB,8BAA8B,UAAU,IACxC,GAAG,qBACD,8BAA8B,GAAG,kBAAkB,QACnD;AAEN,SACE,MAAM,GAAG,IAAI,IAAI,GAAG,IAAI;AAAA,YACX,GAAG,EAAE;AAAA,EACf,GAAG,gBAAgB;AAAA;AAAA,cACP,GAAG,OAAO,MAAM;AAAA,EAAO,SAAS;AAAA;AAAA,cAChC,iBAAiB;AAAA;AAGpC;AAqBO,SAAS,gCACd,UACA,SACe;AACf,QAAM,aAAa,SAAS,OAAO,GAAG,EAAE;AAExC,MAAI,CAAC,YAAY;AACf,WAAO,aAAa,SAAS,EAAE;AAAA,EACjC;AAEA,MAAI,YAAY,WAAW,IAAI;AAC7B,WACE,aAAa,SAAS,EAAE,8DACpB,WAAW,EAAE,MAAM,WAAW,KAAK;AAAA,EAE3C;AAEA,SAAO;AACT;AAQA,SAASC,aAAY,GAAW,GAAmB;AACjD,QAAM,IAAI,EAAE;AACZ,QAAM,IAAI,EAAE;AACZ,QAAM,KAAiB,MAAM;AAAA,IAAK,EAAE,QAAQ,IAAI,EAAE;AAAA,IAAG,CAAC,GAAG,MACvD,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,GAAG,CAACC,IAAG,MAAO,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,CAAE;AAAA,EACzE;AACA,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,SAAG,CAAC,EAAE,CAAC,IACL,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAChB,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,IACf,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,GAAI,GAAG,CAAC,EAAE,IAAI,CAAC,GAAI,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,CAAE;AAAA,IACpE;AAAA,EACF;AACA,SAAO,GAAG,CAAC,EAAE,CAAC;AAChB;AAQA,SAAS,iBACP,OACA,QAC6C;AAC7C,MAAI,OAAO,WAAW,EAAG,QAAO;AAIhC,QAAM,iBAAiB,OAAO;AAAA,IAC5B,CAAC,MAAM,EAAE,GAAG,SAAS,KAAK,KAAK,MAAM,SAAS,EAAE,EAAE;AAAA,EACpD;AACA,MAAI,eAAgB,QAAO;AAI3B,MAAI,OAAO,OAAO,CAAC;AACnB,MAAI,WAAWD,aAAY,OAAO,KAAK,EAAE;AACzC,aAAW,KAAK,OAAO,MAAM,CAAC,GAAG;AAC/B,UAAM,OAAOA,aAAY,OAAO,EAAE,EAAE;AACpC,QAAI,OAAO,UAAU;AACnB,iBAAW;AACX,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,YAAY,KAAK,KAAK,KAAK,IAAI,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,CAAC;AACtE,SAAO,YAAY,YAAY,OAAO;AACxC;AAEO,SAAS,sBAAsB,QAAyB;AAE7D,QAAM,oBAAiF;AAAA,IACrF,MAAM,MAAME,YAAW;AAAA,IACvB,WAAW,CAAC,SAAS;AACnB,UAAI,CAAC,KAAK,SAAS,CAAC,KAAK,YAAY;AACnC,eAAO,QAAQ,QAAQ,iBAAiB,2DAA2D,CAAC;AAAA,MACtG;AACA,aAAO,aAAa,KAAK,OAAO,KAAK,UAAU;AAAA,IACjD;AAAA,IACA,OAAO,CAAC,SAAS,YAAY,KAAK,UAAU;AAAA,IAC5C,YAAY,CAAC,SAAS;AAAA,MACpB,KAAK;AAAA,MAAY,KAAK;AAAA,MAAS,KAAK;AAAA,MAAQ,KAAK;AAAA,MAAS,KAAK;AAAA,MAC/D,KAAK;AAAA,MAAa,KAAK;AAAA,MAAoB,KAAK;AAAA,MAAgB,KAAK;AAAA,MACrE,KAAK;AAAA,MAAkB,KAAK;AAAA,IAC9B;AAAA,IACA,cAAc,OAAO,SAAS;AAC5B,YAAMC,UAAS,MAAM,cAAc,KAAK,OAAO;AAC/C,YAAM,UAAU,UAAUA,QAAO,OAAO,KAAKA,QAAO,KAAK,MAAM;AAC/D,aAAO,EAAE,SAAS,YAAYA,QAAO,IAAI,GAAG,mBAAmB,QAAQ,SAASA,OAAM,EAAE;AAAA,IAC1F;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAUF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,OAAO,eAAe,MAAM;AAAA,IAC1G;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,iBAAiB,IAAI;AAChD,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,aAAa,OAAO;AAAA,QAAG,MACvD,sBAAsB,aAAa,sBAAsB,OAAO,MAAM,wBAAwB,iBAAiB;AAAA,MACjH;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAeD,cAAa;AAC1B,QAAM,YAAY,cAAc;AAEhC,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,EAAE,WAAW,CAAC,GAAG,OAAO,EAAE;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,QAAQ,UAAU,IAAI,kBAAkB,EAAE,KAAK,aAAa;AAElE,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MACE;AAAA;AAAA,EACG,UAAU,MAAM;AAAA;AAAA;AAAA;AAAA,EACT,KAAK;AAAA,IACnB,CAAC;AAAA,IACD,mBAAmB;AAAA,MACjB,SAAS,UAAU,MAAM;AAAA,MACzB;AAAA,QACE,WAAW,UAAU,IAAI,CAAC,OAAO;AAAA,UAC/B,IAAI,EAAE;AAAA,UACN,MAAM,EAAE;AAAA,UACR,QAAQ,EAAE,OAAO;AAAA,UACjB,kBAAkB,EAAE,sBAAsB;AAAA,QAC5C,EAAE;AAAA,QACF,OAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;AAGA,eAAsB,YAAY,YAAoB;AACpD,uBAAqB;AACrB,QAAM,iBAAiB,kBAAkB;AACzC,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,YAAY,UAAU;AACjC,MAAI,CAAC,IAAI;AACP,UAAM,YAAY,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,IAAI;AAC5D,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE,aAAa,UAAU,2BAA2B,SAAS;AAAA;AAAA;AAAA,MAE/D,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB;AAAA,QACA,aAAa,UAAU;AAAA,QACvB,cAAc,SAAS;AAAA,QACvB,CAAC,EAAE,MAAM,aAAa,aAAa,kBAAkB,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,GAAG,OAAO,CAAC;AAC9B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,MACL,aAAa,UAAU;AAAA,IACzB;AAAA,EACF;AAGA,MAAI,MAAmC;AACvC,MAAI;AACF,UAAM,MAAM,YAAwE,kCAAkC;AAAA,MACpH;AAAA,MACA,YAAY,GAAG;AAAA,IACjB,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AAEA,QAAM,WAAW,KAAK,WAAW,YAAY,IAAI,kBAAkB;AACnE,QAAM,QAAQ,WACV,GAAG,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,IAAK,cAAc,KAAK,aACvD;AAEJ,QAAM,YACJ,GAAG,OAAO,0BACN,6HACA,GAAG,OAAO,UACR,iGACA;AAER,QAAM,WACJ,6FAA6F,GAAG,EAAE,mBAAmB,MAAM,EAAE,gEAC5H,KAAK,QAAQ,kBAAkB,IAAI,KAAK,6CAA6C;AAExF,QAAM,QAAQ;AAAA,IACZ,WAAW,aAAa,GAAG,IAAI,OAAO,GAAG,EAAE,QAAQ,YAAY,GAAG,IAAI,OAAO,GAAG,EAAE;AAAA,IAClF;AAAA,IACA,WAAW,MAAM,GAAG,WAAM,MAAM,KAAK,SAAS,MAAM,EAAE;AAAA,IACtD;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,YAAY,CAAC,IAAI,SAAS,IAAI,CAAC;AAAA,EACrC;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,WACI,mBAAmB,GAAG,EAAE,aAAa,MAAM,GAAG,KAAK,MAAM,KAAK,OAC9D,kBAAkB,GAAG,EAAE,iBAAY,MAAM,GAAG,KAAK,MAAM,KAAK;AAAA,MAChE;AAAA,QACE,YAAY,GAAG;AAAA,QACf,cAAc,GAAG;AAAA,QACjB,OAAO,KAAK,SAAS;AAAA,QACrB,OAAO;AAAA,UACL,IAAI,MAAM;AAAA,UACV,KAAK,MAAM;AAAA,UACX,OAAO,MAAM;AAAA,UACb,aAAa,MAAM;AAAA,UACnB,qBAAqB,MAAM;AAAA,UAC3B,cAAc,MAAM,aAAa;AAAA,QACnC;AAAA,QACA,UAAU;AAAA,UACR,QAAQ;AAAA,UACR,YAAY,GAAG;AAAA,UACf,SAAS,MAAM;AAAA,UACf,GAAI,KAAK,QAAQ,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,QAC3C;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,aAAa,oBAAoB,MAAM,GAAG;AAAA,UAC1C,YAAY;AAAA,YACV,QAAQ;AAAA,YACR,YAAY,GAAG;AAAA,YACf,SAAS,MAAM;AAAA,YACf,GAAI,KAAK,QAAQ,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,UAC3C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AA6BA,eAAsB,aACpB,OACA,YACA;AACA,MAAI;AACJ,MAAI,OAAO;AACT,UAAM,MAAM,YAAkE,4BAA4B;AAAA,MACxG;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AACL,yBAAqB;AAErB,UAAM,iBAAiB,kBAAkB;AACzC,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,YAAwE,kCAAkC;AAAA,MACpH;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,KAAK;AACR,UAAM,SAAS,QACX,iBAAiB,KAAK,MACtB,aAAa,UAAU;AAC3B,WAAO,iBAAiB,8BAA8B,MAAM,GAAG;AAAA,EACjE;AAEA,MAAI,cAAc,IAAI,eAAe,YAAY;AAC/C,WAAO;AAAA,MACL,iBAAiB,IAAI,KAAK,0BAA0B,IAAI,UAAU,WAAW,UAAU;AAAA,IACzF;AAAA,EACF;AAEA,QAAM,YAAY,IAAI,WAAW,MAAM,IAAI,CAAC,SAAS;AACnD,UAAME,UAAS,KAAK,OAAO,YAAY;AACvC,UAAM,gBAAgB,KAAK,SACvB,WAAM,wBAAwB,KAAK,MAAM,CAAC,KAC1C;AACJ,WAAO,KAAK,KAAK,GAAG,KAAK,KAAK,KAAK,KAAKA,OAAM,IAAI,aAAa;AAAA,EACjE,CAAC;AAED,QAAM,QAAQ;AAAA,IACZ,mBAAmB,IAAI,YAAY;AAAA,IACnC;AAAA,IACA,eAAe,IAAI,KAAK;AAAA,IACxB,oBAAoB,IAAI,UAAU;AAAA,IAClC,aAAa,IAAI,MAAM;AAAA,IACvB,eAAe,IAAI,WAAW,cAAc,IAAI,IAAI,WAAW,UAAU;AAAA,IACzE,oBAAoB,IAAI,iBAAiB,KAAK,IAAI,cAAc,OAAO,UAAU;AAAA,IACjF,0BAA0B,OAAO,KAAK,IAAI,WAAW,OAAO,KAAK,EAAE,MAAM,IAAI,IAAI,WAAW,OAAO,SAAS,MAAM;AAAA,IAClH,cAAc,IAAI,SAAS;AAAA,IAC3B,GAAI,IAAI,cAAc,CAAC,gBAAgB,IAAI,WAAW,EAAE,IAAI,CAAC;AAAA,IAC7D,GAAI,IAAI,UACJ,CAAC,sBAAsB,IAAI,QAAQ,OAAO,IAAI,IAC9C,CAAC;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,uBAAuB,IAAI,KAAK,KAAK,IAAI,YAAY;AAAA,MACrD;AAAA,MACA,IAAI,UACA;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY,EAAE,QAAQ,WAAW,SAAS,IAAI,QAAQ,QAAQ;AAAA,QAChE;AAAA,MACF,IACA;AAAA,IACN;AAAA,EACF;AACF;AAEA,eAAsB,iBACpB,YAAoB,SAAiB,QACrC,SAAmB,SAAmB,aAAsB,oBAC5D,gBAAyB,OAAuB,kBAA2B,kBAC3E;AACA,QAAM,KAAK,YAAY,UAAU;AACjC,MAAI,CAAC,IAAI;AACP,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE,aAAa,UAAU,2BACT,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,MAE7D,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB;AAAA,QACA,aAAa,UAAU;AAAA,QACvB;AAAA,QACA,CAAC,EAAE,MAAM,aAAa,aAAa,kBAAkB,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,GAAG,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AACpD,MAAI,CAAC,OAAO;AACV,UAAM,kBAAkB,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,IAAI;AAC5D,UAAM,UAAU,iBAAiB,SAAS,GAAG,MAAM;AAEnD,UAAM,oBAAkC,UACpC;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,aAAa,kCAAkC,QAAQ,EAAE;AAAA,QACzD,YAAY,EAAE,QAAQ,cAAc,YAAY,SAAS,QAAQ,GAAG;AAAA,MACtE;AAAA,IACF,IACA;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,aAAa;AAAA,QACb,YAAY,EAAE,QAAQ,OAAO;AAAA,MAC/B;AAAA,IACF;AAEJ,UAAM,iBAAiB,UAAU,kBAAkB,QAAQ,EAAE,OAAO;AAEpE,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE,UAAU,OAAO,4BAA4B,UAAU,KAAK,cAAc,sBACrD,eAAe;AAAA;AAAA;AAAA,MAExC,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB;AAAA,QACA,UAAU,OAAO,4BAA4B,UAAU;AAAA,QACvD,UACI,iBAAiB,QAAQ,EAAE,wBAAwB,eAAe,KAClE,qBAAqB,eAAe;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB;AAAA,IACtB,wBAAwB,MAAM,GAAG,WAAM,MAAM,KAAK;AAAA,IAClD,aAAa,GAAG,IAAI,OAAO,GAAG,EAAE;AAAA,IAChC;AAAA,EACF;AAEA,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,uBAAmB,wBAAwB,OAAO,MAAM;AAAA,EAC1D,SAAS,OAAgB;AACvB,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO,iBAAiB,OAAO;AAAA,EACjC;AAEA,QAAM,gBAAgB,wBAAwB,gBAAgB;AAE9D,MAAI,SAAS;AACX,UAAM,iCAAiC;AAAA,MACrC;AAAA,MACA;AAAA,IACF;AACA,QAAI,gCAAgC;AAClC,aAAO,iBAAiB,8BAA8B;AAAA,IACxD;AAEA,UAAM,aAAa,sBAAsB,UAAU;AACnD,UAAM,WAAW,aACb,4BAA4B,UAAU,IACtC,EAAE,MAAM,GAAG,IAAI,MAAM,GAAG,KAAK;AACjC,UAAM,iBAAiB,aACnB,oCAAoC,UAAU,IAC9C,GAAG,sBAAsB,GAAG,mBAC1B;AAAA,MACE,SAAS;AAAA,QACP,MAAM;AAAA,QACN,YAAY,GAAG;AAAA,MACjB;AAAA,MACA,cAAc,GAAG,iBAAiB;AAAA,MAClC,kBAAkB,GAAG,iBAAiB;AAAA,MACtC,mBAAmB;AAAA,IACrB,IACA;AAEN,QAAI,CAAC,kBAAkB,CAAC,gBAAgB;AACtC,aAAO;AAAA,QACL,aAAa,UAAU;AAAA,MACzB;AAAA,IACF;AAEA,uBAAmB;AACnB,UAAM,iBAAiB,kBAAkB;AACzC,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,QAAI,kBAAkB,CAAC,gBAAgB;AACrC,aAAO;AAAA,QACL;AAAA,QAAI;AAAA,QAAY;AAAA,QAAS;AAAA,QAAkB;AAAA,QAAgB;AAAA,QAAgB;AAAA,QAAO;AAAA,MACpF;AAAA,IACF;AAKA,UAAM,yBAAyB;AAG/B,UAAM,cAAc,MAAM;AAAA,MACxB;AAAA,MACA;AAAA,QACE;AAAA,QACA,YAAY,GAAG;AAAA,MACjB;AAAA,IACF;AACA,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,QACL,aAAa,UAAU;AAAA,MACzB;AAAA,IACF;AAEA,QAAI;AAGF,UAAI;AACJ,UAAI,uBAAuB,QAAQ,SAAS,cAAc;AACxD,cAAM,eAAe,eAAe,GAAG;AACvC,cAAM,eAAe,sBAAsB;AAC3C,cAAM,WAAW,MAAM,kBAAkB,EAAE,MAAM,cAAc,aAAa,aAAa,CAAC;AAC1F,YAAI,YAAY,SAAS,SAAS,OAAO;AACvC,mCAAyB,SAAS;AAAA,QACpC;AAAA,MACF;AAEA,YAAMD,UAAS,MAAM,eASlB,iCAAiC;AAAA,QAClC;AAAA,QACA,YAAY,GAAG;AAAA,QACf,cAAc,GAAG;AAAA,QACjB,cAAc,SAAS;AAAA,QACvB,cAAc,SAAS;AAAA,QACvB,OAAO,GAAG,OAAO,IAAI,CAAC,mBAAmB;AAAA,UACvC,SAAS,cAAc;AAAA,UACvB,KAAK,cAAc;AAAA,UACnB,OAAO,cAAc;AAAA,UACrB,MAAM,cAAc;AAAA,UACpB,aAAa,cAAc,aAAa;AAAA,UACxC,cAAc,cAAc,aAAa;AAAA,QAC3C,EAAE;AAAA,QACF,cAAc;AAAA,QACd,aAAa;AAAA,QACb,gBAAgB;AAAA,UACd,SACE,uBAAuB,QAAQ,SAAS,UACpC;AAAA,YACE,MAAM;AAAA,YACN,YAAY,uBAAuB,QAAQ;AAAA,UAC7C,IACA;AAAA,YACE,MAAM;AAAA,UACR;AAAA,UACN,cAAc,uBAAuB;AAAA,UACrC,kBAAkB,uBAAuB;AAAA,UACzC,mBAAmB,uBAAuB;AAAA,QAC5C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAEA,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,QAC/C,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,MACjD,CAAC;AAED,YAAM;AAAA,QACJA,QAAO,QAAQ,UACX,wBAAwBA,QAAO,QAAQ,OAAO,OAC9C,+BAA+BA,QAAO,QAAQ,OAAO;AAAA,QACzD,iBAAiBA,QAAO,QAAQ,eAAe,uBAAuB,QAAQ,SAAS,UAAU,uBAAuB,QAAQ,aAAa,oBAAoB;AAAA,QACjK,SAASA,QAAO,QAAQ,IAAI;AAAA,QAC5B;AAAA,QACA,4EAA4EA,QAAO,QAAQ,OAAO;AAAA,QAClG,2CAA2CA,QAAO,QAAQ,OAAO;AAAA,MACnE;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,QAC3D,mBAAmB;AAAA,UACjB,UAAUA,QAAO,QAAQ,IAAI,KAAKA,QAAO,QAAQ,UAAU,YAAY,QAAQ,KAAKA,QAAO,QAAQ,OAAO,kBAAkB,UAAU;AAAA,UACtI;AAAA,YACE,SAASA,QAAO,QAAQ;AAAA,YACxB;AAAA,YACA;AAAA,YACA,YACEA,QAAO,QAAQ,eACd,uBAAuB,QAAQ,SAAS,UACrC,uBAAuB,QAAQ,aAC/B;AAAA,YACN,SAAS;AAAA,YACT,OAAOA,QAAO;AAAA,YACd,SAASA,QAAO,QAAQ;AAAA,UAC1B;AAAA,UACA;AAAA,YACE;AAAA,cACE,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY,EAAE,QAAQ,UAAU,SAASA,QAAO,QAAQ,QAAQ;AAAA,YAClE;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,aAAa;AAAA,cACb,YAAY,EAAE,QAAQ,WAAW,SAASA,QAAO,QAAQ,QAAQ;AAAA,YACnE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAc;AACrB,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAM;AAAA,QACJ,4BAA4B,GAAG;AAAA,QAC/B;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBAAmB,uBAAuB,QAAQ,SAAS,UAAU,uBAAuB,QAAQ,aAAa,mBAAmB;AAAA,QACpI,WAAW,eAAe,uBAAuB,YAAY;AAAA,QAC7D,kBAAkB,sBAAsB,aAAa;AAAA,MACvD;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,QAC3D,mBAAmB;AAAA,UACjB;AAAA,UACA,wBAAwB,GAAG;AAAA,UAC3B;AAAA,UACA,CAAC,EAAE,MAAM,WAAW,aAAa,oBAAoB,YAAY,CAAC,EAAE,CAAC;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,uBAAmB;AACnB,UAAM,iBAAiB,kBAAkB;AACzC,QAAI,CAAC,gBAAgB;AACnB,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,aAAa,sBAAsB,UAAU;AACnD,YAAM,WAAW,aACb,4BAA4B,UAAU,IACtC,EAAE,MAAM,GAAG,IAAI,MAAM,GAAG,KAAK;AACjC,YAAM,mBAAmB,MAAM,eAA+E,sCAAsC;AAAA,QAClJ;AAAA,QACA,YAAY,GAAG;AAAA,QACf,cAAc,GAAG;AAAA,QACjB,cAAc,SAAS;AAAA,QACvB,cAAc,SAAS;AAAA,QACvB,OAAO,GAAG,OAAO,IAAI,CAAC,mBAAmB;AAAA,UACvC,SAAS,cAAc;AAAA,UACvB,KAAK,cAAc;AAAA,UACnB,OAAO,cAAc;AAAA,UACrB,MAAM,cAAc;AAAA,UACpB,aAAa,cAAc,aAAa;AAAA,UACxC,cAAc,cAAc,aAAa;AAAA,QAC3C,EAAE;AAAA,QACF,YAAY;AAAA,UACV;AAAA,UACA,QAAQ;AAAA,UACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrC;AAAA,QACA;AAAA,QACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,QACzB,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;AAAA,MAC7C,CAAC;AAED,YAAM;AAAA,QACJ,SAAS,MAAM,GAAG;AAAA,QAClB,WAAW,cAAc,UAAU,GAAG,GAAG,CAAC,GAAG,cAAc,SAAS,MAAM,QAAQ,EAAE;AAAA,QACpF,aAAa,iBAAiB,WAAW,cAAc,IAAI,iBAAiB,WAAW,UAAU;AAAA,MACnG;AAEA,YAAM,oBAAoB,iBAAiB,WAAW,iBAClD,GAAG,OAAO,KAAK,CAAC,kBAAkB,cAAc,OAAO,iBAAiB,WAAW,cAAc,IACjG;AACJ,YAAM,YAAY,oBACd,EAAE,IAAI,kBAAkB,IAAI,KAAK,kBAAkB,KAAK,OAAO,kBAAkB,MAAM,IACvF;AAEJ,UAAI,iBAAiB,SAAS,QAAQ;AACpC,cAAM;AAAA,UACJ;AAAA,UACA,yDAAyD,iBAAiB,QAAQ,OAAO;AAAA,QAC3F;AAAA,MACF,WAAW,mBAAmB;AAC5B,cAAM;AAAA,UACJ;AAAA,UACA,mBAAmB,kBAAkB,GAAG,WAAM,kBAAkB,KAAK;AAAA,UACrE,IAAI,kBAAkB,WAAW;AAAA,QACnC;AAAA,MACF,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,QAC3D,mBAAmB;AAAA,UACjB,SAAS,MAAM,GAAG,KAAK,MAAM,KAAK,kCAAkC,UAAU;AAAA,UAC9E;AAAA,YACE;AAAA,YACA;AAAA,YACA,UAAU,MAAM;AAAA,YAChB,YAAY,MAAM;AAAA,YAClB,SAAS;AAAA,YACT;AAAA,YACA,OAAO,iBAAiB;AAAA,YACxB,WAAW,iBAAiB,IAAI;AAAA,YAChC,UAAU;AAAA,cACR,gBAAgB,iBAAiB,WAAW;AAAA,cAC5C,YAAY,iBAAiB,WAAW;AAAA,YAC1C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAc;AACrB,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAM;AAAA,QACJ,sCAAsC,GAAG;AAAA,QACzC;AAAA,QACA;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,QAC3D,mBAAmB;AAAA,UACjB;AAAA,UACA,2CAA2C,GAAG;AAAA,UAC9C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,8BACb,IACA,YACA,SACA,kBACA,gBACA,gBACA,OACA,OACA;AACA,QAAM,WAAW,aACb,4BAA4B,UAAU,IACtC,EAAE,MAAM,GAAG,IAAI,MAAM,GAAG,KAAK;AAEjC,MAAI;AACF,UAAM,mBAAmB,MAAM,eAA+E,sCAAsC;AAAA,MAClJ;AAAA,MACA,YAAY,GAAG;AAAA,MACf,cAAc,GAAG;AAAA,MACjB,cAAc,SAAS;AAAA,MACvB,cAAc,SAAS;AAAA,MACvB,OAAO,GAAG,OAAO,IAAI,CAAC,mBAAmB;AAAA,QACvC,SAAS,cAAc;AAAA,QACvB,KAAK,cAAc;AAAA,QACnB,OAAO,cAAc;AAAA,QACrB,MAAM,cAAc;AAAA,QACpB,aAAa,cAAc,aAAa;AAAA,QACxC,cAAc,cAAc,aAAa;AAAA,MAC3C,EAAE;AAAA,MACF,YAAY;AAAA,QACV;AAAA,QACA,QAAQ;AAAA,QACR,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC;AAAA,MACA;AAAA,MACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IAC3B,CAAC;AAED,UAAM,SAAS,iBAAiB,SAAS,UAAU;AACnD,UAAM;AAAA,MACJ,iDAAiD,cAAc;AAAA,MAC/D,WAAW,iBAAiB,IAAI,MAAM;AAAA,MACtC,aAAa,iBAAiB,WAAW,cAAc,IAAI,iBAAiB,WAAW,UAAU;AAAA,IACnG;AAEA,QAAI,CAAC,UAAU,iBAAiB,IAAI,WAAW,aAAa;AAC1D,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC3D,mBAAmB;AAAA,QACjB,YAAY,GAAG,EAAE,gCAAgC,cAAc;AAAA,QAC/D;AAAA,UACE,SAAS;AAAA,UACT,YAAY,GAAG;AAAA,UACf;AAAA,UACA,SAAS;AAAA,UACT,OAAO,iBAAiB;AAAA,UACxB;AAAA,UACA,WAAW,iBAAiB,IAAI;AAAA,QAClC;AAAA,QACA;AAAA,UACE;AAAA,YACE,MAAM;AAAA,YACN,aAAa;AAAA,YACb,YAAY,EAAE,QAAQ,WAAW,SAAS,eAAe;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAM;AAAA,MACJ,4BAA4B,GAAG;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC3D,mBAAmB;AAAA,QACjB;AAAA,QACA,oCAAoC,GAAG;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,wBACd,OACA,QACmB;AACnB,MAAI,OAAO,WAAW,UAAU;AAC9B,wCAAoC,OAAO,MAAM;AACjD,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,KAAK;AAE5B,UAAQ,MAAM,aAAa,QAAQ;AAAA,IACjC,KAAK;AACH,aAAO,EAAE,QAAQ,YAAY,OAAO,QAAQ;AAAA,IAC9C,KAAK;AACH,aAAO,EAAE,QAAQ,QAAQ,OAAO,gBAAgB,OAAO,EAAE;AAAA,IAC3D,KAAK;AACH,aAAO,EAAE,QAAQ,UAAU,OAAO,QAAQ;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,QAAQ,cAAc,OAAO,EAAE,MAAM,QAAQ,EAAE;AAAA,EAC5D;AACF;AAEA,SAAS,oCACP,OACA,QACM;AACN,MAAI,OAAO,WAAW,MAAM,aAAa,QAAQ;AAC/C,UAAM,IAAI;AAAA,MACR,UAAU,MAAM,EAAE,cAAc,MAAM,aAAa,MAAM,uBAAuB,OAAO,MAAM;AAAA,IAC/F;AAAA,EACF;AACF;AAEO,SAAS,gBAAgB,QAA0B;AACxD,QAAM,QAAQ,OACX,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,OAAO,EACd,IAAI,CAAC,SAAS,KAAK,QAAQ,YAAY,EAAE,EAAE,QAAQ,aAAa,EAAE,EAAE,KAAK,CAAC,EAC1E,OAAO,OAAO;AAEjB,SAAO,MAAM,SAAS,IAAI,QAAQ,CAAC,MAAM;AAC3C;;;AIrkCA,SAAS,KAAAE,WAAS;;;ACGlB,SAAS,KAAAC,WAAS;AAalB,IAAM,eAAe,IAAI,KAAK;AAC9B,IAAM,iBAAiB;AAKvB,IAAM,aAAa,oBAAI,IAA6B;AACpD,SAAS,eAAe,KAAqD;AAC3E,QAAM,QAAQ,WAAW,IAAI,GAAG;AAChC,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,KAAK,IAAI,KAAK,MAAM,WAAW;AACjC,eAAW,OAAO,GAAG;AACrB,WAAO;AAAA,EACT;AACA,SAAO,MAAM;AACf;AACA,SAAS,eAAe,KAAa,KAA0C;AAC7E,aAAW,IAAI,KAAK,EAAE,KAAK,WAAW,KAAK,IAAI,IAAI,aAAa,CAAC;AACjE,mBAAiB;AACnB;AACA,SAAS,mBAAyB;AAChC,MAAI,WAAW,QAAQ,eAAgB;AAEvC,QAAM,MAAM,KAAK,IAAI;AACrB,aAAW,CAAC,GAAG,CAAC,KAAK,YAAY;AAC/B,QAAI,OAAO,EAAE,UAAW,YAAW,OAAO,CAAC;AAAA,EAC7C;AAEA,MAAI,WAAW,OAAO,gBAAgB;AACpC,UAAM,SAAS,CAAC,GAAG,WAAW,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS;AACvF,UAAM,SAAS,WAAW,OAAO;AACjC,aAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,YAAW,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,EACjE;AACF;AAIA,IAAM,gBAAgB,CAAC,KAAK;AAErB,IAAM,cAAcC,IAAE,OAAO;AAAA,EAClC,QAAQA,IAAE,KAAK,aAAa,EAAE;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,SAASA,IAAE,OAAO,EAAE,SAAS,qDAAqD;AAAA,EAClF,OAAOA,IAAE,KAAK,CAAC,WAAW,SAAS,CAAC,EAAE,QAAQ,SAAS,EAAE,SAAS,EAC/D;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AA0CD,eAAsB,eAAe,SAAiB,OAA8B;AAClF,MAAIC;AAEJ,MAAI;AACF,IAAAA,UAAS,MAAM,YAAwD,kBAAkB,EAAE,SAAS,MAAM,CAAC;AAAA,EAC7G,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAI,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,WAAW,GAAG;AAC1D,aAAO;AAAA,QACL,UAAU,OAAO;AAAA,QACjB;AAAA,QACA,UAAU,OAAO;AAAA,QACjB;AAAA,QACA,CAAC,EAAE,MAAM,WAAW,aAAa,kBAAkB,YAAY,EAAE,QAAQ,UAAU,OAAO,QAAQ,EAAE,CAAC;AAAA,MACvG;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAUA,MAAI;AACJ,QAAM,WAAW,iBAAiB,KAAK;AACvC,QAAM,SAAS,eAAe,QAAQ;AACtC,MAAI,WAAW,QAAQ;AACrB,eAAW;AAAA,EACb,OAAO;AACL,QAAI;AAEF,YAAM,QAAQ,MAAM,YAA6D,uBAAuB,CAAC,CAAC;AAC1G,UAAI,OAAO,oBAAoB,OAAO,oBAAoB;AACxD,mBAAW;AAAA,UACT,GAAI,MAAM,mBAAmB,EAAE,kBAAkB,MAAM,iBAA0D,IAAI,CAAC;AAAA,UACtH,GAAI,MAAM,qBAAqB,EAAE,oBAAoB,MAAM,mBAA8D,IAAI,CAAC;AAAA,QAChI;AAAA,MACF;AACA,qBAAe,UAAU,QAAQ;AAAA,IACnC,QAAQ;AAAA,IAAoE;AAAA,EAC9E;AAKA,aAAW,QAAQA,QAAO,OAAO;AAC/B,QAAI,KAAK,QAAQ,OAAQ,MAAK,SAAS,mBAAmB,KAAK,QAAQ,QAAQ;AAC/E,QAAI,KAAK,QAAQ,OAAO,KAAK,IAAK,MAAK,MAAM,mBAAmB,KAAK,KAAK,QAAQ;AAClF,QAAI,KAAK,QAAQ,QAAQ,KAAK,KAAM,MAAK,OAAO,mBAAmB,KAAK,MAAM,QAAQ;AAAA,EACxF;AAEA,QAAM,EAAE,SAAS,OAAO,SAAS,WAAW,WAAW,IAAIA;AAG3D,QAAM,cAAc,YAAY,SAAS,WAAM,YAAY,SAAS,WAAM;AAC1E,QAAM,eAAe,QAAQ,YAAY;AAEzC,QAAM,QAAkB;AAAA,IACtB,aAAa,OAAO,WAAM,SAAS;AAAA,IACnC,UAAU,KAAK,eAAe,WAAW,IAAI,YAAY,MAAM,UAAU;AAAA,IACzE,UAAU,QAAQ,MAAM,IAAI,QAAQ,KAAK,gBAAa,QAAQ,MAAM,gBAAa,QAAQ,MAAM;AAAA,IAC/F;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AACtD,QAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AACtD,QAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AAEtD,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,oCAA+B;AAC1C,eAAW,QAAQ,QAAQ;AACzB,YAAM,KAAK,KAAK,KAAK,IAAI,OAAO,KAAK,MAAM,EAAE;AAC7C,UAAI,KAAK,IAAK,OAAM,KAAK,iBAAY,KAAK,GAAG,EAAE;AAC/C,UAAI,KAAK,KAAM,OAAM,KAAK,kBAAa,KAAK,IAAI,EAAE;AAAA,IACpD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,oCAA+B;AAC1C,eAAW,QAAQ,QAAQ;AACzB,YAAM,KAAK,KAAK,KAAK,IAAI,OAAO,KAAK,MAAM,EAAE;AAC7C,UAAI,KAAK,IAAK,OAAM,KAAK,iBAAY,KAAK,GAAG,EAAE;AAC/C,UAAI,KAAK,KAAM,OAAM,KAAK,kBAAa,KAAK,IAAI,EAAE;AAAA,IACpD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,SAAS,KAAK,YAAY,QAAQ;AAC3C,UAAM,KAAK,6BAAwB;AACnC,eAAW,QAAQ,QAAQ;AACzB,YAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,EAAE;AAAA,IAC7C;AAAA,EACF,WAAW,OAAO,SAAS,GAAG;AAC5B,UAAM,KAAK,sBAAiB,OAAO,MAAM,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACvF;AAGA,QAAM,cAAc,CAAC;AACrB,MAAI,YAAY,QAAQ;AACtB,gBAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY,EAAE,QAAQ,OAAO,QAAQ;AAAA,IACvC,CAAC;AACD,gBAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY,EAAE,QAAQ,QAAQ,QAAQ;AAAA,IACxC,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,SAAS,OAAO,KAAK,KAAK,MAAM,YAAY,WAAM,QAAQ,MAAM,IAAI,QAAQ,KAAK;AAAA,MACjF;AAAA,QACE,SAASA,QAAO;AAAA,QAChB,WAAWA,QAAO;AAAA,QAClB,OAAOA,QAAO;AAAA,QACd,OAAOA,QAAO;AAAA,QACd,SAASA,QAAO;AAAA,QAChB,OAAOA,QAAO;AAAA,QACd,SAASA,QAAO;AAAA,QAChB,YAAYA,QAAO;AAAA,MACrB;AAAA,MACA,YAAY,SAAS,IAAI,cAAc;AAAA,IACzC;AAAA,EACF;AACF;;;ACvNA,eAAsB,iBAAiB,OAAgB,UAAU,OAAO;AACtE,QAAM,iBAAiB,MAAM;AAAA,IAC3B;AAAA,IACA,EAAE,cAAc,OAAO,QAAQ;AAAA,EACjC;AACA,QAAM,MAAM,MAAM,YAAuE,iCAAiC,CAAC,CAAC;AAM5H,QAAM,eAAe,eAAe;AAEpC,MAAI,CAAC,KAAK;AACR,UAAM,OAAO,eACT,mKACA;AACJ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MACzC,mBAAmB,QAAQ,MAAM,EAAE,YAAY,OAAO,cAAc,aAAa,CAAC;AAAA,IACpF;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,IAAI;AACpB,MAAI,QAAQ,gBAAgB;AAC1B,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gDAA2C,CAAC;AAAA,MACrF,mBAAmB,QAAQ,yBAAyB,EAAE,YAAY,MAAM,gBAAgB,KAAK,CAAC;AAAA,IAChG;AAAA,EACF;AAEA,QAAM,QAAkB,CAAC,gBAAgB;AACzC,MAAI,cAAc;AAChB,UAAM,KAAK,0HAAqH,IAAI,KAAK,IAAI,SAAS,EAAE,YAAY,CAAC,oDAAoD,EAAE;AAAA,EAC7N,WAAW,eAAe,WAAW,qBAAqB;AACxD,UAAM,KAAK,8GAAyG,IAAI,KAAK,IAAI,SAAS,EAAE,YAAY,CAAC,+BAA+B,EAAE;AAAA,EAC5L,WAAW,IAAI,OAAO;AACpB,UAAM,KAAK,kBAAa,IAAI,eAAe,MAAM,uFAAuF,EAAE;AAAA,EAC5I;AAEA,QAAM,IAAI,QAAQ;AAClB,QAAM,KAAK,4BAA4B,EAAE,SAAS,SAAS,MAAM,EAAE;AACnE,MAAI,EAAE,QAAQ,SAAS,EAAG,OAAM,KAAK,YAAY,EAAE,QAAQ,KAAK,IAAI,CAAC,EAAE;AACvE,MAAI,EAAE,oBAAoB,QAAS,OAAM,KAAK,uDAAuD,EAAE,oBAAoB,QAAQ,KAAK,IAAI,CAAC,EAAE;AAC/I,MAAI,EAAE,oBAAoB,OAAQ,OAAM,KAAK,sDAAsD,EAAE,oBAAoB,OAAO,KAAK,IAAI,CAAC,EAAE;AAC5I,MAAI,EAAE,uBAAuB,SAAS,EAAG,OAAM,KAAK,2DAA2D,EAAE,uBAAuB,KAAK,IAAI,CAAC,EAAE;AAKpJ,OAAK,EAAE,qCAAqC,CAAC,GAAG,SAAS,GAAG;AAC1D,UAAM,KAAK,oFAA+E,EAAE,kCAAkC,KAAK,IAAI,CAAC,EAAE;AAAA,EAC5I;AACA,MAAI,EAAE,6BAA6B,MAAO,OAAM,KAAK,gCAAgC;AACrF,MAAI,EAAE,mCAAoC,OAAM,KAAK,oEAA+D;AACpH,MAAI,QAAQ,oBAAqB,OAAM,KAAK,wEAAmE;AAC/G,MAAI,QAAQ,+BAAgC,OAAM,KAAK,kHAA6G;AAEpK,MAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,UAAM,KAAK,IAAI,mCAAmC,QAAQ,YAAY,MAAM,IAAI;AAChF,eAAW,KAAK,QAAQ,aAAa;AACnC,YAAM,UAAU,EAAE,QAAQ,mBAAmB,8CAA8C;AAK3F,YAAM,KAAK,EAAE,cACT,wBAAwB,EAAE,YAAY,oBAAoB,6BAA6B,gCAAgC,KACvH;AACJ,YAAM,KAAK,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,EAAE,EAAE;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,QAAQ,OAAO;AACjB,UAAM,KAAK,IAAI,gDAAgD,QAAQ,MAAM,SAAS,SAAS,MAAM,EAAE;AACvG,QAAI,CAAC,QAAQ,MAAM,UAAU,QAAQ,MAAM,gBAAiB,OAAM,KAAK,qBAAqB,QAAQ,MAAM,eAAe,EAAE;AAAA,EAC7H,WAAW,IAAI,mBAAmB;AAUhC,UAAM,KAAK,IAAI,qLAAgL;AAAA,EACjM,OAAO;AACL,UAAM,KAAK,IAAI,yEAAoE;AAAA,EACrF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,2BAA2B,EAAE,SAAS,SAAS,MAAM,GAAG,QAAQ,QAAQ,WAAW,QAAQ,MAAM,SAAS,SAAS,MAAM,mBAAmB,EAAE,GAAG,eAAe,gEAA2D,EAAE;AAAA,MAC7N;AAAA,QACE,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,kBAAkB,EAAE;AAAA,QACpB,aAAa,QAAQ,OAAO,UAAU;AAAA,QACtC,OAAO,IAAI;AAAA,QACX;AAAA,QACA,WAAW,eAAe;AAAA,QAC1B,gBAAgB,eAAe;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACF;;;AFtHA,IAAM,kBAAkB,CAAC,SAAS,eAAe,gBAAgB,SAAS,aAAa;AAIhF,IAAM,gBAAgBC,IAAE,OAAO;AAAA,EACpC,QAAQA,IAAE,KAAK,eAAe,EAAE;AAAA,IAC9B;AAAA,EAIF;AAAA,EACA,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mFAAmF;AAAA,EACpI,SAASA,IAAE,KAAK,CAAC,WAAW,UAAU,QAAQ,CAAC,EAAE,QAAQ,QAAQ,EAAE,SAAS,EACzE,SAAS,qCAAqC;AAAA,EACjD,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,EACxH,MAAMA,IAAE,KAAK,CAAC,UAAU,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,oHAAoH;AAAA,EACxK,OAAOA,IAAE,KAAK,CAAC,WAAW,SAAS,CAAC,EAAE,SAAS,EAAE;AAAA,IAC/C;AAAA,EACF;AAAA,EACA,OAAOA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oHAAoH;AAAA,EAC3J,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE;AAAA,IAC9B;AAAA,EAGF;AACF,CAAC;AAGD,IAAM,sBAAsBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AACjG,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EACxC,QAAQA,IAAE,QAAQ,aAAa;AAAA,EAC/B,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,SAASA,IAAE,KAAK,CAAC,WAAW,UAAU,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,QAAQ;AAC9E,CAAC;AACD,IAAM,4BAA4BA,IAAE,OAAO;AAAA,EACzC,QAAQA,IAAE,QAAQ,cAAc;AAAA,EAChC,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,QAAQ,UAAU;AAAA,EAC7D,MAAMA,IAAE,KAAK,CAAC,UAAU,KAAK,CAAC,EAAE,SAAS,EAAE,QAAQ,QAAQ;AAC7D,CAAC;AACD,IAAM,sBAAsBA,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,QAAQ,OAAO;AAAA,EACzB,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC3B,OAAOA,IAAE,KAAK,CAAC,WAAW,SAAS,CAAC,EAAE,SAAS,EAAE,QAAQ,SAAS;AACpE,CAAC;AACD,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EACxC,QAAQA,IAAE,QAAQ,aAAa;AAAA,EAC/B,OAAOA,IAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAAA,EAC3C,SAASA,IAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAC/C,CAAC;AAEM,IAAM,qBAAqBA,IAAE,mBAAmB,UAAU;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,uBAA+D;AAAA,EAC1E,OAAO,EAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,uBAAuB;AAAA,EAClE,eAAe,EAAE,QAAQ,CAAC,WAAW,SAAS,GAAG,aAAa,uBAAuB;AAAA,EACrF,gBAAgB,EAAE,QAAQ,CAAC,cAAc,MAAM,GAAG,aAAa,0DAA0D;AAAA,EACzH,OAAO,EAAE,QAAQ,CAAC,WAAW,OAAO,GAAG,aAAa,uBAAuB;AAAA,EAC3E,eAAe,EAAE,QAAQ,CAAC,SAAS,SAAS,GAAG,aAAa,sLAAiL;AAC/O;AAIO,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EAC/C,SAASA,IAAE,OAAO;AAAA;AAAA,EAElB,YAAYA,IAAE,QAAQ,EAAE,SAAS;AAAA,EACjC,YAAYA,IAAE,QAAQ;AAAA;AAAA,EAEtB,OAAOA,IAAE,QAAQ,EAAE,SAAS;AAAA,EAC5B,MAAMA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,QAAQA,IAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,UAAUA,IAAE,MAAMA,IAAE,OAAO;AAAA,IACzB,IAAIA,IAAE,OAAO;AAAA,IACb,QAAQA,IAAE,QAAQ;AAAA,IAClB,MAAMA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,CAAC,CAAC;AACJ,CAAC;AAEM,IAAM,gCAAgCA,IAAE,OAAO;AAAA,EACpD,SAASA,IAAE,OAAO;AAAA,EAClB,SAASA,IAAE,OAAO;AAAA,EAClB,OAAOA,IAAE,OAAO;AAAA,EAChB,UAAUA,IAAE,OAAO;AAAA,EACnB,UAAUA,IAAE,QAAQ;AACtB,CAAC;AAEM,IAAM,gCAAgCA,IAAE,OAAO;AAAA,EACpD,YAAYA,IAAE,QAAQ;AAAA,EACtB,gBAAgBA,IAAE,QAAQ,EAAE,SAAS;AAAA,EACrC,kBAAkBA,IAAE,QAAQ,EAAE,SAAS;AAAA,EACvC,aAAaA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS;AAAA,EAC7C,OAAOA,IAAE,QAAQ,EAAE,SAAS;AAC9B,CAAC;AAEM,SAAS,qBAAqB,QAAyB;AAE5D,QAAM,kBAA6E;AAAA,IACjF,OAAO,CAAC,SAAS,YAAY,KAAK,OAAO;AAAA,IACzC,eAAe,CAAC,SAAS,iBAAiB,KAAK,SAAS,KAAK,WAAW,QAAQ;AAAA,IAChF,gBAAgB,CAAC,SAAS,kBAAkB,QAAQ,EAAE,YAAY,KAAK,cAAc,YAAY,MAAM,KAAK,QAAQ,SAAS,CAAC;AAAA,IAC9H,OAAO,CAAC,SAAS,eAAe,KAAK,SAAS,KAAK,SAAS,SAAS;AAAA,IACrE,eAAe,CAAC,SAAS,iBAAiB,KAAK,SAAS,OAAO,KAAK,WAAW,KAAK;AAAA,EACtF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAcF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,MAAM,eAAe,MAAM;AAAA,IACzG;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,eAAe,IAAI;AAC9C,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,WAAW,OAAO;AAAA,QAAG,MACrD,sBAAsB,WAAW,oBAAoB,OAAO,MAAM,sBAAsB,eAAe;AAAA,MACzG;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAUA,eAAe,sBAAsB,SAAiB,OAAgC;AACpF,MAAI,gBAAgB;AACpB,MAAI;AACF,UAAM,YAAY,MAAM,YAAkE,4BAA4B,EAAE,QAAQ,CAAC;AACjI,oBAAgB,WAAW,UAAU;AAAA,EACvC,QAAQ;AAEN;AAAA,EACF;AACA,MAAI,kBAAkB,EAAG;AAEzB,MAAI;AACF,UAAM,cAAc,MAAM,YAAiE,2BAA2B;AAAA,MACpH;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,IACT,CAAC;AAED,SAAK,aAAa,aAAa,UAAU,KAAK,GAAG;AAC/C,YAAM,aAAa,YAAY,eAAe,CAAC,GAC5C,IAAI,CAAC,MAAM,4CAAuC,OAAO,SAAS,EAAE,OAAO,WAAW,EAAE,uBAAuB,cAAS,EAAE,IAAI,KAAK,EAAE,cAAc,MAAM,EAAE,KAAK,OAAO,EACvK,KAAK,IAAI;AAEZ,YAAM,KAAK;AAAA;AAAA,EAA4C,SAAS,EAAE;AAAA,IACpE;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAEA,eAAe,YAAY,SAAiB;AAK1C,QAAM,MAAM,MAAM,YAA0E,oCAAoC,EAAE,QAAQ,CAAC;AAI3I,MAAI,CAAC,OAAO,CAAC,IAAI,YAAY;AAC3B,WAAO;AAAA,MACL,oBAAoB,OAAO;AAAA;AAAA,UAAe,OAAO;AAAA,MACjD,SAAS,OAAO;AAAA,MAChB,EAAE,SAAS,YAAY,OAAO,YAAY,OAAO,UAAU,CAAC,EAA2D;AAAA,MACvH,CAAC,EAAE,MAAM,UAAU,aAAa,kBAAkB,YAAY,EAAE,OAAO,QAAQ,EAAE,CAAC;AAAA,IACpF;AAAA,EACF;AAEA,QAAM,UAAU,IAAI;AAKpB,MAAI,CAAC,SAAS;AACZ,UAAMC,SAAkB;AAAA,MACtB,oBAAoB,OAAO;AAAA,MAC3B;AAAA,MACA,gCAAgC,OAAO,iDAAiD,OAAO;AAAA,IACjG;AACA,UAAM,sBAAsB,SAASA,MAAK;AAC1C,WAAO;AAAA,MACLA,OAAM,KAAK,IAAI;AAAA,MACf,8BAA8B,OAAO;AAAA,MACrC,EAAE,SAAS,YAAY,MAAM,YAAY,OAAO,UAAU,CAAC,EAA2D;AAAA,MACtH,CAAC,EAAE,MAAM,WAAW,aAAa,gBAAgB,YAAY,EAAE,QAAQ,eAAe,QAAQ,EAAE,CAAC;AAAA,IACnG;AAAA,EACF;AAMA,QAAM,WAAkE,QAAQ,YAAY,CAAC;AAC7F,QAAM,QAAkB,CAAC,oBAAoB,OAAO,IAAI,EAAE;AAG1D,MAAI,IAAI,OAAO;AACb,UAAM;AAAA,MACJ,0EAAqE,OAAO,8EAC/B,OAAO;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AACA,QAAM,iBAAiB,2BAA2B,OAAO;AACzD,QAAM,KAAK,kBAAkB,kBAAkB,QAAQ,QAAQ,SAAS,YAAY,OAAO,yCAAoC;AAE/H,QAAM,sBAAsB,SAAS,KAAK;AAE1C,MAAI;AACF,UAAM,gBAAgB,MAAM,oBAAoB;AAChD,sBAAkB,cAAc,aAAa;AAAA,MAC3C,UAAU;AAAA,MACV,YAAY,QAAQ,gBAAgB;AAAA,MACpC,MAAM,QAAQ,QAAQ;AAAA,MACtB,QAAQ,QAAQ,UAAU;AAAA,MAC1B,QAAQ,QAAQ,UAAU;AAAA,MAC1B,YAAY,QAAQ;AAAA,MACpB,iBAAiB,QAAQ;AAAA,MACzB,WAAW,QAAQ;AAAA,MACnB,kBAAkB,CAAC,CAAC,QAAQ;AAAA,IAC9B,CAAC;AAAA,EACH,QAAQ;AAAA,EAA6B;AAErC,QAAM,cAAc,SAAS,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AACrD,SAAO;AAAA,IACL,MAAM,KAAK,IAAI;AAAA,IACf,qBAAqB,OAAO,KAAK,QAAQ,QAAQ,SAAS,UAAU,WAAW,IAAI,SAAS,MAAM,qBAC/F,IAAI,QAAQ,0FAAqF;AAAA,IACpG;AAAA,MACE;AAAA,MACA,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,OAAO,IAAI,SAAS;AAAA,MACpB,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,MAChB,UAAU,SAAS,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,QAAQ,MAAM,EAAE,KAAK,EAAE;AAAA,IAC9E;AAAA,IACA;AAAA,MACE,EAAE,MAAM,aAAa,aAAa,uBAAuB,YAAY,EAAE,QAAQ,WAAW,QAAQ,EAAE;AAAA,IACtG;AAAA,EACF;AACF;AAEA,eAAe,iBAAiB,SAAiB,SAA0C;AACzF,qBAAmB;AACnB,QAAM,KAAK,MAAM,oBAAoB;AACrC,QAAMC,UAAS,MAAM,eAAoE,2BAA2B;AAAA,IAClH;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,CAACA,SAAQ;AACX,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB;AAAA,MACA,UAAU,OAAO;AAAA,MACjB;AAAA,MACA,CAAC,EAAE,MAAM,WAAW,aAAa,kBAAkB,YAAY,EAAE,QAAQ,UAAU,OAAO,QAAQ,EAAE,CAAC;AAAA,IACvG;AAAA,EACF;AAEA,QAAM,eAAeA,QAAO,QAAQ,SAAS;AAC7C,QAAM,QAAkB,CAAC,kBAAkB,OAAO,WAAW,OAAO,aAAa;AACjF,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,2BAA2B;AAAA,IACpC,GAAGA,QAAO;AAAA,IACV,QAAQA,QAAO;AAAA,IACf,WAAW,eAAe,YAAY;AAAA,EACxC,CAAC,CAAC;AAEF,MAAI;AACF,wBAAoB,GAAG,aAAa;AAAA,MAClC,UAAU;AAAA,MACV,YAAYA,QAAO,QAAQ,gBAAgB;AAAA,MAC3C,MAAMA,QAAO,QAAQ,QAAQ;AAAA,MAC7B;AAAA,MACA,QAAQA,QAAO,QAAQ,UAAU;AAAA,MACjC,QAAQ;AAAA,MACR,gBAAgBA,QAAO,QAAQ,UAAU,UAAU;AAAA,MACnD,iBAAiBA,QAAO,QAAQ,UAAU,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU;AAAA,MAC7E,eAAe;AAAA,MACf,qBAAqBA,QAAO,QAAQ;AAAA,IACtC,CAAC;AAAA,EACH,QAAQ;AAAA,EAA6B;AAErC,QAAM,WAAWA,QAAO,QAAQ,YAAY,CAAC;AAC7C,QAAM,cAAc,SAAS,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AACrD,QAAM,iBAAiB,SAAS;AAEhC,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,gBAAgB,OAAO,OAAO,OAAO,oBAAoB,WAAW,IAAI,cAAc;AAAA,MACtF;AAAA,QACE;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAUA,QAAO,QAAQ,UAAU;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AACF;;;AG5VA,SAAS,KAAAC,WAAS;;;ACG2D,SAAS,KAAAC,WAAS;;;ACyC/F,SAAS,WAAW,GAAoE;AACtF,SAAO,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,MAAM,OAAO,EAAE,MAAM;AAC5D;AAEO,SAAS,kBAAkB,KAAwC;AACxE,QAAM,YAAY;AAAA,IAChB,IAAI,IAAI,aAAa,CAAC,GAAG,IAAI,UAAU;AAAA,IACvC,IAAI,IAAI,qBAAqB,CAAC,GAAG,IAAI,UAAU;AAAA,EACjD;AACA,QAAM,SAAS;AAAA,IACb,IAAI,IAAI,UAAU,CAAC,GAAG,IAAI,UAAU;AAAA,IACpC,IAAI,IAAI,kBAAkB,CAAC,GAAG,IAAI,UAAU;AAAA,EAC9C;AACA,QAAM,oBAAoB,IAAI,qBAAqB;AACnD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,OAAO,WAAW,KAAK,sBAAsB;AAAA,EACzD;AACF;;;ADyFA,eAAe,mBACb,OACA,QACA,cAAc,GACsB;AACpC,QAAM,UAAqC,IAAI,MAAM,MAAM,MAAM;AACjE,MAAI,QAAQ;AAEZ,iBAAe,UAAyB;AACtC,WAAO,QAAQ,MAAM,QAAQ;AAC3B,YAAM,IAAI;AACV,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,MAAM,CAAC,CAAC;AACnC,gBAAQ,CAAC,IAAI,EAAE,QAAQ,aAAa,MAAM;AAAA,MAC5C,SAAS,QAAQ;AACf,gBAAQ,CAAC,IAAI,EAAE,QAAQ,YAAY,OAAO;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC;AAAA,EAC7E;AACA,SAAO;AACT;AAcA,SAAS,cAAc,GAAuE;AAC5F,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,MAAM;AACZ,SACE,OAAO,IAAI,aAAa,YACxB,OAAO,IAAI,SAAS,YACpB,OAAO,IAAI,aAAa,aACvB,IAAI,aAAa,WAAW,IAAI,aAAa,aAAa,IAAI,aAAa;AAEhF;AAEA,eAAe,8BACb,WACmC;AACnC,MAAI;AACF,UAAM,UAAU,MAAM,WAAyD,oBAAoB;AAAA,MACjG;AAAA,IACF,CAAC;AACD,UAAM,MAAM,SAAS;AACrB,QACE,OACA,OAAO,IAAI,cAAc,YACzB,OAAO,IAAI,cAAc,YACzB,MAAM,QAAQ,IAAI,OAAO,KACzB,IAAI,QAAQ,MAAM,aAAa,GAC/B;AACA,aAAO;AAAA,IACT;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,QAAQ,IAAI,iBAAiB;AAC/B,cAAQ,MAAM,sCAAsC,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,IAC9F;AAAA,EACF;AACA,SAAO;AACT;AAIA,eAAe,uBAAuB,SAAmD;AACvF,QAAM,cAAgC,CAAC;AAEvC,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA,OAAO,UAAU;AACf,YAAMC,UAAS,MAAM,YAAiE,2BAA2B;AAAA,QAC/G,SAAS,MAAM;AAAA,QACf,OAAO;AAAA,MACT,CAAC;AACD,aAAO,EAAE,OAAO,aAAaA,QAAO,eAAe,CAAC,EAAE;AAAA,IACxD;AAAA,IACA;AAAA,EACF;AAEA,aAAWA,WAAU,SAAS;AAC5B,QAAIA,QAAO,WAAW,YAAa;AACnC,UAAM,EAAE,OAAO,aAAa,iBAAiB,IAAIA,QAAO;AAIxD,eAAW,KAAK,iBAAiB,OAAO,CAAC,MAA2C,EAAE,WAAW,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG;AAClH,kBAAY,KAAK;AAAA,QACf,aAAa,MAAM;AAAA,QACnB,WAAW,EAAE;AAAA,QACb,MAAM,EAAE;AAAA,QACR,OAAO,GAAG,MAAM,OAAO,WAAM,EAAE,OAAO,KAAK,EAAE,IAAI,MAAM,EAAE,uBAAuB;AAAA;AAAA,QAEhF,YAAY,EAAE;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAIA,eAAe,kBAA+C;AAC5D,QAAM,YAAY,kBAAkB;AACpC,MAAI,CAAC,WAAW;AACd,WAAO,EAAE,MAAM,+DAA+D,MAAM,MAAM,aAAa,CAAC,GAAG,aAAa,mBAAmB;AAAA,EAC7I;AAEA,MAAI,eAAe,MAAM,QAAQ;AAC/B,WAAO,EAAE,MAAM,+CAA0C,MAAM,MAAM,aAAa,CAAC,GAAG,aAAa,iBAAiB;AAAA,EACtH;AAEA,QAAM,EAAE,YAAY,IAAI,MAAM,oBAAoB;AAElD,QAAM,iBAAiB,MAAM,mBAAuC,iCAAiC;AAAA,IACnG;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,OAAO,eAAe;AAO5B,QAAM,sBAAsB,KAAK,kBAAkB,CAAC,GAAG;AACvD,QAAM,oBAAoB,KAAK,qBAAqB;AACpD,QAAM,YAAY,KAAK,OAAO,WAAW,KAAK,uBAAuB,KAAK,sBAAsB;AAChG,MAAI,KAAK,qBAAqB,WAAW;AACvC,WAAO,EAAE,MAAM,0CAA0C,MAAM,aAAa,CAAC,GAAG,aAAa,oBAAoB;AAAA,EACnH;AAEA,MACE,KAAK,OAAO,WAAW,KACvB,KAAK,UAAU,WAAW,KAC1B,uBAAuB,MACtB,KAAK,qBAAqB,CAAC,GAAG,WAAW,GAC1C;AACA,WAAO,EAAE,MAAM,8CAAyC,MAAM,aAAa,CAAC,GAAG,aAAa,YAAY;AAAA,EAC1G;AAEA,QAAM,QAAkB,CAAC;AAEzB,QAAM;AAAA,IACJ,yBAAyB,KAAK,QAAQ,OAAO,aAAa,KAAK,QAAQ,QAAQ,cAC5E,KAAK,QAAQ,WAAW;AAAA,EAC7B;AAIA,MAAI,oBAAoB,GAAG;AACzB,UAAM,KAAK,WAAW,iBAAiB,aAAa,sBAAsB,IAAI,MAAM,KAAK,6DAA6D;AAAA,EACxJ;AACA,QAAM,KAAK,EAAE;AAEb,MAAI,KAAK,OAAO,SAAS,GAAG;AAC1B,UAAM,KAAK,0BAA0B,EAAE;AACvC,UAAM,KAAK,2DAA2D;AACtE,UAAM,KAAK,2DAA2D;AAEtE,eAAW,SAAS,KAAK,QAAQ;AAC/B,YAAM,UAAU,KAAK,gBAAgB,MAAM,OAAO;AAClD,YAAM,QAAQ,KAAK,iBAAiB,MAAM,OAAO,KAAK;AACtD,YAAM,aAAa,UACf,GAAG,QAAQ,SAAS,SAAS,YAAY,KAAK,QAAQ,MAAM,MAC5D;AAGJ,YAAM,UAAU,SAAS;AACzB,YAAM,WAAW,UAAU,QAAQ,OAAO;AAE1C,YAAM,KAAK,OAAO,MAAM,OAAO,MAAM,MAAM,IAAI,MAAM,MAAM,UAAU,MAAM,UAAU,MAAM,KAAK,MAAM,QAAQ,IAAI;AAAA,IACpH;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,KAAK,UAAU,SAAS,GAAG;AAC7B,UAAM,KAAK,0BAA0B,KAAK,UAAU,MAAM,KAAK,EAAE;AACjE,eAAW,SAAS,KAAK,WAAW;AAClC,YAAM,QAAQ,KAAK,iBAAiB,MAAM,OAAO,KAAK;AACtD,YAAM,KAAK,OAAO,MAAM,OAAO,OAAO,MAAM,UAAU,KAAK,MAAM,IAAI,KAAK,KAAK,eAAe;AAAA,IAChG;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAKA,QAAM,iBAAiB,KAAK,kBAAkB,CAAC;AAC/C,QAAM,oBAAoB,KAAK,qBAAqB,CAAC;AACrD,MAAI,eAAe,SAAS,KAAK,kBAAkB,SAAS,GAAG;AAC7D,UAAM,KAAK,0BAA0B,eAAe,SAAS,kBAAkB,MAAM,KAAK,EAAE;AAC5F,UAAM,KAAK,4EAAuE,EAAE;AACpF,eAAW,KAAK,mBAAmB;AACjC,YAAM,KAAK,OAAO,EAAE,OAAO,aAAQ,EAAE,IAAI,cAAc;AAAA,IACzD;AACA,eAAW,KAAK,gBAAgB;AAC9B,YAAM,KAAK,OAAO,EAAE,OAAO,aAAQ,EAAE,IAAI,UAAU;AAAA,IACrD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,QAAM,iBAAiB,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,SAAS,EAAE;AAAA,IACzD,CAAC,OAAO,KAAK,iBAAiB,EAAE,OAAO,KAAK,KAAK;AAAA,EACnD;AAEA,QAAM,cAAc,eAAe,SAAS,IACxC,MAAM,uBAAuB,eAAe,MAAM,GAAG,EAAE,CAAC,IACxD,CAAC;AAEL,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,KAAK,uBAAuB,EAAE;AACpC,eAAW,KAAK,aAAa;AAC3B,YAAM,KAAK,KAAK,EAAE,KAAK,EAAE;AAAA,IAC3B;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,UAAU,WAAW,CAAC;AAC5B,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,8BAA8B,EAAE;AAC3C,UAAM,KAAK,mCAAmC,QAAQ,MAAM,SAAS,QAAQ,WAAW,IAAI,KAAK,GAAG,0BAA0B,EAAE;AAChI,eAAW,OAAO,SAAS;AACzB,YAAM,OAAO,IAAI,QAAQ,IAAI,MAAM,IAAI,KAAK,QAAQ;AACpD,YAAM,KAAK,OAAO,IAAI,KAAK,6BAAwB,IAAI,EAAE;AAAA,IAC3D;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,6DAA6D;AACxE,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,UAAM,cAAc,mBAAmB;AACvC,QAAI,aAAa;AACf,YAAM,eAAe,wBAAwB,WAAW;AACxD,YAAM,kBAAkB,MAAM,8BAA8B,SAAS;AACrE,YAAM,cAAc,aAAa,OAAO,KAAK,oBAAoB;AAEjE,UAAI,aAAa;AACf,cAAM,UAAU,MAAM,kBAAkB,WAAW;AAEnD,YAAI,QAAQ,WAAW,WAAW;AAMhC,gBAAM,KAAK,qBAAqB;AAChC,gBAAM,KAAK,4GAAuG,QAAQ,MAAM,IAAI;AACpI,gBAAM,KAAK,EAAE;AAAA,QACf,WAAW,QAAQ,WAAW,MAAM;AAClC,gBAAM,EAAE,QAAQ,UAAU,cAAc,IAAI;AAE5C,cAAI,iBAAiB;AACnB,kBAAM,QAAQ,aAAa,iBAAiB,aAAa;AACzD,+BAAmB,MAAM;AACzB,kBAAM,aAAa,qBAAqB,KAAK;AAC7C,kBAAM,KAAK,GAAG,UAAU;AAExB,gBAAI,aAAa,OAAO,GAAG;AACzB,oBAAM;AAAA,gBACJ,yBAAyB,aAAa,IAAI,iBAAiB,aAAa,SAAS,IAAI,KAAK,GAAG,KAC1F,CAAC,GAAG,YAAY,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,GAC/D,aAAa,OAAO,IAAI,QAAQ,aAAa,OAAO,CAAC,UAAU,EAAE;AAAA,cACtE;AACA,oBAAM,KAAK,EAAE;AAAA,YACf;AAGA,6BAAiB,mBAAmB,OAAO,OAAO,UAAU;AAC5D,gBAAI,eAAe,SAAS,GAAG;AAC7B,oBAAM,KAAK,GAAG,0BAA0B,cAAc,CAAC;AAAA,YACzD;AAAA,UACF,WAAW,aAAa,OAAO,GAAG;AAChC,kBAAM,KAAK,qBAAqB;AAChC,kBAAM;AAAA,cACJ,wBAAwB,aAAa,IAAI,iBAAiB,aAAa,SAAS,IAAI,KAAK,GAAG;AAAA,YAE9F;AACA,kBAAM,EAAE,QAAQ,IAAI;AACpB,gBAAI,QAAQ,UAAU,GAAG;AACvB,oBAAM,KAAK,wCAAmC;AAAA,YAChD,OAAO;AACL,oBAAM,KAAK,KAAK,QAAQ,KAAK,OAAO,QAAQ,UAAU,IAAI,KAAK,GAAG,OAAO,QAAQ,MAAM,SAAS,QAAQ,WAAW,IAAI,KAAK,GAAG,KAAK,QAAQ,QAAQ,WAAW,QAAQ,aAAa,IAAI,KAAK,GAAG,KAAK,QAAQ,KAAK,QAAQ;AAAA,YAC5N;AACA,kBAAM,KAAK,EAAE;AAAA,UACf;AAAA,QACF;AAAA,MAGF;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,QAAQ,IAAI,iBAAiB;AAC/B,cAAQ,MAAM,8CAA8C,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,IACtG;AAAA,EACF;AAIA,QAAM,kBAAkB,CAAC,GAAG,KAAK,QAAQ,GAAG,cAAc;AAC1D,MAAI,gBAAgB,SAAS,GAAG;AAC9B,UAAM,WAAW,gBAAgB,IAAI,CAAC,MAAM,KAAK,EAAE,OAAO,IAAI,EAAE,KAAK,IAAI;AACzE,UAAM,KAAK,eAAe,EAAE;AAC5B,UAAM,KAAK,gBAAgB,QAAQ,EAAE;AACrC,UAAM,KAAK,uDAAyD;AACpE,UAAM,KAAK,kGAA+F;AAAA,EAC5G;AACA,MAAI,oBAAoB,GAAG;AACzB,UAAM,KAAK,EAAE;AACb,UAAM;AAAA,MACJ,MAAM,iBAAiB;AAAA,IAEzB;AAAA,EACF;AAGA,MAAI,KAAK,cAAc;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mBAAmB;AAC9B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,IAAI,KAAK,aAAa,OAAO,GAAG;AAC3C,QAAI,KAAK,aAAa,YAAY,SAAS,GAAG;AAC5C,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,iCAAiC;AAC5C,iBAAW,KAAK,KAAK,aAAa,aAAa;AAC7C,cAAM,KAAK,OAAO,EAAE,cAAc,OAAO,EAAE,IAAI,EAAE;AAAA,MACnD;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,GAAI,KAAK,0BAA0B,MAAM,SAAS,CAAC,IAAI,2BAA2B,IAAI,IAAI,KAAK,yBAAyB,MAAM,KAAK,GAAG,KAAK,yBAAyB,MAAM,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAE;AAEpN,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,OAAO,KAAK,UAAU,IAAI;AAGrC,MAAI,KAAK,cAAc;AACrB,UAAM,QAAQ,MAAM,oBAAoB;AACxC,QAAI,OAAO;AACT,iCAA2B,MAAM,aAAa;AAAA,QAC5C,kBAAkB,KAAK,aAAa,YAAY;AAAA,MAClD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,WAAW,eAAe,EAAE;AAClC,SAAO;AAAA,IACL,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,eAAe;AAAA,IAC9B,YAAY,eAAe;AAAA,IAC3B,YAAY,eAAe;AAAA,EAC7B;AACF;AAIA,eAAe,mBACb,MACA,mBAC8J;AAC9J,qBAAmB;AAEnB,QAAM,YAAY,kBAAkB;AACpC,MAAI,CAAC,WAAW;AACd,WAAO,EAAE,MAAM,sBAAsB,WAAW,GAAG,kBAAkB,GAAG,cAAc,GAAG,aAAa,GAAG,QAAQ,GAAG,mBAAmB,EAAE;AAAA,EAC3I;AAEA,QAAM,QAAQ,MAAM,oBAAoB;AAExC,QAAM,UAAkF,CAAC;AACzF,MAAI,eAAe;AACnB,MAAI,cAAc;AAElB,MAAI,eAAe;AACnB,QAAM,qBAA+B,CAAC;AACtC,MAAI,mBAAmB;AAMvB,QAAM,YAAY,CAAC,GAAG,KAAK,QAAQ,GAAI,KAAK,kBAAkB,CAAC,CAAE;AACjE,QAAM,oBAAoB,KAAK,qBAAqB;AAEpD,aAAW,SAAS,WAAW;AAC7B,QAAI;AACF,YAAMA,UAAS,MAAM,eAA8D,qBAAqB;AAAA,QACtG,SAAS,MAAM;AAAA,QACf,QAAQ,SAAS,SAAS;AAAA,QAC1B;AAAA,MACF,CAAC;AAMD,UAAIA,WAAU,YAAYA,WAAUA,QAAO,WAAW,qBAAqB;AACzE,cAAM,UAAU,aAAaA,UAASA,QAAO,UAAU;AACvD,gBAAQ,KAAK;AAAA,UACX,SAAS,MAAM;AAAA,UACf,IAAI;AAAA,UACJ,OAAO,6CAAyC,SAA6C,UAAU,+BAA+B;AAAA,QACxI,CAAC;AACD;AAAA,MACF;AACA,YAAM,WAAW,CAAC,EAAEA,WAAU,YAAYA,WAAUA,QAAO,WAAW;AACtE,UAAI,CAAC,UAAU;AACb,cAAM,sBAAsB,EAAE,eAAe,MAAM,MAAM,CAAC;AAC1D,iCAAyB,MAAM,aAAa;AAAA,UAC1C,UAAU,MAAM;AAAA,UAChB,eAAe;AAAA,UACf,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AACA,UAAI,UAAU;AACZ;AAAA,MACF;AACA,cAAQ,KAAK,EAAE,SAAS,MAAM,SAAS,IAAI,MAAM,SAAS,CAAC;AAAA,IAC7D,SAAS,KAAc;AACrB,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,cAAQ,KAAK,EAAE,SAAS,MAAM,SAAS,IAAI,OAAO,OAAO,IAAI,CAAC;AAAA,IAChE;AAAA,EACF;AAGA,QAAM,qBAAqB,kBAAkB,SAAS,IAClD,oBACA,MAAM;AAAA,IACJ,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,SAAS,EAAE;AAAA,MAClC,CAAC,OAAO,KAAK,iBAAiB,EAAE,OAAO,KAAK,KAAK;AAAA,IACnD,EAAE,MAAM,GAAG,EAAE;AAAA,EACf;AACJ,QAAM,oBAAoB,oBAAI,IAAI;AAAA,IAChC,GAAG,KAAK,UAAU,IAAI,CAAC,UAAU,MAAM,OAAO;AAAA,IAC9C,GAAG,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,EACpE,CAAC;AAED,QAAM,UAAU,mBACb,OAAO,CAAC,MAAM,kBAAkB,IAAI,EAAE,WAAW,CAAC,EAClD,MAAM,GAAG,EAAE;AACd,QAAM,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS;AAC9D,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS;AAE5D,MAAI,UAAU,SAAS,GAAG;AACxB,QAAI;AACF,YAAM,cAAc,MAAM,eAAuE,8BAA8B;AAAA;AAAA;AAAA,QAG7H,WAAW,UAAU,IAAI,CAAC,OAAO;AAAA,UAC/B,aAAa,EAAE;AAAA,UACf,WAAW,EAAE;AAAA,UACb,MAAM,EAAE;AAAA,UACR,YAAY;AAAA,UACZ,GAAI,EAAE,eAAe,SAAY,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,QACnE,EAAE;AAAA,QACF;AAAA,MACF,CAAC;AACD,sBAAgB,aAAa,WAAW;AAGxC,sBAAgB,aAAa,WAAW;AAGxC,UAAI,eAAe,YAAY,SAAS,GAAG;AACzC,uBAAe,YAAY;AAC3B,cAAM,gBAAgB,YAAY,QAC/B,IAAI,CAAC,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,EAAE,EAClC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,SAAS;AAChD,mBAAW,MAAM,eAAe;AAC9B,gBAAM,MAAM,UAAU,GAAG,KAAK;AAC9B,cAAI,KAAK;AACP,+BAAmB;AAAA,cACjB,GAAG,IAAI,WAAW,WAAM,IAAI,SAAS,KAAK,IAAI,IAAI,MAAM,GAAG,SAAS,eAAe;AAAA,YACrF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AAEZ,qBAAe,UAAU;AACzB,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,yBAAmB,KAAK,0BAA0B,UAAU,MAAM,gBAAgB,GAAG,EAAE;AAAA,IACzF;AAAA,EACF;AAEA,aAAW,KAAK,aAAa;AAC3B,QAAI;AACF,YAAMA,UAAS,MAAM,eAAsE,6BAA6B;AAAA,QACtH,aAAa,EAAE;AAAA,QACf,WAAW,EAAE;AAAA,QACb,MAAM,EAAE;AAAA;AAAA,QAER,YAAY;AAAA,QACZ,GAAI,EAAE,eAAe,SAAY,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC;AAAA,QACjE;AAAA,MACF,CAAC;AAKD,UAAIA,SAAQ,WAAW,oBAAoB;AAAA,MAG3C,WAAWA,SAAQ,SAAS;AAC1B;AAAA,MACF,OAAO;AACL;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ;AACA,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,yBAAmB,KAAK,GAAG,EAAE,WAAW,WAAM,EAAE,SAAS,KAAK,EAAE,IAAI,MAAM,GAAG,EAAE;AAAA,IACjF;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE;AAC7D,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE;AAO1C,QAAM,aAAa,OAAO,WAAW,KAAK,sBAAsB;AAChE,MAAI,YAAY;AACd,UAAM,WAA2D,sBAAsB;AAAA,MACrF;AAAA,MACA,gBAAgB,UAAU;AAAA,MAC1B,iBAAiB;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,KAAK,SAAS,yBAAyB,gBAAgB,2BAA2B,YAAY;AAAA,EAChG;AAEA,MAAI,cAAc,GAAG;AACnB,UAAM,KAAK,KAAK,WAAW,UAAU,gBAAgB,IAAI,KAAK,GAAG,oBAAoB;AAAA,EACvF;AAIA,MAAI,eAAe,GAAG;AACpB,UAAM,KAAK,KAAK,YAAY,8GAAyG;AAAA,EACvI;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,sBAAsB;AACjC,eAAW,KAAK,QAAQ;AACtB,YAAM,KAAK,OAAO,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE;AAAA,IAC7C;AACA,UAAM,KAAK,4CAA4C;AAAA,EACzD;AAEA,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,4BAA4B;AACvC,eAAW,UAAU,oBAAoB;AACvC,YAAM,KAAK,KAAK,MAAM,EAAE;AAAA,IAC1B;AACA,UAAM,KAAK,8EAA8E;AAAA,EAC3F;AAEA,SAAO;AAAA,IACL,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,OAAO;AAAA,IACf;AAAA,EACF;AACF;AAIO,IAAM,eAAeC,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,KAAK,CAAC,UAAU,YAAY,CAAC,EAAE,SAAS,EAAE;AAAA,IAClD;AAAA,EACF;AACF,CAAC;AAYM,SAAS,sBAAsB;AACpC,MAAI,iBAAoC;AACxC,MAAI,wBAA0C,CAAC;AAC/C,MAAI,sBAAqC;AAEzC,SAAO,OAAO,EAAE,OAAO,MAA4C;AACjE,QAAI,WAAW,cAAc;AACzB,YAAM,YAAY,kBAAkB;AACpC,UAAI,CAAC,WAAW;AACd,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,CAAC,EAAE,MAAM,WAAW,aAAa,mBAAmB,YAAY,EAAE,QAAQ,QAAQ,EAAE,CAAC;AAAA,QACvF;AAAA,MACF;AAEA,YAAM,kBAAkB,wBAAwB;AAChD,UAAIC;AACJ,UAAI,mBAAmB,gBAAgB;AACrC,QAAAA,QAAO;AAAA,MACT,OAAO;AACL,cAAM,EAAE,YAAY,IAAI,MAAM,oBAAoB;AAElD,QAAAA,SAAQ,MAAM,mBAAuC,iCAAiC;AAAA,UACpF;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,QACV,CAAC,GAAG;AAAA,MACN;AAIA,UAAIA,MAAK,OAAO,WAAW,MAAMA,MAAK,kBAAkB,CAAC,GAAG,WAAW,GAAG;AACxE,eAAO,cAAc,oCAAoC,aAAa,oCAAoC,oBAAoB;AAAA,MAChI;AAEA,YAAMF,UAAS,MAAM,mBAAmBE,OAAM,kBAAkB,wBAAwB,CAAC,CAAC;AAC1F,uBAAiB;AACjB,8BAAwB,CAAC;AACzB,4BAAsB;AACtB,YAAM,iBAAiBF,QAAO,cAAc,IAAI,KAAKA,QAAO,WAAW,oBAAoB;AAK3F,YAAM,aACJA,QAAO,oBAAoB,IACvB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,aACE,GAAGA,QAAO,iBAAiB;AAAA,UAE7B,YAAY,EAAE,QAAQ,QAAQ;AAAA,QAChC;AAAA,MACF,IACAA,QAAO,SAAS,IACd,CAAC,EAAE,MAAM,WAAW,aAAa,6CAA6C,YAAY,EAAE,QAAQ,gBAAgB,EAAE,CAAC,IACvH,CAAC,EAAE,MAAM,WAAW,aAAa,mDAAmD,YAAY,EAAE,QAAQ,QAAQ,EAAE,CAAC;AAC7H,aAAO;AAAA,QACLA,QAAO;AAAA,QACP,qBAAqBA,QAAO,SAAS,cAAcA,QAAO,gBAAgB,eAAeA,QAAO,YAAY,SAAS,cAAc;AAAA,QACnI;AAAA,UACE,WAAWA,QAAO;AAAA,UAClB,kBAAkBA,QAAO;AAAA,UACzB,cAAcA,QAAO;AAAA,UACrB,aAAaA,QAAO;AAAA,UACpB,QAAQA,QAAO;AAAA,QACjB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,EAAE,MAAM,MAAM,aAAa,aAAa,UAAU,kBAAkB,gBAAgB,eAAe,YAAY,WAAW,IAAI,MAAM,gBAAgB;AAC1J,qBAAiB;AACjB,4BAAwB;AACxB,0BAAsB,kBAAkB;AAKxC,UAAM,WAAW,OAAO,kBAAkB,IAAI,IAAI;AAClD,UAAM,WAAW,aAAa,SAAS,OAAO,SAAS,KAAK,SAAS,UAAU,SAAS,KACpF;AAAA;AAAA,EAAwB,IAAI,KAC5B;AAEJ,QAAI,aAAa;AACf,aAAO,cAAc,UAAU,aAAa,IAAI;AAAA,IAClD;AAKA,UAAM,YACJ,YAAY,CAAC,SAAS,WAClB,CAAC,EAAE,MAAM,WAAW,aAAa,qBAAqB,YAAY,EAAE,QAAQ,gBAAgB,EAAE,CAAC,IAC/F;AACN,UAAM,OAAO,cAAc;AAE3B,UAAM,cAAc,WAAW,KAAK,QAAQ,6BAA6B;AACzE,UAAM,mBAAmB,mBAAmB,gBAAgB,gBAAgB,KAAK;AACjF,UAAM,oBAAoB,gBAAgB,SAAS,KAAK,eAAe,MAAM,+BAA+B;AAK5G,UAAM,cAAc,UAAU,OAAO,UAAU,KAAM,OAAO;AAC5D,UAAM,iBAAiB,UAAU,UAAU,UAAU,KAAM,UAAU;AACrE,UAAM,cAAc,mBAAmB,WAAW,iBAAiB,cAAc,eAAe,YAAY,MAAM,oBAAoB,WAAW,GAAG,gBAAgB,GAAG,iBAAiB;AACxL,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,SAAS,CAAC;AAAA,MACnD,mBAAmB;AAAA,QACjB,IAAI;AAAA,QACJ,SAAS,iBAAiB;AAAA,QAC1B,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,KAAM,QAAQ;AAAA,UAC3B,gBAAgB,YAAY;AAAA,UAC5B,eAAe,YAAY;AAAA,UAC3B,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,UAC/C,GAAI,gBAAgB,SAAS,EAAE,yBAAyB,eAAe,OAAO,IAAI,CAAC;AAAA,QACrF;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACJ;AACF;;;AE93BA,SAAS,KAAAG,WAAS;AAalB,IAAM,qBAAqB,CAAC,UAAU,sBAAsB;AAM5D,IAAM,iCAAiCC,IAAE,OAAO;AAAA,EAC9C,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAG,EACzB,SAAS,gFAAgF;AAAA,EAC5F,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACnC,SAAS,sEAAsE;AAAA,EAClF,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EACnC,SAAS,8DAA8D;AAAA,EAC1E,gBAAgBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAC1C,SAAS,iDAAiD;AAC/D,CAAC;AAEM,IAAM,mBAAmBA,IAAE,OAAO;AAAA,EACvC,QAAQA,IAAE,KAAK,kBAAkB,EAAE;AAAA,IACjC;AAAA,EAEF;AAAA,EACA,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACtC,SAAS,0CAA0C;AAAA,EACtD,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACvC,SAAS,4DAA4D;AAAA;AAAA;AAAA,EAGxE,2BAA2BA,IAAE,MAAM,8BAA8B,EAAE,IAAI,EAAE,EAAE,SAAS,EACjF;AAAA,IACC;AAAA,EAEF;AAAA,EACF,wBAAwBA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EACnD;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AAgDD,SAAS,eAAe,eAAuB,SAAyB;AACtE,QAAM,SAAS,QAAQ,IAAI,wBAAwB;AACnD,SAAO,GAAG,MAAM,IAAI,aAAa,mBAAmB,OAAO;AAC7D;AASA,eAAsB,aAAa,MAAwC;AACzE,QAAM,QAAQ,KAAK;AACnB,MAAI,CAAC,OAAO;AACV,WAAO,iBAAiB,6CAA6C;AAAA,EACvE;AAEA,QAAM,EAAE,aAAa,cAAc,IAAI,MAAM,oBAAoB;AAcjE,QAAM,WAAW,MAAM,mBAAuC,qCAAqC;AAAA,IACjG;AAAA,IACA,QAAQ;AAAA,IACR,YAAY;AAAA,EACd,CAAC;AAGD,QAAM,eAAe;AAAA,IACnB,GAAG,SAAS;AAAA,IACZ,WAAW,eAAe,eAAe,KAAK;AAAA,EAChD;AAGA,QAAM,MAAM,aAAa;AACzB,QAAM,KAAK,aAAa;AACxB,QAAM,qBAA+B,CAAC;AACtC,MAAI,GAAG,eAAe,EAAG,oBAAmB,KAAK,GAAG,GAAG,YAAY,aAAa;AAChF,MAAI,GAAG,YAAY,EAAG,oBAAmB,KAAK,GAAG,GAAG,SAAS,UAAU;AACvE,MAAI,GAAG,gBAAgB,EAAG,oBAAmB,KAAK,GAAG,GAAG,aAAa,cAAc;AACnF,QAAM,uBAAuB,mBAAmB,SAAS,IACrD,mBAAmB,KAAK,IAAI,IAC5B;AAEJ,QAAM,aAAa,aAAa,cAAc,MAAM,GAAG,EAAE,EAAE;AAAA,IACzD,CAAC,MAAoB,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,UAAU,MAAM,EAAE,MAAM;AAAA,EAClF;AACA,QAAM,YAAY;AAAA,IAChB,KAAK,IAAI,IAAI;AAAA,IACb;AAAA,IACA,aAAa,IAAI,UAAU,uBAAoB,IAAI,MAAM;AAAA,IACzD,aAAa,YAAY,eAAe,aAAa,SAAS,KAAK;AAAA,IACnE;AAAA,IACA,sBAAsB,oBAAoB;AAAA,IAC1C,GAAI,WAAW,SAAS,IAAI,CAAC,IAAI,uBAAuB,GAAG,UAAU,IAAI,CAAC;AAAA,EAC5E,EAAE,OAAO,CAAC,MAAM,MAAM,MAAS;AAE/B,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,UAAU,KAAK,IAAI,EAAE,CAAC;AAAA,IAC/D,mBAAmB;AAAA,MACjB,IAAI;AAAA,MACJ,SAAS,SAAS;AAAA,MAClB,MAAM;AAAA,MACN,MAAM,SAAS;AAAA,MACf,OAAO,SAAS;AAAA,IAClB;AAAA,EACF;AACF;AAIA,eAAsB,0BAA0B,MAAwC;AACtF,qBAAmB;AAEnB,QAAM,QAAQ,KAAK;AACnB,MAAI,CAAC,OAAO;AACV,WAAO,iBAAiB,2DAA2D;AAAA,EACrF;AAEA,QAAM,EAAE,YAAY,IAAI,MAAM,oBAAoB;AAClD,QAAM,YAAY,kBAAkB;AACpC,QAAM,cAAc,KAAK,eAAe,GAAG,KAAK,IAAI,aAAa,aAAa,IAAI,KAAK,IAAI,CAAC;AAI5F,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI;AACJ,MAAI;AAOF,UAAM,cAAc,MAAM,mBAAkC,kBAAkB,EAAE,SAAS,MAAM,CAAC;AAChG,UAAM,QAAQ,YAAY;AAC1B,QAAI,OAAO;AACT,gBAAU,MAAM,QAAQ;AACxB,YAAM,IAAI,MAAM,QAAQ,CAAC;AACzB,YAAM,QAAQ,EAAE,OAAO;AACvB,gBAAW,EAAE,WAAuB,OAAO,WAAuB,EAAE,eAA0B;AAC9F,0BAAoB,MAAM,kBAAkB,MAAM,YAAY,QAAQ,MAAM,YAAY;AAAA,IAC1F;AAAA,EACF,QAAQ;AAAA,EAER;AAOA,QAAM,YAAY,MAAM,qBAAqB,SAAS,SAAS,iBAAiB;AAEhF,MAAI,UAAU,WAAW,aAAa,UAAU,UAAU,SAAS,IAAI,UAAU,iBAAiB,SAAS,GAAG;AAC5G,UAAM,sBAAsB,EAAE,sBAAsB,KAAK,CAAC;AAAA,EAC5D;AAUA,QAAM,mBAAmB,UAAU,WAAW,aAC1C,UAAU,UAAU,IAAI,CAAC,OAAO;AAAA,IAC9B,cAAc,EAAE;AAAA,IAChB,gBAAgB,EAAE;AAAA,IAClB,GAAI,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,sBAAsB,IAAI,CAAC;AAAA,IACpF,MAAM,EAAE;AAAA,IACR,YAAY,EAAE;AAAA,IACd,aAAa,EAAE;AAAA,EACjB,EAAE,IACF,CAAC;AAGL,MAAI;AACJ,MAAI;AAGF,eAAW,MAAM,mBAA4C,qCAAqC;AAAA,MAChG;AAAA,MACA,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ;AAAA,MACA,WAAW,aAAa;AAAA,MACxB,QAAQ,YAAY,SAAS,SAAS,KAAK;AAAA;AAAA;AAAA,MAG3C,GAAI,KAAK,4BAA4B,EAAE,2BAA2B,KAAK,0BAA0B,IAAI,CAAC;AAAA,MACtG,GAAI,KAAK,yBAAyB,EAAE,wBAAwB,KAAK,uBAAuB,IAAI,CAAC;AAAA,MAC7F,GAAI,iBAAiB,SAAS,IAAI,EAAE,WAAW,iBAAiB,IAAI,CAAC;AAAA,IACvE,CAAC;AAAA,EACH,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAM,OAAQ,KAA2B;AACzC,UAAM,cAAe,KAAmD;AASxE,QAAI,SAAS,qBAAqB;AAChC,YAAM,oBAAqB,MAAM,QAAQ,aAAa,iBAAiB,IACnE,YAAY,oBACZ,CAAC;AACL,YAAM,gBAAgB,kBACnB,IAAI,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,OAAQ,EAAE,SAAiC,UAAU,iCAAiC,CAAC,EAAE,EACrI,KAAK,IAAI;AACZ,YAAM,QAAQ,kBAAkB;AAChC,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA,KAAK,KAAK,8BAAyB,KAAK,QAAQ,UAAU,IAAI,MAAM,KAAK;AAAA,YACzE,GAAI,gBAAgB,CAAC,IAAI,aAAa,IAAI,CAAC;AAAA,UAC7C,EAAE,KAAK,IAAI;AAAA,QACb,CAAC;AAAA,QACD,mBAAmB;AAAA,UACjB;AAAA,UACA,uBAAuB,KAAK,QAAQ,UAAU,IAAI,MAAM,KAAK;AAAA,UAC7D;AAAA,UACA,CAAC,EAAE,MAAM,WAAW,aAAa,yCAAyC,YAAY,EAAE,QAAQ,wBAAwB,YAAY,MAAM,EAAE,CAAC;AAAA,UAC7I,EAAE,kBAAkB;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAOA,QAAI,SAAS,yBAAyB;AACpC,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA;AAAA,IAAuC,KAAK,wBAAwB,GAAG;AAAA;AAAA;AAAA,QAC/E,CAAC;AAAA,QACD,mBAAmB;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA;AAAA,IAAqC,KAAK,6BAA6B,GAAG;AAAA;AAAA;AAAA,MAClF,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB;AAAA,QACA,+BAA+B,GAAG;AAAA,QAClC;AAAA,QACA,CAAC,EAAE,MAAM,WAAW,aAAa,kBAAkB,YAAY,EAAE,QAAQ,UAAU,YAAY,MAAM,EAAE,CAAC;AAAA,QACxG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAQA,aAAW,SAAU,SAAS,MAAM,QAAQ,gBAAgB,CAAC,GAAI;AAC/D,QAAI;AACF,YAAM,sBAAsB,EAAE,eAAe,MAAM,CAAC;AAAA,IACtD,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,QAAMC,UAAS,SAAS,KAAK;AAQ7B,QAAM,cAAc;AAAA,IAClB,yBAAyB,UAAU;AAAA,IACnC,GAAI,UAAU,WAAW,cAAc,UAAU,UAAU,SAAS,IAChE,EAAE,WAAW,UAAU,UAAU,IACjC,CAAC;AAAA,IACL,GAAI,UAAU,WAAW,eAAe,UAAU,iBAAiB,SAAS,IACxE,EAAE,kBAAkB,UAAU,iBAAiB,IAC/C,CAAC;AAAA,EACP;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAaA,QAAO,WAAW,UAAU,KAAK,MAAMA,QAAO,aAAa,UAAU,KAAK;AAC7F,MAAIA,QAAO,iBAAiB;AAC1B,UAAM;AAAA,MACJ,YAAY,mCAAmC;AAAA,MAC/C;AAAA,MACA,8CAA8C,KAAK;AAAA,MACnD;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM;AAAA,MACJ,YAAY,2BAA2B;AAAA,MACvC;AAAA,MACA,KAAKA,QAAO,cAAc,UAAU,CAAC,yCAAyCA,QAAO,cAAc;AAAA,MACnG,YACI,KAAK,KAAK,oHACV,KAAK,KAAK;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,UAAU,WAAW,cAAc,UAAU,UAAU,SAAS,GAAG;AACrE,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,GAAG,UAAU,UAAU,IAAI,CAAC,MAAM,OAAO,EAAE,YAAY,MAAM,EAAE,cAAc,KAAK,EAAE,WAAW,EAAE;AAAA,IACnG;AAAA,EACF,WAAW,UAAU,WAAW,eAAe,UAAU,iBAAiB,SAAS,GAAG;AACpF,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,GAAG,UAAU,iBAAiB;AAAA,QAC5B,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,UAAU,MAAM,EAAE,YAAY,oBAAoB,EAAE,iBAAiB,IAAI,KAAK,GAAG;AAAA,MAC7H;AAAA,IACF;AAAA,EACF;AAEA,OAAKA,QAAO,cAAc,UAAU,KAAK,GAAG;AAC1C,UAAM,KAAK,IAAI,iBAAiBA,QAAO,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EAClE;AACA,OAAKA,QAAO,qBAAqB,UAAU,KAAK,GAAG;AACjD,UAAM,KAAK,IAAI,yBAAyBA,QAAO,oBAAoB,KAAK,IAAI,CAAC,EAAE;AAAA,EACjF;AACA,OAAKA,QAAO,aAAa,UAAU,KAAK,GAAG;AACzC,UAAM,KAAK,IAAI,oCAAoCA,QAAO,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EACpF;AACA,OAAKA,QAAO,aAAa,UAAU,KAAK,GAAG;AACzC,UAAM,KAAK,IAAI,KAAKA,QAAO,YAAY,MAAM,eAAe;AAC5D,eAAW,KAAKA,QAAO,aAAa;AAClC,YAAM,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE;AAAA,IACxD;AAAA,EACF;AACA,OAAKA,QAAO,WAAW,UAAU,KAAK,GAAG;AACvC,UAAM,KAAK,IAAI,KAAKA,QAAO,UAAU,MAAM,YAAY;AACvD,eAAW,KAAKA,QAAO,WAAW;AAChC,YAAM,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,EAAE,KAAK,EAAE;AAAA,IACvD;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,IAAI;AAAA,MACJ,SAAS,SAAS;AAAA,MAClB,MAAM,EAAE,QAAAA,SAAQ,YAAY;AAAA,MAC5B,MAAM,SAAS;AAAA,MACf,OAAO,SAAS;AAAA,IAClB;AAAA,EACF;AACF;;;AHzaA,IAAM,kBAAkB;AAAA,EACtB;AAAA,EAAS;AAAA,EAAS;AAAA,EAAU;AAAA,EAAiB;AAAA,EAAiB;AAAA,EAAU;AAC1E;AAGA,IAAMC,sCAAqCC,IAAE,OAAO;AAAA,EAClD,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,gFAAgF;AAAA,EACvH,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EACtF,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,EAC/G,gBAAgBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAC3G,CAAC;AAGM,IAAM,gBAAgBA,IAAE,OAAO;AAAA,EACpC,QAAQA,IAAE,KAAK,eAAe,EAAE;AAAA,IAC9B;AAAA,EAKF;AAAA,EACA,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,EAC3H,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mEAAmE;AAAA,EACxH,2BAA2BA,IAAE,MAAMD,mCAAkC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE;AAAA,IACxF;AAAA,EACF;AAAA,EACA,wBAAwBC,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE;AAAA,IACtD;AAAA,EACF;AACF,CAAC;AAKD,IAAM,sBAAsBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,EAAE,CAAC;AACnE,IAAM,sBAAsBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,EAAE,CAAC;AACnE,IAAM,uBAAuBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AACrE,IAAM,6BAA6BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,eAAe,EAAE,CAAC;AAClF,IAAM,6BAA6BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,eAAe,EAAE,CAAC;AAClF,IAAM,uBAAuB,iBAAiB,KAAK,EAAE,QAAQ,KAAK,CAAC,EAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AAC3G,IAAM,oCAAoC,iBAAiB,KAAK,EAAE,QAAQ,KAAK,CAAC,EAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,sBAAsB,EAAE,CAAC;AAE/H,IAAM,qBAAqBA,IAAE,mBAAmB,UAAU;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,uBAA+D;AAAA,EAC1E,OAAO,EAAE,QAAQ,CAAC,GAAG,aAAa,sCAAsC;AAAA,EACxE,OAAO,EAAE,QAAQ,CAAC,GAAG,aAAa,sCAAsC;AAAA,EACxE,QAAQ,EAAE,QAAQ,CAAC,GAAG,aAAa,0CAA0C;AAAA,EAC7E,iBAAiB,EAAE,QAAQ,CAAC,GAAG,aAAa,wCAAwC;AAAA,EACpF,iBAAiB,EAAE,QAAQ,CAAC,GAAG,aAAa,4CAA4C;AAAA,EACxF,QAAQ,EAAE,QAAQ,CAAC,YAAY,GAAG,aAAa,0BAA0B;AAAA,EACzE,wBAAwB;AAAA,IACtB,QAAQ,CAAC,cAAc,eAAe,6BAA6B,wBAAwB;AAAA,IAC3F,aAAa;AAAA,EACf;AACF;AAEO,SAAS,qBAAqB,QAAyB;AAG5D,QAAM,gBAAgB,oBAAoB;AAG1C,QAAM,kBAA6E;AAAA,IACjF,OAAO,MAAMC,aAAY;AAAA,IACzB,OAAO,MAAM,YAAY;AAAA,IACzB,QAAQ,MAAM,aAAa;AAAA,IAC3B,iBAAiB,MAAM,cAAc,EAAE,QAAQ,SAAS,CAAC;AAAA,IACzD,iBAAiB,MAAM,cAAc,EAAE,QAAQ,aAAa,CAAC;AAAA,IAC7D,QAAQ,CAAC,SAAS,aAAa,IAAI;AAAA,IACnC,wBAAwB,CAAC,SAAS,0BAA0B,IAAI;AAAA,EAClE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAYF,aAAa;AAAA;AAAA,MAEb,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,eAAe,MAAM;AAAA,IACnF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,eAAe,IAAI;AAC9C,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAE9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,WAAW,OAAO;AAAA,QAAG,MACrD,sBAAsB,WAAW,oBAAoB,OAAO,MAAM,sBAAsB,eAAe;AAAA,MACzG;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAeA,eAAc;AAC3B,QAAMC,UAAS,MAAM,kBAAkB;AAEvC,QAAM,QAAkB,CAAC;AAEzB,QAAM;AAAA,IACJ,WAAWA,QAAO,SAAS,yBACTA,QAAO,WAAW,eACrBA,QAAO,aAAa,YACvBA,QAAO,UAAU;AAAA,EAE/B;AAQA,QAAM,KAAK,oBAAoB;AAI/B,QAAM,cAAc,kBAAkBA,QAAO,OAAO;AACpD,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,KAAK,IAAI,YAAY,GAAG,WAAW;AAAA,EAC3C;AAIA,QAAM,aAAa,yBAAyBA,QAAO,kBAAkB;AACrE,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,KAAK,IAAI,GAAG,UAAU;AAAA,EAC9B;AAEA,QAAM,UAAU,WAAWA,QAAO,SAAS,sBAAsBA,QAAO,aAAa;AACrF,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB,QAAQ,SAAS;AAAA,MAClC,WAAWA,QAAO;AAAA,MAClB,aAAaA,QAAO;AAAA,MACpB,eAAeA,QAAO;AAAA,MACtB,YAAYA,QAAO;AAAA,MACnB,kBAAkBA,QAAO;AAAA,MACzB,qBAAqBA,QAAO;AAAA,MAC5B,SAASA,QAAO,WAAW,CAAC;AAAA,MAC5B,oBAAoBA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7B,GAAG,CAAC,EAAE,MAAM,UAAU,aAAa,kBAAkB,YAAY,EAAE,QAAQ,QAAQ,EAAE,GAAG,GAAG,qBAAqBA,QAAO,OAAO,CAAC,CAAC;AAAA,EAClI;AACF;AAEA,eAAe,cAAc;AAC3B,QAAM,YAAY,kBAAkB;AACpC,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,EAAE,MAAM,WAAW,aAAa,mBAAmB,YAAY,EAAE,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACvF;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,WAAyD,oBAAoB;AAAA,IACjG;AAAA,EACF,CAAC;AAED,MAAI,cAAc;AAClB,MAAI,WAAW,CAAE,QAAQ,mBAA8B;AACrD,QAAI;AACF,YAAM,EAAE,MAAM,KAAK,IAAI,MAAM,gBAAgB;AAC7C,UAAI,QAAQ,KAAK,OAAO,SAAS,GAAG;AAClC,sBAAc;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO,KAAK,OAAO,MAAM;AAAA,UAEzB;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,MACb;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,kBAAkB;AACxB,mBAAiB;AAGjB,QAAM,UAAW,SAAS,gBAA6B,UAAU;AACjE,QAAM,WAAY,SAAS,iBAA8B,UAAU;AACnE,QAAM,YAAa,SAAS,oBAA+B;AAE3D,QAAM,QAAQ,MAAM,oBAAoB;AACxC,MAAI,OAAO;AACT,4BAAwB,MAAM,aAAa;AAAA,MACzC,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,MACnB,cAAc,UAAU;AAAA,IAC1B,CAAC;AAAA,EACH;AAEA,QAAM,QAAkB;AAAA,IACtB,WAAW,SAAS;AAAA,IACpB;AAAA,EACF;AACA,QAAM,QAAS,SAAS,gBAA2B;AACnD,QAAM,WAAY,SAAS,yBAAoC;AAE/D,MAAI,SAAS;AACX,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,uBAAuB,OAAO;AAAA,MAC9B,wBAAwB,QAAQ;AAAA,MAChC,yBAAyB,SAAS;AAAA,MAClC,qBAAqB,KAAK;AAAA,MAC1B,8BAA8B,QAAQ;AAAA,IACxC;AAAA,EACF;AAQA,MAAI,UAAwC;AAC5C,MAAI;AACF,cAAU,MAAM,WAAgE,2BAA2B,CAAC,CAAC;AAAA,EAC/G,QAAQ;AAAA,EAER;AACA,MAAI,QAAS,OAAM,KAAK,GAAG,yBAAyB,OAAO,CAAC;AAE5D,QAAM,KAAK,IAAI,yEAAyE;AAExF,QAAM,eAAe,cAAc,MAAM,KAAK,IAAI;AAClD,QAAM,UAAU,WAAW,SAAS,YAAY,OAAO,aAAa,QAAQ;AAC5E,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,aAAa,CAAC;AAAA,IACvD,mBAAmB,QAAQ,SAAS;AAAA,MAClC;AAAA,MACA,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,uBAAuB;AAAA,MACvB,aAAa,YAAY,SAAS;AAAA;AAAA;AAAA;AAAA,MAIlC,GAAI,SAAS,kBAAkB,SAAY,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,MACvF,GAAI,SAAS,mBAAmB,SAAY,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC;AAAA,MAC1F,GAAI,SAAS,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC3E,GAAI,SAAS,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA;AAAA,IAC7E,CAAC;AAAA,EACH;AACF;AAEA,eAAe,eAAe;AAC5B,QAAM,YAAY,kBAAkB;AACpC,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,EAAE,MAAM,WAAW,aAAa,mBAAmB,YAAY,EAAE,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACvF;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,WAAyD,oBAAoB;AAAA,IACjG;AAAA,EACF,CAAC;AAED,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,EAAE,MAAM,WAAW,aAAa,mBAAmB,YAAY,EAAE,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACvF;AAAA,EACF;AAEA,QAAM,WAAW,kBAAkB;AACnC,QAAM,UAAW,QAAQ,gBAA6B,UAAU;AAChE,QAAM,WAAY,QAAQ,iBAA8B,UAAU;AAElE,QAAM,QAAQ;AAAA,IACZ,WAAW,SAAS,IAAI,QAAQ,MAAM;AAAA,IACtC,gBAAgB,QAAQ,WAAW;AAAA,IACnC,UAAU,QAAQ,UAAU;AAAA,IAC5B,aAAa,WAAW,QAAQ,IAAI;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA,uBAAuB,OAAO;AAAA,IAC9B,wBAAwB,QAAQ;AAAA,IAChC,yBAAyB,QAAQ,oBAAoB,CAAC;AAAA,IACtD,eAAe,IAAI,KAAK,QAAQ,SAAmB,EAAE,YAAY,CAAC;AAAA,IAClE,eAAe,IAAI,KAAK,QAAQ,SAAmB,EAAE,YAAY,CAAC;AAAA,EACpE;AAEA,QAAM,UAAU,WAAW,SAAS,IAAI,QAAQ,MAAM,KAAK,OAAO,aAAa,QAAQ;AACvF,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB,QAAQ,SAAS;AAAA,MAClC;AAAA,MACA,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,YAAY,QAAQ;AAAA,MACpB;AAAA,MACA,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,kBAAkB,QAAQ,oBAAoB;AAAA,IAChD,CAAC;AAAA,EACH;AACF;;;AI7WA,SAAS,KAAAC,WAAS;;;ACFX,SAAS,iBAAiB,SAA4C;AAC3E,MAAI,WAAW,QAAQ,YAAY,EAAG,QAAO;AAC7C,SAAO,IAAI,OAAO;AACpB;;;ADKO,IAAM,cAAcC,IAAE,OAAO;AAAA,EAClC,QAAQA,IAAE,KAAK,CAAC,UAAU,OAAO,QAAQ,MAAM,CAAC,EAAE,SAAS,2FAA2F;AAAA,EACtJ,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,EAC9F,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EACpF,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,QAAQ,oBAAoB,EACrE,SAAS,qGAAqG;AAAA,EACjH,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EACjF,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2EAA2E;AAAA,EAC3H,SAASA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,EAC/F,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,EAChG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA;AAAA,EAElG,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,EAC1G,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAC5G,CAAC;AAEM,IAAM,qBAAqBA,IAAE,OAAO;AAAA,EACzC,QAAQA,IAAE,KAAK,CAAC,UAAU,QAAQ,QAAQ,UAAU,SAAS,CAAC,EAC3D,SAAS,kGAAkG;AAAA,EAC9G,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,sBAAsB;AAAA,EACjE,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAC1C,SAAS,2EAA2E;AAAA,EACvF,UAAUA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EACnE,UAAUA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,EACjE,WAAWA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EACvE,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kDAAkD;AACpG,CAAC;AAEM,IAAM,oBAAoBA,IAAE,OAAO;AAAA,EACxC,QAAQA,IAAE,KAAK,CAAC,UAAU,QAAQ,SAAS,WAAW,CAAC,EACpD,SAAS,gFAAgF;AAAA,EAC5F,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,sBAAsB;AAAA,EACjE,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACtC,SAAS,iEAAiE;AAAA,EAC7E,UAAUA,IAAE,KAAK,CAAC,gBAAgB,QAAQ,CAAC,EAAE,SAAS,EACnD,SAAS,sDAAsD;AAAA,EAClE,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kDAAkD;AACpG,CAAC;AAEM,IAAM,oBAAoBA,IAAE,OAAO;AAAA,EACxC,QAAQA,IAAE,KAAK,CAAC,QAAQ,WAAW,mBAAmB,eAAe,CAAC,EACnE,SAAS,gFAAgF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5F,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,2EAA2E;AAAA,EACjI,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAC1C,SAAS,0CAA0C;AAAA,EACtD,eAAeA,IAAE,OAAO,EAAE,SAAS,EAChC,SAAS,4CAA4C;AAAA,EACxD,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAClC,SAAS,kDAAkD;AAAA,EAC9D,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAClC,SAAS,4CAA4C;AAAA,EACxD,WAAWA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EACrC,SAAS,2CAA2C;AAAA,EACvD,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kDAAkD;AACpG,CAAC;AAMD,SAAS,YAAY,OAAwC;AAC3D,SAAO,OAAO,QAAQ,KAAK,EACxB,IAAI,CAAC,CAAC,IAAI,OAAO,MAAM;AACtB,UAAM,SAAS,OAAO,YAAY,YAAY,QAAQ,SAAS;AAC/D,UAAM,UAAU,SACZ,QAAQ,UAAU,GAAG,EAAE,KAAK,QAAQ,SAAS,KAAK,QAAQ,MAC1D;AACJ,WAAO,SAAS,EAAE,OAAO,OAAO;AAAA,EAClC,CAAC,EACA,KAAK,IAAI;AACd;AASA,eAAsB,gBAAgB,EAAE,QAAQ,cAAc,OAAO,aAAa,aAAa,QAAQ,SAAS,QAAAC,SAAQ,QAAQ,kBAAkB,iBAAiB,GAAgC;AAC7L,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,OAAO;AACV,aAAO,iBAAiB,4CAA4C;AAAA,IACtE;AAEA,UAAMC,UAAS,MAAM;AAAA,MACnB;AAAA,MACA,EAAE,OAAO,aAAa,aAAa,QAAQ,kBAAkB,iBAAiB;AAAA,IAChF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE;AAAA;AAAA,oBACqBA,QAAO,OAAO;AAAA,eACnB,KAAK;AAAA,cACN,WAAW;AAAA;AAAA;AAAA,wCAEeA,QAAO,OAAO;AAAA,MAC3D,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,oBAAoB,KAAK,MAAMA,QAAO,OAAO,YAAY,WAAW;AAAA,QACpE,EAAE,SAASA,QAAO,SAAS,OAAO,aAAa,QAAQ,QAAQ;AAAA,QAC/D,CAAC,EAAE,MAAM,SAAS,aAAa,eAAe,YAAY,EAAE,QAAQ,QAAQ,cAAcA,QAAO,SAAS,QAAQ,UAAU,EAAE,CAAC;AAAA,MACjI;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,cAAc;AACjB,aAAO,iBAAiB,+BAA+B;AAAA,IACzD;AAEA,UAAM,QAAQ,MAAM,YAA2D,qBAAqB,EAAE,aAAa,CAAC;AACpH,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,YAAY,YAAY,eAAe,CAAC;AAAA,QACjF,mBAAmB;AAAA,UACjB;AAAA,UACA,YAAY,YAAY;AAAA,UACxB;AAAA,UACA,CAAC,EAAE,MAAM,SAAS,aAAa,kBAAkB,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,QACnF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAAe,MAAM,SACvB;AAAA,gBAAmB,MAAM,cAAc;AAAA;AAAA,IACvC,MAAM,OAAO,SACV,IAAI,CAAC,MAAW,OAAO,EAAE,GAAG,OAAO,EAAE,KAAK,SAAS,SAAI,OAAO,KAAK,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,GAAG,SAAI,OAAO,KAAK,IAAI,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,EACzI,KAAK,IAAI,IACZ;AAEJ,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE,KAAK,MAAM,IAAI;AAAA;AAAA,oBACM,MAAM,OAAO;AAAA,cACnB,MAAM,aAAa;AAAA,gBACjB,MAAM,MAAM;AAAA,sBACN,MAAM,WAAW,IAAI,MAAM,UAAU;AAAA,iBAC1C,iBAAiB,MAAM,cAAc,CAAC;AAAA,oBACnC,MAAM,aAAa,SAAS;AAAA,wBACxB,MAAM,YAAY;AAAA,IAC3C,eACA;AAAA;AAAA;AAAA;AAAA,IACA,YAAY,MAAM,KAAK;AAAA,MAC3B,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,GAAG,MAAM,IAAI,KAAK,MAAM,WAAW,IAAI,MAAM,UAAU,qBAAqB,MAAM,cAAc,MAAM,iBAAiB,MAAM,cAAc,CAAC;AAAA,QAC5I,EAAE,SAAS,MAAM,SAAS,MAAM,MAAM,MAAM,QAAQ,MAAM,QAAQ,aAAa,MAAM,aAAa,YAAY,MAAM,YAAY,gBAAgB,MAAM,gBAAgB,SAAS,MAAM,kBAAkB,MAAM,gBAAgB,iBAAiB,MAAM,cAAc,EAAE;AAAA,MACtQ;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,YAAmB,uBAAuB,EAAE,aAAa,QAAAD,QAAO,CAAC;AAEtF,QAAI,OAAO,WAAW,GAAG;AACvB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,+DAA+D,CAAC;AAAA,QACzG,mBAAmB;AAAA,UACjB;AAAA,UACA,EAAE,QAAQ,CAAC,GAAG,OAAO,EAAE;AAAA,UACvB,CAAC,EAAE,MAAM,SAAS,aAAa,oBAAoB,YAAY,EAAE,QAAQ,SAAS,EAAE,CAAC;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,OACf;AAAA,MAAI,CAAC,MACJ,SAAS,EAAE,OAAO,QAAQ,EAAE,IAAI,WAAM,EAAE,WAAW,SAChD,EAAE,WAAW,IAAI,EAAE,UAAU,0BAClB,EAAE,cAAc,kBAAe,EAAE,MAAM;AAAA,IACvD,EACC,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,aAAa,OAAO,MAAM;AAAA;AAAA,EAAQ,SAAS,GAAG,CAAC;AAAA,MACxF,mBAAmB;AAAA,QACjB,SAAS,OAAO,MAAM;AAAA,QACtB,EAAE,OAAO,OAAO,OAAO;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ;AACrB,QAAI,CAAC,cAAc;AACjB,aAAO,iBAAiB,+BAA+B;AAAA,IACzD;AACA,QAAI,CAAC,QAAQ;AACX,aAAO,iBAAiB,0EAA0E;AAAA,IACpG;AACA,QAAI,CAAC,SAAS;AACZ,aAAO,iBAAiB,yCAAyC;AAAA,IACnE;AAEA,UAAMC,UAAS,MAAM,eAA8D,qBAAqB,EAAE,cAAc,QAAQ,SAAS,OAAO,CAAC;AAIjJ,UAAM,cAAcA,QAAO,qBAAqB;AAAA;AAAA,mBAAwBA,QAAO,kBAAkB,KAAK;AAEtG,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA;AAAA,iBAAoCA,QAAO,OAAO;AAAA,cAAmBA,QAAO,MAAM;AAAA,sBAAyBA,QAAO,MAAM;AAAA,wBAA2B,QAAQ,MAAM,SAAS,WAAW;AAAA;AAAA;AAAA,MAC7L,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,iBAAiBA,QAAO,MAAM,QAAQA,QAAO,OAAO,aAAaA,QAAO,MAAM,IAAIA,QAAO,qBAAqB,IAAIA,QAAO,kBAAkB,KAAK,EAAE;AAAA,QAClJ,EAAE,SAASA,QAAO,SAAS,QAAQA,QAAO,QAAQ,QAAQA,QAAO,QAAQ,eAAe,QAAQ,QAAQ,GAAIA,QAAO,qBAAqB,EAAE,oBAAoBA,QAAO,mBAAmB,IAAI,CAAC,EAAG;AAAA,QAChM,CAAC,EAAE,MAAM,SAAS,aAAa,mBAAmB,YAAY,EAAE,QAAQ,OAAO,aAAa,EAAE,CAAC;AAAA,MACjG;AAAA,IACF;AAAA,EACF;AAEA,SAAO,cAAc,QAAQ,CAAC,UAAU,OAAO,QAAQ,MAAM,CAAC;AACpE;AAOA,eAAsB,mBAAmB,EAAE,QAAQ,cAAc,eAAe,UAAU,UAAU,WAAW,OAAO,GAAuC;AACvJ,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,eAAe;AAClB,aAAO,iBAAiB,gCAAgC;AAAA,IAC1D;AAEA,UAAMA,UAAS,MAAM,eAAiE,wBAAwB,EAAE,cAAc,eAAe,OAAO,CAAC;AAErJ,UAAM,UAAUA,QAAO,oBACnB;AAAA;AAAA,sBAA2BA,QAAO,iBAAiB,KACnD;AAEJ,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE,gBAAgBA,QAAO,OAAO;AAAA;AAAA,iBACZA,QAAO,OAAO;AAAA,iBACdA,QAAO,OAAO;AAAA,iBACd,aAAa;AAAA,mBACXA,QAAO,cAAc;AAAA,wBAChBA,QAAO,cAAc,SAAS,IAAIA,QAAO,cAAc,KAAK,IAAI,IAAI,MAAM;AAAA,IACnG;AAAA,MACJ,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,cAAcA,QAAO,OAAO,OAAOA,QAAO,OAAO,gBAAgBA,QAAO,cAAc;AAAA,QACtF,EAAE,SAASA,QAAO,SAAS,SAASA,QAAO,SAAS,gBAAgB,iBAAiBA,QAAO,OAAO,GAAG,gBAAgBA,QAAO,gBAAgB,eAAeA,QAAO,eAAe,aAAaA,QAAO,kBAAkB;AAAA,MAC1N;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,UAAU,MAAM,YAAmB,wBAAwB,EAAE,aAAa,CAAC;AAEjF,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,+BAA+B,YAAY,uEAAuE,CAAC;AAAA,QAC5J,mBAAmB;AAAA,UACjB,kBAAkB,YAAY;AAAA,UAC9B,EAAE,cAAc,SAAS,CAAC,GAAG,OAAO,EAAE;AAAA,UACtC,CAAC,EAAE,MAAM,SAAS,aAAa,gBAAgB,YAAY,EAAE,QAAQ,kBAAkB,aAAa,EAAE,CAAC;AAAA,QACzG;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,QACf,IAAI,CAAC,MAAW;AACf,YAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,KAAK,GAAG,EAAE,UAAU,GAAG,EAAE;AAClF,YAAM,MAAM,EAAE,iBAAiB,EAAE,cAAc;AAC/C,YAAM,QAAQ,EAAE,eAAe,SAAS,IAAI,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC,MAAM;AACjF,aAAO,QAAQ,EAAE,OAAO,MAAM,IAAI,OAAO,EAAE,MAAM,WAAM,GAAG,GAAG,KAAK,KAAK,EAAE,aAAa;AAAA,IACxF,CAAC,EACA,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iBAAiB,YAAY,KAAK,QAAQ,MAAM;AAAA;AAAA,EAAQ,SAAS,GAAG,CAAC;AAAA,MAC9G,mBAAmB;AAAA,QACjB,GAAG,QAAQ,MAAM,kBAAkB,YAAY;AAAA,QAC/C,EAAE,cAAc,OAAO,QAAQ,OAAO;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ;AACrB,QAAI,YAAY,QAAQ,YAAY,MAAM;AACxC,aAAO,iBAAiB,uDAAuD;AAAA,IACjF;AAEA,UAAM,OAAO,MAAM,eAAkE,yBAAyB,EAAE,cAAc,UAAU,SAAS,CAAC;AAElJ,QAAI,OACF,YAAY,QAAQ,YAAO,QAAQ;AAAA;AAAA,iBACjB,KAAK,YAAY;AAAA,mBACf,KAAK,eAAe,YAAO,KAAK,cAAc,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,GAAG,KAAK,cAAc;AAAA,uBACzG,KAAK,aAAa,SAAS,IAAI,KAAK,aAAa,KAAK,IAAI,IAAI,MAAM;AAAA;AAE9F,eAAW,MAAM,KAAK,WAAW;AAC/B,UAAI,GAAG,WAAW,YAAa;AAC/B,cAAQ;AAAA,KAAQ,GAAG,MAAM,KAAK,GAAG,MAAM;AAAA;AAAA;AACvC,YAAM,WAAW,KAAK,UAAU,GAAG,MAAM;AACzC,UAAI,UAAU,SAAS,GAAG;AACxB,mBAAW,KAAK,UAAU;AACxB,cAAI,EAAE,SAAS,SAAU,SAAQ,KAAK,EAAE,MAAM,UAAU,GAAG,GAAG,CAAC;AAAA,mBACtD,EAAE,SAAS,SAAU,SAAQ,KAAK,EAAE,MAAM,UAAU,GAAG,GAAG,CAAC;AAAA,cAC/D,SAAQ,EAAE,MAAM,UAAU,GAAG,GAAG;AAAA,QACvC;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC;AAAA,MACzC,mBAAmB;AAAA,QACjB,SAAS,QAAQ,YAAO,QAAQ,eAAe,KAAK,eAAe,YAAO,KAAK,cAAc,MAAM,KAAK,aAAa,MAAM;AAAA,QAC3H,EAAE,cAAc,KAAK,cAAc,UAAU,UAAU,iBAAiB,KAAK,iBAAiB,gBAAgB,KAAK,gBAAgB,gBAAgB,KAAK,gBAAgB,cAAc,KAAK,aAAa;AAAA,MAC1M;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,aAAa,MAAM;AACrB,aAAO,iBAAiB,uCAAuC;AAAA,IACjE;AAEA,UAAMA,UAAS,MAAM,eAAiE,wBAAwB,EAAE,cAAc,WAAW,OAAO,CAAC;AAEjJ,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE;AAAA;AAAA,iBACkBA,QAAO,OAAO;AAAA,sBACTA,QAAO,UAAU;AAAA,sBACjBA,QAAO,UAAU;AAAA,wBACfA,QAAO,cAAc,SAAS,IAAIA,QAAO,cAAc,KAAK,IAAI,IAAI,MAAM;AAAA;AAAA;AAAA,MAEvG,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,YAAYA,QAAO,OAAO,QAAQA,QAAO,UAAU,mBAAmBA,QAAO,UAAU;AAAA,QACvF,EAAE,SAASA,QAAO,SAAS,YAAYA,QAAO,YAAY,mBAAmB,iBAAiBA,QAAO,UAAU,GAAG,YAAYA,QAAO,YAAY,mBAAmB,iBAAiBA,QAAO,UAAU,GAAG,eAAeA,QAAO,cAAc;AAAA,MAC/O;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,WAAW;AACxB,UAAM,UAAU,MAAM,YAAmB,uBAAuB,EAAE,aAAa,CAAC;AAEhF,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,+BAA+B,YAAY,KAAK,CAAC;AAAA,QAC1F,mBAAmB;AAAA,UACjB,kBAAkB,YAAY;AAAA,UAC9B,EAAE,cAAc,QAAQ,CAAC,GAAG,OAAO,EAAE;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,QACf,KAAK,CAAC,GAAQ,MAAW,EAAE,YAAY,EAAE,SAAS,EAClD,IAAI,CAAC,MAAW;AACf,YAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,KAAK,GAAG,EAAE,UAAU,GAAG,EAAE;AAClF,aAAO,OAAO,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,aAAa,SAAS,WAAM,EAAE,QAAQ,EAAE;AAAA,IACpF,CAAC,EACA,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iBAAiB,YAAY,KAAK,QAAQ,MAAM;AAAA;AAAA,EAAe,SAAS,GAAG,CAAC;AAAA,MACrH,mBAAmB;AAAA,QACjB,GAAG,QAAQ,MAAM,yBAAyB,YAAY;AAAA,QACtD,EAAE,cAAc,OAAO,QAAQ,OAAO;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,cAAc,QAAQ,CAAC,UAAU,QAAQ,QAAQ,UAAU,SAAS,CAAC;AAClF;AAOA,eAAsB,kBAAkB,EAAE,QAAQ,cAAc,YAAY,UAAU,OAAO,GAAsC;AAC7H,MAAI,WAAW,UAAU;AACvB,UAAMA,UAAS,MAAM,eAAkE,yBAAyB,EAAE,cAAc,MAAM,YAAY,OAAO,CAAC;AAE1J,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE;AAAA;AAAA,cACeA,QAAO,IAAI;AAAA,mBACNA,QAAO,WAAW;AAAA,iBACpB,YAAY;AAAA;AAAA;AAAA,MAElC,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,mBAAmBA,QAAO,IAAI,eAAeA,QAAO,WAAW;AAAA,QAC/D,EAAE,UAAUA,QAAO,UAAU,MAAMA,QAAO,MAAM,aAAaA,QAAO,aAAa,aAAa;AAAA,QAC9F,CAAC,EAAE,MAAM,gBAAgB,aAAa,gBAAgB,YAAY,EAAE,QAAQ,gBAAgB,cAAc,YAAYA,QAAO,KAAK,EAAE,CAAC;AAAA,MACvI;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,WAAW,MAAM,eAAsB,yBAAyB,EAAE,aAAa,CAAC;AAEtF,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gCAAgC,YAAY,KAAK,CAAC;AAAA,QAC3F,mBAAmB;AAAA,UACjB,mBAAmB,YAAY;AAAA,UAC/B,EAAE,cAAc,UAAU,CAAC,GAAG,OAAO,EAAE;AAAA,UACvC,CAAC,EAAE,MAAM,gBAAgB,aAAa,mBAAmB,YAAY,EAAE,QAAQ,iBAAiB,aAAa,EAAE,CAAC;AAAA,QAClH;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,SACf,IAAI,CAAC,MAAW,OAAO,EAAE,IAAI,OAAO,EAAE,MAAM,sBAAiB,EAAE,WAAW,QAAQ,EAAE,SAAS,EAAE,EAC/F,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,kBAAkB,YAAY,KAAK,SAAS,MAAM;AAAA;AAAA,EAAQ,SAAS,GAAG,CAAC;AAAA,MAChH,mBAAmB;AAAA,QACjB,GAAG,SAAS,MAAM,mBAAmB,YAAY;AAAA,QACjD,EAAE,cAAc,OAAO,SAAS,OAAO;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,SAAS;AACtB,QAAI,CAAC,YAAY;AACf,aAAO,iBAAiB,uCAAuC;AAAA,IACjE;AAEA,UAAMA,UAAS,MAAM,eAAiE,wBAAwB,EAAE,cAAc,YAAY,UAAU,OAAO,CAAC;AAE5J,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE;AAAA;AAAA,iBACkBA,QAAO,OAAO;AAAA,gBACfA,QAAO,UAAU;AAAA,kBACfA,QAAO,OAAO;AAAA,kBACdA,QAAO,QAAQ;AAAA;AAAA,kBACfA,QAAO,OAAO;AAAA,MACrC,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,kBAAkBA,QAAO,UAAU,UAAUA,QAAO,OAAO,QAAQA,QAAO,OAAO;AAAA,QACjF,EAAE,SAASA,QAAO,SAAS,YAAYA,QAAO,YAAY,SAASA,QAAO,SAAS,gBAAgB,iBAAiBA,QAAO,OAAO,GAAG,UAAUA,QAAO,SAAS;AAAA,MACjK;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,aAAa;AAC1B,QAAI,CAAC,YAAY;AACf,aAAO,iBAAiB,gDAAgD;AAAA,IAC1E;AAEA,UAAMA,UAAS,MAAM,eAAoE,2BAA2B,EAAE,cAAc,WAAW,CAAC;AAEhJ,QAAI,CAACA,QAAO,cAAc;AACxB,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM;AAAA;AAAA,UAA6B,UAAU,UAAU,YAAY;AAAA,QACrE,CAAC;AAAA,QACD,mBAAmB;AAAA,UACjB,2BAA2B,UAAU;AAAA,UACrC,EAAE,cAAc,YAAY,cAAc,MAAM;AAAA,UAChD,CAAC,EAAE,MAAM,gBAAgB,aAAa,gBAAgB,YAAY,EAAE,QAAQ,gBAAgB,cAAc,WAAW,EAAE,CAAC;AAAA,QAC1H;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgBA,QAAO,UAC1B;AAAA,MAAI,CAAC,MACJ,OAAO,EAAE,MAAM,0BAAqB,EAAE,SAAS,IAAI,CAAC,MAAW,GAAG,EAAE,UAAU,KAAK,EAAE,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,IAC5G,EACC,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE;AAAA;AAAA,UACW,UAAU;AAAA;AAAA,IACrB,gBACA;AAAA;AAAA;AAAA,MACJ,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB;AAAA,QACA,WAAW,UAAU,SAASA,QAAO,UAAU,MAAM;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,cAAc,QAAQ,CAAC,UAAU,QAAQ,SAAS,WAAW,CAAC;AAC3E;AAOA,eAAsB,kBAAkB,EAAE,QAAQ,cAAc,eAAe,eAAe,QAAQ,MAAM,WAAW,OAAO,GAAsC;AAC9J,MAAI,WAAW,QAAQ;AACrB,UAAM,OAAO,MAAM,YAA0D,oBAAoB,EAAE,cAAc,cAAc,CAAC;AAEhI,UAAM,aAAa,KAAK,OACrB,IAAI,CAAC,MAAW,KAAK,EAAE,OAAO,SAAS,MAAM,MAAM,EAAE,IAAI,OAAO,EAAE,MAAM,EAAE,EAC1E,KAAK,IAAI;AAEZ,UAAM,OAAO,KAAK,OAAO,SAAS;AAElC,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE,WAAW,IAAI;AAAA;AAAA,eACC,KAAK,KAAK;AAAA,mBACN,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA,EAClB,UAAU;AAAA,MAC9B,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,QAAQ,IAAI,KAAK,KAAK,KAAK,gBAAgB,KAAK,SAAS;AAAA,QACzD,EAAE,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,WAAW,KAAK,WAAW,QAAQ,KAAK,OAAO;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,WAAW;AACxB,QAAI,CAAC,eAAe;AAClB,aAAO,iBAAiB,gCAAgC;AAAA,IAC1D;AACA,QAAI,CAAC,MAAM;AACT,aAAO,iBAAiB,uBAAuB;AAAA,IACjD;AAEA,UAAMA,UAAS,MAAM,eAAgE,uBAAuB;AAAA,MAC1G;AAAA,MAAc;AAAA,MAAe;AAAA,MAAQ;AAAA,MAAM;AAAA,IAC7C,CAAC;AAED,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MACE;AAAA;AAAA,iBACkBA,QAAO,YAAY;AAAA,kBAClBA,QAAO,aAAa;AAAA,KACtCA,QAAO,SAAS,eAAeA,QAAO,MAAM;AAAA,IAAO,MACpD,eAAe,KAAK,UAAU,GAAG,GAAG,CAAC;AAAA,MACzC,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,oBAAoBA,QAAO,YAAY,KAAKA,QAAO,aAAa,GAAGA,QAAO,SAAS,KAAKA,QAAO,MAAM,MAAM,EAAE;AAAA,QAC7G,EAAE,cAAcA,QAAO,cAAc,eAAeA,QAAO,eAAe,QAAQA,QAAO,OAAO;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,mBAAmB;AAChC,QAAI,CAAC,WAAW;AACd,aAAO,iBAAiB,4BAA4B;AAAA,IACtD;AACA,UAAM,eAAoE,2BAA2B,EAAE,UAAU,CAAC;AAClH,WAAO,cAAc,qBAAqB,WAAW,SAAS,cAAc,EAAE,WAAW,UAAU,KAAK,CAAC;AAAA,EAC3G;AAEA,MAAI,WAAW,iBAAiB;AAC9B,UAAM,WAAW,MAAM,eAAkE,yBAAyB;AAAA,MAChH;AAAA,MAAc;AAAA,IAChB,CAAC;AAED,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gCAAgC,YAAY,IAAI,gBAAgB,KAAK,aAAa,KAAK,EAAE,IAAI,CAAC;AAAA,QACvI,mBAAmB;AAAA,UACjB,mBAAmB,YAAY,GAAG,gBAAgB,KAAK,aAAa,KAAK,EAAE;AAAA,UAC3E,EAAE,cAAc,UAAU,CAAC,GAAG,OAAO,GAAG,YAAY,EAAE;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,SACf,IAAI,CAAC,MAAW;AACf,YAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,KAAK,GAAG,EAAE,UAAU,GAAG,EAAE;AAClF,YAAM,WAAW,EAAE,WAAW,gBAAgB;AAC9C,YAAM,OAAO,EAAE,SAAS,KAAK,EAAE,MAAM,MAAM;AAC3C,aAAO,QAAQ,EAAE,OAAO,GAAG,IAAI,MAAM,IAAI,OAAO,EAAE,MAAM,GAAG,QAAQ,KAAK,EAAE,KAAK,UAAU,GAAG,GAAG,CAAC;AAAA,IAClG,CAAC,EACA,KAAK,IAAI;AAEZ,UAAM,kBAAkB,SAAS,OAAO,CAAC,MAAW,CAAC,EAAE,QAAQ,EAAE;AAEjE,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,kBAAkB,YAAY,KAAK,SAAS,MAAM,KAAK,eAAe;AAAA;AAAA,EAAmB,SAAS;AAAA,MAC1G,CAAC;AAAA,MACD,mBAAmB;AAAA,QACjB,GAAG,SAAS,MAAM,mBAAmB,YAAY,KAAK,eAAe;AAAA,QACrE,EAAE,cAAc,OAAO,SAAS,QAAQ,YAAY,gBAAgB;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAEA,SAAO,cAAc,QAAQ,CAAC,QAAQ,WAAW,mBAAmB,eAAe,CAAC;AAC1F;AAsBA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EAAU;AAAA,EAAO;AAAA,EAAQ;AAAA,EACzB;AAAA,EAAkB;AAAA,EAAgB;AAAA,EAAgB;AAAA,EAAkB;AACtE;AAGA,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAmB;AAAA,EACtC;AAAA,EAAiB;AAAA,EAAe;AAAA,EAAgB;AAClD;AAKO,IAAM,sBAAsBF,IAAE,OAAO;AAAA,EAC1C,QAAQA,IAAE,KAAK,aAAa,EAAE;AAAA,IAC5B;AAAA,EAGF;AAAA,EACA,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kEAAkE;AAAA,EACxH,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,EACxF,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,QAAQ,oBAAoB,EAAE,SAAS,6CAA6C;AAAA,EAChI,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EACnF,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,EACtF,SAASA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA,EACrG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAC/E,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA,EAClG,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA,EAC1G,UAAUA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,EAC1F,UAAUA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,EACxF,WAAWA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA;AAAA,EAEzG,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,EAC1G,kBAAkBA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAC5G,CAAC;AAIM,IAAM,4BAA4BA,IAAE,OAAO;AAAA,EAChD,QAAQA,IAAE,KAAK,oBAAoB,EAAE;AAAA,IACnC;AAAA,EAGF;AAAA,EACA,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,qEAAqE;AAAA,EAC3H,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EAC7F,eAAeA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4EAA4E;AAAA,EAC1H,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,EACpG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,EACzF,WAAWA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,EAClG,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,iFAAiF;AAAA,EACrI,UAAUA,IAAE,KAAK,CAAC,gBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,EAC9H,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kDAAkD;AACpG,CAAC;AAID,IAAM,qBAAqB,YAAY,KAAK,EAAE,QAAQ,KAAK,CAAC,EAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AACpG,IAAM,kBAAkBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,KAAK,GAAG,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAChG,IAAM,mBAAmBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,GAAG,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;AACpJ,IAAM,mBAAmBA,IAAE,OAAO;AAAA,EAChC,QAAQA,IAAE,QAAQ,MAAM;AAAA,EACxB,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAChC,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC1B,SAASA,IAAE,OAAO,EAAE,IAAI,GAAK;AAAA,EAC7B,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AACvC,CAAC;AACD,IAAM,cAAc,mBAAmB,KAAK,EAAE,QAAQ,KAAK,CAAC;AAC5D,IAAM,4BAA4B,YAAY,OAAO,EAAE,QAAQA,IAAE,QAAQ,gBAAgB,GAAG,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,CAAC;AACjI,IAAM,0BAA0B,YAAY,OAAO,EAAE,QAAQA,IAAE,QAAQ,cAAc,EAAE,CAAC;AACxF,IAAM,0BAA0B,YAAY,OAAO,EAAE,QAAQA,IAAE,QAAQ,cAAc,GAAG,UAAUA,IAAE,OAAO,GAAG,UAAUA,IAAE,OAAO,EAAE,CAAC;AACpI,IAAM,4BAA4B,YAAY,OAAO,EAAE,QAAQA,IAAE,QAAQ,gBAAgB,GAAG,WAAWA,IAAE,OAAO,EAAE,CAAC;AACnH,IAAM,6BAA6B,YAAY,OAAO,EAAE,QAAQA,IAAE,QAAQ,iBAAiB,EAAE,CAAC;AAEvF,IAAM,mBAAmBA,IAAE,mBAAmB,UAAU;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,aAAa,kBAAkB,KAAK,EAAE,QAAQ,KAAK,CAAC;AAI1D,IAAM,yBAAyB,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,GAAG,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AACjH,IAAM,4BAA4B,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,SAAS,GAAG,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,eAAeA,IAAE,OAAO,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,CAAC;AAC/K,IAAM,mCAAmC,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,iBAAiB,GAAG,WAAWA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AACnI,IAAM,iCAAiC,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,eAAe,GAAG,cAAcA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAClI,IAAM,aAAa,kBAAkB,KAAK,EAAE,QAAQ,KAAK,CAAC;AAC1D,IAAM,2BAA2B,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,eAAe,EAAE,CAAC;AACzF,IAAM,yBAAyB,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,aAAa,EAAE,CAAC;AACrF,IAAM,0BAA0B,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,cAAc,GAAG,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AACxH,IAAM,8BAA8B,WAAW,OAAO,EAAE,QAAQA,IAAE,QAAQ,kBAAkB,GAAG,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAEzH,IAAM,yBAAyBA,IAAE,mBAAmB,UAAU;AAAA,EACnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,qBAA2D;AAAA,EACtE,QAAQ,EAAE,QAAQ,CAAC,SAAS,eAAe,eAAe,UAAU,oBAAoB,kBAAkB,GAAG,aAAa,qBAAqB;AAAA,EAC/I,KAAK,EAAE,QAAQ,CAAC,cAAc,GAAG,aAAa,4BAA4B;AAAA,EAC1E,MAAM,EAAE,QAAQ,CAAC,eAAe,QAAQ,GAAG,aAAa,uBAAuB;AAAA,EAC/E,MAAM,EAAE,QAAQ,CAAC,gBAAgB,UAAU,WAAW,QAAQ,GAAG,aAAa,kDAAkD;AAAA,EAChI,kBAAkB,EAAE,QAAQ,CAAC,gBAAgB,iBAAiB,QAAQ,GAAG,aAAa,+CAA+C;AAAA,EACrI,gBAAgB,EAAE,QAAQ,CAAC,cAAc,GAAG,aAAa,4BAA4B;AAAA,EACrF,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,YAAY,UAAU,GAAG,aAAa,qDAAqD;AAAA,EACtI,kBAAkB,EAAE,QAAQ,CAAC,gBAAgB,aAAa,QAAQ,GAAG,aAAa,2CAA2C;AAAA,EAC7H,mBAAmB,EAAE,QAAQ,CAAC,cAAc,GAAG,aAAa,4BAA4B;AAC1F;AAGO,IAAM,4BAAwE;AAAA,EACnF,MAAM,EAAE,QAAQ,CAAC,gBAAgB,eAAe,GAAG,aAAa,4BAA4B;AAAA,EAC5F,SAAS,EAAE,QAAQ,CAAC,gBAAgB,iBAAiB,UAAU,QAAQ,QAAQ,GAAG,aAAa,sDAAsD;AAAA,EACrJ,mBAAmB,EAAE,QAAQ,CAAC,WAAW,GAAG,aAAa,yBAAyB;AAAA,EAClF,iBAAiB,EAAE,QAAQ,CAAC,gBAAgB,eAAe,GAAG,aAAa,4BAA4B;AAAA,EACvG,iBAAiB,EAAE,QAAQ,CAAC,gBAAgB,cAAc,QAAQ,GAAG,aAAa,4BAA4B;AAAA,EAC9G,eAAe,EAAE,QAAQ,CAAC,cAAc,GAAG,aAAa,4BAA4B;AAAA,EACpF,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB,cAAc,YAAY,QAAQ,GAAG,aAAa,4CAA4C;AAAA,EACzI,oBAAoB,EAAE,QAAQ,CAAC,gBAAgB,YAAY,GAAG,aAAa,4CAA4C;AACzH;AAEO,SAAS,sBAAsB,QAAmB;AAIvD,QAAM,gBAAyE;AAAA,IAC7E,QAAQ,CAAC,SAAS,gBAAgB,EAAE,GAAG,MAAM,QAAQ,SAAS,CAAC;AAAA,IAC/D,KAAK,CAAC,SAAS,gBAAgB,EAAE,GAAG,MAAM,QAAQ,MAAM,CAAC;AAAA,IACzD,MAAM,CAAC,SAAS,gBAAgB,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,IAC3D,MAAM,CAAC,SAAS,gBAAgB,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,IAC3D,kBAAkB,CAAC,SAAS,mBAAmB,EAAE,GAAG,MAAM,QAAQ,SAAS,CAAC;AAAA,IAC5E,gBAAgB,CAAC,SAAS,mBAAmB,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,IACxE,gBAAgB,CAAC,SAAS,mBAAmB,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,IACxE,kBAAkB,CAAC,SAAS,mBAAmB,EAAE,GAAG,MAAM,QAAQ,SAAS,CAAC;AAAA,IAC5E,mBAAmB,CAAC,SAAS,mBAAmB,EAAE,GAAG,MAAM,QAAQ,UAAU,CAAC;AAAA,EAChF;AAKA,QAAM,sBAAqF;AAAA,IACzF,MAAM,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,IAC7D,SAAS,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,UAAU,CAAC;AAAA,IACnE,mBAAmB,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,kBAAkB,CAAC;AAAA,IACrF,iBAAiB,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,gBAAgB,CAAC;AAAA,IACjF,iBAAiB,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,SAAS,CAAC;AAAA,IAC1E,eAAe,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,IACtE,gBAAgB,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACxE,oBAAoB,CAAC,SAAS,kBAAkB,EAAE,GAAG,MAAM,QAAQ,YAAY,CAAC;AAAA,EAClF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAMF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,eAAe,MAAM;AAAA,IACnF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,qBAAqB,IAAI;AACpD,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,SAAS,OAAO;AAAA,QAAG,MACnD,sBAAsB,SAAS,kBAAkB,OAAO,MAAM,oBAAoB,aAAa;AAAA,MACjG;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAKF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,eAAe,MAAM;AAAA,IACnF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,2BAA2B,IAAI;AAC1D,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,gBAAgB,OAAO;AAAA,QAAG,MAC1D,sBAAsB,gBAAgB,wBAAwB,OAAO,MAAM,2BAA2B,mBAAmB;AAAA,MAC3H;AAAA,IACF,CAAC;AAAA,EACH;AAOF;;;AEv2BA,SAAS,KAAAG,WAAS;;;ACXlB,SAAS,KAAAC,WAA0B;;;ACiDnC,eAAsB,qBAAqB,OAAyC;AAClF,QAAM,QAAQ,WAAW;AACzB,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,eAAe;AAAA,EACnC,QAAQ;AACN,gBAAY;AAAA,EACd;AASA,QAAM,YAAY,CAAC,WAAW,KAAK;AAMnC,QAAM,MAAM,YAAY,SAAS;AACjC,QAAM,SAAS,IAAI,MAAM,CAAC,KAAK;AAC/B,QAAM,cAAc,6BAA6B,SAAS;AAE1D,QAAM,WAAW;AAAA,IACf,qBAAqB,OAAO,MAAM,OAAO,IAAI,MAAM;AAAA;AAAA,IACnD,GAAG,OAAO,IAAI,CAAC,UAAU;AACvB,YAAM,WAAW,MAAM,cACnB,KAAK,MAAM,YAAY,IAAI,GAAG,MAAM,YAAY,SAAS,WAAW,MAAM,YAAY,MAAM,KAAK,EAAE,MACnG;AACJ,YAAM,UAAU,MAAM,QAAQ,WAAM,MAAM,KAAK,KAAK;AACpD,aAAO,GAAG,MAAM,WAAW,OAAO,WAAM,QAAG,MAAM,MAAM,EAAE,KAAK,QAAQ,IAAI,MAAM,UAAU,MAAM,MAAM,MAAM,GAAG,OAAO;AAAA,IACxH,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,WAAW,KAAK,QAAQ,aAAa,UAAU,iBAAiB,yBAAyB,WAAW,EAAE;AACjH;;;ADhFA,IAAM,kBAAgD;AAAA,EACpD,kBAAkB;AAAA,EAClB,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,oBAAoB;AACtB;AAEA,SAAS,WAAW,IAA0B;AAC5C,SAAO,gBAAgB,EAAE,KAAK;AAChC;AAEA,SAAS,eAAe,IAAoB;AAC1C,MAAI,KAAK,IAAQ,QAAO,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC;AAChD,QAAM,OAAO,KAAK,MAAM,KAAK,GAAM;AACnC,QAAM,OAAO,KAAK,MAAO,KAAK,MAAU,GAAI;AAC5C,SAAO,GAAG,IAAI,KAAK,IAAI;AACzB;AAEA,SAAS,oBAAoB,KAAoC;AAC/D,MAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,QAAM,aAAa,oBAAI,IAAuC;AAC9D,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,eAAe;AAEnB,aAAW,SAAS,KAAK;AACvB,UAAM,MAAM,WAAW,MAAM,EAAE;AAC/B,QAAI,CAAC,WAAW,IAAI,GAAG,EAAG,YAAW,IAAI,KAAK,oBAAI,IAAI,CAAC;AACvD,UAAM,WAAW,WAAW,IAAI,GAAG;AACnC,aAAS,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,EAAE,KAAK,KAAK,CAAC;AAExD,QAAI,MAAM,WAAW,QAAS;AAC9B,QAAI,MAAM,OAAO,uBAAuB,MAAM,WAAW,KAAM;AAC/D,QAAI,MAAM,OAAO,uBAAuB,MAAM,WAAW,KAAM;AAAA,EACjE;AAEA,QAAM,UAAU,IAAI,KAAK,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ;AAC5C,QAAM,SAAS,IAAI,KAAK,IAAI,IAAI,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ;AACxD,QAAM,WAAW,eAAe,SAAS,OAAO;AAEhD,QAAM,QAAkB,CAAC,sBAAsB,QAAQ;AAAA,CAAK;AAE5D,QAAM,iBAA2C;AAAA,IAC/C,CAAC,QAAQ,OAAO;AAAA,IAChB,CAAC,UAAU,UAAU;AAAA,IACrB,CAAC,SAAS,QAAQ;AAAA,IAClB,CAAC,SAAS,QAAQ;AAAA,IAClB,CAAC,QAAQ,MAAM;AAAA,EACjB;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB;AACzC,UAAM,WAAW,WAAW,IAAI,GAAG;AACnC,QAAI,CAAC,YAAY,SAAS,SAAS,EAAG;AACtC,UAAM,QAAQ,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAC9D,UAAM,SAAS,CAAC,GAAG,SAAS,QAAQ,CAAC,EAClC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,GAAG,GAAG,QAAQ,UAAU,EAAE,CAAC,KAAK,KAAK,EAAE,EAC5D,KAAK,IAAI;AACZ,UAAM,KAAK,OAAO,KAAK,OAAO,KAAK,QAAQ,UAAU,IAAI,KAAK,GAAG,KAAK,MAAM,GAAG;AAAA,EACjF;AAEA,QAAM,KAAK,iBAAiB,UAAU,EAAE;AAExC,MAAI,eAAe,KAAK,eAAe,GAAG;AACxC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,2BAA2B;AACtC,QAAI,eAAe,EAAG,OAAM,KAAK,KAAK,YAAY,QAAQ,iBAAiB,IAAI,MAAM,KAAK,UAAU;AACpG,QAAI,eAAe,EAAG,OAAM,KAAK,KAAK,YAAY,QAAQ,iBAAiB,IAAI,MAAM,KAAK,UAAU;AAAA,EACtG;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAwBO,SAAS,0BACd,SACA,iBACiB;AACjB,MAAI,aAAa;AACjB,MAAI,gBAAgB;AACpB,MAAI,cAAc;AAClB,QAAM,UAAU,oBAAI,IAAiC;AAErD,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC,EAAE,kBAAkB,QAAQ,CAAC,EAAE,cAAc;AACnE,UAAMC,UAAS,gBAAgB,CAAC;AAEhC,QAAI,CAACA,SAAQ,YAAY;AACvB;AACA;AAAA,IACF;AAEA,QAAIA,QAAO,eAAe,MAAM;AAC9B;AAAA,IACF,OAAO;AACL;AACA,UAAI,CAAC,QAAQ,IAAI,IAAI,EAAG,SAAQ,IAAI,MAAM,oBAAI,IAAI,CAAC;AACnD,YAAM,cAAc,QAAQ,IAAI,IAAI;AACpC,kBAAY,IAAIA,QAAO,aAAa,YAAY,IAAIA,QAAO,UAAU,KAAK,KAAK,CAAC;AAAA,IAClF;AAAA,EACF;AAEA,QAAM,cAAc,aAAa;AACjC,QAAM,gBAAgB,cAAc,IAAI,KAAK,MAAO,aAAa,cAAe,GAAG,IAAI;AAEvF,QAAM,QAAQ,CAAC,GAAG,QAAQ,QAAQ,CAAC,EAChC,IAAI,CAAC,CAAC,YAAY,WAAW,MAAM;AAClC,UAAM,QAAQ,CAAC,GAAG,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AACjE,UAAM,eAAe,CAAC,GAAG,YAAY,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AAC7E,WAAO,EAAE,YAAY,OAAO,OAAO,qBAAqB,eAAe,CAAC,KAAK,UAAU;AAAA,EACzF,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,MAAM,GAAG,CAAC;AAEb,SAAO,EAAE,UAAU,QAAQ,QAAQ,YAAY,eAAe,aAAa,eAAe,MAAM;AAClG;AAEO,SAAS,qBAAqB,WAA4B,WAAW,GAAa;AACvF,QAAM,QAAkB,CAAC;AACzB,MAAI,UAAU,gBAAgB,GAAG;AAC/B,UAAM;AAAA,MACJ,GAAG,UAAU,aAAa,OAAO,UAAU,QAAQ,gCAAgC,UAAU,aAAa;AAAA,IAC5G;AACA,eAAW,QAAQ,UAAU,MAAM,MAAM,GAAG,QAAQ,GAAG;AACrD,YAAM,KAAK,OAAO,KAAK,UAAU,OAAO,KAAK,KAAK,4BAA4B,KAAK,mBAAmB,IAAI;AAAA,IAC5G;AAAA,EACF,WAAW,UAAU,WAAW,GAAG;AACjC,UAAM,KAAK,OAAO,UAAU,WAAW,UAAU,WAAW,qDAAqD,UAAU,WAAW,qBAAqB;AAAA,EAC7J;AACA,SAAO;AACT;AAEA,eAAe,0BAA2D;AACxE,MAAI;AACF,UAAM,aAAa,MAAM;AAAA,MACvB;AAAA,MACA,EAAE,QAAQ,CAAC,QAAQ,eAAe,gBAAgB,EAAE;AAAA,IACtD;AACA,QAAI,CAAC,cAAc,WAAW,WAAW,EAAG,QAAO;AASnD,UAAM,mBAAmB;AACzB,UAAM,gBAAgB,iBAAiB,IAAI,CAAC,OAAO;AAAA,MACjD,MAAM,EAAE,QAAQ;AAAA,MAChB,aAAa,OAAO,EAAE,gBAAgB,WAAW,EAAE,cAAc;AAAA,IACnE,EAAE;AACF,UAAM,kBAAkB,MAAM;AAAA,MAC5B;AAAA,MACA,EAAE,SAAS,cAAc;AAAA,IAC3B;AAEA,WAAO,0BAA0B,kBAAkB,eAAe;AAAA,EACpE,SAAS,KAAK;AACZ,YAAQ,OAAO,MAAM,yCAA0C,IAAc,OAAO;AAAA,CAAI;AACxF,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,oBAAoB;AACxC,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,SAAmB,CAAC;AAE1B,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,eAAe;AAAA,EACrC,SAAS,GAAY;AACnB,WAAO,KAAK,gCAAgC,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EAC1F;AAEA,MAAI,cAAyB,CAAC;AAC9B,MAAI;AACF,kBAAc,MAAM,YAAuB,uBAAuB;AAAA,EACpE,SAAS,GAAY;AACnB,WAAO,KAAK,4BAA4B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EACtF;AAEA,MAAI,eAAe;AACnB,MAAI,YAAY,SAAS,GAAG;AAC1B,QAAI;AACF,YAAM,UAAU,MAAM;AAAA,QACpB;AAAA,QACA,EAAE,QAAQ,CAAC,SAAS,EAAE;AAAA,MACxB;AACA,sBAAgB,WAAW,CAAC,GAAG;AAAA,IACjC,SAAS,GAAY;AACnB,aAAO,KAAK,uBAAuB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,IACjF;AAAA,EACF;AAEA,MAAI,QAAiE;AACrE,MAAI;AACF,YAAQ,MAAM,oBAAoB;AAAA,EACpC,QAAQ;AAAA,EAA+C;AAEvD,QAAM,aAAa,KAAK,IAAI,IAAI;AAChC,QAAM,UAAU,OAAO,WAAW;AAElC,QAAM,QAAQ;AAAA,IACZ,KAAK,UAAU,YAAY,UAAU;AAAA,IACrC;AAAA,IACA,kBAAkB,eAAe,YAAY;AAAA,IAC7C,uBAAuB,OAAO,iBAAiB,SAAS;AAAA,IACxD,uBAAuB,OAAO,iBAAiB,SAAS;AAAA,IACxD,oBAAoB,YAAY,MAAM;AAAA,IACtC,gBAAgB,YAAY;AAAA,IAC5B,gBAAgB,UAAU;AAAA,EAC5B;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,IAAI,WAAW;AAC1B,eAAW,OAAO,QAAQ;AACxB,YAAM,KAAK,KAAK,GAAG,EAAE;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,aAAa,YAAY;AAAA,IACzB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW,eAAe;AAAA,EAC5B;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,UAAU,YAAY,YAAY,MAAM,iBAAiB,YAAY,aAAa,UAAU,QAAQ,aAAa,OAAO,MAAM;AAAA,MAC9H;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,eAAe;AACnC,QAAM,MAAM,MAAM,oBAAoB;AACtC,QAAM,YAAY,kBAAkB;AACpC,QAAM,QAAQ,eAAe;AAC7B,QAAM,WAAW,kBAAkB;AACnC,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,qBAAqB,IAAI,WAAW;AAAA,IACpC,uBAAuB,IAAI,aAAa;AAAA,IACxC,uBAAuB,IAAI,aAAa;AAAA,EAC1C;AACA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,YAAY,IAAI,aAAa,KAAK,KAAK,MAAM,WAAW,cAAc,eAAe;AAAA,MACrF,EAAE,aAAa,IAAI,aAAa,eAAe,IAAI,eAAe,OAAO,WAAW,SAAS;AAAA,IAC/F;AAAA,EACF;AACF;AAEA,IAAM,eAAuC;AAAA,EAC3C,OAAW;AAAA,EACX,QAAW;AAAA,EACX,UAAW;AAAA,EACX,WAAW;AACb;AAEA,IAAM,qBAA6C;AAAA,EACjD,OAAW;AAAA,EACX,QAAW;AAAA,EACX,UAAW;AAAA,EACX,WAAW;AACb;AAEA,eAAsB,wBAAwB;AAC5C,QAAMA,UAAS,MAAM,YAAkE,0BAA0B;AAEjH,QAAM,EAAE,OAAO,aAAa,cAAc,QAAQ,MAAM,OAAO,eAAe,IAAIA;AAElF,QAAM,iBAA8BA,QAAO,kBAAkB;AAC7D,QAAM,QAAuDA,QAAO,SAAS;AAE7E,QAAM,aAAa,aAAa,KAAK,KAAK;AAC1C,QAAM,mBAAmB,mBAAmB,KAAK,KAAK;AACtD,QAAM,WAAW,SAAI,OAAO,KAAK,MAAM,QAAQ,EAAE,CAAC,IAAI,SAAI,OAAO,KAAK,KAAK,MAAM,QAAQ,EAAE,CAAC;AAE5F,QAAM,QAAQ;AAAA,IACZ,mBAAmB,UAAU;AAAA,IAC7B,IAAI,gBAAgB;AAAA,IACpB;AAAA,IACA,GAAG,QAAQ,IAAI,UAAU,SAAM,KAAK;AAAA,IACpC,mBAAmB,kBAAkB,MAAM,IAAI,kBAAkB,YAAY,SAAS,gCAAgC,EAAE;AAAA,IACxH;AAAA,IACA;AAAA,IACA,kBAAkB,MAAM,YAAY,KAAK,MAAM,WAAW,YAAY,MAAM,UAAU;AAAA,IACtF,oBAAoB,MAAM,cAAc;AAAA,IACxC,sBAAsB,MAAM,eAAe;AAAA,IAC3C,mBAAmB,MAAM,aAAa;AAAA,IACtC;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,KAAK,SAAS;AACpB,eAAW,OAAO,MAAM;AAEtB,YAAM,SAAS,IAAI,sBAAsB,IAAI;AAC7C,YAAM,KAAK,WAAW,IAAI,KAAK,IAAI;AACnC,YAAM,KAAK,MAAM,MAAM,GAAG;AAAA,IAC5B;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,MAAM;AAC5C,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,mBAAmB;AAC9B,eAAW,SAAS,QAAQ;AAC1B,YAAM,KAAK,SAAS,MAAM,KAAK,KAAK,MAAM,OAAO,IAAI,MAAM,QAAQ,GAAG;AAAA,IACxE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,YAAY,MAAM,wBAAwB;AAChD,MAAI,aAAa,UAAU,WAAW,GAAG;AACvC,UAAM,KAAK,wBAAwB;AACnC,UAAM,KAAK,GAAG,qBAAqB,SAAS,CAAC;AAC7C,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,aAAsC;AAAA,IAC1C;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,eAAe,MAAM;AAAA,IACrB,gBAAgB,MAAM;AAAA,IACtB,iBAAiB,MAAM;AAAA,IACvB,MAAM,KAAK,IAAI,CAAC,OAAO;AAAA,MACrB,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,UAAU,EAAE,sBAAsB,EAAE;AAAA,IACtC,EAAE;AAAA,IACF,GAAI,aAAa,EAAE,oBAAoB,UAAU;AAAA,EACnD;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,UAAU,UAAU,KAAK,KAAK,OAAO,MAAM,WAAW,oBAAoB,KAAK,MAAM;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsBC,aAAY,OAAe;AAG/C,QAAM,EAAE,KAAK,QAAQ,aAAa,UAAU,gBAAgB,IAAI,MAAM,qBAAqB,KAAK;AAGhG,MAAI,OAAO,WAAW,EAAG,QAAO,cAAc,sCAAsC,eAAe,IAAI,uCAAuC,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,YAAY,CAAC;AAEvL,QAAM,UAAU,oBAAoB,GAAG;AAEvC,QAAM,YAAY;AAAA,IAChB,YAAY,IAAI;AAAA,IAAQ;AAAA,IACxB,OAAO,OAAO,IAAI,CAAC,WAAW;AAAA,MAC5B,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,aAAa,UAAU,EAAE,QAAQ,MAAM,YAAY,OAAO;AAAA,MACpE,WAAW,MAAM;AAAA,MACjB,GAAI,MAAM,cAAc,QAAQ,EAAE,YAAY,MAAM,WAAW;AAAA,MAC/D,GAAI,MAAM,YAAY,QAAQ,EAAE,UAAU,MAAM,SAAS;AAAA,MAAI,GAAI,MAAM,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;AAAA,IAC1G,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,OAAO;AAAA;AAAA;AAAA;AAAA,EAAc,SAAS,KAAK,IAAI,CAAC,GAAG,eAAe,GAAG,CAAC;AAAA,IAC1G,mBAAmB;AAAA,MACjB,UAAU,IAAI,MAAM,8BAA8B,OAAO,MAAM;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,iBAAiB,CAAC,SAAS,UAAU,UAAU,SAAS,WAAW;AAGlE,IAAM,eAAeC,IAAE,OAAO;AAAA,EACnC,QAAQA,IAAE,KAAK,cAAc,EAAE;AAAA,IAC7B;AAAA,EACF;AAAA,EACA,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,EACnD,SAAS,mDAAmD;AACjE,CAAC;AAIM,IAAM,0BAA0BA,IAAE,OAAO;AAAA,EAC9C,SAASA,IAAE,QAAQ;AAAA,EACnB,aAAaA,IAAE,OAAO;AAAA,EACtB,SAASA,IAAE,OAAO;AAAA,EAClB,WAAWA,IAAE,OAAO;AAAA,EACpB,WAAWA,IAAE,OAAO;AACtB,CAAC;AAED,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EACxC,UAAUA,IAAE,OAAO;AAAA,EACnB,YAAYA,IAAE,OAAO;AAAA,EACrB,eAAeA,IAAE,OAAO;AAAA,EACxB,aAAaA,IAAE,OAAO;AAAA,EACtB,eAAeA,IAAE,OAAO;AAAA,EACxB,OAAOA,IAAE,MAAMA,IAAE,OAAO;AAAA,IACtB,YAAYA,IAAE,OAAO;AAAA,IACrB,OAAOA,IAAE,OAAO;AAAA,IAChB,qBAAqBA,IAAE,OAAO;AAAA,EAChC,CAAC,CAAC;AACJ,CAAC;AAEM,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EAC/C,OAAOA,IAAE,KAAK,CAAC,SAAS,UAAU,YAAY,WAAW,CAAC,EAAE,SAAS,EAAE,QAAQ,QAAQ;AAAA,EACvF,gBAAgBA,IAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EAC5D,gBAAgBA,IAAE,OAAO;AAAA,EACzB,eAAeA,IAAE,OAAO;AAAA,EACxB,gBAAgBA,IAAE,OAAO;AAAA,EACzB,iBAAiBA,IAAE,OAAO;AAAA,EAC1B,MAAMA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAIA,IAAE,OAAO,GAAG,OAAOA,IAAE,OAAO,GAAG,UAAUA,IAAE,OAAO,EAAE,CAAC,CAAC;AAAA,EACnF,oBAAoB,yBAAyB,SAAS;AACxD,CAAC;AAEM,IAAM,0BAA0BA,IAAE,OAAO;AAAA,EAC9C,YAAYA,IAAE,OAAO;AAAA,EACrB,OAAOA,IAAE,MAAMA,IAAE,OAAO;AAAA,IACtB,MAAMA,IAAE,OAAO;AAAA,IACf,QAAQA,IAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAWA,IAAE,OAAO;AAAA,IACpB,YAAYA,IAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC,CAAC;AACJ,CAAC;AAEM,IAAM,2BAA2BA,IAAE,OAAO;AAAA,EAC/C,aAAaA,IAAE,OAAO;AAAA,EACtB,eAAeA,IAAE,OAAO;AAAA,EACxB,OAAOA,IAAE,OAAO;AAAA,EAChB,WAAWA,IAAE,MAAM,CAACA,IAAE,OAAO,GAAGA,IAAE,KAAK,CAAC,CAAC;AAAA,EACzC,UAAUA,IAAE,QAAQ;AACtB,CAAC;AAEM,IAAM,uBAAuBA,IAAE,OAAO;AAAA,EAC3C,QAAQA,IAAE,OAAO;AAAA,EACjB,QAAQA,IAAE,OAAO;AAAA,EACjB,OAAOA,IAAE,OAAO;AAAA,EAChB,SAASA,IAAE,MAAMA,IAAE,OAAO;AAAA,IACxB,MAAMA,IAAE,OAAO;AAAA,IACf,OAAOA,IAAE,QAAQ;AAAA,IACjB,OAAOA,IAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,CAAC,CAAC;AACJ,CAAC;AAYM,SAAS,eAAe,QAAmB;AAChD,QAAM,WAAY,OAEf;AAEH,QAAM,UAAmE,CAAC;AAE1E,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,UAAM,SAAS,KAAK;AACpB,QAAI;AACF,UAAI,CAAC,UAAU,OAAO,OAAO,cAAc,YAAY;AACrD,gBAAQ,KAAK,EAAE,MAAM,MAAM,OAAO,OAAO,OAAO,mCAAmC,CAAC;AACpF;AAAA,MACF;AACA,YAAM,OAAO,OAAO,UAAU,CAAC,CAAC;AAEhC,UAAI,KAAK,WAAW,KAAK,OAAO;AAC9B,gBAAQ,KAAK,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC;AAAA,MAC1C;AAAA,IACF,SAAS,GAAY;AACnB,cAAQ,KAAK,EAAE,MAAM,MAAM,OAAO,OAAO,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAE,CAAC;AAAA,IAC9F;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;AAC9C,QAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE;AAC/C,QAAM,QAAQ,QAAQ;AAEtB,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA,eAAe,WAAW,IAAI,aAAa,GAAG,MAAM,SAAS;AAAA,IAC7D,0BAA0B,MAAM,IAAI,KAAK;AAAA,IACzC;AAAA,EACF;AAEA,MAAI,SAAS,GAAG;AACd,UAAM,KAAK,aAAa;AACxB,eAAW,KAAK,QAAQ,OAAO,CAACC,OAAM,CAACA,GAAE,KAAK,GAAG;AAC/C,YAAM,KAAK,OAAO,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE;AAAA,IAC1C;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,cAAc;AACzB,aAAW,KAAK,SAAS;AACvB,UAAM,KAAK,KAAK,EAAE,QAAQ,SAAS,MAAM,MAAM,EAAE,IAAI,IAAI;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,IAC3D,mBAAmB;AAAA,MACjB,WAAW,IAAI,kBAAkB,KAAK,oBAAoB,cAAc,MAAM,IAAI,KAAK;AAAA,MACvF,EAAE,QAAQ,QAAQ,OAAO,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;;;AEjjBA,SAAS,KAAAC,WAAS;AAIX,IAAM,qBAAqBC,IAAE,OAAO;AAAA,EACzC,YAAYA,IACT,OAAO,EACP,IAAI,CAAC,EACL,IAAI,EAAE,EACN,SAAS,EACT,SAAS,kDAAkD;AAChE,CAAC;AAOD,eAAsB,mBAAmB,YAAqB;AAC5D,QAAM,KAAK,MAAM,oBAAoB;AACrC,QAAM,YAAY,kBAAkB;AAEpC,QAAM,UAAU,MAAM,YAAmE,6BAA6B;AAAA,IACpH,YAAY,cAAc;AAAA,EAC5B,CAAC;AAED,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAkB;AAAA,IACtB,2BAAsB,GAAG,aAAa;AAAA,IACtC,gBAAgB,QAAQ,UAAU;AAAA,IAClC;AAAA,IACA,qBAAqB,QAAQ,aAAa,QAAQ,CAAC,CAAC,SAAS,QAAQ,aAAa;AAAA,IAClF,qBAAqB,QAAQ,YAAY,eAAe,CAAC,aAAa,QAAQ,aAAa,eAAe,CAAC,gBAAgB,QAAQ,gBAAgB,eAAe,CAAC;AAAA,IACnK,wBAAwB,QAAQ,eAAe,KAAK,QAAQ,CAAC,CAAC;AAAA,EAChE;AAEA,MAAI,QAAQ,eAAe,SAAS,GAAG;AACrC,UAAM,KAAK,IAAI,qBAAqB;AACpC,eAAW,KAAK,QAAQ,gBAAgB;AACtC,YAAM,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,QAAQ,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,YAAY;AAAA,IAClF;AAAA,EACF;AAEA,MAAI,QAAQ,iBAAiB,SAAS,GAAG;AACvC,UAAM,KAAK,IAAI,uBAAuB;AACtC,eAAW,KAAK,QAAQ,kBAAkB;AACxC,YAAM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,QAAQ,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,YAAY;AAAA,IACpF;AAAA,EACF;AAEA,MAAI,WAAW;AACb,UAAM,KAAK,IAAI,2BAA2B,SAAS,GAAG;AAAA,EACxD;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,MAAM,KAAK,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,IACA,mBAAmB;AAAA,MACjB,aAAa,GAAG,aAAa,MAAM,QAAQ,aAAa,QAAQ,CAAC,CAAC,SAAS,QAAQ,UAAU,UAAU,QAAQ,aAAa;AAAA,MAC5H;AAAA,QACE,YAAY,QAAQ;AAAA,QACpB,aAAa,QAAQ;AAAA,QACrB,cAAc,QAAQ;AAAA,QACtB,eAAe,QAAQ;AAAA,QACvB,cAAc,QAAQ;AAAA,QACtB,gBAAgB,QAAQ;AAAA,QACxB,kBAAkB,QAAQ;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AACF;;;ACpEA,eAAsB,oBAAoBC,SAAuD;AAC/F,QAAM,YAAY,MAAM,YAAkE,4BAA4B;AAAA,IACpH,GAAIA,UAAS,EAAE,QAAAA,QAAO,IAAI,CAAC;AAAA,EAC7B,CAAC;AAED,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,cAAcA,WAAU;AAC9B,WAAO;AAAA,MACL,MAAM,WAAW;AAAA,MACjB,MAAM,WAAW;AAAA,MACjB,EAAE,WAAW,CAAC,GAAG,OAAO,EAAE;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,QAAkB,CAAC,uBAAuB,EAAE;AAElD,aAAW,KAAK,WAAW;AACzB,UAAM,UAAU,EAAE,YACd,YACA,EAAE,iBAAiB,IACjB,mBACA,GAAG,EAAE,cAAc;AAEzB,UAAM,KAAK,MAAM,EAAE,eAAe,WAAM,EAAE,eAAe,SAAS,EAAE;AACpE,UAAM,KAAK,eAAe,EAAE,GAAG,IAAI;AACnC,UAAM,KAAK,iBAAiB,EAAE,MAAM,KAAK,OAAO,GAAG;AACnD,UAAM,KAAK,oBAAoB,EAAE,iBAAiB,EAAE;AACpD,UAAM,KAAK,oBAAoB,EAAE,SAAS,EAAE;AAC5C,UAAM,KAAK,sBAAsB,EAAE,UAAU,EAAE;AAC/C,QAAI,EAAE,iBAAiB;AACrB,YAAM,KAAK,oBAAoB,EAAE,eAAe,EAAE;AAAA,IACpD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO;AAAA,IACL,MAAM,KAAK,IAAI;AAAA,IACf,SAAS,UAAU,MAAM;AAAA,IACzB,EAAE,WAAW,OAAO,UAAU,OAAO;AAAA,IACrC;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,aAAa;AAAA,QACb,YAAY,EAAE,QAAQ,oBAAoB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,uBAAuB;AAC3C,QAAMC,UAAS,MAAM,YAAuE,+BAA+B;AAE3H,SAAO;AAAA,IACLA,QAAO,UAAU,IACb,+BACA,GAAGA,QAAO,KAAK;AAAA,IACnB,GAAGA,QAAO,KAAK;AAAA,IACfA;AAAA,IACAA,QAAO,QAAQ,IACX,CAAC;AAAA,MACC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,YAAY,EAAE,QAAQ,iBAAiB;AAAA,IACzC,CAAC,IACD;AAAA,EACN;AACF;AAEA,eAAsB,uBAAuB,YAAoB,SAA+B,QAAiB;AAC/G,qBAAmB;AACnB,MAAI,YAAY,YAAY,CAAC,QAAQ;AACnC,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,UAAMA,UAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC7B;AAAA,IACF;AAEA,WAAO;AAAA,MACLA,QAAO;AAAA,MACPA,QAAO;AAAA,MACPA;AAAA,MACA;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY,EAAE,QAAQ,iBAAiB;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,KAAU;AACjB,UAAM,MAAM,KAAK,WAAW,OAAO,GAAG;AACtC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY,EAAE,QAAQ,iBAAiB;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AJnHA,IAAM,oBAAoB;AAAA,EACxB;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EAAS;AAAA,EACtC;AAAA,EAAS;AAAA,EAAkB;AAAA,EAAqB;AAClD;AAIO,IAAM,kBAAkBC,IAAE,OAAO;AAAA,EACtC,QAAQA,IAAE,KAAK,iBAAiB,EAAE;AAAA,IAChC;AAAA,EASF;AAAA,EACA,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,kEAAkE;AAAA,EACvH,YAAYA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,gEAAgE;AAAA,EAC1H,QAAQA,IAAE,KAAK,CAAC,QAAQ,YAAY,YAAY,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,EACzI,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,EAC3F,SAASA,IAAE,KAAK,CAAC,WAAW,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,EACxG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,4EAA4E;AAC/H,CAAC;AAGD,IAAM,wBAAwBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,EAAE,CAAC;AACrE,IAAM,yBAAyBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AACvE,IAAM,yBAAyBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,EAAE,CAAC;AACvE,IAAM,wBAAwBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;AAC9H,IAAM,2BAA2BA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,WAAW,EAAE,CAAC;AAC5E,IAAM,wBAAwBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,YAAYA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;AACvH,IAAM,gCAAgCA,IAAE,OAAO;AAAA,EAC7C,QAAQA,IAAE,QAAQ,gBAAgB;AAAA,EAClC,QAAQA,IAAE,KAAK,CAAC,QAAQ,YAAY,YAAY,SAAS,CAAC,EAAE,SAAS;AACvE,CAAC;AACD,IAAM,mCAAmCA,IAAE,OAAO;AAAA,EAChD,QAAQA,IAAE,QAAQ,mBAAmB;AAAA,EACrC,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EAC9B,SAASA,IAAE,KAAK,CAAC,WAAW,QAAQ,CAAC;AAAA,EACrC,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AACxC,CAAC;AACD,IAAM,iCAAiCA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,iBAAiB,EAAE,CAAC;AAEjF,IAAM,uBAAuBA,IAAE,mBAAmB,UAAU;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,yBAAmE;AAAA,EAC9E,OAAO,EAAE,QAAQ,CAAC,GAAG,aAAa,kCAAkC;AAAA,EACpE,QAAQ,EAAE,QAAQ,CAAC,GAAG,aAAa,+BAA+B;AAAA,EAClE,QAAQ,EAAE,QAAQ,CAAC,GAAG,aAAa,kCAAkC;AAAA,EACrE,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,aAAa,0CAA0C;AAAA,EACnF,aAAa,EAAE,QAAQ,CAAC,GAAG,aAAa,wCAAwC;AAAA,EAChF,OAAO,EAAE,QAAQ,CAAC,YAAY,GAAG,aAAa,+CAA+C;AAAA,EAC7F,kBAAkB,EAAE,QAAQ,CAAC,QAAQ,GAAG,aAAa,uCAAuC;AAAA,EAC5F,qBAAqB,EAAE,QAAQ,CAAC,cAAc,WAAW,QAAQ,GAAG,aAAa,0EAA0E;AAAA,EAC3J,mBAAmB,EAAE,QAAQ,CAAC,GAAG,aAAa,mCAAmC;AACnF;AAEO,SAAS,uBAAuB,QAAyB;AAE9D,QAAM,oBAAiF;AAAA,IACrF,OAAO,MAAM,kBAAkB;AAAA,IAC/B,QAAQ,MAAM,aAAa;AAAA,IAC3B,QAAQ,MAAM,sBAAsB;AAAA,IACpC,OAAO,CAAC,SAASC,aAAY,KAAK,SAAS,EAAE;AAAA,IAC7C,aAAa,MAAM,QAAQ,QAAQ,eAAe,MAAM,CAAC;AAAA,IACzD,OAAO,CAAC,SAAS,mBAAmB,KAAK,UAAU;AAAA,IACnD,kBAAkB,CAAC,SAAS,oBAAoB,KAAK,MAAM;AAAA,IAC3D,qBAAqB,CAAC,SAAS,uBAAuB,KAAK,YAAY,KAAK,SAAS,KAAK,MAAM;AAAA,IAChG,mBAAmB,MAAM,qBAAqB;AAAA,EAChD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAUF,aAAa;AAAA;AAAA,MAEb,aAAa,EAAE,cAAc,OAAO,gBAAgB,MAAM,eAAe,MAAM;AAAA,IACjF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,iBAAiB,IAAI;AAChD,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,aAAa,OAAO;AAAA,QAAG,MACvD,sBAAsB,aAAa,sBAAsB,OAAO,MAAM,wBAAwB,iBAAiB;AAAA,MACjH;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AKpIA,SAAS,KAAAC,WAAS;;;ACGX,IAAM,8BAA8B,CAAC,OAAO,YAAY,QAAQ,UAAU,OAAO;AAGjF,IAAM,4BAA4B,CAAC,OAAO,WAAW,WAAW,YAAY,aAAa,WAAW;AAWpG,IAAM,2BAA2B,0BAA0B;AAAA,EACjE,CAACC,YAA2CA,YAAW;AACxD;;;ADbA,IAAM,UAAU,CAAC,UAAU,QAAQ,SAAS,QAAQ,SAAS,QAAQ;AAErE,IAAM,WAAWC,IAAE,KAAK,2BAA2B;AAEnD,IAAM,SAASA,IAAE,KAAK,yBAAyB;AAW/C,IAAM,eAAeA,IAAE,KAAK,wBAA6E;AAQlG,IAAM,2BAA2B;AACxC,IAAM,YAAY,CAAC,UAA0B,IAAI,YAAY,EAAE,OAAO,KAAK,EAAE;AAC7E,IAAM,mBAAmB,CAAC,UAA2B,UAAU,KAAK,KAAK;AACzE,IAAM,mBAAmB,CAAC,WAAmB;AAAA,EAC3C,SAAS,GAAG,KAAK,iCAAiC,yBAAyB,eAAe,OAAO,CAAC;AACpG;AAGA,IAAM,wBAAwB;AAE9B,IAAM,yBAAyB;AAExB,IAAM,iBAAiBA,IAAE,OAAO;AAAA,EACrC,QAAQA,IAAE,KAAK,OAAO,EAAE,SAAS,oRAAqR;AAAA,EACtT,SAASA,IAAE,OAAO,EAAE,IAAI,GAAM,EAAE,SAAS,EAAE,SAAS,2FAA2F;AAAA,EAC/I,UAAU,SAAS,SAAS,EAAE,SAAS,kDAAkD;AAAA,EACzF,SAASA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,4EAA4E;AAAA,EAC/H,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC/E,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAC/E,YAAYA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,EACnG,aAAaA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,qDAAgD;AAAA,EACvH,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,sEAAsE;AAAA,EACtH,QAAQ,OAAO,SAAS,EAAE,SAAS,sIAAsI;AAAA,EACzK,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,+EAA+E;AAAA,EAClJ,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,kKAA6J;AAAA,EAClN,OAAOA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4EAA4E;AAAA,EAClH,QAAQA,IAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2IAAsI;AAAA,EAC7K,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,EAC5G,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,yGAAyG;AAAA,EAC3J,MAAMA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4EAA4E,sBAAsB,GAAG;AAC7I,CAAC;AAED,IAAM,QAAQA,IAAE,mBAAmB,UAAU;AAAA,EAC3CA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAM,EAAE,OAAO,kBAAkB,iBAAiB,SAAS,CAAC,GAAG,UAAU,SAAS,SAAS,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,GAAG,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;AAAA,EAC/RA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,GAAG,QAAQ,OAAO,SAAS,GAAG,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,GAAG,MAAMA,IAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAAA,EAC7LA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,QAAQ,OAAO,SAAS,GAAG,UAAU,SAAS,SAAS,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,aAAaA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,OAAOA,IAAE,OAAO,EAAE,SAAS,GAAG,QAAQA,IAAE,OAAO,EAAE,SAAS,GAAG,OAAOA,IAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,SAAS,GAAG,MAAMA,IAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAAA,EACvXA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,GAAG,YAAYA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAK,EAAE,OAAO,kBAAkB,iBAAiB,MAAM,CAAC,EAAE,CAAC;AAAA,EAC9JA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,aAAaA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;AAAA,EACzJA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,GAAG,YAAYA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,GAAG,QAAQ,aAAa,CAAC;AACxG,CAAC;AAED,IAAM,QAAiD;AAAA,EACrD,QAAQ,EAAE,QAAQ,CAAC,WAAW,YAAY,WAAW,SAAS,QAAQ,GAAG,aAAa,mDAAmD;AAAA;AAAA,EAEzI,MAAM,EAAE,QAAQ,CAAC,UAAU,SAAS,UAAU,MAAM,GAAG,aAAa,kKAA6J;AAAA,EACjO,OAAO,EAAE,QAAQ,CAAC,UAAU,YAAY,WAAW,eAAe,SAAS,UAAU,SAAS,UAAU,MAAM,GAAG,aAAa,sKAAsK;AAAA,EACpS,MAAM,EAAE,QAAQ,CAAC,cAAc,MAAM,GAAG,aAAa,oCAAoC;AAAA,EACzF,OAAO,EAAE,QAAQ,CAAC,eAAe,SAAS,GAAG,aAAa,6DAA6D;AAAA,EACvH,QAAQ,EAAE,QAAQ,CAAC,cAAc,QAAQ,GAAG,aAAa,yFAAyF;AACpJ;AAEA,SAAS,OAAO,QAAwB,MAA2B;AACjE,QAAM,UAAU,WAAW,WAAW,wBAAwB,YAAY,MAAM;AAChF,SAAO,EAAE,SAAS,YAAY,GAAG,OAAO;AAAA,EAAK,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC,EAAE,GAAG,mBAAmB,QAAQ,SAAS,EAAE,QAAQ,QAAQ,KAAK,CAAC,EAAE;AAC/I;AAWA,SAAS,YAAY,MAA2B;AAC9C,QAAM,OAAQ,MAAuC;AACrD,MAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,QAAO,OAAO,SAAS,IAAI;AACrD,QAAM,UAAU;AAChB,QAAM,SAAS,QAAQ,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI;AACvD,QAAM,UAAU,QAAQ,SAAS,OAAO;AACxC,QAAM,cAAc,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,cAAc,SAAS,KAAK,IAAI,SAAS,eAAe,EAAE;AAC3G,MAAI,QAAQ,SAAS,KAAK,YAAY,GAAG;AACvC,UAAM,UAAU,iCAAiC,OAAO,MAAM;AAC9D,WAAO;AAAA,MACL,GAAG,OAAO;AAAA,EAAK,YAAY,KAAK,IAAI,CAAC;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,EAAE,QAAQ,SAAS,QAAQ;AAAA,IAC7B;AAAA,EACF;AACA,QAAM,UAAU,OAAO,WAAW,IAC9B,mBAAmB,OAAO,cAC1B,mBAAmB,OAAO,aAAa,OAAO,MAAM;AACxD,QAAM,OAAO,OAAO,WAAW,IAC3B,GAAG,OAAO;AAAA,EAAK,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC,KAC5C,GAAG,OAAO;AAAA;AAAA,EAAmB,YAAY,KAAK,IAAI,CAAC;AAAA,EAAK,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AACzF,SAAO,EAAE,SAAS,YAAY,IAAI,GAAG,mBAAmB,QAAQ,SAAS,EAAE,QAAQ,SAAS,QAAQ,KAAK,CAAC,EAAE;AAC9G;AAKA,SAAS,kBAAkB,KAAgC;AACzD,MAAI,MAAM,QAAQ,GAAG,EAAG,QAAO,EAAE,OAAO,KAAK,gBAAgB,MAAM,QAAQ,KAAK;AAChF,QAAM,OAAQ,OAAO,CAAC;AACtB,SAAO;AAAA,IACL,OAAO,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AAAA,IACjD,gBAAgB,OAAO,KAAK,mBAAmB,WAAW,KAAK,iBAAiB;AAAA,IAChF,QAAQ,KAAK,WAAW;AAAA,EAC1B;AACF;AAQA,SAAS,kBAAkB,OAAkB,MAA0B;AACrE,MAAI,KAAM,QAAO;AACjB,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,QAAI,SAAS,QAAQ,OAAO,SAAS,SAAU,QAAO;AACtD,UAAM,MAAM;AACZ,QAAI,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,UAAU,sBAAuB,QAAO;AAC3F,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,qBAAqB,CAAC,sBAAiB,IAAI,QAAQ,MAAM;AAAA,IAC5F;AAAA,EACF,CAAC;AACH;AAEA,SAAS,yBAAiC;AAMxC,4BAA0B;AAC1B,QAAM,YAAY,kBAAkB;AACpC,MAAI,CAAC,UAAW,OAAM,IAAI,MAAM,6CAA6C;AAC7E,SAAO;AACT;AAEO,SAAS,qBAAqB,QAAyB;AAC5D,QAAM,WAAuE;AAAA,IAC3E,QAAQ,OAAO,SAAS;AACtB,YAAM,YAAY,kBAAkB;AACpC,aAAO,OAAO,UAAU,MAAM,WAAwD,mBAAmB;AAAA,QACvG,SAAS,KAAK;AAAA,QACd,UAAU,KAAK,YAAY;AAAA,QAC3B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,QACjC,SAAS,EAAE,SAAS,KAAK,SAAS,OAAO,KAAK,OAAO,QAAQ,KAAK,UAAU,MAAM;AAAA,MACpF,CAAC,CAAC;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA,IAIA,MAAM,OAAO,EAAE,QAAQ,SAAS,MAAM,QAAQ,GAAG,KAAK,MAAM;AAC1D,YAAM,WAAW,SAAS;AAC1B,UAAI,aAAa,KAAK,SAAS,MAAM,wBAAwB;AAC3D,cAAM,IAAI,MAAM,4EAA4E,sBAAsB,qEAAqE;AAAA,MACzL;AAGA,YAAM,OAAO,kBAAkB,MAAM,WAAW,oBAAoB;AAAA,QAClE,GAAG;AAAA,QAAM,QAAQ,UAAU;AAAA,MAC7B,CAAC,CAAC;AACF,aAAO,OAAO,QAAQ,EAAE,GAAG,MAAM,OAAO,kBAAkB,KAAK,OAAO,QAAQ,EAAE,CAAC;AAAA,IACnF;AAAA;AAAA;AAAA,IAGA,OAAO,OAAO,EAAE,QAAQ,SAAS,MAAM,QAAQ,SAAS,GAAG,KAAK,MAAM;AACpE,YAAM,WAAW,SAAS;AAC1B,UAAI,aAAa,KAAK,SAAS,MAAM,wBAAwB;AAC3D,cAAM,IAAI,MAAM,4EAA4E,sBAAsB,qEAAqE;AAAA,MACzL;AAGA,YAAM,OAAO,kBAAkB,MAAM,WAAW,iBAAiB;AAAA,QAC/D,GAAG;AAAA,QAAM,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,QAAI,QAAQ,UAAU;AAAA,QAAM,WAAW,uBAAuB;AAAA,MACpH,CAAC,CAAC;AACF,aAAO,OAAO,SAAS,EAAE,GAAG,MAAM,OAAO,kBAAkB,KAAK,OAAO,QAAQ,EAAE,CAAC;AAAA,IACpF;AAAA,IACA,MAAM,OAAO,EAAE,QAAQ,SAAS,GAAG,KAAK,MAAM,OAAO,QAAQ,MAAM,WAAW,iBAAiB,EAAE,GAAG,MAAM,WAAW,uBAAuB,EAAE,CAAC,CAAC;AAAA,IAChJ,OAAO,OAAO,EAAE,QAAQ,SAAS,GAAG,KAAK,MAAM,YAAY,MAAM,WAAuD,kBAAkB,EAAE,GAAG,MAAM,WAAW,uBAAuB,EAAE,CAAC,CAAC;AAAA,IAC3L,QAAQ,OAAO,EAAE,QAAQ,SAAS,GAAG,KAAK,MAAM,OAAO,UAAU,MAAM,WAAW,mBAAmB,EAAE,GAAG,MAAM,WAAW,uBAAuB,EAAE,CAAC,CAAC;AAAA,EACxJ;AAEA,SAAO,aAAa,YAAY;AAAA,IAC9B,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,EAAE,cAAc,OAAO,iBAAiB,MAAM,eAAe,MAAM;AAAA,EAClF,GAAG,YAAY,OAAO,SAAS;AAC7B,UAAM,SAAS,YAAY,gBAAgB,IAAI;AAC/C,QAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,WAAO,mBAAmB,EAAE,MAAM,YAAY,QAAQ,OAAO,KAAK,OAAO,GAAG,MAC1E,sBAAsB,YAAY,OAAO,OAAO,MAAM,OAAO,QAAQ,CAAC;AAAA,EAC1E,CAAC,CAAC;AACJ;;;AEtMA,SAAS,KAAAC,WAAS;AAMlB,IAAM,gBAAgB,CAAC,QAAQ,QAAQ,SAAS,SAAS;AAGzD,IAAM,oBAAoB,CAAC,WAAW,UAAU,aAAa,SAAS;AACtE,IAAM,gBAAgB,CAAC,iBAAiB,UAAU,YAAY,aAAa;AAuBpE,IAAM,cAAcC,IAAE,OAAO;AAAA,EAClC,QAAQA,IAAE,KAAK,aAAa,EAAE;AAAA,IAC5B;AAAA,EAIF;AAAA,EACA,aAAaA,IAAE,KAAK,iBAAiB,EAAE,SAAS,EAAE;AAAA,IAChD;AAAA,EACF;AAAA,EACA,SAASA,IAAE,KAAK,aAAa,EAAE,SAAS,EAAE;AAAA,IACxC;AAAA,EACF;AAAA,EACA,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,EACnG,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,EACnG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,gEAAgE;AACnH,CAAC;AAGD,IAAM,mBAAmBA,IAAE,OAAO;AAAA,EAChC,QAAQA,IAAE,QAAQ,MAAM;AAAA,EACxB,aAAaA,IAAE,KAAK,iBAAiB,EAAE,SAAS;AAAA,EAChD,SAASA,IAAE,KAAK,aAAa,EAAE,SAAS;AAAA,EACxC,OAAOA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAC7C,CAAC;AACD,IAAM,mBAAmBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,GAAG,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAC3F,IAAM,oBAAoBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,CAAC;AACtI,IAAM,sBAAsBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,SAAS,GAAG,OAAOA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,CAAC;AAEnI,IAAM,mBAAmBA,IAAE,mBAAmB,UAAU;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,IAAM,qBAA2D;AAAA,EACtE,MAAM,EAAE,QAAQ,CAAC,eAAe,WAAW,OAAO,GAAG,aAAa,sFAAsF;AAAA,EACxJ,MAAM,EAAE,QAAQ,CAAC,OAAO,GAAG,aAAa,qBAAqB;AAAA,EAC7D,OAAO,EAAE,QAAQ,CAAC,SAAS,QAAQ,GAAG,aAAa,yCAAyC;AAAA,EAC5F,SAAS,EAAE,QAAQ,CAAC,SAAS,QAAQ,GAAG,aAAa,yCAAyC;AAChG;AAEA,eAAsB,gBAAgB,aAAsB,SAAkB,OAAqC;AAQjH,QAAM,iBAAiB,gBAAgB,UAAa,YAAY;AAChE,QAAM,uBAAuB,gBAAgB,iBAAiB,YAAY;AAC1E,QAAM,mBAAmB,YAAY,iBAAiB,aAAa;AAQnE,QAAM,cAAc,MAAM,eAAe;AACzC,QAAM,WAAW,MAAM,mBAAwC,yBAAyB;AAAA,IACtF,GAAI,uBAAuB,EAAE,aAAa,qBAAqB,IAAI,CAAC;AAAA,IACpE,GAAI,mBAAmB,EAAE,SAAS,iBAAiB,IAAI,CAAC;AAAA,IACxD,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB;AAAA,EACF,CAAC;AACD,QAAM,QAAQ,SAAS;AACvB,QAAM,YAAY,QAAS,SAAS,OAA+C,SAAS;AAC5F,QAAM,iBAAiB;AAEvB,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL,YAAY;AAAA;AAAA,EAAiC,cAAc,KAAK;AAAA,MAChE,YAAY,sFAAiF;AAAA,MAC7F,EAAE,OAAO,CAAC,GAAG,OAAO,GAAG,UAAU;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,QAAQ,CAAC,sBAAsB,EAAE;AACvC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,YAAY,iBAAiB,KAAK,oBAAoB,eAAe,KAAK,iBAAiB,MAAM,KAAK;AAC3H,UAAM,KAAK,OAAO,KAAK,EAAE,aAAQ,KAAK,cAAc,SAAM,OAAO,qBAAkB,KAAK,WAAW,SAAM,KAAK,MAAM,EAAE;AAAA,EACxH;AACA,MAAI,UAAW,OAAM,KAAK,IAAI,cAAc;AAM5C,SAAO;AAAA,IACL,MAAM,KAAK,IAAI;AAAA,IACf,SAAS,MAAM,MAAM,iBAAiB,MAAM,WAAW,IAAI,MAAM,KAAK,IAAI,YAAY,0DAAqD,EAAE;AAAA,IAC7I,EAAE,OAAO,OAAO,MAAM,QAAQ,UAAU;AAAA,IACxC,CAAC,EAAE,MAAM,SAAS,aAAa,6BAA6B,YAAY,EAAE,QAAQ,QAAQ,OAAO,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;AAAA,EAClH;AACF;AAQA,SAAS,wBAAwB,MAAiC;AAChE,QAAM,QAAQ;AAAA,IACZ,KAAK,KAAK,EAAE;AAAA,IACZ,cAAc,KAAK,cAAc,KAAK,KAAK,cAAc;AAAA,IACzD,cAAc,KAAK,OAAO;AAAA,IAC1B,kBAAkB,KAAK,WAAW;AAAA,IAClC,aAAa,KAAK,MAAM;AAAA,EAC1B;AACA,MAAI,KAAK,eAAe,QAAQ;AAC9B,UAAM,KAAK,IAAI,mBAAmB,KAAK,cAAc,MAAM,YAAY;AACvE,SAAK,cAAc,QAAQ,CAAC,MAAM,QAAQ;AACxC,YAAM,KAAK,MAAM,GAAG,KAAK,KAAK,KAAK,WAAM,KAAK,OAAO,EAAE;AACvD,YAAM,KAAK,UAAU,KAAK,WAAW,GAAG;AACxC,UAAI,KAAK,oBAAqB,OAAM,KAAK,+BAA+B,KAAK,mBAAmB,EAAE;AAAA,IACpG,CAAC;AAAA,EACH;AACA,MAAI,KAAK,eAAe,QAAQ;AAC9B,UAAM,KAAK,IAAI,iBAAiB;AAChC,eAAW,QAAQ,KAAK,eAAe;AACrC,YAAM,OAAO,KAAK,YAAY,KAAK,aAAa,IAAI,KAAK,OAAO;AAChE,YAAM,KAAK,KAAK,IAAI,MAAM,KAAK,QAAQ,QAAQ,KAAK,KAAK,GAAG;AAAA,IAC9D;AAAA,EACF;AACA,MAAI,KAAK,kBAAmB,OAAM,KAAK,IAAI,yBAAyB,KAAK,iBAAiB,EAAE;AAC5F,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAsB,gBAAgB,OAAoC;AACxE,QAAM,OAAO,MAAM,YAAsC,2BAA2B,EAAE,MAAM,CAAC;AAC7F,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL,aAAa,KAAK;AAAA,MAClB;AAAA,MACA,aAAa,KAAK;AAAA,MAClB;AAAA,MACA,CAAC,EAAE,MAAM,SAAS,aAAa,mBAAmB,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC;AAAA,IACpF;AAAA,EACF;AACA,SAAO;AAAA,IACL,wBAAwB,IAAI;AAAA,IAC5B,YAAY,KAAK,EAAE,KAAK,KAAK,OAAO,iBAAiB,KAAK,WAAW;AAAA,IACrE;AAAA,EACF;AACF;AAEA,eAAsB,uBACpB,aACA,OACA,QACqB;AACrB,qBAAmB;AACnB,MAAI;AACF,UAAMC,UAAS,MAAM,eAAmC,kCAAkC;AAAA,MACxF;AAAA,MACA;AAAA,MACA,GAAI,SAAS,EAAE,mBAAmB,OAAO,IAAI,CAAC;AAAA,IAChD,CAAC;AACD,WAAO;AAAA,MACL,YAAYA,QAAO,KAAK,mBAAmBA,QAAO,WAAW;AAAA,MAC7D,2BAA2BA,QAAO,WAAW;AAAA,MAC7CA;AAAA,IACF;AAAA,EACF,SAAS,KAAc;AAMrB,UAAM,aAAa,cAAc,GAAG;AAMpC,UAAM,aAAa,WAAW,SAAS;AACvC,WAAO;AAAA,MACL,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,MACX,aACI,uCACC,WAAW,YAAY;AAAA,MAC5B,aACI,CAAC,EAAE,MAAM,SAAS,aAAa,mBAAmB,YAAY,EAAE,QAAQ,OAAO,EAAE,CAAC,IACjF,WAAW,oBAAoB,CAAC,EAAE,MAAM,SAAS,aAAa,qBAAqB,YAAY,EAAE,QAAQ,QAAQ,MAAM,EAAE,CAAC;AAAA,MAC/H,WAAW;AAAA,IACb;AAAA,EACF;AACF;AAEO,SAAS,mBAAmB,QAAyB;AAE1D,QAAM,gBAAyE;AAAA,IAC7E,MAAM,CAAC,SAAS,gBAAgB,KAAK,aAAa,KAAK,SAAS,KAAK,KAAK;AAAA,IAC1E,MAAM,CAAC,SAAS,gBAAgB,KAAK,KAAK;AAAA,IAC1C,OAAO,CAAC,SAAS,uBAAuB,UAAU,KAAK,OAAO,KAAK,MAAM;AAAA,IACzE,SAAS,CAAC,SAAS,uBAAuB,aAAa,KAAK,OAAO,KAAK,MAAM;AAAA,EAChF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAKF,aAAa;AAAA;AAAA;AAAA,MAGb,aAAa,EAAE,cAAc,OAAO,gBAAgB,OAAO,eAAe,MAAM;AAAA,IAClF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,aAAa,IAAI;AAC5C,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,SAAS,OAAO;AAAA,QAAG,MACnD,sBAAsB,SAAS,kBAAkB,OAAO,MAAM,oBAAoB,aAAa;AAAA,MACjG;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACvQA,SAAS,KAAAC,WAAS;;;ACLlB,IAAMC,uBAAsB;AAErB,SAAS,kBAAkB,KAAqB;AACrD,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,IAAI,QAAQA,sBAAqB,EAAE;AAC5C;;;ADSA,IAAM,mBAAmB,CAAC,UAAU,SAAS,UAAU,UAAU,WAAW,UAAU,eAAe,MAAM;AAIpG,IAAM,iBAAiBC,IAAE,OAAO;AAAA,EACrC,QAAQA,IAAE,KAAK,gBAAgB,EAAE;AAAA,IAC/B;AAAA,EAQF;AAAA,EACA,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gHAAgH;AAAA,EACjK,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,iHAAiH;AAAA,EAChK,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gFAAgF;AAAA,EAChI,QAAQA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,qEAAqE;AAAA,EACtI,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,yEAAyE;AAAA,EACzH,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,EACxG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,EAC5F,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,uGAAuG;AAAA,EAC9J,MAAMA,IAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mHAAmH;AAC3J,CAAC;AAGD,IAAM,gBAAgBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,QAAQA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;AAClM,IAAM,eAAeA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,OAAO,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,QAAQA,IAAE,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;AAC3L,IAAM,gBAAgBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,GAAG,UAAUA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;AAC9K,IAAM,gBAAgBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC;AAC5F,IAAM,iBAAiBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,SAAS,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,CAAC;AASnI,IAAM,gBAAgBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,QAAQ,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,MAAMA,IAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,GAAG,eAAeA,IAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;AAClL,IAAM,oBAAoBA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,aAAa,GAAG,SAASA,IAAE,OAAO,EAAE,IAAI,GAAG,GAAG,QAAQA,IAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,CAAC;AAC1I,IAAM,cAAcA,IAAE,OAAO,EAAE,QAAQA,IAAE,QAAQ,MAAM,GAAG,MAAMA,IAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAEjF,IAAM,sBAAsBA,IAAE,mBAAmB,UAAU;AAAA,EAChE;AAAA,EAAe;AAAA,EAAc;AAAA,EAAe;AAAA,EAAe;AAAA,EAAgB;AAAA,EAAe;AAAA,EAAmB;AAC/G,CAAC;AAEM,IAAM,wBAAiE;AAAA,EAC5E,QAAQ,EAAE,QAAQ,CAAC,QAAQ,UAAU,QAAQ,GAAG,aAAa,gDAAgD;AAAA,EAC7G,OAAO,EAAE,QAAQ,CAAC,WAAW,UAAU,QAAQ,GAAG,aAAa,kFAAkF;AAAA,EACjJ,QAAQ,EAAE,QAAQ,CAAC,WAAW,UAAU,UAAU,GAAG,aAAa,6FAA6F;AAAA,EAC/J,QAAQ,EAAE,QAAQ,CAAC,SAAS,GAAG,aAAa,uBAAuB;AAAA,EACnE,SAAS,EAAE,QAAQ,CAAC,WAAW,QAAQ,GAAG,aAAa,wCAAwC;AAAA,EAC/F,QAAQ,EAAE,QAAQ,CAAC,WAAW,QAAQ,eAAe,GAAG,aAAa,oEAAoE;AAAA,EACzI,eAAe,EAAE,QAAQ,CAAC,WAAW,QAAQ,GAAG,aAAa,wCAAwC;AAAA,EACrG,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,aAAa,+FAA0F;AACnI;AAOA,IAAM,mBAAmB;AAEzB,eAAe,gBAAgB,KAAa,OAAgC;AAC1E,MAAI,CAAC,iBAAiB,KAAK,GAAG,EAAG,QAAO;AACxC,QAAM,QAAQ,MAAM,YAAoC,kBAAkB,EAAE,SAAS,IAAI,CAAC;AAC1F,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,GAAG,KAAK,KAAK,GAAG,cAAc;AAC1D,SAAO,MAAM;AACf;AAQA,eAAe,YAAY,IAAqD;AAC9E,MAAI,CAAC,GAAI,QAAO;AAChB,MAAI;AACF,UAAM,QAAQ,MAAM,YAAsC,kBAAkB,EAAE,GAAG,CAAC;AAIlF,WAAO,OAAO,OAAO,kBAAkB,MAAM,IAAI,IAAI;AAAA,EACvD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,aAAgC;AACxD,MAAI,CAAC,YAAa,QAAO;AACzB,SAAO,YAAY,SAAS,IAAI,+BAA+B,YAAY,KAAK,IAAI,CAAC,MAAM;AAC7F;AAeA,eAAe,8BAA8BC,SAA2B,SAAmC;AACzG,QAAM,OAAO,UAAU,GAAGA,QAAO,OAAO,+BAA+B;AACvE,MAAI;AACJ,MAAIA,QAAO,WAAW,YAAY;AAChC,UAAM,WAAY,MAAM,YAAYA,QAAO,eAAe,KAAMA,QAAO;AACvE,WAAO,UAAU,GAAG,IAAI,iBAAiB,QAAQ,MAAM,GAAG,IAAI,iBAAiB,QAAQ,sCAAsCA,QAAO,OAAO;AAAA,EAC7I,OAAO;AACL,UAAM,WAAY,MAAM,YAAYA,QAAO,WAAW,KAAMA,QAAO;AACnE,WAAO,UACH,GAAGA,QAAO,OAAO,+EAA+E,QAAQ,MACxG,sEAAsE,QAAQ;AAAA,EACpF;AACA,QAAM,aAAa;AACnB,QAAM,QAAQA,QAAO,QAAQ,IAAIA,QAAO,KAAK,KAAK;AAClD,SAAO,GAAG,IAAI,GAAG,iBAAiBA,QAAO,WAAW,CAAC,GAAG,UAAU,GAAG,KAAK;AAC5E;AAEA,eAAsB,qBAAqB,MAAc,QAAiB,QAAwC;AAChH,qBAAmB;AACnB,MAAI;AACF,UAAM,iBAAiB,SAAS,MAAM,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC,CAAC,IAAI;AAC5G,UAAMA,UAAS,MAAM,eAAkC,mBAAmB,EAAE,MAAM,YAAY,QAAQ,QAAQ,eAAe,CAAC;AAC9H,UAAM,UAAU,MAAM,8BAA8BA,SAAQ,KAAK;AAKjE,UAAM,OAAOA,QAAO,WAAW,aAC3B,CAAC,EAAE,MAAM,YAAY,aAAa,sCAAsC,YAAY,EAAE,QAAQ,UAAU,SAASA,QAAO,QAAQ,EAAE,CAAC,IACnI;AACJ,WAAO,cAAc,SAAS,SAASA,SAAQ,IAAI;AAAA,EACrD,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,UAAU,EAAE,MAAM,QAAQ,OAAO,CAAC;AAAA,EACpE;AACF;AAEA,eAAsB,oBAAoB,SAAiB,QAAiB,QAAwC;AAClH,qBAAmB;AACnB,MAAI;AACF,UAAM,kBAAkB,MAAM,gBAAgB,SAAS,OAAO;AAC9D,UAAM,iBAAiB,SAAS,MAAM,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC,CAAC,IAAI;AAC5G,UAAMA,UAAS,MAAM,eAAkC,kBAAkB,EAAE,SAAS,iBAAiB,YAAY,QAAQ,QAAQ,eAAe,CAAC;AACjJ,UAAM,UAAU,MAAM,8BAA8BA,SAAQ,IAAI;AAChE,WAAO,cAAc,SAAS,SAASA,OAAM;AAAA,EAC/C,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,SAAS,EAAE,SAAS,QAAQ,OAAO,CAAC;AAAA,EACtE;AACF;AAIA,eAAsB,qBAAqB,SAAiB,QAAiB,UAAwC;AACnH,qBAAmB;AACnB,MAAI;AACF,UAAM,kBAAkB,MAAM,gBAAgB,SAAS,OAAO;AAC9D,UAAM,mBAAmB,SAAS,MAAM,gBAAgB,QAAQ,MAAM,IAAI;AAC1E,UAAMA,UAAS,MAAM,eAA6B,mBAAmB,EAAE,SAAS,iBAAiB,UAAU,kBAAkB,YAAY,SAAS,CAAC;AACnJ,UAAM,aAAa,QAAQ,UAAU,QAAQ;AAC7C,QAAI;AACJ,QAAI,YAAY;AAQd,YAAM,MAAM,WAAY,kBAAkBA,QAAO,mBAAmB,EAAE,KAAKA,QAAO,iBAAiB,eAAkB,MAAM,YAAYA,QAAO,WAAW,KAAMA,QAAO,eAAe;AACrL,gBAAU,GAAG,OAAO,kBAAkB,GAAG;AAAA,IAC3C,OAAO;AACL,gBAAU,GAAG,OAAO;AAAA,IACtB;AACA,WAAO,cAAc,SAAS,SAASA,OAAM;AAAA,EAC/C,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,UAAU,EAAE,SAAS,QAAQ,SAAS,CAAC;AAAA,EACzE;AACF;AAIA,eAAsB,qBAAqB,SAAsC;AAC/E,qBAAmB;AACnB,MAAI;AACF,UAAM,kBAAkB,MAAM,gBAAgB,SAAS,OAAO;AAC9D,UAAMA,UAAS,MAAM,eAA6B,mBAAmB,EAAE,SAAS,gBAAgB,CAAC;AACjG,QAAI;AACJ,QAAIA,QAAO,aAAa;AACtB,gBAAU,iBAAiB,IAAI,KAAKA,QAAO,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,KAAKA,QAAO,eAAe,GAAG;AAAA,IAClH,WAAWA,QAAO,WAAW,aAAa;AACxC,YAAM,WAAY,MAAM,YAAYA,QAAO,WAAW,KAAM;AAC5D,gBAAU,+EAA0E,QAAQ;AAAA,IAC9F,OAAO;AACL,gBAAU;AAAA,IACZ;AACA,WAAO,cAAc,SAAS,SAASA,OAAM;AAAA,EAC/C,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,EACvD;AACF;AAIA,eAAsB,sBAAsB,SAAiB,QAAqC;AAChG,qBAAmB;AACnB,MAAI;AACF,UAAM,kBAAkB,MAAM,gBAAgB,SAAS,OAAO;AAC9D,UAAMA,UAAS,MAAM,eAA8B,oBAAoB,EAAE,SAAS,iBAAiB,OAAO,CAAC;AAI3G,QAAI;AACJ,QAAIA,QAAO,WAAW,aAAa;AACjC,gBAAU;AAAA,IACZ,WAAWA,QAAO,WAAW,MAAM;AACjC,gBAAU,uBAAkBA,QAAO,mBAAmB,CAAC;AAAA,IACzD,WAAWA,QAAO,WAAW,OAAO;AAClC,YAAM,WAAY,MAAM,YAAYA,QAAO,WAAW,KAAMA,QAAO;AACnE,gBAAU,6BAA6B,QAAQ;AAAA,IACjD,WAAWA,QAAO,iBAAiB;AACjC,YAAM,WAAY,MAAM,YAAYA,QAAO,eAAe,KAAMA,QAAO;AACvE,gBAAU,WAAW,OAAO,wBAAwB,QAAQ;AAAA,IAC9D,WAAWA,QAAO,aAAa;AAC7B,YAAM,WAAY,MAAM,YAAYA,QAAO,WAAW,KAAMA,QAAO;AACnE,gBAAU,yDAAyD,QAAQ;AAAA,IAC7E,OAAO;AACL,gBAAU;AAAA,IACZ;AACA,WAAO,cAAc,SAAS,SAASA,OAAM;AAAA,EAC/C,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,WAAW,EAAE,SAAS,OAAO,CAAC;AAAA,EAChE;AACF;AAIA,eAAsB,qBAAqB,SAAiB,MAAe,eAA6C;AAItH,MAAI,SAAS,UAAa,kBAAkB,QAAW;AACrD,WAAO,mBAAmB,YAAY,UAAU,sBAAsB,QAAQ,kEAAkE;AAAA,EAClJ;AACA,MAAI,SAAS,UAAa,kBAAkB,QAAW;AACrD,WAAO,mBAAmB,YAAY,UAAU,sBAAsB,QAAQ,8CAA8C;AAAA,EAC9H;AACA,qBAAmB;AACnB,MAAI;AACF,UAAM,kBAAkB,MAAM,gBAAgB,SAAS,OAAO;AAC9D,UAAM,wBAAwB,gBAAgB,MAAM,gBAAgB,eAAe,cAAc,IAAI;AACrG,UAAMA,UAAS,MAAM,eAA6B,mBAAmB,EAAE,SAAS,iBAAiB,MAAM,eAAe,sBAAsB,CAAC;AAO7I,UAAM,aAAaA,QAAO,YAAY,kBAAkBA,QAAO,SAAS,IAAI,OAAO;AACnF,UAAM,cAAcA,QAAO,gBAAgB,4CAA4C;AAUvF,UAAM,UAAUA,QAAO,aACnBA,QAAO,iBAAiB,cAAcA,QAAO,iBAAiB,iBAC5D,GAAG,OAAO,0BAA0BA,QAAO,iBAAiB,aAAa,aAAa,cAAc,wBACpG,GAAG,OAAO,2CACZ,aAAa,SAAS,gFAAgF,WAAW;AACrH,WAAO,cAAc,SAAS,SAASA,OAAM;AAAA,EAC/C,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,UAAU,EAAE,SAAS,MAAM,cAAc,CAAC;AAAA,EAC5E;AACF;AAIA,eAAsB,yBAAyB,SAAiB,QAAqC;AACnG,qBAAmB;AACnB,MAAI;AACF,UAAM,kBAAkB,MAAM,gBAAgB,SAAS,OAAO;AAC9D,UAAMA,UAAS,MAAM,eAAiC,uBAAuB,EAAE,SAAS,iBAAiB,OAAO,CAAC;AACjH,UAAM,UAAUA,QAAO,aAAa,GAAG,OAAO,yCAAoC;AAClF,WAAO,cAAc,SAAS,SAASA,OAAM;AAAA,EAC/C,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,eAAe,EAAE,SAAS,OAAO,CAAC;AAAA,EACpE;AACF;AAyBA,eAAsB,mBAAmB,MAAqC;AAC5E,MAAI;AACF,UAAMA,UAAS,MAAM,YAAwB,iBAAiB,EAAE,KAAK,CAAC;AACtE,UAAM,OAAOA,QAAO;AACpB,QAAI,KAAK,WAAW,GAAG;AACrB,YAAMC,WAAU,OAAO,yCAAyC;AAChE,aAAO,cAAcA,UAASA,UAAS,EAAE,GAAGD,SAAQ,QAAQ,OAAO,CAAC;AAAA,IACtE;AAMA,UAAM,QAAQ,KAAK,IAAI,CAAC,MAAM;AAC5B,YAAM,gBAAgB,QAAQ,EAAE,UAAU,WAAM,kBAAkB,EAAE,OAAO,CAAC,KAAK;AACjF,aAAO,IAAI,kBAAkB,EAAE,OAAO,CAAC,KAAK,kBAAkB,EAAE,QAAQ,CAAC,WAAM,kBAAkB,EAAE,UAAU,CAAC,WAAM,kBAAkB,EAAE,GAAG,CAAC,WAAM,kBAAkB,EAAE,MAAM,CAAC,WAAM,kBAAkB,EAAE,SAAS,CAAC,WAAM,EAAE,OAAO,IAAI,aAAa;AAAA,IACnP,CAAC;AAID,UAAM,iBAAiBA,QAAO,YAC1B;AAAA,GAAM,OAAO,sFAAiF,sEAAiE,MAC/J;AACJ,UAAM,UAAU,GAAG,KAAK,MAAM,YAAY,KAAK,WAAW,IAAI,KAAK,GAAG;AAAA,EAAM,MAAM,KAAK,IAAI,CAAC,GAAG,cAAc;AAC7G,WAAO,cAAc,SAAS,SAAS,EAAE,GAAGA,SAAQ,QAAQ,OAAO,CAAC;AAAA,EACtE,SAAS,KAAK;AACZ,WAAO,oBAAoB,KAAK,QAAQ,EAAE,KAAK,CAAC;AAAA,EAClD;AACF;AAIA,SAAS,oBAAoB,KAAc,QAAwB,SAAkC,CAAC,GAAe;AACnH,QAAM,aAAa,cAAc,GAAG;AAMpC,QAAM,gBAAgB,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,CAAC;AAOlG,QAAM,kBAAkB,WAAW,SAAS,qBACxC,SACA,CAAC,EAAE,MAAM,YAAY,aAAa,SAAS,MAAM,IAAI,YAAY,EAAE,QAAQ,GAAG,cAAc,EAAE,CAAC;AACnG,SAAO;AAAA,IACL,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW,YAAY;AAAA,IACvB,WAAW,oBAAoB;AAAA,IAC/B,WAAW;AAAA,EACb;AACF;AAEO,SAAS,sBAAsB,QAAyB;AAC7D,QAAM,mBAA+E;AAAA,IACnF,QAAQ,CAAC,SAAS,qBAAqB,KAAK,MAAM,KAAK,QAAQ,KAAK,MAAM;AAAA,IAC1E,OAAO,CAAC,SAAS,oBAAoB,KAAK,SAAS,KAAK,QAAQ,KAAK,MAAM;AAAA,IAC3E,QAAQ,CAAC,SAAS,qBAAqB,KAAK,SAAS,KAAK,QAAQ,KAAK,QAAQ;AAAA,IAC/E,QAAQ,CAAC,SAAS,qBAAqB,KAAK,OAAO;AAAA,IACnD,SAAS,CAAC,SAAS,sBAAsB,KAAK,SAAS,KAAK,MAAM;AAAA,IAClE,QAAQ,CAAC,SAAS,qBAAqB,KAAK,SAAS,KAAK,MAAM,KAAK,aAAa;AAAA,IAClF,eAAe,CAAC,SAAS,yBAAyB,KAAK,SAAS,KAAK,MAAM;AAAA,IAC3E,MAAM,CAAC,SAAS,mBAAmB,KAAK,IAAI;AAAA,EAC9C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAUF,aAAa;AAAA,MACb,aAAa,EAAE,cAAc,OAAO,gBAAgB,OAAO,eAAe,MAAM;AAAA,IAClF;AAAA,IACA,YAAY,OAAO,SAAS;AAC1B,YAAM,SAAS,YAAY,gBAAgB,IAAI;AAC/C,UAAI,CAAC,OAAO,GAAI,QAAO,OAAO;AAC9B,YAAM,EAAE,OAAO,IAAI,OAAO;AAE1B,aAAO;AAAA,QAAmB,EAAE,MAAM,YAAY,OAAO;AAAA,QAAG,MACtD,sBAAsB,YAAY,qBAAqB,OAAO,MAAM,uBAAuB,gBAAgB;AAAA,MAC7G;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AE1cA,SAAS,cAAAE,mBAAkB;AAC3B,SAAS,SAAS,MAAM,WAAAC,gBAAe;AACvC,SAAS,qBAAqB;AAC9B,SAAoB,wBAAwB;;;ACHrC,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ADiBhC,IAAM,aAAa,QAAQ,cAAc,YAAY,GAAG,CAAC;AACzD,IAAM,0BAA0B;AAAA,EAC9BC,SAAQ,YAAY,OAAO;AAAA,EAC3BA,SAAQ,YAAY,MAAM,OAAO;AAAA,EACjCA,SAAQ,YAAY,MAAM,MAAM,QAAQ,OAAO;AAAA,EAC/CA,SAAQ,YAAY,MAAM,MAAM,MAAM,aAAa,MAAM;AAC3D;AA8IA,SAAS,oBAAoB,OAA8B;AACzD,QAAM,KAAK,MAAM,UAAU,GAAG,MAAM,OAAO,OAAO;AAClD,QAAM,QAAQ,CAAC,MAAM,EAAE,GAAG,MAAM,IAAI,KAAK,MAAM,MAAM,GAAG;AACxD,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,UAAU;AAChD,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,IAAI,GAAG;AACnD,UAAI,OAAO,QAAQ,WAAW;AAC5B,cAAM,KAAK,KAAK,GAAG,OAAO,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,yBACP,aACA,gBACA,WACA,eACA,YACQ;AACR,QAAM,WAAqB,CAAC,oCAA+B;AAG3D,WAAS;AAAA,IACP;AAAA,EAgBF;AAGA,QAAM,UAAkF,CAAC;AAEzF,aAAW,MAAM,cAAc,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,YAAY,EAAE,WAAW,UAAU,GAAG;AAClG,YAAQ,KAAK,EAAE,IAAI,EAAE,WAAW,IAAI,MAAM,EAAE,MAAM,UAAW,EAAE,MAAM,YAAuB,QAAW,QAAQ,aAAa,CAAC;AAAA,EAC/H;AACA,aAAW,MAAM,aAAa,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,YAAY,EAAE,WAAW,UAAU,GAAG;AACjG,YAAQ,KAAK,EAAE,IAAI,EAAE,WAAW,IAAI,MAAM,EAAE,MAAM,UAAW,EAAE,MAAM,YAAuB,QAAW,QAAQ,YAAY,CAAC;AAAA,EAC9H;AACA,aAAW,MAAM,iBAAiB,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,YAAY,EAAE,WAAW,UAAU,GAAG;AACrG,YAAQ,KAAK,EAAE,IAAI,EAAE,WAAW,IAAI,MAAM,EAAE,MAAM,UAAW,EAAE,MAAM,YAAuB,QAAW,QAAQ,iBAAiB,CAAC;AAAA,EACnI;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,YAAY,QACf,IAAI,CAAC,MAAM;AACV,YAAM,MAAM,EAAE,WAAW,KAAK,EAAE,QAAQ,MAAM;AAC9C,aAAO,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,GAAG,GAAG;AAAA,IACvC,CAAC,EACA,KAAK,IAAI;AACZ,aAAS;AAAA,MACP,yCAAyC,QAAQ,MAAM;AAAA;AAAA;AAAA,IAGvD,YAAY;AAAA,IAEd;AAAA,EACF,OAAO;AACL,aAAS;AAAA,MACP;AAAA,IAIF;AAAA,EACF;AAGA,WAAS;AAAA,IACP;AAAA,EAWF;AAGA,WAAS;AAAA,IACP;AAAA,EAUF;AAGA,MAAI,aAAa;AACf,UAAM,WAAW,YACd,IAAI,CAAC,MAAM;AACV,YAAM,SAAS,EAAE,OAAO,GAAG,EAAE,IAAI,MAAM;AACvC,aAAO,KAAK,MAAM,KAAK,EAAE,IAAI,SAAS,EAAE,IAAI,cAAS,EAAE,eAAe,gBAAgB;AAAA,IACxF,CAAC,EACA,KAAK,IAAI;AACZ,aAAS;AAAA,MACP,kBAAkB,YAAY,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,IAIpC,WAAW;AAAA,IAEb;AAAA,EACF,OAAO;AACL,aAAS;AAAA,MACP;AAAA,IAEF;AAAA,EACF;AAGA,QAAM,aAAa,gBAAgB,GAAG,cAAc,MAAM,aAAa;AACvE,WAAS;AAAA,IACP;AAAA,kCACmC,UAAU;AAAA;AAAA;AAAA;AAAA,EAI/C;AAGA,QAAM,cAAc,iBAAiB,GAAG,eAAe,MAAM,YAAY;AACzE,QAAM,iBAAiB,YACnB,wGACA;AACJ,WAAS;AAAA,IACP;AAAA,iDACkD,WAAW;AAAA,EAC1D,cAAc;AAAA;AAAA;AAAA,EAGnB;AAGA,WAAS;AAAA,IACP;AAAA,EAiBF;AAGA,WAAS;AAAA,IACP;AAAA,EAeF;AAGA,WAAS;AAAA,IACP;AAAA,EAeF;AAEA,SAAO,SAAS,KAAK,aAAa;AACpC;AAEO,SAAS,kBAAkB,QAAmB;AAEnD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,SAAS;AAAA,MACd,UAAU,CAAC;AAAA,QACT,KAAK,IAAI;AAAA,QACT,MAAM;AAAA,QACN,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,CAAC,mBAAmB,cAAc,iBAAiB,aAAa,gBAAgB,IAAI,MAAM,QAAQ,WAAW;AAAA,QACjH,YAA0B,uBAAuB;AAAA,QACjD,YAA2D,qBAAqB,EAAE,gBAAgB,kBAAkB,CAAC;AAAA,QACrH,YAA2D,qBAAqB,EAAE,gBAAgB,YAAY,CAAC;AAAA,QAC/G,YAA2D,qBAAqB,EAAE,gBAAgB,iBAAiB,CAAC;AAAA,QACpH,YAA2D,qBAAqB,EAAE,gBAAgB,aAAa,CAAC;AAAA,MAClH,CAAC;AAED,YAAM,cAAc,kBAAkB,WAAW,cAAc,kBAAkB,QAAQ;AACzF,YAAM,iBAAiB,aAAa,WAAW,cAAc,aAAa,QAAQ;AAClF,YAAM,YAAY,gBAAgB,WAAW,cAAc,gBAAgB,QAAQ;AACnF,YAAM,gBAAgB,YAAY,WAAW,cAAc,YAAY,QAAQ;AAC/E,YAAM,aAAa,iBAAiB,WAAW,cAAc,iBAAiB,QAAQ;AAEtF,aAAO;AAAA,QACL,UAAU,CAAC;AAAA,UACT,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMT,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,CAAC,gBAAgB,eAAe,IAAI,MAAM,QAAQ,WAAW;AAAA,QACjE,YAA2D,qBAAqB,EAAE,gBAAgB,WAAW,CAAC;AAAA,QAC9G,YAA2D,qBAAqB,EAAE,gBAAgB,YAAY,CAAC;AAAA,MACjH,CAAC;AAED,YAAM,QAAkB,CAAC,oCAA+B;AAExD,UAAI,eAAe,WAAW,aAAa;AACzC,cAAM,WAAW,eAAe,SAAS,CAAC;AAC1C,YAAI,SAAS,SAAS,GAAG;AACvB,gBAAM,QAAQ,SACX,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,OAAO,EAAE,WAAW,QAAG,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,aAAa,EAAE,MAAM,eAAe,EAAE,EAAE,EACnH,KAAK,IAAI;AACZ,gBAAM,KAAK,gBAAgB,SAAS,MAAM;AAAA;AAAA,EAAc,KAAK,EAAE;AAAA,QACjE,OAAO;AACL,gBAAM,KAAK,8FAA8F;AAAA,QAC3G;AAAA,MACF,OAAO;AACL,cAAM,KAAK,iHAA4G;AAAA,MACzH;AAEA,UAAI,gBAAgB,WAAW,aAAa;AAC1C,cAAM,YAAY,gBAAgB,SAAS,CAAC;AAC5C,YAAI,UAAU,SAAS,GAAG;AACxB,gBAAM,OAAO,UACV,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,OAAO,EAAE,WAAW,QAAG,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,eAAe,EAAE,EAAE,EAC9F,KAAK,IAAI;AACZ,gBAAM,KAAK,iBAAiB,UAAU,MAAM;AAAA;AAAA,EAAgB,IAAI,EAAE;AAAA,QACpE,OAAO;AACL,gBAAM,KAAK,+FAA+F;AAAA,QAC5G;AAAA,MACF,OAAO;AACL,cAAM,KAAK,oHAA+G;AAAA,MAC5H;AAEA,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,MAAM,KAAK,aAAa,GAAG,UAAU,gBAAgB,CAAC;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,cAAe,MAAM,YAA0B,uBAAuB,KAAM,CAAC;AAEnF,UAAI,YAAY,WAAW,GAAG;AAC5B,eAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,8GAA8G,UAAU,gBAAgB,CAAC,EAAE;AAAA,MACxL;AAEA,YAAM,YAAY,YACf,IAAI,CAAC,MAAM;AACV,cAAM,aAAa,EAAE,UAAU,CAAC,GAC7B,IAAI,CAAC,MAAM,SAAS,EAAE,GAAG,OAAO,EAAE,IAAI,GAAG,EAAE,WAAW,eAAe,EAAE,GAAG,EAAE,aAAa,iBAAiB,EAAE,GAAG,EAC/G,KAAK,IAAI;AACZ,eAAO,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,IAAI;AAAA,EAAQ,EAAE,eAAe,EAAE;AAAA;AAAA;AAAA,EAAoB,SAAS;AAAA,MAC1G,CAAC,EACA,KAAK,aAAa;AAErB,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,4BAA4B,YAAY,MAAM;AAAA;AAAA,EAAQ,SAAS,IAAI,UAAU,gBAAgB,CAAC;AAAA,MAClI;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,iCAAiC;AAAA,MACpD,MAAM,YAAY;AAChB,cAAM,cAAe,MAAM,YAA0B,uBAAuB,KAAM,CAAC;AACnF,eAAO;AAAA,UACL,WAAW,YAAY,IAAI,CAAC,OAAO;AAAA,YACjC,KAAK,kBAAkB,EAAE,IAAI;AAAA,YAC7B,MAAM,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,KAAK;AAAA,UACzC,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACD,OAAO,KAAK,EAAE,KAAK,MAAM;AAEvB,YAAM,UAAY,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,KAAe,CAAC,KAAM,CAAC;AACjJ,YAAM,YAAY,QAAQ,IAAI,mBAAmB,EAAE,KAAK,aAAa;AAErE,aAAO;AAAA,QACL,UAAU,CAAC;AAAA,UACT,KAAK,IAAI;AAAA,UACT,MAAM,aAAa;AAAA,UACnB,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,SAAU,MAAM,YAA2B,kBAAkB,KAAM,CAAC;AAE1E,UAAI,OAAO,WAAW,GAAG;AACvB,eAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,gCAAgC,UAAU,gBAAgB,CAAC,EAAE;AAAA,MAC1G;AAEA,YAAM,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO;AAC7C,YAAM,YAAY,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE,QAAQ;AAChE,YAAM,WAAW,CAAC,aAAqB,OAAO,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AAEnF,YAAM,QAAkB,CAAC;AACzB,iBAAW,SAAS,QAAQ;AAC1B,cAAM,KAAK,MAAM,MAAM,IAAI,EAAE;AAC7B,mBAAW,SAAS,SAAS,MAAM,GAAG,GAAG;AACvC,gBAAM,KAAK,OAAO,MAAM,IAAI,MAAM,MAAM,IAAI,GAAG,MAAM,QAAQ,KAAK,MAAM,KAAK,MAAM,EAAE,EAAE;AAAA,QACzF;AAAA,MACF;AACA,UAAI,UAAU,SAAS,GAAG;AACxB,cAAM,KAAK,cAAc;AACzB,mBAAW,KAAK,WAAW;AACzB,gBAAM,KAAK,OAAO,EAAE,IAAI,MAAM,EAAE,IAAI,GAAG,EAAE,QAAQ,KAAK,EAAE,KAAK,MAAM,EAAE,EAAE;AAAA,QACzE;AAAA,MACF;AAEA,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,uBAAuB,OAAO,MAAM;AAAA;AAAA,EAAQ,MAAM,KAAK,IAAI,CAAC,IAAI,UAAU,gBAAgB,CAAC;AAAA,MAC/H;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,oCAAoC;AAAA,MACvD,MAAM;AAAA,MACN,UAAU;AAAA,QACR,SAAS,OAAO,UAAU;AACxB,cAAI,CAAC,SAAS,MAAM,SAAS,EAAG,QAAO,CAAC;AACxC,gBAAM,UAAW,MAAM,YAA6D,uBAAuB,EAAE,OAAO,MAAM,CAAC,KAAM,CAAC;AAClI,iBAAO,QAAQ,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG;AAAA,QAC3D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACD,OAAO,KAAK,EAAE,QAAQ,MAAM;AAC1B,YAAM,CAAC,OAAO,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC7C,YAAgC,kBAAkB,EAAE,QAA2B,CAAC;AAAA,QAChF,YAA0B,uBAAuB;AAAA,MACnD,CAAC;AACD,UAAI,CAAC,OAAO;AACV,eAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,UAAU,OAAO,gBAAgB,UAAU,gBAAgB,CAAC,EAAE;AAAA,MAC3G;AAEA,YAAM,gBAAgB,IAAI,KAAK,eAAe,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACxE,YAAM,MAAM,cAAc,IAAK,MAAc,YAAY;AACzD,YAAM,YAAY,KAAK,QAAQ,MAAM,kBAAkB,MAAM,kBAAkB;AAE/E,YAAM,QAAkB;AAAA,QACtB,KAAK,MAAM,OAAO,KAAK,MAAM,IAAI;AAAA,QACjC,mBAAmB,SAAS;AAAA,QAC5B,eAAe,MAAM,MAAM;AAAA,QAC3B;AAAA,MACF;AAEA,UAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,UAAU;AAChD,cAAM,KAAK,SAAS;AACpB,mBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,IAAI,GAAG;AACnD,cAAI,OAAO,QAAQ,WAAW;AAC5B,kBAAM,MAAM,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,KAAK,MAAM,CAAC;AACvE,kBAAM,KAAK,KAAK,GAAG,OAAO,GAAG,EAAE;AAAA,UACjC;AAAA,QACF;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,MAAM,aAAa,MAAM,UAAU,SAAS,GAAG;AACjD,cAAM,KAAK,cAAc;AACzB,mBAAW,OAAO,MAAM,WAAW;AACjC,gBAAM,QAAQ,IAAI,cAAc,aAAa,WAAM;AACnD,gBAAM,KAAK,IAAI,gBAAgB;AAC/B,gBAAM,OAAO,IAAI,aAAa;AAC9B,gBAAM,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,KAAK,IAAI,EAAE;AAAA,QACxD;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,MAAM,UAAU,MAAM,OAAO,SAAS,GAAG;AAC3C,cAAM,KAAK;AAAA,EAAc,MAAM,OAAO,IAAI,CAAC,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MACxF;AAEA,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,UAAU,gBAAgB,CAAC;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,oCAAoC;AAAA,MACvD,MAAM;AAAA,MACN,UAAU;AAAA,QACR,SAAS,OAAO,UAAU;AACxB,cAAI,CAAC,SAAS,MAAM,SAAS,EAAG,QAAO,CAAC;AACxC,gBAAM,UAAW,MAAM,YAA6D,uBAAuB,EAAE,OAAO,MAAM,CAAC,KAAM,CAAC;AAClI,iBAAO,QAAQ,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG;AAAA,QAC3D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACD,OAAO,KAAK,EAAE,QAAQ,MAAM;AAC1B,YAAMC,UAAS,MAAM,YAA6D,uBAAuB;AAAA,QACvG;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AAED,UAAI,CAACA,SAAQ,MAAM;AACjB,eAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,UAAU,OAAO,gBAAgB,UAAU,gBAAgB,CAAC,EAAE;AAAA,MAC3G;AAEA,YAAM,QAAkB;AAAA,QACtB,cAAcA,QAAO,KAAK,OAAO,KAAKA,QAAO,KAAK,IAAI;AAAA,QACtD,IAAIA,QAAO,cAAc,qBAAqBA,QAAO,aAAa;AAAA,QAClE;AAAA,MACF;AAEA,YAAM,eAAe,oBAAI,IAAyD;AAClF,iBAAW,SAASA,QAAO,WAAW,CAAC,GAAG;AACxC,cAAM,MAAM,MAAM,kBAAkB;AACpC,YAAI,CAAC,aAAa,IAAI,GAAG,EAAG,cAAa,IAAI,KAAK,CAAC,CAAC;AACpD,qBAAa,IAAI,GAAG,EAAG,KAAK,KAAK;AAAA,MACnC;AAEA,iBAAW,CAAC,UAAU,OAAO,KAAK,cAAc;AAC9C,cAAM,KAAK,MAAM,QAAQ,KAAK,QAAQ,MAAM,GAAG;AAC/C,mBAAW,KAAK,SAAS;AACvB,gBAAM,QAAQ,EAAE,sBAAsB,aAAa,WAAM;AACzD,gBAAM,WAAW,EAAE,MAAM,IAAI,SAAS,EAAE,GAAG,MAAM;AACjD,gBAAM,KAAK,EAAE,UAAU,GAAG,EAAE,OAAO,OAAO;AAC1C,gBAAM,KAAK,KAAK,KAAK,MAAM,EAAE,YAAY,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,QAAQ,EAAE;AAAA,QACzE;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,UAAU,gBAAgB,CAAC;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,sDAAsD;AAAA,MACzE,MAAM,YAAY;AAEhB,cAAM,cAAe,MAAM,YAA0B,uBAAuB,KAAM,CAAC;AACnF,eAAO;AAAA,UACL,WAAW,YAAY,IAAI,CAAC,OAAO;AAAA,YACjC,KAAK,8BAA8B,EAAE,IAAI;AAAA,YACzC,MAAM,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,2BAAsB,KAAK;AAAA,UAC5D,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACD,OAAO,KAAK,EAAE,KAAK,MAAM;AACvB,YAAM,iBAAiB;AAGvB,UAAI,cAA6B;AACjC,UAAI;AACF,cAAM,MAAM,MAAM,oBAAoB;AACtC,sBAAc,IAAI;AAAA,MACpB,QAAQ;AAAA,MAER;AAEA,UAAI,WAAiE;AACrE,UAAI;AACF,mBAAW,MAAM;AAAA,UACf;AAAA,UACA,EAAE,eAAe;AAAA,QACnB;AAAA,MACF,QAAQ;AAEN,mBAAW;AAAA,MACb;AAEA,UAAI,CAAC,UAAU;AAEb,YAAI,aAAa;AACf,mCAAyB,aAAa,EAAE,MAAM,eAAe,CAAC;AAAA,QAChE;AAEA,eAAO;AAAA,UACL,UAAU,CAAC;AAAA,YACT,KAAK,IAAI;AAAA,YACT,UAAU;AAAA,YACV,MAAM,KAAK,UAAU;AAAA,cACnB,IAAI;AAAA,cACJ,OAAO,eAAe,cAAc;AAAA,cACpC,MAAM;AAAA,YACR,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAMA,UAAgC;AAAA,QACpC;AAAA,QACA,gBAAgB,SAAS;AAAA,QACzB,WAAW,SAAS;AAAA,QACpB,oBAAoB,SAAS;AAAA,MAC/B;AAEA,aAAO;AAAA,QACL,UAAU,CAAC;AAAA,UACT,KAAK,IAAI;AAAA,UACT,UAAU;AAAA,UACV,MAAM,KAAK,UAAUA,OAAM;AAAA,QAC7B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,iCAAiC;AAAA,MACpD,MAAM;AAAA,MACN,UAAU;AAAA,QACR,OAAO,OAAO,UAAU;AACtB,cAAI,CAAC,MAAO,QAAO,CAAC,aAAa,mBAAmB,cAAc,WAAW;AAC7E,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACD,OAAO,KAAK,EAAE,MAAM,MAAM;AACxB,YAAM,UAAU,MAAM,YAA6D,uBAAuB,EAAE,MAAuB,CAAC;AAEpI,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,eAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,mBAAmB,KAAK,MAAM,UAAU,gBAAgB,CAAC,EAAE;AAAA,MACxG;AAEA,YAAM,QAAkB;AAAA,QACtB,cAAc,KAAK;AAAA,QACnB,IAAI,QAAQ,MAAM;AAAA,QAClB;AAAA,MACF;AAEA,iBAAW,SAAS,SAAS;AAC3B,cAAM,KAAK,MAAM,UAAU,KAAK,MAAM,OAAO,SAAS;AAKtD,cAAM,OAAO,MAAM,kBAAkB;AACrC,cAAM,KAAK,KAAK,EAAE,GAAG,MAAM,IAAI,KAAK,IAAI,MAAM,MAAM,MAAM,GAAG;AAAA,MAC/D;AAEA,aAAO;AAAA,QACL,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,MAAM,KAAK,IAAI,GAAG,UAAU,gBAAgB,CAAC;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AACF;;;AE5xBA,SAAS,KAAAC,WAAS;AAGX,SAAS,gBAAgB,QAAmB;AACjD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,QAAQC,IAAE,OAAO,EAAE,SAAS,iFAAiF,EAAE;AAAA,IACjH,OAAO,EAAE,OAAO,MAAM;AACpB,YAAM,UAAU,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,iBAAiB,CAAC;AAM1I,YAAM,QAAQ,QAAQ,OAAO,CAAC,MAAO,EAAE,MAA8C,WAAW,MAAM;AAEtG,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO;AAAA,UACL,UAAU;AAAA,YACR;AAAA,cACE,MAAM;AAAA,cACN,SAAS;AAAA,gBACP,MAAM;AAAA,gBACN,MAAM,uCAAuC,MAAM;AAAA,cACrD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,YAAY,MACf;AAAA,QACC,CAAC,MACC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI;AAAA,UACtB,EAAE,MAAM,gBAAgB,EAAE,MAAM,YAAY,SAAS;AAAA,eAChD,EAAE,MAAM,eAAe,EAAE;AAAA,eACzB,EAAE,MAAM,cAAc,EAAE;AAAA,cACzB,EAAE,MAAM,aAAa,CAAC,GAAG,KAAK,IAAI,CAAC;AAAA,KACjD,EAAE,MAAM,eAAe,aAAa,EAAE,KAAK,aAAa,IAAI,WAAM,EAAE,KAAK,aAAa,MAAM;AAAA,IAAO;AAAA,MACxG,EACC,KAAK,WAAW;AAEnB,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,cACP,MAAM;AAAA,cACN,MACE,mFAAmF,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKnE,SAAS;AAAA;AAAA;AAAA,YAEnC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,OAAOA,IAAE,OAAO,EAAE,SAAS,8FAA8F,EAAE;AAAA,IAC7H,OAAO,EAAE,MAAM,MAAM;AACnB,YAAM,QAAQ,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,WAAW,CAAC;AAElI,YAAM,kBAAkB,MACrB;AAAA,QACC,CAAC,MACC,GAAG,EAAE,IAAI,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,aAAa,EAAE,MACvE,EAAE,MAAM,cAAc,SAAS,IAAI,gCAA2B,EAAE,KAAK,aAAa,KAAK,IAAI,CAAC,KAAK,OACjG,EAAE,MAAM,aAAa,SAAS,IAC3B;AAAA,mBAAsB,EAAE,KAAK,YAAY,IAAI,CAAC,MAAW,GAAG,EAAE,QAAQ,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,IAAI,CAAC,KAC/F;AAAA,MACR,EACC,KAAK,IAAI;AAEZ,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,cACP,MAAM;AAAA,cACN,MACE;AAAA;AAAA,kBACmB,KAAK;AAAA;AAAA;AAAA,EACQ,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAOnD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAASA,IAAE,OAAO,EAAE,SAAS,yGAAyG,EAAE;AAAA,IAC1I,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,kBAAkB,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,YAAY,CAAC;AAC7I,YAAM,SAAS,CAAC,GAAG,eAAe,EAC/B,KAAK,CAAC,GAAG,OAAQ,EAAE,MAAM,QAAQ,OAAO,EAAE,MAAM,QAAQ,MAAM,IAAI,EAAG,EACrE,MAAM,GAAG,CAAC;AAEb,YAAM,gBAAgB,OAAO,SAAS,IAClC,OAAO,IAAI,CAAC,MAAM,MAAM,EAAE,MAAM,KAAK,EAAE,IAAI,KAAK,EAAE,MAAM,QAAQ,SAAS,GAAG,EAAE,KAAK,IAAI,IACvF;AAEJ,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,cACP,MAAM;AAAA,cACN,MACE;AAAA;AAAA,GACI,OAAO;AAAA;AAAA;AAAA,EACyB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAUrD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAaA,IAAE,OAAO,EAAE,SAAS,2FAA2F;AAAA,MAC5H,QAAQA,IAAE,OAAO,EAAE,SAAS,yEAAyE;AAAA,IACvG;AAAA,IACA,OAAO,EAAE,aAAa,OAAO,MAAM;AACjC,YAAM,WAAW,MAAM,YAA2D,qBAAqB,EAAE,gBAAgB,iBAAiB,CAAC;AAE3I,YAAM,gBAAgB,SAAS,OAAO,CAAC,MAAO,EAAE,MAA8C,WAAW,MAAM;AAE/G,YAAM,kBACJ,cAAc,SAAS,IACnB,cAAc,IAAI,CAAC,MAAM,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,MAAM,YAAO,EAAE,MAAM,eAAe,EAAE,EAAE,EAAE,KAAK,IAAI,IAChH;AAEN,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,cACP,MAAM;AAAA,cACN,MACE;AAAA;AAAA,GACI,WAAW;AAAA;AAAA,UACJ,MAAM;AAAA;AAAA;AAAA,EACkB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAWtD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AhFxKO,IAAM,iBAAiB;AAE9B,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EASA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAEJ,SAAS,2BAAsC;AACpD,QAAM,SAAS,IAAIC;AAAA,IACjB,EAAE,MAAM,iBAAiB,SAAS,eAAe;AAAA,IACjD,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,GAAG,cAAc,aAAa;AAAA,EAC9D;AAQA,QAAM,iBAAiB,IAAI;AAAA,KACxB,QAAQ,IAAI,cAAc,QACxB,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC;AAAA,EACjD;AAOA,uBAAqB,MAAM;AAC3B,uBAAqB,MAAM;AAC3B,yBAAuB,MAAM;AAC7B,uBAAqB,MAAM;AAC3B,2BAAyB,MAAM;AAC/B,qBAAmB,MAAM;AACzB,4BAA0B,MAAM;AAChC,uBAAqB,MAAM;AAC3B,wBAAsB,MAAM;AAC5B,yBAAuB,MAAM;AAC7B,uBAAqB,MAAM;AAC3B,qBAAmB,MAAM;AACzB,wBAAsB,MAAM;AAI5B,MAAI,eAAe,IAAI,UAAU,EAAG,uBAAsB,MAAM;AAEhE,oBAAkB,MAAM;AACxB,kBAAgB,MAAM;AAQtB,SAAO;AACT;;;AiFpHA,SAAS,gBAAgB,MAAkC;AAC1D,MAAI;AAEH,UAAM,MAAO,YAA6D;AAC1E,WAAO,MAAM,IAAI;AAAA,EAClB,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEA,SAAS,mBAAmB,MAAkC;AAC7D,MAAI;AACH,QAAI,OAAO,YAAY,eAAe,QAAQ,KAAK;AAClD,aAAO,QAAQ,IAAI,IAAI;AAAA,IACxB;AAAA,EACD,QAAQ;AAAA,EAER;AACA,SAAO;AACR;AAEA,IAAM,OACL,gBAAgB,0BAA0B,MAAM,UAChD,mBAAmB,qBAAqB,MAAM;AAS/C,IAAM,oBACL,gBAAgB,2BAA2B,MAAM,UACjD,mBAAmB,sBAAsB,MAAM;AAOzC,IAAM,KAAK;AAAA,EACjB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AACvB;AAEO,IAAM,MAAM;AAAA;AAAA,EAElB,OAAO;AAAA;AAAA,EAEP,WAAW;AAAA;AAAA,EAEX,OAAO;AACR;AAaO,IAAM,QAAQ;AAAA;AAAA,EAEpB,oBAAoB;AAAA,IACnB,SAAS;AAAA,IACT,gBAAgB;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,IAAI,OAAO,IAAI,OAAO,IAAI,SAAS;AAAA,EAChD;AAAA;AAAA,EAEA,0BAA0B;AAAA,IACzB,SAAS;AAAA,IACT,gBAAgB;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,IAAI,OAAO,IAAI,OAAO,IAAI,SAAS;AAAA,EAChD;AAAA;AAAA,EAEA,wBAAwB;AAAA,IACvB,SAAS;AAAA,IACT,gBAAgB;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,IAAI,OAAO,IAAI,OAAO,IAAI,SAAS;AAAA,EAChD;AAAA;AAAA,EAEA,qBAAqB;AAAA,IACpB,SAAS;AAAA,IACT,gBAAgB;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,IAAI,OAAO,IAAI,OAAO,IAAI,SAAS;AAAA,EAChD;AAAA;AAAA,EAEA,yBAAyB;AAAA,IACxB,SAAS;AAAA,IACT,gBAAgB;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,IAAI,OAAO,IAAI,OAAO,IAAI,SAAS;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,6BAA6B;AAAA,IAC5B,SAAS;AAAA,IACT,gBAAgB;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACJ;AAAA,IACA,WAAW,CAAC,IAAI,OAAO,IAAI,SAAS;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,+BAA+B;AAAA;AAAA,EAE/B,4BAA4B;AAAA;AAAA;AAAA;AAAA,EAI5B,qBAAqB;AAAA,IACpB,SAAS;AAAA,EACV;AACD;;;ACvLO,SAAS,iBAAiB,gBAAsC;AAGvE;","names":["McpServer","z","result","ws","union","z","z","result","displayName","result","z","z","z","z","result","result","result","z","z","resolved","classifierMeta","z","displayName","result","preview","z","z","z","status","result","wsCtx","existsSync","resolve","z","resolve","existsSync","z","result","z","z","result","z","status","z","z","z","result","z","result","suggested","suggestedWithPosture","z","z","z","result","z","result","root","byCollection","lines","rootId","nodes","edges","z","z","z","z","handleList","handleCreate","z","result","readFileSync","resolve","result","kernelQuery","taskGroundingWarningLines","status","z","z","z","actions","z","status","result","z","z","result","z","orientationStatus","z","z","levenshtein","_","handleList","result","status","z","z","z","result","z","lines","result","z","z","result","z","data","z","z","result","coherencyAcknowledgementFlatSchema","z","handleStart","result","z","z","status","result","z","z","result","handleAudit","z","r","z","z","status","result","z","handleAudit","z","status","z","z","z","result","z","ANSI_AND_CONTROL_RE","z","result","message","existsSync","resolve","resolve","result","z","z","McpServer"]}