@productbrain/mcp 0.0.1-beta.0
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.
- package/.env.mcp.example +32 -0
- package/README.md +238 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.js +2546 -0
- package/dist/index.js.map +1 -0
- package/dist/setup-K757L5KR.js +227 -0
- package/dist/setup-K757L5KR.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tools/knowledge.ts","../src/analytics.ts","../src/client.ts","../src/tools/labels.ts","../src/tools/health.ts","../src/tools/verify.ts","../src/tools/smart-capture.ts","../src/resources/index.ts","../src/prompts/index.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nimport { registerKnowledgeTools } from \"./tools/knowledge.js\";\nimport { registerLabelTools } from \"./tools/labels.js\";\nimport { registerHealthTools } from \"./tools/health.js\";\nimport { registerVerifyTools } from \"./tools/verify.js\";\nimport { registerSmartCaptureTools } from \"./tools/smart-capture.js\";\nimport { registerResources } from \"./resources/index.js\";\nimport { registerPrompts } from \"./prompts/index.js\";\nimport { getWorkspaceId, bootstrapCloudMode } from \"./client.js\";\nimport { initAnalytics, trackSessionStarted, shutdownAnalytics } from \"./analytics.js\";\n\n// Dev convenience: load .env.mcp from cwd when env vars aren't already set.\n// In production (npx / Cursor MCP config), env vars come from the launcher.\nif (!process.env.CONVEX_SITE_URL && !process.env.PRODUCTBRAIN_API_KEY) {\n try {\n const envPath = resolve(process.cwd(), \".env.mcp\");\n for (const line of readFileSync(envPath, \"utf-8\").split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx === -1) continue;\n process.env[trimmed.slice(0, eqIdx)] ??= trimmed.slice(eqIdx + 1);\n }\n } catch {\n // .env.mcp not found — rely on env vars being set by the launcher\n }\n}\n\n// Cloud mode: PRODUCTBRAIN_API_KEY → auto-resolve cloud URL + skip WORKSPACE_SLUG\nbootstrapCloudMode();\n\nconst SERVER_VERSION = \"1.0.0\";\n\ninitAnalytics();\n\nlet workspaceId: string;\ntry {\n workspaceId = await getWorkspaceId();\n} catch (err: any) {\n const hint =\n !process.env.PRODUCTBRAIN_API_KEY && !process.env.CONVEX_SITE_URL\n ? \"\\n[MCP] Hint: Set PRODUCTBRAIN_API_KEY in your MCP config env block. Get your key at SynergyOS → Settings → API Keys.\"\n : \"\";\n process.stderr.write(`[MCP] Startup failed: ${err.message}${hint}\\n`);\n process.exit(1);\n}\n\ntrackSessionStarted(\n process.env.WORKSPACE_SLUG ?? \"unknown\",\n workspaceId,\n SERVER_VERSION,\n);\n\nconst server = new McpServer(\n {\n name: \"Product Brain\",\n version: SERVER_VERSION,\n },\n {\n capabilities: { logging: {} },\n instructions: [\n \"ProductBrain — 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 \"Terminology & naming: For 'what is X?' or naming questions, fetch `productbrain://terminology`\",\n \"or use the `name-check` prompt to validate names against the glossary.\",\n \"\",\n \"Workflow:\",\n \" 1. Verify: call `health` to confirm connectivity.\",\n \" 2. Terminology: fetch `productbrain://terminology` or use `name-check` prompt for naming questions.\",\n \" 3. Discover: use `kb-search` to find entries by text, or `list-entries` to browse a collection.\",\n \" 4. Drill in: use `get-entry` for full details — data, labels, relations, history.\",\n \" 5. Capture: use `smart-capture` to create entries — it auto-links related entries and\",\n \" returns a quality scorecard in one call. Use `create-entry` only when you need\",\n \" full control over every field.\",\n \" 6. Connect: use `suggest-links` then `relate-entries` to build the graph.\",\n \" 7. Quality: use `quality-check` to assess entry completeness.\",\n \" 8. Debug: use `mcp-audit` to see what backend calls happened this session.\",\n \"\",\n \"Always prefer `smart-capture` over `create-entry` or `quick-capture` for new entries.\",\n \"Always prefer kb-search or list-entries before get-entry — discover, then drill in.\",\n \"\",\n \"Orientation:\",\n \" When you need to understand the system — architecture, data model, rules,\",\n \" or analytics — fetch the `productbrain://orientation` resource first.\",\n \" It gives you the map. Then use the appropriate tool to drill in.\",\n ].join(\"\\n\"),\n },\n);\n\nregisterKnowledgeTools(server);\nregisterLabelTools(server);\nregisterHealthTools(server);\nregisterVerifyTools(server);\nregisterSmartCaptureTools(server);\nregisterResources(server);\nregisterPrompts(server);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n\nasync function gracefulShutdown() {\n await shutdownAnalytics();\n process.exit(0);\n}\n\nprocess.on(\"SIGINT\", gracefulShutdown);\nprocess.on(\"SIGTERM\", gracefulShutdown);\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { mcpQuery, mcpMutation } from \"../client.js\";\n\nfunction extractPreview(data: any, maxLen: number): string {\n if (!data || typeof data !== \"object\") return \"\";\n const raw = data.description ?? data.canonical ?? data.detail ?? \"\";\n if (typeof raw !== \"string\" || !raw) return \"\";\n return raw.length > maxLen ? raw.substring(0, maxLen) + \"...\" : raw;\n}\n\nexport function registerKnowledgeTools(server: McpServer) {\n\n server.registerTool(\n \"list-collections\",\n {\n title: \"Browse Collections\",\n description:\n \"List every knowledge collection in the workspace — glossary, business rules, tracking events, standards, etc. \" +\n \"Returns each collection's slug, name, description, and field schema. \" +\n \"Start here before create-entry so you know which collections exist and what fields they expect.\",\n annotations: { readOnlyHint: true },\n },\n async () => {\n const collections = await mcpQuery<any[]>(\"kb.listCollections\");\n\n if (collections.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No collections found in this workspace.\" }] };\n }\n\n const formatted = collections\n .map((c) => {\n const fieldList = c.fields\n .map((f: any) => ` - \\`${f.key}\\` (${f.type}${f.required ? \", required\" : \"\"}${f.searchable ? \", searchable\" : \"\"})`)\n .join(\"\\n\");\n return `## ${c.name} (\\`${c.slug}\\`)\\n${c.description || \"_No description_\"}\\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 };\n }\n );\n\n server.registerTool(\n \"list-entries\",\n {\n title: \"Browse Entries\",\n description:\n \"List entries in a collection, with optional filters for status, tag, or label. \" +\n \"Returns entry IDs, names, status, and a data preview. \" +\n \"Use list-collections first to discover available collection slugs.\",\n inputSchema: {\n collection: z.string().optional().describe(\"Collection slug, e.g. 'glossary', 'tracking-events', 'business-rules'\"),\n status: z.string().optional().describe(\"Filter: draft | active | verified | deprecated\"),\n tag: z.string().optional().describe(\"Filter by internal tag, e.g. 'health:ambiguous'\"),\n label: z.string().optional().describe(\"Filter by label slug — matches entries across all collections\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ collection, status, tag, label }) => {\n let entries: any[];\n\n if (label) {\n entries = await mcpQuery<any[]>(\"kb.listEntriesByLabel\", { labelSlug: label });\n if (status) entries = entries.filter((e: any) => e.status === status);\n } else {\n entries = await mcpQuery<any[]>(\"kb.listEntries\", {\n collectionSlug: collection,\n status,\n tag,\n });\n }\n\n if (entries.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No entries match the given filters.\" }] };\n }\n\n const formatted = entries\n .map((e) => {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const dataPreview = e.data\n ? Object.entries(e.data)\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} \\`${e.status}\\`${dataPreview ? `\\n${dataPreview}` : \"\"}`;\n })\n .join(\"\\n\\n\");\n\n const scope = collection ? ` in \\`${collection}\\`` : \"\";\n return {\n content: [{ type: \"text\" as const, text: `# Entries${scope} (${entries.length})\\n\\n${formatted}` }],\n };\n }\n );\n\n server.registerTool(\n \"get-entry\",\n {\n title: \"Look Up Entry\",\n description:\n \"Retrieve a single knowledge entry by its human-readable ID (e.g. 'T-SUPPLIER', 'BR-001', 'EVT-workspace_created'). \" +\n \"Returns the full record: all data fields, labels, relations, and change history. \" +\n \"Use kb-search or list-entries first to discover entry IDs.\",\n inputSchema: {\n entryId: z.string().describe(\"Entry ID, e.g. 'T-SUPPLIER', 'BR-001', 'EVT-workspace_created'\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ entryId }) => {\n const entry = await mcpQuery<any>(\"kb.getEntry\", { entryId });\n\n if (!entry) {\n return { content: [{ type: \"text\" as const, text: `Entry \\`${entryId}\\` not found. Try kb-search to find the right ID.` }] };\n }\n\n const lines: string[] = [\n `# ${entry.entryId ? `${entry.entryId}: ` : \"\"}${entry.name}`,\n \"\",\n `**Status:** ${entry.status}`,\n ];\n\n if (entry.data && typeof entry.data === \"object\") {\n lines.push(\"\");\n for (const [key, val] of Object.entries(entry.data)) {\n const display = typeof val === \"string\" ? val : JSON.stringify(val);\n lines.push(`**${key}:** ${display}`);\n }\n }\n\n if (entry.tags?.length > 0) {\n lines.push(\"\", `**Tags:** ${entry.tags.join(\", \")}`);\n }\n\n if (entry.labels?.length > 0) {\n lines.push(\"\", `**Labels:** ${entry.labels.map((l: any) => `\\`${l.slug ?? l.name}\\``).join(\", \")}`);\n }\n\n if (entry.relations?.length > 0) {\n lines.push(\"\", \"## Relations\");\n for (const r of entry.relations) {\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 (entry.history?.length > 0) {\n lines.push(\"\", \"## History (last 10)\");\n for (const h of entry.history.slice(-10)) {\n const date = new Date(h.timestamp).toISOString().split(\"T\")[0];\n lines.push(`- ${date}: ${h.event}${h.changedBy ? ` _(${h.changedBy})_` : \"\"}`);\n }\n }\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n );\n\n const governedCollections = new Set([\n \"glossary\", \"business-rules\", \"principles\", \"standards\", \"strategy\",\n ]);\n\n server.registerTool(\n \"create-entry\",\n {\n title: \"Create Entry\",\n description:\n \"Create a new knowledge entry. Provide the collection slug, a display name, status, and data matching the collection's field schema. \" +\n \"Call list-collections first to see available collections and their field definitions. \" +\n \"Governed collections (glossary, business-rules, principles, standards, strategy) require status 'draft' — \" +\n \"to promote to 'active' or 'verified', raise a tension or use update-entry after approval.\",\n inputSchema: {\n collection: z.string().describe(\"Collection slug, e.g. 'tracking-events', 'standards', 'glossary'\"),\n entryId: z.string().optional().describe(\"Human-readable ID, e.g. 'EVT-workspace_created', 'STD-posthog-events'\"),\n name: z.string().describe(\"Display name\"),\n status: z.string().default(\"draft\").describe(\"Lifecycle status: draft | active | verified | deprecated\"),\n data: z.record(z.unknown()).describe(\"Data object — keys must match the collection's field definitions\"),\n order: z.number().optional().describe(\"Manual sort order within the collection\"),\n },\n annotations: { destructiveHint: false },\n },\n async ({ collection, entryId, name, status, data, order }) => {\n if (governedCollections.has(collection) && status !== \"draft\" && status !== \"deprecated\") {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Governance Required\\n\\n` +\n `The \\`${collection}\\` collection is governed. New entries must be created with status \\`draft\\`.\\n\\n` +\n `**How to proceed:**\\n` +\n `1. Create the entry with status \\`draft\\` (treated as a proposal)\\n` +\n `2. Raise a tension in the \\`tensions\\` collection to request promotion\\n` +\n `3. After approval, use \\`update-entry\\` to change status to \\`active\\` or \\`verified\\``,\n }],\n };\n }\n\n try {\n const id = await mcpMutation<string>(\"kb.createEntry\", {\n collectionSlug: collection,\n entryId,\n name,\n status,\n data,\n order,\n });\n\n return {\n content: [{ type: \"text\" as const, text: `# Entry Created\\n\\n**${entryId ?? name}** added to \\`${collection}\\` as \\`${status}\\`.\\n\\nInternal ID: ${id}` }],\n };\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"Duplicate entry\") || msg.includes(\"already exists\")) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Cannot Create — Duplicate Detected\\n\\n${msg}\\n\\n` +\n `**What to do:**\\n` +\n `- Use \\`get-entry\\` to inspect the existing entry\\n` +\n `- Use \\`update-entry\\` to modify it\\n` +\n `- If a genuinely new entry is needed, raise a tension to propose it`,\n }],\n };\n }\n throw error;\n }\n }\n );\n\n server.registerTool(\n \"update-entry\",\n {\n title: \"Update Entry\",\n description:\n \"Update an existing entry by its human-readable ID. Only provide the fields you want to change — data fields are merged with existing values. \" +\n \"Use get-entry first to see current values. SOS-020: Cannot update tension status via MCP — process decides (use SynergyOS UI after approval).\",\n inputSchema: {\n entryId: z.string().describe(\"Entry ID to update, e.g. 'T-SUPPLIER', 'BR-001'\"),\n name: z.string().optional().describe(\"New display name\"),\n status: z.string().optional().describe(\"New status: draft | active | verified | deprecated\"),\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 },\n annotations: { idempotentHint: true, destructiveHint: false },\n },\n async ({ entryId, name, status, data, order }) => {\n try {\n const id = await mcpMutation<string>(\"kb.updateEntry\", {\n entryId,\n name,\n status,\n data,\n order,\n });\n\n return {\n content: [{ type: \"text\" as const, text: `# Entry Updated\\n\\n**${entryId}** has been updated.\\n\\nInternal ID: ${id}` }],\n };\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"SOS-020\")) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# SOS-020: Tension Status Cannot Be Changed via MCP\\n\\n` +\n `Tension status (open, in-progress, closed) must be changed through the defined process, not via MCP.\\n\\n` +\n `**What you can do:**\\n` +\n `- Create tensions: \\`create-entry collection=tensions name=\"...\" status=open\\`\\n` +\n `- List tensions: \\`list-entries collection=tensions\\`\\n` +\n `- Update non-status fields (raised, date, priority, description) via \\`update-entry\\`\\n` +\n `- After process approval, a human uses the SynergyOS UI to change status\\n\\n` +\n `Process criteria (TBD): e.g. 3+ users approved, or 7 days without valid concerns.`,\n }],\n };\n }\n throw error;\n }\n }\n );\n\n server.registerTool(\n \"kb-search\",\n {\n title: \"Search Knowledge Base\",\n description:\n \"Full-text search across all knowledge entries. Returns entry names, collection, status, and a description preview. \" +\n \"Scope results to a specific collection (e.g. collection='business-rules') or filter by status (e.g. status='active'). \" +\n \"Use this to discover entries before calling get-entry for full details.\",\n inputSchema: {\n query: z.string().describe(\"Search text (min 2 characters)\"),\n collection: z.string().optional().describe(\"Scope to a collection slug, e.g. 'business-rules', 'glossary', 'tracking-events'\"),\n status: z.string().optional().describe(\"Filter by status: draft | active | verified | deprecated\"),\n },\n annotations: { readOnlyHint: true, openWorldHint: true },\n },\n async ({ query, collection, status }) => {\n const scope = collection ? ` in \\`${collection}\\`` : \"\";\n await server.sendLoggingMessage({ level: \"info\", data: `Searching${scope} for \"${query}\"...`, logger: \"product-os\" });\n\n const [results, collections] = await Promise.all([\n mcpQuery<any[]>(\"kb.searchEntries\", { query, collectionSlug: collection, status }),\n mcpQuery<any[]>(\"kb.listCollections\"),\n ]);\n\n if (results.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No results for \"${query}\"${scope}. Try a broader search or check list-collections for available data.` }] };\n }\n\n const collMap = new Map<string, { name: string; slug: string }>();\n for (const c of collections) {\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) {\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\n .map((e) => {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const col = collMap.get(e.collectionId);\n const colTag = col ? ` [${col.slug}]` : \"\";\n const desc = extractPreview(e.data, 150);\n const preview = desc ? `\\n ${desc}` : \"\";\n return `- ${id}${e.name} \\`${e.status}\\`${colTag}${preview}`;\n })\n .join(\"\\n\");\n\n const header = `# 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 get-entry with an entry ID for full details._`;\n\n return {\n content: [{ type: \"text\" as const, text: `${header}\\n\\n${formatted}\\n\\n${footer}` }],\n };\n }\n );\n\n server.registerTool(\n \"get-history\",\n {\n title: \"Entry Change History\",\n description:\n \"Get the audit trail for an entry — when it was created, updated, status-changed, etc. \" +\n \"Returns timestamped events with change details.\",\n inputSchema: {\n entryId: z.string().describe(\"Entry ID, e.g. 'T-SUPPLIER', 'BR-001'\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ entryId }) => {\n const history = await mcpQuery<any[]>(\"kb.listEntryHistory\", { entryId });\n\n if (history.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No history found for \\`${entryId}\\`.` }] };\n }\n\n const formatted = history\n .map((h) => {\n const date = new Date(h.timestamp).toISOString();\n const changes = h.changes ? ` — ${JSON.stringify(h.changes)}` : \"\";\n return `- **${date}** ${h.event}${h.changedBy ? ` _(${h.changedBy})_` : \"\"}${changes}`;\n })\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\" as const, text: `# History for \\`${entryId}\\` (${history.length} events)\\n\\n${formatted}` }],\n };\n }\n );\n\n server.registerTool(\n \"relate-entries\",\n {\n title: \"Link Two Entries\",\n description:\n \"Create a typed relation between two entries, building the knowledge graph. \" +\n \"Use get-entry to see existing relations before adding new ones.\\n\\n\" +\n \"Recommended relation types (extensible — any string is accepted):\\n\" +\n \"- related_to, depends_on, replaces, conflicts_with, references, confused_with\\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\\n\" +\n \"- informs — a decision or insight informs a feature\\n\" +\n \"- surfaces_tension_in — a tension exists within a feature area\\n\\n\" +\n \"Check glossary for relation type definitions if unsure which to use.\",\n inputSchema: {\n from: z.string().describe(\"Source entry ID, e.g. 'T-SUPPLIER'\"),\n to: z.string().describe(\"Target entry ID, e.g. 'BR-001'\"),\n type: z.string().describe(\"Relation type — use a recommended type or any descriptive string\"),\n },\n annotations: { destructiveHint: false },\n },\n async ({ from, to, type }) => {\n await mcpMutation(\"kb.createEntryRelation\", {\n fromEntryId: from,\n toEntryId: to,\n type,\n });\n\n return {\n content: [{ type: \"text\" as const, text: `# Relation Created\\n\\n**${from}** \\u2014[${type}]\\u2192 **${to}**` }],\n };\n }\n );\n\n server.registerTool(\n \"find-related\",\n {\n title: \"Find Related Entries\",\n description:\n \"Navigate the knowledge graph — find all entries related to a given entry. \" +\n \"Shows incoming references (what points to this entry), outgoing references (what this entry points to), or both. \" +\n \"Use after get-entry to explore connections, or to answer 'what depends on X?' or 'what references Y?'\",\n inputSchema: {\n entryId: z.string().describe(\"Entry ID, e.g. 'GT-019', 'SOS-006'\"),\n direction: z.enum([\"incoming\", \"outgoing\", \"both\"]).default(\"both\")\n .describe(\"Filter: 'incoming' = what references this entry, 'outgoing' = what this entry references\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ entryId, direction }) => {\n const relations = await mcpQuery<any[]>(\"kb.listEntryRelations\", { entryId });\n\n if (relations.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No relations found for \\`${entryId}\\`. Use relate-entries to create connections.` }] };\n }\n\n const sourceEntry = await mcpQuery<any>(\"kb.getEntry\", { entryId });\n if (!sourceEntry) {\n return { content: [{ type: \"text\" as const, text: `Entry \\`${entryId}\\` not found. Try kb-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 mcpQuery<any>(\"kb.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 mcpQuery<any[]>(\"kb.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[] = [`# 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 };\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(`- \\u2192 **${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(`- \\u2190 **${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 get-entry for the full picture._`);\n }\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n );\n\n server.registerTool(\n \"gather-context\",\n {\n title: \"Gather Full Context\",\n description:\n \"Assemble the full knowledge context around an entry by traversing the knowledge graph. \" +\n \"Returns all related entries grouped by collection — glossary terms, business rules, tensions, decisions, features, etc. \" +\n \"Use this when starting work on a feature or investigating an area to get the complete picture in one call.\\n\\n\" +\n \"Example: gather-context entryId='FEAT-001' returns all glossary terms, business rules, and tensions linked to that feature.\",\n inputSchema: {\n entryId: z.string().describe(\"Entry ID, e.g. 'FEAT-001', 'GT-019', 'BR-007'\"),\n maxHops: z.number().min(1).max(3).default(2)\n .describe(\"How many relation hops to traverse (1=direct only, 2=default, 3=wide net)\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ entryId, maxHops }) => {\n const result = await mcpQuery<any>(\"kb.gatherContext\", { entryId, maxHops });\n\n if (!result?.root) {\n return { content: [{ type: \"text\" as const, text: `Entry \\`${entryId}\\` not found. Try kb-search to find the right ID.` }] };\n }\n\n if (result.related.length === 0) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Context for ${result.root.entryId}: ${result.root.name}\\n\\n` +\n `_No relations found._ This entry is not yet connected to the knowledge graph.\\n\\n` +\n `Use \\`suggest-links\\` to discover potential connections, or \\`relate-entries\\` to link manually.`,\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;\n if (!byCollection.has(key)) byCollection.set(key, []);\n byCollection.get(key)!.push(entry);\n }\n\n const lines: string[] = [\n `# Context for ${result.root.entryId}: ${result.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})`);\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 return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n );\n\n server.registerTool(\n \"suggest-links\",\n {\n title: \"Suggest Links\",\n description:\n \"Discover potential connections for an entry by scanning the knowledge base for related content. \" +\n \"Returns ranked suggestions based on text similarity — review them and use relate-entries to create the ones that make sense.\\n\\n\" +\n \"This is a discovery tool, not auto-linking. Always review suggestions before linking.\",\n inputSchema: {\n entryId: z.string().describe(\"Entry ID to find suggestions for, e.g. 'FEAT-001'\"),\n limit: z.number().min(1).max(20).default(10)\n .describe(\"Max number of suggestions to return\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ entryId, limit }) => {\n const entry = await mcpQuery<any>(\"kb.getEntry\", { entryId });\n if (!entry) {\n return { content: [{ type: \"text\" as const, text: `Entry \\`${entryId}\\` not found. Try kb-search to find the right ID.` }] };\n }\n\n const searchTerms = [entry.name];\n if (entry.data?.description) searchTerms.push(entry.data.description);\n if (entry.data?.canonical) searchTerms.push(entry.data.canonical);\n if (entry.data?.rationale) searchTerms.push(entry.data.rationale);\n if (entry.data?.rule) searchTerms.push(entry.data.rule);\n\n const queryText = searchTerms\n .join(\" \")\n .replace(/[^\\w\\s]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 3)\n .slice(0, 8)\n .join(\" \");\n\n if (!queryText) {\n return { content: [{ type: \"text\" as const, text: `Entry \\`${entryId}\\` has too little text content to generate suggestions.` }] };\n }\n\n const results = await mcpQuery<any[]>(\"kb.searchEntries\", { query: queryText });\n if (!results || results.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No suggestions found for \\`${entryId}\\`. The knowledge base may need more entries.` }] };\n }\n\n const existingRelations = await mcpQuery<any[]>(\"kb.listEntryRelations\", { entryId });\n const relatedIds = new Set(\n existingRelations.flatMap((r) => [r.fromId, r.toId])\n );\n\n const collections = await mcpQuery<any[]>(\"kb.listCollections\");\n const collMap = new Map<string, string>();\n for (const c of collections) collMap.set(c._id, c.slug);\n\n const suggestions = results\n .filter((r) => r._id !== entry._id && !relatedIds.has(r._id))\n .slice(0, limit)\n .map((r) => ({\n entryId: r.entryId,\n name: r.name,\n collection: collMap.get(r.collectionId) ?? \"unknown\",\n preview: extractPreview(r.data, 80),\n }));\n\n if (suggestions.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No new link suggestions for \\`${entryId}\\` — it may already be well-connected, or no similar entries exist.` }] };\n }\n\n const lines = [\n `# Link Suggestions for ${entryId}: ${entry.name}`,\n `_${suggestions.length} potential connections found. Review and use \\`relate-entries\\` to create the ones that make sense._`,\n \"\",\n ];\n\n for (let i = 0; i < suggestions.length; i++) {\n const s = suggestions[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 lines.push(\"\");\n lines.push(\"**To link:** `relate-entries from='FEAT-001' to='GT-019' type='defines_term_for'`\");\n lines.push(\"\");\n lines.push(\"_Recommended relation types: governs, defines_term_for, belongs_to, informs, surfaces_tension_in, related_to, depends_on_\");\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n );\n\n server.registerTool(\n \"quick-capture\",\n {\n title: \"Quick Capture\",\n description:\n \"Quickly capture a knowledge entry with just a name and description — no need to look up the full field schema first. \" +\n \"Always creates as 'draft' status with sensible defaults for remaining fields. \" +\n \"Use update-entry later to fill in details. Embodies 'Capture Now, Curate Later' (PRI-81cbdq).\",\n inputSchema: {\n collection: z.string().describe(\"Collection slug, e.g. 'business-rules', 'glossary', 'tensions', 'decisions'\"),\n name: z.string().describe(\"Display name for the entry\"),\n description: z.string().describe(\"Short description — the essential context to capture now\"),\n entryId: z.string().optional().describe(\"Optional human-readable ID (e.g. 'SOS-020', 'GT-031')\"),\n },\n annotations: { destructiveHint: false },\n },\n async ({ collection, name, description, entryId }) => {\n const col = await mcpQuery<any>(\"kb.getCollection\", { slug: collection });\n if (!col) {\n return { content: [{ type: \"text\" as const, text: `Collection \\`${collection}\\` not found. Use list-collections to see available collections.` }] };\n }\n\n const data: Record<string, unknown> = {};\n const emptyFields: string[] = [];\n\n for (const field of col.fields ?? []) {\n const key = field.key as string;\n if (key === \"description\" || key === \"canonical\" || key === \"detail\") {\n data[key] = description;\n } else if (field.type === \"array\" || field.type === \"multi-select\") {\n data[key] = [];\n emptyFields.push(key);\n } else if (field.type === \"select\") {\n data[key] = field.options?.[0] ?? \"\";\n emptyFields.push(key);\n } else {\n data[key] = \"\";\n emptyFields.push(key);\n }\n }\n\n if (!data.description && !data.canonical && !data.detail) {\n data.description = description;\n }\n\n try {\n const id = await mcpMutation<string>(\"kb.createEntry\", {\n collectionSlug: collection,\n entryId,\n name,\n status: \"draft\",\n data,\n });\n\n const emptyNote = emptyFields.length > 0\n ? `\\n\\n**Fields to fill later** (via \\`update-entry\\`):\\n${emptyFields.map((f) => `- \\`${f}\\``).join(\"\\n\")}`\n : \"\";\n\n return {\n content: [{\n type: \"text\" as const,\n text: `# Quick Capture — Done\\n\\n**${entryId ?? name}** added to \\`${collection}\\` as \\`draft\\`.\\n\\nInternal ID: ${id}${emptyNote}\\n\\n_Use \\`update-entry\\` to fill in details when ready. Use \\`get-entry\\` to review._`,\n }],\n };\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\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 \\`get-entry\\` to inspect the existing entry, or \\`update-entry\\` to modify it.`,\n }],\n };\n }\n throw error;\n }\n }\n );\n\n server.registerTool(\n \"load-context-for-task\",\n {\n title: \"Load Context for Task\",\n description:\n \"Auto-load relevant domain knowledge for a task in a single call. \" +\n \"Pass a natural-language task description; the tool searches the KB, traverses the knowledge graph, \" +\n \"and returns a ranked set of entries (business rules, glossary terms, decisions, features, etc.) \" +\n \"grouped by collection with a confidence score.\\n\\n\" +\n \"Use this at the start of a conversation to ground the agent in domain context before writing code or making recommendations.\\n\\n\" +\n \"Confidence levels:\\n\" +\n \"- high: 3+ direct KB matches — strong domain coverage\\n\" +\n \"- medium: 1-2 direct matches — partial coverage, may want to drill deeper\\n\" +\n \"- low: no direct matches but related entries found via graph traversal\\n\" +\n \"- none: no relevant entries found — KB may not cover this area yet\",\n inputSchema: {\n taskDescription: z.string().describe(\"Natural-language description of the task or user message\"),\n maxResults: z.number().min(1).max(25).default(10).optional()\n .describe(\"Max entries to return (default 10)\"),\n maxHops: z.number().min(1).max(3).default(2).optional()\n .describe(\"Graph traversal depth from each search hit (default 2)\"),\n },\n annotations: { readOnlyHint: true, openWorldHint: true },\n },\n async ({ taskDescription, maxResults, maxHops }) => {\n await server.sendLoggingMessage({\n level: \"info\",\n data: `Loading context for task: \"${taskDescription.substring(0, 80)}...\"`,\n logger: \"product-os\",\n });\n\n const result = await mcpQuery<{\n entries: Array<{\n entryId?: string;\n name: string;\n collectionSlug: string;\n collectionName: string;\n descriptionPreview: string;\n codePaths: string[];\n hop: number;\n relationType?: string;\n }>;\n confidence: string;\n searchTerms: string;\n totalFound: number;\n }>(\"kb.loadContextForTask\", {\n taskDescription,\n maxResults: maxResults ?? 10,\n maxHops: maxHops ?? 2,\n });\n\n if (result.confidence === \"none\" || result.entries.length === 0) {\n return {\n content: [{\n type: \"text\" as const,\n text: `# Context Loaded\\n\\n**Confidence:** None\\n\\n` +\n `No KB context found for this task. The knowledge base may not cover this area yet.\\n\\n` +\n `_Consider capturing domain knowledge discovered during this task via \\`smart-capture\\`._`,\n }],\n };\n }\n\n const byCollection = new Map<string, typeof result.entries>();\n for (const entry of result.entries) {\n const key = entry.collectionName;\n if (!byCollection.has(key)) byCollection.set(key, []);\n byCollection.get(key)!.push(entry);\n }\n\n const lines: string[] = [\n `# Context Loaded`,\n `**Confidence:** ${result.confidence.charAt(0).toUpperCase() + result.confidence.slice(1)}`,\n `**Matched:** ${result.entries.length} entries across ${byCollection.size} collection${byCollection.size === 1 ? \"\" : \"s\"}`,\n \"\",\n ];\n\n for (const [collName, entries] of byCollection) {\n lines.push(`### ${collName} (${entries.length})`);\n for (const e of entries) {\n const id = e.entryId ? `**${e.entryId}:** ` : \"\";\n const hopLabel = e.hop > 0 ? ` _(hop ${e.hop}${e.relationType ? `, ${e.relationType}` : \"\"})_` : \"\";\n const preview = e.descriptionPreview ? `\\n ${e.descriptionPreview}` : \"\";\n const codePaths = e.codePaths.length > 0 ? `\\n Code: ${e.codePaths.join(\", \")}` : \"\";\n lines.push(`- ${id}${e.name}${hopLabel}${preview}${codePaths}`);\n }\n lines.push(\"\");\n }\n\n lines.push(`_Use \\`get-entry\\` for full details on any entry._`);\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n };\n }\n );\n\n server.registerTool(\n \"review-rules\",\n {\n title: \"Review Business Rules\",\n description:\n \"Surface all active business rules for a domain, formatted for compliance review. \" +\n \"Use when reviewing code, designs, or decisions against ProductBrain governance. \" +\n \"Optionally provide context (what you're building or reviewing) to help focus the review. \" +\n \"This is the tool form of the review-against-rules prompt.\",\n inputSchema: {\n domain: z.string().describe(\"Business rule domain, e.g. 'AI & MCP Integration', 'Governance & Decision-Making'\"),\n context: z.string().optional().describe(\"What you're reviewing — code change, design decision, file path, etc.\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ domain, context }) => {\n const entries = await mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"business-rules\" });\n\n const domainLower = domain.toLowerCase();\n const rules = entries.filter((e) => {\n const ruleDomain = (e.data?.domain ?? \"\") as string;\n return ruleDomain.toLowerCase() === domainLower || ruleDomain.toLowerCase().includes(domainLower);\n });\n\n if (rules.length === 0) {\n const allDomains = [...new Set(entries.map((e) => e.data?.domain).filter(Boolean))];\n return {\n content: [{\n type: \"text\" as const,\n text: `# No Rules Found for \"${domain}\"\\n\\nAvailable domains:\\n${allDomains.map((d) => `- ${d}`).join(\"\\n\")}\\n\\n_Try one of the domains above, or use kb-search to find rules by keyword._`,\n }],\n };\n }\n\n const header = context\n ? `# Business Rules: ${domain}\\n\\n**Review context:** ${context}\\n\\nFor each rule, assess: compliant, at risk, violation, or not applicable.\\n`\n : `# Business Rules: ${domain}\\n`;\n\n const formatted = rules\n .map((r) => {\n const id = r.entryId ? `**${r.entryId}:** ` : \"\";\n const severity = r.data?.severity ? ` | Severity: ${r.data.severity}` : \"\";\n const desc = r.data?.description ?? \"\";\n const impact = r.data?.dataImpact ? `\\n Data impact: ${r.data.dataImpact}` : \"\";\n const related = (r.data?.relatedRules as string[] ?? []).length > 0\n ? `\\n Related: ${(r.data.relatedRules as string[]).join(\", \")}`\n : \"\";\n return `### ${id}${r.name} \\`${r.status}\\`${severity}\\n\\n${desc}${impact}${related}`;\n })\n .join(\"\\n\\n---\\n\\n\");\n\n const footer = `\\n_${rules.length} rule${rules.length === 1 ? \"\" : \"s\"} in this domain. Use \\`get-entry\\` for full details. Use the \\`draft-rule-from-context\\` prompt to propose new rules._`;\n\n return {\n content: [{ type: \"text\" as const, text: `${header}\\n${formatted}\\n${footer}` }],\n };\n }\n );\n}\n","/**\n * PostHog server-side analytics for MCP tool usage.\n *\n * Captures mcp_tool_called and mcp_session_started events so we can track\n * per-workspace, per-developer MCP adoption in the same PostHog project\n * as the frontend.\n *\n * Gracefully no-ops when POSTHOG_MCP_KEY is not set (local dev).\n */\n\nimport { userInfo } from \"node:os\";\nimport { PostHog } from \"posthog-node\";\n\nlet client: PostHog | null = null;\nlet distinctId = \"anonymous\";\n\nconst POSTHOG_HOST = \"https://eu.i.posthog.com\";\n\n/** Only write to stderr when MCP_DEBUG=1 for quieter default DX. */\nfunction log(msg: string): void {\n if (process.env.MCP_DEBUG === \"1\") {\n process.stderr.write(msg);\n }\n}\n\nexport function initAnalytics(): void {\n const apiKey = process.env.POSTHOG_MCP_KEY;\n if (!apiKey) {\n log(\"[MCP-ANALYTICS] POSTHOG_MCP_KEY not set — tracking disabled\\n\");\n return;\n }\n\n client = new PostHog(apiKey, {\n host: POSTHOG_HOST,\n flushAt: 1,\n flushInterval: 5000,\n });\n distinctId = process.env.MCP_USER_ID || fallbackDistinctId();\n\n log(`[MCP-ANALYTICS] Initialized — host=${POSTHOG_HOST} distinctId=${distinctId}\\n`);\n}\n\nfunction fallbackDistinctId(): string {\n try {\n return userInfo().username;\n } catch {\n return `os-${process.pid}`;\n }\n}\n\nexport function trackSessionStarted(\n workspaceSlug: string,\n workspaceId: string,\n serverVersion: string,\n): void {\n if (!client) return;\n client.capture({\n distinctId,\n event: \"mcp_session_started\",\n properties: {\n workspace_slug: workspaceSlug,\n workspace_id: workspaceId,\n server_version: serverVersion,\n source: \"mcp-server\",\n $groups: { workspace: workspaceId },\n },\n });\n}\n\nexport function trackToolCall(\n fn: string,\n status: \"ok\" | \"error\",\n durationMs: number,\n workspaceId: string,\n errorMsg?: string,\n): void {\n const properties: Record<string, unknown> = {\n tool: fn,\n status,\n duration_ms: durationMs,\n workspace_slug: process.env.WORKSPACE_SLUG ?? \"unknown\",\n source: \"mcp-server\",\n $groups: { workspace: workspaceId },\n };\n if (errorMsg) properties.error = errorMsg;\n\n if (!client) return;\n client.capture({\n distinctId,\n event: \"mcp_tool_called\",\n properties,\n });\n}\n\nexport async function shutdownAnalytics(): Promise<void> {\n await client?.shutdown();\n}\n","/**\n * MCP client — communicates with the Convex HTTP Action gateway.\n *\n * Two configuration modes:\n *\n * 1. **Cloud mode** (single key):\n * PRODUCTBRAIN_API_KEY=pb_sk_...\n * The cloud URL is resolved automatically. Workspace is inferred from the key.\n *\n * 2. **Self-hosted mode** (three vars):\n * CONVEX_SITE_URL — base URL of the Convex deployment (*.convex.site)\n * MCP_API_KEY — secret key matching MCP_API_KEY set in the Convex dashboard env vars\n * WORKSPACE_SLUG — slug of the workspace to operate on\n */\n\nimport { trackToolCall } from \"./analytics.js\";\n\nconst DEFAULT_CLOUD_URL = \"https://earnest-sheep-635.convex.site\";\n\nlet cachedWorkspaceId: string | null = null;\nlet cloudMode = false;\n\nexport interface AuditEntry {\n ts: string;\n fn: string;\n workspace: string;\n status: 'ok' | 'error';\n durationMs: number;\n error?: string;\n}\n\nconst AUDIT_BUFFER_SIZE = 50;\nconst auditBuffer: AuditEntry[] = [];\n\n/**\n * Bootstrap cloud mode: if PRODUCTBRAIN_API_KEY is set, map it to the\n * internal env vars so the rest of the client works transparently.\n */\nexport function bootstrapCloudMode(): void {\n const pbKey = process.env.PRODUCTBRAIN_API_KEY;\n if (pbKey?.startsWith(\"pb_sk_\")) {\n const cloudUrl = process.env.PRODUCTBRAIN_URL ?? DEFAULT_CLOUD_URL;\n process.env.CONVEX_SITE_URL ??= cloudUrl;\n process.env.MCP_API_KEY ??= pbKey;\n cloudMode = true;\n }\n}\n\nfunction getEnv(key: string): string {\n const value = process.env[key];\n if (!value) throw new Error(`${key} environment variable is required`);\n return value;\n}\n\n/** Only write audit to stderr on errors, or when MCP_DEBUG=1. Keeps default DX quiet. */\nfunction shouldLogAudit(status: 'ok' | 'error'): boolean {\n return status === 'error' || process.env.MCP_DEBUG === '1';\n}\n\nfunction audit(fn: string, status: 'ok' | 'error', durationMs: number, errorMsg?: string): void {\n const ts = new Date().toISOString();\n const workspace = cachedWorkspaceId ?? 'unresolved';\n\n const entry: AuditEntry = { ts, fn, workspace, status, durationMs };\n if (errorMsg) entry.error = errorMsg;\n auditBuffer.push(entry);\n if (auditBuffer.length > AUDIT_BUFFER_SIZE) auditBuffer.shift();\n\n trackToolCall(fn, status, durationMs, workspace, errorMsg);\n\n if (!shouldLogAudit(status)) return;\n\n const base = `[MCP-AUDIT] ${ts} fn=${fn} workspace=${workspace} status=${status} duration=${durationMs}ms`;\n if (status === 'error' && errorMsg) {\n process.stderr.write(`${base} error=${JSON.stringify(errorMsg)}\\n`);\n } else {\n process.stderr.write(`${base}\\n`);\n }\n}\n\n/** Returns a snapshot of the audit ring buffer (most recent last). */\nexport function getAuditLog(): readonly AuditEntry[] {\n return auditBuffer;\n}\n\n/**\n * Low-level call to the HTTP Action gateway. Does NOT inject workspaceId.\n * Use mcpQuery / mcpMutation for workspace-scoped calls.\n */\nexport async function mcpCall<T>(fn: string, args: Record<string, unknown> = {}): Promise<T> {\n const siteUrl = getEnv('CONVEX_SITE_URL').replace(/\\/$/, '');\n const apiKey = getEnv('MCP_API_KEY');\n\n const start = Date.now();\n\n let res: Response;\n try {\n res = await fetch(`${siteUrl}/api/mcp`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ fn, args }),\n });\n } catch (err: any) {\n audit(fn, 'error', Date.now() - start, err.message);\n throw new Error(`MCP call \"${fn}\" network error: ${err.message}`);\n }\n\n const json = await res.json() as { data?: T; error?: string };\n\n if (!res.ok || json.error) {\n audit(fn, 'error', Date.now() - start, json.error);\n throw new Error(`MCP call \"${fn}\" failed (${res.status}): ${json.error ?? 'unknown error'}`);\n }\n\n audit(fn, 'ok', Date.now() - start);\n return json.data as T;\n}\n\n/** Resolve and cache the workspace ID. Cloud mode resolves from the API key; self-hosted uses WORKSPACE_SLUG. */\nexport async function getWorkspaceId(): Promise<string> {\n if (cachedWorkspaceId) return cachedWorkspaceId;\n\n if (cloudMode) {\n // Cloud keys: the backend resolves workspace from the key itself\n const workspace = await mcpCall<{ _id: string; name: string; slug: string } | null>(\n 'resolveWorkspace',\n { slug: \"__cloud__\" },\n );\n if (!workspace) {\n throw new Error(\"Cloud key is valid but no workspace is associated. Run `npx productbrain setup` again.\");\n }\n cachedWorkspaceId = workspace._id;\n return cachedWorkspaceId;\n }\n\n const slug = getEnv('WORKSPACE_SLUG');\n const workspace = await mcpCall<{ _id: string; name: string; slug: string } | null>(\n 'resolveWorkspace',\n { slug },\n );\n\n if (!workspace) {\n throw new Error(`Workspace with slug \"${slug}\" not found`);\n }\n\n cachedWorkspaceId = workspace._id;\n return cachedWorkspaceId;\n}\n\n/** Call a query scoped to the current workspace. */\nexport async function mcpQuery<T>(fn: string, args: Record<string, unknown> = {}): Promise<T> {\n const workspaceId = await getWorkspaceId();\n return mcpCall<T>(fn, { ...args, workspaceId });\n}\n\n/** Call a mutation scoped to the current workspace. */\nexport async function mcpMutation<T>(fn: string, args: Record<string, unknown> = {}): Promise<T> {\n const workspaceId = await getWorkspaceId();\n return mcpCall<T>(fn, { ...args, workspaceId });\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { mcpQuery, mcpMutation } from \"../client.js\";\n\nexport function registerLabelTools(server: McpServer) {\n\n server.registerTool(\n \"list-labels\",\n {\n title: \"Browse Labels\",\n description:\n \"List all workspace labels with their groups and hierarchy. \" +\n \"Labels can be applied to any entry across any collection for cross-domain filtering. \" +\n \"Similar to labels in Linear or GitHub.\",\n annotations: { readOnlyHint: true },\n },\n async () => {\n const labels = await mcpQuery<any[]>(\"kb.listLabels\");\n\n if (labels.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No labels defined in this workspace yet.\" }] };\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 color = child.color ? ` ${child.color}` : \"\";\n lines.push(` - \\`${child.slug}\\` ${child.name}${color}`);\n }\n }\n\n if (ungrouped.length > 0) {\n lines.push(\"\\n## Ungrouped\");\n for (const label of ungrouped) {\n const color = label.color ? ` ${label.color}` : \"\";\n lines.push(`- \\`${label.slug}\\` ${label.name}${color}${label.description ? ` — _${label.description}_` : \"\"}`);\n }\n }\n\n return {\n content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n };\n }\n );\n\n server.registerTool(\n \"manage-labels\",\n {\n title: \"Manage Labels\",\n description:\n \"Create, update, or delete a workspace label. Labels support hierarchy (groups with children). \" +\n \"Use list-labels first to see what exists.\",\n inputSchema: {\n action: z.enum([\"create\", \"update\", \"delete\"]).describe(\"What to do\"),\n slug: z.string().describe(\"Label slug (machine name), e.g. 'p1-critical', 'needs-review'\"),\n name: z.string().optional().describe(\"Display name (required for create)\"),\n color: z.string().optional().describe(\"Hex color, e.g. '#ef4444'\"),\n description: z.string().optional().describe(\"What this label means\"),\n parentSlug: z.string().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 },\n },\n async ({ action, slug, name, color, description, parentSlug, isGroup, order }) => {\n if (action === \"create\") {\n if (!name) {\n return { content: [{ type: \"text\" as const, text: \"Cannot create a label without a name.\" }] };\n }\n\n let parentId: string | undefined;\n if (parentSlug) {\n const labels = await mcpQuery<any[]>(\"kb.listLabels\");\n const parent = labels.find((l: any) => l.slug === parentSlug);\n if (!parent) {\n return { content: [{ type: \"text\" as const, text: `Parent label \\`${parentSlug}\\` not found. Use list-labels to see available groups.` }] };\n }\n parentId = parent._id;\n }\n\n await mcpMutation(\"kb.createLabel\", { slug, name, color, description, parentId, isGroup, order });\n return { content: [{ type: \"text\" as const, text: `# Label Created\\n\\n**${name}** (\\`${slug}\\`)` }] };\n }\n\n if (action === \"update\") {\n await mcpMutation(\"kb.updateLabel\", { slug, name, color, description, isGroup, order });\n return { content: [{ type: \"text\" as const, text: `# Label Updated\\n\\n\\`${slug}\\` has been updated.` }] };\n }\n\n if (action === \"delete\") {\n await mcpMutation(\"kb.deleteLabel\", { slug });\n return { content: [{ type: \"text\" as const, text: `# Label Deleted\\n\\n\\`${slug}\\` removed from all entries and deleted.` }] };\n }\n\n return { content: [{ type: \"text\" as const, text: \"Unknown action.\" }] };\n }\n );\n\n server.registerTool(\n \"label-entry\",\n {\n title: \"Tag Entry with Label\",\n description:\n \"Apply or remove a label from a knowledge entry. Labels work across all collections for cross-domain filtering. \" +\n \"Use list-labels to see available label slugs.\",\n inputSchema: {\n action: z.enum([\"apply\", \"remove\"]).describe(\"Apply or remove the label\"),\n entryId: z.string().describe(\"Entry ID, e.g. 'T-SUPPLIER', 'EVT-workspace_created'\"),\n label: z.string().describe(\"Label slug to apply/remove\"),\n },\n },\n async ({ action, entryId, label }) => {\n if (action === \"apply\") {\n await mcpMutation(\"kb.applyLabel\", { entryId, labelSlug: label });\n return { content: [{ type: \"text\" as const, text: `Label \\`${label}\\` applied to **${entryId}**.` }] };\n }\n\n await mcpMutation(\"kb.removeLabel\", { entryId, labelSlug: label });\n return { content: [{ type: \"text\" as const, text: `Label \\`${label}\\` removed from **${entryId}**.` }] };\n }\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { mcpQuery, getWorkspaceId, getAuditLog, type AuditEntry } from \"../client.js\";\n\ntype CallCategory = \"read\" | \"search\" | \"write\" | \"label\" | \"meta\";\n\nconst CALL_CATEGORIES: Record<string, CallCategory> = {\n \"kb.getEntry\": \"read\",\n \"kb.listEntries\": \"read\",\n \"kb.listEntryHistory\": \"read\",\n \"kb.listEntryRelations\": \"read\",\n \"kb.listEntriesByLabel\": \"read\",\n \"kb.searchEntries\": \"search\",\n \"kb.createEntry\": \"write\",\n \"kb.updateEntry\": \"write\",\n \"kb.createEntryRelation\": \"write\",\n \"kb.applyLabel\": \"label\",\n \"kb.removeLabel\": \"label\",\n \"kb.createLabel\": \"label\",\n \"kb.updateLabel\": \"label\",\n \"kb.deleteLabel\": \"label\",\n \"kb.listCollections\": \"meta\",\n \"kb.getCollection\": \"meta\",\n \"kb.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 === \"kb.createEntry\" && entry.status === \"ok\") writeCreates++;\n if (entry.fn === \"kb.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(\"kb.\", \"\")} 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\nexport function registerHealthTools(server: McpServer) {\n\n server.registerTool(\n \"health\",\n {\n title: \"Health Check\",\n description:\n \"Verify that ProductBrain is running and can reach its backend. \" +\n \"Returns workspace status, collection count, entry count, and latency. \" +\n \"Use this to confirm connectivity before doing real work.\",\n annotations: { readOnlyHint: true },\n },\n async () => {\n const start = Date.now();\n const errors: string[] = [];\n\n let workspaceId: string | undefined;\n try {\n workspaceId = await getWorkspaceId();\n } catch (e: any) {\n errors.push(`Workspace resolution failed: ${e.message}`);\n }\n\n let collections: any[] = [];\n try {\n collections = await mcpQuery<any[]>(\"kb.listCollections\");\n } catch (e: any) {\n errors.push(`Collection fetch failed: ${e.message}`);\n }\n\n let totalEntries = 0;\n if (collections.length > 0) {\n try {\n const entries = await mcpQuery<any[]>(\"kb.listEntries\", {});\n totalEntries = entries.length;\n } catch (e: any) {\n errors.push(`Entry count failed: ${e.message}`);\n }\n }\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 `**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 return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n );\n\n server.registerTool(\n \"mcp-audit\",\n {\n title: \"Session Audit Log\",\n description:\n \"Show a session summary (reads, writes, searches, contributions) and the last N backend calls. \" +\n \"Useful for debugging, tracing tool behavior, and seeing what you contributed to the knowledge base.\",\n inputSchema: {\n limit: z.number().min(1).max(50).default(20).describe(\"How many recent calls to show (max 50)\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ limit }) => {\n const log = getAuditLog();\n const recent = log.slice(-limit);\n\n if (recent.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No calls recorded yet this session.\" }] };\n }\n\n const summary = buildSessionSummary(log);\n\n const logLines = [`# Audit Log (last ${recent.length} of ${log.length} total)\\n`];\n for (const entry of recent) {\n const icon = entry.status === \"ok\" ? \"\\u2713\" : \"\\u2717\";\n const errPart = entry.error ? ` \\u2014 ${entry.error}` : \"\";\n logLines.push(`${icon} \\`${entry.fn}\\` ${entry.durationMs}ms ${entry.status}${errPart}`);\n }\n\n return {\n content: [{ type: \"text\" as const, text: `${summary}\\n\\n---\\n\\n${logLines.join(\"\\n\")}` }],\n };\n }\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { mcpQuery, mcpMutation } from \"../client.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// ── Project Root Resolution ────────────────────────────────────────────\n\nfunction resolveProjectRoot(): string | null {\n const candidates = [\n process.env.WORKSPACE_PATH,\n process.cwd(),\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\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 function registerVerifyTools(server: McpServer) {\n server.registerTool(\n \"verify\",\n {\n title: \"Verify Knowledge Base\",\n description:\n \"Verify knowledge entries against the actual codebase. Checks glossary code mappings \" +\n \"(do referenced files and schema fields still exist?) and validates cross-references \" +\n \"(do relatedRules point to real entries?). Produces a trust report with a trust score. \" +\n \"Use mode='fix' to auto-update drifted codeMapping statuses.\",\n inputSchema: {\n collection: z.string().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 annotations: { readOnlyHint: false },\n },\n async ({ collection, mode }) => {\n const projectRoot = resolveProjectRoot();\n if (!projectRoot) {\n return {\n content: [{\n type: \"text\" as const,\n text: \"# 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 ProductBrain project root.\",\n }],\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 mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: collection });\n\n if (scopedEntries.length === 0) {\n return {\n content: [{ type: \"text\" as const, text: `No entries found in \\`${collection}\\`. Nothing to verify.` }],\n };\n }\n\n // Build cross-reference lookup: fetch all entries to check relatedRules\n let allEntryIds: Set<string>;\n try {\n const allEntries = await mcpQuery<any[]>(\"kb.listEntries\", {});\n allEntryIds = new Set(allEntries.map((e: any) => e.entryId).filter(Boolean));\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 (const entry of scopedEntries) {\n const eid = entry.entryId ?? entry.name;\n const ename = entry.name;\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 // ── Fix mode: update aligned → drifted ──\n const fixes: 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\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 await mcpMutation(\"kb.updateEntry\", {\n entryId: entry.entryId,\n data: { codeMapping: updated },\n });\n fixes.push(entry.entryId);\n }\n }\n\n const report = formatTrustReport(\n collection, scopedEntries.length,\n mappingChecks, refChecks, fixes, mode,\n schema.size, projectRoot,\n );\n\n return { content: [{ type: \"text\" as const, text: report }] };\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { mcpQuery, mcpMutation } from \"../client.js\";\n\n// ── Collection Workflow Profiles ────────────────────────────────────────────\n\ninterface FieldDefault {\n key: string;\n value: unknown | \"today\" | \"infer\";\n}\n\ninterface QualityCheck {\n id: string;\n label: string;\n check: (ctx: CaptureContext) => boolean;\n suggestion?: (ctx: CaptureContext) => string;\n}\n\ninterface CollectionProfile {\n idPrefix: string;\n governedDraft: boolean;\n defaults: FieldDefault[];\n descriptionField: string;\n recommendedRelationTypes: string[];\n qualityChecks: QualityCheck[];\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 linksCreated: LinkResult[];\n linksSuggested: LinkSuggestion[];\n collectionFields: Array<{ key: string; type: string; required?: boolean }>;\n}\n\ninterface LinkResult {\n targetEntryId: string;\n targetName: string;\n targetCollection: string;\n relationType: string;\n}\n\ninterface LinkSuggestion {\n entryId?: string;\n name: string;\n collection: string;\n reason: string;\n preview: string;\n}\n\nconst AREA_KEYWORDS: Record<string, string[]> = {\n \"Architecture\": [\"convex\", \"schema\", \"database\", \"migration\", \"api\", \"backend\", \"infrastructure\", \"scaling\", \"performance\"],\n \"Knowledge Base\": [\"knowledge\", \"glossary\", \"entry\", \"collection\", \"terminology\", \"drift\", \"graph\"],\n \"AI & MCP Integration\": [\"mcp\", \"ai\", \"cursor\", \"agent\", \"tool\", \"llm\", \"prompt\", \"context\"],\n \"Developer Experience\": [\"dx\", \"developer\", \"ide\", \"workflow\", \"friction\", \"ceremony\"],\n \"Governance & Decision-Making\": [\"governance\", \"decision\", \"rule\", \"policy\", \"compliance\", \"approval\"],\n \"Analytics & Tracking\": [\"analytics\", \"posthog\", \"tracking\", \"event\", \"metric\", \"funnel\"],\n \"Security\": [\"security\", \"auth\", \"api key\", \"permission\", \"access\", \"token\"],\n};\n\nfunction inferArea(text: string): string {\n const lower = text.toLowerCase();\n let bestArea = \"\";\n let bestScore = 0;\n for (const [area, keywords] of Object.entries(AREA_KEYWORDS)) {\n const score = keywords.filter((kw) => lower.includes(kw)).length;\n if (score > bestScore) {\n bestScore = score;\n bestArea = area;\n }\n }\n return bestArea;\n}\n\nfunction inferDomain(text: string): string {\n return inferArea(text) || \"\";\n}\n\nconst COMMON_CHECKS: Record<string, QualityCheck> = {\n clearName: {\n id: \"clear-name\",\n label: \"Clear, specific name (not vague)\",\n check: (ctx) => ctx.name.length > 10 && ![\"new tension\", \"new entry\", \"untitled\", \"test\"].includes(ctx.name.toLowerCase()),\n suggestion: () => \"Rename to something specific — describe the actual problem or concept.\",\n },\n hasDescription: {\n id: \"has-description\",\n label: \"Description provided (>50 chars)\",\n check: (ctx) => ctx.description.length > 50,\n suggestion: () => \"Add a fuller description explaining context and impact.\",\n },\n hasRelations: {\n id: \"has-relations\",\n label: \"At least 1 relation created\",\n check: (ctx) => ctx.linksCreated.length >= 1,\n suggestion: () => \"Use `suggest-links` and `relate-entries` to connect this entry to related knowledge.\",\n },\n diverseRelations: {\n id: \"diverse-relations\",\n label: \"Relations span multiple collections\",\n check: (ctx) => {\n const colls = new Set(ctx.linksCreated.map((l) => l.targetCollection));\n return colls.size >= 2;\n },\n suggestion: () => \"Try linking to entries in different collections (glossary, business-rules, strategy).\",\n },\n};\n\nconst PROFILES: Map<string, CollectionProfile> = new Map([\n [\"tensions\", {\n idPrefix: \"TEN\",\n governedDraft: false,\n descriptionField: \"description\",\n defaults: [\n { key: \"priority\", value: \"medium\" },\n { key: \"date\", value: \"today\" },\n { key: \"raised\", value: \"infer\" },\n { key: \"severity\", value: \"infer\" },\n ],\n recommendedRelationTypes: [\"surfaces_tension_in\", \"references\", \"belongs_to\", \"related_to\"],\n inferField: (ctx) => {\n const fields: Record<string, unknown> = {};\n const text = `${ctx.name} ${ctx.description}`;\n const area = inferArea(text);\n if (area) fields.raised = area;\n if (text.toLowerCase().includes(\"critical\") || text.toLowerCase().includes(\"blocker\")) {\n fields.severity = \"critical\";\n } else if (text.toLowerCase().includes(\"bottleneck\") || text.toLowerCase().includes(\"scaling\") || text.toLowerCase().includes(\"breaking\")) {\n fields.severity = \"high\";\n } else {\n fields.severity = \"medium\";\n }\n if (area) fields.affectedArea = area;\n return fields;\n },\n qualityChecks: [\n COMMON_CHECKS.clearName,\n COMMON_CHECKS.hasDescription,\n COMMON_CHECKS.hasRelations,\n {\n id: \"has-severity\",\n label: \"Severity specified\",\n check: (ctx) => !!ctx.data.severity && ctx.data.severity !== \"\",\n suggestion: (ctx) => {\n const text = `${ctx.name} ${ctx.description}`.toLowerCase();\n const inferred = text.includes(\"critical\") ? \"critical\" : text.includes(\"bottleneck\") ? \"high\" : \"medium\";\n return `Set severity — suggest: ${inferred} (based on description keywords).`;\n },\n },\n {\n id: \"has-affected-area\",\n label: \"Affected area identified\",\n check: (ctx) => !!ctx.data.affectedArea && ctx.data.affectedArea !== \"\",\n suggestion: (ctx) => {\n const area = inferArea(`${ctx.name} ${ctx.description}`);\n return area\n ? `Set affectedArea — suggest: \"${area}\" (inferred from content).`\n : \"Specify which product area or domain this tension impacts.\";\n },\n },\n ],\n }],\n\n [\"business-rules\", {\n idPrefix: \"SOS\",\n governedDraft: true,\n descriptionField: \"description\",\n defaults: [\n { key: \"severity\", value: \"medium\" },\n { key: \"domain\", value: \"infer\" },\n ],\n recommendedRelationTypes: [\"governs\", \"references\", \"conflicts_with\", \"related_to\"],\n inferField: (ctx) => {\n const fields: Record<string, unknown> = {};\n const domain = inferDomain(`${ctx.name} ${ctx.description}`);\n if (domain) fields.domain = domain;\n return fields;\n },\n qualityChecks: [\n COMMON_CHECKS.clearName,\n COMMON_CHECKS.hasDescription,\n COMMON_CHECKS.hasRelations,\n {\n id: \"has-rationale\",\n label: \"Rationale provided\",\n check: (ctx) => typeof ctx.data.rationale === \"string\" && ctx.data.rationale.length > 10,\n suggestion: () => \"Add a rationale explaining why this rule exists via `update-entry`.\",\n },\n {\n id: \"has-domain\",\n label: \"Domain specified\",\n check: (ctx) => !!ctx.data.domain && ctx.data.domain !== \"\",\n suggestion: (ctx) => {\n const domain = inferDomain(`${ctx.name} ${ctx.description}`);\n return domain\n ? `Set domain — suggest: \"${domain}\" (inferred from content).`\n : \"Specify the business domain this rule belongs to.\";\n },\n },\n ],\n }],\n\n [\"glossary\", {\n idPrefix: \"GT\",\n governedDraft: true,\n descriptionField: \"canonical\",\n defaults: [\n { key: \"category\", value: \"infer\" },\n ],\n recommendedRelationTypes: [\"defines_term_for\", \"confused_with\", \"related_to\", \"references\"],\n inferField: (ctx) => {\n const fields: Record<string, unknown> = {};\n const area = inferArea(`${ctx.name} ${ctx.description}`);\n if (area) {\n const categoryMap: Record<string, string> = {\n \"Architecture\": \"Platform & Architecture\",\n \"Knowledge Base\": \"Knowledge Management\",\n \"AI & MCP Integration\": \"AI & Developer Tools\",\n \"Developer Experience\": \"AI & Developer Tools\",\n \"Governance & Decision-Making\": \"Governance & Process\",\n \"Analytics & Tracking\": \"Platform & Architecture\",\n \"Security\": \"Platform & Architecture\",\n };\n fields.category = categoryMap[area] ?? \"\";\n }\n return fields;\n },\n qualityChecks: [\n COMMON_CHECKS.clearName,\n {\n id: \"has-canonical\",\n label: \"Canonical definition provided (>20 chars)\",\n check: (ctx) => {\n const canonical = ctx.data.canonical;\n return typeof canonical === \"string\" && canonical.length > 20;\n },\n suggestion: () => \"Add a clear canonical definition — this is the single source of truth for this term.\",\n },\n COMMON_CHECKS.hasRelations,\n {\n id: \"has-category\",\n label: \"Category assigned\",\n check: (ctx) => !!ctx.data.category && ctx.data.category !== \"\",\n suggestion: () => \"Assign a category (e.g., 'Platform & Architecture', 'Governance & Process').\",\n },\n ],\n }],\n\n [\"decisions\", {\n idPrefix: \"DEC\",\n governedDraft: false,\n descriptionField: \"rationale\",\n defaults: [\n { key: \"date\", value: \"today\" },\n { key: \"decidedBy\", value: \"infer\" },\n ],\n recommendedRelationTypes: [\"informs\", \"references\", \"replaces\", \"related_to\"],\n inferField: (ctx) => {\n const fields: Record<string, unknown> = {};\n const area = inferArea(`${ctx.name} ${ctx.description}`);\n if (area) fields.decidedBy = area;\n return fields;\n },\n qualityChecks: [\n COMMON_CHECKS.clearName,\n {\n id: \"has-rationale\",\n label: \"Rationale provided (>30 chars)\",\n check: (ctx) => {\n const rationale = ctx.data.rationale;\n return typeof rationale === \"string\" && rationale.length > 30;\n },\n suggestion: () => \"Explain why this decision was made — what was considered and rejected?\",\n },\n COMMON_CHECKS.hasRelations,\n {\n id: \"has-date\",\n label: \"Decision date recorded\",\n check: (ctx) => !!ctx.data.date && ctx.data.date !== \"\",\n suggestion: () => \"Record when this decision was made.\",\n },\n ],\n }],\n]);\n\nconst FALLBACK_PROFILE: CollectionProfile = {\n idPrefix: \"\",\n governedDraft: false,\n descriptionField: \"description\",\n defaults: [],\n recommendedRelationTypes: [\"related_to\", \"references\"],\n qualityChecks: [\n COMMON_CHECKS.clearName,\n COMMON_CHECKS.hasDescription,\n COMMON_CHECKS.hasRelations,\n ],\n};\n\n// ── ID Generation ───────────────────────────────────────────────────────────\n\nfunction generateEntryId(prefix: string): string {\n if (!prefix) return \"\";\n const chars = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let suffix = \"\";\n for (let i = 0; i < 6; i++) {\n suffix += chars[Math.floor(Math.random() * chars.length)];\n }\n return `${prefix}-${suffix}`;\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\nfunction computeLinkConfidence(\n candidate: { name: string; data?: any; entryId?: string },\n sourceName: string,\n sourceDescription: string,\n sourceCollection: string,\n candidateCollection: string,\n): number {\n const text = `${sourceName} ${sourceDescription}`.toLowerCase();\n const candidateName = candidate.name.toLowerCase();\n let score = 0;\n\n if (text.includes(candidateName) && candidateName.length > 3) {\n score += 40;\n }\n\n const candidateWords = candidateName.split(/\\s+/).filter((w) => w.length > 3);\n const matchingWords = candidateWords.filter((w) => text.includes(w));\n score += (matchingWords.length / Math.max(candidateWords.length, 1)) * 30;\n\n const HUB_COLLECTIONS = new Set([\"strategy\", \"features\"]);\n if (HUB_COLLECTIONS.has(candidateCollection)) {\n score += 15;\n }\n\n if (candidateCollection !== sourceCollection) {\n score += 10;\n }\n\n return Math.min(score, 100);\n}\n\nfunction inferRelationType(\n sourceCollection: string,\n targetCollection: string,\n profile: CollectionProfile,\n): string {\n const typeMap: Record<string, Record<string, string>> = {\n tensions: {\n glossary: \"surfaces_tension_in\",\n \"business-rules\": \"references\",\n strategy: \"belongs_to\",\n features: \"surfaces_tension_in\",\n decisions: \"references\",\n },\n \"business-rules\": {\n glossary: \"references\",\n features: \"governs\",\n strategy: \"belongs_to\",\n tensions: \"references\",\n },\n glossary: {\n features: \"defines_term_for\",\n \"business-rules\": \"references\",\n strategy: \"references\",\n },\n decisions: {\n features: \"informs\",\n \"business-rules\": \"references\",\n strategy: \"references\",\n tensions: \"references\",\n },\n };\n\n return typeMap[sourceCollection]?.[targetCollection]\n ?? profile.recommendedRelationTypes[0]\n ?? \"related_to\";\n}\n\n// ── Quality Scoring ─────────────────────────────────────────────────────────\n\ninterface QualityResult {\n score: number;\n maxScore: number;\n checks: Array<{ id: string; label: string; passed: boolean; suggestion?: string }>;\n}\n\nfunction scoreQuality(ctx: CaptureContext, profile: CollectionProfile): QualityResult {\n const checks = profile.qualityChecks.map((qc) => {\n const passed = qc.check(ctx);\n return {\n id: qc.id,\n label: qc.label,\n passed,\n suggestion: passed ? undefined : qc.suggestion?.(ctx),\n };\n });\n\n const passed = checks.filter((c) => c.passed).length;\n const total = checks.length;\n const score = total > 0 ? Math.round((passed / total) * 10) : 10;\n\n return { score, maxScore: 10, checks };\n}\n\nexport function formatQualityReport(result: QualityResult): string {\n const lines: string[] = [`## Quality: ${result.score}/${result.maxScore}`];\n for (const check of result.checks) {\n const icon = check.passed ? \"[x]\" : \"[ ]\";\n const suggestion = check.passed ? \"\" : ` -- ${check.suggestion ?? \"\"}`;\n lines.push(`${icon} ${check.label}${suggestion}`);\n }\n return lines.join(\"\\n\");\n}\n\n// ── Exported: quality-check for existing entries ────────────────────────────\n\nexport async function checkEntryQuality(entryId: string): Promise<{ text: string; quality: QualityResult }> {\n const entry = await mcpQuery<any>(\"kb.getEntry\", { entryId });\n if (!entry) {\n return {\n text: `Entry \\`${entryId}\\` not found. Try kb-search to find the right ID.`,\n quality: { score: 0, maxScore: 10, checks: [] },\n };\n }\n\n const collections = await mcpQuery<any[]>(\"kb.listCollections\");\n const collMap = new Map<string, string>();\n for (const c of collections) collMap.set(c._id, c.slug);\n const collectionSlug = collMap.get(entry.collectionId) ?? \"unknown\";\n\n const profile = PROFILES.get(collectionSlug) ?? FALLBACK_PROFILE;\n\n const relations = await mcpQuery<any[]>(\"kb.listEntryRelations\", { entryId });\n const linksCreated: LinkResult[] = [];\n for (const r of relations) {\n const otherId = r.fromId === entry._id ? r.toId : r.fromId;\n linksCreated.push({\n targetEntryId: otherId,\n targetName: \"\",\n targetCollection: \"\",\n relationType: r.type,\n });\n }\n\n const descField = profile.descriptionField;\n const description = typeof entry.data?.[descField] === \"string\" ? entry.data[descField] : \"\";\n\n const ctx: CaptureContext = {\n collection: collectionSlug,\n name: entry.name,\n description,\n data: entry.data ?? {},\n entryId: entry.entryId ?? \"\",\n linksCreated,\n linksSuggested: [],\n collectionFields: [],\n };\n\n const quality = scoreQuality(ctx, profile);\n\n const lines: string[] = [\n `# Quality Check: ${entry.entryId ?? entry.name}`,\n `**${entry.name}** in \\`${collectionSlug}\\` [${entry.status}]`,\n \"\",\n formatQualityReport(quality),\n ];\n\n if (quality.score < 10) {\n const failedChecks = quality.checks.filter((c) => !c.passed && c.suggestion);\n if (failedChecks.length > 0) {\n lines.push(\"\");\n lines.push(`_To improve: use \\`update-entry\\` to fill missing fields, or \\`relate-entries\\` to add connections._`);\n }\n }\n\n return { text: lines.join(\"\\n\"), quality };\n}\n\n// ── Tool Registration ───────────────────────────────────────────────────────\n\nconst GOVERNED_COLLECTIONS = new Set([\n \"glossary\", \"business-rules\", \"principles\", \"standards\", \"strategy\", \"features\",\n]);\n\nconst AUTO_LINK_CONFIDENCE_THRESHOLD = 35;\nconst MAX_AUTO_LINKS = 5;\nconst MAX_SUGGESTIONS = 5;\n\nexport function registerSmartCaptureTools(server: McpServer) {\n\n server.registerTool(\n \"smart-capture\",\n {\n title: \"Smart Capture\",\n description:\n \"One-call knowledge capture: creates an entry, auto-links related entries, and returns a quality scorecard. \" +\n \"Replaces the multi-step workflow of create-entry + suggest-links + relate-entries. \" +\n \"Provide a collection, name, and description — everything else is inferred or auto-filled.\\n\\n\" +\n \"Supported collections with smart profiles: tensions, business-rules, glossary, decisions.\\n\" +\n \"All other collections use sensible defaults (same as quick-capture + auto-linking).\\n\\n\" +\n \"Always creates as 'draft' for governed collections. Embodies 'Capture Now, Curate Later' (PRI-81cbdq).\",\n inputSchema: {\n collection: z.string().describe(\"Collection slug, e.g. 'tensions', 'business-rules', 'glossary', 'decisions'\"),\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 gather-context calls taking 700ms+')\"),\n entryId: z.string().optional().describe(\"Optional custom entry ID (e.g. 'TEN-my-id'). Auto-generated if omitted.\"),\n },\n annotations: { destructiveHint: false },\n },\n async ({ collection, name, description, context, entryId }) => {\n const profile = PROFILES.get(collection) ?? FALLBACK_PROFILE;\n\n // 1. Resolve collection schema\n const col = await mcpQuery<any>(\"kb.getCollection\", { slug: collection });\n if (!col) {\n return {\n content: [{ type: \"text\" as const, text: `Collection \\`${collection}\\` not found. Use \\`list-collections\\` to see available collections.` }],\n };\n }\n\n // 2. Build data with profile defaults + inference\n const data: Record<string, unknown> = {};\n const today = new Date().toISOString().split(\"T\")[0];\n\n for (const field of col.fields ?? []) {\n const key = field.key as string;\n if (key === profile.descriptionField) {\n data[key] = description;\n } else if (field.type === \"array\" || field.type === \"multi-select\") {\n data[key] = [];\n } else {\n data[key] = \"\";\n }\n }\n\n for (const def of profile.defaults) {\n if (def.value === \"today\") {\n data[def.key] = today;\n } else if (def.value !== \"infer\") {\n data[def.key] = def.value;\n }\n }\n\n if (profile.inferField) {\n const inferred = profile.inferField({\n collection, 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 (!data[profile.descriptionField] && !data.description && !data.canonical) {\n data[profile.descriptionField || \"description\"] = description;\n }\n\n // 3. Determine status\n const status = GOVERNED_COLLECTIONS.has(collection) ? \"draft\" : \"draft\";\n\n // 4. Generate entry ID\n const finalEntryId = entryId ?? generateEntryId(profile.idPrefix);\n\n // 5. Create entry\n let internalId: string;\n try {\n internalId = await mcpMutation<string>(\"kb.createEntry\", {\n collectionSlug: collection,\n entryId: finalEntryId || undefined,\n name,\n status,\n data,\n createdBy: \"smart-capture\",\n });\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\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 \\`get-entry\\` to inspect the existing entry, or \\`update-entry\\` to modify it.`,\n }],\n };\n }\n throw error;\n }\n\n // 6. Discover and auto-link related entries\n const linksCreated: LinkResult[] = [];\n const linksSuggested: LinkSuggestion[] = [];\n\n const searchQuery = extractSearchTerms(name, description);\n if (searchQuery) {\n const [searchResults, allCollections] = await Promise.all([\n mcpQuery<any[]>(\"kb.searchEntries\", { query: searchQuery }),\n mcpQuery<any[]>(\"kb.listCollections\"),\n ]);\n\n const collMap = new Map<string, string>();\n for (const c of allCollections) collMap.set(c._id, c.slug);\n\n const candidates = (searchResults ?? [])\n .filter((r) => r.entryId !== finalEntryId && r._id !== internalId)\n .map((r) => ({\n ...r,\n collSlug: collMap.get(r.collectionId) ?? \"unknown\",\n confidence: computeLinkConfidence(r, name, description, collection, collMap.get(r.collectionId) ?? \"unknown\"),\n }))\n .sort((a, b) => b.confidence - a.confidence);\n\n // Auto-link high-confidence matches\n for (const c of candidates) {\n if (linksCreated.length >= MAX_AUTO_LINKS) break;\n if (c.confidence < AUTO_LINK_CONFIDENCE_THRESHOLD) break;\n if (!c.entryId || !finalEntryId) continue;\n\n const relationType = inferRelationType(collection, c.collSlug, profile);\n try {\n await mcpMutation(\"kb.createEntryRelation\", {\n fromEntryId: finalEntryId,\n toEntryId: c.entryId,\n type: relationType,\n });\n linksCreated.push({\n targetEntryId: c.entryId,\n targetName: c.name,\n targetCollection: c.collSlug,\n relationType,\n });\n } catch {\n // Relation creation failed (e.g. entry not found) — skip silently\n }\n }\n\n // Collect suggestions for remaining candidates\n const linkedIds = new Set(linksCreated.map((l) => l.targetEntryId));\n for (const c of candidates) {\n if (linksSuggested.length >= MAX_SUGGESTIONS) break;\n if (linkedIds.has(c.entryId)) continue;\n if (c.confidence < 10) continue;\n\n const preview = extractPreview(c.data, 80);\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({\n entryId: c.entryId,\n name: c.name,\n collection: c.collSlug,\n reason,\n preview,\n });\n }\n }\n\n // 7. Score quality\n const captureCtx: CaptureContext = {\n collection,\n name,\n description,\n context,\n data,\n entryId: finalEntryId,\n linksCreated,\n linksSuggested,\n collectionFields: col.fields ?? [],\n };\n const quality = scoreQuality(captureCtx, profile);\n\n // 8. Format response\n const lines: string[] = [\n `# Captured: ${finalEntryId || name}`,\n `**${name}** added to \\`${collection}\\` as \\`${status}\\``,\n ];\n\n if (linksCreated.length > 0) {\n lines.push(\"\");\n lines.push(`## Auto-linked (${linksCreated.length})`);\n for (const link of linksCreated) {\n lines.push(`- -> **${link.relationType}** ${link.targetEntryId}: ${link.targetName} [${link.targetCollection}]`);\n }\n }\n\n if (linksSuggested.length > 0) {\n lines.push(\"\");\n lines.push(\"## Suggested links (review and use relate-entries)\");\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 lines.push(\"\");\n lines.push(formatQualityReport(quality));\n\n const failedChecks = quality.checks.filter((c) => !c.passed);\n if (failedChecks.length > 0) {\n lines.push(\"\");\n lines.push(`_To improve: \\`update-entry entryId=\"${finalEntryId}\"\\` to fill missing fields._`);\n }\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n );\n\n // ── Quality Check Tool ──────────────────────────────────────────────────\n\n server.registerTool(\n \"quality-check\",\n {\n title: \"Quality Check\",\n description:\n \"Score an existing knowledge entry against collection-specific quality criteria. \" +\n \"Returns a scorecard (X/10) with specific, actionable suggestions for improvement. \" +\n \"Checks: name clarity, description completeness, relation connectedness, and collection-specific fields.\\n\\n\" +\n \"Use after creating entries to assess their quality, or to audit existing entries.\",\n inputSchema: {\n entryId: z.string().describe(\"Entry ID to check, e.g. 'TEN-graph-db', 'GT-019', 'SOS-006'\"),\n },\n annotations: { readOnlyHint: true },\n },\n async ({ entryId }) => {\n const result = await checkEntryQuality(entryId);\n return { content: [{ type: \"text\" as const, text: result.text }] };\n }\n );\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nfunction extractPreview(data: any, maxLen: number): string {\n if (!data || typeof data !== \"object\") return \"\";\n const raw = data.description ?? data.canonical ?? data.detail ?? data.rule ?? \"\";\n if (typeof raw !== \"string\" || !raw) return \"\";\n return raw.length > maxLen ? raw.substring(0, maxLen) + \"...\" : raw;\n}\n","import { McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { mcpQuery } from \"../client.js\";\n\nfunction formatEntryMarkdown(entry: any): 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: any[] | null,\n trackingEvents: any[] | null,\n standards: any[] | null,\n businessRules: any[] | null,\n): string {\n const sections: string[] = [\"# ProductBrain — Orientation\"];\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/mcp with Bearer token\\n\" +\n \" → Convex HTTP Action (convex/http.ts)\\n\" +\n \" → internalQuery / internalMutation (convex/mcpKnowledge.ts)\\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: `mcp-server/src/client.ts` (HTTP client + audit), `convex/schema.ts` (9-table 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 \"Tags for filtering (e.g. `severity:high`), relations via `entryRelations`, history via `entryHistory`, labels via `labels` + `entryLabels`.\\n\\n\" +\n collList + \"\\n\\n\" +\n \"Use `list-collections` for field schemas, `get-entry` for full records.\",\n );\n } else {\n sections.push(\n \"## Data Model\\n\" +\n \"Could not load collections — use `list-collections` 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: `kb-search` for text search, `list-entries 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: `list-entries collection=tracking-events`. Full setup: `docs/posthog-setup.md`.\",\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\\n\" +\n \"- `informs` — a decision or insight informs a feature\\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.\\n\\n\" +\n \"**Tools:**\\n\" +\n \"- `gather-context` — get the full context around any entry (multi-hop graph traversal)\\n\" +\n \"- `suggest-links` — discover potential connections for an entry\\n\" +\n \"- `relate-entries` — create a typed link between two entries\\n\" +\n \"- `find-related` — list direct relations for an entry\\n\\n\" +\n \"**Convention:** When creating or updating entries in governed collections, always use `suggest-links` to discover and create relevant relations.\",\n );\n\n // Creating Knowledge\n sections.push(\n \"## Creating Knowledge\\n\" +\n \"Use `smart-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 knowledge base (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`.\\n\" +\n \"All other collections use sensible defaults.\\n\\n\" +\n \"Example: `smart-capture collection='tensions' name='...' description='...'`\\n\\n\" +\n \"Use `quality-check` to score existing entries retroactively.\\n\" +\n \"Use `create-entry` only when you need full control over every field.\\n\" +\n \"Use `quick-capture` for minimal ceremony without auto-linking.\",\n );\n\n // Where to go next\n sections.push(\n \"## Where to Go Next\\n\" +\n \"- **Create entry** → `smart-capture` tool (auto-links + quality score in one call)\\n\" +\n \"- **Full context** → `gather-context` tool (start here when working on a feature)\\n\" +\n \"- **Discover links** → `suggest-links` tool\\n\" +\n \"- **Quality audit** → `quality-check` tool\\n\" +\n \"- **Terminology** → `name-check` prompt or `productbrain://terminology` resource\\n\" +\n \"- **Schema details** → `productbrain://collections` resource or `list-collections` tool\\n\" +\n \"- **Labels** → `productbrain://labels` resource or `list-labels` tool\\n\" +\n \"- **Any collection** → `productbrain://{slug}/entries` resource\\n\" +\n \"- **Log a decision** → `draft-decision-record` prompt\\n\" +\n \"- **Health check** → `health` tool\\n\" +\n \"- **Debug MCP calls** → `mcp-audit` tool\",\n );\n\n return sections.join(\"\\n\\n---\\n\\n\");\n}\n\nexport function registerResources(server: McpServer) {\n // Orientation: single-call system map for AI developers\n server.resource(\n \"kb-orientation\",\n \"productbrain://orientation\",\n async (uri) => {\n const [collectionsResult, eventsResult, standardsResult, rulesResult] = await Promise.allSettled([\n mcpQuery<any[]>(\"kb.listCollections\"),\n mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"tracking-events\" }),\n mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"standards\" }),\n mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"business-rules\" }),\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\n return {\n contents: [{\n uri: uri.href,\n text: buildOrientationMarkdown(collections, trackingEvents, standards, businessRules),\n mimeType: \"text/markdown\",\n }],\n };\n }\n );\n\n // Terminology: glossary + standards summary for deep-dives\n server.resource(\n \"kb-terminology\",\n \"productbrain://terminology\",\n async (uri) => {\n const [glossaryResult, standardsResult] = await Promise.allSettled([\n mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"glossary\" }),\n mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"standards\" }),\n ]);\n\n const lines: string[] = [\"# ProductBrain — Terminology\"];\n\n if (glossaryResult.status === \"fulfilled\") {\n if (glossaryResult.value.length > 0) {\n const terms = glossaryResult.value\n .map((t) => `- **${t.name}** (${t.entryId ?? \"—\"}) [${t.status}]: ${t.data?.canonical ?? t.data?.description ?? \"\"}`)\n .join(\"\\n\");\n lines.push(`## Glossary (${glossaryResult.value.length} terms)\\n\\n${terms}`);\n } else {\n lines.push(\"## Glossary\\n\\nNo glossary terms yet. Use `create-entry` with collection `glossary` to add terms.\");\n }\n } else {\n lines.push(\"## Glossary\\n\\nCould not load glossary — use `list-entries collection=glossary` to browse manually.\");\n }\n\n if (standardsResult.status === \"fulfilled\") {\n if (standardsResult.value.length > 0) {\n const stds = standardsResult.value\n .map((s) => `- **${s.name}** (${s.entryId ?? \"—\"}) [${s.status}]: ${s.data?.description ?? \"\"}`)\n .join(\"\\n\");\n lines.push(`## Standards (${standardsResult.value.length} entries)\\n\\n${stds}`);\n } else {\n lines.push(\"## Standards\\n\\nNo standards yet. Use `create-entry` with collection `standards` to add standards.\");\n }\n } else {\n lines.push(\"## Standards\\n\\nCould not load standards — use `list-entries 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 \"kb-collections\",\n \"productbrain://collections\",\n async (uri) => {\n const collections = await mcpQuery<any[]>(\"kb.listCollections\");\n\n if (collections.length === 0) {\n return { contents: [{ uri: uri.href, text: \"No collections in this workspace.\", mimeType: \"text/markdown\" }] };\n }\n\n const formatted = collections\n .map((c) => {\n const fieldList = c.fields\n .map((f: any) => ` - \\`${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 \"kb-collection-entries\",\n new ResourceTemplate(\"productbrain://{slug}/entries\", {\n list: async () => {\n const collections = await mcpQuery<any[]>(\"kb.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 const entries = await mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: slug as string });\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 \"kb-labels\",\n \"productbrain://labels\",\n async (uri) => {\n const labels = await mcpQuery<any[]>(\"kb.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","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { mcpQuery } 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 mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"business-rules\" });\n const rules = entries.filter((e) => e.data?.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 the list-entries tool with 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 mcpQuery<any[]>(\"kb.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 mcpQuery<any[]>(\"kb.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 create-entry 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 mcpQuery<any[]>(\"kb.listEntries\", { collectionSlug: \"business-rules\" });\n const existingRules = allRules.filter((r) => r.data?.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 const highestRuleNum = allRules\n .map((r) => parseInt((r.entryId ?? \"\").replace(/^[A-Z]+-/, \"\"), 10))\n .filter((n) => !isNaN(n))\n .sort((a, b) => b - a)[0] || 0;\n const nextRuleId = `SOS-${String(highestRuleNum + 1).padStart(3, \"0\")}`;\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 `Suggested rule ID: ${nextRuleId}\\n\\n` +\n `Existing rules in this domain:\\n${existingContext}\\n\\n` +\n `Draft the rule with these fields:\\n` +\n `1. **entryId**: ${nextRuleId}\\n` +\n `2. **name**: Concise rule title\\n` +\n `3. **data.description**: What the rule states\\n` +\n `4. **data.rationale**: Why this rule matters\\n` +\n `5. **data.dataImpact**: How this affects data models, APIs, or storage\\n` +\n `6. **data.severity**: high / medium / low\\n` +\n `7. **data.platforms**: Which platforms are affected\\n` +\n `8. **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 create-entry tool with collection \"business-rules\".`,\n },\n },\n ],\n };\n }\n );\n}\n"],"mappings":";;;AAAA,SAAS,gBAAAA,qBAAoB;AAC7B,SAAS,WAAAC,gBAAe;AACxB,SAAS,aAAAC,kBAAiB;AAC1B,SAAS,4BAA4B;;;ACFrC,SAAS,SAAS;;;ACSlB,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAExB,IAAI,SAAyB;AAC7B,IAAI,aAAa;AAEjB,IAAM,eAAe;AAGrB,SAAS,IAAI,KAAmB;AAC9B,MAAI,QAAQ,IAAI,cAAc,KAAK;AACjC,YAAQ,OAAO,MAAM,GAAG;AAAA,EAC1B;AACF;AAEO,SAAS,gBAAsB;AACpC,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,QAAQ;AACX,QAAI,oEAA+D;AACnE;AAAA,EACF;AAEA,WAAS,IAAI,QAAQ,QAAQ;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,IACT,eAAe;AAAA,EACjB,CAAC;AACD,eAAa,QAAQ,IAAI,eAAe,mBAAmB;AAE3D,MAAI,2CAAsC,YAAY,eAAe,UAAU;AAAA,CAAI;AACrF;AAEA,SAAS,qBAA6B;AACpC,MAAI;AACF,WAAO,SAAS,EAAE;AAAA,EACpB,QAAQ;AACN,WAAO,MAAM,QAAQ,GAAG;AAAA,EAC1B;AACF;AAEO,SAAS,oBACd,eACAC,cACA,eACM;AACN,MAAI,CAAC,OAAQ;AACb,SAAO,QAAQ;AAAA,IACb;AAAA,IACA,OAAO;AAAA,IACP,YAAY;AAAA,MACV,gBAAgB;AAAA,MAChB,cAAcA;AAAA,MACd,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,WAAWA,aAAY;AAAA,IACpC;AAAA,EACF,CAAC;AACH;AAEO,SAAS,cACd,IACA,QACA,YACAA,cACA,UACM;AACN,QAAM,aAAsC;AAAA,IAC1C,MAAM;AAAA,IACN;AAAA,IACA,aAAa;AAAA,IACb,gBAAgB,QAAQ,IAAI,kBAAkB;AAAA,IAC9C,QAAQ;AAAA,IACR,SAAS,EAAE,WAAWA,aAAY;AAAA,EACpC;AACA,MAAI,SAAU,YAAW,QAAQ;AAEjC,MAAI,CAAC,OAAQ;AACb,SAAO,QAAQ;AAAA,IACb;AAAA,IACA,OAAO;AAAA,IACP;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,oBAAmC;AACvD,QAAM,QAAQ,SAAS;AACzB;;;AC/EA,IAAM,oBAAoB;AAE1B,IAAI,oBAAmC;AACvC,IAAI,YAAY;AAWhB,IAAM,oBAAoB;AAC1B,IAAM,cAA4B,CAAC;AAM5B,SAAS,qBAA2B;AACzC,QAAM,QAAQ,QAAQ,IAAI;AAC1B,MAAI,OAAO,WAAW,QAAQ,GAAG;AAC/B,UAAM,WAAW,QAAQ,IAAI,oBAAoB;AACjD,YAAQ,IAAI,oBAAoB;AAChC,YAAQ,IAAI,gBAAgB;AAC5B,gBAAY;AAAA,EACd;AACF;AAEA,SAAS,OAAO,KAAqB;AACnC,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,GAAG,GAAG,mCAAmC;AACrE,SAAO;AACT;AAGA,SAAS,eAAe,QAAiC;AACvD,SAAO,WAAW,WAAW,QAAQ,IAAI,cAAc;AACzD;AAEA,SAAS,MAAM,IAAY,QAAwB,YAAoB,UAAyB;AAC9F,QAAM,MAAK,oBAAI,KAAK,GAAE,YAAY;AAClC,QAAM,YAAY,qBAAqB;AAEvC,QAAM,QAAoB,EAAE,IAAI,IAAI,WAAW,QAAQ,WAAW;AAClE,MAAI,SAAU,OAAM,QAAQ;AAC5B,cAAY,KAAK,KAAK;AACtB,MAAI,YAAY,SAAS,kBAAmB,aAAY,MAAM;AAE9D,gBAAc,IAAI,QAAQ,YAAY,WAAW,QAAQ;AAEzD,MAAI,CAAC,eAAe,MAAM,EAAG;AAE7B,QAAM,OAAO,eAAe,EAAE,OAAO,EAAE,cAAc,SAAS,WAAW,MAAM,aAAa,UAAU;AACtG,MAAI,WAAW,WAAW,UAAU;AAClC,YAAQ,OAAO,MAAM,GAAG,IAAI,UAAU,KAAK,UAAU,QAAQ,CAAC;AAAA,CAAI;AAAA,EACpE,OAAO;AACL,YAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,EAClC;AACF;AAGO,SAAS,cAAqC;AACnD,SAAO;AACT;AAMA,eAAsB,QAAW,IAAY,OAAgC,CAAC,GAAe;AAC3F,QAAM,UAAU,OAAO,iBAAiB,EAAE,QAAQ,OAAO,EAAE;AAC3D,QAAM,SAAS,OAAO,aAAa;AAEnC,QAAM,QAAQ,KAAK,IAAI;AAEvB,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,GAAG,OAAO,YAAY;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,IAAI,KAAK,CAAC;AAAA,IACnC,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,UAAM,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,IAAI,OAAO;AAClD,UAAM,IAAI,MAAM,aAAa,EAAE,oBAAoB,IAAI,OAAO,EAAE;AAAA,EAClE;AAEA,QAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,MAAI,CAAC,IAAI,MAAM,KAAK,OAAO;AACzB,UAAM,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK;AACjD,UAAM,IAAI,MAAM,aAAa,EAAE,aAAa,IAAI,MAAM,MAAM,KAAK,SAAS,eAAe,EAAE;AAAA,EAC7F;AAEA,QAAM,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK;AAClC,SAAO,KAAK;AACd;AAGA,eAAsB,iBAAkC;AACtD,MAAI,kBAAmB,QAAO;AAE9B,MAAI,WAAW;AAEb,UAAMC,aAAY,MAAM;AAAA,MACtB;AAAA,MACA,EAAE,MAAM,YAAY;AAAA,IACtB;AACA,QAAI,CAACA,YAAW;AACd,YAAM,IAAI,MAAM,wFAAwF;AAAA,IAC1G;AACA,wBAAoBA,WAAU;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,OAAO,gBAAgB;AACpC,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,EAAE,KAAK;AAAA,EACT;AAEA,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,wBAAwB,IAAI,aAAa;AAAA,EAC3D;AAEA,sBAAoB,UAAU;AAC9B,SAAO;AACT;AAGA,eAAsB,SAAY,IAAY,OAAgC,CAAC,GAAe;AAC5F,QAAMC,eAAc,MAAM,eAAe;AACzC,SAAO,QAAW,IAAI,EAAE,GAAG,MAAM,aAAAA,aAAY,CAAC;AAChD;AAGA,eAAsB,YAAe,IAAY,OAAgC,CAAC,GAAe;AAC/F,QAAMA,eAAc,MAAM,eAAe;AACzC,SAAO,QAAW,IAAI,EAAE,GAAG,MAAM,aAAAA,aAAY,CAAC;AAChD;;;AF9JA,SAAS,eAAe,MAAW,QAAwB;AACzD,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,MAAM,KAAK,eAAe,KAAK,aAAa,KAAK,UAAU;AACjE,MAAI,OAAO,QAAQ,YAAY,CAAC,IAAK,QAAO;AAC5C,SAAO,IAAI,SAAS,SAAS,IAAI,UAAU,GAAG,MAAM,IAAI,QAAQ;AAClE;AAEO,SAAS,uBAAuBC,SAAmB;AAExD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,YAAY;AACV,YAAM,cAAc,MAAM,SAAgB,oBAAoB;AAE9D,UAAI,YAAY,WAAW,GAAG;AAC5B,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,0CAA0C,CAAC,EAAE;AAAA,MACjG;AAEA,YAAM,YAAY,YACf,IAAI,CAAC,MAAM;AACV,cAAM,YAAY,EAAE,OACjB,IAAI,CAAC,MAAW,SAAS,EAAE,GAAG,OAAO,EAAE,IAAI,GAAG,EAAE,WAAW,eAAe,EAAE,GAAG,EAAE,aAAa,iBAAiB,EAAE,GAAG,EACpH,KAAK,IAAI;AACZ,eAAO,MAAM,EAAE,IAAI,OAAO,EAAE,IAAI;AAAA,EAAQ,EAAE,eAAe,kBAAkB;AAAA;AAAA;AAAA,EAAoB,SAAS;AAAA,MAC1G,CAAC,EACA,KAAK,aAAa;AAErB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,4BAA4B,YAAY,MAAM;AAAA;AAAA,EAAQ,SAAS,GAAG,CAAC;AAAA,MAC9G;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa;AAAA,QACX,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,QAClH,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,QACvF,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,QACrF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oEAA+D;AAAA,MACvG;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,YAAY,QAAQ,KAAK,MAAM,MAAM;AAC5C,UAAI;AAEJ,UAAI,OAAO;AACT,kBAAU,MAAM,SAAgB,yBAAyB,EAAE,WAAW,MAAM,CAAC;AAC7E,YAAI,OAAQ,WAAU,QAAQ,OAAO,CAAC,MAAW,EAAE,WAAW,MAAM;AAAA,MACtE,OAAO;AACL,kBAAU,MAAM,SAAgB,kBAAkB;AAAA,UAChD,gBAAgB;AAAA,UAChB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAEA,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sCAAsC,CAAC,EAAE;AAAA,MAC7F;AAEA,YAAM,YAAY,QACf,IAAI,CAAC,MAAM;AACV,cAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,cAAM,cAAc,EAAE,OAClB,OAAO,QAAQ,EAAE,IAAI,EAClB,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,eAAO,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,EAAE,MAAM,KAAK,cAAc;AAAA,EAAK,WAAW,KAAK,EAAE;AAAA,MACjF,CAAC,EACA,KAAK,MAAM;AAEd,YAAM,QAAQ,aAAa,SAAS,UAAU,OAAO;AACrD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,YAAY,KAAK,KAAK,QAAQ,MAAM;AAAA;AAAA,EAAQ,SAAS,GAAG,CAAC;AAAA,MACpG;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa;AAAA,QACX,SAAS,EAAE,OAAO,EAAE,SAAS,gEAAgE;AAAA,MAC/F;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,QAAQ,MAAM,SAAc,eAAe,EAAE,QAAQ,CAAC;AAE5D,UAAI,CAAC,OAAO;AACV,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,OAAO,oDAAoD,CAAC,EAAE;AAAA,MAC7H;AAEA,YAAM,QAAkB;AAAA,QACtB,KAAK,MAAM,UAAU,GAAG,MAAM,OAAO,OAAO,EAAE,GAAG,MAAM,IAAI;AAAA,QAC3D;AAAA,QACA,eAAe,MAAM,MAAM;AAAA,MAC7B;AAEA,UAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,UAAU;AAChD,cAAM,KAAK,EAAE;AACb,mBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,IAAI,GAAG;AACnD,gBAAM,UAAU,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG;AAClE,gBAAM,KAAK,KAAK,GAAG,OAAO,OAAO,EAAE;AAAA,QACrC;AAAA,MACF;AAEA,UAAI,MAAM,MAAM,SAAS,GAAG;AAC1B,cAAM,KAAK,IAAI,aAAa,MAAM,KAAK,KAAK,IAAI,CAAC,EAAE;AAAA,MACrD;AAEA,UAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,cAAM,KAAK,IAAI,eAAe,MAAM,OAAO,IAAI,CAAC,MAAW,KAAK,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MACpG;AAEA,UAAI,MAAM,WAAW,SAAS,GAAG;AAC/B,cAAM,KAAK,IAAI,cAAc;AAC7B,mBAAW,KAAK,MAAM,WAAW;AAC/B,gBAAM,QAAQ,EAAE,cAAc,aAAa,WAAW;AACtD,gBAAM,QAAQ,EAAE,eAAe,GAAG,EAAE,YAAY,KAAK,EAAE,SAAS,KAAM,EAAE,aAAa;AACrF,gBAAM,KAAK,KAAK,KAAK,MAAM,EAAE,IAAI,MAAM,KAAK,EAAE;AAAA,QAChD;AAAA,MACF;AAEA,UAAI,MAAM,SAAS,SAAS,GAAG;AAC7B,cAAM,KAAK,IAAI,sBAAsB;AACrC,mBAAW,KAAK,MAAM,QAAQ,MAAM,GAAG,GAAG;AACxC,gBAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7D,gBAAM,KAAK,KAAK,IAAI,KAAK,EAAE,KAAK,GAAG,EAAE,YAAY,MAAM,EAAE,SAAS,OAAO,EAAE,EAAE;AAAA,QAC/E;AAAA,MACF;AAEA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,QAAM,sBAAsB,oBAAI,IAAI;AAAA,IAClC;AAAA,IAAY;AAAA,IAAkB;AAAA,IAAc;AAAA,IAAa;AAAA,EAC3D,CAAC;AAED,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAa;AAAA,QACX,YAAY,EAAE,OAAO,EAAE,SAAS,kEAAkE;AAAA,QAClG,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,QAC/G,MAAM,EAAE,OAAO,EAAE,SAAS,cAAc;AAAA,QACxC,QAAQ,EAAE,OAAO,EAAE,QAAQ,OAAO,EAAE,SAAS,0DAA0D;AAAA,QACvG,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,uEAAkE;AAAA,QACvG,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,MACjF;AAAA,MACA,aAAa,EAAE,iBAAiB,MAAM;AAAA,IACxC;AAAA,IACA,OAAO,EAAE,YAAY,SAAS,MAAM,QAAQ,MAAM,MAAM,MAAM;AAC5D,UAAI,oBAAoB,IAAI,UAAU,KAAK,WAAW,WAAW,WAAW,cAAc;AACxF,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA;AAAA,QACK,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAKvB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI;AACF,cAAM,KAAK,MAAM,YAAoB,kBAAkB;AAAA,UACrD,gBAAgB;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAED,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA,IAAwB,WAAW,IAAI,iBAAiB,UAAU,WAAW,MAAM;AAAA;AAAA,eAAuB,EAAE,GAAG,CAAC;AAAA,QAC3J;AAAA,MACF,SAAS,OAAgB;AACvB,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,YAAI,IAAI,SAAS,iBAAiB,KAAK,IAAI,SAAS,gBAAgB,GAAG;AACrE,iBAAO;AAAA,YACL,SAAS,CAAC;AAAA,cACR,MAAM;AAAA,cACN,MAAM;AAAA;AAAA,EAA2C,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAKtD,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,QACX,SAAS,EAAE,OAAO,EAAE,SAAS,iDAAiD;AAAA,QAC9E,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,QACvD,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,QAC3F,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,QAC9F,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gBAAgB;AAAA,MACxD;AAAA,MACA,aAAa,EAAE,gBAAgB,MAAM,iBAAiB,MAAM;AAAA,IAC9D;AAAA,IACA,OAAO,EAAE,SAAS,MAAM,QAAQ,MAAM,MAAM,MAAM;AAChD,UAAI;AACF,cAAM,KAAK,MAAM,YAAoB,kBAAkB;AAAA,UACrD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAED,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA,IAAwB,OAAO;AAAA;AAAA,eAAwC,EAAE,GAAG,CAAC;AAAA,QACxH;AAAA,MACF,SAAS,OAAgB;AACvB,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,YAAI,IAAI,SAAS,SAAS,GAAG;AAC3B,iBAAO;AAAA,YACL,SAAS,CAAC;AAAA,cACR,MAAM;AAAA,cACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAQR,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa;AAAA,QACX,OAAO,EAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,QAC3D,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kFAAkF;AAAA,QAC7H,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0DAA0D;AAAA,MACnG;AAAA,MACA,aAAa,EAAE,cAAc,MAAM,eAAe,KAAK;AAAA,IACzD;AAAA,IACA,OAAO,EAAE,OAAO,YAAY,OAAO,MAAM;AACvC,YAAM,QAAQ,aAAa,SAAS,UAAU,OAAO;AACrD,YAAMA,QAAO,mBAAmB,EAAE,OAAO,QAAQ,MAAM,YAAY,KAAK,SAAS,KAAK,QAAQ,QAAQ,aAAa,CAAC;AAEpH,YAAM,CAAC,SAAS,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC/C,SAAgB,oBAAoB,EAAE,OAAO,gBAAgB,YAAY,OAAO,CAAC;AAAA,QACjF,SAAgB,oBAAoB;AAAA,MACtC,CAAC;AAED,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,mBAAmB,KAAK,IAAI,KAAK,uEAAuE,CAAC,EAAE;AAAA,MAC/J;AAEA,YAAM,UAAU,oBAAI,IAA4C;AAChE,iBAAW,KAAK,aAAa;AAC3B,gBAAQ,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,CAAC;AAAA,MACnD;AAEA,YAAM,eAAe,oBAAI,IAAoB;AAC7C,iBAAW,KAAK,SAAS;AACvB,cAAM,MAAM,QAAQ,IAAI,EAAE,YAAY;AACtC,cAAM,OAAO,KAAK,QAAQ;AAC1B,qBAAa,IAAI,OAAO,aAAa,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,MAC1D;AACA,YAAM,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,YAAM,YAAY,QACf,IAAI,CAAC,MAAM;AACV,cAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,cAAM,MAAM,QAAQ,IAAI,EAAE,YAAY;AACtC,cAAM,SAAS,MAAM,KAAK,IAAI,IAAI,MAAM;AACxC,cAAM,OAAO,eAAe,EAAE,MAAM,GAAG;AACvC,cAAM,UAAU,OAAO;AAAA,IAAO,IAAI,KAAK;AACvC,eAAO,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO;AAAA,MAC5D,CAAC,EACA,KAAK,IAAI;AAEZ,YAAM,SAAS,yBAAyB,KAAK,IAAI,KAAK,KAAK,QAAQ,MAAM,SAAS,QAAQ,WAAW,IAAI,KAAK,IAAI;AAAA;AAAA,qBAA2B,WAAW;AACxJ,YAAM,SAAS;AAEf,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,MAAM;AAAA;AAAA,EAAO,SAAS;AAAA;AAAA,EAAO,MAAM,GAAG,CAAC;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,QACX,SAAS,EAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,MACtE;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,UAAU,MAAM,SAAgB,uBAAuB,EAAE,QAAQ,CAAC;AAExE,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,0BAA0B,OAAO,MAAM,CAAC,EAAE;AAAA,MAC9F;AAEA,YAAM,YAAY,QACf,IAAI,CAAC,MAAM;AACV,cAAM,OAAO,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY;AAC/C,cAAM,UAAU,EAAE,UAAU,WAAM,KAAK,UAAU,EAAE,OAAO,CAAC,KAAK;AAChE,eAAO,OAAO,IAAI,MAAM,EAAE,KAAK,GAAG,EAAE,YAAY,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO;AAAA,MACtF,CAAC,EACA,KAAK,IAAI;AAEZ,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,mBAAmB,OAAO,OAAO,QAAQ,MAAM;AAAA;AAAA,EAAe,SAAS,GAAG,CAAC;AAAA,MACtH;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAUF,aAAa;AAAA,QACX,MAAM,EAAE,OAAO,EAAE,SAAS,oCAAoC;AAAA,QAC9D,IAAI,EAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,QACxD,MAAM,EAAE,OAAO,EAAE,SAAS,uEAAkE;AAAA,MAC9F;AAAA,MACA,aAAa,EAAE,iBAAiB,MAAM;AAAA,IACxC;AAAA,IACA,OAAO,EAAE,MAAM,IAAI,KAAK,MAAM;AAC5B,YAAM,YAAY,0BAA0B;AAAA,QAC1C,aAAa;AAAA,QACb,WAAW;AAAA,QACX;AAAA,MACF,CAAC;AAED,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA,IAA2B,IAAI,aAAa,IAAI,aAAa,EAAE,KAAK,CAAC;AAAA,MAChH;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa;AAAA,QACX,SAAS,EAAE,OAAO,EAAE,SAAS,oCAAoC;AAAA,QACjE,WAAW,EAAE,KAAK,CAAC,YAAY,YAAY,MAAM,CAAC,EAAE,QAAQ,MAAM,EAC/D,SAAS,0FAA0F;AAAA,MACxG;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,SAAS,UAAU,MAAM;AAChC,YAAM,YAAY,MAAM,SAAgB,yBAAyB,EAAE,QAAQ,CAAC;AAE5E,UAAI,UAAU,WAAW,GAAG;AAC1B,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,4BAA4B,OAAO,gDAAgD,CAAC,EAAE;AAAA,MAC1I;AAEA,YAAM,cAAc,MAAM,SAAc,eAAe,EAAE,QAAQ,CAAC;AAClE,UAAI,CAAC,aAAa;AAChB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,OAAO,oDAAoD,CAAC,EAAE;AAAA,MAC7H;AACA,YAAM,mBAAmB,YAAY;AAErC,YAAM,gBAAgB;AACtB,YAAM,YAAY,UAAU,SAAS;AACrC,YAAM,SAAS,UAAU,MAAM,GAAG,aAAa;AAE/C,YAAM,WAAW,oBAAI,IAAY;AACjC,iBAAW,KAAK,QAAQ;AACtB,cAAM,UAAU,EAAE,WAAW,mBAAmB,EAAE,OAAO,EAAE;AAC3D,iBAAS,IAAI,OAAO;AAAA,MACtB;AAEA,YAAM,eAAe,oBAAI,IAAsE;AAC/F,iBAAW,MAAM,UAAU;AACzB,cAAM,QAAQ,MAAM,SAAc,eAAe,EAAE,GAAG,CAAC;AACvD,YAAI,OAAO;AACT,uBAAa,IAAI,MAAM,KAAK,EAAE,SAAS,MAAM,SAAS,MAAM,MAAM,MAAM,cAAc,MAAM,aAAa,CAAC;AAAA,QAC5G;AAAA,MACF;AAEA,YAAM,cAAc,MAAM,SAAgB,oBAAoB;AAC9D,YAAM,UAAU,oBAAI,IAAoB;AACxC,iBAAW,KAAK,YAAa,SAAQ,IAAI,EAAE,KAAK,EAAE,IAAI;AAEtD,YAAM,QAAkB,CAAC,mBAAmB,OAAO,KAAK,YAAY,IAAI,IAAI,EAAE;AAE9E,YAAM,WAAW,OAAO,IAAI,CAAC,MAAM;AACjC,cAAM,aAAa,EAAE,WAAW;AAChC,cAAM,UAAU,aAAa,EAAE,OAAO,EAAE;AACxC,cAAM,QAAQ,aAAa,IAAI,OAAO;AACtC,cAAM,aAAa,OAAO,UAAU,GAAG,MAAM,OAAO,KAAK,MAAM,IAAI,KAAM,OAAO,QAAQ;AACxF,cAAM,UAAU,QAAS,QAAQ,IAAI,MAAM,YAAY,KAAK,YAAa;AACzE,eAAO,EAAE,YAAY,MAAM,EAAE,MAAM,YAAY,QAAQ;AAAA,MACzD,CAAC;AAED,YAAM,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,UAAU;AACpD,YAAM,WAAW,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU;AAErD,WAAK,cAAc,cAAc,cAAc,WAAW,SAAS,SAAS,GAAG;AAC7E,cAAM,KAAK,gBAAgB,SAAS,MAAM,GAAG;AAC7C,mBAAW,KAAK,UAAU;AACxB,gBAAM,KAAK,cAAc,EAAE,IAAI,MAAM,EAAE,UAAU,KAAK,EAAE,OAAO,GAAG;AAAA,QACpE;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,WAAK,cAAc,cAAc,cAAc,WAAW,SAAS,SAAS,GAAG;AAC7E,cAAM,KAAK,gBAAgB,SAAS,MAAM,GAAG;AAC7C,mBAAW,KAAK,UAAU;AACxB,gBAAM,KAAK,cAAc,EAAE,IAAI,MAAM,EAAE,UAAU,KAAK,EAAE,OAAO,GAAG;AAAA,QACpE;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,YAAM,QAAQ,cAAc,aAAa,WAAW,cAAc,aAAa,WAAW;AAC1F,UAAI,MAAM,WAAW,GAAG;AACtB,cAAM,KAAK,MAAM,SAAS,0BAA0B,OAAO,KAAK;AAAA,MAClE;AAEA,UAAI,WAAW;AACb,cAAM,KAAK,kBAAkB,aAAa,OAAO,UAAU,MAAM,kDAAkD;AAAA,MACrH;AAEA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAa;AAAA,QACX,SAAS,EAAE,OAAO,EAAE,SAAS,+CAA+C;AAAA,QAC5E,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EACxC,SAAS,2EAA2E;AAAA,MACzF;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,SAAS,QAAQ,MAAM;AAC9B,YAAM,SAAS,MAAM,SAAc,oBAAoB,EAAE,SAAS,QAAQ,CAAC;AAE3E,UAAI,CAAC,QAAQ,MAAM;AACjB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,OAAO,oDAAoD,CAAC,EAAE;AAAA,MAC7H;AAEA,UAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM,iBAAiB,OAAO,KAAK,OAAO,KAAK,OAAO,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,UAGjE,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,eAAe,oBAAI,IAAmC;AAC5D,iBAAW,SAAS,OAAO,SAAS;AAClC,cAAM,MAAM,MAAM;AAClB,YAAI,CAAC,aAAa,IAAI,GAAG,EAAG,cAAa,IAAI,KAAK,CAAC,CAAC;AACpD,qBAAa,IAAI,GAAG,EAAG,KAAK,KAAK;AAAA,MACnC;AAEA,YAAM,QAAkB;AAAA,QACtB,iBAAiB,OAAO,KAAK,OAAO,KAAK,OAAO,KAAK,IAAI;AAAA,QACzD,IAAI,OAAO,cAAc,2BAA2B,aAAa,IAAI,iBAAiB,OAAO,aAAa;AAAA,QAC1G;AAAA,MACF;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,WAAW;AAC9D,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,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa;AAAA,QACX,SAAS,EAAE,OAAO,EAAE,SAAS,mDAAmD;AAAA,QAChF,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EACxC,SAAS,qCAAqC;AAAA,MACnD;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,SAAS,MAAM,MAAM;AAC5B,YAAM,QAAQ,MAAM,SAAc,eAAe,EAAE,QAAQ,CAAC;AAC5D,UAAI,CAAC,OAAO;AACV,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,OAAO,oDAAoD,CAAC,EAAE;AAAA,MAC7H;AAEA,YAAM,cAAc,CAAC,MAAM,IAAI;AAC/B,UAAI,MAAM,MAAM,YAAa,aAAY,KAAK,MAAM,KAAK,WAAW;AACpE,UAAI,MAAM,MAAM,UAAW,aAAY,KAAK,MAAM,KAAK,SAAS;AAChE,UAAI,MAAM,MAAM,UAAW,aAAY,KAAK,MAAM,KAAK,SAAS;AAChE,UAAI,MAAM,MAAM,KAAM,aAAY,KAAK,MAAM,KAAK,IAAI;AAEtD,YAAM,YAAY,YACf,KAAK,GAAG,EACR,QAAQ,YAAY,GAAG,EACvB,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,MAAM,GAAG,CAAC,EACV,KAAK,GAAG;AAEX,UAAI,CAAC,WAAW;AACd,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,OAAO,0DAA0D,CAAC,EAAE;AAAA,MACnI;AAEA,YAAM,UAAU,MAAM,SAAgB,oBAAoB,EAAE,OAAO,UAAU,CAAC;AAC9E,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,8BAA8B,OAAO,gDAAgD,CAAC,EAAE;AAAA,MAC5I;AAEA,YAAM,oBAAoB,MAAM,SAAgB,yBAAyB,EAAE,QAAQ,CAAC;AACpF,YAAM,aAAa,IAAI;AAAA,QACrB,kBAAkB,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC;AAAA,MACrD;AAEA,YAAM,cAAc,MAAM,SAAgB,oBAAoB;AAC9D,YAAM,UAAU,oBAAI,IAAoB;AACxC,iBAAW,KAAK,YAAa,SAAQ,IAAI,EAAE,KAAK,EAAE,IAAI;AAEtD,YAAM,cAAc,QACjB,OAAO,CAAC,MAAM,EAAE,QAAQ,MAAM,OAAO,CAAC,WAAW,IAAI,EAAE,GAAG,CAAC,EAC3D,MAAM,GAAG,KAAK,EACd,IAAI,CAAC,OAAO;AAAA,QACX,SAAS,EAAE;AAAA,QACX,MAAM,EAAE;AAAA,QACR,YAAY,QAAQ,IAAI,EAAE,YAAY,KAAK;AAAA,QAC3C,SAAS,eAAe,EAAE,MAAM,EAAE;AAAA,MACpC,EAAE;AAEJ,UAAI,YAAY,WAAW,GAAG;AAC5B,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iCAAiC,OAAO,2EAAsE,CAAC,EAAE;AAAA,MACrK;AAEA,YAAM,QAAQ;AAAA,QACZ,0BAA0B,OAAO,KAAK,MAAM,IAAI;AAAA,QAChD,IAAI,YAAY,MAAM;AAAA,QACtB;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;AAC3C,cAAM,IAAI,YAAY,CAAC;AACvB,cAAM,UAAU,EAAE,UAAU,WAAM,EAAE,OAAO,KAAK;AAChD,cAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,SAAS,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,IAAI,OAAO,EAAE;AAAA,MAC7F;AAEA,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,mFAAmF;AAC9F,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,2HAA2H;AAEtI,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa;AAAA,QACX,YAAY,EAAE,OAAO,EAAE,SAAS,6EAA6E;AAAA,QAC7G,MAAM,EAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,QACtD,aAAa,EAAE,OAAO,EAAE,SAAS,+DAA0D;AAAA,QAC3F,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uDAAuD;AAAA,MACjG;AAAA,MACA,aAAa,EAAE,iBAAiB,MAAM;AAAA,IACxC;AAAA,IACA,OAAO,EAAE,YAAY,MAAM,aAAa,QAAQ,MAAM;AACpD,YAAM,MAAM,MAAM,SAAc,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACxE,UAAI,CAAC,KAAK;AACR,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gBAAgB,UAAU,mEAAmE,CAAC,EAAE;AAAA,MACpJ;AAEA,YAAM,OAAgC,CAAC;AACvC,YAAM,cAAwB,CAAC;AAE/B,iBAAW,SAAS,IAAI,UAAU,CAAC,GAAG;AACpC,cAAM,MAAM,MAAM;AAClB,YAAI,QAAQ,iBAAiB,QAAQ,eAAe,QAAQ,UAAU;AACpE,eAAK,GAAG,IAAI;AAAA,QACd,WAAW,MAAM,SAAS,WAAW,MAAM,SAAS,gBAAgB;AAClE,eAAK,GAAG,IAAI,CAAC;AACb,sBAAY,KAAK,GAAG;AAAA,QACtB,WAAW,MAAM,SAAS,UAAU;AAClC,eAAK,GAAG,IAAI,MAAM,UAAU,CAAC,KAAK;AAClC,sBAAY,KAAK,GAAG;AAAA,QACtB,OAAO;AACL,eAAK,GAAG,IAAI;AACZ,sBAAY,KAAK,GAAG;AAAA,QACtB;AAAA,MACF;AAEA,UAAI,CAAC,KAAK,eAAe,CAAC,KAAK,aAAa,CAAC,KAAK,QAAQ;AACxD,aAAK,cAAc;AAAA,MACrB;AAEA,UAAI;AACF,cAAM,KAAK,MAAM,YAAoB,kBAAkB;AAAA,UACrD,gBAAgB;AAAA,UAChB;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AAED,cAAM,YAAY,YAAY,SAAS,IACnC;AAAA;AAAA;AAAA,EAAyD,YAAY,IAAI,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,KACxG;AAEJ,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA;AAAA,IAA+B,WAAW,IAAI,iBAAiB,UAAU;AAAA;AAAA,eAAoC,EAAE,GAAG,SAAS;AAAA;AAAA;AAAA,UACnI,CAAC;AAAA,QACH;AAAA,MACF,SAAS,OAAgB;AACvB,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,YAAI,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,gBAAgB,GAAG;AAC/D,iBAAO;AAAA,YACL,SAAS,CAAC;AAAA,cACR,MAAM;AAAA,cACN,MAAM;AAAA;AAAA,EAA4C,GAAG;AAAA;AAAA;AAAA,YACvD,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAUF,aAAa;AAAA,QACX,iBAAiB,EAAE,OAAO,EAAE,SAAS,0DAA0D;AAAA,QAC/F,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,EACxD,SAAS,oCAAoC;AAAA,QAChD,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,EACnD,SAAS,wDAAwD;AAAA,MACtE;AAAA,MACA,aAAa,EAAE,cAAc,MAAM,eAAe,KAAK;AAAA,IACzD;AAAA,IACA,OAAO,EAAE,iBAAiB,YAAY,QAAQ,MAAM;AAClD,YAAMA,QAAO,mBAAmB;AAAA,QAC9B,OAAO;AAAA,QACP,MAAM,8BAA8B,gBAAgB,UAAU,GAAG,EAAE,CAAC;AAAA,QACpE,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,SAAS,MAAM,SAclB,yBAAyB;AAAA,QAC1B;AAAA,QACA,YAAY,cAAc;AAAA,QAC1B,SAAS,WAAW;AAAA,MACtB,CAAC;AAED,UAAI,OAAO,eAAe,UAAU,OAAO,QAAQ,WAAW,GAAG;AAC/D,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAGR,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,eAAe,oBAAI,IAAmC;AAC5D,iBAAW,SAAS,OAAO,SAAS;AAClC,cAAM,MAAM,MAAM;AAClB,YAAI,CAAC,aAAa,IAAI,GAAG,EAAG,cAAa,IAAI,KAAK,CAAC,CAAC;AACpD,qBAAa,IAAI,GAAG,EAAG,KAAK,KAAK;AAAA,MACnC;AAEA,YAAM,QAAkB;AAAA,QACtB;AAAA,QACA,mBAAmB,OAAO,WAAW,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,WAAW,MAAM,CAAC,CAAC;AAAA,QACzF,gBAAgB,OAAO,QAAQ,MAAM,mBAAmB,aAAa,IAAI,cAAc,aAAa,SAAS,IAAI,KAAK,GAAG;AAAA,QACzH;AAAA,MACF;AAEA,iBAAW,CAAC,UAAU,OAAO,KAAK,cAAc;AAC9C,cAAM,KAAK,OAAO,QAAQ,KAAK,QAAQ,MAAM,GAAG;AAChD,mBAAW,KAAK,SAAS;AACvB,gBAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,gBAAM,WAAW,EAAE,MAAM,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,eAAe,KAAK,EAAE,YAAY,KAAK,EAAE,OAAO;AACjG,gBAAM,UAAU,EAAE,qBAAqB;AAAA,IAAO,EAAE,kBAAkB,KAAK;AACvE,gBAAM,YAAY,EAAE,UAAU,SAAS,IAAI;AAAA,UAAa,EAAE,UAAU,KAAK,IAAI,CAAC,KAAK;AACnF,gBAAM,KAAK,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,EAAE;AAAA,QAChE;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,YAAM,KAAK,oDAAoD;AAE/D,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAa;AAAA,QACX,QAAQ,EAAE,OAAO,EAAE,SAAS,mFAAmF;AAAA,QAC/G,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4EAAuE;AAAA,MACjH;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,QAAQ,QAAQ,MAAM;AAC7B,YAAM,UAAU,MAAM,SAAgB,kBAAkB,EAAE,gBAAgB,iBAAiB,CAAC;AAE5F,YAAM,cAAc,OAAO,YAAY;AACvC,YAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM;AAClC,cAAM,aAAc,EAAE,MAAM,UAAU;AACtC,eAAO,WAAW,YAAY,MAAM,eAAe,WAAW,YAAY,EAAE,SAAS,WAAW;AAAA,MAClG,CAAC;AAED,UAAI,MAAM,WAAW,GAAG;AACtB,cAAM,aAAa,CAAC,GAAG,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC;AAClF,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM,yBAAyB,MAAM;AAAA;AAAA;AAAA,EAA4B,WAAW,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,UAC7G,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,SAAS,UACX,qBAAqB,MAAM;AAAA;AAAA,sBAA2B,OAAO;AAAA;AAAA;AAAA,IAC7D,qBAAqB,MAAM;AAAA;AAE/B,YAAM,YAAY,MACf,IAAI,CAAC,MAAM;AACV,cAAM,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,SAAS;AAC9C,cAAM,WAAW,EAAE,MAAM,WAAW,gBAAgB,EAAE,KAAK,QAAQ,KAAK;AACxE,cAAM,OAAO,EAAE,MAAM,eAAe;AACpC,cAAM,SAAS,EAAE,MAAM,aAAa;AAAA,iBAAoB,EAAE,KAAK,UAAU,KAAK;AAC9E,cAAM,WAAW,EAAE,MAAM,gBAA4B,CAAC,GAAG,SAAS,IAC9D;AAAA,aAAiB,EAAE,KAAK,aAA0B,KAAK,IAAI,CAAC,KAC5D;AACJ,eAAO,OAAO,EAAE,GAAG,EAAE,IAAI,MAAM,EAAE,MAAM,KAAK,QAAQ;AAAA;AAAA,EAAO,IAAI,GAAG,MAAM,GAAG,OAAO;AAAA,MACpF,CAAC,EACA,KAAK,aAAa;AAErB,YAAM,SAAS;AAAA,GAAM,MAAM,MAAM,QAAQ,MAAM,WAAW,IAAI,KAAK,GAAG;AAEtE,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,MAAM;AAAA,EAAK,SAAS;AAAA,EAAK,MAAM,GAAG,CAAC;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AACF;;;AG13BA,SAAS,KAAAC,UAAS;AAGX,SAAS,mBAAmBC,SAAmB;AAEpD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,YAAY;AACV,YAAM,SAAS,MAAM,SAAgB,eAAe;AAEpD,UAAI,OAAO,WAAW,GAAG;AACvB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,2CAA2C,CAAC,EAAE;AAAA,MAClG;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,oBAAoB;AAE7C,iBAAW,SAAS,QAAQ;AAC1B,cAAM,KAAK;AAAA,KAAQ,MAAM,IAAI,EAAE;AAC/B,YAAI,MAAM,YAAa,OAAM,KAAK,IAAI,MAAM,WAAW,GAAG;AAC1D,mBAAW,SAAS,SAAS,MAAM,GAAG,GAAG;AACvC,gBAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAK;AAChD,gBAAM,KAAK,SAAS,MAAM,IAAI,MAAM,MAAM,IAAI,GAAG,KAAK,EAAE;AAAA,QAC1D;AAAA,MACF;AAEA,UAAI,UAAU,SAAS,GAAG;AACxB,cAAM,KAAK,gBAAgB;AAC3B,mBAAW,SAAS,WAAW;AAC7B,gBAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAK;AAChD,gBAAM,KAAK,OAAO,MAAM,IAAI,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM,cAAc,YAAO,MAAM,WAAW,MAAM,EAAE,EAAE;AAAA,QAC/G;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,QACX,QAAQC,GAAE,KAAK,CAAC,UAAU,UAAU,QAAQ,CAAC,EAAE,SAAS,YAAY;AAAA,QACpE,MAAMA,GAAE,OAAO,EAAE,SAAS,+DAA+D;AAAA,QACzF,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,QACzE,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,QACjE,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,QACnE,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QAClF,SAASA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,QAClG,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,MACrE;AAAA,IACF;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM,MAAM,OAAO,aAAa,YAAY,SAAS,MAAM,MAAM;AAChF,UAAI,WAAW,UAAU;AACvB,YAAI,CAAC,MAAM;AACT,iBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,wCAAwC,CAAC,EAAE;AAAA,QAC/F;AAEA,YAAI;AACJ,YAAI,YAAY;AACd,gBAAM,SAAS,MAAM,SAAgB,eAAe;AACpD,gBAAM,SAAS,OAAO,KAAK,CAAC,MAAW,EAAE,SAAS,UAAU;AAC5D,cAAI,CAAC,QAAQ;AACX,mBAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,kBAAkB,UAAU,yDAAyD,CAAC,EAAE;AAAA,UAC5I;AACA,qBAAW,OAAO;AAAA,QACpB;AAEA,cAAM,YAAY,kBAAkB,EAAE,MAAM,MAAM,OAAO,aAAa,UAAU,SAAS,MAAM,CAAC;AAChG,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA,IAAwB,IAAI,SAAS,IAAI,MAAM,CAAC,EAAE;AAAA,MACtG;AAEA,UAAI,WAAW,UAAU;AACvB,cAAM,YAAY,kBAAkB,EAAE,MAAM,MAAM,OAAO,aAAa,SAAS,MAAM,CAAC;AACtF,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA,IAAwB,IAAI,uBAAuB,CAAC,EAAE;AAAA,MAC1G;AAEA,UAAI,WAAW,UAAU;AACvB,cAAM,YAAY,kBAAkB,EAAE,KAAK,CAAC;AAC5C,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA,IAAwB,IAAI,2CAA2C,CAAC,EAAE;AAAA,MAC9H;AAEA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,kBAAkB,CAAC,EAAE;AAAA,IACzE;AAAA,EACF;AAEA,EAAAD,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,QACX,QAAQC,GAAE,KAAK,CAAC,SAAS,QAAQ,CAAC,EAAE,SAAS,2BAA2B;AAAA,QACxE,SAASA,GAAE,OAAO,EAAE,SAAS,sDAAsD;AAAA,QACnF,OAAOA,GAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,MACzD;AAAA,IACF;AAAA,IACA,OAAO,EAAE,QAAQ,SAAS,MAAM,MAAM;AACpC,UAAI,WAAW,SAAS;AACtB,cAAM,YAAY,iBAAiB,EAAE,SAAS,WAAW,MAAM,CAAC;AAChE,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,KAAK,mBAAmB,OAAO,MAAM,CAAC,EAAE;AAAA,MACvG;AAEA,YAAM,YAAY,kBAAkB,EAAE,SAAS,WAAW,MAAM,CAAC;AACjE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,KAAK,qBAAqB,OAAO,MAAM,CAAC,EAAE;AAAA,IACzG;AAAA,EACF;AACF;;;AC9HA,SAAS,KAAAC,UAAS;AAKlB,IAAM,kBAAgD;AAAA,EACpD,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,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,oBAAoBC,MAAoC;AAC/D,MAAIA,KAAI,WAAW,EAAG,QAAO;AAE7B,QAAM,aAAa,oBAAI,IAAuC;AAC9D,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,eAAe;AAEnB,aAAW,SAASA,MAAK;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,oBAAoB,MAAM,WAAW,KAAM;AAC5D,QAAI,MAAM,OAAO,oBAAoB,MAAM,WAAW,KAAM;AAAA,EAC9D;AAEA,QAAM,UAAU,IAAI,KAAKA,KAAI,CAAC,EAAE,EAAE,EAAE,QAAQ;AAC5C,QAAM,SAAS,IAAI,KAAKA,KAAIA,KAAI,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,OAAO,EAAE,CAAC,KAAK,KAAK,EAAE,EACzD,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;AAEO,SAAS,oBAAoBC,SAAmB;AAErD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,YAAY;AACV,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,SAAmB,CAAC;AAE1B,UAAIC;AACJ,UAAI;AACF,QAAAA,eAAc,MAAM,eAAe;AAAA,MACrC,SAAS,GAAQ;AACf,eAAO,KAAK,gCAAgC,EAAE,OAAO,EAAE;AAAA,MACzD;AAEA,UAAI,cAAqB,CAAC;AAC1B,UAAI;AACF,sBAAc,MAAM,SAAgB,oBAAoB;AAAA,MAC1D,SAAS,GAAQ;AACf,eAAO,KAAK,4BAA4B,EAAE,OAAO,EAAE;AAAA,MACrD;AAEA,UAAI,eAAe;AACnB,UAAI,YAAY,SAAS,GAAG;AAC1B,YAAI;AACF,gBAAM,UAAU,MAAM,SAAgB,kBAAkB,CAAC,CAAC;AAC1D,yBAAe,QAAQ;AAAA,QACzB,SAAS,GAAQ;AACf,iBAAO,KAAK,uBAAuB,EAAE,OAAO,EAAE;AAAA,QAChD;AAAA,MACF;AAEA,YAAM,aAAa,KAAK,IAAI,IAAI;AAChC,YAAM,UAAU,OAAO,WAAW;AAElC,YAAM,QAAQ;AAAA,QACZ,KAAK,UAAU,YAAY,UAAU;AAAA,QACrC;AAAA,QACA,kBAAkBA,gBAAe,YAAY;AAAA,QAC7C,oBAAoB,YAAY,MAAM;AAAA,QACtC,gBAAgB,YAAY;AAAA,QAC5B,gBAAgB,UAAU;AAAA,MAC5B;AAEA,UAAI,OAAO,SAAS,GAAG;AACrB,cAAM,KAAK,IAAI,WAAW;AAC1B,mBAAW,OAAO,QAAQ;AACxB,gBAAM,KAAK,KAAK,GAAG,EAAE;AAAA,QACvB;AAAA,MACF;AAEA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAEA,EAAAD,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,QACX,OAAOE,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,wCAAwC;AAAA,MAChG;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,MAAM,MAAM;AACnB,YAAMH,OAAM,YAAY;AACxB,YAAM,SAASA,KAAI,MAAM,CAAC,KAAK;AAE/B,UAAI,OAAO,WAAW,GAAG;AACvB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sCAAsC,CAAC,EAAE;AAAA,MAC7F;AAEA,YAAM,UAAU,oBAAoBA,IAAG;AAEvC,YAAM,WAAW,CAAC,qBAAqB,OAAO,MAAM,OAAOA,KAAI,MAAM;AAAA,CAAW;AAChF,iBAAW,SAAS,QAAQ;AAC1B,cAAM,OAAO,MAAM,WAAW,OAAO,WAAW;AAChD,cAAM,UAAU,MAAM,QAAQ,WAAW,MAAM,KAAK,KAAK;AACzD,iBAAS,KAAK,GAAG,IAAI,MAAM,MAAM,EAAE,MAAM,MAAM,UAAU,MAAM,MAAM,MAAM,GAAG,OAAO,EAAE;AAAA,MACzF;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,OAAO;AAAA;AAAA;AAAA;AAAA,EAAc,SAAS,KAAK,IAAI,CAAC,GAAG,CAAC;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AACF;;;AC/LA,SAAS,YAAY,oBAAoB;AACzC,SAAS,eAAe;AAExB,SAAS,KAAAI,UAAS;AA2BlB,SAAS,qBAAoC;AAC3C,QAAM,aAAa;AAAA,IACjB,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA,IACZ,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;AAIA,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,WAAW,QAAQ,MAAM,QAAQ;AACvC,MAAI,WAAW,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,SAAS,oBAAoBC,SAAmB;AACrD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAa;AAAA,QACX,YAAYC,GAAE,OAAO,EAAE,QAAQ,UAAU,EACtC,SAAS,+CAA+C;AAAA,QAC3D,MAAMA,GAAE,KAAK,CAAC,UAAU,KAAK,CAAC,EAAE,QAAQ,QAAQ,EAC7C,SAAS,sFAAsF;AAAA,MACpG;AAAA,MACA,aAAa,EAAE,cAAc,MAAM;AAAA,IACrC;AAAA,IACA,OAAO,EAAE,YAAY,KAAK,MAAM;AAC9B,YAAM,cAAc,mBAAmB;AACvC,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM;AAAA,UAGR,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,SAAS,kBAAkB,QAAQ,aAAa,kBAAkB,CAAC;AAEzE,YAAMD,QAAO,mBAAmB;AAAA,QAC9B,OAAO;AAAA,QACP,MAAM,cAAc,UAAU,aAAa,OAAO,IAAI,qBAAqB,WAAW;AAAA,QACtF,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,gBAAgB,MAAM,SAAgB,kBAAkB,EAAE,gBAAgB,WAAW,CAAC;AAE5F,UAAI,cAAc,WAAW,GAAG;AAC9B,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,yBAAyB,UAAU,yBAAyB,CAAC;AAAA,QACxG;AAAA,MACF;AAGA,UAAI;AACJ,UAAI;AACF,cAAM,aAAa,MAAM,SAAgB,kBAAkB,CAAC,CAAC;AAC7D,sBAAc,IAAI,IAAI,WAAW,IAAI,CAAC,MAAW,EAAE,OAAO,EAAE,OAAO,OAAO,CAAC;AAAA,MAC7E,QAAQ;AACN,sBAAc,IAAI,IAAI,cAAc,IAAI,CAAC,MAAW,EAAE,OAAO,EAAE,OAAO,OAAO,CAAC;AAAA,MAChF;AAEA,YAAM,gBAAgC,CAAC;AACvC,YAAM,YAAwB,CAAC;AAE/B,iBAAW,SAAS,eAAe;AACjC,cAAM,MAAM,MAAM,WAAW,MAAM;AACnC,cAAM,QAAQ,MAAM;AAGpB,cAAM,eAAsB,MAAM,MAAM,eAAe,CAAC;AACxD,mBAAW,MAAM,cAAc;AAC7B,gBAAM,WAAmB,GAAG,SAAS;AACrC,qBAAW,UAAU,eAAe,QAAQ,GAAG;AAC7C,kBAAM,UAAU,cAAc,MAAM;AACpC,gBAAI,CAAC,QAAS;AAEd,kBAAM,OAAO,YAAY,OAAO;AAChC,gBAAI;AACJ,gBAAI;AAEJ,gBAAI,SAAS,QAAQ;AACnB,eAAC,EAAE,QAAQ,OAAO,IAAI,aAAa,SAAS,WAAW;AAAA,YACzD,WAAW,SAAS,UAAU;AAC5B,eAAC,EAAE,QAAQ,OAAO,IAAI,eAAe,SAAS,MAAM;AAAA,YACtD,OAAO;AACL,uBAAS;AACT,uBAAS;AAAA,YACX;AAEA,0BAAc,KAAK;AAAA,cACjB,SAAS;AAAA,cAAK,WAAW;AAAA,cAAO,OAAO,OAAO,KAAK;AAAA,cACnD;AAAA,cAAM;AAAA,cAAQ;AAAA,cAAQ,eAAe,GAAG,UAAU;AAAA,YACpD,CAAC;AAAA,UACH;AAAA,QACF;AAGA,cAAM,iBAAiB;AACvB,cAAM,eAAyB,MAAM,MAAM,gBAAgB,CAAC;AAC5D,mBAAW,UAAU,cAAc;AACjC,cAAI,UAAU,UAAU,eAAgB;AACxC,oBAAU,KAAK;AAAA,YACb,SAAS;AAAA,YAAK,WAAW;AAAA,YAAO,UAAU;AAAA,YAC1C,OAAO,YAAY,IAAI,MAAM;AAAA,UAC/B,CAAC;AAAA,QACH;AAAA,MACF;AAGA,YAAM,QAAkB,CAAC;AACzB,UAAI,SAAS,OAAO;AAClB,cAAM,iBAAiB,oBAAI,IAAyB;AACpD,mBAAW,MAAM,eAAe;AAC9B,cAAI,GAAG,WAAW,aAAa,GAAG,kBAAkB,WAAW;AAC7D,gBAAI,CAAC,eAAe,IAAI,GAAG,OAAO,EAAG,gBAAe,IAAI,GAAG,SAAS,oBAAI,IAAI,CAAC;AAC7E,2BAAe,IAAI,GAAG,OAAO,EAAG,IAAI,GAAG,KAAK;AAAA,UAC9C;AAAA,QACF;AAEA,mBAAW,CAAC,KAAK,aAAa,KAAK,gBAAgB;AACjD,gBAAM,QAAQ,cAAc,KAAK,CAAC,OAAY,EAAE,WAAW,EAAE,UAAU,GAAG;AAC1E,cAAI,CAAC,OAAO,QAAS;AAErB,gBAAM,WAAW,MAAM,MAAM,eAAe,CAAC,GAAG;AAAA,YAAI,CAAC,OACnD,GAAG,WAAW,aAAa,cAAc,IAAI,GAAG,KAAK,IACjD,EAAE,GAAG,IAAI,QAAQ,UAAU,IAC3B;AAAA,UACN;AAEA,gBAAM,YAAY,kBAAkB;AAAA,YAClC,SAAS,MAAM;AAAA,YACf,MAAM,EAAE,aAAa,QAAQ;AAAA,UAC/B,CAAC;AACD,gBAAM,KAAK,MAAM,OAAO;AAAA,QAC1B;AAAA,MACF;AAEA,YAAM,SAAS;AAAA,QACb;AAAA,QAAY,cAAc;AAAA,QAC1B;AAAA,QAAe;AAAA,QAAW;AAAA,QAAO;AAAA,QACjC,OAAO;AAAA,QAAM;AAAA,MACf;AAEA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,OAAO,CAAC,EAAE;AAAA,IAC9D;AAAA,EACF;AACF;;;AC9WA,SAAS,KAAAE,UAAS;AAsDlB,IAAM,gBAA0C;AAAA,EAC9C,gBAAgB,CAAC,UAAU,UAAU,YAAY,aAAa,OAAO,WAAW,kBAAkB,WAAW,aAAa;AAAA,EAC1H,kBAAkB,CAAC,aAAa,YAAY,SAAS,cAAc,eAAe,SAAS,OAAO;AAAA,EAClG,wBAAwB,CAAC,OAAO,MAAM,UAAU,SAAS,QAAQ,OAAO,UAAU,SAAS;AAAA,EAC3F,wBAAwB,CAAC,MAAM,aAAa,OAAO,YAAY,YAAY,UAAU;AAAA,EACrF,gCAAgC,CAAC,cAAc,YAAY,QAAQ,UAAU,cAAc,UAAU;AAAA,EACrG,wBAAwB,CAAC,aAAa,WAAW,YAAY,SAAS,UAAU,QAAQ;AAAA,EACxF,YAAY,CAAC,YAAY,QAAQ,WAAW,cAAc,UAAU,OAAO;AAC7E;AAEA,SAAS,UAAU,MAAsB;AACvC,QAAM,QAAQ,KAAK,YAAY;AAC/B,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,aAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC5D,UAAM,QAAQ,SAAS,OAAO,CAAC,OAAO,MAAM,SAAS,EAAE,CAAC,EAAE;AAC1D,QAAI,QAAQ,WAAW;AACrB,kBAAY;AACZ,iBAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAAsB;AACzC,SAAO,UAAU,IAAI,KAAK;AAC5B;AAEA,IAAM,gBAA8C;AAAA,EAClD,WAAW;AAAA,IACT,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO,CAAC,QAAQ,IAAI,KAAK,SAAS,MAAM,CAAC,CAAC,eAAe,aAAa,YAAY,MAAM,EAAE,SAAS,IAAI,KAAK,YAAY,CAAC;AAAA,IACzH,YAAY,MAAM;AAAA,EACpB;AAAA,EACA,gBAAgB;AAAA,IACd,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO,CAAC,QAAQ,IAAI,YAAY,SAAS;AAAA,IACzC,YAAY,MAAM;AAAA,EACpB;AAAA,EACA,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO,CAAC,QAAQ,IAAI,aAAa,UAAU;AAAA,IAC3C,YAAY,MAAM;AAAA,EACpB;AAAA,EACA,kBAAkB;AAAA,IAChB,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO,CAAC,QAAQ;AACd,YAAM,QAAQ,IAAI,IAAI,IAAI,aAAa,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC;AACrE,aAAO,MAAM,QAAQ;AAAA,IACvB;AAAA,IACA,YAAY,MAAM;AAAA,EACpB;AACF;AAEA,IAAM,WAA2C,oBAAI,IAAI;AAAA,EACvD,CAAC,YAAY;AAAA,IACX,UAAU;AAAA,IACV,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,UAAU;AAAA,MACR,EAAE,KAAK,YAAY,OAAO,SAAS;AAAA,MACnC,EAAE,KAAK,QAAQ,OAAO,QAAQ;AAAA,MAC9B,EAAE,KAAK,UAAU,OAAO,QAAQ;AAAA,MAChC,EAAE,KAAK,YAAY,OAAO,QAAQ;AAAA,IACpC;AAAA,IACA,0BAA0B,CAAC,uBAAuB,cAAc,cAAc,YAAY;AAAA,IAC1F,YAAY,CAAC,QAAQ;AACnB,YAAM,SAAkC,CAAC;AACzC,YAAM,OAAO,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW;AAC3C,YAAM,OAAO,UAAU,IAAI;AAC3B,UAAI,KAAM,QAAO,SAAS;AAC1B,UAAI,KAAK,YAAY,EAAE,SAAS,UAAU,KAAK,KAAK,YAAY,EAAE,SAAS,SAAS,GAAG;AACrF,eAAO,WAAW;AAAA,MACpB,WAAW,KAAK,YAAY,EAAE,SAAS,YAAY,KAAK,KAAK,YAAY,EAAE,SAAS,SAAS,KAAK,KAAK,YAAY,EAAE,SAAS,UAAU,GAAG;AACzI,eAAO,WAAW;AAAA,MACpB,OAAO;AACL,eAAO,WAAW;AAAA,MACpB;AACA,UAAI,KAAM,QAAO,eAAe;AAChC,aAAO;AAAA,IACT;AAAA,IACA,eAAe;AAAA,MACb,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,aAAa;AAAA,QAC7D,YAAY,CAAC,QAAQ;AACnB,gBAAM,OAAO,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,GAAG,YAAY;AAC1D,gBAAM,WAAW,KAAK,SAAS,UAAU,IAAI,aAAa,KAAK,SAAS,YAAY,IAAI,SAAS;AACjG,iBAAO,gCAA2B,QAAQ;AAAA,QAC5C;AAAA,MACF;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,gBAAgB,IAAI,KAAK,iBAAiB;AAAA,QACrE,YAAY,CAAC,QAAQ;AACnB,gBAAM,OAAO,UAAU,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE;AACvD,iBAAO,OACH,qCAAgC,IAAI,+BACpC;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,CAAC,kBAAkB;AAAA,IACjB,UAAU;AAAA,IACV,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,UAAU;AAAA,MACR,EAAE,KAAK,YAAY,OAAO,SAAS;AAAA,MACnC,EAAE,KAAK,UAAU,OAAO,QAAQ;AAAA,IAClC;AAAA,IACA,0BAA0B,CAAC,WAAW,cAAc,kBAAkB,YAAY;AAAA,IAClF,YAAY,CAAC,QAAQ;AACnB,YAAM,SAAkC,CAAC;AACzC,YAAM,SAAS,YAAY,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE;AAC3D,UAAI,OAAQ,QAAO,SAAS;AAC5B,aAAO;AAAA,IACT;AAAA,IACA,eAAe;AAAA,MACb,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,OAAO,IAAI,KAAK,cAAc,YAAY,IAAI,KAAK,UAAU,SAAS;AAAA,QACtF,YAAY,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,WAAW;AAAA,QACzD,YAAY,CAAC,QAAQ;AACnB,gBAAM,SAAS,YAAY,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE;AAC3D,iBAAO,SACH,+BAA0B,MAAM,+BAChC;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,CAAC,YAAY;AAAA,IACX,UAAU;AAAA,IACV,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,UAAU;AAAA,MACR,EAAE,KAAK,YAAY,OAAO,QAAQ;AAAA,IACpC;AAAA,IACA,0BAA0B,CAAC,oBAAoB,iBAAiB,cAAc,YAAY;AAAA,IAC1F,YAAY,CAAC,QAAQ;AACnB,YAAM,SAAkC,CAAC;AACzC,YAAM,OAAO,UAAU,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE;AACvD,UAAI,MAAM;AACR,cAAM,cAAsC;AAAA,UAC1C,gBAAgB;AAAA,UAChB,kBAAkB;AAAA,UAClB,wBAAwB;AAAA,UACxB,wBAAwB;AAAA,UACxB,gCAAgC;AAAA,UAChC,wBAAwB;AAAA,UACxB,YAAY;AAAA,QACd;AACA,eAAO,WAAW,YAAY,IAAI,KAAK;AAAA,MACzC;AACA,aAAO;AAAA,IACT;AAAA,IACA,eAAe;AAAA,MACb,cAAc;AAAA,MACd;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ;AACd,gBAAM,YAAY,IAAI,KAAK;AAC3B,iBAAO,OAAO,cAAc,YAAY,UAAU,SAAS;AAAA,QAC7D;AAAA,QACA,YAAY,MAAM;AAAA,MACpB;AAAA,MACA,cAAc;AAAA,MACd;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,aAAa;AAAA,QAC7D,YAAY,MAAM;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,CAAC,aAAa;AAAA,IACZ,UAAU;AAAA,IACV,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,UAAU;AAAA,MACR,EAAE,KAAK,QAAQ,OAAO,QAAQ;AAAA,MAC9B,EAAE,KAAK,aAAa,OAAO,QAAQ;AAAA,IACrC;AAAA,IACA,0BAA0B,CAAC,WAAW,cAAc,YAAY,YAAY;AAAA,IAC5E,YAAY,CAAC,QAAQ;AACnB,YAAM,SAAkC,CAAC;AACzC,YAAM,OAAO,UAAU,GAAG,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE;AACvD,UAAI,KAAM,QAAO,YAAY;AAC7B,aAAO;AAAA,IACT;AAAA,IACA,eAAe;AAAA,MACb,cAAc;AAAA,MACd;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ;AACd,gBAAM,YAAY,IAAI,KAAK;AAC3B,iBAAO,OAAO,cAAc,YAAY,UAAU,SAAS;AAAA,QAC7D;AAAA,QACA,YAAY,MAAM;AAAA,MACpB;AAAA,MACA,cAAc;AAAA,MACd;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,SAAS;AAAA,QACrD,YAAY,MAAM;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;AAED,IAAM,mBAAsC;AAAA,EAC1C,UAAU;AAAA,EACV,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,UAAU,CAAC;AAAA,EACX,0BAA0B,CAAC,cAAc,YAAY;AAAA,EACrD,eAAe;AAAA,IACb,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,EAChB;AACF;AAIA,SAAS,gBAAgB,QAAwB;AAC/C,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,QAAQ;AACd,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAU,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,EAC1D;AACA,SAAO,GAAG,MAAM,IAAI,MAAM;AAC5B;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;AAEA,SAAS,sBACP,WACA,YACA,mBACA,kBACA,qBACQ;AACR,QAAM,OAAO,GAAG,UAAU,IAAI,iBAAiB,GAAG,YAAY;AAC9D,QAAM,gBAAgB,UAAU,KAAK,YAAY;AACjD,MAAI,QAAQ;AAEZ,MAAI,KAAK,SAAS,aAAa,KAAK,cAAc,SAAS,GAAG;AAC5D,aAAS;AAAA,EACX;AAEA,QAAM,iBAAiB,cAAc,MAAM,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC5E,QAAM,gBAAgB,eAAe,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AACnE,WAAU,cAAc,SAAS,KAAK,IAAI,eAAe,QAAQ,CAAC,IAAK;AAEvE,QAAM,kBAAkB,oBAAI,IAAI,CAAC,YAAY,UAAU,CAAC;AACxD,MAAI,gBAAgB,IAAI,mBAAmB,GAAG;AAC5C,aAAS;AAAA,EACX;AAEA,MAAI,wBAAwB,kBAAkB;AAC5C,aAAS;AAAA,EACX;AAEA,SAAO,KAAK,IAAI,OAAO,GAAG;AAC5B;AAEA,SAAS,kBACP,kBACA,kBACA,SACQ;AACR,QAAM,UAAkD;AAAA,IACtD,UAAU;AAAA,MACR,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB,UAAU;AAAA,MACV,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,IACA,kBAAkB;AAAA,MAChB,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB,UAAU;AAAA,IACZ;AAAA,IACA,WAAW;AAAA,MACT,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,QAAQ,gBAAgB,IAAI,gBAAgB,KAC9C,QAAQ,yBAAyB,CAAC,KAClC;AACP;AAUA,SAAS,aAAa,KAAqB,SAA2C;AACpF,QAAM,SAAS,QAAQ,cAAc,IAAI,CAAC,OAAO;AAC/C,UAAMC,UAAS,GAAG,MAAM,GAAG;AAC3B,WAAO;AAAA,MACL,IAAI,GAAG;AAAA,MACP,OAAO,GAAG;AAAA,MACV,QAAAA;AAAA,MACA,YAAYA,UAAS,SAAY,GAAG,aAAa,GAAG;AAAA,IACtD;AAAA,EACF,CAAC;AAED,QAAM,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AAC9C,QAAM,QAAQ,OAAO;AACrB,QAAM,QAAQ,QAAQ,IAAI,KAAK,MAAO,SAAS,QAAS,EAAE,IAAI;AAE9D,SAAO,EAAE,OAAO,UAAU,IAAI,OAAO;AACvC;AAEO,SAAS,oBAAoB,QAA+B;AACjE,QAAM,QAAkB,CAAC,eAAe,OAAO,KAAK,IAAI,OAAO,QAAQ,EAAE;AACzE,aAAW,SAAS,OAAO,QAAQ;AACjC,UAAM,OAAO,MAAM,SAAS,QAAQ;AACpC,UAAM,aAAa,MAAM,SAAS,KAAK,OAAO,MAAM,cAAc,EAAE;AACpE,UAAM,KAAK,GAAG,IAAI,IAAI,MAAM,KAAK,GAAG,UAAU,EAAE;AAAA,EAClD;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAIA,eAAsB,kBAAkB,SAAoE;AAC1G,QAAM,QAAQ,MAAM,SAAc,eAAe,EAAE,QAAQ,CAAC;AAC5D,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,MAAM,WAAW,OAAO;AAAA,MACxB,SAAS,EAAE,OAAO,GAAG,UAAU,IAAI,QAAQ,CAAC,EAAE;AAAA,IAChD;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,SAAgB,oBAAoB;AAC9D,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,KAAK,YAAa,SAAQ,IAAI,EAAE,KAAK,EAAE,IAAI;AACtD,QAAM,iBAAiB,QAAQ,IAAI,MAAM,YAAY,KAAK;AAE1D,QAAM,UAAU,SAAS,IAAI,cAAc,KAAK;AAEhD,QAAM,YAAY,MAAM,SAAgB,yBAAyB,EAAE,QAAQ,CAAC;AAC5E,QAAM,eAA6B,CAAC;AACpC,aAAW,KAAK,WAAW;AACzB,UAAM,UAAU,EAAE,WAAW,MAAM,MAAM,EAAE,OAAO,EAAE;AACpD,iBAAa,KAAK;AAAA,MAChB,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,cAAc,EAAE;AAAA,IAClB,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,QAAQ;AAC1B,QAAM,cAAc,OAAO,MAAM,OAAO,SAAS,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI;AAE1F,QAAM,MAAsB;AAAA,IAC1B,YAAY;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ;AAAA,IACA,MAAM,MAAM,QAAQ,CAAC;AAAA,IACrB,SAAS,MAAM,WAAW;AAAA,IAC1B;AAAA,IACA,gBAAgB,CAAC;AAAA,IACjB,kBAAkB,CAAC;AAAA,EACrB;AAEA,QAAM,UAAU,aAAa,KAAK,OAAO;AAEzC,QAAM,QAAkB;AAAA,IACtB,oBAAoB,MAAM,WAAW,MAAM,IAAI;AAAA,IAC/C,KAAK,MAAM,IAAI,WAAW,cAAc,OAAO,MAAM,MAAM;AAAA,IAC3D;AAAA,IACA,oBAAoB,OAAO;AAAA,EAC7B;AAEA,MAAI,QAAQ,QAAQ,IAAI;AACtB,UAAM,eAAe,QAAQ,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,UAAU;AAC3E,QAAI,aAAa,SAAS,GAAG;AAC3B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,sGAAsG;AAAA,IACnH;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,MAAM,KAAK,IAAI,GAAG,QAAQ;AAC3C;AAIA,IAAM,uBAAuB,oBAAI,IAAI;AAAA,EACnC;AAAA,EAAY;AAAA,EAAkB;AAAA,EAAc;AAAA,EAAa;AAAA,EAAY;AACvE,CAAC;AAED,IAAM,iCAAiC;AACvC,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAEjB,SAAS,0BAA0BC,SAAmB;AAE3D,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAMF,aAAa;AAAA,QACX,YAAYC,GAAE,OAAO,EAAE,SAAS,6EAA6E;AAAA,QAC7G,MAAMA,GAAE,OAAO,EAAE,SAAS,gGAA2F;AAAA,QACrH,aAAaA,GAAE,OAAO,EAAE,SAAS,yEAAoE;AAAA,QACrG,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yFAAyF;AAAA,QACjI,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yEAAyE;AAAA,MACnH;AAAA,MACA,aAAa,EAAE,iBAAiB,MAAM;AAAA,IACxC;AAAA,IACA,OAAO,EAAE,YAAY,MAAM,aAAa,SAAS,QAAQ,MAAM;AAC7D,YAAM,UAAU,SAAS,IAAI,UAAU,KAAK;AAG5C,YAAM,MAAM,MAAM,SAAc,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACxE,UAAI,CAAC,KAAK;AACR,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gBAAgB,UAAU,uEAAuE,CAAC;AAAA,QAC7I;AAAA,MACF;AAGA,YAAM,OAAgC,CAAC;AACvC,YAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAEnD,iBAAW,SAAS,IAAI,UAAU,CAAC,GAAG;AACpC,cAAM,MAAM,MAAM;AAClB,YAAI,QAAQ,QAAQ,kBAAkB;AACpC,eAAK,GAAG,IAAI;AAAA,QACd,WAAW,MAAM,SAAS,WAAW,MAAM,SAAS,gBAAgB;AAClE,eAAK,GAAG,IAAI,CAAC;AAAA,QACf,OAAO;AACL,eAAK,GAAG,IAAI;AAAA,QACd;AAAA,MACF;AAEA,iBAAW,OAAO,QAAQ,UAAU;AAClC,YAAI,IAAI,UAAU,SAAS;AACzB,eAAK,IAAI,GAAG,IAAI;AAAA,QAClB,WAAW,IAAI,UAAU,SAAS;AAChC,eAAK,IAAI,GAAG,IAAI,IAAI;AAAA,QACtB;AAAA,MACF;AAEA,UAAI,QAAQ,YAAY;AACtB,cAAM,WAAW,QAAQ,WAAW;AAAA,UAClC;AAAA,UAAY;AAAA,UAAM;AAAA,UAAa;AAAA,UAAS;AAAA,UAAM,SAAS;AAAA,UACvD,cAAc,CAAC;AAAA,UAAG,gBAAgB,CAAC;AAAA,UAAG,kBAAkB,IAAI,UAAU,CAAC;AAAA,QACzE,CAAC;AACD,mBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACjD,cAAI,QAAQ,UAAa,QAAQ,IAAI;AACnC,iBAAK,GAAG,IAAI;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,KAAK,QAAQ,gBAAgB,KAAK,CAAC,KAAK,eAAe,CAAC,KAAK,WAAW;AAC3E,aAAK,QAAQ,oBAAoB,aAAa,IAAI;AAAA,MACpD;AAGA,YAAM,SAAS,qBAAqB,IAAI,UAAU,IAAI,UAAU;AAGhE,YAAM,eAAe,WAAW,gBAAgB,QAAQ,QAAQ;AAGhE,UAAI;AACJ,UAAI;AACF,qBAAa,MAAM,YAAoB,kBAAkB;AAAA,UACvD,gBAAgB;AAAA,UAChB,SAAS,gBAAgB;AAAA,UACzB;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb,CAAC;AAAA,MACH,SAAS,OAAgB;AACvB,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,YAAI,IAAI,SAAS,WAAW,KAAK,IAAI,SAAS,gBAAgB,GAAG;AAC/D,iBAAO;AAAA,YACL,SAAS,CAAC;AAAA,cACR,MAAM;AAAA,cACN,MAAM;AAAA;AAAA,EAA4C,GAAG;AAAA;AAAA;AAAA,YACvD,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAGA,YAAM,eAA6B,CAAC;AACpC,YAAM,iBAAmC,CAAC;AAE1C,YAAM,cAAc,mBAAmB,MAAM,WAAW;AACxD,UAAI,aAAa;AACf,cAAM,CAAC,eAAe,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,UACxD,SAAgB,oBAAoB,EAAE,OAAO,YAAY,CAAC;AAAA,UAC1D,SAAgB,oBAAoB;AAAA,QACtC,CAAC;AAED,cAAM,UAAU,oBAAI,IAAoB;AACxC,mBAAW,KAAK,eAAgB,SAAQ,IAAI,EAAE,KAAK,EAAE,IAAI;AAEzD,cAAM,cAAc,iBAAiB,CAAC,GACnC,OAAO,CAAC,MAAM,EAAE,YAAY,gBAAgB,EAAE,QAAQ,UAAU,EAChE,IAAI,CAAC,OAAO;AAAA,UACX,GAAG;AAAA,UACH,UAAU,QAAQ,IAAI,EAAE,YAAY,KAAK;AAAA,UACzC,YAAY,sBAAsB,GAAG,MAAM,aAAa,YAAY,QAAQ,IAAI,EAAE,YAAY,KAAK,SAAS;AAAA,QAC9G,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,UAAU;AAG7C,mBAAW,KAAK,YAAY;AAC1B,cAAI,aAAa,UAAU,eAAgB;AAC3C,cAAI,EAAE,aAAa,+BAAgC;AACnD,cAAI,CAAC,EAAE,WAAW,CAAC,aAAc;AAEjC,gBAAM,eAAe,kBAAkB,YAAY,EAAE,UAAU,OAAO;AACtE,cAAI;AACF,kBAAM,YAAY,0BAA0B;AAAA,cAC1C,aAAa;AAAA,cACb,WAAW,EAAE;AAAA,cACb,MAAM;AAAA,YACR,CAAC;AACD,yBAAa,KAAK;AAAA,cAChB,eAAe,EAAE;AAAA,cACjB,YAAY,EAAE;AAAA,cACd,kBAAkB,EAAE;AAAA,cACpB;AAAA,YACF,CAAC;AAAA,UACH,QAAQ;AAAA,UAER;AAAA,QACF;AAGA,cAAM,YAAY,IAAI,IAAI,aAAa,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC;AAClE,mBAAW,KAAK,YAAY;AAC1B,cAAI,eAAe,UAAU,gBAAiB;AAC9C,cAAI,UAAU,IAAI,EAAE,OAAO,EAAG;AAC9B,cAAI,EAAE,aAAa,GAAI;AAEvB,gBAAM,UAAUC,gBAAe,EAAE,MAAM,EAAE;AACzC,gBAAM,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,yBAAe,KAAK;AAAA,YAClB,SAAS,EAAE;AAAA,YACX,MAAM,EAAE;AAAA,YACR,YAAY,EAAE;AAAA,YACd;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAGA,YAAM,aAA6B;AAAA,QACjC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,kBAAkB,IAAI,UAAU,CAAC;AAAA,MACnC;AACA,YAAM,UAAU,aAAa,YAAY,OAAO;AAGhD,YAAM,QAAkB;AAAA,QACtB,eAAe,gBAAgB,IAAI;AAAA,QACnC,KAAK,IAAI,iBAAiB,UAAU,WAAW,MAAM;AAAA,MACvD;AAEA,UAAI,aAAa,SAAS,GAAG;AAC3B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,mBAAmB,aAAa,MAAM,GAAG;AACpD,mBAAW,QAAQ,cAAc;AAC/B,gBAAM,KAAK,UAAU,KAAK,YAAY,MAAM,KAAK,aAAa,KAAK,KAAK,UAAU,KAAK,KAAK,gBAAgB,GAAG;AAAA,QACjH;AAAA,MACF;AAEA,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,oDAAoD;AAC/D,iBAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,gBAAM,IAAI,eAAe,CAAC;AAC1B,gBAAM,UAAU,EAAE,UAAU,WAAM,EAAE,OAAO,KAAK;AAChD,gBAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,SAAS,OAAO,EAAE,IAAI,KAAK,EAAE,UAAU,IAAI,OAAO,EAAE;AAAA,QAC7F;AAAA,MACF;AAEA,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,oBAAoB,OAAO,CAAC;AAEvC,YAAM,eAAe,QAAQ,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM;AAC3D,UAAI,aAAa,SAAS,GAAG;AAC3B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,wCAAwC,YAAY,8BAA8B;AAAA,MAC/F;AAEA,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,IACxE;AAAA,EACF;AAIA,EAAAF,QAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAa;AAAA,QACX,SAASC,GAAE,OAAO,EAAE,SAAS,6DAA6D;AAAA,MAC5F;AAAA,MACA,aAAa,EAAE,cAAc,KAAK;AAAA,IACpC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,kBAAkB,OAAO;AAC9C,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,OAAO,KAAK,CAAC,EAAE;AAAA,IACnE;AAAA,EACF;AACF;AAIA,SAASC,gBAAe,MAAW,QAAwB;AACzD,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,MAAM,KAAK,eAAe,KAAK,aAAa,KAAK,UAAU,KAAK,QAAQ;AAC9E,MAAI,OAAO,QAAQ,YAAY,CAAC,IAAK,QAAO;AAC5C,SAAO,IAAI,SAAS,SAAS,IAAI,UAAU,GAAG,MAAM,IAAI,QAAQ;AAClE;;;ACrvBA,SAAoB,wBAAwB;AAG5C,SAAS,oBAAoB,OAAoB;AAC/C,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,eACQ;AACR,QAAM,WAAqB,CAAC,mCAA8B;AAG1D,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,IAGpC,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,EAgBF;AAGA,WAAS;AAAA,IACP;AAAA,EAWF;AAGA,WAAS;AAAA,IACP;AAAA,EAYF;AAEA,SAAO,SAAS,KAAK,aAAa;AACpC;AAEO,SAAS,kBAAkBC,SAAmB;AAEnD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,CAAC,mBAAmB,cAAc,iBAAiB,WAAW,IAAI,MAAM,QAAQ,WAAW;AAAA,QAC/F,SAAgB,oBAAoB;AAAA,QACpC,SAAgB,kBAAkB,EAAE,gBAAgB,kBAAkB,CAAC;AAAA,QACvE,SAAgB,kBAAkB,EAAE,gBAAgB,YAAY,CAAC;AAAA,QACjE,SAAgB,kBAAkB,EAAE,gBAAgB,iBAAiB,CAAC;AAAA,MACxE,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;AAE/E,aAAO;AAAA,QACL,UAAU,CAAC;AAAA,UACT,KAAK,IAAI;AAAA,UACT,MAAM,yBAAyB,aAAa,gBAAgB,WAAW,aAAa;AAAA,UACpF,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,CAAC,gBAAgB,eAAe,IAAI,MAAM,QAAQ,WAAW;AAAA,QACjE,SAAgB,kBAAkB,EAAE,gBAAgB,WAAW,CAAC;AAAA,QAChE,SAAgB,kBAAkB,EAAE,gBAAgB,YAAY,CAAC;AAAA,MACnE,CAAC;AAED,YAAM,QAAkB,CAAC,mCAA8B;AAEvD,UAAI,eAAe,WAAW,aAAa;AACzC,YAAI,eAAe,MAAM,SAAS,GAAG;AACnC,gBAAM,QAAQ,eAAe,MAC1B,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,eAAe,MAAM,MAAM;AAAA;AAAA,EAAc,KAAK,EAAE;AAAA,QAC7E,OAAO;AACL,gBAAM,KAAK,mGAAmG;AAAA,QAChH;AAAA,MACF,OAAO;AACL,cAAM,KAAK,0GAAqG;AAAA,MAClH;AAEA,UAAI,gBAAgB,WAAW,aAAa;AAC1C,YAAI,gBAAgB,MAAM,SAAS,GAAG;AACpC,gBAAM,OAAO,gBAAgB,MAC1B,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,gBAAgB,MAAM,MAAM;AAAA;AAAA,EAAgB,IAAI,EAAE;AAAA,QAChF,OAAO;AACL,gBAAM,KAAK,oGAAoG;AAAA,QACjH;AAAA,MACF,OAAO;AACL,cAAM,KAAK,6GAAwG;AAAA,MACrH;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,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,cAAc,MAAM,SAAgB,oBAAoB;AAE9D,UAAI,YAAY,WAAW,GAAG;AAC5B,eAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,MAAM,qCAAqC,UAAU,gBAAgB,CAAC,EAAE;AAAA,MAC/G;AAEA,YAAM,YAAY,YACf,IAAI,CAAC,MAAM;AACV,cAAM,YAAY,EAAE,OACjB,IAAI,CAAC,MAAW,SAAS,EAAE,GAAG,OAAO,EAAE,IAAI,GAAG,EAAE,WAAW,eAAe,EAAE,GAAG,EAAE,aAAa,iBAAiB,EAAE,GAAG,EACpH,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,EAAAA,QAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,iCAAiC;AAAA,MACpD,MAAM,YAAY;AAChB,cAAM,cAAc,MAAM,SAAgB,oBAAoB;AAC9D,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;AACvB,YAAM,UAAU,MAAM,SAAgB,kBAAkB,EAAE,gBAAgB,KAAe,CAAC;AAC1F,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,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,SAAS,MAAM,SAAgB,eAAe;AAEpD,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;AACF;;;ACrSA,SAAS,KAAAC,UAAS;AAGX,SAAS,gBAAgBC,SAAmB;AACjD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,QAAQC,GAAE,OAAO,EAAE,SAAS,iFAAiF,EAAE;AAAA,IACjH,OAAO,EAAE,OAAO,MAAM;AACpB,YAAM,UAAU,MAAM,SAAgB,kBAAkB,EAAE,gBAAgB,iBAAiB,CAAC;AAC5F,YAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,MAAM;AAE7D,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,EAAAD,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,OAAOC,GAAE,OAAO,EAAE,SAAS,8FAA8F,EAAE;AAAA,IAC7H,OAAO,EAAE,MAAM,MAAM;AACnB,YAAM,QAAQ,MAAM,SAAgB,kBAAkB,EAAE,gBAAgB,WAAW,CAAC;AAEpF,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,EAAAD,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,EAAE,SAASC,GAAE,OAAO,EAAE,SAAS,yGAAyG,EAAE;AAAA,IAC1I,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,kBAAkB,MAAM,SAAgB,kBAAkB,EAAE,gBAAgB,YAAY,CAAC;AAC/F,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,EAAAD,QAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAaC,GAAE,OAAO,EAAE,SAAS,2FAA2F;AAAA,MAC5H,QAAQA,GAAE,OAAO,EAAE,SAAS,yEAAyE;AAAA,IACvG;AAAA,IACA,OAAO,EAAE,aAAa,OAAO,MAAM;AACjC,YAAM,WAAW,MAAM,SAAgB,kBAAkB,EAAE,gBAAgB,iBAAiB,CAAC;AAC7F,YAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,MAAM;AAEtE,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,YAAM,iBAAiB,SACpB,IAAI,CAAC,MAAM,UAAU,EAAE,WAAW,IAAI,QAAQ,YAAY,EAAE,GAAG,EAAE,CAAC,EAClE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EACvB,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK;AAC/B,YAAM,aAAa,OAAO,OAAO,iBAAiB,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAErE,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,qBACK,UAAU;AAAA;AAAA;AAAA,EACG,eAAe;AAAA;AAAA;AAAA,kBAE/B,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAUjC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AT/KA,IAAI,CAAC,QAAQ,IAAI,mBAAmB,CAAC,QAAQ,IAAI,sBAAsB;AACrE,MAAI;AACF,UAAM,UAAUC,SAAQ,QAAQ,IAAI,GAAG,UAAU;AACjD,eAAW,QAAQC,cAAa,SAAS,OAAO,EAAE,MAAM,IAAI,GAAG;AAC7D,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,YAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,UAAI,UAAU,GAAI;AAClB,cAAQ,IAAI,QAAQ,MAAM,GAAG,KAAK,CAAC,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,IAClE;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAGA,mBAAmB;AAEnB,IAAM,iBAAiB;AAEvB,cAAc;AAEd,IAAI;AACJ,IAAI;AACF,gBAAc,MAAM,eAAe;AACrC,SAAS,KAAU;AACjB,QAAM,OACJ,CAAC,QAAQ,IAAI,wBAAwB,CAAC,QAAQ,IAAI,kBAC9C,oIACA;AACN,UAAQ,OAAO,MAAM,yBAAyB,IAAI,OAAO,GAAG,IAAI;AAAA,CAAI;AACpE,UAAQ,KAAK,CAAC;AAChB;AAEA;AAAA,EACE,QAAQ,IAAI,kBAAkB;AAAA,EAC9B;AAAA,EACA;AACF;AAEA,IAAM,SAAS,IAAIC;AAAA,EACjB;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,cAAc,EAAE,SAAS,CAAC,EAAE;AAAA,IAC5B,cAAc;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEA,uBAAuB,MAAM;AAC7B,mBAAmB,MAAM;AACzB,oBAAoB,MAAM;AAC1B,oBAAoB,MAAM;AAC1B,0BAA0B,MAAM;AAChC,kBAAkB,MAAM;AACxB,gBAAgB,MAAM;AAEtB,IAAM,YAAY,IAAI,qBAAqB;AAC3C,MAAM,OAAO,QAAQ,SAAS;AAE9B,eAAe,mBAAmB;AAChC,QAAM,kBAAkB;AACxB,UAAQ,KAAK,CAAC;AAChB;AAEA,QAAQ,GAAG,UAAU,gBAAgB;AACrC,QAAQ,GAAG,WAAW,gBAAgB;","names":["readFileSync","resolve","McpServer","workspaceId","workspace","workspaceId","server","z","server","z","z","log","server","workspaceId","z","z","server","z","z","passed","server","z","extractPreview","server","z","server","z","resolve","readFileSync","McpServer"]}
|