@chrok/dsh-braid 0.0.0-stage → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../client/index.tsx", "../panel-contract.ts", "../client/Panel.tsx", "../client/layout.ts", "../client/styles.ts", "../client/navigation.ts", "../client/ToolCall.tsx"],
4
+ "sourcesContent": ["import * as React from \"react\";\nimport type { Context } from \"@deepseek-ai/cordis\";\nimport type {} from \"@deepseek-ai/dsh-api-gateway/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-renderer/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-conversation/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-sidebar-right/client\";\nimport type {} from \"@deepseek-ai/dsh-client-ui-tool/client\";\nimport type { PropsRuntime } from \"@deepseek-ai/dsh-client-ui-slots\";\nimport type { SessionId } from \"@deepseek-ai/dsh-session/types\";\nimport type { PanelApi } from \"../panel-types.js\";\nimport { PANEL_PACKAGE, panelDescriptors } from \"../panel-contract.js\";\nimport { BraidPanelView } from \"./Panel.js\";\nimport { styles, toolStyles } from \"./styles.js\";\nimport { BraidToolCall } from \"./ToolCall.js\";\nimport { braidToolNames, readNavigation, type BraidNavigation } from \"./navigation.js\";\n\ndeclare module \"@deepseek-ai/dsh-client-ui-sidebar-right/client\" {\n interface SidebarRightTabParamsMap { braid: BraidNavigation }\n}\n\nexport const inject = [\"remote\", \"slots\", \"sidebarRight\", \"sidebarRightTabs\"];\nexport async function apply(ctx: Context): Promise<void> {\n await ctx.remote.$mount({ package: PANEL_PACKAGE, descriptors: panelDescriptors });\n ctx.inject([\"remote.braidPanel\"], ctx => {\n // Capture traced services inside their declared Cordis scope, not React event stacks.\n const remote = ctx.remote.braidPanel;\n const sidebar = ctx.sidebarRight;\n const api: PanelApi = {\n watch: (request, signal) => remote.watch(request, signal),\n control: async request => { const result = await remote.control(request); if (!result.ok) throw result.error; return result.value; },\n detail: async request => { const result = await remote.detail(request); if (!result.ok) throw result.error; return result.value; },\n };\n ctx.effect(() => {\n const style = document.createElement(\"style\"); style.dataset.plugin = PANEL_PACKAGE; style.textContent = styles + toolStyles;\n document.head.append(style); return () => { style.remove(); };\n });\n ctx.effect(() => ctx.sidebarRightTabs.register({ id: PANEL_PACKAGE, kind: \"braid\", title: () => \"Braid\",\n guide: [{ id: \"braid\", order: 50, title: () => \"Braid\", description: () => \"Live agent graphs, execution details and controls\" }],\n }));\n ctx.effect(() => ctx.slots.inject(\"sidebar.right.pane.tab\", () => ctx.slots.register({\n name: \"sidebar.right.pane.tab\", key: PANEL_PACKAGE, inject: sessionId => ({ api, sessionId }),\n }, PanelSeat)));\n ctx.effect(() => ctx.slots.inject(\"conversation.session.header.actions\", () => ctx.slots.register({\n name: \"conversation.session.header.actions\", id: \"braid\", order: 25,\n inject: () => ({ open: () => { sidebar.openTab(\"braid\"); } }),\n }, HeaderAction)));\n for (const key of braidToolNames) ctx.effect(() => ctx.slots.inject(\"tool.call.toolview\", () => ctx.slots.register({\n name: \"tool.call.toolview\", key,\n inject: sessionId => ({ openBraid: (target: BraidNavigation) => { sidebar.openTabIn(sessionId as SessionId, \"braid\", { params: target }); } }),\n }, BraidToolCall)));\n });\n}\nfunction HeaderAction({ open }: { open: () => void }) {\n return <button className=\"br-header-action\" onClick={open} title=\"Open Braid graph and execution details\" aria-label=\"Open Braid panel\">\u2387 Braid</button>;\n}\nfunction PanelSeat({ sessionId, api, useTabInfo }: PropsRuntime<\"sidebar.right.pane.tab\"> & { sessionId: string; api: PanelApi }) {\n const { tab: { navigation } } = useTabInfo();\n return <BraidPanelView key={navigation.revision} sessionId={sessionId} api={api} target={readNavigation(navigation.params)}/>;\n}\n", "import type { InvocationDescriptor, RemoteResult } from \"@deepseek-ai/dsh-typert-protocol\";\nimport type { ControlRequest, DetailRequest, PanelDetail, PanelFrame, PanelRequest } from \"./panel-types.js\";\n\n/** One descriptor table shared by Host registration and Client Remote mounting. */\nexport const PANEL_PACKAGE = \"@chrok/dsh-braid\";\nfunction parseRequest(value: unknown, method: string): unknown {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"Invalid Braid panel request\");\n const r = value as Record<string, unknown>;\n const id = (key: string) => typeof r[key] === \"string\" && (r[key] as string).length > 0 && (r[key] as string).length <= 1024;\n if (!id(\"sessionId\") || (r.jobId !== undefined && !id(\"jobId\"))) throw new Error(\"Invalid session or job ID\");\n if (r.createdBefore !== undefined && (!Number.isSafeInteger(r.createdBefore) || Number(r.createdBefore) < 0)) throw new Error(\"Invalid call timestamp\");\n if (method !== \"watch\" && !id(\"jobId\")) throw new Error(\"A job ID is required\");\n if (method === \"control\" && (\n ![\"cancel\", \"resume\"].includes(String(r.action)) || !Number.isSafeInteger(r.revision) || Number(r.revision) < 0 ||\n !Array.isArray(r.executionIds) || r.executionIds.length > 10000 || r.executionIds.some(v => typeof v !== \"string\" || !v || v.length > 1024)\n )) throw new Error(\"Invalid Braid control request\");\n if (method === \"detail\" && (!id(\"executionId\") || !Number.isSafeInteger(r.offset) || Number(r.offset) < 0)) throw new Error(\"Invalid execution or offset\");\n return value;\n}\nexport const panelDescriptors: InvocationDescriptor[] = [\"watch\", \"control\", \"detail\"].map(method => ({\n id: `${PANEL_PACKAGE}#braidPanel/${method}`, service: \"braidPanel\", namespace: \"braidPanel\", method,\n invocation: { kind: \"direct\" },\n parameters: [{ name: \"request\", wire: \"request\", source: \"json\", codec: {\n mode: \"strict\", typeSymbol: `${PANEL_PACKAGE}/${method}Request`, create: () => ({ parse: value => parseRequest(value, method) }),\n } }],\n result: { mode: \"src-json\" },\n ...(method === \"watch\" ? { mode: \"stream\" as const, cancellation: { parameter: \"signal\" as const } } : {}),\n}));\nexport interface PanelRemote {\n watch(request: PanelRequest, signal?: AbortSignal): AsyncIterable<PanelFrame>;\n control(request: ControlRequest): Promise<RemoteResult<PanelFrame>>;\n detail(request: DetailRequest): Promise<RemoteResult<PanelDetail>>;\n}\ndeclare module \"@deepseek-ai/dsh-typert-protocol\" {\n interface TypertRemoteNamespaceMap { braidPanel: PanelRemote }\n interface RemoteErrorDetailsMap { \"braid/panel\": { sessionId: string } }\n}\n", "import * as React from \"react\";\nimport { useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport type { PanelApi, PanelDetail, PanelExecution, PanelFrame, PanelJob } from \"../panel-types.js\";\nimport { layoutGraph } from \"./layout.js\";\nimport type { BraidNavigation } from \"./navigation.js\";\n\nconst number = (n: number) => n.toLocaleString();\nconst message = (error: unknown) => error instanceof Error ? error.message : String(error);\nexport function Status({ status }: { status: string }) {\n return <span className=\"br-status\" data-status={status}>{status}</span>;\n}\n\nexport function Graph({ job, selected, select }: { job: PanelJob; selected: string; select: (id: string) => void }) {\n const layout = useMemo(() => layoutGraph(job.nodes, job.edges), [job.nodes, job.edges]);\n const [zoom, setZoom] = useState(1);\n const arrow = useId().replaceAll(\":\", \"\");\n const selectedButton = useRef<HTMLButtonElement>(null);\n useEffect(() => { selectedButton.current?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" }); }, [selected]);\n return <section className=\"br-section\" aria-label=\"Execution graph\">\n <div className=\"br-section-head\"><h3>Execution graph</h3><div className=\"br-toolbar\">\n <button aria-label=\"Zoom out\" disabled={zoom <= .5} onClick={() => setZoom(v => Math.max(.5, v - .25))}>\u2212</button>\n <button aria-label=\"Reset zoom\" onClick={() => setZoom(1)}>{Math.round(zoom * 100)}%</button>\n <button aria-label=\"Zoom in\" disabled={zoom >= 1.5} onClick={() => setZoom(v => Math.min(1.5, v + .25))}>+</button>\n </div></div>\n <div className=\"br-graph\"><div style={{ width: layout.width * zoom, height: layout.height * zoom }}>\n <div className=\"br-graph-canvas\" style={{ width: layout.width, height: layout.height, transform: `scale(${zoom})`, transformOrigin: \"top left\" }}>\n <svg width={layout.width} height={layout.height} aria-hidden=\"true\"><defs><marker id={arrow} viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" style={{ fill: \"var(--br-muted)\" }}/></marker></defs>\n {job.edges.map((edge, i) => {\n const a = layout.positions.get(edge.from), b = layout.positions.get(edge.to);\n if (!a || !b) return null;\n const x = a.x + 77, y = a.y + 72, endX = b.x + 77, endY = b.y;\n const d = edge.feedback ? `M ${a.x} ${a.y + 36} C 6 ${a.y + 36}, 6 ${b.y + 36}, ${b.x} ${b.y + 36}` : `M ${x} ${y} C ${x} ${y + 26}, ${endX} ${endY - 26}, ${endX} ${endY}`;\n return <g key={i}><path d={d} strokeDasharray={edge.feedback ? \"4 4\" : undefined} markerEnd={`url(#${arrow})`}><title>{edge.from} \u2192 {edge.to}{edge.choice ? ` (${edge.choice})` : \"\"}{edge.feedback ? ` \u00B7 loop ${edge.feedback}` : \"\"}{edge.executionId ? ` \u00B7 ${edge.executionId}` : \"\"}</title></path>\n {edge.choice && !edge.feedback && <text x={(x + endX) / 2 + 5} y={(y + endY) / 2 - 4}>{edge.choice.slice(0, 22)}</text>}</g>;\n })}\n </svg>\n {job.nodes.map(node => { const p = layout.positions.get(node.id)!; return <button key={node.id} ref={selected === node.id ? selectedButton : undefined} className=\"br-node\" style={{ left: p.x, top: p.y }} aria-pressed={selected === node.id} onClick={() => select(node.id)} title={`${node.id} \u00B7 ${node.type} \u00B7 ${node.status}`}>\n <small>{node.type}</small><strong>{node.id}</strong><Status status={node.status}/>\n </button>; })}\n </div>\n </div></div>\n <div className=\"br-legend\"><span>Solid \u00B7 dependency</span><span>Dashed \u00B7 loop feedback</span><span>Click a node to inspect</span></div>\n {job.loops.map(loop => <p className=\"br-note\" key={loop.id}>Loop {loop.id} \u00B7 entry {loop.entry} \u00B7 maximum {loop.maxIterations} iterations</p>)}\n </section>;\n}\n\nfunction ExecutionDetail({ api, sessionId, job, execution }: { api: PanelApi; sessionId: string; job: PanelJob; execution: PanelExecution }) {\n const [detail, setDetail] = useState<PanelDetail>();\n const [error, setError] = useState(\"\");\n const [offset, setOffset] = useState(0);\n const [retry, setRetry] = useState(0);\n useEffect(() => {\n let active = true;\n setDetail(undefined); setError(\"\");\n void api.detail({ sessionId, jobId: job.jobId, executionId: execution.executionId, offset }).then(value => {\n if (active) setDetail(value);\n }, e => { if (active) setError(message(e)); });\n return () => { active = false; };\n }, [api, sessionId, job.jobId, job.status, execution.executionId, execution.status, offset, retry]);\n const p = execution.progress;\n return <>\n <div className=\"br-detail-grid\">\n <div><span>Execution</span>{execution.executionId}</div><div><span>Revision / iteration</span>r{execution.revision} / {execution.iteration ?? \"\u2014\"}</div>\n <div><span>Elapsed</span>{execution.latencyMs === undefined ? \"\u2014\" : `${(execution.latencyMs / 1000).toFixed(1)}s`}</div>\n <div><span>Worker</span>{p?.phase ?? execution.status}</div>\n <div><span>Context ({p?.contextSource ?? \"unreported\"})</span>{p ? `${number(p.contextTokens)}${p.contextWindow ? ` / ${number(p.contextWindow)}` : \"\"}` : \"\u2014\"}</div>\n <div><span>Tool calls / rounds</span>{p ? `${p.toolCalls} / ${p.toolRounds}` : \"\u2014\"}</div>\n </div>\n {error && <div role=\"alert\">{error} <button onClick={() => setRetry(v => v + 1)}>Retry output</button></div>}\n {!detail && !error && <p className=\"br-muted\" role=\"status\">Loading output\u2026</p>}\n {detail && <>\n {detail.error && <p role=\"alert\">{detail.error}</p>}\n {detail.decision && <p>Decision: <strong>{detail.decision}</strong></p>}\n <pre className=\"br-output\" aria-label=\"Execution output\">{detail.output || (execution.status === \"running\" ? \"Output will appear when this execution finishes.\" : \"No output for this execution.\")}</pre>\n {detail.total > 32768 && <div className=\"br-toolbar\"><button disabled={offset === 0} onClick={() => setOffset(Math.max(0, offset - 32768))}>Previous output</button><small className=\"br-muted\">{number(detail.offset)}\u2013{number(detail.next)} / {number(detail.total)} characters</small><button disabled={detail.next >= detail.total} onClick={() => setOffset(detail.next)}>Next output</button></div>}\n {detail.workspace && <details><summary>Workspace and recovery refs</summary><pre className=\"br-output\">{detail.workspace}</pre></details>}\n </>}\n </>;\n}\n\nfunction JobView({ job, api, sessionId, connected, act, busy, target }: { job: PanelJob; api: PanelApi; sessionId: string; connected: boolean; act: (action: \"cancel\" | \"resume\", ids: string[]) => void; busy: boolean; target: BraidNavigation | undefined }) {\n const [selected, setSelected] = useState(() => job.executions.find(e => e.executionId === target?.executionId)?.id\n ?? target?.nodeId ?? (target?.executionId ? \"\" : job.nodes[0]?.id ?? \"\"));\n const [chosenExecution, setChosenExecution] = useState(target?.executionId ?? \"\");\n const [tab, setTab] = useState(\"output\");\n const executions = job.executions.filter(e => e.id === selected);\n const execution = chosenExecution ? executions.find(e => e.executionId === chosenExecution) : executions.at(-1);\n const paused = execution && job.pausedExecutionIds.includes(execution.executionId);\n return <>\n <div className=\"br-stats\"><div><strong>{job.executions.filter(e => e.status === \"completed\").length}/{job.executions.length}</strong><span>Executions complete</span></div><div><strong>{number(job.usage.inputTokens)}</strong><span>Input tokens</span></div><div><strong>{number(job.usage.outputTokens)}</strong><span>Output tokens</span></div><div><strong>{number(job.usage.cacheReadTokens + job.usage.cacheWriteTokens)}</strong><span>Cache tokens</span></div></div>\n {job.error && <div className=\"br-notice\" role=\"alert\">{job.error}</div>}\n {job.pausedExecutionIds.length > 0 && <div className=\"br-notice\"><strong>{job.pausedExecutionIds.length} execution(s) paused</strong><p className=\"br-note\">Inspect the output, then resume outgoing scheduling. Job deadlines continue while paused.</p><button className=\"br-primary\" disabled={!connected || busy || job.status !== \"running\"} onClick={() => act(\"resume\", job.pausedExecutionIds)}>Resume all paused</button></div>}\n <Graph job={job} selected={selected} select={id => { setSelected(id); setChosenExecution(\"\"); setTab(\"output\"); }}/>\n <section className=\"br-section\" aria-label=\"Execution details\"><div className=\"br-section-head\"><h3>{selected || \"Execution details\"}</h3>{execution && <Status status={paused ? \"waiting\" : execution.status}/>}</div>\n {chosenExecution && !execution && <p role=\"status\">The requested execution ({chosenExecution}) is no longer available. Select a node to inspect its current history.</p>}\n {executions.length > 0 ? <label><span className=\"br-muted\">Execution history</span><select className=\"br-select\" aria-label=\"Execution history\" value={execution?.executionId ?? \"\"} onChange={e => setChosenExecution(e.target.value)}>{executions.map(e => <option key={e.executionId} value={e.executionId}>{e.executionId} \u00B7 {e.status}{e.iteration === undefined ? \"\" : ` \u00B7 iteration ${e.iteration}`}</option>)}</select></label> : <p className=\"br-muted\">This node has not run yet.</p>}\n {paused && <button className=\"br-primary\" disabled={!connected || busy || job.status !== \"running\"} onClick={() => act(\"resume\", [execution!.executionId])}>Resume this execution</button>}\n <div className=\"br-tabs\"><button aria-pressed={tab === \"output\"} onClick={() => setTab(\"output\")}>Output & details</button><button aria-pressed={tab === \"events\"} onClick={() => setTab(\"events\")}>Event log ({job.events.length})</button></div>\n {tab === \"output\" && execution && <ExecutionDetail key={execution.executionId} api={api} sessionId={sessionId} job={job} execution={execution}/>}\n {tab === \"events\" && <><p className=\"br-note\">Latest 80 lifecycle events. Full results remain available through braid_status.</p><ol className=\"br-events\">{[...job.events].reverse().map(event => <li key={event.sequence}><time>{new Date(event.timestamp).toLocaleTimeString([], { hour12: false })}</time><div><p>{event.message}</p><small>#{event.sequence}{event.nodeId ? ` \u00B7 ${event.nodeId}` : \"\"}{event.executionId ? ` \u00B7 ${event.executionId}` : \"\"}</small></div></li>)}</ol></>}\n <p className=\"br-note\">Cache read {number(job.usage.cacheReadTokens)} \u00B7 cache write {number(job.usage.cacheWriteTokens)}. Usage is reported by DSH; monetary cost is not estimated.</p>\n </section>\n </>;\n}\n\n/** The session key deliberately resets every local selection and request generation. */\nexport function BraidPanelView(props: { sessionId: string; api: PanelApi; target?: BraidNavigation }) {\n return <SessionPanel key={props.sessionId} {...props}/>;\n}\nfunction SessionPanel({ sessionId, api, target }: { sessionId: string; api: PanelApi; target?: BraidNavigation }) {\n const [jobId, setJobId] = useState<string | undefined>(target?.jobId);\n const [createdBefore, setCreatedBefore] = useState<number | undefined>(target?.createdBefore);\n const [frame, setFrame] = useState<PanelFrame>();\n const [connected, setConnected] = useState(false);\n const [error, setError] = useState(\"\");\n const [actionError, setActionError] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [retry, setRetry] = useState(0);\n useEffect(() => {\n const controller = new AbortController();\n setConnected(false); setFrame(undefined); setError(\"\"); setActionError(\"\");\n void (async () => {\n for (let attempt = 0; !controller.signal.aborted; attempt++) {\n try {\n for await (const value of api.watch({ sessionId, ...(jobId ? { jobId } : {}), ...(createdBefore === undefined ? {} : { createdBefore }) }, controller.signal)) {\n if (controller.signal.aborted) return;\n setFrame(value); setConnected(true); setError(\"\"); attempt = 0;\n }\n if (!controller.signal.aborted) throw new Error(\"Braid connection closed\");\n } catch (e) {\n if (controller.signal.aborted) return;\n setConnected(false); setError(`${message(e)}${attempt < 2 ? \" \u00B7 reconnecting\u2026\" : \"\"}`);\n if (attempt >= 2) return;\n await new Promise<void>(resolve => {\n const done = () => { clearTimeout(timer); controller.signal.removeEventListener(\"abort\", done); resolve(); };\n const timer = setTimeout(done, 1000 * 2 ** attempt);\n controller.signal.addEventListener(\"abort\", done, { once: true });\n });\n }\n }\n })();\n return () => { controller.abort(); };\n }, [api, sessionId, jobId, createdBefore, retry]);\n const job = frame?.job;\n // In-flight mutations only affect their mounted job view; stream frames remain authoritative.\n const [actionOwner, setActionOwner] = useState(\"\");\n const act = async (action: \"cancel\" | \"resume\", executionIds: string[]) => {\n if (!job || !connected || busy) return;\n const owner = job.jobId;\n setBusy(true); setActionOwner(owner); setActionError(\"\");\n try { await api.control({ sessionId, jobId: owner, action, executionIds, revision: job.revision }); }\n catch (e) { setActionError(message(e)); }\n finally { setBusy(false); }\n };\n return <div className=\"braid-panel\">\n <header className=\"br-header\"><div className=\"br-eyebrow\">Agent orchestration</div><div className=\"br-heading\"><h2>Braid</h2><small role=\"status\">{connected ? \"\u25CF Live\" : error ? \"\u25CB Disconnected\" : \"Connecting\u2026\"}</small></div>\n {frame && frame.rows.length > 0 && <><select className=\"br-select\" aria-label=\"Braid job\" disabled={busy} value={job?.jobId ?? \"\"} onChange={e => { setJobId(e.target.value); setCreatedBefore(undefined); setActionError(\"\"); }}>{frame.rows.map(row => <option key={row.jobId} value={row.jobId}>{row.handle} \u00B7 {row.status} \u00B7 {row.goal.slice(0, 70)}</option>)}</select>\n {job && <><p className=\"br-goal\">{job.goal}</p><div className=\"br-toolbar\"><Status status={job.phase === \"waiting\" ? \"waiting\" : job.status}/><small className=\"br-muted\">r{job.revision} \u00B7 {job.nodes.length} nodes</small><button className=\"br-danger\" style={{ marginLeft: \"auto\" }} disabled={!connected || busy || job.status !== \"running\"} onClick={() => void act(\"cancel\", [])}>{busy ? \"Working\u2026\" : \"Cancel job\"}</button></div></>}\n </>}\n </header>\n {error && <div className=\"br-notice\" role=\"alert\">{error}<div className=\"br-toolbar\"><button onClick={() => setRetry(v => v + 1)}>Reconnect</button><button onClick={() => { setJobId(undefined); setCreatedBefore(undefined); setRetry(v => v + 1); }}>Latest job</button></div></div>}\n {actionError && actionOwner === job?.jobId && <div className=\"br-notice\" role=\"alert\">{actionError}</div>}\n {connected && frame?.rows.length === 0 && <div className=\"br-empty\"><h3>No Braid jobs in this session</h3><p>Ask the agent to use Braid for a parallel or multi-step task. Its graph, execution history and results will appear here.</p></div>}\n {job && <JobView key={job.jobId} job={job} api={api} sessionId={sessionId} connected={connected} act={(action, ids) => void act(action, ids)} busy={busy}\n target={target?.jobId && [job.jobId, job.handle].includes(target.jobId) ? target : undefined}/>}\n </div>;\n}\n", "import type { PanelJob } from \"../panel-types.js\";\n\n/** Longest-path ranks in the forward DAG. Feedback is drawn separately. */\nexport function layoutGraph(nodes: PanelJob[\"nodes\"], edges: PanelJob[\"edges\"]) {\n const rank = new Map(nodes.map(node => [node.id, 0]));\n const incoming = new Map(nodes.map(node => [node.id, 0]));\n const outgoing = new Map(nodes.map(node => [node.id, [] as string[]]));\n for (const edge of edges) {\n if (edge.feedback || !rank.has(edge.from) || !rank.has(edge.to)) continue;\n incoming.set(edge.to, incoming.get(edge.to)! + 1);\n outgoing.get(edge.from)!.push(edge.to);\n }\n const queue = nodes.filter(node => incoming.get(node.id) === 0).map(node => node.id);\n for (let i = 0; i < queue.length; i++) for (const to of outgoing.get(queue[i]!)!) {\n rank.set(to, Math.max(rank.get(to)!, rank.get(queue[i]!)! + 1));\n incoming.set(to, incoming.get(to)! - 1);\n if (incoming.get(to) === 0) queue.push(to);\n }\n const columns = new Map<number, number>();\n const positions = new Map(nodes.map(node => {\n const row = rank.get(node.id)!, column = columns.get(row) ?? 0;\n columns.set(row, column + 1);\n return [node.id, { x: 32 + column * 186, y: 28 + row * 124 }];\n }));\n return { positions, width: Math.max(280, ...[...columns.values()].map(count => count * 186 + 32)),\n height: Math.max(160, ...[...rank.values()].map(row => (row + 1) * 124 + 28)) };\n}\n", "/** Scoped styles share the Host's fonts and honor both system and DSH dark themes. */\nexport const styles = `\n.braid-panel{--br-bg:var(--dsw-alias-bg-base,#fff);--br-fg:var(--dsw-alias-label-primary,#222b38);--br-soft:var(--dsw-alias-bg-module-platform,#f4f6f8);--br-line:var(--dsw-alias-border-l2,#dce2e8);--br-muted:var(--dsw-alias-label-secondary,#667384);--br-accent:#336dbe;--br-green:var(--dsw-alias-state-success-primary,#18794e);--br-red:var(--dsw-alias-state-error-primary,#ba3340);color:var(--br-fg);background:var(--br-bg);font:inherit;font-size:13px;line-height:1.5;box-sizing:border-box;height:100%;overflow:auto;min-width:0;container-type:inline-size}\n.braid-panel *{box-sizing:border-box}.braid-panel button,.braid-panel select{font:inherit;color:inherit}.braid-panel button,.braid-panel select{border:1px solid var(--br-line);border-radius:7px;background:var(--br-bg);padding:6px 10px}.braid-panel button{cursor:pointer}.braid-panel button:hover:not(:disabled){border-color:var(--br-accent)}.braid-panel button:focus-visible,.braid-panel select:focus-visible{outline:2px solid var(--br-accent);outline-offset:2px}.braid-panel button:disabled{opacity:.45;cursor:default}.braid-panel .br-primary{background:var(--br-accent);color:white;border-color:transparent}.braid-panel .br-danger{color:var(--br-red)}\n.br-header{padding:20px 18px 12px;border-bottom:1px solid var(--br-line)}.br-heading{display:flex;align-items:center;gap:9px}.br-heading h2{font-size:18px;letter-spacing:-.4px;margin:0}.br-heading small{margin-left:auto;color:var(--br-muted)}.br-eyebrow{text-transform:uppercase;letter-spacing:1.4px;font-size:10px;color:var(--br-muted);margin-bottom:5px}.br-select{width:100%;margin:14px 0 8px}.br-goal{margin:8px 0;overflow-wrap:anywhere}.br-muted{color:var(--br-muted)}.br-toolbar{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.br-status{display:inline-flex;align-items:center;gap:5px;font-size:11px;white-space:nowrap}.br-status:before{content:'';width:6px;height:6px;border-radius:50%;background:var(--br-muted)}.br-status[data-status=running]:before,.br-status[data-status=runnable]:before{background:var(--br-accent)}.br-status[data-status=completed]:before{background:var(--br-green)}.br-status[data-status=failed]:before,.br-status[data-status=cancelled]:before{background:var(--br-red)}.br-status[data-status=waiting]:before{background:#ba861a}\n.br-stats{display:grid;grid-template-columns:repeat(4,1fr);padding:14px 18px;gap:8px;border-bottom:1px solid var(--br-line)}.br-stats strong{display:block;font-size:16px;font-variant-numeric:tabular-nums}.br-stats span{font-size:10px;color:var(--br-muted)}.br-section{padding:14px 18px;border-bottom:1px solid var(--br-line)}.br-section h3{font-size:12px;margin:0 0 10px}.br-section-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:10px}.br-section-head h3{margin:0}.br-section-head button{padding:2px 8px}.br-graph{overflow:auto;background:var(--br-soft);border:1px solid var(--br-line);border-radius:9px;max-height:420px}.br-graph-canvas{position:relative}.br-graph svg{position:absolute;inset:0;overflow:visible}.br-graph path{fill:none;stroke:var(--br-muted);stroke-width:1.2}.br-graph text{font-size:10px;fill:var(--br-muted)}.br-node{position:absolute;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;width:154px;height:72px;text-align:left;gap:2px;box-shadow:0 2px 5px #00000006}.br-node[aria-pressed=true]{outline:2px solid var(--br-accent);outline-offset:2px}.br-node strong{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.br-node small{font-size:10px;color:var(--br-muted)}.br-legend{display:flex;gap:12px;flex-wrap:wrap;font-size:10px;color:var(--br-muted);margin-top:8px}.br-note{font-size:11px;color:var(--br-muted);margin:8px 0 0;overflow-wrap:anywhere}\n.br-notice{margin:12px 18px;padding:10px 12px;border:1px solid var(--br-line);border-radius:8px;background:var(--br-soft);overflow-wrap:anywhere}.br-notice[role=alert]{color:var(--br-red)}.br-empty{padding:48px 24px;text-align:center}.br-empty h3{font-size:15px}.br-empty p{color:var(--br-muted);max-width:36em;margin:12px auto}.br-detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px 16px;font-size:11px;margin:12px 0}.br-detail-grid span{color:var(--br-muted);display:block}.br-output{white-space:pre-wrap;overflow-wrap:anywhere;background:var(--br-soft);border:1px solid var(--br-line);padding:12px;border-radius:8px;max-height:340px;overflow:auto;font:11px/1.65 ui-monospace,SFMono-Regular,monospace;margin:8px 0}.br-tabs{display:flex;gap:5px;margin:14px 0 10px}.br-tabs button[aria-pressed=true]{border-color:var(--br-accent);color:var(--br-accent)}.br-events{list-style:none;padding:0;margin:0;max-height:320px;overflow:auto}.br-events li{padding:8px 0;display:grid;grid-template-columns:64px 1fr;gap:8px;border-bottom:1px solid var(--br-line);font-size:11px}.br-events time{color:var(--br-muted);font-variant-numeric:tabular-nums}.br-events p{margin:0;overflow-wrap:anywhere}.br-events small{color:var(--br-muted)}.br-header-action{font:inherit;border:0;border-radius:6px;padding:5px 9px;background:transparent;color:inherit;cursor:pointer}.br-header-action:hover{background:#8882}\n@container (max-width:330px){.br-stats{grid-template-columns:repeat(2,1fr)}.br-header,.br-section{padding-left:12px;padding-right:12px}}\n@media(prefers-color-scheme:dark){.braid-panel{--br-bg:var(--dsw-alias-bg-base,#171b22);--br-fg:var(--dsw-alias-label-primary,#e0e6ee);--br-soft:var(--dsw-alias-bg-module-platform,#202630);--br-line:var(--dsw-alias-border-l2,#354050);--br-muted:var(--dsw-alias-label-secondary,#a0adbe);--br-accent:#80b6ff;--br-green:var(--dsw-alias-state-success-primary,#69d6a0);--br-red:var(--dsw-alias-state-error-primary,#ff919a)}.braid-panel .br-primary{color:#162336}}\n[data-theme=dark] .braid-panel,.dark .braid-panel{--br-bg:var(--dsw-alias-bg-base,#171b22);--br-fg:var(--dsw-alias-label-primary,#e0e6ee);--br-soft:var(--dsw-alias-bg-module-platform,#202630);--br-line:var(--dsw-alias-border-l2,#354050);--br-muted:var(--dsw-alias-label-secondary,#a0adbe);--br-accent:#80b6ff;--br-green:var(--dsw-alias-state-success-primary,#69d6a0);--br-red:var(--dsw-alias-state-error-primary,#ff919a)}\n`;\n\nexport const toolStyles = `\n.br-tool-call{font:inherit;font-size:12px;color:var(--dsw-alias-label-primary,inherit);border:1px solid var(--dsw-alias-border-l2,#8884);border-radius:9px;margin:8px 0;overflow:hidden}\n.br-tool-call button{font:inherit;color:inherit;cursor:pointer}.br-tool-call button:focus-visible{outline:2px solid #639be6;outline-offset:-2px}.br-tool-call button:disabled{cursor:default;opacity:.6}\n.br-tool-open{display:flex;width:100%;align-items:center;gap:10px;padding:12px;border:0;background:var(--dsw-alias-bg-module-platform,#8881);text-align:left}.br-tool-open:hover:not(:disabled){background:var(--dsw-alias-fill-l1,#8882)}.br-tool-open>span:last-child{margin-left:auto}\n.br-tool-main{display:flex;flex-wrap:wrap;align-items:baseline;gap:3px 8px;min-width:0}.br-tool-target{overflow-wrap:anywhere;color:var(--dsw-alias-label-secondary,inherit)}.br-tool-summary{flex-basis:100%;font-size:11px}.br-tool-call[data-state=failed] .br-tool-summary,.br-tool-error{color:var(--dsw-alias-state-error-primary,#c34e59)}\n.br-tool-actions{display:flex;gap:8px;padding:6px 12px}.br-tool-actions button{border:0;background:transparent;font-size:11px;text-decoration:underline;text-underline-offset:3px;padding:3px 0}.br-tool-details{padding:8px 12px;border-top:1px solid var(--dsw-alias-border-l2,#8884)}.br-tool-details pre{font:11px/1.6 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;max-height:220px;overflow:auto}.br-tool-error{padding:0 12px;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px}\n.br-tool-note{margin:4px 12px;color:var(--dsw-alias-label-secondary,inherit);font-size:10px;opacity:.8}.br-tool-changes{display:flex;flex-wrap:wrap;gap:5px;padding:8px 12px}.br-tool-changes span{padding:3px 6px;border-radius:4px;background:var(--dsw-alias-bg-module-platform,#8881);font-size:10px;overflow-wrap:anywhere}.br-tool-jobs{list-style:none;margin:0;padding:6px 12px;max-height:230px;overflow:auto}.br-tool-jobs button{display:flex;gap:12px;width:100%;padding:6px 0;border:0;background:transparent;text-align:left}.br-tool-jobs span{margin-left:auto}\n`;\n", "import type { ToolCallPhaseProps } from \"@deepseek-ai/dsh-client-ui-tool/client\";\n\nexport interface BraidNavigation { jobId?: string; nodeId?: string; executionId?: string; createdBefore?: number }\nexport const braidToolNames = [\"braid\", \"braid_status\", \"braid_update\", \"braid_resume\", \"braid_cancel\"] as const;\n\nfunction record(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : {};\n}\nfunction json(raw: string): Record<string, unknown> {\n try { return record(JSON.parse(raw)); } catch { return {}; }\n}\nconst id = (value: unknown): string | undefined => typeof value === \"string\" && value.trim() && value.length <= 1024 ? value : undefined;\n\n/** Sidebar navigation also survives layout restoration, so validate its loose JSON boundary. */\nexport function readNavigation(value: unknown): BraidNavigation {\n const source = record(value), target: BraidNavigation = {};\n for (const key of [\"jobId\", \"nodeId\", \"executionId\"] as const) {\n const text = id(source[key]); if (text !== undefined) target[key] = text;\n }\n if (typeof source.createdBefore === \"number\" && Number.isSafeInteger(source.createdBefore) && source.createdBefore >= 0)\n target.createdBefore = source.createdBefore;\n return target;\n}\n\nfunction toolData(props: ToolCallPhaseProps) {\n const args = json(props.phase === \"result\" ? props.block.call?.argsRaw ?? \"\" : props.phase === \"start\" ? props.block.argsRaw : \"\");\n let result: Record<string, unknown> = {};\n if (props.phase === \"result\" && !props.block.isError) for (const content of props.block.content) {\n if (content.type !== \"text\") continue;\n const value = json(content.text);\n if (Object.keys(value).length > 0) { result = value; break; }\n }\n return { args, result };\n}\n\n/** Read only envelope identifiers, never the result preview, prompts, or worker output. */\nexport function toolNavigation(toolName: string, props: ToolCallPhaseProps): BraidNavigation | null {\n if (!braidToolNames.some(name => name === toolName) || props.phase === \"preparing\") return null;\n const { args, result } = toolData(props);\n const jobId = id(result.canonicalJobId) ?? id(result.jobId) ?? id(args.jobId);\n // A submission has no target until its receipt arrives. A list call opens the roster.\n if (!jobId) return toolName === \"braid_status\" && !(\"jobId\" in args || \"nodeId\" in args || \"executionId\" in args) ? {} : null;\n const target: BraidNavigation = { jobId };\n const node = record(result.node);\n const executionId = id(args.executionId) ?? id(node.executionId)\n ?? (toolName === \"braid_resume\" && Array.isArray(args.executionIds) && args.executionIds.length === 1 ? id(args.executionIds[0]) : undefined);\n const nodeId = id(args.nodeId) ?? id(node.id);\n if (executionId) target.executionId = executionId;\n if (nodeId) target.nodeId = nodeId;\n const time = props.block.time;\n if (Number.isSafeInteger(time) && time >= 0) target.createdBefore = time;\n return target;\n}\n\nexport interface ToolPresentation {\n label: string;\n summary: string;\n changes: string[];\n jobs: { label: string; status: string; target: BraidNavigation }[];\n}\nconst array = (value: unknown): unknown[] => Array.isArray(value) ? value : [];\nconst revision = (value: unknown): string => typeof value === \"number\" && Number.isSafeInteger(value) ? `r${value}` : \"\";\nconst names = (values: unknown[]): string => {\n const ids = values.map(value => id(value) ?? id(record(value).id)).filter(Boolean);\n return ids.slice(0, 8).join(\", \") + (ids.length > 8 ? ` \u2026 (+${ids.length - 8})` : \"\");\n};\n\n/** Each tool card describes its recorded operation; the sidebar is explicitly live. */\nexport function toolPresentation(toolName: string, props: ToolCallPhaseProps): ToolPresentation {\n const { args, result } = toolData(props);\n const label = id(result.handle) ?? id(args.jobId) ?? id(result.jobId) ?? \"\";\n const model: ToolPresentation = { label, summary: \"\", changes: [], jobs: [] };\n const failed = props.phase === \"result\" && props.block.isError;\n const settled = props.phase === \"result\";\n if (toolName === \"braid_update\") {\n const revisions = [revision(args.expectedRevision), revision(result.revision)].filter(Boolean).join(\" \u2192 \");\n model.summary = `${failed ? \"Update rejected \u00B7 not applied\" : settled ? \"Graph updated\" : \"Updating graph\"}${revisions ? ` \u00B7 ${revisions}` : \"\"}`;\n for (const [key, title] of [[\"upsertNodes\", \"Upsert nodes\"], [\"removeNodeIds\", \"Remove nodes\"], [\"resume\", \"Resume executions\"]] as const) {\n const values = array(args[key]); if (values.length) model.changes.push(`${title}: ${names(values)}`);\n }\n for (const [key, title] of [[\"addEdges\", \"Add edges\"], [\"removeEdges\", \"Remove edges\"]] as const) {\n const values = array(args[key]); if (values.length) model.changes.push(`${title}: ${values.length}`);\n }\n if (\"loops\" in args) model.changes.push(`Replace loops: ${array(args.loops).length}`);\n if (\"promptTemplates\" in args) model.changes.push(`Prompt templates: ${Object.keys(record(args.promptTemplates)).length}`);\n } else if (toolName === \"braid_resume\") {\n model.summary = failed ? \"Resume rejected\" : `${settled ? \"Resumed\" : \"Resuming\"} ${array(args.executionIds).length} execution(s)`;\n const ids = names(array(args.executionIds)); if (ids) model.changes.push(ids);\n if (Array.isArray(result.pausedExecutionIds)) model.changes.push(`${result.pausedExecutionIds.length} still paused \u00B7 ${revision(result.revision)}`);\n } else if (toolName === \"braid_cancel\") {\n model.summary = failed ? \"Cancellation failed\" : !settled ? \"Requesting cancellation\" : result.cancelled === false ? \"Job already finished\" : \"Cancellation requested\";\n } else if (toolName === \"braid_status\" && Array.isArray(result.jobs)) {\n model.summary = `${result.jobs.length} job(s) at this call`;\n model.jobs = result.jobs.flatMap(value => {\n const row = record(value), jobId = id(row.jobId);\n return jobId ? [{ label: id(row.handle) ?? jobId, status: id(row.status) ?? \"\", target: { jobId, createdBefore: props.block.time } }] : [];\n });\n } else if (toolName === \"braid_status\") {\n const execution = record(result.execution), node = record(result.node);\n const executions = Object.values(record(execution.executions));\n const details = id(node.status)\n ? [`execution ${id(node.status)}`, id(execution.status) ? `graph ${id(execution.status)}` : undefined, revision(execution.revision)]\n : [id(execution.status) ?? id(result.status), revision(execution.revision)];\n if (executions.length) details.push(`${executions.filter(value => record(value).status === \"completed\").length}/${executions.length} executions complete`);\n if (Array.isArray(execution.pausedExecutionIds) && execution.pausedExecutionIds.length) details.push(`${execution.pausedExecutionIds.length} paused`);\n model.summary = failed ? \"Status query failed\" : details.filter(Boolean).join(\" \u00B7 \") || (settled ? \"Recorded status\" : \"Reading status\");\n } else {\n const graph = record(result.graph), nodes = array(graph.nodes).length || array(args.nodes).length;\n model.summary = failed ? \"Submission failed\" : `${settled ? \"Graph submitted\" : \"Starting graph\"}${nodes ? ` \u00B7 ${nodes} nodes` : \"\"}`;\n }\n if (result.truncated === true) model.changes.push(\"Large result saved to file; view fullOutputPath in tool details\");\n return model;\n}\n", "import * as React from \"react\";\nimport type { ToolCallOwnerProps } from \"@deepseek-ai/dsh-client-ui-tool/client\";\nimport { toolNavigation, toolPresentation, type BraidNavigation } from \"./navigation.js\";\n\nexport type BraidToolCallProps = ToolCallOwnerProps & { openBraid: (target: BraidNavigation) => void };\n\n/** The main row opens the graph; a separate disclosure preserves the raw tool evidence. */\nexport function BraidToolCall(props: BraidToolCallProps) {\n const { toolName, phase, block, openBraid, useDisclosure, inspect } = props;\n const { expanded, toggle } = useDisclosure();\n const target = toolNavigation(toolName, props);\n const model = toolPresentation(toolName, props);\n const failed = phase === \"result\" && block.isError;\n const state = failed ? \"failed\" : phase === \"result\" ? \"completed\" : phase === \"preparing\" ? \"preparing\" : \"running\";\n const raw = phase === \"result\" ? block.call?.argsRaw : phase === \"start\" ? block.argsRaw : undefined;\n const output = phase === \"result\" ? block.content.filter(c => c.type === \"text\").map(c => c.text).join(\"\\n\") : \"\";\n return <div className=\"br-tool-call\" data-state={state}>\n <button type=\"button\" className=\"br-tool-open\" disabled={!target} onClick={() => { if (target) openBraid(target); }}\n aria-label={`Open Braid view for ${toolName}`} title={target ? \"Open Braid graph and execution details\" : \"Waiting for a Braid job receipt\"}>\n <span aria-hidden=\"true\">\u2387</span><span className=\"br-tool-main\"><strong>{toolName}</strong>\n <span className=\"br-tool-target\">{model.label}{target?.executionId ? ` / ${target.executionId}` : target?.nodeId ? ` / ${target.nodeId}` : \"\"}</span>\n <span className=\"br-tool-summary\">{model.summary}</span></span><span aria-hidden=\"true\">\u2197</span>\n </button>\n {model.changes.length > 0 && <div className=\"br-tool-changes\" aria-label={failed ? \"Changes not applied\" : \"Operation details\"}>{model.changes.map((change, i) => <span key={i}>{change}</span>)}</div>}\n {model.jobs.length > 0 && <ul className=\"br-tool-jobs\">{model.jobs.map(job => <li key={job.target.jobId}><button type=\"button\" onClick={() => openBraid(job.target)} aria-label={`View ${job.label}`}>{job.label} <span>{job.status}</span> \u2197</button></li>)}</ul>}\n {phase === \"result\" && target && <p className=\"br-tool-note\">Recorded result \u00B7 open the graph for live state</p>}\n {failed && <p role=\"alert\" className=\"br-tool-error\">{block.error?.reason ?? block.error?.code ?? (output.slice(0, 600) || \"Braid tool call failed. Expand the result for details.\")}</p>}\n <div className=\"br-tool-actions\"><button type=\"button\" aria-expanded={expanded} onClick={toggle}>{expanded ? \"Hide\" : \"Show\"} tool details</button>\n {inspect && <button type=\"button\" onClick={inspect}>Inspect call</button>}\n </div>\n {expanded && <div className=\"br-tool-details\"><strong>Arguments</strong><pre>{raw ?? \"Arguments are being prepared\u2026\"}</pre>\n {phase === \"result\" && <><strong>Result</strong><pre>{output || \"No text result.\"}</pre></>}\n </div>}\n </div>;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIO,IAAM,gBAAgB;AAC7B,SAAS,aAAa,OAAgB,QAAyB;AAC7D,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,OAAM,IAAI,MAAM,6BAA6B;AAC9G,QAAM,IAAI;AACV,QAAMA,MAAK,CAAC,QAAgB,OAAO,EAAE,GAAG,MAAM,YAAa,EAAE,GAAG,EAAa,SAAS,KAAM,EAAE,GAAG,EAAa,UAAU;AACxH,MAAI,CAACA,IAAG,WAAW,KAAM,EAAE,UAAU,UAAa,CAACA,IAAG,OAAO,EAAI,OAAM,IAAI,MAAM,2BAA2B;AAC5G,MAAI,EAAE,kBAAkB,WAAc,CAAC,OAAO,cAAc,EAAE,aAAa,KAAK,OAAO,EAAE,aAAa,IAAI,GAAI,OAAM,IAAI,MAAM,wBAAwB;AACtJ,MAAI,WAAW,WAAW,CAACA,IAAG,OAAO,EAAG,OAAM,IAAI,MAAM,sBAAsB;AAC9E,MAAI,WAAW,cACb,CAAC,CAAC,UAAU,QAAQ,EAAE,SAAS,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,cAAc,EAAE,QAAQ,KAAK,OAAO,EAAE,QAAQ,IAAI,KAC9G,CAAC,MAAM,QAAQ,EAAE,YAAY,KAAK,EAAE,aAAa,SAAS,OAAS,EAAE,aAAa,KAAK,OAAK,OAAO,MAAM,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,GACzI,OAAM,IAAI,MAAM,+BAA+B;AAClD,MAAI,WAAW,aAAa,CAACA,IAAG,aAAa,KAAK,CAAC,OAAO,cAAc,EAAE,MAAM,KAAK,OAAO,EAAE,MAAM,IAAI,GAAI,OAAM,IAAI,MAAM,6BAA6B;AACzJ,SAAO;AACT;AACO,IAAM,mBAA2C,CAAC,SAAS,WAAW,QAAQ,EAAE,IAAI,aAAW;AAAA,EACpG,IAAI,GAAG,aAAa,eAAe,MAAM;AAAA,EAAI,SAAS;AAAA,EAAc,WAAW;AAAA,EAAc;AAAA,EAC7F,YAAY,EAAE,MAAM,SAAS;AAAA,EAC7B,YAAY,CAAC,EAAE,MAAM,WAAW,MAAM,WAAW,QAAQ,QAAQ,OAAO;AAAA,IACtE,MAAM;AAAA,IAAU,YAAY,GAAG,aAAa,IAAI,MAAM;AAAA,IAAW,QAAQ,OAAO,EAAE,OAAO,WAAS,aAAa,OAAO,MAAM,EAAE;AAAA,EAChI,EAAE,CAAC;AAAA,EACH,QAAQ,EAAE,MAAM,WAAW;AAAA,EAC3B,GAAI,WAAW,UAAU,EAAE,MAAM,UAAmB,cAAc,EAAE,WAAW,SAAkB,EAAE,IAAI,CAAC;AAC1G,EAAE;;;AC1BF,mBAA4D;;;ACErD,SAAS,YAAY,OAA0B,OAA0B;AAC9E,QAAM,OAAO,IAAI,IAAI,MAAM,IAAI,UAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AACpD,QAAM,WAAW,IAAI,IAAI,MAAM,IAAI,UAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;AACxD,QAAM,WAAW,IAAI,IAAI,MAAM,IAAI,UAAQ,CAAC,KAAK,IAAI,CAAC,CAAa,CAAC,CAAC;AACrE,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,YAAY,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,EAAE,EAAG;AACjE,aAAS,IAAI,KAAK,IAAI,SAAS,IAAI,KAAK,EAAE,IAAK,CAAC;AAChD,aAAS,IAAI,KAAK,IAAI,EAAG,KAAK,KAAK,EAAE;AAAA,EACvC;AACA,QAAM,QAAQ,MAAM,OAAO,UAAQ,SAAS,IAAI,KAAK,EAAE,MAAM,CAAC,EAAE,IAAI,UAAQ,KAAK,EAAE;AACnF,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,YAAW,MAAM,SAAS,IAAI,MAAM,CAAC,CAAE,GAAI;AAChF,SAAK,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE,GAAI,KAAK,IAAI,MAAM,CAAC,CAAE,IAAK,CAAC,CAAC;AAC9D,aAAS,IAAI,IAAI,SAAS,IAAI,EAAE,IAAK,CAAC;AACtC,QAAI,SAAS,IAAI,EAAE,MAAM,EAAG,OAAM,KAAK,EAAE;AAAA,EAC3C;AACA,QAAM,UAAU,oBAAI,IAAoB;AACxC,QAAM,YAAY,IAAI,IAAI,MAAM,IAAI,UAAQ;AAC1C,UAAM,MAAM,KAAK,IAAI,KAAK,EAAE,GAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAC7D,YAAQ,IAAI,KAAK,SAAS,CAAC;AAC3B,WAAO,CAAC,KAAK,IAAI,EAAE,GAAG,KAAK,SAAS,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC;AAAA,EAC9D,CAAC,CAAC;AACF,SAAO;AAAA,IAAE;AAAA,IAAW,OAAO,KAAK,IAAI,KAAK,GAAG,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,IAAI,WAAS,QAAQ,MAAM,EAAE,CAAC;AAAA,IAC9F,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE,IAAI,UAAQ,MAAM,KAAK,MAAM,EAAE,CAAC;AAAA,EAAE;AAClF;;;ADjBS;AAHT,IAAM,SAAS,CAAC,MAAc,EAAE,eAAe;AAC/C,IAAM,UAAU,CAAC,UAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAClF,SAAS,OAAO,EAAE,OAAO,GAAuB;AACrD,SAAO,4CAAC,UAAK,WAAU,aAAY,eAAa,QAAS,kBAAO;AAClE;AAEO,SAAS,MAAM,EAAE,KAAK,UAAU,OAAO,GAAsE;AAClH,QAAM,aAAS,sBAAQ,MAAM,YAAY,IAAI,OAAO,IAAI,KAAK,GAAG,CAAC,IAAI,OAAO,IAAI,KAAK,CAAC;AACtF,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,CAAC;AAClC,QAAM,YAAQ,oBAAM,EAAE,WAAW,KAAK,EAAE;AACxC,QAAM,qBAAiB,qBAA0B,IAAI;AACrD,8BAAU,MAAM;AAAE,mBAAe,SAAS,iBAAiB,EAAE,OAAO,WAAW,QAAQ,UAAU,CAAC;AAAA,EAAG,GAAG,CAAC,QAAQ,CAAC;AAClH,SAAO,6CAAC,aAAQ,WAAU,cAAa,cAAW,mBAChD;AAAA,iDAAC,SAAI,WAAU,mBAAkB;AAAA,kDAAC,QAAG,6BAAe;AAAA,MAAK,6CAAC,SAAI,WAAU,cACtE;AAAA,oDAAC,YAAO,cAAW,YAAW,UAAU,QAAQ,KAAI,SAAS,MAAM,QAAQ,OAAK,KAAK,IAAI,KAAI,IAAI,IAAG,CAAC,GAAG,oBAAC;AAAA,QACzG,6CAAC,YAAO,cAAW,cAAa,SAAS,MAAM,QAAQ,CAAC,GAAI;AAAA,eAAK,MAAM,OAAO,GAAG;AAAA,UAAE;AAAA,WAAC;AAAA,QACpF,4CAAC,YAAO,cAAW,WAAU,UAAU,QAAQ,KAAK,SAAS,MAAM,QAAQ,OAAK,KAAK,IAAI,KAAK,IAAI,IAAG,CAAC,GAAG,eAAC;AAAA,SAC5G;AAAA,OAAM;AAAA,IACN,4CAAC,SAAI,WAAU,YAAW,sDAAC,SAAI,OAAO,EAAE,OAAO,OAAO,QAAQ,MAAM,QAAQ,OAAO,SAAS,KAAK,GAC/F,uDAAC,SAAI,WAAU,mBAAkB,OAAO,EAAE,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,WAAW,SAAS,IAAI,KAAK,iBAAiB,WAAW,GAC7I;AAAA,mDAAC,SAAI,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,eAAY,QAAO;AAAA,oDAAC,UAAK,sDAAC,YAAO,IAAI,OAAO,SAAQ,aAAY,MAAK,KAAI,MAAK,KAAI,aAAY,KAAI,cAAa,KAAI,QAAO,sBAAqB,sDAAC,UAAK,GAAE,yBAAwB,OAAO,EAAE,MAAM,kBAAkB,GAAE,GAAE,GAAS;AAAA,QAC3Q,IAAI,MAAM,IAAI,CAAC,MAAM,MAAM;AAC1B,gBAAM,IAAI,OAAO,UAAU,IAAI,KAAK,IAAI,GAAG,IAAI,OAAO,UAAU,IAAI,KAAK,EAAE;AAC3E,cAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,gBAAM,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE;AAC5D,gBAAM,IAAI,KAAK,WAAW,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI,IAAI;AACzK,iBAAO,6CAAC,OAAU;AAAA,wDAAC,UAAK,GAAM,iBAAiB,KAAK,WAAW,QAAQ,QAAW,WAAW,QAAQ,KAAK,KAAK,uDAAC,WAAO;AAAA,mBAAK;AAAA,cAAK;AAAA,cAAI,KAAK;AAAA,cAAI,KAAK,SAAS,KAAK,KAAK,MAAM,MAAM;AAAA,cAAI,KAAK,WAAW,cAAW,KAAK,QAAQ,KAAK;AAAA,cAAI,KAAK,cAAc,SAAM,KAAK,WAAW,KAAK;AAAA,eAAG,GAAQ;AAAA,YAC7R,KAAK,UAAU,CAAC,KAAK,YAAY,4CAAC,UAAK,IAAI,IAAI,QAAQ,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAI,GAAI,eAAK,OAAO,MAAM,GAAG,EAAE,GAAE;AAAA,eADnG,CAC2G;AAAA,QAC5H,CAAC;AAAA,SACH;AAAA,MACC,IAAI,MAAM,IAAI,UAAQ;AAAE,cAAM,IAAI,OAAO,UAAU,IAAI,KAAK,EAAE;AAAI,eAAO,6CAAC,YAAqB,KAAK,aAAa,KAAK,KAAK,iBAAiB,QAAW,WAAU,WAAU,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,gBAAc,aAAa,KAAK,IAAI,SAAS,MAAM,OAAO,KAAK,EAAE,GAAG,OAAO,GAAG,KAAK,EAAE,SAAM,KAAK,IAAI,SAAM,KAAK,MAAM,IAC/T;AAAA,sDAAC,WAAO,eAAK,MAAK;AAAA,UAAQ,4CAAC,YAAQ,eAAK,IAAG;AAAA,UAAS,4CAAC,UAAO,QAAQ,KAAK,QAAO;AAAA,aADK,KAAK,EAE5F;AAAA,MAAW,CAAC;AAAA,OACd,GACF,GAAM;AAAA,IACN,6CAAC,SAAI,WAAU,aAAY;AAAA,kDAAC,UAAK,mCAAkB;AAAA,MAAO,4CAAC,UAAK,uCAAsB;AAAA,MAAO,4CAAC,UAAK,qCAAuB;AAAA,OAAO;AAAA,IAChI,IAAI,MAAM,IAAI,UAAQ,6CAAC,OAAE,WAAU,WAAwB;AAAA;AAAA,MAAM,KAAK;AAAA,MAAG;AAAA,MAAU,KAAK;AAAA,MAAM;AAAA,MAAY,KAAK;AAAA,MAAc;AAAA,SAA3E,KAAK,EAAiF,CAAI;AAAA,KAC/I;AACF;AAEA,SAAS,gBAAgB,EAAE,KAAK,WAAW,KAAK,UAAU,GAAmF;AAC3I,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAsB;AAClD,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,EAAE;AACrC,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,CAAC;AACtC,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,CAAC;AACpC,8BAAU,MAAM;AACd,QAAI,SAAS;AACb,cAAU,MAAS;AAAG,aAAS,EAAE;AACjC,SAAK,IAAI,OAAO,EAAE,WAAW,OAAO,IAAI,OAAO,aAAa,UAAU,aAAa,OAAO,CAAC,EAAE,KAAK,WAAS;AACzG,UAAI,OAAQ,WAAU,KAAK;AAAA,IAC7B,GAAG,OAAK;AAAE,UAAI,OAAQ,UAAS,QAAQ,CAAC,CAAC;AAAA,IAAG,CAAC;AAC7C,WAAO,MAAM;AAAE,eAAS;AAAA,IAAO;AAAA,EACjC,GAAG,CAAC,KAAK,WAAW,IAAI,OAAO,IAAI,QAAQ,UAAU,aAAa,UAAU,QAAQ,QAAQ,KAAK,CAAC;AAClG,QAAM,IAAI,UAAU;AACpB,SAAO,4EACL;AAAA,iDAAC,SAAI,WAAU,kBACb;AAAA,mDAAC,SAAI;AAAA,oDAAC,UAAK,uBAAS;AAAA,QAAQ,UAAU;AAAA,SAAY;AAAA,MAAM,6CAAC,SAAI;AAAA,oDAAC,UAAK,kCAAoB;AAAA,QAAO;AAAA,QAAE,UAAU;AAAA,QAAS;AAAA,QAAI,UAAU,aAAa;AAAA,SAAI;AAAA,MAClJ,6CAAC,SAAI;AAAA,oDAAC,UAAK,qBAAO;AAAA,QAAQ,UAAU,cAAc,SAAY,WAAM,IAAI,UAAU,YAAY,KAAM,QAAQ,CAAC,CAAC;AAAA,SAAI;AAAA,MAClH,6CAAC,SAAI;AAAA,oDAAC,UAAK,oBAAM;AAAA,QAAQ,GAAG,SAAS,UAAU;AAAA,SAAO;AAAA,MACtD,6CAAC,SAAI;AAAA,qDAAC,UAAK;AAAA;AAAA,UAAU,GAAG,iBAAiB;AAAA,UAAa;AAAA,WAAC;AAAA,QAAQ,IAAI,GAAG,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE,gBAAgB,MAAM,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,KAAK;AAAA,SAAI;AAAA,MAC/J,6CAAC,SAAI;AAAA,oDAAC,UAAK,iCAAmB;AAAA,QAAQ,IAAI,GAAG,EAAE,SAAS,MAAM,EAAE,UAAU,KAAK;AAAA,SAAI;AAAA,OACrF;AAAA,IACC,SAAS,6CAAC,SAAI,MAAK,SAAS;AAAA;AAAA,MAAM;AAAA,MAAC,4CAAC,YAAO,SAAS,MAAM,SAAS,OAAK,IAAI,CAAC,GAAG,0BAAY;AAAA,OAAS;AAAA,IACrG,CAAC,UAAU,CAAC,SAAS,4CAAC,OAAE,WAAU,YAAW,MAAK,UAAS,kCAAe;AAAA,IAC1E,UAAU,4EACR;AAAA,aAAO,SAAS,4CAAC,OAAE,MAAK,SAAS,iBAAO,OAAM;AAAA,MAC9C,OAAO,YAAY,6CAAC,OAAE;AAAA;AAAA,QAAU,4CAAC,YAAQ,iBAAO,UAAS;AAAA,SAAS;AAAA,MACnE,4CAAC,SAAI,WAAU,aAAY,cAAW,oBAAoB,iBAAO,WAAW,UAAU,WAAW,YAAY,qDAAqD,kCAAiC;AAAA,MAClM,OAAO,QAAQ,SAAS,6CAAC,SAAI,WAAU,cAAa;AAAA,oDAAC,YAAO,UAAU,WAAW,GAAG,SAAS,MAAM,UAAU,KAAK,IAAI,GAAG,SAAS,KAAK,CAAC,GAAG,6BAAe;AAAA,QAAS,6CAAC,WAAM,WAAU,YAAY;AAAA,iBAAO,OAAO,MAAM;AAAA,UAAE;AAAA,UAAE,OAAO,OAAO,IAAI;AAAA,UAAE;AAAA,UAAI,OAAO,OAAO,KAAK;AAAA,UAAE;AAAA,WAAW;AAAA,QAAQ,4CAAC,YAAO,UAAU,OAAO,QAAQ,OAAO,OAAO,SAAS,MAAM,UAAU,OAAO,IAAI,GAAG,yBAAW;AAAA,SAAS;AAAA,MAClY,OAAO,aAAa,6CAAC,aAAQ;AAAA,oDAAC,aAAQ,yCAA2B;AAAA,QAAU,4CAAC,SAAI,WAAU,aAAa,iBAAO,WAAU;AAAA,SAAM;AAAA,OACjI;AAAA,KACF;AACF;AAEA,SAAS,QAAQ,EAAE,KAAK,KAAK,WAAW,WAAW,KAAK,MAAM,OAAO,GAA2L;AAC9P,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,MAAM,IAAI,WAAW,KAAK,OAAK,EAAE,gBAAgB,QAAQ,WAAW,GAAG,MAC3G,QAAQ,WAAW,QAAQ,cAAc,KAAK,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG;AAC1E,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,uBAAS,QAAQ,eAAe,EAAE;AAChF,QAAM,CAAC,KAAK,MAAM,QAAI,uBAAS,QAAQ;AACvC,QAAM,aAAa,IAAI,WAAW,OAAO,OAAK,EAAE,OAAO,QAAQ;AAC/D,QAAM,YAAY,kBAAkB,WAAW,KAAK,OAAK,EAAE,gBAAgB,eAAe,IAAI,WAAW,GAAG,EAAE;AAC9G,QAAM,SAAS,aAAa,IAAI,mBAAmB,SAAS,UAAU,WAAW;AACjF,SAAO,4EACL;AAAA,iDAAC,SAAI,WAAU,YAAW;AAAA,mDAAC,SAAI;AAAA,qDAAC,YAAQ;AAAA,cAAI,WAAW,OAAO,OAAK,EAAE,WAAW,WAAW,EAAE;AAAA,UAAO;AAAA,UAAE,IAAI,WAAW;AAAA,WAAO;AAAA,QAAS,4CAAC,UAAK,iCAAmB;AAAA,SAAO;AAAA,MAAM,6CAAC,SAAI;AAAA,oDAAC,YAAQ,iBAAO,IAAI,MAAM,WAAW,GAAE;AAAA,QAAS,4CAAC,UAAK,0BAAY;AAAA,SAAO;AAAA,MAAM,6CAAC,SAAI;AAAA,oDAAC,YAAQ,iBAAO,IAAI,MAAM,YAAY,GAAE;AAAA,QAAS,4CAAC,UAAK,2BAAa;AAAA,SAAO;AAAA,MAAM,6CAAC,SAAI;AAAA,oDAAC,YAAQ,iBAAO,IAAI,MAAM,kBAAkB,IAAI,MAAM,gBAAgB,GAAE;AAAA,QAAS,4CAAC,UAAK,0BAAY;AAAA,SAAO;AAAA,OAAM;AAAA,IACzc,IAAI,SAAS,4CAAC,SAAI,WAAU,aAAY,MAAK,SAAS,cAAI,OAAM;AAAA,IAChE,IAAI,mBAAmB,SAAS,KAAK,6CAAC,SAAI,WAAU,aAAY;AAAA,mDAAC,YAAQ;AAAA,YAAI,mBAAmB;AAAA,QAAO;AAAA,SAAoB;AAAA,MAAS,4CAAC,OAAE,WAAU,WAAU,uGAAyF;AAAA,MAAI,4CAAC,YAAO,WAAU,cAAa,UAAU,CAAC,aAAa,QAAQ,IAAI,WAAW,WAAW,SAAS,MAAM,IAAI,UAAU,IAAI,kBAAkB,GAAG,+BAAiB;AAAA,OAAS;AAAA,IACla,4CAAC,SAAM,KAAU,UAAoB,QAAQ,CAAAC,QAAM;AAAE,kBAAYA,GAAE;AAAG,yBAAmB,EAAE;AAAG,aAAO,QAAQ;AAAA,IAAG,GAAE;AAAA,IAClH,6CAAC,aAAQ,WAAU,cAAa,cAAW,qBAAoB;AAAA,mDAAC,SAAI,WAAU,mBAAkB;AAAA,oDAAC,QAAI,sBAAY,qBAAoB;AAAA,QAAM,aAAa,4CAAC,UAAO,QAAQ,SAAS,YAAY,UAAU,QAAO;AAAA,SAAG;AAAA,MAC9M,mBAAmB,CAAC,aAAa,6CAAC,OAAE,MAAK,UAAS;AAAA;AAAA,QAA0B;AAAA,QAAgB;AAAA,SAAuE;AAAA,MACnK,WAAW,SAAS,IAAI,6CAAC,WAAM;AAAA,oDAAC,UAAK,WAAU,YAAW,+BAAiB;AAAA,QAAO,4CAAC,YAAO,WAAU,aAAY,cAAW,qBAAoB,OAAO,WAAW,eAAe,IAAI,UAAU,OAAK,mBAAmB,EAAE,OAAO,KAAK,GAAI,qBAAW,IAAI,OAAK,6CAAC,YAA2B,OAAO,EAAE,aAAc;AAAA,YAAE;AAAA,UAAY;AAAA,UAAI,EAAE;AAAA,UAAQ,EAAE,cAAc,SAAY,KAAK,mBAAgB,EAAE,SAAS;AAAA,aAA9H,EAAE,WAA+H,CAAS,GAAE;AAAA,SAAS,IAAW,4CAAC,OAAE,WAAU,YAAW,wCAA0B;AAAA,MAC3d,UAAU,4CAAC,YAAO,WAAU,cAAa,UAAU,CAAC,aAAa,QAAQ,IAAI,WAAW,WAAW,SAAS,MAAM,IAAI,UAAU,CAAC,UAAW,WAAW,CAAC,GAAG,mCAAqB;AAAA,MACjL,6CAAC,SAAI,WAAU,WAAU;AAAA,oDAAC,YAAO,gBAAc,QAAQ,UAAU,SAAS,MAAM,OAAO,QAAQ,GAAG,8BAAgB;AAAA,QAAS,6CAAC,YAAO,gBAAc,QAAQ,UAAU,SAAS,MAAM,OAAO,QAAQ,GAAG;AAAA;AAAA,UAAY,IAAI,OAAO;AAAA,UAAO;AAAA,WAAC;AAAA,SAAS;AAAA,MAC3O,QAAQ,YAAY,aAAa,4CAAC,mBAA4C,KAAU,WAAsB,KAAU,aAAjE,UAAU,WAA4E;AAAA,MAC7I,QAAQ,YAAY,4EAAE;AAAA,oDAAC,OAAE,WAAU,WAAU,6FAA+E;AAAA,QAAI,4CAAC,QAAG,WAAU,aAAa,WAAC,GAAG,IAAI,MAAM,EAAE,QAAQ,EAAE,IAAI,WAAS,6CAAC,QAAwB;AAAA,sDAAC,UAAM,cAAI,KAAK,MAAM,SAAS,EAAE,mBAAmB,CAAC,GAAG,EAAE,QAAQ,MAAM,CAAC,GAAE;AAAA,UAAO,6CAAC,SAAI;AAAA,wDAAC,OAAG,gBAAM,SAAQ;AAAA,YAAI,6CAAC,WAAM;AAAA;AAAA,cAAE,MAAM;AAAA,cAAU,MAAM,SAAS,SAAM,MAAM,MAAM,KAAK;AAAA,cAAI,MAAM,cAAc,SAAM,MAAM,WAAW,KAAK;AAAA,eAAG;AAAA,aAAQ;AAAA,aAA3P,MAAM,QAA2P,CAAK,GAAE;AAAA,SAAK;AAAA,MACzd,6CAAC,OAAE,WAAU,WAAU;AAAA;AAAA,QAAY,OAAO,IAAI,MAAM,eAAe;AAAA,QAAE;AAAA,QAAgB,OAAO,IAAI,MAAM,gBAAgB;AAAA,QAAE;AAAA,SAA2D;AAAA,OACrL;AAAA,KACF;AACF;AAGO,SAAS,eAAe,OAAuE;AACpG,SAAO,4CAAC,gBAAoC,GAAG,SAArB,MAAM,SAAqB;AACvD;AACA,SAAS,aAAa,EAAE,WAAW,KAAK,OAAO,GAAmE;AAChH,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAA6B,QAAQ,KAAK;AACpE,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAA6B,QAAQ,aAAa;AAC5F,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAqB;AAC/C,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,EAAE;AACrC,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,EAAE;AACjD,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,CAAC;AACpC,8BAAU,MAAM;AACd,UAAM,aAAa,IAAI,gBAAgB;AACvC,iBAAa,KAAK;AAAG,aAAS,MAAS;AAAG,aAAS,EAAE;AAAG,mBAAe,EAAE;AACzE,UAAM,YAAY;AAChB,eAAS,UAAU,GAAG,CAAC,WAAW,OAAO,SAAS,WAAW;AAC3D,YAAI;AACF,2BAAiB,SAAS,IAAI,MAAM,EAAE,WAAW,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,GAAI,GAAI,kBAAkB,SAAY,CAAC,IAAI,EAAE,cAAc,EAAG,GAAG,WAAW,MAAM,GAAG;AAC7J,gBAAI,WAAW,OAAO,QAAS;AAC/B,qBAAS,KAAK;AAAG,yBAAa,IAAI;AAAG,qBAAS,EAAE;AAAG,sBAAU;AAAA,UAC/D;AACA,cAAI,CAAC,WAAW,OAAO,QAAS,OAAM,IAAI,MAAM,yBAAyB;AAAA,QAC3E,SAAS,GAAG;AACV,cAAI,WAAW,OAAO,QAAS;AAC/B,uBAAa,KAAK;AAAG,mBAAS,GAAG,QAAQ,CAAC,CAAC,GAAG,UAAU,IAAI,6BAAqB,EAAE,EAAE;AACrF,cAAI,WAAW,EAAG;AAClB,gBAAM,IAAI,QAAc,aAAW;AACjC,kBAAM,OAAO,MAAM;AAAE,2BAAa,KAAK;AAAG,yBAAW,OAAO,oBAAoB,SAAS,IAAI;AAAG,sBAAQ;AAAA,YAAG;AAC3G,kBAAM,QAAQ,WAAW,MAAM,MAAO,KAAK,OAAO;AAClD,uBAAW,OAAO,iBAAiB,SAAS,MAAM,EAAE,MAAM,KAAK,CAAC;AAAA,UAClE,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,GAAG;AACH,WAAO,MAAM;AAAE,iBAAW,MAAM;AAAA,IAAG;AAAA,EACrC,GAAG,CAAC,KAAK,WAAW,OAAO,eAAe,KAAK,CAAC;AAChD,QAAM,MAAM,OAAO;AAEnB,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,EAAE;AACjD,QAAM,MAAM,OAAO,QAA6B,iBAA2B;AACzE,QAAI,CAAC,OAAO,CAAC,aAAa,KAAM;AAChC,UAAM,QAAQ,IAAI;AAClB,YAAQ,IAAI;AAAG,mBAAe,KAAK;AAAG,mBAAe,EAAE;AACvD,QAAI;AAAE,YAAM,IAAI,QAAQ,EAAE,WAAW,OAAO,OAAO,QAAQ,cAAc,UAAU,IAAI,SAAS,CAAC;AAAA,IAAG,SAC7F,GAAG;AAAE,qBAAe,QAAQ,CAAC,CAAC;AAAA,IAAG,UACxC;AAAU,cAAQ,KAAK;AAAA,IAAG;AAAA,EAC5B;AACA,SAAO,6CAAC,SAAI,WAAU,eACpB;AAAA,iDAAC,YAAO,WAAU,aAAY;AAAA,kDAAC,SAAI,WAAU,cAAa,iCAAmB;AAAA,MAAM,6CAAC,SAAI,WAAU,cAAa;AAAA,oDAAC,QAAG,mBAAK;AAAA,QAAK,4CAAC,WAAM,MAAK,UAAU,sBAAY,gBAAW,QAAQ,wBAAmB,oBAAc;AAAA,SAAQ;AAAA,MACxN,SAAS,MAAM,KAAK,SAAS,KAAK,4EAAE;AAAA,oDAAC,YAAO,WAAU,aAAY,cAAW,aAAY,UAAU,MAAM,OAAO,KAAK,SAAS,IAAI,UAAU,OAAK;AAAE,mBAAS,EAAE,OAAO,KAAK;AAAG,2BAAiB,MAAS;AAAG,yBAAe,EAAE;AAAA,QAAG,GAAI,gBAAM,KAAK,IAAI,SAAO,6CAAC,YAAuB,OAAO,IAAI,OAAQ;AAAA,cAAI;AAAA,UAAO;AAAA,UAAI,IAAI;AAAA,UAAO;AAAA,UAAI,IAAI,KAAK,MAAM,GAAG,EAAE;AAAA,aAAhF,IAAI,KAA8E,CAAS,GAAE;AAAA,QAChW,OAAO,4EAAE;AAAA,sDAAC,OAAE,WAAU,WAAW,cAAI,MAAK;AAAA,UAAI,6CAAC,SAAI,WAAU,cAAa;AAAA,wDAAC,UAAO,QAAQ,IAAI,UAAU,YAAY,YAAY,IAAI,QAAO;AAAA,YAAE,6CAAC,WAAM,WAAU,YAAW;AAAA;AAAA,cAAE,IAAI;AAAA,cAAS;AAAA,cAAI,IAAI,MAAM;AAAA,cAAO;AAAA,eAAM;AAAA,YAAQ,4CAAC,YAAO,WAAU,aAAY,OAAO,EAAE,YAAY,OAAO,GAAG,UAAU,CAAC,aAAa,QAAQ,IAAI,WAAW,WAAW,SAAS,MAAM,KAAK,IAAI,UAAU,CAAC,CAAC,GAAI,iBAAO,kBAAa,cAAa;AAAA,aAAS;AAAA,WAAM;AAAA,SAC7a;AAAA,OACF;AAAA,IACC,SAAS,6CAAC,SAAI,WAAU,aAAY,MAAK,SAAS;AAAA;AAAA,MAAM,6CAAC,SAAI,WAAU,cAAa;AAAA,oDAAC,YAAO,SAAS,MAAM,SAAS,OAAK,IAAI,CAAC,GAAG,uBAAS;AAAA,QAAS,4CAAC,YAAO,SAAS,MAAM;AAAE,mBAAS,MAAS;AAAG,2BAAiB,MAAS;AAAG,mBAAS,OAAK,IAAI,CAAC;AAAA,QAAG,GAAG,wBAAU;AAAA,SAAS;AAAA,OAAM;AAAA,IAChR,eAAe,gBAAgB,KAAK,SAAS,4CAAC,SAAI,WAAU,aAAY,MAAK,SAAS,uBAAY;AAAA,IAClG,aAAa,OAAO,KAAK,WAAW,KAAK,6CAAC,SAAI,WAAU,YAAW;AAAA,kDAAC,QAAG,2CAA6B;AAAA,MAAK,4CAAC,OAAE,sIAAwH;AAAA,OAAI;AAAA,IACxO,OAAO;AAAA,MAAC;AAAA;AAAA,QAAwB;AAAA,QAAU;AAAA,QAAU;AAAA,QAAsB;AAAA,QAAsB,KAAK,CAAC,QAAQ,QAAQ,KAAK,IAAI,QAAQ,GAAG;AAAA,QAAG;AAAA,QAC5I,QAAQ,QAAQ,SAAS,CAAC,IAAI,OAAO,IAAI,MAAM,EAAE,SAAS,OAAO,KAAK,IAAI,SAAS;AAAA;AAAA,MAD/D,IAAI;AAAA,IACqE;AAAA,KACjG;AACF;;;AErKO,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWf,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACTnB,IAAM,iBAAiB,CAAC,SAAS,gBAAgB,gBAAgB,gBAAgB,cAAc;AAEtG,SAAS,OAAO,OAAyC;AACvD,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAmC,CAAC;AACpH;AACA,SAAS,KAAK,KAAsC;AAClD,MAAI;AAAE,WAAO,OAAO,KAAK,MAAM,GAAG,CAAC;AAAA,EAAG,QAAQ;AAAE,WAAO,CAAC;AAAA,EAAG;AAC7D;AACA,IAAM,KAAK,CAAC,UAAuC,OAAO,UAAU,YAAY,MAAM,KAAK,KAAK,MAAM,UAAU,OAAO,QAAQ;AAGxH,SAAS,eAAe,OAAiC;AAC9D,QAAM,SAAS,OAAO,KAAK,GAAG,SAA0B,CAAC;AACzD,aAAW,OAAO,CAAC,SAAS,UAAU,aAAa,GAAY;AAC7D,UAAM,OAAO,GAAG,OAAO,GAAG,CAAC;AAAG,QAAI,SAAS,OAAW,QAAO,GAAG,IAAI;AAAA,EACtE;AACA,MAAI,OAAO,OAAO,kBAAkB,YAAY,OAAO,cAAc,OAAO,aAAa,KAAK,OAAO,iBAAiB;AACpH,WAAO,gBAAgB,OAAO;AAChC,SAAO;AACT;AAEA,SAAS,SAAS,OAA2B;AAC3C,QAAM,OAAO,KAAK,MAAM,UAAU,WAAW,MAAM,MAAM,MAAM,WAAW,KAAK,MAAM,UAAU,UAAU,MAAM,MAAM,UAAU,EAAE;AACjI,MAAI,SAAkC,CAAC;AACvC,MAAI,MAAM,UAAU,YAAY,CAAC,MAAM,MAAM,QAAS,YAAW,WAAW,MAAM,MAAM,SAAS;AAC/F,QAAI,QAAQ,SAAS,OAAQ;AAC7B,UAAM,QAAQ,KAAK,QAAQ,IAAI;AAC/B,QAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AAAE,eAAS;AAAO;AAAA,IAAO;AAAA,EAC9D;AACA,SAAO,EAAE,MAAM,OAAO;AACxB;AAGO,SAAS,eAAe,UAAkB,OAAmD;AAClG,MAAI,CAAC,eAAe,KAAK,UAAQ,SAAS,QAAQ,KAAK,MAAM,UAAU,YAAa,QAAO;AAC3F,QAAM,EAAE,MAAM,OAAO,IAAI,SAAS,KAAK;AACvC,QAAM,QAAQ,GAAG,OAAO,cAAc,KAAK,GAAG,OAAO,KAAK,KAAK,GAAG,KAAK,KAAK;AAE5E,MAAI,CAAC,MAAO,QAAO,aAAa,kBAAkB,EAAE,WAAW,QAAQ,YAAY,QAAQ,iBAAiB,QAAQ,CAAC,IAAI;AACzH,QAAM,SAA0B,EAAE,MAAM;AACxC,QAAM,OAAO,OAAO,OAAO,IAAI;AAC/B,QAAM,cAAc,GAAG,KAAK,WAAW,KAAK,GAAG,KAAK,WAAW,MACzD,aAAa,kBAAkB,MAAM,QAAQ,KAAK,YAAY,KAAK,KAAK,aAAa,WAAW,IAAI,GAAG,KAAK,aAAa,CAAC,CAAC,IAAI;AACrI,QAAM,SAAS,GAAG,KAAK,MAAM,KAAK,GAAG,KAAK,EAAE;AAC5C,MAAI,YAAa,QAAO,cAAc;AACtC,MAAI,OAAQ,QAAO,SAAS;AAC5B,QAAM,OAAO,MAAM,MAAM;AACzB,MAAI,OAAO,cAAc,IAAI,KAAK,QAAQ,EAAG,QAAO,gBAAgB;AACpE,SAAO;AACT;AAQA,IAAM,QAAQ,CAAC,UAA8B,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AAC7E,IAAM,WAAW,CAAC,UAA2B,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,IAAI,IAAI,KAAK,KAAK;AACtH,IAAM,QAAQ,CAAC,WAA8B;AAC3C,QAAM,MAAM,OAAO,IAAI,WAAS,GAAG,KAAK,KAAK,GAAG,OAAO,KAAK,EAAE,EAAE,CAAC,EAAE,OAAO,OAAO;AACjF,SAAO,IAAI,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,IAAI,SAAS,IAAI,aAAQ,IAAI,SAAS,CAAC,MAAM;AACpF;AAGO,SAAS,iBAAiB,UAAkB,OAA6C;AAC9F,QAAM,EAAE,MAAM,OAAO,IAAI,SAAS,KAAK;AACvC,QAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,GAAG,KAAK,KAAK,KAAK,GAAG,OAAO,KAAK,KAAK;AACzE,QAAM,QAA0B,EAAE,OAAO,SAAS,IAAI,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AAC5E,QAAM,SAAS,MAAM,UAAU,YAAY,MAAM,MAAM;AACvD,QAAM,UAAU,MAAM,UAAU;AAChC,MAAI,aAAa,gBAAgB;AAC/B,UAAM,YAAY,CAAC,SAAS,KAAK,gBAAgB,GAAG,SAAS,OAAO,QAAQ,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,UAAK;AACzG,UAAM,UAAU,GAAG,SAAS,qCAAkC,UAAU,kBAAkB,gBAAgB,GAAG,YAAY,SAAM,SAAS,KAAK,EAAE;AAC/I,eAAW,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,eAAe,cAAc,GAAG,CAAC,iBAAiB,cAAc,GAAG,CAAC,UAAU,mBAAmB,CAAC,GAAY;AACzI,YAAM,SAAS,MAAM,KAAK,GAAG,CAAC;AAAG,UAAI,OAAO,OAAQ,OAAM,QAAQ,KAAK,GAAG,KAAK,KAAK,MAAM,MAAM,CAAC,EAAE;AAAA,IACrG;AACA,eAAW,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,YAAY,WAAW,GAAG,CAAC,eAAe,cAAc,CAAC,GAAY;AAChG,YAAM,SAAS,MAAM,KAAK,GAAG,CAAC;AAAG,UAAI,OAAO,OAAQ,OAAM,QAAQ,KAAK,GAAG,KAAK,KAAK,OAAO,MAAM,EAAE;AAAA,IACrG;AACA,QAAI,WAAW,KAAM,OAAM,QAAQ,KAAK,kBAAkB,MAAM,KAAK,KAAK,EAAE,MAAM,EAAE;AACpF,QAAI,qBAAqB,KAAM,OAAM,QAAQ,KAAK,qBAAqB,OAAO,KAAK,OAAO,KAAK,eAAe,CAAC,EAAE,MAAM,EAAE;AAAA,EAC3H,WAAW,aAAa,gBAAgB;AACtC,UAAM,UAAU,SAAS,oBAAoB,GAAG,UAAU,YAAY,UAAU,IAAI,MAAM,KAAK,YAAY,EAAE,MAAM;AACnH,UAAM,MAAM,MAAM,MAAM,KAAK,YAAY,CAAC;AAAG,QAAI,IAAK,OAAM,QAAQ,KAAK,GAAG;AAC5E,QAAI,MAAM,QAAQ,OAAO,kBAAkB,EAAG,OAAM,QAAQ,KAAK,GAAG,OAAO,mBAAmB,MAAM,sBAAmB,SAAS,OAAO,QAAQ,CAAC,EAAE;AAAA,EACpJ,WAAW,aAAa,gBAAgB;AACtC,UAAM,UAAU,SAAS,wBAAwB,CAAC,UAAU,4BAA4B,OAAO,cAAc,QAAQ,yBAAyB;AAAA,EAChJ,WAAW,aAAa,kBAAkB,MAAM,QAAQ,OAAO,IAAI,GAAG;AACpE,UAAM,UAAU,GAAG,OAAO,KAAK,MAAM;AACrC,UAAM,OAAO,OAAO,KAAK,QAAQ,WAAS;AACxC,YAAM,MAAM,OAAO,KAAK,GAAG,QAAQ,GAAG,IAAI,KAAK;AAC/C,aAAO,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,MAAM,KAAK,OAAO,QAAQ,GAAG,IAAI,MAAM,KAAK,IAAI,QAAQ,EAAE,OAAO,eAAe,MAAM,MAAM,KAAK,EAAE,CAAC,IAAI,CAAC;AAAA,IAC3I,CAAC;AAAA,EACH,WAAW,aAAa,gBAAgB;AACtC,UAAM,YAAY,OAAO,OAAO,SAAS,GAAG,OAAO,OAAO,OAAO,IAAI;AACrE,UAAM,aAAa,OAAO,OAAO,OAAO,UAAU,UAAU,CAAC;AAC7D,UAAM,UAAU,GAAG,KAAK,MAAM,IAC1B,CAAC,aAAa,GAAG,KAAK,MAAM,CAAC,IAAI,GAAG,UAAU,MAAM,IAAI,SAAS,GAAG,UAAU,MAAM,CAAC,KAAK,QAAW,SAAS,UAAU,QAAQ,CAAC,IACjI,CAAC,GAAG,UAAU,MAAM,KAAK,GAAG,OAAO,MAAM,GAAG,SAAS,UAAU,QAAQ,CAAC;AAC5E,QAAI,WAAW,OAAQ,SAAQ,KAAK,GAAG,WAAW,OAAO,WAAS,OAAO,KAAK,EAAE,WAAW,WAAW,EAAE,MAAM,IAAI,WAAW,MAAM,sBAAsB;AACzJ,QAAI,MAAM,QAAQ,UAAU,kBAAkB,KAAK,UAAU,mBAAmB,OAAQ,SAAQ,KAAK,GAAG,UAAU,mBAAmB,MAAM,SAAS;AACpJ,UAAM,UAAU,SAAS,wBAAwB,QAAQ,OAAO,OAAO,EAAE,KAAK,QAAK,MAAM,UAAU,oBAAoB;AAAA,EACzH,OAAO;AACL,UAAM,QAAQ,OAAO,OAAO,KAAK,GAAG,QAAQ,MAAM,MAAM,KAAK,EAAE,UAAU,MAAM,KAAK,KAAK,EAAE;AAC3F,UAAM,UAAU,SAAS,sBAAsB,GAAG,UAAU,oBAAoB,gBAAgB,GAAG,QAAQ,SAAM,KAAK,WAAW,EAAE;AAAA,EACrI;AACA,MAAI,OAAO,cAAc,KAAM,OAAM,QAAQ,KAAK,iEAAiE;AACnH,SAAO;AACT;;;AC7FM,IAAAC,sBAAA;AAZC,SAAS,cAAc,OAA2B;AACvD,QAAM,EAAE,UAAU,OAAO,OAAO,WAAW,eAAe,QAAQ,IAAI;AACtE,QAAM,EAAE,UAAU,OAAO,IAAI,cAAc;AAC3C,QAAM,SAAS,eAAe,UAAU,KAAK;AAC7C,QAAM,QAAQ,iBAAiB,UAAU,KAAK;AAC9C,QAAM,SAAS,UAAU,YAAY,MAAM;AAC3C,QAAM,QAAQ,SAAS,WAAW,UAAU,WAAW,cAAc,UAAU,cAAc,cAAc;AAC3G,QAAM,MAAM,UAAU,WAAW,MAAM,MAAM,UAAU,UAAU,UAAU,MAAM,UAAU;AAC3F,QAAM,SAAS,UAAU,WAAW,MAAM,QAAQ,OAAO,OAAK,EAAE,SAAS,MAAM,EAAE,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,IAAI;AAC/G,SAAO,8CAAC,SAAI,WAAU,gBAAe,cAAY,OAC/C;AAAA;AAAA,MAAC;AAAA;AAAA,QAAO,MAAK;AAAA,QAAS,WAAU;AAAA,QAAe,UAAU,CAAC;AAAA,QAAQ,SAAS,MAAM;AAAE,cAAI,OAAQ,WAAU,MAAM;AAAA,QAAG;AAAA,QAChH,cAAY,uBAAuB,QAAQ;AAAA,QAAI,OAAO,SAAS,2CAA2C;AAAA,QAC1G;AAAA,uDAAC,UAAK,eAAY,QAAO,oBAAC;AAAA,UAAO,8CAAC,UAAK,WAAU,gBAAe;AAAA,yDAAC,YAAQ,oBAAS;AAAA,YAChF,8CAAC,UAAK,WAAU,kBAAkB;AAAA,oBAAM;AAAA,cAAO,QAAQ,cAAc,MAAM,OAAO,WAAW,KAAK,QAAQ,SAAS,MAAM,OAAO,MAAM,KAAK;AAAA,eAAG;AAAA,YAC9I,6CAAC,UAAK,WAAU,mBAAmB,gBAAM,SAAQ;AAAA,aAAO;AAAA,UAAO,6CAAC,UAAK,eAAY,QAAO,oBAAC;AAAA;AAAA;AAAA,IAC7F;AAAA,IACC,MAAM,QAAQ,SAAS,KAAK,6CAAC,SAAI,WAAU,mBAAkB,cAAY,SAAS,wBAAwB,qBAAsB,gBAAM,QAAQ,IAAI,CAAC,QAAQ,MAAM,6CAAC,UAAc,oBAAJ,CAAW,CAAO,GAAE;AAAA,IAChM,MAAM,KAAK,SAAS,KAAK,6CAAC,QAAG,WAAU,gBAAgB,gBAAM,KAAK,IAAI,SAAO,6CAAC,QAA0B,wDAAC,YAAO,MAAK,UAAS,SAAS,MAAM,UAAU,IAAI,MAAM,GAAG,cAAY,QAAQ,IAAI,KAAK,IAAK;AAAA,UAAI;AAAA,MAAM;AAAA,MAAC,6CAAC,UAAM,cAAI,QAAO;AAAA,MAAO;AAAA,OAAE,KAAtJ,IAAI,OAAO,KAAoJ,CAAK,GAAE;AAAA,IAC5P,UAAU,YAAY,UAAU,6CAAC,OAAE,WAAU,gBAAe,gEAA+C;AAAA,IAC3G,UAAU,6CAAC,OAAE,MAAK,SAAQ,WAAU,iBAAiB,gBAAM,OAAO,UAAU,MAAM,OAAO,SAAS,OAAO,MAAM,GAAG,GAAG,KAAK,2DAA0D;AAAA,IACrL,8CAAC,SAAI,WAAU,mBAAkB;AAAA,oDAAC,YAAO,MAAK,UAAS,iBAAe,UAAU,SAAS,QAAS;AAAA,mBAAW,SAAS;AAAA,QAAO;AAAA,SAAa;AAAA,MACvI,WAAW,6CAAC,YAAO,MAAK,UAAS,SAAS,SAAS,0BAAY;AAAA,OAClE;AAAA,IACC,YAAY,8CAAC,SAAI,WAAU,mBAAkB;AAAA,mDAAC,YAAO,uBAAS;AAAA,MAAS,6CAAC,SAAK,iBAAO,sCAAgC;AAAA,MAClH,UAAU,YAAY,8EAAE;AAAA,qDAAC,YAAO,oBAAM;AAAA,QAAS,6CAAC,SAAK,oBAAU,mBAAkB;AAAA,SAAM;AAAA,OAC1F;AAAA,KACF;AACF;;;ANmBS,IAAAC,sBAAA;AAjCF,IAAM,SAAS,CAAC,UAAU,SAAS,gBAAgB,kBAAkB;AAC5E,eAAsB,MAAM,KAA6B;AACvD,QAAM,IAAI,OAAO,OAAO,EAAE,SAAS,eAAe,aAAa,iBAAiB,CAAC;AACjF,MAAI,OAAO,CAAC,mBAAmB,GAAG,CAAAC,SAAO;AAEvC,UAAM,SAASA,KAAI,OAAO;AAC1B,UAAM,UAAUA,KAAI;AACpB,UAAM,MAAgB;AAAA,MACpB,OAAO,CAAC,SAAS,WAAW,OAAO,MAAM,SAAS,MAAM;AAAA,MACxD,SAAS,OAAM,YAAW;AAAE,cAAM,SAAS,MAAM,OAAO,QAAQ,OAAO;AAAG,YAAI,CAAC,OAAO,GAAI,OAAM,OAAO;AAAO,eAAO,OAAO;AAAA,MAAO;AAAA,MACnI,QAAQ,OAAM,YAAW;AAAE,cAAM,SAAS,MAAM,OAAO,OAAO,OAAO;AAAG,YAAI,CAAC,OAAO,GAAI,OAAM,OAAO;AAAO,eAAO,OAAO;AAAA,MAAO;AAAA,IACnI;AACA,IAAAA,KAAI,OAAO,MAAM;AACf,YAAM,QAAQ,SAAS,cAAc,OAAO;AAAG,YAAM,QAAQ,SAAS;AAAe,YAAM,cAAc,SAAS;AAClH,eAAS,KAAK,OAAO,KAAK;AAAG,aAAO,MAAM;AAAE,cAAM,OAAO;AAAA,MAAG;AAAA,IAC9D,CAAC;AACD,IAAAA,KAAI,OAAO,MAAMA,KAAI,iBAAiB,SAAS;AAAA,MAAE,IAAI;AAAA,MAAe,MAAM;AAAA,MAAS,OAAO,MAAM;AAAA,MAC9F,OAAO,CAAC,EAAE,IAAI,SAAS,OAAO,IAAI,OAAO,MAAM,SAAS,aAAa,MAAM,oDAAoD,CAAC;AAAA,IAClI,CAAC,CAAC;AACF,IAAAA,KAAI,OAAO,MAAMA,KAAI,MAAM,OAAO,0BAA0B,MAAMA,KAAI,MAAM,SAAS;AAAA,MACnF,MAAM;AAAA,MAA0B,KAAK;AAAA,MAAe,QAAQ,gBAAc,EAAE,KAAK,UAAU;AAAA,IAC7F,GAAG,SAAS,CAAC,CAAC;AACd,IAAAA,KAAI,OAAO,MAAMA,KAAI,MAAM,OAAO,uCAAuC,MAAMA,KAAI,MAAM,SAAS;AAAA,MAChG,MAAM;AAAA,MAAuC,IAAI;AAAA,MAAS,OAAO;AAAA,MACjE,QAAQ,OAAO,EAAE,MAAM,MAAM;AAAE,gBAAQ,QAAQ,OAAO;AAAA,MAAG,EAAE;AAAA,IAC7D,GAAG,YAAY,CAAC,CAAC;AACjB,eAAW,OAAO,eAAgB,CAAAA,KAAI,OAAO,MAAMA,KAAI,MAAM,OAAO,sBAAsB,MAAMA,KAAI,MAAM,SAAS;AAAA,MACjH,MAAM;AAAA,MAAsB;AAAA,MAC5B,QAAQ,gBAAc,EAAE,WAAW,CAAC,WAA4B;AAAE,gBAAQ,UAAU,WAAwB,SAAS,EAAE,QAAQ,OAAO,CAAC;AAAA,MAAG,EAAE;AAAA,IAC9I,GAAG,aAAa,CAAC,CAAC;AAAA,EACpB,CAAC;AACH;AACA,SAAS,aAAa,EAAE,KAAK,GAAyB;AACpD,SAAO,6CAAC,YAAO,WAAU,oBAAmB,SAAS,MAAM,OAAM,0CAAyC,cAAW,oBAAmB,0BAAO;AACjJ;AACA,SAAS,UAAU,EAAE,WAAW,KAAK,WAAW,GAAkF;AAChI,QAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,WAAW;AAC3C,SAAO,6CAAC,kBAAyC,WAAsB,KAAU,QAAQ,eAAe,WAAW,MAAM,KAA7F,WAAW,QAAoF;AAC7H;",
6
+ "names": ["id", "id", "import_jsx_runtime", "import_jsx_runtime", "ctx"]
7
+ }
@@ -0,0 +1,3 @@
1
+ import type { JobSnapshot } from "./jobs.js";
2
+ /** Plain text works in both DSH's native job panel and human command results. */
3
+ export declare function renderPanel(job: JobSnapshot): string;
@@ -0,0 +1,22 @@
1
+ /** Plain text works in both DSH's native job panel and human command results. */
2
+ export function renderPanel(job) {
3
+ const state = job.execution;
4
+ const lines = [`Braid ${job.handle} · ${job.status} · revision ${state.revision}`, job.goal,
5
+ `Paused: ${state.pausedExecutionIds.join(", ") || "none"}`, ""];
6
+ for (const node of state.graph.nodes.slice(0, 80)) {
7
+ const result = state.nodes[node.id];
8
+ const progress = result?.executionId ? job.progress[result.executionId] : undefined;
9
+ lines.push(`${result?.status === "running" ? "▶" : "·"} ${node.id} [${node.type}] ${result?.status ?? "pending"}` +
10
+ (progress ? ` · context ${progress.contextTokens}${progress.contextWindow ? `/${progress.contextWindow}` : ""} (${progress.contextSource}) · tools ${progress.toolCalls}` : "") +
11
+ (result?.startedAt ? ` · ${Math.max(0, (result.finishedAt ?? Date.now()) - result.startedAt)} ms` : ""));
12
+ for (const edge of state.graph.edges.filter(edge => edge.from === node.id))
13
+ lines.push(` └─${edge.choice ? ` ${edge.choice}` : ""}${edge.feedback ? ` ↻ ${edge.feedback}` : ""} → ${edge.to}`);
14
+ if (result?.error)
15
+ lines.push(` ${result.error.code}: ${result.error.message}`);
16
+ }
17
+ if (state.graph.nodes.length > 80)
18
+ lines.push("… additional nodes available through braid_status");
19
+ lines.push("", "Recent events:", ...job.events.slice(-12).map(event => `#${event.sequence} ${event.type}${"nodeId" in event ? ` · ${event.nodeId}` : ""}${event.executionId ? ` · ${event.executionId}` : ""}`));
20
+ lines.push("", `Usage: ${job.usage.totalTokens ?? 0} tokens (including cache)`, `Results: braid_status({"jobId":"${job.handle}"})`, `/braid cancel ${job.handle}`);
21
+ return lines.join("\n");
22
+ }
@@ -0,0 +1,19 @@
1
+ import type { Context } from "@deepseek-ai/cordis";
2
+ declare module "@deepseek-ai/dsh-llm" {
3
+ interface MessageSourceMap {
4
+ braid: {
5
+ kind: "braid";
6
+ reminderId: string;
7
+ form: "notice";
8
+ summary: string;
9
+ };
10
+ }
11
+ }
12
+ declare module "@deepseek-ai/dsh-jobs" {
13
+ interface JobKindMap {
14
+ braid: "braid";
15
+ }
16
+ }
17
+ export declare const name = "braid";
18
+ export declare const inject: string[];
19
+ export declare function apply(ctx: Context): void;
package/dist/index.js ADDED
@@ -0,0 +1,162 @@
1
+ import { createUserMessage } from "@deepseek-ai/dsh-llm";
2
+ import { BraidJobs } from "./jobs.js";
3
+ import { createBraidTools, graphReceipt } from "./tools.js";
4
+ import { BRAID_USAGE_GUIDANCE } from "./schema.js";
5
+ import { renderPanel } from "./display.js";
6
+ import { BraidPanel } from "./panel.js";
7
+ export const name = "braid";
8
+ export const inject = ["tools", "llm", "commands", "systemPrompt", "jobs"];
9
+ export function apply(ctx) {
10
+ const observers = new Set();
11
+ const changed = () => { for (const listener of observers)
12
+ listener(); };
13
+ const sessions = new Map();
14
+ ctx.inject(["typert"], ctx => {
15
+ new BraidPanel(ctx, id => [...sessions].find(([agent]) => agent.session.id === id)?.[1].jobs, listener => { observers.add(listener); return () => { observers.delete(listener); }; });
16
+ });
17
+ const send = (agent, message) => {
18
+ if (message.source.kind !== "braid")
19
+ return;
20
+ const state = sessions.get(agent);
21
+ if (!state || state.queued.has(message.source.reminderId))
22
+ return;
23
+ state.queued.add(message.source.reminderId);
24
+ try {
25
+ agent.steer(message);
26
+ }
27
+ catch {
28
+ state.queued.delete(message.source.reminderId);
29
+ }
30
+ };
31
+ const session = (agent) => {
32
+ const existing = sessions.get(agent);
33
+ if (existing)
34
+ return existing;
35
+ const pending = new Map();
36
+ const jobs = new BraidJobs(ctx.llm, completion => {
37
+ const { jobId, handle, status, executionId, nodeId, paused, sequence } = completion;
38
+ const reminderId = JSON.stringify([jobId, executionId ?? "job", sequence ?? 0]);
39
+ const lookup = JSON.stringify({ jobId: handle, ...(executionId ? { executionId } : {}) });
40
+ const summary = `Braid ${handle}${nodeId ? ` / ${nodeId}` : ""}: ${paused ? "paused" : status}`.slice(0, 120);
41
+ const message = createUserMessage({
42
+ source: { kind: "braid", reminderId, form: "notice", summary },
43
+ content: [{ type: "text", text: `[system-reminder] ${summary}. Retrieve results with braid_status(${lookup}) and continue the original task. Failed or cancelled jobs may contain successful partial results. ${paused ? "Outgoing scheduling was paused. Inspect CURRENT execution.revision and pausedExecutionIds before braid_update with resume or braid_resume. Deadlines continue; finalized jobs cannot resume." : "This reminder does not pause scheduling."} [/system-reminder]` }],
44
+ });
45
+ pending.set(reminderId, message);
46
+ send(agent, message);
47
+ });
48
+ const value = { jobs, pending, queued: new Set(), release: () => jobs.dispose() };
49
+ sessions.set(agent, value);
50
+ const off = jobs.subscribe(changed);
51
+ changed();
52
+ // Agent-scoped effects unwind on clear, reload, disposal, or session replacement.
53
+ value.release = agent.ctx.effect(() => () => {
54
+ off();
55
+ pending.clear();
56
+ sessions.delete(agent);
57
+ changed();
58
+ return jobs.dispose();
59
+ });
60
+ return value;
61
+ };
62
+ const requireAgent = (agent) => {
63
+ if (!agent)
64
+ throw new Error("Braid requires an owning DSH agent");
65
+ return agent;
66
+ };
67
+ ctx.jobs.attachController("braid");
68
+ for (const tool of createBraidTools(exec => session(requireAgent(exec.agent)).jobs, (args, exec) => {
69
+ const jobs = session(requireAgent(exec.agent)).jobs;
70
+ const agent = requireAgent(exec.agent);
71
+ const { options, ...input } = args;
72
+ let snapshot;
73
+ const nativeJobId = ctx.jobs.start({
74
+ kind: "braid", label: args.goal.slice(0, 200), owner: agent.session.id,
75
+ run(native) {
76
+ const { provider, model } = agent.options;
77
+ snapshot = jobs.start(input, (options ?? {}), {
78
+ cwd: agent.session.header.cwd ?? process.cwd(),
79
+ ...(provider && model ? { model: `${provider}/${model}` } : {}),
80
+ });
81
+ const handle = snapshot.handle;
82
+ native.append(renderPanel(snapshot) + "\n", { channel: "log" });
83
+ let previous = "", timer;
84
+ const refresh = () => {
85
+ timer = undefined;
86
+ const job = jobs.get(handle);
87
+ const panel = renderPanel(job);
88
+ if (panel !== previous) {
89
+ previous = panel;
90
+ native.append("\n" + panel + "\n", { channel: "log" });
91
+ }
92
+ native.updateProgress(`${handle} · ${job.execution.status} · ${Object.keys(job.execution.executions).length} executions`);
93
+ };
94
+ const unsubscribe = jobs.subscribe(() => { timer ??= setTimeout(refresh, 250); });
95
+ return {
96
+ cancel: () => { jobs.cancel(handle); },
97
+ done: jobs.wait(handle).then(() => {
98
+ clearTimeout(timer);
99
+ unsubscribe();
100
+ refresh();
101
+ const job = jobs.get(handle);
102
+ return { status: job.status === "cancelled" ? "killed" : job.status === "completed" ? "completed" : "failed",
103
+ detail: `Braid ${handle}; retrieve with braid_status`, result: JSON.stringify({ jobId: handle, status: job.status }) };
104
+ }),
105
+ };
106
+ },
107
+ });
108
+ return { jobId: snapshot.handle, canonicalJobId: snapshot.jobId, nativeJobId, status: snapshot.status,
109
+ graph: graphReceipt(snapshot), message: "Running in background. Open Braid in the session header for the live graph and execution details, or use the Jobs panel / /braid. Completion reminders wake an idle agent or steer at the next step. Do not poll repeatedly." };
110
+ }))
111
+ ctx.tools.register(tool);
112
+ ctx.systemPrompt.section({ name: "braid", order: 80, text: BRAID_USAGE_GUIDANCE, interpolate: false });
113
+ ctx.commands.register({ name: "braid", description: "Show Braid flow/progress or cancel a job; live progress also appears in the Jobs panel.", input: { hint: "[jobId] | cancel <jobId> | list" },
114
+ handler({ agent, rawInput, signal }) {
115
+ signal.throwIfAborted();
116
+ try {
117
+ const jobs = session(agent).jobs;
118
+ const parts = rawInput.trim().split(/\s+/).filter(Boolean);
119
+ if (parts[0] === "cancel" && parts.length === 2)
120
+ return { kind: "success", text: jobs.cancel(parts[1]) ? "Cancellation requested." : "Job already finished." };
121
+ if (parts.length > 1 || parts[0] === "cancel")
122
+ return { kind: "error", text: "Usage: /braid [jobId] | cancel <jobId> | list" };
123
+ if (parts[0] === "list")
124
+ return { kind: "success", text: JSON.stringify(jobs.list(), null, 2) };
125
+ const id = parts[0] ?? jobs.list()[0]?.handle;
126
+ return { kind: "success", text: id ? renderPanel(jobs.get(id)) : "No Braid jobs in this session." };
127
+ }
128
+ catch (error) {
129
+ return { kind: "error", text: error instanceof Error ? error.message : String(error) };
130
+ }
131
+ },
132
+ });
133
+ ctx.on("agent/inbox/claimed", ({ agent, message }) => {
134
+ if (message.source.kind === "braid") {
135
+ sessions.get(agent)?.pending.delete(message.source.reminderId);
136
+ sessions.get(agent)?.queued.delete(message.source.reminderId);
137
+ }
138
+ });
139
+ ctx.on("agent/inbox/discarded", ({ agent, message }) => {
140
+ if (message.source.kind === "braid")
141
+ sessions.get(agent)?.queued.delete(message.source.reminderId);
142
+ });
143
+ ctx.on("agent/status", ({ agent, status }) => {
144
+ if (status === "idle")
145
+ for (const message of sessions.get(agent)?.pending.values() ?? [])
146
+ send(agent, message);
147
+ });
148
+ ctx.on("agent/disposed", ({ agent }) => {
149
+ const value = sessions.get(agent);
150
+ value?.pending.clear();
151
+ sessions.delete(agent);
152
+ changed();
153
+ void value?.release();
154
+ });
155
+ ctx.effect(() => async () => {
156
+ const active = [...sessions.values()];
157
+ sessions.clear();
158
+ for (const value of active)
159
+ value.pending.clear();
160
+ await Promise.all(active.map(value => value.release()));
161
+ });
162
+ }
package/dist/jobs.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ import { type BraidInput, type BraidResult, type BraidSnapshot, type GraphUpdate, type ExecutionEvent, type NodeResult } from "@chrok/braid";
2
+ import type { TokenUsage } from "@deepseek-ai/dsh-llm";
3
+ import { type NodeProgress, type DshLlm } from "./runner.js";
4
+ export interface JobOptions {
5
+ maxConcurrency?: number;
6
+ maxExecutions?: number;
7
+ nodeTimeoutMs?: number;
8
+ graphTimeoutMs?: number;
9
+ maxToolRounds?: number;
10
+ maxToolCalls?: number;
11
+ }
12
+ export interface JobSnapshot {
13
+ jobId: string;
14
+ handle: string;
15
+ goal: string;
16
+ status: "running" | "completed" | "failed" | "cancelled";
17
+ createdAt: number;
18
+ execution: BraidSnapshot;
19
+ result?: BraidResult;
20
+ error?: string;
21
+ usage: TokenUsage;
22
+ progress: Record<string, NodeProgress>;
23
+ events: ExecutionEvent[];
24
+ }
25
+ export interface Completion {
26
+ jobId: string;
27
+ handle: string;
28
+ status: string;
29
+ executionId?: string;
30
+ nodeId?: string;
31
+ iteration?: number;
32
+ paused?: boolean;
33
+ sequence?: number;
34
+ }
35
+ /** One manager per live DSH agent; foreground cancellation never owns these runs. */
36
+ export declare class BraidJobs {
37
+ private llm;
38
+ private notify;
39
+ private jobs;
40
+ private handles;
41
+ private listeners;
42
+ private disposed;
43
+ private nextHandle;
44
+ constructor(llm: DshLlm, notify?: (completion: Completion) => void);
45
+ subscribe(listener: () => void): () => void;
46
+ private changed;
47
+ start(input: BraidInput, options: JobOptions, context: {
48
+ cwd: string;
49
+ model?: string;
50
+ }): JobSnapshot;
51
+ private onEvent;
52
+ private remind;
53
+ private lookup;
54
+ get(id: string): JobSnapshot;
55
+ getNode(id: string, nodeId?: string, executionId?: string): NodeResult;
56
+ list(): {
57
+ jobId: string;
58
+ handle: string;
59
+ goal: string;
60
+ status: "failed" | "running" | "completed" | "cancelled";
61
+ createdAt: number;
62
+ }[];
63
+ update(id: string, patch: GraphUpdate): JobSnapshot;
64
+ resume(id: string, executionIds: readonly string[], expectedRevision: number): JobSnapshot;
65
+ cancel(id: string): boolean;
66
+ wait(id: string): Promise<void>;
67
+ dispose(): Promise<void>;
68
+ }
package/dist/jobs.js ADDED
@@ -0,0 +1,146 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { setImmediate as nextTurn } from "node:timers/promises";
3
+ import { startBraid, validateGraph } from "@chrok/braid";
4
+ import { createDshRunner, sumUsage, validateBudgets } from "./runner.js";
5
+ /** One manager per live DSH agent; foreground cancellation never owns these runs. */
6
+ export class BraidJobs {
7
+ llm;
8
+ notify;
9
+ jobs = new Map();
10
+ handles = new Map();
11
+ listeners = new Set();
12
+ disposed = false;
13
+ nextHandle = 1;
14
+ constructor(llm, notify = () => { }) {
15
+ this.llm = llm;
16
+ this.notify = notify;
17
+ }
18
+ subscribe(listener) {
19
+ this.listeners.add(listener);
20
+ return () => { this.listeners.delete(listener); };
21
+ }
22
+ changed() {
23
+ for (const listener of this.listeners) {
24
+ try {
25
+ listener();
26
+ }
27
+ catch { /* UI isolation. */ }
28
+ }
29
+ }
30
+ start(input, options, context) {
31
+ if (this.disposed)
32
+ throw new Error("Braid session has closed");
33
+ validateGraph(input);
34
+ validateBudgets({ maxToolRounds: options.maxToolRounds, maxToolCalls: options.maxToolCalls });
35
+ const jobId = randomUUID(), handle = `job-${this.nextHandle}`;
36
+ const reports = [];
37
+ const events = [];
38
+ const progress = Object.create(null);
39
+ const invoke = createDshRunner(this.llm, { cwd: context.cwd,
40
+ ...(options.maxToolRounds === undefined ? {} : { maxToolRounds: options.maxToolRounds }),
41
+ ...(options.maxToolCalls === undefined ? {} : { maxToolCalls: options.maxToolCalls }),
42
+ onUsage: usage => { reports.push(usage); },
43
+ onProgress: value => { progress[value.executionId] = value; this.changed(); },
44
+ });
45
+ // Core options and graph validation happen synchronously before publishing a handle.
46
+ const run = startBraid(structuredClone(input), {
47
+ cwd: context.cwd, ...options,
48
+ nodeTimeoutMs: options.nodeTimeoutMs ?? Infinity, graphTimeoutMs: options.graphTimeoutMs ?? Infinity,
49
+ ...(context.model ? { defaultModel: context.model } : {}),
50
+ runner: async (request) => { await nextTurn(); return invoke(request); },
51
+ onEvent: event => {
52
+ events.push(structuredClone(event));
53
+ if (events.length > 80)
54
+ events.shift();
55
+ this.changed();
56
+ this.onEvent(jobId, handle, event);
57
+ },
58
+ });
59
+ const job = { jobId, handle, goal: input.goal, status: "running", createdAt: Date.now(), run, reports, progress, events, done: Promise.resolve() };
60
+ this.nextHandle++;
61
+ this.jobs.set(jobId, job);
62
+ this.handles.set(handle, jobId);
63
+ job.done = (async () => {
64
+ try {
65
+ job.result = await run.result;
66
+ job.status = job.result.error?.code === "CANCELLED" ? "cancelled" : job.result.status;
67
+ }
68
+ catch (error) {
69
+ job.error = error instanceof Error ? error.message : String(error);
70
+ job.status = "failed";
71
+ }
72
+ this.changed();
73
+ this.remind({ jobId, handle, status: job.status });
74
+ })();
75
+ this.changed();
76
+ return this.get(handle);
77
+ }
78
+ onEvent(jobId, handle, event) {
79
+ if (!["execution_paused", "node_completed", "node_failed"].includes(event.type) || !event.executionId)
80
+ return;
81
+ const state = this.jobs.get(jobId)?.run.snapshot();
82
+ const node = state?.executions[event.executionId];
83
+ if (!node)
84
+ return;
85
+ const paused = event.type === "execution_paused";
86
+ if (!paused && (!node.node.notifyOnCompletion || (node.node.pauseAfter && !state?.error)))
87
+ return;
88
+ this.remind({ jobId, handle, status: node.status, executionId: node.executionId, nodeId: node.id,
89
+ ...(node.iteration === undefined ? {} : { iteration: node.iteration }), paused, sequence: event.sequence });
90
+ }
91
+ remind(completion) {
92
+ if (this.disposed)
93
+ return;
94
+ try {
95
+ this.notify(completion);
96
+ }
97
+ catch { /* Notification failures cannot fail jobs. */ }
98
+ }
99
+ lookup(id) {
100
+ const job = this.jobs.get(this.handles.get(id) ?? id);
101
+ if (!job)
102
+ throw new Error(`Unknown Braid job: ${id}. Use an exact session handle or UUID. Available jobs: ${JSON.stringify(this.list())}`);
103
+ return job;
104
+ }
105
+ get(id) {
106
+ const { run, done: _done, reports, ...job } = this.lookup(id);
107
+ return structuredClone({ ...job, execution: run.snapshot(), usage: sumUsage(reports) });
108
+ }
109
+ getNode(id, nodeId, executionId) {
110
+ const state = this.lookup(id).run.snapshot();
111
+ const selected = executionId ? state.executions : state.nodes;
112
+ const key = executionId ?? nodeId;
113
+ const node = key && Object.hasOwn(selected, key) ? selected[key] : undefined;
114
+ if (!node || (nodeId && node.id !== nodeId))
115
+ throw new Error("Unknown Braid node or execution; inspect braid_status with only jobId");
116
+ return structuredClone(node);
117
+ }
118
+ list() {
119
+ return [...this.jobs.values()].reverse().map(({ jobId, handle, goal, status, createdAt }) => ({ jobId, handle, goal, status, createdAt }));
120
+ }
121
+ update(id, patch) {
122
+ this.lookup(id).run.update(patch);
123
+ this.changed();
124
+ return this.get(id);
125
+ }
126
+ resume(id, executionIds, expectedRevision) {
127
+ this.lookup(id).run.resume(executionIds, expectedRevision);
128
+ this.changed();
129
+ return this.get(id);
130
+ }
131
+ cancel(id) {
132
+ const job = this.lookup(id);
133
+ if (job.status !== "running")
134
+ return false;
135
+ job.run.cancel();
136
+ return true;
137
+ }
138
+ async wait(id) { await this.lookup(id).done; }
139
+ async dispose() {
140
+ this.disposed = true;
141
+ this.listeners.clear();
142
+ for (const job of this.jobs.values())
143
+ job.run.cancel();
144
+ await Promise.all([...this.jobs.values()].map(job => job.done));
145
+ }
146
+ }
@@ -0,0 +1,20 @@
1
+ import type { InvocationDescriptor, RemoteResult } from "@deepseek-ai/dsh-typert-protocol";
2
+ import type { ControlRequest, DetailRequest, PanelDetail, PanelFrame, PanelRequest } from "./panel-types.js";
3
+ /** One descriptor table shared by Host registration and Client Remote mounting. */
4
+ export declare const PANEL_PACKAGE = "@chrok/dsh-braid";
5
+ export declare const panelDescriptors: InvocationDescriptor[];
6
+ export interface PanelRemote {
7
+ watch(request: PanelRequest, signal?: AbortSignal): AsyncIterable<PanelFrame>;
8
+ control(request: ControlRequest): Promise<RemoteResult<PanelFrame>>;
9
+ detail(request: DetailRequest): Promise<RemoteResult<PanelDetail>>;
10
+ }
11
+ declare module "@deepseek-ai/dsh-typert-protocol" {
12
+ interface TypertRemoteNamespaceMap {
13
+ braidPanel: PanelRemote;
14
+ }
15
+ interface RemoteErrorDetailsMap {
16
+ "braid/panel": {
17
+ sessionId: string;
18
+ };
19
+ }
20
+ }