acpx 0.4.1 → 0.5.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/dist/agent-registry-DGw0-3Tc.js +54 -0
- package/dist/agent-registry-DGw0-3Tc.js.map +1 -0
- package/dist/{cli-idpWyCOs.js → cli-CLRrs6eQ.js} +8 -12
- package/dist/cli-CLRrs6eQ.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1018 -1009
- package/dist/cli.js.map +1 -1
- package/dist/client-DLTWuu4w.d.ts +116 -0
- package/dist/client-DLTWuu4w.d.ts.map +1 -0
- package/dist/{flags-CCcX9fZj.js → flags-BmubjvOw.js} +5 -55
- package/dist/flags-BmubjvOw.js.map +1 -0
- package/dist/{flows-BL1tSvZT.js → flows-CR7xCmkR.js} +471 -281
- package/dist/flows-CR7xCmkR.js.map +1 -0
- package/dist/flows.d.ts +5 -9
- package/dist/flows.d.ts.map +1 -1
- package/dist/flows.js +1 -1
- package/dist/{queue-ipc-CE8_QGX3.js → ipc-DN6M4Ui9.js} +12 -571
- package/dist/ipc-DN6M4Ui9.js.map +1 -0
- package/dist/{acp-jsonrpc-BbBgC5gO.js → jsonrpc-M3y-qzy8.js} +2 -2
- package/dist/jsonrpc-M3y-qzy8.js.map +1 -0
- package/dist/{output-Du3m6oPQ.js → output-Di0M9Et8.js} +6 -6
- package/dist/output-Di0M9Et8.js.map +1 -0
- package/dist/perf-metrics-D9QC81lB.js +568 -0
- package/dist/perf-metrics-D9QC81lB.js.map +1 -0
- package/dist/{session-RO_LZUnv.js → prompt-turn-Bt8T3SRR.js} +2304 -3632
- package/dist/prompt-turn-Bt8T3SRR.js.map +1 -0
- package/dist/{output-render-Bz58qaQn.js → render-BL5ynRkN.js} +7 -6
- package/dist/render-BL5ynRkN.js.map +1 -0
- package/dist/runtime.d.ts +266 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +984 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session-BbN0SBgf.js +1488 -0
- package/dist/session-BbN0SBgf.js.map +1 -0
- package/dist/{types-CeRKmEQ1.d.ts → types-DXxLBQc3.d.ts} +40 -3
- package/dist/types-DXxLBQc3.d.ts.map +1 -0
- package/package.json +5 -3
- package/dist/acp-jsonrpc-BbBgC5gO.js.map +0 -1
- package/dist/cli-idpWyCOs.js.map +0 -1
- package/dist/flags-CCcX9fZj.js.map +0 -1
- package/dist/flows-BL1tSvZT.js.map +0 -1
- package/dist/output-Du3m6oPQ.js.map +0 -1
- package/dist/output-render-Bz58qaQn.js.map +0 -1
- package/dist/queue-ipc-CE8_QGX3.js.map +0 -1
- package/dist/session-RO_LZUnv.js.map +0 -1
- package/dist/types-CeRKmEQ1.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-turn-Bt8T3SRR.js","names":["sessionBaseDir","asRecord","hasOwn","isUserMessage","isAgentMessage","asRecord","fs","fs","isoNow","nowIso","canPromptForPermission","fs","canPromptForPermission","isoNow","waitForSpawn","asRecord","waitForSpawn","isoNow","ensureAcpxState","isoNow"],"sources":["../src/async-control.ts","../src/session/persistence/serialize.ts","../src/persisted-key-policy.ts","../src/session/event-log.ts","../src/session/persistence/parse.ts","../src/session/persistence/index.ts","../src/session/persistence/repository.ts","../src/permission-prompt.ts","../src/filesystem.ts","../src/permissions.ts","../src/spawn-command-options.ts","../src/acp/client-process.ts","../src/acp/agent-command.ts","../src/acp/auth-env.ts","../src/acp/session-control-errors.ts","../src/acp/terminal-manager.ts","../src/acp/client.ts","../src/session/conversation-model.ts","../src/session/mode-preference.ts","../src/runtime/engine/lifecycle.ts","../src/runtime/engine/reconnect.ts","../src/runtime/engine/session-options.ts","../src/runtime/engine/connected-session.ts","../src/runtime/engine/prompt-turn.ts"],"sourcesContent":["export class TimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Timed out after ${timeoutMs}ms`);\n this.name = \"TimeoutError\";\n }\n}\n\nexport class InterruptedError extends Error {\n constructor() {\n super(\"Interrupted\");\n this.name = \"InterruptedError\";\n }\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (timeoutMs == null || timeoutMs <= 0) {\n return await promise;\n }\n\n let timer: NodeJS.Timeout | undefined;\n const timeoutPromise = new Promise<T>((_resolve, reject) => {\n timer = setTimeout(() => {\n reject(new TimeoutError(timeoutMs));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timer) {\n clearTimeout(timer);\n }\n }\n}\n\nexport async function withInterrupt<T>(\n run: () => Promise<T>,\n onInterrupt: () => Promise<void>,\n): Promise<T> {\n return await new Promise<T>((resolve, reject) => {\n let settled = false;\n\n const finish = (cb: () => void) => {\n if (settled) {\n return;\n }\n settled = true;\n process.off(\"SIGINT\", onSigint);\n process.off(\"SIGTERM\", onSigterm);\n process.off(\"SIGHUP\", onSighup);\n cb();\n };\n\n const rejectInterrupted = () => {\n void onInterrupt().finally(() => {\n finish(() => reject(new InterruptedError()));\n });\n };\n\n const onSigint = () => {\n rejectInterrupted();\n };\n\n const onSigterm = () => {\n rejectInterrupted();\n };\n\n const onSighup = () => {\n rejectInterrupted();\n };\n\n process.once(\"SIGINT\", onSigint);\n process.once(\"SIGTERM\", onSigterm);\n process.once(\"SIGHUP\", onSighup);\n\n void run().then(\n (result) => finish(() => resolve(result)),\n (error) => finish(() => reject(error)),\n );\n });\n}\n","import type { SessionRecord } from \"../../types.js\";\nimport { SESSION_RECORD_SCHEMA } from \"../../types.js\";\nimport { normalizeRuntimeSessionId } from \"../runtime-session-id.js\";\n\nexport function serializeSessionRecordForDisk(record: SessionRecord): Record<string, unknown> {\n const canonical: SessionRecord = {\n ...record,\n schema: SESSION_RECORD_SCHEMA,\n };\n\n return {\n schema: canonical.schema,\n acpx_record_id: canonical.acpxRecordId,\n acp_session_id: canonical.acpSessionId,\n agent_session_id: normalizeRuntimeSessionId(canonical.agentSessionId),\n agent_command: canonical.agentCommand,\n cwd: canonical.cwd,\n name: canonical.name,\n created_at: canonical.createdAt,\n last_used_at: canonical.lastUsedAt,\n last_seq: canonical.lastSeq,\n last_request_id: canonical.lastRequestId,\n event_log: canonical.eventLog,\n closed: canonical.closed,\n closed_at: canonical.closedAt,\n pid: canonical.pid,\n agent_started_at: canonical.agentStartedAt,\n last_prompt_at: canonical.lastPromptAt,\n last_agent_exit_code: canonical.lastAgentExitCode,\n last_agent_exit_signal: canonical.lastAgentExitSignal,\n last_agent_exit_at: canonical.lastAgentExitAt,\n last_agent_disconnect_reason: canonical.lastAgentDisconnectReason,\n protocol_version: canonical.protocolVersion,\n agent_capabilities: canonical.agentCapabilities,\n title: canonical.title,\n messages: canonical.messages,\n updated_at: canonical.updated_at,\n cumulative_token_usage: canonical.cumulative_token_usage,\n request_token_usage: canonical.request_token_usage,\n acpx: canonical.acpx,\n };\n}\n","const SNAKE_CASE_KEY = /^[a-z][a-z0-9_]*$/;\n\nconst ZED_TAG_KEYS = new Set([\n \"User\",\n \"Agent\",\n \"Resume\",\n \"Text\",\n \"Mention\",\n \"Image\",\n \"Thinking\",\n \"RedactedThinking\",\n \"ToolUse\",\n]);\n\nconst MAP_OBJECT_PATHS = new Set([\"request_token_usage\", \"messages.Agent.tool_results\"]);\n\nconst OPAQUE_VALUE_PATHS = new Set([\n \"agent_capabilities\",\n \"messages.Agent.content.ToolUse.input\",\n \"acpx.config_options\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction joinPath(path: string[]): string {\n return path.join(\".\");\n}\n\nfunction isAllowedKey(path: string[], key: string): boolean {\n if (ZED_TAG_KEYS.has(key)) {\n return true;\n }\n\n return false;\n}\n\nfunction shouldSkipKeyRule(path: string[]): boolean {\n return MAP_OBJECT_PATHS.has(joinPath(path));\n}\n\nfunction shouldSkipDescend(path: string[]): boolean {\n return OPAQUE_VALUE_PATHS.has(joinPath(path)) || isToolResultOutputPath(path);\n}\n\nfunction isToolResultOutputPath(path: string[]): boolean {\n if (path.length < 5 || path[path.length - 1] !== \"output\") {\n return false;\n }\n\n const toolResultsIndex = path.lastIndexOf(\"tool_results\");\n if (toolResultsIndex === -1 || toolResultsIndex + 2 !== path.length - 1) {\n return false;\n }\n\n const parentPath = path.slice(0, toolResultsIndex + 1).join(\".\");\n return parentPath === \"messages.Agent.tool_results\";\n}\n\nfunction collectViolations(value: unknown, path: string[], violations: string[]): void {\n if (Array.isArray(value)) {\n for (const entry of value) {\n collectViolations(entry, path, violations);\n }\n return;\n }\n\n if (!isRecord(value)) {\n return;\n }\n\n const skipKeyRule = shouldSkipKeyRule(path);\n for (const [key, child] of Object.entries(value)) {\n if (!skipKeyRule && !SNAKE_CASE_KEY.test(key) && !isAllowedKey(path, key)) {\n violations.push(`${joinPath(path)}.${key}`.replace(/^\\./, \"\"));\n }\n\n const childPath = [...path, key];\n if (shouldSkipDescend(childPath)) {\n continue;\n }\n\n collectViolations(child, childPath, violations);\n }\n}\n\nexport function findPersistedKeyPolicyViolations(value: unknown): string[] {\n const violations: string[] = [];\n collectViolations(value, [], violations);\n return violations;\n}\n\nexport function assertPersistedKeyPolicy(value: unknown): void {\n const violations = findPersistedKeyPolicyViolations(value);\n if (violations.length === 0) {\n return;\n }\n\n throw new Error(\n `Persisted key policy violation (expected snake_case keys): ${violations.join(\", \")}`,\n );\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport type { SessionEventLog } from \"../types.js\";\n\nexport const DEFAULT_EVENT_SEGMENT_MAX_BYTES = 64 * 1024 * 1024;\nexport const DEFAULT_EVENT_MAX_SEGMENTS = 5;\n\nexport function sessionBaseDir(): string {\n return path.join(os.homedir(), \".acpx\", \"sessions\");\n}\n\nexport function safeSessionId(sessionId: string): string {\n return encodeURIComponent(sessionId);\n}\n\nexport function sessionEventActivePath(sessionId: string): string {\n return path.join(sessionBaseDir(), `${safeSessionId(sessionId)}.stream.ndjson`);\n}\n\nexport function sessionEventSegmentPath(sessionId: string, segment: number): string {\n return path.join(sessionBaseDir(), `${safeSessionId(sessionId)}.stream.${segment}.ndjson`);\n}\n\nexport function sessionEventLockPath(sessionId: string): string {\n return path.join(sessionBaseDir(), `${safeSessionId(sessionId)}.stream.lock`);\n}\n\nexport function defaultSessionEventLog(sessionId: string): SessionEventLog {\n return {\n active_path: sessionEventActivePath(sessionId),\n segment_count: DEFAULT_EVENT_MAX_SEGMENTS,\n max_segment_bytes: DEFAULT_EVENT_SEGMENT_MAX_BYTES,\n max_segments: DEFAULT_EVENT_MAX_SEGMENTS,\n last_write_at: undefined,\n last_write_error: null,\n };\n}\n","import type {\n SessionAcpxState,\n SessionEventLog,\n SessionRecord,\n SessionConversation,\n} from \"../../types.js\";\nimport { SESSION_RECORD_SCHEMA } from \"../../types.js\";\nimport { defaultSessionEventLog } from \"../event-log.js\";\nimport { normalizeRuntimeSessionId } from \"../runtime-session-id.js\";\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction hasOwn(source: object, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(source, key);\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction parseTokenUsage(\n raw: unknown,\n): SessionConversation[\"cumulative_token_usage\"] | null | undefined {\n if (raw === undefined || raw === null) {\n return undefined;\n }\n\n const record = asRecord(raw);\n if (!record) {\n return null;\n }\n\n const usage: SessionConversation[\"cumulative_token_usage\"] = {};\n const fields: Array<keyof SessionConversation[\"cumulative_token_usage\"]> = [\n \"input_tokens\",\n \"output_tokens\",\n \"cache_creation_input_tokens\",\n \"cache_read_input_tokens\",\n ];\n\n for (const field of fields) {\n const value = record[field];\n if (value === undefined) {\n continue;\n }\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n return null;\n }\n usage[field] = value;\n }\n\n return usage;\n}\n\nfunction parseRequestTokenUsage(\n raw: unknown,\n): SessionConversation[\"request_token_usage\"] | null | undefined {\n if (raw === undefined || raw === null) {\n return undefined;\n }\n\n const record = asRecord(raw);\n if (!record) {\n return null;\n }\n\n const usage: SessionConversation[\"request_token_usage\"] = {};\n for (const [key, value] of Object.entries(record)) {\n const parsed = parseTokenUsage(value);\n if (parsed == null) {\n return null;\n }\n usage[key] = parsed;\n }\n\n return usage;\n}\n\nfunction isSessionMessageImage(raw: unknown): boolean {\n const record = asRecord(raw);\n if (!record || typeof record.source !== \"string\") {\n return false;\n }\n\n if (record.size === undefined || record.size === null) {\n return true;\n }\n\n const size = asRecord(record.size);\n return (\n !!size &&\n typeof size.width === \"number\" &&\n Number.isFinite(size.width) &&\n typeof size.height === \"number\" &&\n Number.isFinite(size.height)\n );\n}\n\nfunction isUserContent(raw: unknown): boolean {\n const record = asRecord(raw);\n if (!record) {\n return false;\n }\n\n if (typeof record.Text === \"string\") {\n return true;\n }\n\n if (record.Mention !== undefined) {\n const mention = asRecord(record.Mention);\n return !!mention && typeof mention.uri === \"string\" && typeof mention.content === \"string\";\n }\n\n if (record.Image !== undefined) {\n return isSessionMessageImage(record.Image);\n }\n\n return false;\n}\n\nfunction isToolUse(raw: unknown): boolean {\n const record = asRecord(raw);\n return (\n !!record &&\n typeof record.id === \"string\" &&\n typeof record.name === \"string\" &&\n typeof record.raw_input === \"string\" &&\n hasOwn(record, \"input\") &&\n typeof record.is_input_complete === \"boolean\" &&\n (record.thought_signature === undefined ||\n record.thought_signature === null ||\n typeof record.thought_signature === \"string\")\n );\n}\n\nfunction isToolResultContent(raw: unknown): boolean {\n const record = asRecord(raw);\n if (!record) {\n return false;\n }\n\n if (typeof record.Text === \"string\") {\n return true;\n }\n\n if (record.Image !== undefined) {\n return isSessionMessageImage(record.Image);\n }\n\n return false;\n}\n\nfunction isToolResult(raw: unknown): boolean {\n const record = asRecord(raw);\n return (\n !!record &&\n typeof record.tool_use_id === \"string\" &&\n typeof record.tool_name === \"string\" &&\n typeof record.is_error === \"boolean\" &&\n isToolResultContent(record.content)\n );\n}\n\nfunction isAgentContent(raw: unknown): boolean {\n const record = asRecord(raw);\n if (!record) {\n return false;\n }\n\n if (typeof record.Text === \"string\") {\n return true;\n }\n\n if (record.Thinking !== undefined) {\n const thinking = asRecord(record.Thinking);\n return (\n !!thinking &&\n typeof thinking.text === \"string\" &&\n (thinking.signature === undefined ||\n thinking.signature === null ||\n typeof thinking.signature === \"string\")\n );\n }\n\n if (typeof record.RedactedThinking === \"string\") {\n return true;\n }\n\n if (record.ToolUse !== undefined) {\n return isToolUse(record.ToolUse);\n }\n\n return false;\n}\n\nfunction isUserMessage(raw: unknown): boolean {\n const record = asRecord(raw);\n if (!record || record.User === undefined) {\n return false;\n }\n\n const user = asRecord(record.User);\n return (\n !!user &&\n typeof user.id === \"string\" &&\n Array.isArray(user.content) &&\n user.content.every((entry) => isUserContent(entry))\n );\n}\n\nfunction isAgentMessage(raw: unknown): boolean {\n const record = asRecord(raw);\n if (!record || record.Agent === undefined) {\n return false;\n }\n\n const agent = asRecord(record.Agent);\n if (!agent || !Array.isArray(agent.content) || !agent.content.every(isAgentContent)) {\n return false;\n }\n\n const toolResults = asRecord(agent.tool_results);\n if (!toolResults) {\n return false;\n }\n\n return Object.values(toolResults).every(isToolResult);\n}\n\nfunction isConversationMessage(raw: unknown): boolean {\n return raw === \"Resume\" || isUserMessage(raw) || isAgentMessage(raw);\n}\n\nfunction parseConversationRecord(record: Record<string, unknown>): SessionConversation | undefined {\n if (\n !Array.isArray(record.messages) ||\n !record.messages.every(isConversationMessage) ||\n typeof record.updated_at !== \"string\"\n ) {\n return undefined;\n }\n\n if (record.title !== undefined && record.title !== null && typeof record.title !== \"string\") {\n return undefined;\n }\n\n const cumulativeTokenUsage = parseTokenUsage(record.cumulative_token_usage);\n const requestTokenUsage = parseRequestTokenUsage(record.request_token_usage);\n if (cumulativeTokenUsage === null || requestTokenUsage === null) {\n return undefined;\n }\n\n return {\n title:\n record.title === undefined || record.title === null || typeof record.title === \"string\"\n ? record.title\n : null,\n messages: record.messages as SessionConversation[\"messages\"],\n updated_at: record.updated_at,\n cumulative_token_usage: cumulativeTokenUsage ?? {},\n request_token_usage: requestTokenUsage ?? {},\n };\n}\n\nfunction parseAcpxState(raw: unknown): SessionAcpxState | undefined {\n const record = asRecord(raw);\n if (!record) {\n return undefined;\n }\n\n const state: SessionAcpxState = {};\n\n if (typeof record.current_mode_id === \"string\") {\n state.current_mode_id = record.current_mode_id;\n }\n\n if (typeof record.desired_mode_id === \"string\") {\n state.desired_mode_id = record.desired_mode_id;\n }\n\n if (typeof record.current_model_id === \"string\") {\n state.current_model_id = record.current_model_id;\n }\n\n if (isStringArray(record.available_models)) {\n state.available_models = [...record.available_models];\n }\n\n if (isStringArray(record.available_commands)) {\n state.available_commands = [...record.available_commands];\n }\n\n if (Array.isArray(record.config_options)) {\n state.config_options = record.config_options as SessionAcpxState[\"config_options\"];\n }\n\n const sessionOptions = asRecord(record.session_options);\n if (sessionOptions) {\n const parsedSessionOptions: NonNullable<SessionAcpxState[\"session_options\"]> = {};\n\n if (typeof sessionOptions.model === \"string\") {\n parsedSessionOptions.model = sessionOptions.model;\n }\n\n if (isStringArray(sessionOptions.allowed_tools)) {\n parsedSessionOptions.allowed_tools = [...sessionOptions.allowed_tools];\n }\n\n if (\n typeof sessionOptions.max_turns === \"number\" &&\n Number.isInteger(sessionOptions.max_turns) &&\n sessionOptions.max_turns > 0\n ) {\n parsedSessionOptions.max_turns = sessionOptions.max_turns;\n }\n\n if (Object.keys(parsedSessionOptions).length > 0) {\n state.session_options = parsedSessionOptions;\n }\n }\n\n return state;\n}\n\nfunction parseEventLog(raw: unknown, sessionId: string): SessionEventLog {\n const record = asRecord(raw);\n if (!record) {\n return defaultSessionEventLog(sessionId);\n }\n\n if (\n typeof record.active_path !== \"string\" ||\n typeof record.segment_count !== \"number\" ||\n !Number.isInteger(record.segment_count) ||\n record.segment_count < 1 ||\n typeof record.max_segment_bytes !== \"number\" ||\n !Number.isInteger(record.max_segment_bytes) ||\n record.max_segment_bytes < 1 ||\n typeof record.max_segments !== \"number\" ||\n !Number.isInteger(record.max_segments) ||\n record.max_segments < 1\n ) {\n return defaultSessionEventLog(sessionId);\n }\n\n return {\n active_path: record.active_path,\n segment_count: record.segment_count,\n max_segment_bytes: record.max_segment_bytes,\n max_segments: record.max_segments,\n last_write_at: typeof record.last_write_at === \"string\" ? record.last_write_at : undefined,\n last_write_error:\n record.last_write_error == null || typeof record.last_write_error === \"string\"\n ? record.last_write_error\n : null,\n };\n}\n\nfunction normalizeOptionalName(value: unknown): string | undefined | null {\n if (value == null) {\n return undefined;\n }\n\n if (typeof value !== \"string\") {\n return null;\n }\n\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeOptionalPid(value: unknown): number | undefined | null {\n if (value == null) {\n return undefined;\n }\n\n if (!Number.isInteger(value) || (value as number) <= 0) {\n return null;\n }\n\n return value as number;\n}\n\nfunction normalizeOptionalBoolean(value: unknown, fallback = false): boolean | null {\n if (value == null) {\n return fallback;\n }\n return typeof value === \"boolean\" ? value : null;\n}\n\nfunction normalizeOptionalString(value: unknown): string | undefined | null {\n if (value == null) {\n return undefined;\n }\n return typeof value === \"string\" ? value : null;\n}\n\nfunction normalizeOptionalExitCode(value: unknown): number | null | undefined | symbol {\n if (value === undefined) {\n return undefined;\n }\n if (value === null) {\n return null;\n }\n if (Number.isInteger(value)) {\n return value as number;\n }\n return Symbol(\"invalid\");\n}\n\nfunction normalizeOptionalSignal(value: unknown): NodeJS.Signals | null | undefined | symbol {\n if (value === undefined) {\n return undefined;\n }\n if (value === null) {\n return null;\n }\n if (typeof value === \"string\") {\n return value as NodeJS.Signals;\n }\n return Symbol(\"invalid\");\n}\n\nexport function parseSessionRecord(raw: unknown): SessionRecord | null {\n const record = asRecord(raw);\n if (!record) {\n return null;\n }\n\n if (record.schema !== SESSION_RECORD_SCHEMA) {\n return null;\n }\n\n const name = normalizeOptionalName(record.name);\n const pid = normalizeOptionalPid(record.pid);\n const closed = normalizeOptionalBoolean(record.closed, false);\n const closedAt = normalizeOptionalString(record.closed_at);\n const agentStartedAt = normalizeOptionalString(record.agent_started_at);\n const lastPromptAt = normalizeOptionalString(record.last_prompt_at);\n const lastAgentExitCode = normalizeOptionalExitCode(record.last_agent_exit_code);\n const lastAgentExitSignal = normalizeOptionalSignal(record.last_agent_exit_signal);\n const lastAgentExitAt = normalizeOptionalString(record.last_agent_exit_at);\n const lastAgentDisconnectReason = normalizeOptionalString(record.last_agent_disconnect_reason);\n\n if (\n typeof record.acpx_record_id !== \"string\" ||\n typeof record.acp_session_id !== \"string\" ||\n typeof record.agent_command !== \"string\" ||\n typeof record.cwd !== \"string\" ||\n typeof record.created_at !== \"string\" ||\n typeof record.last_used_at !== \"string\" ||\n typeof record.last_seq !== \"number\" ||\n !Number.isInteger(record.last_seq) ||\n record.last_seq < 0 ||\n name === null ||\n pid === null ||\n closed === null ||\n closedAt === null ||\n agentStartedAt === null ||\n lastPromptAt === null ||\n typeof lastAgentExitCode === \"symbol\" ||\n typeof lastAgentExitSignal === \"symbol\" ||\n lastAgentExitAt === null ||\n lastAgentDisconnectReason === null\n ) {\n return null;\n }\n\n const conversation = parseConversationRecord(record);\n if (!conversation) {\n return null;\n }\n\n const eventLog = parseEventLog(record.event_log, record.acpx_record_id);\n const lastRequestId = normalizeOptionalString(record.last_request_id);\n if (lastRequestId === null) {\n return null;\n }\n\n return {\n schema: SESSION_RECORD_SCHEMA,\n acpxRecordId: record.acpx_record_id,\n acpSessionId: record.acp_session_id,\n agentSessionId: normalizeRuntimeSessionId(record.agent_session_id),\n agentCommand: record.agent_command,\n cwd: record.cwd,\n name,\n createdAt: record.created_at,\n lastUsedAt: record.last_used_at,\n lastSeq: record.last_seq,\n lastRequestId,\n eventLog,\n closed,\n closedAt,\n pid,\n agentStartedAt,\n lastPromptAt,\n lastAgentExitCode,\n lastAgentExitSignal: lastAgentExitSignal,\n lastAgentExitAt,\n lastAgentDisconnectReason,\n protocolVersion:\n typeof record.protocol_version === \"number\" ? record.protocol_version : undefined,\n agentCapabilities: asRecord(record.agent_capabilities) as SessionRecord[\"agentCapabilities\"],\n title: conversation.title,\n messages: conversation.messages,\n updated_at: conversation.updated_at,\n cumulative_token_usage: conversation.cumulative_token_usage,\n request_token_usage: conversation.request_token_usage,\n acpx: parseAcpxState(record.acpx),\n };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { SessionRecord } from \"../../types.js\";\nimport { parseSessionRecord } from \"./parse.js\";\n\nconst SESSION_INDEX_SCHEMA = \"acpx.session-index.v1\";\n\nexport type SessionIndexEntry = {\n file: string;\n acpxRecordId: string;\n acpSessionId: string;\n agentCommand: string;\n cwd: string;\n name?: string;\n closed: boolean;\n lastUsedAt: string;\n};\n\ntype SessionIndex = {\n schema: typeof SESSION_INDEX_SCHEMA;\n files: string[];\n entries: SessionIndexEntry[];\n};\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction parseIndexEntry(raw: unknown): SessionIndexEntry | undefined {\n const record = asRecord(raw);\n if (!record) {\n return undefined;\n }\n if (\n typeof record.file !== \"string\" ||\n typeof record.acpxRecordId !== \"string\" ||\n typeof record.acpSessionId !== \"string\" ||\n typeof record.agentCommand !== \"string\" ||\n typeof record.cwd !== \"string\" ||\n typeof record.lastUsedAt !== \"string\" ||\n typeof record.closed !== \"boolean\"\n ) {\n return undefined;\n }\n if (record.name !== undefined && typeof record.name !== \"string\") {\n return undefined;\n }\n return {\n file: record.file,\n acpxRecordId: record.acpxRecordId,\n acpSessionId: record.acpSessionId,\n agentCommand: record.agentCommand,\n cwd: record.cwd,\n name: record.name,\n closed: record.closed,\n lastUsedAt: record.lastUsedAt,\n };\n}\n\nexport function sessionIndexPath(sessionDir: string): string {\n return path.join(sessionDir, \"index.json\");\n}\n\nexport function toSessionIndexEntry(record: SessionRecord, fileName: string): SessionIndexEntry {\n return {\n file: fileName,\n acpxRecordId: record.acpxRecordId,\n acpSessionId: record.acpSessionId,\n agentCommand: record.agentCommand,\n cwd: record.cwd,\n name: record.name,\n closed: record.closed === true,\n lastUsedAt: record.lastUsedAt,\n };\n}\n\nexport async function readSessionIndex(sessionDir: string): Promise<SessionIndex | undefined> {\n const filePath = sessionIndexPath(sessionDir);\n try {\n const payload = await fs.readFile(filePath, \"utf8\");\n const parsed = JSON.parse(payload) as unknown;\n const record = asRecord(parsed);\n if (!record || record.schema !== SESSION_INDEX_SCHEMA || !Array.isArray(record.files)) {\n return undefined;\n }\n const files = record.files.filter((entry): entry is string => typeof entry === \"string\");\n if (files.length !== record.files.length || !Array.isArray(record.entries)) {\n return undefined;\n }\n const entries = record.entries\n .map((entry) => parseIndexEntry(entry))\n .filter((entry): entry is SessionIndexEntry => Boolean(entry));\n if (entries.length !== record.entries.length) {\n return undefined;\n }\n return {\n schema: SESSION_INDEX_SCHEMA,\n files,\n entries,\n };\n } catch {\n return undefined;\n }\n}\n\nexport async function writeSessionIndex(\n sessionDir: string,\n index: {\n files: string[];\n entries: SessionIndexEntry[];\n },\n): Promise<void> {\n const filePath = sessionIndexPath(sessionDir);\n const tempFile = `${filePath}.${process.pid}.${Date.now()}.tmp`;\n const payload = JSON.stringify(\n {\n schema: SESSION_INDEX_SCHEMA,\n files: [...index.files].toSorted(),\n entries: [...index.entries].toSorted((a, b) => b.lastUsedAt.localeCompare(a.lastUsedAt)),\n },\n null,\n 2,\n );\n await fs.writeFile(tempFile, `${payload}\\n`, \"utf8\");\n await fs.rename(tempFile, filePath);\n}\n\nexport async function rebuildSessionIndex(sessionDir: string): Promise<SessionIndex> {\n const entries = await fs.readdir(sessionDir, { withFileTypes: true });\n const files = entries\n .filter(\n (entry) => entry.isFile() && entry.name.endsWith(\".json\") && entry.name !== \"index.json\",\n )\n .map((entry) => entry.name)\n .toSorted();\n\n const indexEntries: SessionIndexEntry[] = [];\n for (const file of files) {\n try {\n const payload = await fs.readFile(path.join(sessionDir, file), \"utf8\");\n const parsed = parseSessionRecord(JSON.parse(payload));\n if (!parsed) {\n continue;\n }\n indexEntries.push(toSessionIndexEntry(parsed, file));\n } catch {\n // ignore corrupt session files while rebuilding the cache index\n }\n }\n\n const index: SessionIndex = {\n schema: SESSION_INDEX_SCHEMA,\n files,\n entries: indexEntries,\n };\n await writeSessionIndex(sessionDir, index);\n return index;\n}\n\nexport async function loadOrRebuildSessionIndex(sessionDir: string): Promise<SessionIndex> {\n const files = (await fs.readdir(sessionDir, { withFileTypes: true }))\n .filter(\n (entry) => entry.isFile() && entry.name.endsWith(\".json\") && entry.name !== \"index.json\",\n )\n .map((entry) => entry.name)\n .toSorted();\n const existing = await readSessionIndex(sessionDir);\n if (\n existing &&\n existing.files.length === files.length &&\n existing.files.every((file, index) => file === files[index])\n ) {\n return existing;\n }\n return await rebuildSessionIndex(sessionDir);\n}\n","import { statSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { SessionNotFoundError, SessionResolutionError } from \"../../errors.js\";\nimport { incrementPerfCounter, measurePerf } from \"../../perf-metrics.js\";\nimport { assertPersistedKeyPolicy } from \"../../persisted-key-policy.js\";\nimport type { SessionRecord } from \"../../types.js\";\nimport {\n loadOrRebuildSessionIndex,\n rebuildSessionIndex,\n toSessionIndexEntry,\n writeSessionIndex,\n type SessionIndexEntry,\n} from \"./index.js\";\nimport { parseSessionRecord } from \"./parse.js\";\nimport { serializeSessionRecordForDisk } from \"./serialize.js\";\n\nexport const DEFAULT_HISTORY_LIMIT = 20;\n\ntype FindSessionOptions = {\n agentCommand: string;\n cwd: string;\n name?: string;\n includeClosed?: boolean;\n};\n\ntype FindSessionByDirectoryWalkOptions = {\n agentCommand: string;\n cwd: string;\n name?: string;\n boundary?: string;\n};\n\nfunction sessionFilePath(acpxRecordId: string): string {\n const safeId = encodeURIComponent(acpxRecordId);\n return path.join(sessionBaseDir(), `${safeId}.json`);\n}\n\nfunction sessionBaseDir(): string {\n return path.join(os.homedir(), \".acpx\", \"sessions\");\n}\n\nasync function ensureSessionDir(): Promise<void> {\n await fs.mkdir(sessionBaseDir(), { recursive: true });\n}\n\nasync function loadRecordFromIndexEntry(\n entry: SessionIndexEntry,\n): Promise<SessionRecord | undefined> {\n try {\n const payload = await fs.readFile(path.join(sessionBaseDir(), entry.file), \"utf8\");\n return parseSessionRecord(JSON.parse(payload)) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function loadSessionIndexEntries(): Promise<SessionIndexEntry[]> {\n await ensureSessionDir();\n const index = await measurePerf(\"session.index_load\", async () => {\n return await loadOrRebuildSessionIndex(sessionBaseDir());\n });\n return index.entries;\n}\n\nfunction matchesSessionEntry(\n session: SessionIndexEntry,\n normalizedCwd: string,\n normalizedName: string | undefined,\n includeClosed = false,\n): boolean {\n if (session.cwd !== normalizedCwd) {\n return false;\n }\n if (!includeClosed && session.closed) {\n return false;\n }\n if (normalizedName == null) {\n return session.name == null;\n }\n return session.name === normalizedName;\n}\n\nexport async function writeSessionRecord(record: SessionRecord): Promise<void> {\n await measurePerf(\"session.write_record\", async () => {\n await ensureSessionDir();\n\n const persisted = serializeSessionRecordForDisk(record);\n assertPersistedKeyPolicy(persisted);\n\n const file = sessionFilePath(record.acpxRecordId);\n const tempFile = `${file}.${process.pid}.${Date.now()}.tmp`;\n const payload = JSON.stringify(persisted, null, 2);\n await fs.writeFile(tempFile, `${payload}\\n`, \"utf8\");\n await fs.rename(tempFile, file);\n\n const sessionDir = sessionBaseDir();\n const index = await loadOrRebuildSessionIndex(sessionDir);\n const fileName = path.basename(file);\n const entries = index.entries.filter((entry) => entry.file !== fileName);\n entries.push(toSessionIndexEntry(record, fileName));\n const files = [...new Set([...index.files.filter((entry) => entry !== fileName), fileName])];\n await writeSessionIndex(sessionDir, { files, entries });\n });\n}\n\nexport async function resolveSessionRecord(sessionId: string): Promise<SessionRecord> {\n await ensureSessionDir();\n\n const directPath = sessionFilePath(sessionId);\n try {\n const directPayload = await measurePerf(\"session.resolve_direct\", async () => {\n return await fs.readFile(directPath, \"utf8\");\n });\n const directRecord = parseSessionRecord(JSON.parse(directPayload));\n if (directRecord) {\n return directRecord;\n }\n } catch {\n // fallback to indexed search\n }\n\n const entries = await loadSessionIndexEntries();\n const exactEntries = entries.filter(\n (entry) => entry.acpxRecordId === sessionId || entry.acpSessionId === sessionId,\n );\n const exactRecords = (\n await Promise.all(exactEntries.map((entry) => loadRecordFromIndexEntry(entry)))\n ).filter((entry): entry is SessionRecord => Boolean(entry));\n if (exactRecords.length === 1) {\n return exactRecords[0];\n }\n if (exactRecords.length > 1) {\n throw new SessionResolutionError(`Multiple sessions match id: ${sessionId}`);\n }\n\n const suffixEntries = entries.filter(\n (entry) => entry.acpxRecordId.endsWith(sessionId) || entry.acpSessionId.endsWith(sessionId),\n );\n const suffixRecords = (\n await Promise.all(suffixEntries.map((entry) => loadRecordFromIndexEntry(entry)))\n ).filter((entry): entry is SessionRecord => Boolean(entry));\n if (suffixRecords.length === 1) {\n return suffixRecords[0];\n }\n if (suffixRecords.length > 1) {\n throw new SessionResolutionError(`Session id is ambiguous: ${sessionId}`);\n }\n\n incrementPerfCounter(\"session.resolve_miss\");\n throw new SessionNotFoundError(sessionId);\n}\n\nfunction hasGitDirectory(dir: string): boolean {\n const gitPath = path.join(dir, \".git\");\n try {\n return statSync(gitPath).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isWithinBoundary(boundary: string, target: string): boolean {\n const relative = path.relative(boundary, target);\n return relative.length === 0 || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nexport function absolutePath(value: string): string {\n return path.resolve(value);\n}\n\nexport function findGitRepositoryRoot(startDir: string): string | undefined {\n let current = absolutePath(startDir);\n const root = path.parse(current).root;\n\n for (;;) {\n if (hasGitDirectory(current)) {\n return current;\n }\n\n if (current === root) {\n return undefined;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n return undefined;\n }\n current = parent;\n }\n}\n\nexport function normalizeName(value: string | undefined): string | undefined {\n if (value == null) {\n return undefined;\n }\n\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function isoNow(): string {\n return new Date().toISOString();\n}\n\nexport async function listSessions(): Promise<SessionRecord[]> {\n await ensureSessionDir();\n const entries = await loadSessionIndexEntries();\n const records: SessionRecord[] = [];\n\n for (const entry of entries) {\n const parsed = await loadRecordFromIndexEntry(entry);\n if (parsed) {\n records.push(parsed);\n }\n }\n\n records.sort((a, b) => b.lastUsedAt.localeCompare(a.lastUsedAt));\n return records;\n}\n\nexport async function listSessionsForAgent(agentCommand: string): Promise<SessionRecord[]> {\n const entries = (await loadSessionIndexEntries()).filter(\n (session) => session.agentCommand === agentCommand,\n );\n const records = await Promise.all(entries.map((entry) => loadRecordFromIndexEntry(entry)));\n return records\n .filter((entry): entry is SessionRecord => Boolean(entry))\n .toSorted((a, b) => b.lastUsedAt.localeCompare(a.lastUsedAt));\n}\n\nexport async function findSession(options: FindSessionOptions): Promise<SessionRecord | undefined> {\n const normalizedCwd = absolutePath(options.cwd);\n const normalizedName = normalizeName(options.name);\n const entries = await loadSessionIndexEntries();\n const match = entries.find(\n (session) =>\n session.agentCommand === options.agentCommand &&\n matchesSessionEntry(session, normalizedCwd, normalizedName, options.includeClosed),\n );\n if (!match) {\n return undefined;\n }\n return await loadRecordFromIndexEntry(match);\n}\n\nexport async function findSessionByDirectoryWalk(\n options: FindSessionByDirectoryWalkOptions,\n): Promise<SessionRecord | undefined> {\n const normalizedName = normalizeName(options.name);\n const normalizedStart = absolutePath(options.cwd);\n const normalizedBoundary = absolutePath(options.boundary ?? normalizedStart);\n const walkBoundary = isWithinBoundary(normalizedBoundary, normalizedStart)\n ? normalizedBoundary\n : normalizedStart;\n const sessions = (await loadSessionIndexEntries()).filter(\n (session) => session.agentCommand === options.agentCommand,\n );\n\n let current = normalizedStart;\n const walkRoot = path.parse(current).root;\n\n for (;;) {\n const match = sessions.find((session) => matchesSessionEntry(session, current, normalizedName));\n if (match) {\n return await loadRecordFromIndexEntry(match);\n }\n\n if (current === walkBoundary || current === walkRoot) {\n return undefined;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n return undefined;\n }\n\n current = parent;\n\n if (!isWithinBoundary(walkBoundary, current)) {\n return undefined;\n }\n }\n}\n\nfunction killSignalCandidates(signal: NodeJS.Signals | undefined): NodeJS.Signals[] {\n if (!signal) {\n return [\"SIGTERM\", \"SIGKILL\"];\n }\n\n const normalized = signal.toUpperCase() as NodeJS.Signals;\n if (normalized === \"SIGKILL\") {\n return [\"SIGKILL\"];\n }\n\n return [normalized, \"SIGKILL\"];\n}\n\nexport async function closeSession(id: string): Promise<SessionRecord> {\n const record = await resolveSessionRecord(id);\n const now = isoNow();\n\n if (record.pid) {\n for (const signal of killSignalCandidates(record.lastAgentExitSignal ?? undefined)) {\n try {\n process.kill(record.pid, signal);\n } catch {\n // ignore\n }\n }\n }\n\n record.closed = true;\n record.closedAt = now;\n record.pid = undefined;\n record.lastUsedAt = now;\n record.lastPromptAt = record.lastPromptAt ?? now;\n\n await writeSessionRecord(record);\n await rebuildSessionIndex(sessionBaseDir()).catch(() => {\n // best effort cache rebuild\n });\n return record;\n}\n","import readline from \"node:readline/promises\";\n\nexport type PermissionPromptOptions = {\n prompt: string;\n header?: string;\n details?: string;\n};\n\nexport async function promptForPermission(options: PermissionPromptOptions): Promise<boolean> {\n if (!process.stdin.isTTY || !process.stderr.isTTY) {\n return false;\n }\n\n if (options.header) {\n process.stderr.write(`\\n${options.header}\\n`);\n }\n if (options.details && options.details.trim().length > 0) {\n process.stderr.write(`${options.details}\\n`);\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n try {\n const answer = await rl.question(options.prompt);\n const normalized = answer.trim().toLowerCase();\n return normalized === \"y\" || normalized === \"yes\";\n } finally {\n rl.close();\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n ReadTextFileRequest,\n ReadTextFileResponse,\n WriteTextFileRequest,\n WriteTextFileResponse,\n} from \"@agentclientprotocol/sdk\";\nimport { PermissionDeniedError, PermissionPromptUnavailableError } from \"./errors.js\";\nimport { promptForPermission } from \"./permission-prompt.js\";\nimport type { ClientOperation, NonInteractivePermissionPolicy, PermissionMode } from \"./types.js\";\n\nconst WRITE_PREVIEW_MAX_LINES = 16;\nconst WRITE_PREVIEW_MAX_CHARS = 1_200;\n\nexport type FileSystemHandlersOptions = {\n cwd: string;\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n onOperation?: (operation: ClientOperation) => void;\n confirmWrite?: (filePath: string, preview: string) => Promise<boolean>;\n};\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction isWithinRoot(rootDir: string, targetPath: string): boolean {\n const relative = path.relative(rootDir, targetPath);\n return relative.length === 0 || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction toWritePreview(content: string): string {\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n const lines = normalized.split(\"\\n\");\n const visibleLines = lines.slice(0, WRITE_PREVIEW_MAX_LINES);\n let preview = visibleLines.join(\"\\n\");\n\n if (lines.length > visibleLines.length) {\n preview += `\\n... (${lines.length - visibleLines.length} more lines)`;\n }\n\n if (preview.length > WRITE_PREVIEW_MAX_CHARS) {\n preview = `${preview.slice(0, WRITE_PREVIEW_MAX_CHARS - 3)}...`;\n }\n\n return preview;\n}\n\nasync function defaultConfirmWrite(filePath: string, preview: string): Promise<boolean> {\n return await promptForPermission({\n header: `[permission] Allow write to ${filePath}?`,\n details: preview,\n prompt: \"Allow write? (y/N) \",\n });\n}\n\nfunction canPromptForPermission(): boolean {\n return Boolean(process.stdin.isTTY && process.stderr.isTTY);\n}\n\nexport class FileSystemHandlers {\n private readonly rootDir: string;\n private permissionMode: PermissionMode;\n private nonInteractivePermissions: NonInteractivePermissionPolicy;\n private readonly onOperation?: (operation: ClientOperation) => void;\n private readonly usesDefaultConfirmWrite: boolean;\n private readonly confirmWrite: (filePath: string, preview: string) => Promise<boolean>;\n\n constructor(options: FileSystemHandlersOptions) {\n this.rootDir = path.resolve(options.cwd);\n this.permissionMode = options.permissionMode;\n this.nonInteractivePermissions = options.nonInteractivePermissions ?? \"deny\";\n this.onOperation = options.onOperation;\n this.usesDefaultConfirmWrite = options.confirmWrite == null;\n this.confirmWrite = options.confirmWrite ?? defaultConfirmWrite;\n }\n\n updatePermissionPolicy(\n permissionMode: PermissionMode,\n nonInteractivePermissions?: NonInteractivePermissionPolicy,\n ): void {\n this.permissionMode = permissionMode;\n this.nonInteractivePermissions = nonInteractivePermissions ?? \"deny\";\n }\n\n async readTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse> {\n const filePath = this.resolvePathWithinRoot(params.path);\n const summary = `read_text_file: ${filePath}`;\n this.emitOperation({\n method: \"fs/read_text_file\",\n status: \"running\",\n summary,\n details: this.readWindowDetails(params.line, params.limit),\n timestamp: nowIso(),\n });\n\n try {\n if (this.permissionMode === \"deny-all\") {\n throw new PermissionDeniedError(\"Permission denied for fs/read_text_file (--deny-all)\");\n }\n\n const content = await fs.readFile(filePath, \"utf8\");\n const sliced = this.sliceContent(content, params.line, params.limit);\n\n this.emitOperation({\n method: \"fs/read_text_file\",\n status: \"completed\",\n summary,\n details: this.readWindowDetails(params.line, params.limit),\n timestamp: nowIso(),\n });\n return { content: sliced };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.emitOperation({\n method: \"fs/read_text_file\",\n status: \"failed\",\n summary,\n details: message,\n timestamp: nowIso(),\n });\n throw error;\n }\n }\n\n async writeTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse> {\n const filePath = this.resolvePathWithinRoot(params.path);\n const preview = toWritePreview(params.content);\n const summary = `write_text_file: ${filePath}`;\n\n this.emitOperation({\n method: \"fs/write_text_file\",\n status: \"running\",\n summary,\n details: preview,\n timestamp: nowIso(),\n });\n\n try {\n if (!(await this.isWriteApproved(filePath, preview))) {\n throw new PermissionDeniedError(\"Permission denied for fs/write_text_file\");\n }\n\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, params.content, \"utf8\");\n\n this.emitOperation({\n method: \"fs/write_text_file\",\n status: \"completed\",\n summary,\n details: preview,\n timestamp: nowIso(),\n });\n return {};\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.emitOperation({\n method: \"fs/write_text_file\",\n status: \"failed\",\n summary,\n details: message,\n timestamp: nowIso(),\n });\n throw error;\n }\n }\n\n private async isWriteApproved(filePath: string, preview: string): Promise<boolean> {\n if (this.permissionMode === \"approve-all\") {\n return true;\n }\n if (this.permissionMode === \"deny-all\") {\n return false;\n }\n if (\n this.usesDefaultConfirmWrite &&\n this.nonInteractivePermissions === \"fail\" &&\n !canPromptForPermission()\n ) {\n throw new PermissionPromptUnavailableError();\n }\n return await this.confirmWrite(filePath, preview);\n }\n\n private resolvePathWithinRoot(rawPath: string): string {\n if (!path.isAbsolute(rawPath)) {\n throw new Error(`Path must be absolute: ${rawPath}`);\n }\n const resolved = path.resolve(rawPath);\n if (!isWithinRoot(this.rootDir, resolved)) {\n throw new Error(`Path is outside allowed cwd subtree: ${resolved}`);\n }\n return resolved;\n }\n\n private sliceContent(\n content: string,\n line: number | null | undefined,\n limit: number | null | undefined,\n ): string {\n if (line == null && limit == null) {\n return content;\n }\n\n const lines = content.split(\"\\n\");\n const startLine = line == null ? 1 : Math.max(1, Math.trunc(line));\n const startIndex = Math.max(0, startLine - 1);\n const maxLines = limit == null ? undefined : Math.max(0, Math.trunc(limit));\n\n if (maxLines === 0) {\n return \"\";\n }\n\n const endIndex =\n maxLines == null ? lines.length : Math.min(lines.length, startIndex + maxLines);\n\n return lines.slice(startIndex, endIndex).join(\"\\n\");\n }\n\n private readWindowDetails(\n line: number | null | undefined,\n limit: number | null | undefined,\n ): string | undefined {\n if (line == null && limit == null) {\n return undefined;\n }\n const start = line == null ? 1 : Math.max(1, Math.trunc(line));\n const max = limit == null ? \"all\" : Math.max(0, Math.trunc(limit));\n return `line=${start}, limit=${max}`;\n }\n\n private emitOperation(operation: ClientOperation): void {\n this.onOperation?.(operation);\n }\n}\n","import {\n type PermissionOption,\n type RequestPermissionRequest,\n type RequestPermissionResponse,\n type ToolKind,\n} from \"@agentclientprotocol/sdk\";\nimport { PermissionPromptUnavailableError } from \"./errors.js\";\nimport { promptForPermission } from \"./permission-prompt.js\";\nimport type { NonInteractivePermissionPolicy, PermissionMode } from \"./types.js\";\n\ntype PermissionDecision = \"approved\" | \"denied\" | \"cancelled\";\nconst PERMISSION_MODE_RANK: Record<PermissionMode, number> = {\n \"deny-all\": 0,\n \"approve-reads\": 1,\n \"approve-all\": 2,\n};\n\nfunction selected(optionId: string): RequestPermissionResponse {\n return { outcome: { outcome: \"selected\", optionId } };\n}\n\nfunction cancelled(): RequestPermissionResponse {\n return { outcome: { outcome: \"cancelled\" } };\n}\n\nfunction pickOption(\n options: PermissionOption[],\n kinds: PermissionOption[\"kind\"][],\n): PermissionOption | undefined {\n for (const kind of kinds) {\n const match = options.find((option) => option.kind === kind);\n if (match) {\n return match;\n }\n }\n return undefined;\n}\n\nfunction inferToolKind(params: RequestPermissionRequest): ToolKind | undefined {\n if (params.toolCall.kind) {\n return params.toolCall.kind;\n }\n\n const title = params.toolCall.title?.trim().toLowerCase();\n if (!title) {\n return undefined;\n }\n\n const head = title.split(\":\", 1)[0]?.trim();\n if (!head) {\n return undefined;\n }\n\n if (head.includes(\"read\") || head.includes(\"cat\")) {\n return \"read\";\n }\n if (head.includes(\"search\") || head.includes(\"find\") || head.includes(\"grep\")) {\n return \"search\";\n }\n if (head.includes(\"write\") || head.includes(\"edit\") || head.includes(\"patch\")) {\n return \"edit\";\n }\n if (head.includes(\"delete\") || head.includes(\"remove\")) {\n return \"delete\";\n }\n if (head.includes(\"move\") || head.includes(\"rename\")) {\n return \"move\";\n }\n if (head.includes(\"run\") || head.includes(\"execute\") || head.includes(\"bash\")) {\n return \"execute\";\n }\n if (head.includes(\"fetch\") || head.includes(\"http\") || head.includes(\"url\")) {\n return \"fetch\";\n }\n if (head.includes(\"think\")) {\n return \"think\";\n }\n\n return \"other\";\n}\n\nfunction isAutoApprovedReadKind(kind: ToolKind | undefined): boolean {\n return kind === \"read\" || kind === \"search\";\n}\n\nasync function promptForToolPermission(params: RequestPermissionRequest): Promise<boolean> {\n const toolName = params.toolCall.title ?? \"tool\";\n const toolKind = inferToolKind(params) ?? \"other\";\n return await promptForPermission({\n prompt: `\\n[permission] Allow ${toolName} [${toolKind}]? (y/N) `,\n });\n}\n\nfunction canPromptForPermission(): boolean {\n return Boolean(process.stdin.isTTY && process.stderr.isTTY);\n}\n\nexport function permissionModeSatisfies(actual: PermissionMode, required: PermissionMode): boolean {\n return PERMISSION_MODE_RANK[actual] >= PERMISSION_MODE_RANK[required];\n}\n\nexport async function resolvePermissionRequest(\n params: RequestPermissionRequest,\n mode: PermissionMode,\n nonInteractivePolicy: NonInteractivePermissionPolicy = \"deny\",\n): Promise<RequestPermissionResponse> {\n const options = params.options ?? [];\n if (options.length === 0) {\n return cancelled();\n }\n\n const allowOption = pickOption(options, [\"allow_once\", \"allow_always\"]);\n const rejectOption = pickOption(options, [\"reject_once\", \"reject_always\"]);\n\n if (mode === \"approve-all\") {\n if (allowOption) {\n return selected(allowOption.optionId);\n }\n return selected(options[0].optionId);\n }\n\n if (mode === \"deny-all\") {\n if (rejectOption) {\n return selected(rejectOption.optionId);\n }\n return cancelled();\n }\n\n const kind = inferToolKind(params);\n if (isAutoApprovedReadKind(kind) && allowOption) {\n return selected(allowOption.optionId);\n }\n\n if (!canPromptForPermission()) {\n if (nonInteractivePolicy === \"fail\") {\n throw new PermissionPromptUnavailableError();\n }\n if (rejectOption) {\n return selected(rejectOption.optionId);\n }\n return cancelled();\n }\n\n const approved = await promptForToolPermission(params);\n if (approved && allowOption) {\n return selected(allowOption.optionId);\n }\n if (!approved && rejectOption) {\n return selected(rejectOption.optionId);\n }\n return cancelled();\n}\n\nexport function classifyPermissionDecision(\n params: RequestPermissionRequest,\n response: RequestPermissionResponse,\n): PermissionDecision {\n if (response.outcome.outcome !== \"selected\") {\n return \"cancelled\";\n }\n\n const selectedOptionId = response.outcome.optionId;\n const selectedOption = params.options.find((option) => option.optionId === selectedOptionId);\n\n if (!selectedOption) {\n return \"cancelled\";\n }\n\n if (selectedOption.kind === \"allow_once\" || selectedOption.kind === \"allow_always\") {\n return \"approved\";\n }\n\n return \"denied\";\n}\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nfunction readWindowsEnvValue(env: NodeJS.ProcessEnv, key: string): string | undefined {\n const matchedKey = Object.keys(env).find((entry) => entry.toUpperCase() === key);\n return matchedKey ? env[matchedKey] : undefined;\n}\n\nfunction resolveWindowsCommand(\n command: string,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n const extensions = (readWindowsEnvValue(env, \"PATHEXT\") ?? \".COM;.EXE;.BAT;.CMD\")\n .split(\";\")\n .map((value) => value.trim().toLowerCase())\n .filter((value) => value.length > 0);\n const commandExtension = path.extname(command);\n const candidates =\n commandExtension.length > 0\n ? [command]\n : extensions.map((extension) => `${command}${extension}`);\n const hasPath = command.includes(\"/\") || command.includes(\"\\\\\") || path.isAbsolute(command);\n\n if (hasPath) {\n return candidates.find((candidate) => fs.existsSync(candidate));\n }\n\n const pathValue = readWindowsEnvValue(env, \"PATH\");\n if (!pathValue) {\n return undefined;\n }\n\n for (const directory of pathValue.split(\";\")) {\n const trimmedDirectory = directory.trim();\n if (trimmedDirectory.length === 0) {\n continue;\n }\n for (const candidate of candidates) {\n const resolved = path.join(trimmedDirectory, candidate);\n if (fs.existsSync(resolved)) {\n return resolved;\n }\n }\n }\n\n return undefined;\n}\n\nfunction shouldUseWindowsBatchShell(\n command: string,\n platform: NodeJS.Platform = process.platform,\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n if (platform !== \"win32\") {\n return false;\n }\n const resolvedCommand = resolveWindowsCommand(command, env) ?? command;\n const ext = path.extname(resolvedCommand).toLowerCase();\n return ext === \".cmd\" || ext === \".bat\";\n}\n\nexport function buildSpawnCommandOptions(\n command: string,\n options: Parameters<typeof spawn>[2],\n platform: NodeJS.Platform = process.platform,\n env: NodeJS.ProcessEnv = process.env,\n): Parameters<typeof spawn>[2] {\n if (!shouldUseWindowsBatchShell(command, platform, env)) {\n return options;\n }\n return {\n ...options,\n shell: true,\n };\n}\n","import type { ChildProcess, ChildProcessByStdio } from \"node:child_process\";\nimport path from \"node:path\";\nimport { Readable, Writable } from \"node:stream\";\n\nexport type CommandParts = {\n command: string;\n args: string[];\n};\n\nexport function isoNow(): string {\n return new Date().toISOString();\n}\n\nexport function waitForSpawn(child: ChildProcess): Promise<void> {\n return new Promise((resolve, reject) => {\n const onSpawn = () => {\n child.off(\"error\", onError);\n resolve();\n };\n const onError = (error: Error) => {\n child.off(\"spawn\", onSpawn);\n reject(error);\n };\n\n child.once(\"spawn\", onSpawn);\n child.once(\"error\", onError);\n });\n}\n\nexport function isChildProcessRunning(child: ChildProcess): boolean {\n return child.exitCode == null && child.signalCode == null;\n}\n\nexport function requireAgentStdio(\n child: ChildProcess,\n): ChildProcessByStdio<Writable, Readable, Readable> {\n if (!child.stdin || !child.stdout || !child.stderr) {\n throw new Error(\"ACP agent must be spawned with piped stdin/stdout/stderr\");\n }\n return child as ChildProcessByStdio<Writable, Readable, Readable>;\n}\n\nexport function waitForChildExit(\n child: ChildProcessByStdio<Writable, Readable, Readable>,\n timeoutMs: number,\n): Promise<boolean> {\n if (!isChildProcessRunning(child)) {\n return Promise.resolve(true);\n }\n\n return new Promise<boolean>((resolve) => {\n let settled = false;\n const timer = setTimeout(\n () => {\n finish(false);\n },\n Math.max(0, timeoutMs),\n );\n\n const finish = (value: boolean) => {\n if (settled) {\n return;\n }\n settled = true;\n child.off(\"close\", onExitLike);\n child.off(\"exit\", onExitLike);\n clearTimeout(timer);\n resolve(value);\n };\n\n const onExitLike = () => {\n finish(true);\n };\n\n child.once(\"close\", onExitLike);\n child.once(\"exit\", onExitLike);\n });\n}\n\nexport function splitCommandLine(value: string): CommandParts {\n const parts: string[] = [];\n let current = \"\";\n let quote: \"'\" | '\"' | null = null;\n let escaping = false;\n\n for (const ch of value) {\n if (escaping) {\n current += ch;\n escaping = false;\n continue;\n }\n\n if (ch === \"\\\\\" && quote !== \"'\") {\n escaping = true;\n continue;\n }\n\n if (quote) {\n if (ch === quote) {\n quote = null;\n } else {\n current += ch;\n }\n continue;\n }\n\n if (ch === \"'\" || ch === '\"') {\n quote = ch;\n continue;\n }\n\n if (/\\s/.test(ch)) {\n if (current.length > 0) {\n parts.push(current);\n current = \"\";\n }\n continue;\n }\n\n current += ch;\n }\n\n if (escaping) {\n current += \"\\\\\";\n }\n\n if (quote) {\n throw new Error(\"Invalid --agent command: unterminated quote\");\n }\n\n if (current.length > 0) {\n parts.push(current);\n }\n\n if (parts.length === 0) {\n throw new Error(\"Invalid --agent command: empty command\");\n }\n\n return {\n command: parts[0],\n args: parts.slice(1),\n };\n}\n\nexport function asAbsoluteCwd(cwd: string): string {\n return path.resolve(cwd);\n}\n\nexport function basenameToken(value: string): string {\n return path\n .basename(value)\n .toLowerCase()\n .replace(/\\.(cmd|exe|bat)$/u, \"\");\n}\n","import { spawn } from \"node:child_process\";\nimport { CopilotAcpUnsupportedError } from \"../errors.js\";\nimport { buildSpawnCommandOptions } from \"../spawn-command-options.js\";\nimport { type AcpClientOptions } from \"../types.js\";\nimport { basenameToken, splitCommandLine } from \"./client-process.js\";\n\nconst DEFAULT_AGENT_CLOSE_AFTER_STDIN_END_MS = 100;\nconst QODER_AGENT_CLOSE_AFTER_STDIN_END_MS = 750;\nconst GEMINI_ACP_STARTUP_TIMEOUT_MS = 15_000;\nconst CLAUDE_ACP_SESSION_CREATE_TIMEOUT_MS = 60_000;\nconst GEMINI_VERSION_TIMEOUT_MS = 2_000;\nconst GEMINI_ACP_FLAG_VERSION = [0, 33, 0] as const;\nconst COPILOT_HELP_TIMEOUT_MS = 2_000;\n\ntype GeminiVersion = {\n raw: string;\n parts: [number, number, number];\n};\n\nconst QODER_BENIGN_STDOUT_LINES = new Set([\n \"Received interrupt signal. Cleaning up resources...\",\n \"Cleanup completed. Exiting...\",\n]);\n\nexport function resolveAgentCloseAfterStdinEndMs(agentCommand: string): number {\n const { command } = splitCommandLine(agentCommand);\n return basenameToken(command) === \"qodercli\"\n ? QODER_AGENT_CLOSE_AFTER_STDIN_END_MS\n : DEFAULT_AGENT_CLOSE_AFTER_STDIN_END_MS;\n}\n\nexport function shouldIgnoreNonJsonAgentOutputLine(\n agentCommand: string,\n trimmedLine: string,\n): boolean {\n const { command } = splitCommandLine(agentCommand);\n return basenameToken(command) === \"qodercli\" && QODER_BENIGN_STDOUT_LINES.has(trimmedLine);\n}\n\nexport function isGeminiAcpCommand(command: string, args: readonly string[]): boolean {\n return (\n basenameToken(command) === \"gemini\" &&\n (args.includes(\"--acp\") || args.includes(\"--experimental-acp\"))\n );\n}\n\nexport function isClaudeAcpCommand(command: string, args: readonly string[]): boolean {\n const commandToken = basenameToken(command);\n if (commandToken === \"claude-agent-acp\") {\n return true;\n }\n return args.some((arg) => arg.includes(\"claude-agent-acp\"));\n}\n\nexport function isCopilotAcpCommand(command: string, args: readonly string[]): boolean {\n return basenameToken(command) === \"copilot\" && args.includes(\"--acp\");\n}\n\nexport function isQoderAcpCommand(command: string, args: readonly string[]): boolean {\n return basenameToken(command) === \"qodercli\" && args.includes(\"--acp\");\n}\n\nfunction hasCommandFlag(args: readonly string[], flagName: string): boolean {\n return args.some((arg) => arg === flagName || arg.startsWith(`${flagName}=`));\n}\n\nfunction normalizeQoderAllowedToolName(tool: string): string {\n switch (tool.trim().toLowerCase()) {\n case \"bash\":\n case \"glob\":\n case \"grep\":\n case \"ls\":\n case \"read\":\n case \"write\":\n return tool.trim().toUpperCase();\n default:\n return tool.trim();\n }\n}\n\nexport function buildQoderAcpCommandArgs(\n initialArgs: readonly string[],\n options: Pick<AcpClientOptions, \"sessionOptions\">,\n): string[] {\n const args = [...initialArgs];\n const sessionOptions = options.sessionOptions;\n\n if (typeof sessionOptions?.maxTurns === \"number\" && !hasCommandFlag(args, \"--max-turns\")) {\n args.push(`--max-turns=${sessionOptions.maxTurns}`);\n }\n\n if (\n Array.isArray(sessionOptions?.allowedTools) &&\n !hasCommandFlag(args, \"--allowed-tools\") &&\n !hasCommandFlag(args, \"--disallowed-tools\")\n ) {\n const encodedTools = sessionOptions.allowedTools.map(normalizeQoderAllowedToolName).join(\",\");\n args.push(`--allowed-tools=${encodedTools}`);\n }\n\n return args;\n}\n\nexport function resolveGeminiAcpStartupTimeoutMs(): number {\n const raw = process.env.ACPX_GEMINI_ACP_STARTUP_TIMEOUT_MS;\n if (typeof raw === \"string\" && raw.trim().length > 0) {\n const parsed = Number(raw);\n if (Number.isFinite(parsed) && parsed > 0) {\n return Math.round(parsed);\n }\n }\n return GEMINI_ACP_STARTUP_TIMEOUT_MS;\n}\n\nexport function resolveClaudeAcpSessionCreateTimeoutMs(): number {\n const raw = process.env.ACPX_CLAUDE_ACP_SESSION_CREATE_TIMEOUT_MS;\n if (typeof raw === \"string\" && raw.trim().length > 0) {\n const parsed = Number(raw);\n if (Number.isFinite(parsed) && parsed > 0) {\n return Math.round(parsed);\n }\n }\n return CLAUDE_ACP_SESSION_CREATE_TIMEOUT_MS;\n}\n\nfunction parseGeminiVersion(value: string | undefined): GeminiVersion | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n\n const normalized = value.trim();\n const match = normalized.match(/(\\d+)\\.(\\d+)\\.(\\d+)/);\n if (!match) {\n return undefined;\n }\n\n return {\n raw: normalized,\n parts: [Number(match[1]), Number(match[2]), Number(match[3])],\n };\n}\n\nfunction compareVersionParts(left: readonly number[], right: readonly number[]): number {\n for (let index = 0; index < Math.max(left.length, right.length); index += 1) {\n const leftPart = left[index] ?? 0;\n const rightPart = right[index] ?? 0;\n if (leftPart !== rightPart) {\n return leftPart - rightPart;\n }\n }\n return 0;\n}\n\nasync function detectGeminiVersion(command: string): Promise<GeminiVersion | undefined> {\n return await new Promise<GeminiVersion | undefined>((resolve) => {\n const child = spawn(\n command,\n [\"--version\"],\n buildSpawnCommandOptions(command, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n }),\n );\n\n let stdout = \"\";\n let stderr = \"\";\n let settled = false;\n const finish = (value: GeminiVersion | undefined) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n child.removeAllListeners();\n child.stdout?.removeAllListeners();\n child.stderr?.removeAllListeners();\n resolve(value);\n };\n const timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n finish(undefined);\n }, GEMINI_VERSION_TIMEOUT_MS);\n\n child.stdout?.setEncoding(\"utf8\");\n child.stderr?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n child.once(\"error\", () => {\n finish(undefined);\n });\n child.once(\"close\", () => {\n const versionLine = `${stdout}\\n${stderr}`\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .find((line) => /\\d+\\.\\d+\\.\\d+/.test(line));\n finish(parseGeminiVersion(versionLine));\n });\n });\n}\n\nexport async function resolveGeminiCommandArgs(\n command: string,\n args: readonly string[],\n): Promise<string[]> {\n if (basenameToken(command) !== \"gemini\" || !args.includes(\"--acp\")) {\n return [...args];\n }\n\n const version = await detectGeminiVersion(command);\n if (version && compareVersionParts(version.parts, GEMINI_ACP_FLAG_VERSION) < 0) {\n return args.map((arg) => (arg === \"--acp\" ? \"--experimental-acp\" : arg));\n }\n\n return [...args];\n}\n\nasync function readCommandOutput(\n command: string,\n args: readonly string[],\n timeoutMs: number,\n): Promise<string | undefined> {\n return await new Promise<string | undefined>((resolve) => {\n const child = spawn(\n command,\n [...args],\n buildSpawnCommandOptions(command, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n }),\n );\n\n let stdout = \"\";\n let stderr = \"\";\n let settled = false;\n const finish = (value: string | undefined) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n child.removeAllListeners();\n child.stdout?.removeAllListeners();\n child.stderr?.removeAllListeners();\n resolve(value);\n };\n const timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n finish(undefined);\n }, timeoutMs);\n\n child.stdout?.setEncoding(\"utf8\");\n child.stderr?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n child.once(\"error\", () => {\n finish(undefined);\n });\n child.once(\"close\", () => {\n finish(`${stdout}\\n${stderr}`);\n });\n });\n}\n\nexport async function buildGeminiAcpStartupTimeoutMessage(command: string): Promise<string> {\n const parts = [\n \"Gemini CLI ACP startup timed out before initialize completed.\",\n \"This usually means the local Gemini CLI is waiting on interactive OAuth or has incompatible ACP subprocess behavior.\",\n ];\n\n const version = await detectGeminiVersion(command);\n if (version) {\n parts.push(`Detected Gemini CLI version: ${version.raw}.`);\n }\n\n if (!process.env.GEMINI_API_KEY && !process.env.GOOGLE_API_KEY) {\n parts.push(\"No GEMINI_API_KEY or GOOGLE_API_KEY was set for non-interactive auth.\");\n }\n\n parts.push(\"Try upgrading Gemini CLI and using API-key-based auth for non-interactive ACP runs.\");\n return parts.join(\" \");\n}\n\nexport function buildClaudeAcpSessionCreateTimeoutMessage(): string {\n return [\n \"Claude ACP session creation timed out before session/new completed.\",\n \"This matches the known persistent-session stall seen with some Claude Code and @agentclientprotocol/claude-agent-acp combinations.\",\n \"In harnessed or non-interactive runs, prefer --approve-all with nonInteractivePermissions=deny, upgrade Claude Code and the Claude ACP adapter, or use acpx claude exec as a one-shot fallback.\",\n ].join(\" \");\n}\n\nasync function buildCopilotAcpUnsupportedMessage(command: string): Promise<string> {\n const parts = [\n \"GitHub Copilot CLI ACP stdio mode is not available in the installed copilot binary.\",\n \"acpx copilot expects a Copilot CLI release that supports --acp --stdio.\",\n ];\n\n const helpOutput = await readCommandOutput(command, [\"--help\"], COPILOT_HELP_TIMEOUT_MS);\n if (typeof helpOutput === \"string\" && !helpOutput.includes(\"--acp\")) {\n parts.push(\"Detected copilot --help output without --acp support.\");\n }\n\n parts.push(\n \"Upgrade GitHub Copilot CLI to a release with ACP stdio support, or use --agent with another ACP-compatible adapter in the meantime.\",\n );\n return parts.join(\" \");\n}\n\nexport async function ensureCopilotAcpSupport(command: string): Promise<void> {\n const helpOutput = await readCommandOutput(command, [\"--help\"], COPILOT_HELP_TIMEOUT_MS);\n if (typeof helpOutput === \"string\" && !helpOutput.includes(\"--acp\")) {\n throw new CopilotAcpUnsupportedError(await buildCopilotAcpUnsupportedMessage(command), {\n retryable: false,\n });\n }\n}\n\nexport function buildClaudeCodeOptionsMeta(\n options: AcpClientOptions[\"sessionOptions\"],\n): Record<string, unknown> | undefined {\n if (!options) {\n return undefined;\n }\n\n const claudeCodeOptions: Record<string, unknown> = {};\n if (typeof options.model === \"string\" && options.model.trim().length > 0) {\n claudeCodeOptions.model = options.model;\n }\n if (Array.isArray(options.allowedTools)) {\n claudeCodeOptions.allowedTools = [...options.allowedTools];\n }\n if (typeof options.maxTurns === \"number\") {\n claudeCodeOptions.maxTurns = options.maxTurns;\n }\n\n if (Object.keys(claudeCodeOptions).length === 0) {\n return undefined;\n }\n\n return {\n claudeCode: {\n options: claudeCodeOptions,\n },\n };\n}\n","import type { AcpClientOptions } from \"../types.js\";\n\nfunction toEnvToken(value: string): string {\n return value\n .trim()\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .toUpperCase();\n}\n\nfunction buildAuthEnvKeys(methodId: string): string[] {\n const token = toEnvToken(methodId);\n const keys = new Set<string>([methodId]);\n if (token) {\n keys.add(token);\n keys.add(`ACPX_AUTH_${token}`);\n }\n return [...keys];\n}\n\nconst authEnvKeysCache = new Map<string, string[]>();\n\nfunction authEnvKeys(methodId: string): string[] {\n const cached = authEnvKeysCache.get(methodId);\n if (cached) {\n return cached;\n }\n const keys = buildAuthEnvKeys(methodId);\n authEnvKeysCache.set(methodId, keys);\n return keys;\n}\n\nexport function readEnvCredential(methodId: string): string | undefined {\n for (const key of authEnvKeys(methodId)) {\n const value = process.env[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction buildAgentEnvironment(\n authCredentials: Record<string, string> | undefined,\n): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = { ...process.env };\n if (!authCredentials) {\n return env;\n }\n\n for (const [methodId, credential] of Object.entries(authCredentials)) {\n if (typeof credential !== \"string\" || credential.trim().length === 0) {\n continue;\n }\n\n if (!methodId.includes(\"=\") && !methodId.includes(\"\\u0000\") && env[methodId] == null) {\n env[methodId] = credential;\n }\n\n const normalized = toEnvToken(methodId);\n if (normalized) {\n const prefixed = `ACPX_AUTH_${normalized}`;\n if (env[prefixed] == null) {\n env[prefixed] = credential;\n }\n if (env[normalized] == null) {\n env[normalized] = credential;\n }\n }\n }\n\n return env;\n}\n\nexport function resolveConfiguredAuthCredential(\n methodId: string,\n authCredentials: AcpClientOptions[\"authCredentials\"],\n): string | undefined {\n const configCredentials = authCredentials ?? {};\n return configCredentials[methodId] ?? configCredentials[toEnvToken(methodId)];\n}\n\nexport function buildAgentSpawnOptions(\n cwd: string,\n authCredentials: Record<string, string> | undefined,\n): {\n cwd: string;\n env: NodeJS.ProcessEnv;\n stdio: [\"pipe\", \"pipe\", \"pipe\"];\n windowsHide: true;\n} {\n return {\n cwd,\n env: buildAgentEnvironment(authCredentials),\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n windowsHide: true,\n };\n}\n","import { extractAcpError } from \"./error-shapes.js\";\n\nconst SESSION_CONTROL_UNSUPPORTED_ACP_CODES = new Set([-32601, -32602]);\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction isLikelySessionControlUnsupportedError(acp: {\n code: number;\n message: string;\n data?: unknown;\n}): boolean {\n if (SESSION_CONTROL_UNSUPPORTED_ACP_CODES.has(acp.code)) {\n return true;\n }\n\n if (acp.code !== -32603) {\n return false;\n }\n\n const details = asRecord(acp.data)?.details;\n return typeof details === \"string\" && details.toLowerCase().includes(\"invalid params\");\n}\n\nexport function formatSessionControlAcpSummary(acp: {\n code: number;\n message: string;\n data?: unknown;\n}): string {\n const details = asRecord(acp.data)?.details;\n if (typeof details === \"string\" && details.trim().length > 0) {\n return `${details.trim()} (ACP ${acp.code}, adapter reported \"${acp.message}\")`;\n }\n return `${acp.message} (ACP ${acp.code})`;\n}\n\nexport function maybeWrapSessionControlError(\n method: \"session/set_mode\" | \"session/set_config_option\" | \"session/set_model\",\n error: unknown,\n context?: string,\n): unknown {\n const acp = extractAcpError(error);\n if (!acp || !isLikelySessionControlUnsupportedError(acp)) {\n return error;\n }\n\n const acpSummary = formatSessionControlAcpSummary(acp);\n const contextSuffix = context ? ` ${context}` : \"\";\n const message =\n `Agent rejected ${method}${contextSuffix}: ${acpSummary}. ` +\n `The adapter may not implement ${method}, or the requested value is not supported.`;\n const wrapped = new Error(message, {\n cause: error instanceof Error ? error : undefined,\n }) as Error & {\n acp?: typeof acp;\n };\n wrapped.acp = acp;\n return wrapped;\n}\n","import { spawn, type ChildProcessByStdio } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport type { Readable } from \"node:stream\";\nimport type {\n CreateTerminalRequest,\n CreateTerminalResponse,\n KillTerminalRequest,\n KillTerminalResponse,\n ReleaseTerminalRequest,\n ReleaseTerminalResponse,\n TerminalOutputRequest,\n TerminalOutputResponse,\n WaitForTerminalExitRequest,\n WaitForTerminalExitResponse,\n} from \"@agentclientprotocol/sdk\";\nimport { PermissionDeniedError, PermissionPromptUnavailableError } from \"../errors.js\";\nimport { promptForPermission } from \"../permission-prompt.js\";\nimport { buildSpawnCommandOptions } from \"../spawn-command-options.js\";\nimport type { ClientOperation, NonInteractivePermissionPolicy, PermissionMode } from \"../types.js\";\n\nconst DEFAULT_TERMINAL_OUTPUT_LIMIT_BYTES = 64 * 1024;\nconst DEFAULT_KILL_GRACE_MS = 1_500;\n\ntype ManagedTerminal = {\n process: ChildProcessByStdio<null, Readable, Readable>;\n output: Buffer;\n truncated: boolean;\n outputByteLimit: number;\n exitCode: number | null | undefined;\n signal: NodeJS.Signals | null | undefined;\n exitPromise: Promise<WaitForTerminalExitResponse>;\n resolveExit: (response: WaitForTerminalExitResponse) => void;\n};\n\nexport type TerminalManagerOptions = {\n cwd: string;\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n onOperation?: (operation: ClientOperation) => void;\n confirmExecute?: (commandLine: string) => Promise<boolean>;\n killGraceMs?: number;\n};\n\ntype TerminalSpawnOptions = {\n cwd: string;\n env: NodeJS.ProcessEnv | undefined;\n stdio: [\"ignore\", \"pipe\", \"pipe\"];\n shell?: true;\n windowsHide: true;\n};\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction toCommandLine(command: string, args: string[] | undefined): string {\n const renderedArgs = (args ?? []).map((arg) => JSON.stringify(arg)).join(\" \");\n return renderedArgs.length > 0 ? `${command} ${renderedArgs}` : command;\n}\n\nfunction toEnvObject(env: CreateTerminalRequest[\"env\"]): NodeJS.ProcessEnv | undefined {\n if (!env || env.length === 0) {\n return undefined;\n }\n\n const merged: NodeJS.ProcessEnv = { ...process.env };\n for (const entry of env) {\n merged[entry.name] = entry.value;\n }\n return merged;\n}\n\nexport function buildTerminalSpawnOptions(\n command: string,\n cwd: string,\n env: CreateTerminalRequest[\"env\"],\n platform: NodeJS.Platform = process.platform,\n): TerminalSpawnOptions {\n const resolvedEnv = toEnvObject(env);\n const options: TerminalSpawnOptions = {\n cwd,\n env: resolvedEnv,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n };\n return buildSpawnCommandOptions(\n command,\n options,\n platform,\n resolvedEnv ?? process.env,\n ) as TerminalSpawnOptions;\n}\n\nfunction trimToUtf8Boundary(buffer: Buffer, limit: number): Buffer {\n if (limit <= 0) {\n return Buffer.alloc(0);\n }\n if (buffer.length <= limit) {\n return buffer;\n }\n\n let start = buffer.length - limit;\n while (start < buffer.length && (buffer[start] & 0b1100_0000) === 0b1000_0000) {\n start += 1;\n }\n\n if (start >= buffer.length) {\n start = buffer.length - limit;\n }\n return buffer.subarray(start);\n}\n\nfunction waitForSpawn(process: ChildProcessByStdio<null, Readable, Readable>): Promise<void> {\n return new Promise((resolve, reject) => {\n const onSpawn = () => {\n process.off(\"error\", onError);\n resolve();\n };\n const onError = (error: Error) => {\n process.off(\"spawn\", onSpawn);\n reject(error);\n };\n\n process.once(\"spawn\", onSpawn);\n process.once(\"error\", onError);\n });\n}\n\nasync function defaultConfirmExecute(commandLine: string): Promise<boolean> {\n return await promptForPermission({\n prompt: `\\n[permission] Allow terminal command \"${commandLine}\"? (y/N) `,\n });\n}\n\nfunction canPromptForPermission(): boolean {\n return Boolean(process.stdin.isTTY && process.stderr.isTTY);\n}\n\nfunction waitMs(ms: number): Promise<void> {\n return new Promise<void>((resolve) => {\n setTimeout(resolve, Math.max(0, ms));\n });\n}\n\nexport class TerminalManager {\n private readonly cwd: string;\n private permissionMode: PermissionMode;\n private nonInteractivePermissions: NonInteractivePermissionPolicy;\n private readonly onOperation?: (operation: ClientOperation) => void;\n private readonly usesDefaultConfirmExecute: boolean;\n private readonly confirmExecute: (commandLine: string) => Promise<boolean>;\n private readonly killGraceMs: number;\n private readonly terminals = new Map<string, ManagedTerminal>();\n\n constructor(options: TerminalManagerOptions) {\n this.cwd = options.cwd;\n this.permissionMode = options.permissionMode;\n this.nonInteractivePermissions = options.nonInteractivePermissions ?? \"deny\";\n this.onOperation = options.onOperation;\n this.usesDefaultConfirmExecute = options.confirmExecute == null;\n this.confirmExecute = options.confirmExecute ?? defaultConfirmExecute;\n this.killGraceMs = Math.max(0, Math.round(options.killGraceMs ?? DEFAULT_KILL_GRACE_MS));\n }\n\n updatePermissionPolicy(\n permissionMode: PermissionMode,\n nonInteractivePermissions?: NonInteractivePermissionPolicy,\n ): void {\n this.permissionMode = permissionMode;\n this.nonInteractivePermissions = nonInteractivePermissions ?? \"deny\";\n }\n\n async createTerminal(params: CreateTerminalRequest): Promise<CreateTerminalResponse> {\n const commandLine = toCommandLine(params.command, params.args);\n const summary = `terminal/create: ${commandLine}`;\n\n this.emitOperation({\n method: \"terminal/create\",\n status: \"running\",\n summary,\n timestamp: nowIso(),\n });\n\n try {\n if (!(await this.isExecuteApproved(commandLine))) {\n throw new PermissionDeniedError(\"Permission denied for terminal/create\");\n }\n\n const outputByteLimit = Math.max(\n 0,\n Math.round(params.outputByteLimit ?? DEFAULT_TERMINAL_OUTPUT_LIMIT_BYTES),\n );\n const proc = spawn(\n params.command,\n params.args ?? [],\n buildTerminalSpawnOptions(params.command, params.cwd ?? this.cwd, params.env),\n );\n await waitForSpawn(proc);\n\n let resolveExit: (response: WaitForTerminalExitResponse) => void = () => {};\n const exitPromise = new Promise<WaitForTerminalExitResponse>((resolve) => {\n resolveExit = resolve;\n });\n\n const terminal: ManagedTerminal = {\n process: proc,\n output: Buffer.alloc(0),\n truncated: false,\n outputByteLimit,\n exitCode: undefined,\n signal: undefined,\n exitPromise,\n resolveExit,\n };\n\n const appendOutput = (chunk: Buffer | string): void => {\n const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n if (bytes.length === 0) {\n return;\n }\n\n terminal.output = Buffer.concat([terminal.output, bytes]);\n if (terminal.output.length > terminal.outputByteLimit) {\n terminal.output = trimToUtf8Boundary(terminal.output, terminal.outputByteLimit);\n terminal.truncated = true;\n }\n };\n\n proc.stdout.on(\"data\", appendOutput);\n proc.stderr.on(\"data\", appendOutput);\n proc.once(\"exit\", (exitCode, signal) => {\n terminal.exitCode = exitCode;\n terminal.signal = signal;\n terminal.resolveExit({\n exitCode: exitCode ?? null,\n signal: signal ?? null,\n });\n });\n\n const terminalId = randomUUID();\n this.terminals.set(terminalId, terminal);\n\n this.emitOperation({\n method: \"terminal/create\",\n status: \"completed\",\n summary,\n details: `terminalId=${terminalId}`,\n timestamp: nowIso(),\n });\n return { terminalId };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.emitOperation({\n method: \"terminal/create\",\n status: \"failed\",\n summary,\n details: message,\n timestamp: nowIso(),\n });\n throw error;\n }\n }\n\n async terminalOutput(params: TerminalOutputRequest): Promise<TerminalOutputResponse> {\n const terminal = this.getTerminal(params.terminalId);\n if (!terminal) {\n throw new Error(`Unknown terminal: ${params.terminalId}`);\n }\n\n const hasExitStatus = terminal.exitCode !== undefined || terminal.signal !== undefined;\n\n this.emitOperation({\n method: \"terminal/output\",\n status: \"completed\",\n summary: `terminal/output: ${params.terminalId}`,\n timestamp: nowIso(),\n });\n\n return {\n output: terminal.output.toString(\"utf8\"),\n truncated: terminal.truncated,\n exitStatus: hasExitStatus\n ? {\n exitCode: terminal.exitCode ?? null,\n signal: terminal.signal ?? null,\n }\n : undefined,\n };\n }\n\n async waitForTerminalExit(\n params: WaitForTerminalExitRequest,\n ): Promise<WaitForTerminalExitResponse> {\n const terminal = this.getTerminal(params.terminalId);\n if (!terminal) {\n throw new Error(`Unknown terminal: ${params.terminalId}`);\n }\n\n const response = await terminal.exitPromise;\n this.emitOperation({\n method: \"terminal/wait_for_exit\",\n status: \"completed\",\n summary: `terminal/wait_for_exit: ${params.terminalId}`,\n details: `exitCode=${response.exitCode ?? \"null\"}, signal=${response.signal ?? \"null\"}`,\n timestamp: nowIso(),\n });\n return response;\n }\n\n async killTerminal(params: KillTerminalRequest): Promise<KillTerminalResponse> {\n const terminal = this.getTerminal(params.terminalId);\n if (!terminal) {\n throw new Error(`Unknown terminal: ${params.terminalId}`);\n }\n\n const summary = `terminal/kill: ${params.terminalId}`;\n this.emitOperation({\n method: \"terminal/kill\",\n status: \"running\",\n summary,\n timestamp: nowIso(),\n });\n\n try {\n await this.killProcess(terminal);\n this.emitOperation({\n method: \"terminal/kill\",\n status: \"completed\",\n summary,\n timestamp: nowIso(),\n });\n return {};\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.emitOperation({\n method: \"terminal/kill\",\n status: \"failed\",\n summary,\n details: message,\n timestamp: nowIso(),\n });\n throw error;\n }\n }\n\n async releaseTerminal(params: ReleaseTerminalRequest): Promise<ReleaseTerminalResponse> {\n const summary = `terminal/release: ${params.terminalId}`;\n this.emitOperation({\n method: \"terminal/release\",\n status: \"running\",\n summary,\n timestamp: nowIso(),\n });\n\n const terminal = this.getTerminal(params.terminalId);\n if (!terminal) {\n this.emitOperation({\n method: \"terminal/release\",\n status: \"completed\",\n summary,\n details: \"already released\",\n timestamp: nowIso(),\n });\n return {};\n }\n\n try {\n await this.killProcess(terminal);\n await terminal.exitPromise.catch(() => {\n // ignore best-effort wait failures\n });\n terminal.output = Buffer.alloc(0);\n this.terminals.delete(params.terminalId);\n\n this.emitOperation({\n method: \"terminal/release\",\n status: \"completed\",\n summary,\n timestamp: nowIso(),\n });\n return {};\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.emitOperation({\n method: \"terminal/release\",\n status: \"failed\",\n summary,\n details: message,\n timestamp: nowIso(),\n });\n throw error;\n }\n }\n\n async shutdown(): Promise<void> {\n for (const terminalId of Array.from(this.terminals.keys())) {\n await this.releaseTerminal({ terminalId, sessionId: \"shutdown\" });\n }\n }\n\n private getTerminal(terminalId: string): ManagedTerminal | undefined {\n return this.terminals.get(terminalId);\n }\n\n private emitOperation(operation: ClientOperation): void {\n this.onOperation?.(operation);\n }\n\n private async isExecuteApproved(commandLine: string): Promise<boolean> {\n if (this.permissionMode === \"approve-all\") {\n return true;\n }\n if (this.permissionMode === \"deny-all\") {\n return false;\n }\n if (\n this.usesDefaultConfirmExecute &&\n this.nonInteractivePermissions === \"fail\" &&\n !canPromptForPermission()\n ) {\n throw new PermissionPromptUnavailableError();\n }\n return await this.confirmExecute(commandLine);\n }\n\n private isRunning(terminal: ManagedTerminal): boolean {\n return terminal.exitCode === undefined && terminal.signal === undefined;\n }\n\n private async killProcess(terminal: ManagedTerminal): Promise<void> {\n if (!this.isRunning(terminal)) {\n return;\n }\n\n try {\n terminal.process.kill(\"SIGTERM\");\n } catch {\n return;\n }\n\n const exitedAfterTerm = await Promise.race([\n terminal.exitPromise.then(() => true),\n waitMs(this.killGraceMs).then(() => false),\n ]);\n\n if (exitedAfterTerm || !this.isRunning(terminal)) {\n return;\n }\n\n try {\n terminal.process.kill(\"SIGKILL\");\n } catch {\n return;\n }\n\n await Promise.race([terminal.exitPromise.then(() => undefined), waitMs(this.killGraceMs)]);\n }\n}\n","import { spawn, type ChildProcess, type ChildProcessByStdio } from \"node:child_process\";\nimport { Readable, Writable } from \"node:stream\";\nimport {\n ClientSideConnection,\n PROTOCOL_VERSION,\n type AnyMessage,\n type AuthMethod,\n type CreateTerminalRequest,\n type CreateTerminalResponse,\n type InitializeResponse,\n type KillTerminalRequest,\n type KillTerminalResponse,\n type LoadSessionResponse,\n type PromptResponse,\n type ReadTextFileRequest,\n type ReadTextFileResponse,\n type ReleaseTerminalRequest,\n type ReleaseTerminalResponse,\n type RequestPermissionRequest,\n type RequestPermissionResponse,\n type SessionNotification,\n type SetSessionConfigOptionResponse,\n type TerminalOutputRequest,\n type TerminalOutputResponse,\n type WaitForTerminalExitRequest,\n type WaitForTerminalExitResponse,\n type WriteTextFileRequest,\n type WriteTextFileResponse,\n type SessionModelState,\n} from \"@agentclientprotocol/sdk\";\nimport { TimeoutError, withTimeout } from \"../async-control.js\";\nimport {\n AgentDisconnectedError,\n AgentSpawnError,\n AuthPolicyError,\n ClaudeAcpSessionCreateTimeoutError,\n GeminiAcpStartupTimeoutError,\n PermissionDeniedError,\n PermissionPromptUnavailableError,\n} from \"../errors.js\";\nimport { FileSystemHandlers } from \"../filesystem.js\";\nimport { classifyPermissionDecision, resolvePermissionRequest } from \"../permissions.js\";\nimport { textPrompt } from \"../prompt-content.js\";\nimport { extractRuntimeSessionId } from \"../session/runtime-session-id.js\";\nimport { buildSpawnCommandOptions } from \"../spawn-command-options.js\";\nimport type {\n AcpClientOptions,\n NonInteractivePermissionPolicy,\n PermissionMode,\n PermissionStats,\n PromptInput,\n} from \"../types.js\";\nimport {\n buildClaudeAcpSessionCreateTimeoutMessage,\n buildClaudeCodeOptionsMeta,\n buildGeminiAcpStartupTimeoutMessage,\n buildQoderAcpCommandArgs,\n ensureCopilotAcpSupport,\n isClaudeAcpCommand,\n isCopilotAcpCommand,\n isGeminiAcpCommand,\n isQoderAcpCommand,\n resolveAgentCloseAfterStdinEndMs,\n resolveClaudeAcpSessionCreateTimeoutMs,\n resolveGeminiAcpStartupTimeoutMs,\n resolveGeminiCommandArgs,\n shouldIgnoreNonJsonAgentOutputLine,\n} from \"./agent-command.js\";\nimport {\n buildAgentSpawnOptions,\n readEnvCredential,\n resolveConfiguredAuthCredential,\n} from \"./auth-env.js\";\nimport {\n asAbsoluteCwd,\n isoNow,\n isChildProcessRunning,\n requireAgentStdio,\n splitCommandLine,\n waitForChildExit,\n waitForSpawn,\n} from \"./client-process.js\";\nimport { extractAcpError } from \"./error-shapes.js\";\nimport { isSessionUpdateNotification } from \"./jsonrpc.js\";\nimport {\n formatSessionControlAcpSummary,\n maybeWrapSessionControlError,\n} from \"./session-control-errors.js\";\nimport { TerminalManager } from \"./terminal-manager.js\";\n\nexport { buildSpawnCommandOptions };\nexport {\n buildAgentSpawnOptions,\n buildQoderAcpCommandArgs,\n resolveAgentCloseAfterStdinEndMs,\n shouldIgnoreNonJsonAgentOutputLine,\n};\n\nconst REPLAY_IDLE_MS = 80;\nconst REPLAY_DRAIN_TIMEOUT_MS = 5_000;\nconst DRAIN_POLL_INTERVAL_MS = 20;\nconst AGENT_CLOSE_TERM_GRACE_MS = 1_500;\nconst AGENT_CLOSE_KILL_GRACE_MS = 1_000;\n\ntype LoadSessionOptions = {\n suppressReplayUpdates?: boolean;\n replayIdleMs?: number;\n replayDrainTimeoutMs?: number;\n};\n\nexport type SessionCreateResult = {\n sessionId: string;\n agentSessionId?: string;\n models?: SessionModelState;\n};\n\nexport type SessionLoadResult = {\n agentSessionId?: string;\n models?: SessionModelState;\n};\n\ntype AgentDisconnectReason = \"process_exit\" | \"process_close\" | \"pipe_close\" | \"connection_close\";\n\ntype PendingConnectionRequest = {\n settled: boolean;\n reject: (error: unknown) => void;\n};\n\ntype AuthSelection = {\n methodId: string;\n credential: string;\n source: \"env\" | \"config\";\n};\n\nexport type AgentExitInfo = {\n exitCode: number | null;\n signal: NodeJS.Signals | null;\n exitedAt: string;\n reason: AgentDisconnectReason;\n unexpectedDuringPrompt: boolean;\n};\n\nexport type AgentLifecycleSnapshot = {\n pid?: number;\n startedAt?: string;\n running: boolean;\n lastExit?: AgentExitInfo;\n};\n\ntype ConsoleErrorMethod = typeof console.error;\n\nfunction shouldSuppressSdkConsoleError(args: unknown[]): boolean {\n if (args.length === 0) {\n return false;\n }\n return typeof args[0] === \"string\" && args[0] === \"Error handling request\";\n}\n\nfunction installSdkConsoleErrorSuppression(): () => void {\n const originalConsoleError: ConsoleErrorMethod = console.error;\n console.error = (...args: unknown[]) => {\n if (shouldSuppressSdkConsoleError(args)) {\n return;\n }\n originalConsoleError(...args);\n };\n return () => {\n console.error = originalConsoleError;\n };\n}\n\nfunction createNdJsonMessageStream(\n agentCommand: string,\n output: WritableStream<Uint8Array>,\n input: ReadableStream<Uint8Array>,\n): {\n readable: ReadableStream<AnyMessage>;\n writable: WritableStream<AnyMessage>;\n} {\n const textEncoder = new TextEncoder();\n const textDecoder = new TextDecoder();\n\n const readable = new ReadableStream<AnyMessage>({\n async start(controller) {\n let content = \"\";\n const reader = input.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n break;\n }\n if (!value) {\n continue;\n }\n content += textDecoder.decode(value, { stream: true });\n const lines = content.split(\"\\n\");\n content = lines.pop() || \"\";\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (!trimmedLine || shouldIgnoreNonJsonAgentOutputLine(agentCommand, trimmedLine)) {\n continue;\n }\n try {\n const message = JSON.parse(trimmedLine) as AnyMessage;\n controller.enqueue(message);\n } catch (err) {\n console.error(\"Failed to parse JSON message:\", trimmedLine, err);\n }\n }\n }\n } finally {\n reader.releaseLock();\n controller.close();\n }\n },\n });\n\n const writable = new WritableStream<AnyMessage>({\n async write(message) {\n const content = JSON.stringify(message) + \"\\n\";\n const writer = output.getWriter();\n try {\n await writer.write(textEncoder.encode(content));\n } finally {\n writer.releaseLock();\n }\n },\n });\n\n return { readable, writable };\n}\n\nexport class AcpClient {\n private options: AcpClientOptions;\n private connection?: ClientSideConnection;\n private agent?: ChildProcessByStdio<Writable, Readable, Readable>;\n private initResult?: InitializeResponse;\n private loadedSessionId?: string;\n private eventHandlers: Pick<\n AcpClientOptions,\n \"onAcpMessage\" | \"onAcpOutputMessage\" | \"onSessionUpdate\" | \"onClientOperation\"\n >;\n private readonly permissionStats: PermissionStats = {\n requested: 0,\n approved: 0,\n denied: 0,\n cancelled: 0,\n };\n private readonly filesystem: FileSystemHandlers;\n private readonly terminalManager: TerminalManager;\n private sessionUpdateChain: Promise<void> = Promise.resolve();\n private observedSessionUpdates = 0;\n private processedSessionUpdates = 0;\n private suppressSessionUpdates = false;\n private suppressReplaySessionUpdateMessages = false;\n private activePrompt?: {\n sessionId: string;\n promise: Promise<PromptResponse>;\n };\n private readonly cancellingSessionIds = new Set<string>();\n private closing = false;\n private agentStartedAt?: string;\n private lastAgentExit?: AgentExitInfo;\n private lastKnownPid?: number;\n private readonly promptPermissionFailures = new Map<string, PermissionPromptUnavailableError>();\n private readonly pendingConnectionRequests = new Set<PendingConnectionRequest>();\n\n constructor(options: AcpClientOptions) {\n this.options = {\n ...options,\n cwd: asAbsoluteCwd(options.cwd),\n authPolicy: options.authPolicy ?? \"skip\",\n };\n this.eventHandlers = {\n onAcpMessage: this.options.onAcpMessage,\n onAcpOutputMessage: this.options.onAcpOutputMessage,\n onSessionUpdate: this.options.onSessionUpdate,\n onClientOperation: this.options.onClientOperation,\n };\n\n this.filesystem = new FileSystemHandlers({\n cwd: this.options.cwd,\n permissionMode: this.options.permissionMode,\n nonInteractivePermissions: this.options.nonInteractivePermissions,\n onOperation: (operation) => {\n this.eventHandlers.onClientOperation?.(operation);\n },\n });\n this.terminalManager = new TerminalManager({\n cwd: this.options.cwd,\n permissionMode: this.options.permissionMode,\n nonInteractivePermissions: this.options.nonInteractivePermissions,\n onOperation: (operation) => {\n this.eventHandlers.onClientOperation?.(operation);\n },\n });\n }\n\n get initializeResult(): InitializeResponse | undefined {\n return this.initResult;\n }\n\n getAgentPid(): number | undefined {\n return this.agent?.pid ?? this.lastKnownPid;\n }\n\n getPermissionStats(): PermissionStats {\n return { ...this.permissionStats };\n }\n\n getAgentLifecycleSnapshot(): AgentLifecycleSnapshot {\n const pid = this.agent?.pid ?? this.lastKnownPid;\n const running =\n Boolean(this.agent) &&\n this.agent?.exitCode == null &&\n this.agent?.signalCode == null &&\n !this.agent?.killed;\n return {\n pid,\n startedAt: this.agentStartedAt,\n running,\n lastExit: this.lastAgentExit ? { ...this.lastAgentExit } : undefined,\n };\n }\n\n supportsLoadSession(): boolean {\n return Boolean(this.initResult?.agentCapabilities?.loadSession);\n }\n\n setEventHandlers(\n handlers: Pick<\n AcpClientOptions,\n \"onAcpMessage\" | \"onAcpOutputMessage\" | \"onSessionUpdate\" | \"onClientOperation\"\n >,\n ): void {\n this.eventHandlers = { ...handlers };\n }\n\n clearEventHandlers(): void {\n this.eventHandlers = {};\n }\n\n updateRuntimeOptions(options: {\n permissionMode?: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n suppressSdkConsoleErrors?: boolean;\n verbose?: boolean;\n }): void {\n if (options.permissionMode) {\n this.options.permissionMode = options.permissionMode;\n }\n if (options.nonInteractivePermissions !== undefined) {\n this.options.nonInteractivePermissions = options.nonInteractivePermissions;\n }\n if (options.permissionMode || options.nonInteractivePermissions !== undefined) {\n this.filesystem.updatePermissionPolicy(\n this.options.permissionMode,\n this.options.nonInteractivePermissions,\n );\n this.terminalManager.updatePermissionPolicy(\n this.options.permissionMode,\n this.options.nonInteractivePermissions,\n );\n }\n if (options.suppressSdkConsoleErrors !== undefined) {\n this.options.suppressSdkConsoleErrors = options.suppressSdkConsoleErrors;\n }\n if (options.verbose !== undefined) {\n this.options.verbose = options.verbose;\n }\n }\n\n hasReusableSession(sessionId: string): boolean {\n return (\n this.connection != null &&\n this.agent != null &&\n isChildProcessRunning(this.agent) &&\n this.loadedSessionId === sessionId\n );\n }\n\n hasActivePrompt(sessionId?: string): boolean {\n if (!this.activePrompt) {\n return false;\n }\n if (sessionId == null) {\n return true;\n }\n return this.activePrompt.sessionId === sessionId;\n }\n\n async start(): Promise<void> {\n if (this.connection && this.agent && isChildProcessRunning(this.agent)) {\n return;\n }\n if (this.connection || this.agent) {\n await this.close();\n }\n\n const { command, args: initialArgs } = splitCommandLine(this.options.agentCommand);\n let args = await resolveGeminiCommandArgs(command, initialArgs);\n if (isQoderAcpCommand(command, args)) {\n args = buildQoderAcpCommandArgs(args, this.options);\n }\n this.log(`spawning agent: ${command} ${args.join(\" \")}`);\n const geminiAcp = isGeminiAcpCommand(command, args);\n const copilotAcp = isCopilotAcpCommand(command, args);\n\n if (copilotAcp) {\n await ensureCopilotAcpSupport(command);\n }\n\n const spawnedChild = spawn(\n command,\n args,\n buildSpawnCommandOptions(\n command,\n buildAgentSpawnOptions(this.options.cwd, this.options.authCredentials),\n ),\n ) as ChildProcessByStdio<Writable, Readable, Readable>;\n\n try {\n await waitForSpawn(spawnedChild);\n } catch (error) {\n throw new AgentSpawnError(this.options.agentCommand, error);\n }\n const child = requireAgentStdio(spawnedChild);\n this.closing = false;\n this.agentStartedAt = isoNow();\n this.lastAgentExit = undefined;\n this.lastKnownPid = child.pid ?? undefined;\n this.attachAgentLifecycleObservers(child);\n\n child.stderr.on(\"data\", (chunk: Buffer | string) => {\n if (!this.options.verbose) {\n return;\n }\n process.stderr.write(chunk);\n });\n\n const input = Writable.toWeb(child.stdin);\n const output = Readable.toWeb(child.stdout) as ReadableStream<Uint8Array>;\n const stream = this.createTappedStream(\n createNdJsonMessageStream(this.options.agentCommand, input, output),\n );\n\n const connection = new ClientSideConnection(\n () => ({\n sessionUpdate: async (params: SessionNotification) => {\n await this.handleSessionUpdate(params);\n },\n requestPermission: async (\n params: RequestPermissionRequest,\n ): Promise<RequestPermissionResponse> => {\n return this.handlePermissionRequest(params);\n },\n readTextFile: async (params: ReadTextFileRequest): Promise<ReadTextFileResponse> => {\n return this.handleReadTextFile(params);\n },\n writeTextFile: async (params: WriteTextFileRequest): Promise<WriteTextFileResponse> => {\n return this.handleWriteTextFile(params);\n },\n createTerminal: async (params: CreateTerminalRequest): Promise<CreateTerminalResponse> => {\n return this.handleCreateTerminal(params);\n },\n terminalOutput: async (params: TerminalOutputRequest): Promise<TerminalOutputResponse> => {\n return this.handleTerminalOutput(params);\n },\n waitForTerminalExit: async (\n params: WaitForTerminalExitRequest,\n ): Promise<WaitForTerminalExitResponse> => {\n return this.handleWaitForTerminalExit(params);\n },\n killTerminal: async (params: KillTerminalRequest): Promise<KillTerminalResponse> => {\n return this.handleKillTerminal(params);\n },\n releaseTerminal: async (\n params: ReleaseTerminalRequest,\n ): Promise<ReleaseTerminalResponse> => {\n return this.handleReleaseTerminal(params);\n },\n }),\n stream,\n );\n connection.signal.addEventListener(\n \"abort\",\n () => {\n this.recordAgentExit(\"connection_close\", child.exitCode ?? null, child.signalCode ?? null);\n },\n { once: true },\n );\n\n try {\n const initializePromise = connection.initialize({\n protocolVersion: PROTOCOL_VERSION,\n clientCapabilities: {\n fs: {\n readTextFile: true,\n writeTextFile: true,\n },\n terminal: true,\n },\n clientInfo: {\n name: \"acpx\",\n version: \"0.1.0\",\n },\n });\n const initResult = geminiAcp\n ? await withTimeout(initializePromise, resolveGeminiAcpStartupTimeoutMs())\n : await initializePromise;\n\n await this.authenticateIfRequired(connection, initResult.authMethods ?? []);\n\n this.connection = connection;\n this.agent = child;\n this.initResult = initResult;\n this.log(`initialized protocol version ${initResult.protocolVersion}`);\n } catch (error) {\n child.kill();\n if (geminiAcp && error instanceof TimeoutError) {\n throw new GeminiAcpStartupTimeoutError(await buildGeminiAcpStartupTimeoutMessage(command), {\n cause: error,\n retryable: true,\n });\n }\n throw error;\n }\n }\n\n private createTappedStream(base: {\n readable: ReadableStream<AnyMessage>;\n writable: WritableStream<AnyMessage>;\n }): {\n readable: ReadableStream<AnyMessage>;\n writable: WritableStream<AnyMessage>;\n } {\n const onAcpMessage = () => this.eventHandlers.onAcpMessage;\n const onAcpOutputMessage = () => this.eventHandlers.onAcpOutputMessage;\n\n const shouldSuppressInboundReplaySessionUpdate = (message: AnyMessage): boolean => {\n return this.suppressReplaySessionUpdateMessages && isSessionUpdateNotification(message);\n };\n\n const readable = new ReadableStream<AnyMessage>({\n async start(controller) {\n const reader = base.readable.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n break;\n }\n if (!value) {\n continue;\n }\n if (!shouldSuppressInboundReplaySessionUpdate(value)) {\n onAcpOutputMessage()?.(\"inbound\", value);\n onAcpMessage()?.(\"inbound\", value);\n }\n controller.enqueue(value);\n }\n } finally {\n reader.releaseLock();\n controller.close();\n }\n },\n });\n\n const writable = new WritableStream<AnyMessage>({\n async write(message) {\n onAcpOutputMessage()?.(\"outbound\", message);\n onAcpMessage()?.(\"outbound\", message);\n const writer = base.writable.getWriter();\n try {\n await writer.write(message);\n } finally {\n writer.releaseLock();\n }\n },\n });\n\n return { readable, writable };\n }\n\n async createSession(cwd = this.options.cwd): Promise<SessionCreateResult> {\n const connection = this.getConnection();\n const { command, args } = splitCommandLine(this.options.agentCommand);\n const claudeAcp = isClaudeAcpCommand(command, args);\n\n let result: Awaited<ReturnType<typeof connection.newSession>>;\n try {\n const createPromise = this.runConnectionRequest(() =>\n connection.newSession({\n cwd: asAbsoluteCwd(cwd),\n mcpServers: this.options.mcpServers ?? [],\n _meta: buildClaudeCodeOptionsMeta(this.options.sessionOptions),\n }),\n );\n result = claudeAcp\n ? await withTimeout(createPromise, resolveClaudeAcpSessionCreateTimeoutMs())\n : await createPromise;\n } catch (error) {\n if (claudeAcp && error instanceof TimeoutError) {\n throw new ClaudeAcpSessionCreateTimeoutError(buildClaudeAcpSessionCreateTimeoutMessage(), {\n cause: error,\n retryable: true,\n });\n }\n throw error;\n }\n\n this.loadedSessionId = result.sessionId;\n\n return {\n sessionId: result.sessionId,\n agentSessionId: extractRuntimeSessionId(result._meta),\n models: result.models ?? undefined,\n };\n }\n\n async loadSession(sessionId: string, cwd = this.options.cwd): Promise<SessionLoadResult> {\n this.getConnection();\n return await this.loadSessionWithOptions(sessionId, cwd, {});\n }\n\n async loadSessionWithOptions(\n sessionId: string,\n cwd = this.options.cwd,\n options: LoadSessionOptions = {},\n ): Promise<SessionLoadResult> {\n const connection = this.getConnection();\n const previousSuppression = this.suppressSessionUpdates;\n const previousReplaySuppression = this.suppressReplaySessionUpdateMessages;\n this.suppressSessionUpdates = previousSuppression || Boolean(options.suppressReplayUpdates);\n this.suppressReplaySessionUpdateMessages =\n previousReplaySuppression || Boolean(options.suppressReplayUpdates);\n\n let response: LoadSessionResponse | undefined;\n\n try {\n response = await this.runConnectionRequest(() =>\n connection.loadSession({\n sessionId,\n cwd: asAbsoluteCwd(cwd),\n mcpServers: this.options.mcpServers ?? [],\n }),\n );\n\n await this.waitForSessionUpdateDrain(\n options.replayIdleMs ?? REPLAY_IDLE_MS,\n options.replayDrainTimeoutMs ?? REPLAY_DRAIN_TIMEOUT_MS,\n );\n } finally {\n this.suppressSessionUpdates = previousSuppression;\n this.suppressReplaySessionUpdateMessages = previousReplaySuppression;\n }\n\n this.loadedSessionId = sessionId;\n\n return {\n agentSessionId: extractRuntimeSessionId(response?._meta),\n models: response?.models ?? undefined,\n };\n }\n\n async prompt(sessionId: string, prompt: PromptInput | string): Promise<PromptResponse> {\n const connection = this.getConnection();\n const restoreConsoleError = this.options.suppressSdkConsoleErrors\n ? installSdkConsoleErrorSuppression()\n : undefined;\n\n let promptPromise: Promise<PromptResponse>;\n try {\n promptPromise = this.runConnectionRequest(() =>\n connection.prompt({\n sessionId,\n prompt: typeof prompt === \"string\" ? textPrompt(prompt) : prompt,\n }),\n );\n } catch (error) {\n restoreConsoleError?.();\n throw error;\n }\n\n this.activePrompt = {\n sessionId,\n promise: promptPromise,\n };\n\n try {\n const response = await promptPromise;\n const permissionFailure = this.consumePromptPermissionFailure(sessionId);\n if (permissionFailure) {\n throw permissionFailure;\n }\n return response;\n } catch (error) {\n const permissionFailure = this.consumePromptPermissionFailure(sessionId);\n if (permissionFailure) {\n throw permissionFailure;\n }\n throw error;\n } finally {\n restoreConsoleError?.();\n if (this.activePrompt?.promise === promptPromise) {\n this.activePrompt = undefined;\n }\n this.cancellingSessionIds.delete(sessionId);\n this.promptPermissionFailures.delete(sessionId);\n }\n }\n\n async setSessionMode(sessionId: string, modeId: string): Promise<void> {\n const connection = this.getConnection();\n try {\n await this.runConnectionRequest(() =>\n connection.setSessionMode({\n sessionId,\n modeId,\n }),\n );\n } catch (error) {\n throw maybeWrapSessionControlError(\"session/set_mode\", error, `for mode \"${modeId}\"`);\n }\n }\n\n async setSessionConfigOption(\n sessionId: string,\n configId: string,\n value: string,\n ): Promise<SetSessionConfigOptionResponse> {\n const connection = this.getConnection();\n try {\n return await this.runConnectionRequest(() =>\n connection.setSessionConfigOption({\n sessionId,\n configId,\n value,\n }),\n );\n } catch (error) {\n throw maybeWrapSessionControlError(\n \"session/set_config_option\",\n error,\n `for \"${configId}\"=\"${value}\"`,\n );\n }\n }\n\n async setSessionModel(sessionId: string, modelId: string): Promise<void> {\n const connection = this.getConnection();\n try {\n await this.runConnectionRequest(() =>\n connection.unstable_setSessionModel({\n sessionId,\n modelId,\n }),\n );\n } catch (error) {\n const wrapped = maybeWrapSessionControlError(\n \"session/set_model\",\n error,\n `for model \"${modelId}\"`,\n );\n if (wrapped !== error) {\n throw wrapped;\n }\n const acp = extractAcpError(error);\n const summary = acp\n ? formatSessionControlAcpSummary(acp)\n : error instanceof Error\n ? error.message\n : String(error);\n if (error instanceof Error) {\n throw new Error(`Failed session/set_model for model \"${modelId}\": ${summary}`, {\n cause: error,\n });\n }\n throw new Error(`Failed session/set_model for model \"${modelId}\": ${summary}`, {\n cause: error,\n });\n }\n }\n\n async cancel(sessionId: string): Promise<void> {\n const connection = this.getConnection();\n this.cancellingSessionIds.add(sessionId);\n await this.runConnectionRequest(() =>\n connection.cancel({\n sessionId,\n }),\n );\n }\n\n async requestCancelActivePrompt(): Promise<boolean> {\n const active = this.activePrompt;\n if (!active) {\n return false;\n }\n await this.cancel(active.sessionId);\n return true;\n }\n\n async cancelActivePrompt(waitMs = 2_500): Promise<PromptResponse | undefined> {\n const active = this.activePrompt;\n if (!active) {\n return undefined;\n }\n\n try {\n await this.cancel(active.sessionId);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.log(`failed to send session/cancel: ${message}`);\n }\n\n if (waitMs <= 0) {\n return undefined;\n }\n\n let timer: NodeJS.Timeout | number | undefined;\n const timeoutPromise = new Promise<undefined>((resolve) => {\n timer = setTimeout(resolve, waitMs);\n });\n\n try {\n return await Promise.race([\n active.promise.then(\n (response) => response,\n () => undefined,\n ),\n timeoutPromise,\n ]);\n } finally {\n if (timer) {\n clearTimeout(timer);\n }\n }\n }\n\n async close(): Promise<void> {\n this.closing = true;\n\n await this.terminalManager.shutdown();\n\n const agent = this.agent;\n if (agent) {\n await this.terminateAgentProcess(agent);\n }\n if (this.pendingConnectionRequests.size > 0) {\n this.rejectPendingConnectionRequests(\n this.lastAgentExit\n ? new AgentDisconnectedError(\n this.lastAgentExit.reason,\n this.lastAgentExit.exitCode,\n this.lastAgentExit.signal,\n {\n outputAlreadyEmitted: Boolean(this.activePrompt),\n },\n )\n : new AgentDisconnectedError(\"connection_close\", null, null, {\n outputAlreadyEmitted: Boolean(this.activePrompt),\n }),\n );\n }\n\n this.sessionUpdateChain = Promise.resolve();\n this.observedSessionUpdates = 0;\n this.processedSessionUpdates = 0;\n this.suppressSessionUpdates = false;\n this.suppressReplaySessionUpdateMessages = false;\n this.activePrompt = undefined;\n this.cancellingSessionIds.clear();\n this.promptPermissionFailures.clear();\n this.loadedSessionId = undefined;\n this.initResult = undefined;\n this.connection = undefined;\n this.agent = undefined;\n }\n\n private async terminateAgentProcess(\n child: ChildProcessByStdio<Writable, Readable, Readable>,\n ): Promise<void> {\n const stdinCloseGraceMs = resolveAgentCloseAfterStdinEndMs(this.options.agentCommand);\n\n // Closing stdin is the most graceful shutdown signal for stdio-based ACP agents.\n if (!child.stdin.destroyed) {\n try {\n child.stdin.end();\n } catch {\n // best effort\n }\n }\n\n let exited = await waitForChildExit(child, stdinCloseGraceMs);\n if (!exited && isChildProcessRunning(child)) {\n try {\n child.kill(\"SIGTERM\");\n } catch {\n // best effort\n }\n exited = await waitForChildExit(child, AGENT_CLOSE_TERM_GRACE_MS);\n }\n\n if (!exited && isChildProcessRunning(child)) {\n this.log(`agent did not exit after ${AGENT_CLOSE_TERM_GRACE_MS}ms; forcing SIGKILL`);\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // best effort\n }\n exited = await waitForChildExit(child, AGENT_CLOSE_KILL_GRACE_MS);\n }\n\n // Ensure stdio handles don't keep this process alive after close() returns.\n this.detachAgentHandles(child, !exited);\n }\n\n private detachAgentHandles(agent: ChildProcess, unref: boolean): void {\n const stdin = agent.stdin;\n const stdout = agent.stdout;\n const stderr = agent.stderr;\n\n stdin?.destroy();\n stdout?.destroy();\n stderr?.destroy();\n\n if (unref) {\n try {\n agent.unref();\n } catch {\n // best effort\n }\n }\n }\n\n private getConnection(): ClientSideConnection {\n if (!this.connection) {\n throw new Error(\"ACP client not started\");\n }\n return this.connection;\n }\n\n private log(message: string): void {\n if (!this.options.verbose) {\n return;\n }\n process.stderr.write(`[acpx] ${message}\\n`);\n }\n\n private selectAuthMethod(methods: AuthMethod[]): AuthSelection | undefined {\n for (const method of methods) {\n const envCredential = readEnvCredential(method.id);\n if (envCredential) {\n return {\n methodId: method.id,\n credential: envCredential,\n source: \"env\",\n };\n }\n\n const configCredential = resolveConfiguredAuthCredential(\n method.id,\n this.options.authCredentials,\n );\n if (typeof configCredential === \"string\" && configCredential.trim().length > 0) {\n return {\n methodId: method.id,\n credential: configCredential,\n source: \"config\",\n };\n }\n }\n\n return undefined;\n }\n\n private async authenticateIfRequired(\n connection: ClientSideConnection,\n methods: AuthMethod[],\n ): Promise<void> {\n if (methods.length === 0) {\n return;\n }\n\n const selected = this.selectAuthMethod(methods);\n if (!selected) {\n if (this.options.authPolicy === \"fail\") {\n throw new AuthPolicyError(\n `agent advertised auth methods [${methods.map((m) => m.id).join(\", \")}] but no matching credentials found`,\n );\n }\n\n this.log(\n `agent advertised auth methods [${methods.map((m) => m.id).join(\", \")}] but no matching credentials found — skipping (agent may handle auth internally)`,\n );\n return;\n }\n\n await connection.authenticate({\n methodId: selected.methodId,\n });\n\n this.log(`authenticated with method ${selected.methodId} (${selected.source})`);\n }\n\n private async handlePermissionRequest(\n params: RequestPermissionRequest,\n ): Promise<RequestPermissionResponse> {\n if (this.cancellingSessionIds.has(params.sessionId)) {\n return {\n outcome: {\n outcome: \"cancelled\",\n },\n };\n }\n\n let response: RequestPermissionResponse;\n try {\n response = await resolvePermissionRequest(\n params,\n this.options.permissionMode,\n this.options.nonInteractivePermissions ?? \"deny\",\n );\n } catch (error) {\n if (error instanceof PermissionPromptUnavailableError) {\n this.notePromptPermissionFailure(params.sessionId, error);\n this.recordPermissionDecision(\"cancelled\");\n return {\n outcome: {\n outcome: \"cancelled\",\n },\n };\n }\n throw error;\n }\n\n const decision = classifyPermissionDecision(params, response);\n this.recordPermissionDecision(decision);\n\n return response;\n }\n\n private attachAgentLifecycleObservers(\n child: ChildProcessByStdio<Writable, Readable, Readable>,\n ): void {\n child.once(\"exit\", (exitCode, signal) => {\n this.recordAgentExit(\"process_exit\", exitCode, signal);\n });\n\n child.once(\"close\", (exitCode, signal) => {\n this.recordAgentExit(\"process_close\", exitCode, signal);\n });\n\n child.stdout.once(\"close\", () => {\n this.recordAgentExit(\"pipe_close\", child.exitCode ?? null, child.signalCode ?? null);\n });\n }\n\n private recordAgentExit(\n reason: AgentDisconnectReason,\n exitCode: number | null,\n signal: NodeJS.Signals | null,\n ): void {\n if (this.lastAgentExit) {\n return;\n }\n\n this.lastAgentExit = {\n exitCode,\n signal,\n exitedAt: isoNow(),\n reason,\n unexpectedDuringPrompt: !this.closing && Boolean(this.activePrompt),\n };\n this.rejectPendingConnectionRequests(\n new AgentDisconnectedError(reason, exitCode, signal, {\n outputAlreadyEmitted: Boolean(this.activePrompt),\n }),\n );\n }\n\n private notePromptPermissionFailure(\n sessionId: string,\n error: PermissionPromptUnavailableError,\n ): void {\n if (!this.promptPermissionFailures.has(sessionId)) {\n this.promptPermissionFailures.set(sessionId, error);\n }\n }\n\n private consumePromptPermissionFailure(\n sessionId: string,\n ): PermissionPromptUnavailableError | undefined {\n const error = this.promptPermissionFailures.get(sessionId);\n if (error) {\n this.promptPermissionFailures.delete(sessionId);\n }\n return error;\n }\n\n private async runConnectionRequest<T>(run: () => Promise<T>): Promise<T> {\n return await new Promise<T>((resolve, reject) => {\n const pending: PendingConnectionRequest = {\n settled: false,\n reject,\n };\n\n const finish = (cb: () => void) => {\n if (pending.settled) {\n return;\n }\n pending.settled = true;\n this.pendingConnectionRequests.delete(pending);\n cb();\n };\n\n this.pendingConnectionRequests.add(pending);\n void Promise.resolve()\n .then(run)\n .then(\n (value) => finish(() => resolve(value)),\n (error) => finish(() => reject(error)),\n );\n });\n }\n\n private rejectPendingConnectionRequests(error: unknown): void {\n for (const pending of this.pendingConnectionRequests) {\n if (pending.settled) {\n this.pendingConnectionRequests.delete(pending);\n continue;\n }\n pending.settled = true;\n this.pendingConnectionRequests.delete(pending);\n pending.reject(error);\n }\n }\n\n private async handleReadTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse> {\n try {\n return await this.filesystem.readTextFile(params);\n } catch (error) {\n this.recordPermissionError(params.sessionId, error);\n throw error;\n }\n }\n\n private async handleWriteTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse> {\n try {\n return await this.filesystem.writeTextFile(params);\n } catch (error) {\n this.recordPermissionError(params.sessionId, error);\n throw error;\n }\n }\n\n private async handleCreateTerminal(\n params: CreateTerminalRequest,\n ): Promise<CreateTerminalResponse> {\n try {\n return await this.terminalManager.createTerminal(params);\n } catch (error) {\n this.recordPermissionError(params.sessionId, error);\n throw error;\n }\n }\n\n private async handleTerminalOutput(\n params: TerminalOutputRequest,\n ): Promise<TerminalOutputResponse> {\n return await this.terminalManager.terminalOutput(params);\n }\n\n private async handleWaitForTerminalExit(\n params: WaitForTerminalExitRequest,\n ): Promise<WaitForTerminalExitResponse> {\n return await this.terminalManager.waitForTerminalExit(params);\n }\n\n private async handleKillTerminal(params: KillTerminalRequest): Promise<KillTerminalResponse> {\n return await this.terminalManager.killTerminal(params);\n }\n\n private async handleReleaseTerminal(\n params: ReleaseTerminalRequest,\n ): Promise<ReleaseTerminalResponse> {\n return await this.terminalManager.releaseTerminal(params);\n }\n\n private recordPermissionDecision(decision: \"approved\" | \"denied\" | \"cancelled\"): void {\n this.permissionStats.requested += 1;\n if (decision === \"approved\") {\n this.permissionStats.approved += 1;\n return;\n }\n if (decision === \"denied\") {\n this.permissionStats.denied += 1;\n return;\n }\n this.permissionStats.cancelled += 1;\n }\n\n private recordPermissionError(sessionId: string, error: unknown): void {\n if (error instanceof PermissionPromptUnavailableError) {\n this.notePromptPermissionFailure(sessionId, error);\n this.recordPermissionDecision(\"cancelled\");\n return;\n }\n if (error instanceof PermissionDeniedError) {\n this.recordPermissionDecision(\"denied\");\n }\n }\n\n private async handleSessionUpdate(notification: SessionNotification): Promise<void> {\n const sequence = ++this.observedSessionUpdates;\n this.sessionUpdateChain = this.sessionUpdateChain.then(async () => {\n try {\n if (!this.suppressSessionUpdates) {\n this.eventHandlers.onSessionUpdate?.(notification);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.log(`session update handler failed: ${message}`);\n } finally {\n this.processedSessionUpdates = sequence;\n }\n });\n\n await this.sessionUpdateChain;\n }\n\n private async waitForSessionUpdateDrain(idleMs: number, timeoutMs: number): Promise<void> {\n const normalizedIdleMs = Math.max(0, idleMs);\n const normalizedTimeoutMs = Math.max(normalizedIdleMs, timeoutMs);\n const deadline = Date.now() + normalizedTimeoutMs;\n let lastObserved = this.observedSessionUpdates;\n let idleSince = Date.now();\n\n while (Date.now() <= deadline) {\n const observed = this.observedSessionUpdates;\n if (observed !== lastObserved) {\n lastObserved = observed;\n idleSince = Date.now();\n }\n\n if (\n this.processedSessionUpdates === this.observedSessionUpdates &&\n Date.now() - idleSince >= normalizedIdleMs\n ) {\n await this.sessionUpdateChain;\n if (this.processedSessionUpdates === this.observedSessionUpdates) {\n return;\n }\n }\n\n await new Promise<void>((resolve) => {\n setTimeout(resolve, DRAIN_POLL_INTERVAL_MS);\n });\n }\n\n throw new Error(`Timed out waiting for session replay drain after ${normalizedTimeoutMs}ms`);\n }\n\n async waitForSessionUpdatesIdle(options?: {\n idleMs?: number;\n timeoutMs?: number;\n }): Promise<void> {\n await this.waitForSessionUpdateDrain(options?.idleMs ?? 0, options?.timeoutMs ?? 0);\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport type {\n ContentBlock,\n SessionNotification,\n SessionUpdate,\n ToolCall,\n ToolCallUpdate,\n UsageUpdate,\n} from \"@agentclientprotocol/sdk\";\nimport { textPrompt } from \"../prompt-content.js\";\nimport type {\n ClientOperation,\n PromptInput,\n SessionAcpxState,\n SessionConversation,\n SessionAgentContent,\n SessionAgentMessage,\n SessionMessage,\n SessionTokenUsage,\n SessionToolResult,\n SessionToolResultContent,\n SessionToolUse,\n SessionUserContent,\n} from \"../types.js\";\n\nexport type LegacyHistoryEntry = {\n role: \"user\" | \"assistant\";\n timestamp: string;\n textPreview: string;\n};\n\nconst MAX_RUNTIME_MESSAGES = 200;\nconst MAX_RUNTIME_AGENT_TEXT_CHARS = 8_000;\nconst MAX_RUNTIME_THINKING_CHARS = 4_000;\nconst MAX_RUNTIME_TOOL_IO_CHARS = 4_000;\nconst MAX_RUNTIME_REQUEST_TOKEN_USAGE = 100;\n\nfunction isoNow(): string {\n return new Date().toISOString();\n}\n\nfunction deepClone<T>(value: T): T {\n try {\n return structuredClone(value);\n } catch {\n return value;\n }\n}\n\nfunction hasOwn(source: object, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(source, key);\n}\n\nfunction normalizeAgentName(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction extractText(content: ContentBlock): string | undefined {\n if (content.type === \"text\") {\n return content.text;\n }\n\n if (content.type === \"resource_link\") {\n return content.title ?? content.name ?? content.uri;\n }\n\n if (content.type === \"resource\") {\n if (\"text\" in content.resource && typeof content.resource.text === \"string\") {\n return content.resource.text;\n }\n return content.resource.uri;\n }\n\n return undefined;\n}\n\nfunction contentToUserContent(content: ContentBlock): SessionUserContent | undefined {\n if (content.type === \"text\") {\n return {\n Text: content.text,\n };\n }\n\n if (content.type === \"resource_link\") {\n const value = content.title ?? content.name ?? content.uri;\n return {\n Mention: {\n uri: content.uri,\n content: value,\n },\n };\n }\n\n if (content.type === \"resource\") {\n if (\"text\" in content.resource && typeof content.resource.text === \"string\") {\n return {\n Text: content.resource.text,\n };\n }\n\n return {\n Mention: {\n uri: content.resource.uri,\n content: content.resource.uri,\n },\n };\n }\n\n if (content.type === \"image\") {\n return {\n Image: {\n source: content.data,\n size: null,\n },\n };\n }\n\n return undefined;\n}\n\nfunction nextUserMessageId(): string {\n return randomUUID();\n}\n\nfunction isUserMessage(message: SessionMessage): message is {\n User: SessionConversation[\"messages\"][number] extends infer T\n ? T extends { User: infer U }\n ? U\n : never\n : never;\n} {\n return typeof message === \"object\" && message !== null && hasOwn(message, \"User\");\n}\n\nfunction isAgentMessage(message: SessionMessage): message is { Agent: SessionAgentMessage } {\n return typeof message === \"object\" && message !== null && hasOwn(message, \"Agent\");\n}\n\nfunction isAgentTextContent(content: SessionAgentContent): content is { Text: string } {\n return hasOwn(content, \"Text\");\n}\n\nfunction isAgentThinkingContent(\n content: SessionAgentContent,\n): content is { Thinking: { text: string; signature?: string | null } } {\n return hasOwn(content, \"Thinking\");\n}\n\nfunction isAgentToolUseContent(\n content: SessionAgentContent,\n): content is { ToolUse: SessionToolUse } {\n return hasOwn(content, \"ToolUse\");\n}\n\nfunction updateConversationTimestamp(conversation: SessionConversation, timestamp: string): void {\n conversation.updated_at = timestamp;\n}\n\nfunction ensureAgentMessage(conversation: SessionConversation): SessionAgentMessage {\n const last = conversation.messages.at(-1);\n if (last && isAgentMessage(last)) {\n return last.Agent;\n }\n\n const created: SessionAgentMessage = {\n content: [],\n tool_results: {},\n };\n conversation.messages.push({ Agent: created });\n return created;\n}\n\nfunction appendAgentText(agent: SessionAgentMessage, text: string): void {\n if (!text.trim()) {\n return;\n }\n\n const last = agent.content.at(-1);\n if (last && isAgentTextContent(last)) {\n last.Text = trimRuntimeText(`${last.Text}${text}`, MAX_RUNTIME_AGENT_TEXT_CHARS);\n return;\n }\n\n const next: SessionAgentContent = {\n Text: text,\n };\n agent.content.push(next);\n}\n\nfunction appendAgentThinking(agent: SessionAgentMessage, text: string): void {\n if (!text.trim()) {\n return;\n }\n\n const last = agent.content.at(-1);\n if (last && isAgentThinkingContent(last)) {\n last.Thinking.text = trimRuntimeText(\n `${last.Thinking.text}${text}`,\n MAX_RUNTIME_THINKING_CHARS,\n );\n return;\n }\n\n const next: SessionAgentContent = {\n Thinking: {\n text,\n signature: null,\n },\n };\n agent.content.push(next);\n}\n\nfunction trimRuntimeText(value: string, maxChars: number): string {\n if (value.length <= maxChars) {\n return value;\n }\n return `${value.slice(0, Math.max(0, maxChars - 3))}...`;\n}\n\nfunction statusIndicatesComplete(status: unknown): boolean {\n if (typeof status !== \"string\") {\n return false;\n }\n const normalized = status.toLowerCase();\n return (\n normalized.includes(\"complete\") ||\n normalized.includes(\"done\") ||\n normalized.includes(\"success\") ||\n normalized.includes(\"failed\") ||\n normalized.includes(\"error\") ||\n normalized.includes(\"cancel\")\n );\n}\n\nfunction statusIndicatesError(status: unknown): boolean {\n if (typeof status !== \"string\") {\n return false;\n }\n const normalized = status.toLowerCase();\n return normalized.includes(\"fail\") || normalized.includes(\"error\");\n}\n\nfunction toToolResultContent(value: unknown): SessionToolResultContent {\n if (typeof value === \"string\") {\n return { Text: trimRuntimeText(value, MAX_RUNTIME_TOOL_IO_CHARS) };\n }\n\n if (value != null) {\n try {\n return { Text: trimRuntimeText(JSON.stringify(value), MAX_RUNTIME_TOOL_IO_CHARS) };\n } catch {\n return { Text: \"[Unserializable value]\" };\n }\n }\n\n return { Text: \"\" };\n}\n\nfunction toRawInput(value: unknown): string {\n if (typeof value === \"string\") {\n return trimRuntimeText(value, MAX_RUNTIME_TOOL_IO_CHARS);\n }\n\n try {\n return trimRuntimeText(JSON.stringify(value ?? {}), MAX_RUNTIME_TOOL_IO_CHARS);\n } catch {\n return value == null ? \"\" : \"[Unserializable input]\";\n }\n}\n\nfunction ensureToolUseContent(agent: SessionAgentMessage, toolCallId: string): SessionToolUse {\n for (const content of agent.content) {\n if (isAgentToolUseContent(content) && content.ToolUse.id === toolCallId) {\n return content.ToolUse;\n }\n }\n\n const created: SessionToolUse = {\n id: toolCallId,\n name: \"tool_call\",\n raw_input: \"{}\",\n input: {},\n is_input_complete: false,\n thought_signature: null,\n };\n agent.content.push({ ToolUse: created });\n return created;\n}\n\nfunction upsertToolResult(\n agent: SessionAgentMessage,\n toolCallId: string,\n patch: Partial<SessionToolResult>,\n): void {\n const existing = agent.tool_results[toolCallId];\n const next: SessionToolResult = {\n tool_use_id: toolCallId,\n tool_name: patch.tool_name ?? existing?.tool_name ?? \"tool_call\",\n is_error: patch.is_error ?? existing?.is_error ?? false,\n content: patch.content ?? existing?.content ?? { Text: \"\" },\n output: patch.output ?? existing?.output,\n };\n agent.tool_results[toolCallId] = next;\n}\n\nfunction applyToolCallUpdate(agent: SessionAgentMessage, update: ToolCall | ToolCallUpdate): void {\n const tool = ensureToolUseContent(agent, update.toolCallId);\n\n if (hasOwn(update, \"title\")) {\n tool.name =\n normalizeAgentName((update as { title?: unknown }).title) ?? tool.name ?? \"tool_call\";\n }\n\n if (hasOwn(update, \"kind\")) {\n const kindName = normalizeAgentName((update as { kind?: unknown }).kind);\n if (!tool.name || tool.name === \"tool_call\") {\n tool.name = kindName ?? tool.name;\n }\n }\n\n if (hasOwn(update, \"rawInput\")) {\n const rawInput = deepClone((update as { rawInput?: unknown }).rawInput);\n tool.input = rawInput ?? {};\n tool.raw_input = toRawInput(rawInput);\n }\n\n if (hasOwn(update, \"status\")) {\n tool.is_input_complete = statusIndicatesComplete((update as { status?: unknown }).status);\n }\n\n if (\n hasOwn(update, \"rawOutput\") ||\n hasOwn(update, \"status\") ||\n hasOwn(update, \"title\") ||\n hasOwn(update, \"kind\")\n ) {\n const status = (update as { status?: unknown }).status;\n const output = hasOwn(update, \"rawOutput\")\n ? deepClone((update as { rawOutput?: unknown }).rawOutput)\n : undefined;\n\n upsertToolResult(agent, update.toolCallId, {\n tool_name: tool.name,\n is_error: statusIndicatesError(status),\n content: output === undefined ? undefined : toToolResultContent(output),\n output,\n });\n }\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction numberField(source: Record<string, unknown>, keys: readonly string[]): number | undefined {\n for (const key of keys) {\n const value = source[key];\n if (typeof value === \"number\" && Number.isFinite(value) && value >= 0) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction usageToTokenUsage(update: UsageUpdate): SessionTokenUsage | undefined {\n const updateRecord = asRecord(update);\n const usageMeta = asRecord(updateRecord?._meta)?.usage;\n const source = asRecord(usageMeta) ?? updateRecord;\n if (!source) {\n return undefined;\n }\n\n const normalized: SessionTokenUsage = {\n input_tokens: numberField(source, [\"input_tokens\", \"inputTokens\"]),\n output_tokens: numberField(source, [\"output_tokens\", \"outputTokens\"]),\n cache_creation_input_tokens: numberField(source, [\n \"cache_creation_input_tokens\",\n \"cacheCreationInputTokens\",\n \"cachedWriteTokens\",\n ]),\n cache_read_input_tokens: numberField(source, [\n \"cache_read_input_tokens\",\n \"cacheReadInputTokens\",\n \"cachedReadTokens\",\n ]),\n };\n\n if (\n normalized.input_tokens === undefined &&\n normalized.output_tokens === undefined &&\n normalized.cache_creation_input_tokens === undefined &&\n normalized.cache_read_input_tokens === undefined\n ) {\n return undefined;\n }\n\n return normalized;\n}\n\nfunction ensureAcpxState(state: SessionAcpxState | undefined): SessionAcpxState {\n return state ?? {};\n}\n\nfunction lastUserMessageId(conversation: SessionConversation): string | undefined {\n for (let index = conversation.messages.length - 1; index >= 0; index -= 1) {\n const message = conversation.messages[index];\n if (message && isUserMessage(message)) {\n return message.User.id;\n }\n }\n return undefined;\n}\n\nexport function createSessionConversation(timestamp = isoNow()): SessionConversation {\n return {\n title: null,\n messages: [],\n updated_at: timestamp,\n cumulative_token_usage: {},\n request_token_usage: {},\n };\n}\n\nexport function cloneSessionConversation(\n conversation: SessionConversation | undefined,\n): SessionConversation {\n if (!conversation) {\n return createSessionConversation();\n }\n\n return {\n title: conversation.title,\n messages: deepClone(conversation.messages ?? []),\n updated_at: conversation.updated_at,\n cumulative_token_usage: deepClone(conversation.cumulative_token_usage ?? {}),\n request_token_usage: deepClone(conversation.request_token_usage ?? {}),\n };\n}\n\nexport function cloneSessionAcpxState(\n state: SessionAcpxState | undefined,\n): SessionAcpxState | undefined {\n if (!state) {\n return undefined;\n }\n\n return {\n current_mode_id: state.current_mode_id,\n desired_mode_id: state.desired_mode_id,\n current_model_id: state.current_model_id,\n available_models: state.available_models ? [...state.available_models] : undefined,\n available_commands: state.available_commands ? [...state.available_commands] : undefined,\n config_options: state.config_options ? deepClone(state.config_options) : undefined,\n session_options: state.session_options\n ? {\n model: state.session_options.model,\n allowed_tools: state.session_options.allowed_tools\n ? [...state.session_options.allowed_tools]\n : undefined,\n max_turns: state.session_options.max_turns,\n }\n : undefined,\n };\n}\n\nexport function appendLegacyHistory(\n conversation: SessionConversation,\n entries: LegacyHistoryEntry[],\n): void {\n for (const entry of entries) {\n const text = entry.textPreview?.trim();\n if (!text) {\n continue;\n }\n\n if (entry.role === \"user\") {\n conversation.messages.push({\n User: {\n id: nextUserMessageId(),\n content: [{ Text: text }],\n },\n });\n } else {\n conversation.messages.push({\n Agent: {\n content: [{ Text: text }],\n tool_results: {},\n },\n });\n }\n\n updateConversationTimestamp(conversation, entry.timestamp || conversation.updated_at);\n }\n}\n\nexport function recordPromptSubmission(\n conversation: SessionConversation,\n prompt: PromptInput | string,\n timestamp = isoNow(),\n): string | undefined {\n const normalizedPrompt = typeof prompt === \"string\" ? textPrompt(prompt) : prompt;\n const userContent = normalizedPrompt\n .map((content) => contentToUserContent(content))\n .filter((content) => content !== undefined);\n if (userContent.length === 0) {\n return undefined;\n }\n\n const promptMessageId = nextUserMessageId();\n conversation.messages.push({\n User: {\n id: promptMessageId,\n content: userContent.map((content) => {\n if (\"Text\" in content) {\n return {\n Text: trimRuntimeText(content.Text, MAX_RUNTIME_AGENT_TEXT_CHARS),\n };\n }\n return content;\n }),\n },\n });\n updateConversationTimestamp(conversation, timestamp);\n trimConversationForRuntime(conversation);\n return promptMessageId;\n}\n\nfunction agentMessageHasObservedReply(message: SessionAgentMessage): boolean {\n return message.content.length > 0 || Object.keys(message.tool_results).length > 0;\n}\n\nexport function hasAgentReplyAfterPrompt(\n conversation: SessionConversation,\n promptMessageId: string,\n): boolean {\n let sawPrompt = false;\n\n for (const message of conversation.messages) {\n if (!sawPrompt) {\n if (isUserMessage(message) && message.User.id === promptMessageId) {\n sawPrompt = true;\n }\n continue;\n }\n\n if (isAgentMessage(message) && agentMessageHasObservedReply(message.Agent)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function recordSessionUpdate(\n conversation: SessionConversation,\n state: SessionAcpxState | undefined,\n notification: SessionNotification,\n timestamp = isoNow(),\n): SessionAcpxState {\n const acpx = ensureAcpxState(state);\n\n const update: SessionUpdate = notification.update;\n switch (update.sessionUpdate) {\n case \"user_message_chunk\": {\n const userContent = contentToUserContent(update.content);\n if (userContent) {\n conversation.messages.push({\n User: {\n id: nextUserMessageId(),\n content: [userContent],\n },\n });\n }\n break;\n }\n case \"agent_message_chunk\": {\n const text = extractText(update.content);\n if (text) {\n const agent = ensureAgentMessage(conversation);\n appendAgentText(agent, text);\n }\n break;\n }\n case \"agent_thought_chunk\": {\n const text = extractText(update.content);\n if (text) {\n const agent = ensureAgentMessage(conversation);\n appendAgentThinking(agent, text);\n }\n break;\n }\n case \"tool_call\":\n case \"tool_call_update\": {\n const agent = ensureAgentMessage(conversation);\n applyToolCallUpdate(agent, update);\n break;\n }\n case \"usage_update\": {\n const usage = usageToTokenUsage(update);\n if (usage) {\n conversation.cumulative_token_usage = usage;\n const userId = lastUserMessageId(conversation);\n if (userId) {\n conversation.request_token_usage[userId] = usage;\n }\n }\n break;\n }\n case \"session_info_update\": {\n if (hasOwn(update, \"title\")) {\n conversation.title = update.title ?? null;\n }\n if (hasOwn(update, \"updatedAt\")) {\n conversation.updated_at = update.updatedAt ?? conversation.updated_at;\n }\n break;\n }\n case \"available_commands_update\": {\n acpx.available_commands = update.availableCommands\n .map((entry) => entry.name)\n .filter((entry) => typeof entry === \"string\" && entry.trim().length > 0);\n break;\n }\n case \"current_mode_update\": {\n acpx.current_mode_id = update.currentModeId;\n break;\n }\n case \"config_option_update\": {\n acpx.config_options = deepClone(update.configOptions);\n break;\n }\n default:\n break;\n }\n\n updateConversationTimestamp(conversation, timestamp);\n trimConversationForRuntime(conversation);\n return acpx;\n}\n\nexport function recordClientOperation(\n conversation: SessionConversation,\n state: SessionAcpxState | undefined,\n operation: ClientOperation,\n timestamp = isoNow(),\n): SessionAcpxState {\n const acpx = ensureAcpxState(state);\n updateConversationTimestamp(conversation, timestamp);\n trimConversationForRuntime(conversation);\n return acpx;\n}\n\nexport function trimConversationForRuntime(conversation: SessionConversation): void {\n if (conversation.messages.length > MAX_RUNTIME_MESSAGES) {\n conversation.messages = conversation.messages.slice(-MAX_RUNTIME_MESSAGES);\n }\n\n for (const message of conversation.messages) {\n if (!isAgentMessage(message)) {\n if (isUserMessage(message)) {\n message.User.content = message.User.content.map((content) => {\n if (\"Text\" in content) {\n return {\n Text: trimRuntimeText(content.Text, MAX_RUNTIME_AGENT_TEXT_CHARS),\n };\n }\n return content;\n });\n }\n continue;\n }\n\n for (const content of message.Agent.content) {\n if (\"Text\" in content) {\n content.Text = trimRuntimeText(content.Text, MAX_RUNTIME_AGENT_TEXT_CHARS);\n } else if (\"Thinking\" in content) {\n content.Thinking.text = trimRuntimeText(content.Thinking.text, MAX_RUNTIME_THINKING_CHARS);\n } else if (\"ToolUse\" in content) {\n content.ToolUse.raw_input = trimRuntimeText(\n content.ToolUse.raw_input,\n MAX_RUNTIME_TOOL_IO_CHARS,\n );\n }\n }\n\n for (const result of Object.values(message.Agent.tool_results)) {\n if (\"Text\" in result.content) {\n result.content.Text = trimRuntimeText(result.content.Text, MAX_RUNTIME_TOOL_IO_CHARS);\n }\n if (typeof result.output === \"string\") {\n result.output = trimRuntimeText(result.output, MAX_RUNTIME_TOOL_IO_CHARS);\n }\n }\n }\n\n const requestUsageEntries = Object.entries(conversation.request_token_usage);\n if (requestUsageEntries.length > MAX_RUNTIME_REQUEST_TOKEN_USAGE) {\n conversation.request_token_usage = Object.fromEntries(\n requestUsageEntries.slice(-MAX_RUNTIME_REQUEST_TOKEN_USAGE),\n );\n }\n}\n","import type { SessionModelState } from \"@agentclientprotocol/sdk\";\nimport type { SessionAcpxState, SessionRecord } from \"../types.js\";\n\nfunction ensureAcpxState(state: SessionAcpxState | undefined): SessionAcpxState {\n return state ?? {};\n}\n\nexport function normalizeModeId(modeId: string | undefined): string | undefined {\n if (typeof modeId !== \"string\") {\n return undefined;\n }\n const trimmed = modeId.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeModelId(modelId: string | undefined): string | undefined {\n if (typeof modelId !== \"string\") {\n return undefined;\n }\n const trimmed = modelId.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function getDesiredModeId(state: SessionAcpxState | undefined): string | undefined {\n return normalizeModeId(state?.desired_mode_id);\n}\n\nexport function setDesiredModeId(record: SessionRecord, modeId: string | undefined): void {\n const acpx = ensureAcpxState(record.acpx);\n const normalized = normalizeModeId(modeId);\n\n if (normalized) {\n acpx.desired_mode_id = normalized;\n } else {\n delete acpx.desired_mode_id;\n }\n\n record.acpx = acpx;\n}\n\nexport function getDesiredModelId(state: SessionAcpxState | undefined): string | undefined {\n return normalizeModelId(state?.session_options?.model);\n}\n\nexport function setDesiredModelId(record: SessionRecord, modelId: string | undefined): void {\n const acpx = ensureAcpxState(record.acpx);\n const normalized = normalizeModelId(modelId);\n const sessionOptions = { ...acpx.session_options };\n\n if (normalized) {\n sessionOptions.model = normalized;\n } else {\n delete sessionOptions.model;\n }\n\n if (\n typeof sessionOptions.model === \"string\" ||\n Array.isArray(sessionOptions.allowed_tools) ||\n typeof sessionOptions.max_turns === \"number\"\n ) {\n acpx.session_options = sessionOptions;\n } else {\n delete acpx.session_options;\n }\n\n record.acpx = acpx;\n}\n\nexport function setCurrentModelId(record: SessionRecord, modelId: string | undefined): void {\n const acpx = ensureAcpxState(record.acpx);\n const normalized = normalizeModelId(modelId);\n\n if (normalized) {\n acpx.current_model_id = normalized;\n } else {\n delete acpx.current_model_id;\n }\n\n record.acpx = acpx;\n}\n\nexport function syncAdvertisedModelState(\n record: SessionRecord,\n models: SessionModelState | undefined,\n): void {\n if (!models) {\n return;\n }\n\n const acpx = ensureAcpxState(record.acpx);\n acpx.current_model_id = models.currentModelId;\n acpx.available_models = models.availableModels.map((model) => model.modelId);\n record.acpx = acpx;\n}\n","import type { AgentLifecycleSnapshot } from \"../../acp/client.js\";\nimport { normalizeRuntimeSessionId } from \"../../session/runtime-session-id.js\";\nimport type { SessionConversation, SessionRecord } from \"../../types.js\";\n\nexport function applyLifecycleSnapshotToRecord(\n record: SessionRecord,\n snapshot: AgentLifecycleSnapshot | undefined,\n): void {\n if (!snapshot) {\n return;\n }\n\n record.pid = snapshot.pid;\n record.agentStartedAt = snapshot.startedAt;\n\n if (snapshot.lastExit) {\n record.lastAgentExitCode = snapshot.lastExit.exitCode;\n record.lastAgentExitSignal = snapshot.lastExit.signal;\n record.lastAgentExitAt = snapshot.lastExit.exitedAt;\n record.lastAgentDisconnectReason = snapshot.lastExit.reason;\n return;\n }\n\n record.lastAgentExitCode = undefined;\n record.lastAgentExitSignal = undefined;\n record.lastAgentExitAt = undefined;\n record.lastAgentDisconnectReason = undefined;\n}\n\nexport function reconcileAgentSessionId(\n record: SessionRecord,\n agentSessionId: string | undefined,\n): void {\n const normalized = normalizeRuntimeSessionId(agentSessionId);\n if (!normalized) {\n return;\n }\n\n record.agentSessionId = normalized;\n}\n\nexport function sessionHasAgentMessages(\n recordOrConversation: Pick<SessionRecord, \"messages\"> | SessionConversation,\n): boolean {\n return recordOrConversation.messages.some(\n (message) => typeof message === \"object\" && message !== null && \"Agent\" in message,\n );\n}\n\nexport function applyConversation(record: SessionRecord, conversation: SessionConversation): void {\n record.title = conversation.title;\n record.updated_at = conversation.updated_at;\n record.messages = conversation.messages;\n record.cumulative_token_usage = conversation.cumulative_token_usage;\n record.request_token_usage = conversation.request_token_usage;\n}\n","import type { AcpClient } from \"../../acp/client.js\";\nimport {\n extractAcpError,\n formatErrorMessage,\n isAcpQueryClosedBeforeResponseError,\n isAcpResourceNotFoundError,\n} from \"../../acp/error-normalization.js\";\nimport { InterruptedError, TimeoutError, withTimeout } from \"../../async-control.js\";\nimport {\n SessionModeReplayError,\n SessionModelReplayError,\n SessionResumeRequiredError,\n} from \"../../errors.js\";\nimport { incrementPerfCounter } from \"../../perf-metrics.js\";\nimport {\n getDesiredModeId,\n getDesiredModelId,\n setCurrentModelId,\n syncAdvertisedModelState,\n} from \"../../session/mode-preference.js\";\nimport type { SessionRecord, SessionResumePolicy } from \"../../types.js\";\nimport {\n applyLifecycleSnapshotToRecord,\n reconcileAgentSessionId,\n sessionHasAgentMessages,\n} from \"./lifecycle.js\";\n\nexport type ConnectedSessionController = {\n hasActivePrompt: () => boolean;\n requestCancelActivePrompt: () => Promise<boolean>;\n setSessionMode: (modeId: string) => Promise<void>;\n setSessionModel: (modelId: string) => Promise<void>;\n setSessionConfigOption: (\n configId: string,\n value: string,\n ) => ReturnType<AcpClient[\"setSessionConfigOption\"]>;\n};\n\nfunction isProcessAlive(pid: number | undefined): boolean {\n if (!pid || !Number.isInteger(pid) || pid <= 0 || pid === process.pid) {\n return false;\n }\n\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport type ConnectAndLoadSessionOptions = {\n client: AcpClient;\n record: SessionRecord;\n resumePolicy?: SessionResumePolicy;\n timeoutMs?: number;\n verbose?: boolean;\n activeController: ConnectedSessionController;\n onClientAvailable?: (controller: ConnectedSessionController) => void;\n onConnectedRecord?: (record: SessionRecord) => void;\n onSessionIdResolved?: (sessionId: string) => void;\n};\n\nexport type ConnectAndLoadSessionResult = {\n sessionId: string;\n agentSessionId?: string;\n resumed: boolean;\n loadError?: string;\n};\n\nconst SESSION_LOAD_UNSUPPORTED_CODES = new Set([-32601, -32602]);\n\nfunction shouldFallbackToNewSession(error: unknown, record: SessionRecord): boolean {\n if (error instanceof TimeoutError || error instanceof InterruptedError) {\n return false;\n }\n\n if (isAcpResourceNotFoundError(error)) {\n return true;\n }\n\n const acp = extractAcpError(error);\n if (acp && SESSION_LOAD_UNSUPPORTED_CODES.has(acp.code)) {\n return true;\n }\n\n if (!sessionHasAgentMessages(record)) {\n if (isAcpQueryClosedBeforeResponseError(error)) {\n return true;\n }\n\n if (acp?.code === -32603) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction requiresSameSession(resumePolicy: SessionResumePolicy | undefined): boolean {\n return resumePolicy === \"same-session-only\";\n}\n\nfunction makeSessionResumeRequiredError(params: {\n record: SessionRecord;\n reason: string;\n cause?: unknown;\n}): SessionResumeRequiredError {\n return new SessionResumeRequiredError(\n `Persistent ACP session ${params.record.acpSessionId} could not be resumed: ${params.reason}`,\n {\n cause: params.cause instanceof Error ? params.cause : undefined,\n },\n );\n}\n\nasync function replayDesiredMode(params: {\n client: AcpClient;\n sessionId: string;\n desiredModeId: string | undefined;\n previousSessionId: string;\n timeoutMs?: number;\n verbose?: boolean;\n}): Promise<void> {\n if (!params.desiredModeId) {\n return;\n }\n\n try {\n await withTimeout(\n params.client.setSessionMode(params.sessionId, params.desiredModeId),\n params.timeoutMs,\n );\n if (params.verbose) {\n process.stderr.write(\n `[acpx] replayed desired mode ${params.desiredModeId} on fresh ACP session ${params.sessionId} (previous ${params.previousSessionId})\\n`,\n );\n }\n } catch (error) {\n throw new SessionModeReplayError(\n `Failed to replay saved session mode ${params.desiredModeId} on fresh ACP session ${params.sessionId}: ${formatErrorMessage(error)}`,\n {\n cause: error instanceof Error ? error : undefined,\n retryable: true,\n },\n );\n }\n}\n\nasync function replayDesiredModel(params: {\n client: AcpClient;\n sessionId: string;\n desiredModelId: string | undefined;\n previousSessionId: string;\n models: import(\"../../acp/client.js\").SessionLoadResult[\"models\"] | undefined;\n timeoutMs?: number;\n verbose?: boolean;\n}): Promise<void> {\n if (!params.desiredModelId || !params.models) {\n return;\n }\n if (params.models.currentModelId === params.desiredModelId) {\n return;\n }\n\n try {\n await withTimeout(\n params.client.setSessionModel(params.sessionId, params.desiredModelId),\n params.timeoutMs,\n );\n if (params.verbose) {\n process.stderr.write(\n `[acpx] replayed desired model ${params.desiredModelId} on fresh ACP session ${params.sessionId} (previous ${params.previousSessionId})\\n`,\n );\n }\n } catch (error) {\n throw new SessionModelReplayError(\n `Failed to replay saved session model ${params.desiredModelId} on fresh ACP session ${params.sessionId}: ${formatErrorMessage(error)}`,\n {\n cause: error instanceof Error ? error : undefined,\n retryable: true,\n },\n );\n }\n}\n\nfunction restoreOriginalSessionState(params: {\n record: SessionRecord;\n sessionId: string;\n agentSessionId: string | undefined;\n}): void {\n params.record.acpSessionId = params.sessionId;\n params.record.agentSessionId = params.agentSessionId;\n}\n\nexport async function connectAndLoadSession(\n options: ConnectAndLoadSessionOptions,\n): Promise<ConnectAndLoadSessionResult> {\n const record = options.record;\n const client = options.client;\n const sameSessionOnly = requiresSameSession(options.resumePolicy);\n const originalSessionId = record.acpSessionId;\n const originalAgentSessionId = record.agentSessionId;\n const desiredModeId = getDesiredModeId(record.acpx);\n const desiredModelId = getDesiredModelId(record.acpx);\n const storedProcessAlive = isProcessAlive(record.pid);\n const shouldReconnect = Boolean(record.pid) && !storedProcessAlive;\n\n if (options.verbose) {\n if (storedProcessAlive) {\n process.stderr.write(\n `[acpx] saved session pid ${record.pid} is running; reconnecting with loadSession\\n`,\n );\n } else if (shouldReconnect) {\n process.stderr.write(\n `[acpx] saved session pid ${record.pid} is dead; respawning agent and attempting session/load\\n`,\n );\n }\n }\n\n const reusingLoadedSession = client.hasReusableSession(record.acpSessionId);\n if (reusingLoadedSession) {\n incrementPerfCounter(\"runtime.connect_and_load.reused_session\");\n } else {\n await withTimeout(client.start(), options.timeoutMs);\n }\n options.onClientAvailable?.(options.activeController);\n applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());\n record.closed = false;\n record.closedAt = undefined;\n options.onConnectedRecord?.(record);\n\n let resumed = false;\n let loadError: string | undefined;\n let sessionId = record.acpSessionId;\n let createdFreshSession = false;\n let pendingAgentSessionId = record.agentSessionId;\n let sessionModels: import(\"../../acp/client.js\").SessionLoadResult[\"models\"];\n\n if (reusingLoadedSession) {\n resumed = true;\n } else if (client.supportsLoadSession()) {\n try {\n const loadResult = await withTimeout(\n client.loadSessionWithOptions(record.acpSessionId, record.cwd, {\n suppressReplayUpdates: true,\n }),\n options.timeoutMs,\n );\n reconcileAgentSessionId(record, loadResult.agentSessionId);\n sessionModels = loadResult.models;\n resumed = true;\n } catch (error) {\n loadError = formatErrorMessage(error);\n if (sameSessionOnly) {\n throw makeSessionResumeRequiredError({\n record,\n reason: loadError,\n cause: error,\n });\n }\n if (!shouldFallbackToNewSession(error, record)) {\n throw error;\n }\n const createdSession = await withTimeout(client.createSession(record.cwd), options.timeoutMs);\n sessionId = createdSession.sessionId;\n createdFreshSession = true;\n pendingAgentSessionId = createdSession.agentSessionId;\n sessionModels = createdSession.models;\n }\n } else {\n if (sameSessionOnly) {\n throw makeSessionResumeRequiredError({\n record,\n reason: \"agent does not support session/load\",\n });\n }\n const createdSession = await withTimeout(client.createSession(record.cwd), options.timeoutMs);\n sessionId = createdSession.sessionId;\n createdFreshSession = true;\n pendingAgentSessionId = createdSession.agentSessionId;\n sessionModels = createdSession.models;\n }\n\n if (createdFreshSession) {\n try {\n await replayDesiredMode({\n client,\n sessionId,\n desiredModeId,\n previousSessionId: originalSessionId,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n });\n await replayDesiredModel({\n client,\n sessionId,\n desiredModelId,\n previousSessionId: originalSessionId,\n models: sessionModels,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n });\n } catch (error) {\n restoreOriginalSessionState({\n record,\n sessionId: originalSessionId,\n agentSessionId: originalAgentSessionId,\n });\n if (options.verbose) {\n process.stderr.write(`[acpx] ${formatErrorMessage(error)}\\n`);\n }\n throw error;\n }\n\n record.acpSessionId = sessionId;\n reconcileAgentSessionId(record, pendingAgentSessionId);\n }\n\n syncAdvertisedModelState(record, sessionModels);\n if (createdFreshSession && desiredModelId && sessionModels) {\n setCurrentModelId(record, desiredModelId);\n }\n\n options.onSessionIdResolved?.(sessionId);\n\n return {\n sessionId,\n agentSessionId: record.agentSessionId,\n resumed,\n loadError,\n };\n}\n","import type { SessionRecord } from \"../../types.js\";\n\nexport type SessionAgentOptions = {\n model?: string;\n allowedTools?: string[];\n maxTurns?: number;\n};\n\nexport function sessionOptionsFromRecord(record: SessionRecord): SessionAgentOptions | undefined {\n const stored = record.acpx?.session_options;\n if (!stored) {\n return undefined;\n }\n\n const sessionOptions: SessionAgentOptions = {};\n\n if (typeof stored.model === \"string\" && stored.model.trim().length > 0) {\n sessionOptions.model = stored.model;\n }\n if (Array.isArray(stored.allowed_tools)) {\n sessionOptions.allowedTools = [...stored.allowed_tools];\n }\n if (typeof stored.max_turns === \"number\") {\n sessionOptions.maxTurns = stored.max_turns;\n }\n\n return Object.keys(sessionOptions).length > 0 ? sessionOptions : undefined;\n}\n","import type { SetSessionConfigOptionResponse } from \"@agentclientprotocol/sdk\";\nimport { AcpClient } from \"../../acp/client.js\";\nimport { withInterrupt } from \"../../async-control.js\";\nimport { absolutePath, isoNow } from \"../../session/persistence.js\";\nimport type {\n AuthPolicy,\n McpServer,\n NonInteractivePermissionPolicy,\n PermissionMode,\n SessionRecord,\n SessionResumePolicy,\n} from \"../../types.js\";\nimport { applyLifecycleSnapshotToRecord } from \"./lifecycle.js\";\nimport { connectAndLoadSession, type ConnectedSessionController } from \"./reconnect.js\";\nimport { sessionOptionsFromRecord } from \"./session-options.js\";\n\nexport type FullConnectedSessionController = ConnectedSessionController & {\n setSessionModel: (modelId: string) => Promise<void>;\n setSessionConfigOption: (\n configId: string,\n value: string,\n ) => Promise<SetSessionConfigOptionResponse>;\n};\n\ntype ConnectedSessionContext = {\n record: SessionRecord;\n client: AcpClient;\n activeController: FullConnectedSessionController;\n sessionId: string;\n resumed: boolean;\n loadError?: string;\n};\n\nexport type WithConnectedSessionOptions<T> = {\n sessionRecordId: string;\n loadRecord: (sessionRecordId: string) => Promise<SessionRecord>;\n saveRecord: (record: SessionRecord) => Promise<void>;\n createClient?: (options: ConstructorParameters<typeof AcpClient>[0]) => AcpClient;\n mcpServers?: McpServer[];\n permissionMode?: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n resumePolicy?: SessionResumePolicy;\n timeoutMs?: number;\n verbose?: boolean;\n onClientAvailable?: (controller: FullConnectedSessionController) => void;\n onClientClosed?: () => void;\n onConnectedRecord?: (record: SessionRecord) => void;\n onInterrupt?: (params: { client: AcpClient; record: SessionRecord }) => Promise<void>;\n run: (context: ConnectedSessionContext) => Promise<T>;\n};\n\nexport type WithConnectedSessionResult<T> = {\n value: T;\n record: SessionRecord;\n resumed: boolean;\n loadError?: string;\n};\n\nfunction createActiveSessionController(params: {\n client: AcpClient;\n getActiveSessionId: () => string;\n}): FullConnectedSessionController {\n const getActiveSessionId = () => params.getActiveSessionId();\n return {\n hasActivePrompt: () => params.client.hasActivePrompt(),\n requestCancelActivePrompt: async () => await params.client.requestCancelActivePrompt(),\n setSessionMode: async (modeId: string) => {\n await params.client.setSessionMode(getActiveSessionId(), modeId);\n },\n setSessionModel: async (modelId: string) => {\n await params.client.setSessionModel(getActiveSessionId(), modelId);\n },\n setSessionConfigOption: async (configId: string, value: string) => {\n return await params.client.setSessionConfigOption(getActiveSessionId(), configId, value);\n },\n };\n}\n\nexport async function withConnectedSession<T>(\n options: WithConnectedSessionOptions<T>,\n): Promise<WithConnectedSessionResult<T>> {\n const record = await options.loadRecord(options.sessionRecordId);\n const client =\n options.createClient?.({\n agentCommand: record.agentCommand,\n cwd: absolutePath(record.cwd),\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode ?? \"approve-reads\",\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n verbose: options.verbose,\n sessionOptions: sessionOptionsFromRecord(record),\n }) ??\n new AcpClient({\n agentCommand: record.agentCommand,\n cwd: absolutePath(record.cwd),\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode ?? \"approve-reads\",\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n verbose: options.verbose,\n sessionOptions: sessionOptionsFromRecord(record),\n });\n let activeSessionIdForControl = record.acpSessionId;\n let notifiedClientAvailable = false;\n const activeController = createActiveSessionController({\n client,\n getActiveSessionId: () => activeSessionIdForControl,\n });\n\n try {\n return await withInterrupt(\n async () => {\n const { sessionId, resumed, loadError } = await connectAndLoadSession({\n client,\n record,\n resumePolicy: options.resumePolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n activeController,\n onClientAvailable: (controller) => {\n options.onClientAvailable?.(controller as FullConnectedSessionController);\n notifiedClientAvailable = true;\n },\n onConnectedRecord: options.onConnectedRecord,\n onSessionIdResolved: (sessionIdValue) => {\n activeSessionIdForControl = sessionIdValue;\n },\n });\n\n const value = await options.run({\n record,\n client,\n activeController,\n sessionId,\n resumed,\n loadError,\n });\n\n const now = isoNow();\n record.lastUsedAt = now;\n record.closed = false;\n record.closedAt = undefined;\n record.protocolVersion = client.initializeResult?.protocolVersion;\n record.agentCapabilities = client.initializeResult?.agentCapabilities;\n applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());\n await options.saveRecord(record);\n\n return {\n value,\n record,\n resumed,\n loadError,\n };\n },\n async () => {\n if (options.onInterrupt) {\n await options.onInterrupt({ client, record });\n } else {\n await client.cancelActivePrompt(2_500);\n }\n applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());\n record.lastUsedAt = isoNow();\n await options.saveRecord(record).catch(() => {\n // best effort while process is being interrupted\n });\n await client.close();\n },\n );\n } finally {\n if (notifiedClientAvailable) {\n options.onClientClosed?.();\n }\n await client.close();\n applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());\n await options.saveRecord(record).catch(() => {\n // best effort on close\n });\n }\n}\n","import { TimeoutError, withTimeout } from \"../../async-control.js\";\nimport { hasAgentReplyAfterPrompt } from \"../../session/conversation-model.js\";\nimport type { PromptInput, RunPromptResult, SessionConversation } from \"../../types.js\";\n\nconst SESSION_REPLY_IDLE_MS = 1_000;\nconst SESSION_REPLY_DRAIN_TIMEOUT_MS = 5_000;\n\ntype PromptTurnClient = {\n prompt: (\n sessionId: string,\n prompt: PromptInput | string,\n ) => Promise<{ stopReason: RunPromptResult[\"stopReason\"] }>;\n waitForSessionUpdatesIdle?: (options?: { idleMs?: number; timeoutMs?: number }) => Promise<void>;\n};\n\nexport async function runPromptTurn(params: {\n client: PromptTurnClient;\n sessionId: string;\n prompt: PromptInput | string;\n timeoutMs?: number;\n conversation: SessionConversation;\n promptMessageId?: string;\n onPromptStarted?: () => Promise<void> | void;\n}): Promise<{ stopReason: RunPromptResult[\"stopReason\"]; source: \"rpc\" | \"session\" }> {\n try {\n const promptPromise = params.client.prompt(params.sessionId, params.prompt);\n await params.onPromptStarted?.();\n const response = await withTimeout(promptPromise, params.timeoutMs);\n return {\n stopReason: response.stopReason,\n source: \"rpc\",\n };\n } catch (error) {\n if (!(error instanceof TimeoutError) || !params.promptMessageId) {\n throw error;\n }\n\n await params.client\n .waitForSessionUpdatesIdle?.({\n idleMs: SESSION_REPLY_IDLE_MS,\n timeoutMs: SESSION_REPLY_DRAIN_TIMEOUT_MS,\n })\n .catch(() => {\n // Best effort. If the update drain itself times out, fall back to the prompt error.\n });\n\n if (hasAgentReplyAfterPrompt(params.conversation, params.promptMessageId)) {\n return {\n stopReason: \"end_turn\",\n source: \"session\",\n };\n }\n\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAAA,IAAa,eAAb,cAAkC,MAAM;CACtC,YAAY,WAAmB;AAC7B,QAAM,mBAAmB,UAAU,IAAI;AACvC,OAAK,OAAO;;;AAIhB,IAAa,mBAAb,cAAsC,MAAM;CAC1C,cAAc;AACZ,QAAM,cAAc;AACpB,OAAK,OAAO;;;AAIhB,eAAsB,YAAe,SAAqB,WAAgC;AACxF,KAAI,aAAa,QAAQ,aAAa,EACpC,QAAO,MAAM;CAGf,IAAI;CACJ,MAAM,iBAAiB,IAAI,SAAY,UAAU,WAAW;AAC1D,UAAQ,iBAAiB;AACvB,UAAO,IAAI,aAAa,UAAU,CAAC;KAClC,UAAU;GACb;AAEF,KAAI;AACF,SAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,eAAe,CAAC;WAC5C;AACR,MAAI,MACF,cAAa,MAAM;;;AAKzB,eAAsB,cACpB,KACA,aACY;AACZ,QAAO,MAAM,IAAI,SAAY,SAAS,WAAW;EAC/C,IAAI,UAAU;EAEd,MAAM,UAAU,OAAmB;AACjC,OAAI,QACF;AAEF,aAAU;AACV,WAAQ,IAAI,UAAU,SAAS;AAC/B,WAAQ,IAAI,WAAW,UAAU;AACjC,WAAQ,IAAI,UAAU,SAAS;AAC/B,OAAI;;EAGN,MAAM,0BAA0B;AACzB,gBAAa,CAAC,cAAc;AAC/B,iBAAa,OAAO,IAAI,kBAAkB,CAAC,CAAC;KAC5C;;EAGJ,MAAM,iBAAiB;AACrB,sBAAmB;;EAGrB,MAAM,kBAAkB;AACtB,sBAAmB;;EAGrB,MAAM,iBAAiB;AACrB,sBAAmB;;AAGrB,UAAQ,KAAK,UAAU,SAAS;AAChC,UAAQ,KAAK,WAAW,UAAU;AAClC,UAAQ,KAAK,UAAU,SAAS;AAE3B,OAAK,CAAC,MACR,WAAW,aAAa,QAAQ,OAAO,CAAC,GACxC,UAAU,aAAa,OAAO,MAAM,CAAC,CACvC;GACD;;;;AC3EJ,SAAgB,8BAA8B,QAAgD;CAC5F,MAAM,YAA2B;EAC/B,GAAG;EACH,QAAQ;EACT;AAED,QAAO;EACL,QAAQ,UAAU;EAClB,gBAAgB,UAAU;EAC1B,gBAAgB,UAAU;EAC1B,kBAAkB,0BAA0B,UAAU,eAAe;EACrE,eAAe,UAAU;EACzB,KAAK,UAAU;EACf,MAAM,UAAU;EAChB,YAAY,UAAU;EACtB,cAAc,UAAU;EACxB,UAAU,UAAU;EACpB,iBAAiB,UAAU;EAC3B,WAAW,UAAU;EACrB,QAAQ,UAAU;EAClB,WAAW,UAAU;EACrB,KAAK,UAAU;EACf,kBAAkB,UAAU;EAC5B,gBAAgB,UAAU;EAC1B,sBAAsB,UAAU;EAChC,wBAAwB,UAAU;EAClC,oBAAoB,UAAU;EAC9B,8BAA8B,UAAU;EACxC,kBAAkB,UAAU;EAC5B,oBAAoB,UAAU;EAC9B,OAAO,UAAU;EACjB,UAAU,UAAU;EACpB,YAAY,UAAU;EACtB,wBAAwB,UAAU;EAClC,qBAAqB,UAAU;EAC/B,MAAM,UAAU;EACjB;;;;ACxCH,MAAM,iBAAiB;AAEvB,MAAM,eAAe,IAAI,IAAI;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,mBAAmB,IAAI,IAAI,CAAC,uBAAuB,8BAA8B,CAAC;AAExF,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACD,CAAC;AAEF,SAAS,SAAS,OAAkD;AAClE,QAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAGtE,SAAS,SAAS,MAAwB;AACxC,QAAO,KAAK,KAAK,IAAI;;AAGvB,SAAS,aAAa,MAAgB,KAAsB;AAC1D,KAAI,aAAa,IAAI,IAAI,CACvB,QAAO;AAGT,QAAO;;AAGT,SAAS,kBAAkB,MAAyB;AAClD,QAAO,iBAAiB,IAAI,SAAS,KAAK,CAAC;;AAG7C,SAAS,kBAAkB,MAAyB;AAClD,QAAO,mBAAmB,IAAI,SAAS,KAAK,CAAC,IAAI,uBAAuB,KAAK;;AAG/E,SAAS,uBAAuB,MAAyB;AACvD,KAAI,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,OAAO,SAC/C,QAAO;CAGT,MAAM,mBAAmB,KAAK,YAAY,eAAe;AACzD,KAAI,qBAAqB,MAAM,mBAAmB,MAAM,KAAK,SAAS,EACpE,QAAO;AAIT,QADmB,KAAK,MAAM,GAAG,mBAAmB,EAAE,CAAC,KAAK,IAAI,KAC1C;;AAGxB,SAAS,kBAAkB,OAAgB,MAAgB,YAA4B;AACrF,KAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,OAAK,MAAM,SAAS,MAClB,mBAAkB,OAAO,MAAM,WAAW;AAE5C;;AAGF,KAAI,CAAC,SAAS,MAAM,CAClB;CAGF,MAAM,cAAc,kBAAkB,KAAK;AAC3C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE;AAChD,MAAI,CAAC,eAAe,CAAC,eAAe,KAAK,IAAI,IAAI,CAAC,aAAa,MAAM,IAAI,CACvE,YAAW,KAAK,GAAG,SAAS,KAAK,CAAC,GAAG,MAAM,QAAQ,OAAO,GAAG,CAAC;EAGhE,MAAM,YAAY,CAAC,GAAG,MAAM,IAAI;AAChC,MAAI,kBAAkB,UAAU,CAC9B;AAGF,oBAAkB,OAAO,WAAW,WAAW;;;AAInD,SAAgB,iCAAiC,OAA0B;CACzE,MAAM,aAAuB,EAAE;AAC/B,mBAAkB,OAAO,EAAE,EAAE,WAAW;AACxC,QAAO;;AAGT,SAAgB,yBAAyB,OAAsB;CAC7D,MAAM,aAAa,iCAAiC,MAAM;AAC1D,KAAI,WAAW,WAAW,EACxB;AAGF,OAAM,IAAI,MACR,8DAA8D,WAAW,KAAK,KAAK,GACpF;;;;ACjGH,MAAa,kCAAkC,KAAK,OAAO;AAG3D,SAAgBA,mBAAyB;AACvC,QAAO,KAAK,KAAK,GAAG,SAAS,EAAE,SAAS,WAAW;;AAGrD,SAAgB,cAAc,WAA2B;AACvD,QAAO,mBAAmB,UAAU;;AAGtC,SAAgB,uBAAuB,WAA2B;AAChE,QAAO,KAAK,KAAKA,kBAAgB,EAAE,GAAG,cAAc,UAAU,CAAC,gBAAgB;;AAGjF,SAAgB,wBAAwB,WAAmB,SAAyB;AAClF,QAAO,KAAK,KAAKA,kBAAgB,EAAE,GAAG,cAAc,UAAU,CAAC,UAAU,QAAQ,SAAS;;AAG5F,SAAgB,qBAAqB,WAA2B;AAC9D,QAAO,KAAK,KAAKA,kBAAgB,EAAE,GAAG,cAAc,UAAU,CAAC,cAAc;;AAG/E,SAAgB,uBAAuB,WAAoC;AACzE,QAAO;EACL,aAAa,uBAAuB,UAAU;EAC9C,eAAA;EACA,mBAAmB;EACnB,cAAA;EACA,eAAe,KAAA;EACf,kBAAkB;EACnB;;;;ACzBH,SAASC,WAAS,OAAqD;AACrE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D;AAEF,QAAO;;AAGT,SAASC,SAAO,QAAgB,KAAsB;AACpD,QAAO,OAAO,UAAU,eAAe,KAAK,QAAQ,IAAI;;AAG1D,SAAS,cAAc,OAAmC;AACxD,QAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,OAAO,UAAU,OAAO,UAAU,SAAS;;AAGlF,SAAS,gBACP,KACkE;AAClE,KAAI,QAAQ,KAAA,KAAa,QAAQ,KAC/B;CAGF,MAAM,SAASD,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH,QAAO;CAGT,MAAM,QAAuD,EAAE;AAQ/D,MAAK,MAAM,SAPgE;EACzE;EACA;EACA;EACA;EACD,EAE2B;EAC1B,MAAM,QAAQ,OAAO;AACrB,MAAI,UAAU,KAAA,EACZ;AAEF,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,MAAM,IAAI,QAAQ,EAClE,QAAO;AAET,QAAM,SAAS;;AAGjB,QAAO;;AAGT,SAAS,uBACP,KAC+D;AAC/D,KAAI,QAAQ,KAAA,KAAa,QAAQ,KAC/B;CAGF,MAAM,SAASA,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH,QAAO;CAGT,MAAM,QAAoD,EAAE;AAC5D,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,EAAE;EACjD,MAAM,SAAS,gBAAgB,MAAM;AACrC,MAAI,UAAU,KACZ,QAAO;AAET,QAAM,OAAO;;AAGf,QAAO;;AAGT,SAAS,sBAAsB,KAAuB;CACpD,MAAM,SAASA,WAAS,IAAI;AAC5B,KAAI,CAAC,UAAU,OAAO,OAAO,WAAW,SACtC,QAAO;AAGT,KAAI,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,KAC/C,QAAO;CAGT,MAAM,OAAOA,WAAS,OAAO,KAAK;AAClC,QACE,CAAC,CAAC,QACF,OAAO,KAAK,UAAU,YACtB,OAAO,SAAS,KAAK,MAAM,IAC3B,OAAO,KAAK,WAAW,YACvB,OAAO,SAAS,KAAK,OAAO;;AAIhC,SAAS,cAAc,KAAuB;CAC5C,MAAM,SAASA,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH,QAAO;AAGT,KAAI,OAAO,OAAO,SAAS,SACzB,QAAO;AAGT,KAAI,OAAO,YAAY,KAAA,GAAW;EAChC,MAAM,UAAUA,WAAS,OAAO,QAAQ;AACxC,SAAO,CAAC,CAAC,WAAW,OAAO,QAAQ,QAAQ,YAAY,OAAO,QAAQ,YAAY;;AAGpF,KAAI,OAAO,UAAU,KAAA,EACnB,QAAO,sBAAsB,OAAO,MAAM;AAG5C,QAAO;;AAGT,SAAS,UAAU,KAAuB;CACxC,MAAM,SAASA,WAAS,IAAI;AAC5B,QACE,CAAC,CAAC,UACF,OAAO,OAAO,OAAO,YACrB,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,cAAc,YAC5BC,SAAO,QAAQ,QAAQ,IACvB,OAAO,OAAO,sBAAsB,cACnC,OAAO,sBAAsB,KAAA,KAC5B,OAAO,sBAAsB,QAC7B,OAAO,OAAO,sBAAsB;;AAI1C,SAAS,oBAAoB,KAAuB;CAClD,MAAM,SAASD,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH,QAAO;AAGT,KAAI,OAAO,OAAO,SAAS,SACzB,QAAO;AAGT,KAAI,OAAO,UAAU,KAAA,EACnB,QAAO,sBAAsB,OAAO,MAAM;AAG5C,QAAO;;AAGT,SAAS,aAAa,KAAuB;CAC3C,MAAM,SAASA,WAAS,IAAI;AAC5B,QACE,CAAC,CAAC,UACF,OAAO,OAAO,gBAAgB,YAC9B,OAAO,OAAO,cAAc,YAC5B,OAAO,OAAO,aAAa,aAC3B,oBAAoB,OAAO,QAAQ;;AAIvC,SAAS,eAAe,KAAuB;CAC7C,MAAM,SAASA,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH,QAAO;AAGT,KAAI,OAAO,OAAO,SAAS,SACzB,QAAO;AAGT,KAAI,OAAO,aAAa,KAAA,GAAW;EACjC,MAAM,WAAWA,WAAS,OAAO,SAAS;AAC1C,SACE,CAAC,CAAC,YACF,OAAO,SAAS,SAAS,aACxB,SAAS,cAAc,KAAA,KACtB,SAAS,cAAc,QACvB,OAAO,SAAS,cAAc;;AAIpC,KAAI,OAAO,OAAO,qBAAqB,SACrC,QAAO;AAGT,KAAI,OAAO,YAAY,KAAA,EACrB,QAAO,UAAU,OAAO,QAAQ;AAGlC,QAAO;;AAGT,SAASE,gBAAc,KAAuB;CAC5C,MAAM,SAASF,WAAS,IAAI;AAC5B,KAAI,CAAC,UAAU,OAAO,SAAS,KAAA,EAC7B,QAAO;CAGT,MAAM,OAAOA,WAAS,OAAO,KAAK;AAClC,QACE,CAAC,CAAC,QACF,OAAO,KAAK,OAAO,YACnB,MAAM,QAAQ,KAAK,QAAQ,IAC3B,KAAK,QAAQ,OAAO,UAAU,cAAc,MAAM,CAAC;;AAIvD,SAASG,iBAAe,KAAuB;CAC7C,MAAM,SAASH,WAAS,IAAI;AAC5B,KAAI,CAAC,UAAU,OAAO,UAAU,KAAA,EAC9B,QAAO;CAGT,MAAM,QAAQA,WAAS,OAAO,MAAM;AACpC,KAAI,CAAC,SAAS,CAAC,MAAM,QAAQ,MAAM,QAAQ,IAAI,CAAC,MAAM,QAAQ,MAAM,eAAe,CACjF,QAAO;CAGT,MAAM,cAAcA,WAAS,MAAM,aAAa;AAChD,KAAI,CAAC,YACH,QAAO;AAGT,QAAO,OAAO,OAAO,YAAY,CAAC,MAAM,aAAa;;AAGvD,SAAS,sBAAsB,KAAuB;AACpD,QAAO,QAAQ,YAAYE,gBAAc,IAAI,IAAIC,iBAAe,IAAI;;AAGtE,SAAS,wBAAwB,QAAkE;AACjG,KACE,CAAC,MAAM,QAAQ,OAAO,SAAS,IAC/B,CAAC,OAAO,SAAS,MAAM,sBAAsB,IAC7C,OAAO,OAAO,eAAe,SAE7B;AAGF,KAAI,OAAO,UAAU,KAAA,KAAa,OAAO,UAAU,QAAQ,OAAO,OAAO,UAAU,SACjF;CAGF,MAAM,uBAAuB,gBAAgB,OAAO,uBAAuB;CAC3E,MAAM,oBAAoB,uBAAuB,OAAO,oBAAoB;AAC5E,KAAI,yBAAyB,QAAQ,sBAAsB,KACzD;AAGF,QAAO;EACL,OACE,OAAO,UAAU,KAAA,KAAa,OAAO,UAAU,QAAQ,OAAO,OAAO,UAAU,WAC3E,OAAO,QACP;EACN,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,wBAAwB,wBAAwB,EAAE;EAClD,qBAAqB,qBAAqB,EAAE;EAC7C;;AAGH,SAAS,eAAe,KAA4C;CAClE,MAAM,SAASH,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH;CAGF,MAAM,QAA0B,EAAE;AAElC,KAAI,OAAO,OAAO,oBAAoB,SACpC,OAAM,kBAAkB,OAAO;AAGjC,KAAI,OAAO,OAAO,oBAAoB,SACpC,OAAM,kBAAkB,OAAO;AAGjC,KAAI,OAAO,OAAO,qBAAqB,SACrC,OAAM,mBAAmB,OAAO;AAGlC,KAAI,cAAc,OAAO,iBAAiB,CACxC,OAAM,mBAAmB,CAAC,GAAG,OAAO,iBAAiB;AAGvD,KAAI,cAAc,OAAO,mBAAmB,CAC1C,OAAM,qBAAqB,CAAC,GAAG,OAAO,mBAAmB;AAG3D,KAAI,MAAM,QAAQ,OAAO,eAAe,CACtC,OAAM,iBAAiB,OAAO;CAGhC,MAAM,iBAAiBA,WAAS,OAAO,gBAAgB;AACvD,KAAI,gBAAgB;EAClB,MAAM,uBAAyE,EAAE;AAEjF,MAAI,OAAO,eAAe,UAAU,SAClC,sBAAqB,QAAQ,eAAe;AAG9C,MAAI,cAAc,eAAe,cAAc,CAC7C,sBAAqB,gBAAgB,CAAC,GAAG,eAAe,cAAc;AAGxE,MACE,OAAO,eAAe,cAAc,YACpC,OAAO,UAAU,eAAe,UAAU,IAC1C,eAAe,YAAY,EAE3B,sBAAqB,YAAY,eAAe;AAGlD,MAAI,OAAO,KAAK,qBAAqB,CAAC,SAAS,EAC7C,OAAM,kBAAkB;;AAI5B,QAAO;;AAGT,SAAS,cAAc,KAAc,WAAoC;CACvE,MAAM,SAASA,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH,QAAO,uBAAuB,UAAU;AAG1C,KACE,OAAO,OAAO,gBAAgB,YAC9B,OAAO,OAAO,kBAAkB,YAChC,CAAC,OAAO,UAAU,OAAO,cAAc,IACvC,OAAO,gBAAgB,KACvB,OAAO,OAAO,sBAAsB,YACpC,CAAC,OAAO,UAAU,OAAO,kBAAkB,IAC3C,OAAO,oBAAoB,KAC3B,OAAO,OAAO,iBAAiB,YAC/B,CAAC,OAAO,UAAU,OAAO,aAAa,IACtC,OAAO,eAAe,EAEtB,QAAO,uBAAuB,UAAU;AAG1C,QAAO;EACL,aAAa,OAAO;EACpB,eAAe,OAAO;EACtB,mBAAmB,OAAO;EAC1B,cAAc,OAAO;EACrB,eAAe,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB,KAAA;EACjF,kBACE,OAAO,oBAAoB,QAAQ,OAAO,OAAO,qBAAqB,WAClE,OAAO,mBACP;EACP;;AAGH,SAAS,sBAAsB,OAA2C;AACxE,KAAI,SAAS,KACX;AAGF,KAAI,OAAO,UAAU,SACnB,QAAO;CAGT,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,SAAS,qBAAqB,OAA2C;AACvE,KAAI,SAAS,KACX;AAGF,KAAI,CAAC,OAAO,UAAU,MAAM,IAAK,SAAoB,EACnD,QAAO;AAGT,QAAO;;AAGT,SAAS,yBAAyB,OAAgB,WAAW,OAAuB;AAClF,KAAI,SAAS,KACX,QAAO;AAET,QAAO,OAAO,UAAU,YAAY,QAAQ;;AAG9C,SAAS,wBAAwB,OAA2C;AAC1E,KAAI,SAAS,KACX;AAEF,QAAO,OAAO,UAAU,WAAW,QAAQ;;AAG7C,SAAS,0BAA0B,OAAoD;AACrF,KAAI,UAAU,KAAA,EACZ;AAEF,KAAI,UAAU,KACZ,QAAO;AAET,KAAI,OAAO,UAAU,MAAM,CACzB,QAAO;AAET,QAAO,OAAO,UAAU;;AAG1B,SAAS,wBAAwB,OAA4D;AAC3F,KAAI,UAAU,KAAA,EACZ;AAEF,KAAI,UAAU,KACZ,QAAO;AAET,KAAI,OAAO,UAAU,SACnB,QAAO;AAET,QAAO,OAAO,UAAU;;AAG1B,SAAgB,mBAAmB,KAAoC;CACrE,MAAM,SAASA,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH,QAAO;AAGT,KAAI,OAAO,WAAA,kBACT,QAAO;CAGT,MAAM,OAAO,sBAAsB,OAAO,KAAK;CAC/C,MAAM,MAAM,qBAAqB,OAAO,IAAI;CAC5C,MAAM,SAAS,yBAAyB,OAAO,QAAQ,MAAM;CAC7D,MAAM,WAAW,wBAAwB,OAAO,UAAU;CAC1D,MAAM,iBAAiB,wBAAwB,OAAO,iBAAiB;CACvE,MAAM,eAAe,wBAAwB,OAAO,eAAe;CACnE,MAAM,oBAAoB,0BAA0B,OAAO,qBAAqB;CAChF,MAAM,sBAAsB,wBAAwB,OAAO,uBAAuB;CAClF,MAAM,kBAAkB,wBAAwB,OAAO,mBAAmB;CAC1E,MAAM,4BAA4B,wBAAwB,OAAO,6BAA6B;AAE9F,KACE,OAAO,OAAO,mBAAmB,YACjC,OAAO,OAAO,mBAAmB,YACjC,OAAO,OAAO,kBAAkB,YAChC,OAAO,OAAO,QAAQ,YACtB,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,iBAAiB,YAC/B,OAAO,OAAO,aAAa,YAC3B,CAAC,OAAO,UAAU,OAAO,SAAS,IAClC,OAAO,WAAW,KAClB,SAAS,QACT,QAAQ,QACR,WAAW,QACX,aAAa,QACb,mBAAmB,QACnB,iBAAiB,QACjB,OAAO,sBAAsB,YAC7B,OAAO,wBAAwB,YAC/B,oBAAoB,QACpB,8BAA8B,KAE9B,QAAO;CAGT,MAAM,eAAe,wBAAwB,OAAO;AACpD,KAAI,CAAC,aACH,QAAO;CAGT,MAAM,WAAW,cAAc,OAAO,WAAW,OAAO,eAAe;CACvE,MAAM,gBAAgB,wBAAwB,OAAO,gBAAgB;AACrE,KAAI,kBAAkB,KACpB,QAAO;AAGT,QAAO;EACL,QAAQ;EACR,cAAc,OAAO;EACrB,cAAc,OAAO;EACrB,gBAAgB,0BAA0B,OAAO,iBAAiB;EAClE,cAAc,OAAO;EACrB,KAAK,OAAO;EACZ;EACA,WAAW,OAAO;EAClB,YAAY,OAAO;EACnB,SAAS,OAAO;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACqB;EACrB;EACA;EACA,iBACE,OAAO,OAAO,qBAAqB,WAAW,OAAO,mBAAmB,KAAA;EAC1E,mBAAmBA,WAAS,OAAO,mBAAmB;EACtD,OAAO,aAAa;EACpB,UAAU,aAAa;EACvB,YAAY,aAAa;EACzB,wBAAwB,aAAa;EACrC,qBAAqB,aAAa;EAClC,MAAM,eAAe,OAAO,KAAK;EAClC;;;;AC9fH,MAAM,uBAAuB;AAmB7B,SAASI,WAAS,OAAqD;AACrE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D;AAEF,QAAO;;AAGT,SAAS,gBAAgB,KAA6C;CACpE,MAAM,SAASA,WAAS,IAAI;AAC5B,KAAI,CAAC,OACH;AAEF,KACE,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,iBAAiB,YAC/B,OAAO,OAAO,iBAAiB,YAC/B,OAAO,OAAO,iBAAiB,YAC/B,OAAO,OAAO,QAAQ,YACtB,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,WAAW,UAEzB;AAEF,KAAI,OAAO,SAAS,KAAA,KAAa,OAAO,OAAO,SAAS,SACtD;AAEF,QAAO;EACL,MAAM,OAAO;EACb,cAAc,OAAO;EACrB,cAAc,OAAO;EACrB,cAAc,OAAO;EACrB,KAAK,OAAO;EACZ,MAAM,OAAO;EACb,QAAQ,OAAO;EACf,YAAY,OAAO;EACpB;;AAGH,SAAgB,iBAAiB,YAA4B;AAC3D,QAAO,KAAK,KAAK,YAAY,aAAa;;AAG5C,SAAgB,oBAAoB,QAAuB,UAAqC;AAC9F,QAAO;EACL,MAAM;EACN,cAAc,OAAO;EACrB,cAAc,OAAO;EACrB,cAAc,OAAO;EACrB,KAAK,OAAO;EACZ,MAAM,OAAO;EACb,QAAQ,OAAO,WAAW;EAC1B,YAAY,OAAO;EACpB;;AAGH,eAAsB,iBAAiB,YAAuD;CAC5F,MAAM,WAAW,iBAAiB,WAAW;AAC7C,KAAI;EACF,MAAM,UAAU,MAAMC,KAAG,SAAS,UAAU,OAAO;EAEnD,MAAM,SAASD,WADA,KAAK,MAAM,QAAQ,CACH;AAC/B,MAAI,CAAC,UAAU,OAAO,WAAW,wBAAwB,CAAC,MAAM,QAAQ,OAAO,MAAM,CACnF;EAEF,MAAM,QAAQ,OAAO,MAAM,QAAQ,UAA2B,OAAO,UAAU,SAAS;AACxF,MAAI,MAAM,WAAW,OAAO,MAAM,UAAU,CAAC,MAAM,QAAQ,OAAO,QAAQ,CACxE;EAEF,MAAM,UAAU,OAAO,QACpB,KAAK,UAAU,gBAAgB,MAAM,CAAC,CACtC,QAAQ,UAAsC,QAAQ,MAAM,CAAC;AAChE,MAAI,QAAQ,WAAW,OAAO,QAAQ,OACpC;AAEF,SAAO;GACL,QAAQ;GACR;GACA;GACD;SACK;AACN;;;AAIJ,eAAsB,kBACpB,YACA,OAIe;CACf,MAAM,WAAW,iBAAiB,WAAW;CAC7C,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,IAAI,GAAG,KAAK,KAAK,CAAC;CAC1D,MAAM,UAAU,KAAK,UACnB;EACE,QAAQ;EACR,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC,UAAU;EAClC,SAAS,CAAC,GAAG,MAAM,QAAQ,CAAC,UAAU,GAAG,MAAM,EAAE,WAAW,cAAc,EAAE,WAAW,CAAC;EACzF,EACD,MACA,EACD;AACD,OAAMC,KAAG,UAAU,UAAU,GAAG,QAAQ,KAAK,OAAO;AACpD,OAAMA,KAAG,OAAO,UAAU,SAAS;;AAGrC,eAAsB,oBAAoB,YAA2C;CAEnF,MAAM,SADU,MAAMA,KAAG,QAAQ,YAAY,EAAE,eAAe,MAAM,CAAC,EAElE,QACE,UAAU,MAAM,QAAQ,IAAI,MAAM,KAAK,SAAS,QAAQ,IAAI,MAAM,SAAS,aAC7E,CACA,KAAK,UAAU,MAAM,KAAK,CAC1B,UAAU;CAEb,MAAM,eAAoC,EAAE;AAC5C,MAAK,MAAM,QAAQ,MACjB,KAAI;EACF,MAAM,UAAU,MAAMA,KAAG,SAAS,KAAK,KAAK,YAAY,KAAK,EAAE,OAAO;EACtE,MAAM,SAAS,mBAAmB,KAAK,MAAM,QAAQ,CAAC;AACtD,MAAI,CAAC,OACH;AAEF,eAAa,KAAK,oBAAoB,QAAQ,KAAK,CAAC;SAC9C;CAKV,MAAM,QAAsB;EAC1B,QAAQ;EACR;EACA,SAAS;EACV;AACD,OAAM,kBAAkB,YAAY,MAAM;AAC1C,QAAO;;AAGT,eAAsB,0BAA0B,YAA2C;CACzF,MAAM,SAAS,MAAMA,KAAG,QAAQ,YAAY,EAAE,eAAe,MAAM,CAAC,EACjE,QACE,UAAU,MAAM,QAAQ,IAAI,MAAM,KAAK,SAAS,QAAQ,IAAI,MAAM,SAAS,aAC7E,CACA,KAAK,UAAU,MAAM,KAAK,CAC1B,UAAU;CACb,MAAM,WAAW,MAAM,iBAAiB,WAAW;AACnD,KACE,YACA,SAAS,MAAM,WAAW,MAAM,UAChC,SAAS,MAAM,OAAO,MAAM,UAAU,SAAS,MAAM,OAAO,CAE5D,QAAO;AAET,QAAO,MAAM,oBAAoB,WAAW;;;;AC/J9C,MAAa,wBAAwB;AAgBrC,SAAS,gBAAgB,cAA8B;CACrD,MAAM,SAAS,mBAAmB,aAAa;AAC/C,QAAO,KAAK,KAAK,gBAAgB,EAAE,GAAG,OAAO,OAAO;;AAGtD,SAAS,iBAAyB;AAChC,QAAO,KAAK,KAAK,GAAG,SAAS,EAAE,SAAS,WAAW;;AAGrD,eAAe,mBAAkC;AAC/C,OAAMC,KAAG,MAAM,gBAAgB,EAAE,EAAE,WAAW,MAAM,CAAC;;AAGvD,eAAe,yBACb,OACoC;AACpC,KAAI;EACF,MAAM,UAAU,MAAMA,KAAG,SAAS,KAAK,KAAK,gBAAgB,EAAE,MAAM,KAAK,EAAE,OAAO;AAClF,SAAO,mBAAmB,KAAK,MAAM,QAAQ,CAAC,IAAI,KAAA;SAC5C;AACN;;;AAIJ,eAAe,0BAAwD;AACrE,OAAM,kBAAkB;AAIxB,SAHc,MAAM,YAAY,sBAAsB,YAAY;AAChE,SAAO,MAAM,0BAA0B,gBAAgB,CAAC;GACxD,EACW;;AAGf,SAAS,oBACP,SACA,eACA,gBACA,gBAAgB,OACP;AACT,KAAI,QAAQ,QAAQ,cAClB,QAAO;AAET,KAAI,CAAC,iBAAiB,QAAQ,OAC5B,QAAO;AAET,KAAI,kBAAkB,KACpB,QAAO,QAAQ,QAAQ;AAEzB,QAAO,QAAQ,SAAS;;AAG1B,eAAsB,mBAAmB,QAAsC;AAC7E,OAAM,YAAY,wBAAwB,YAAY;AACpD,QAAM,kBAAkB;EAExB,MAAM,YAAY,8BAA8B,OAAO;AACvD,2BAAyB,UAAU;EAEnC,MAAM,OAAO,gBAAgB,OAAO,aAAa;EACjD,MAAM,WAAW,GAAG,KAAK,GAAG,QAAQ,IAAI,GAAG,KAAK,KAAK,CAAC;EACtD,MAAM,UAAU,KAAK,UAAU,WAAW,MAAM,EAAE;AAClD,QAAMA,KAAG,UAAU,UAAU,GAAG,QAAQ,KAAK,OAAO;AACpD,QAAMA,KAAG,OAAO,UAAU,KAAK;EAE/B,MAAM,aAAa,gBAAgB;EACnC,MAAM,QAAQ,MAAM,0BAA0B,WAAW;EACzD,MAAM,WAAW,KAAK,SAAS,KAAK;EACpC,MAAM,UAAU,MAAM,QAAQ,QAAQ,UAAU,MAAM,SAAS,SAAS;AACxE,UAAQ,KAAK,oBAAoB,QAAQ,SAAS,CAAC;AAEnD,QAAM,kBAAkB,YAAY;GAAE,OADxB,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,MAAM,MAAM,QAAQ,UAAU,UAAU,SAAS,EAAE,SAAS,CAAC,CAAC;GAC/C;GAAS,CAAC;GACvD;;AAGJ,eAAsB,qBAAqB,WAA2C;AACpF,OAAM,kBAAkB;CAExB,MAAM,aAAa,gBAAgB,UAAU;AAC7C,KAAI;EACF,MAAM,gBAAgB,MAAM,YAAY,0BAA0B,YAAY;AAC5E,UAAO,MAAMA,KAAG,SAAS,YAAY,OAAO;IAC5C;EACF,MAAM,eAAe,mBAAmB,KAAK,MAAM,cAAc,CAAC;AAClE,MAAI,aACF,QAAO;SAEH;CAIR,MAAM,UAAU,MAAM,yBAAyB;CAC/C,MAAM,eAAe,QAAQ,QAC1B,UAAU,MAAM,iBAAiB,aAAa,MAAM,iBAAiB,UACvE;CACD,MAAM,gBACJ,MAAM,QAAQ,IAAI,aAAa,KAAK,UAAU,yBAAyB,MAAM,CAAC,CAAC,EAC/E,QAAQ,UAAkC,QAAQ,MAAM,CAAC;AAC3D,KAAI,aAAa,WAAW,EAC1B,QAAO,aAAa;AAEtB,KAAI,aAAa,SAAS,EACxB,OAAM,IAAI,uBAAuB,+BAA+B,YAAY;CAG9E,MAAM,gBAAgB,QAAQ,QAC3B,UAAU,MAAM,aAAa,SAAS,UAAU,IAAI,MAAM,aAAa,SAAS,UAAU,CAC5F;CACD,MAAM,iBACJ,MAAM,QAAQ,IAAI,cAAc,KAAK,UAAU,yBAAyB,MAAM,CAAC,CAAC,EAChF,QAAQ,UAAkC,QAAQ,MAAM,CAAC;AAC3D,KAAI,cAAc,WAAW,EAC3B,QAAO,cAAc;AAEvB,KAAI,cAAc,SAAS,EACzB,OAAM,IAAI,uBAAuB,4BAA4B,YAAY;AAG3E,sBAAqB,uBAAuB;AAC5C,OAAM,IAAI,qBAAqB,UAAU;;AAG3C,SAAS,gBAAgB,KAAsB;CAC7C,MAAM,UAAU,KAAK,KAAK,KAAK,OAAO;AACtC,KAAI;AACF,SAAO,SAAS,QAAQ,CAAC,aAAa;SAChC;AACN,SAAO;;;AAIX,SAAS,iBAAiB,UAAkB,QAAyB;CACnE,MAAM,WAAW,KAAK,SAAS,UAAU,OAAO;AAChD,QAAO,SAAS,WAAW,KAAM,CAAC,SAAS,WAAW,KAAK,IAAI,CAAC,KAAK,WAAW,SAAS;;AAG3F,SAAgB,aAAa,OAAuB;AAClD,QAAO,KAAK,QAAQ,MAAM;;AAG5B,SAAgB,sBAAsB,UAAsC;CAC1E,IAAI,UAAU,aAAa,SAAS;CACpC,MAAM,OAAO,KAAK,MAAM,QAAQ,CAAC;AAEjC,UAAS;AACP,MAAI,gBAAgB,QAAQ,CAC1B,QAAO;AAGT,MAAI,YAAY,KACd;EAGF,MAAM,SAAS,KAAK,QAAQ,QAAQ;AACpC,MAAI,WAAW,QACb;AAEF,YAAU;;;AAId,SAAgB,cAAc,OAA+C;AAC3E,KAAI,SAAS,KACX;CAGF,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,SAAgBC,WAAiB;AAC/B,yBAAO,IAAI,MAAM,EAAC,aAAa;;AAGjC,eAAsB,eAAyC;AAC7D,OAAM,kBAAkB;CACxB,MAAM,UAAU,MAAM,yBAAyB;CAC/C,MAAM,UAA2B,EAAE;AAEnC,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,SAAS,MAAM,yBAAyB,MAAM;AACpD,MAAI,OACF,SAAQ,KAAK,OAAO;;AAIxB,SAAQ,MAAM,GAAG,MAAM,EAAE,WAAW,cAAc,EAAE,WAAW,CAAC;AAChE,QAAO;;AAGT,eAAsB,qBAAqB,cAAgD;CACzF,MAAM,WAAW,MAAM,yBAAyB,EAAE,QAC/C,YAAY,QAAQ,iBAAiB,aACvC;AAED,SADgB,MAAM,QAAQ,IAAI,QAAQ,KAAK,UAAU,yBAAyB,MAAM,CAAC,CAAC,EAEvF,QAAQ,UAAkC,QAAQ,MAAM,CAAC,CACzD,UAAU,GAAG,MAAM,EAAE,WAAW,cAAc,EAAE,WAAW,CAAC;;AAGjE,eAAsB,YAAY,SAAiE;CACjG,MAAM,gBAAgB,aAAa,QAAQ,IAAI;CAC/C,MAAM,iBAAiB,cAAc,QAAQ,KAAK;CAElD,MAAM,SADU,MAAM,yBAAyB,EACzB,MACnB,YACC,QAAQ,iBAAiB,QAAQ,gBACjC,oBAAoB,SAAS,eAAe,gBAAgB,QAAQ,cAAc,CACrF;AACD,KAAI,CAAC,MACH;AAEF,QAAO,MAAM,yBAAyB,MAAM;;AAG9C,eAAsB,2BACpB,SACoC;CACpC,MAAM,iBAAiB,cAAc,QAAQ,KAAK;CAClD,MAAM,kBAAkB,aAAa,QAAQ,IAAI;CACjD,MAAM,qBAAqB,aAAa,QAAQ,YAAY,gBAAgB;CAC5E,MAAM,eAAe,iBAAiB,oBAAoB,gBAAgB,GACtE,qBACA;CACJ,MAAM,YAAY,MAAM,yBAAyB,EAAE,QAChD,YAAY,QAAQ,iBAAiB,QAAQ,aAC/C;CAED,IAAI,UAAU;CACd,MAAM,WAAW,KAAK,MAAM,QAAQ,CAAC;AAErC,UAAS;EACP,MAAM,QAAQ,SAAS,MAAM,YAAY,oBAAoB,SAAS,SAAS,eAAe,CAAC;AAC/F,MAAI,MACF,QAAO,MAAM,yBAAyB,MAAM;AAG9C,MAAI,YAAY,gBAAgB,YAAY,SAC1C;EAGF,MAAM,SAAS,KAAK,QAAQ,QAAQ;AACpC,MAAI,WAAW,QACb;AAGF,YAAU;AAEV,MAAI,CAAC,iBAAiB,cAAc,QAAQ,CAC1C;;;;;ACjRN,eAAsB,oBAAoB,SAAoD;AAC5F,KAAI,CAAC,QAAQ,MAAM,SAAS,CAAC,QAAQ,OAAO,MAC1C,QAAO;AAGT,KAAI,QAAQ,OACV,SAAQ,OAAO,MAAM,KAAK,QAAQ,OAAO,IAAI;AAE/C,KAAI,QAAQ,WAAW,QAAQ,QAAQ,MAAM,CAAC,SAAS,EACrD,SAAQ,OAAO,MAAM,GAAG,QAAQ,QAAQ,IAAI;CAG9C,MAAM,KAAK,SAAS,gBAAgB;EAClC,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;AAEF,KAAI;EAEF,MAAM,cADS,MAAM,GAAG,SAAS,QAAQ,OAAO,EACtB,MAAM,CAAC,aAAa;AAC9C,SAAO,eAAe,OAAO,eAAe;WACpC;AACR,KAAG,OAAO;;;;;AClBd,MAAM,0BAA0B;AAChC,MAAM,0BAA0B;AAUhC,SAASC,WAAiB;AACxB,yBAAO,IAAI,MAAM,EAAC,aAAa;;AAGjC,SAAS,aAAa,SAAiB,YAA6B;CAClE,MAAM,WAAW,KAAK,SAAS,SAAS,WAAW;AACnD,QAAO,SAAS,WAAW,KAAM,CAAC,SAAS,WAAW,KAAK,IAAI,CAAC,KAAK,WAAW,SAAS;;AAG3F,SAAS,eAAe,SAAyB;CAE/C,MAAM,QADa,QAAQ,QAAQ,SAAS,KAAK,CACxB,MAAM,KAAK;CACpC,MAAM,eAAe,MAAM,MAAM,GAAG,wBAAwB;CAC5D,IAAI,UAAU,aAAa,KAAK,KAAK;AAErC,KAAI,MAAM,SAAS,aAAa,OAC9B,YAAW,UAAU,MAAM,SAAS,aAAa,OAAO;AAG1D,KAAI,QAAQ,SAAS,wBACnB,WAAU,GAAG,QAAQ,MAAM,GAAG,0BAA0B,EAAE,CAAC;AAG7D,QAAO;;AAGT,eAAe,oBAAoB,UAAkB,SAAmC;AACtF,QAAO,MAAM,oBAAoB;EAC/B,QAAQ,+BAA+B,SAAS;EAChD,SAAS;EACT,QAAQ;EACT,CAAC;;AAGJ,SAASC,2BAAkC;AACzC,QAAO,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO,MAAM;;AAG7D,IAAa,qBAAb,MAAgC;CAC9B;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAoC;AAC9C,OAAK,UAAU,KAAK,QAAQ,QAAQ,IAAI;AACxC,OAAK,iBAAiB,QAAQ;AAC9B,OAAK,4BAA4B,QAAQ,6BAA6B;AACtE,OAAK,cAAc,QAAQ;AAC3B,OAAK,0BAA0B,QAAQ,gBAAgB;AACvD,OAAK,eAAe,QAAQ,gBAAgB;;CAG9C,uBACE,gBACA,2BACM;AACN,OAAK,iBAAiB;AACtB,OAAK,4BAA4B,6BAA6B;;CAGhE,MAAM,aAAa,QAA4D;EAC7E,MAAM,WAAW,KAAK,sBAAsB,OAAO,KAAK;EACxD,MAAM,UAAU,mBAAmB;AACnC,OAAK,cAAc;GACjB,QAAQ;GACR,QAAQ;GACR;GACA,SAAS,KAAK,kBAAkB,OAAO,MAAM,OAAO,MAAM;GAC1D,WAAWD,UAAQ;GACpB,CAAC;AAEF,MAAI;AACF,OAAI,KAAK,mBAAmB,WAC1B,OAAM,IAAI,sBAAsB,uDAAuD;GAGzF,MAAM,UAAU,MAAME,KAAG,SAAS,UAAU,OAAO;GACnD,MAAM,SAAS,KAAK,aAAa,SAAS,OAAO,MAAM,OAAO,MAAM;AAEpE,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS,KAAK,kBAAkB,OAAO,MAAM,OAAO,MAAM;IAC1D,WAAWF,UAAQ;IACpB,CAAC;AACF,UAAO,EAAE,SAAS,QAAQ;WACnB,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS;IACT,WAAWA,UAAQ;IACpB,CAAC;AACF,SAAM;;;CAIV,MAAM,cAAc,QAA8D;EAChF,MAAM,WAAW,KAAK,sBAAsB,OAAO,KAAK;EACxD,MAAM,UAAU,eAAe,OAAO,QAAQ;EAC9C,MAAM,UAAU,oBAAoB;AAEpC,OAAK,cAAc;GACjB,QAAQ;GACR,QAAQ;GACR;GACA,SAAS;GACT,WAAWA,UAAQ;GACpB,CAAC;AAEF,MAAI;AACF,OAAI,CAAE,MAAM,KAAK,gBAAgB,UAAU,QAAQ,CACjD,OAAM,IAAI,sBAAsB,2CAA2C;AAG7E,SAAME,KAAG,MAAM,KAAK,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AAC3D,SAAMA,KAAG,UAAU,UAAU,OAAO,SAAS,OAAO;AAEpD,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS;IACT,WAAWF,UAAQ;IACpB,CAAC;AACF,UAAO,EAAE;WACF,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS;IACT,WAAWA,UAAQ;IACpB,CAAC;AACF,SAAM;;;CAIV,MAAc,gBAAgB,UAAkB,SAAmC;AACjF,MAAI,KAAK,mBAAmB,cAC1B,QAAO;AAET,MAAI,KAAK,mBAAmB,WAC1B,QAAO;AAET,MACE,KAAK,2BACL,KAAK,8BAA8B,UACnC,CAACC,0BAAwB,CAEzB,OAAM,IAAI,kCAAkC;AAE9C,SAAO,MAAM,KAAK,aAAa,UAAU,QAAQ;;CAGnD,sBAA8B,SAAyB;AACrD,MAAI,CAAC,KAAK,WAAW,QAAQ,CAC3B,OAAM,IAAI,MAAM,0BAA0B,UAAU;EAEtD,MAAM,WAAW,KAAK,QAAQ,QAAQ;AACtC,MAAI,CAAC,aAAa,KAAK,SAAS,SAAS,CACvC,OAAM,IAAI,MAAM,wCAAwC,WAAW;AAErE,SAAO;;CAGT,aACE,SACA,MACA,OACQ;AACR,MAAI,QAAQ,QAAQ,SAAS,KAC3B,QAAO;EAGT,MAAM,QAAQ,QAAQ,MAAM,KAAK;EAEjC,MAAM,aAAa,KAAK,IAAI,IADV,QAAQ,OAAO,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,IACvB,EAAE;EAC7C,MAAM,WAAW,SAAS,OAAO,KAAA,IAAY,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC;AAE3E,MAAI,aAAa,EACf,QAAO;EAGT,MAAM,WACJ,YAAY,OAAO,MAAM,SAAS,KAAK,IAAI,MAAM,QAAQ,aAAa,SAAS;AAEjF,SAAO,MAAM,MAAM,YAAY,SAAS,CAAC,KAAK,KAAK;;CAGrD,kBACE,MACA,OACoB;AACpB,MAAI,QAAQ,QAAQ,SAAS,KAC3B;AAIF,SAAO,QAFO,QAAQ,OAAO,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,CAEzC,UADT,SAAS,OAAO,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC;;CAIpE,cAAsB,WAAkC;AACtD,OAAK,cAAc,UAAU;;;;;AC9NjC,MAAM,uBAAuD;CAC3D,YAAY;CACZ,iBAAiB;CACjB,eAAe;CAChB;AAED,SAAS,SAAS,UAA6C;AAC7D,QAAO,EAAE,SAAS;EAAE,SAAS;EAAY;EAAU,EAAE;;AAGvD,SAAS,YAAuC;AAC9C,QAAO,EAAE,SAAS,EAAE,SAAS,aAAa,EAAE;;AAG9C,SAAS,WACP,SACA,OAC8B;AAC9B,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,QAAQ,MAAM,WAAW,OAAO,SAAS,KAAK;AAC5D,MAAI,MACF,QAAO;;;AAMb,SAAS,cAAc,QAAwD;AAC7E,KAAI,OAAO,SAAS,KAClB,QAAO,OAAO,SAAS;CAGzB,MAAM,QAAQ,OAAO,SAAS,OAAO,MAAM,CAAC,aAAa;AACzD,KAAI,CAAC,MACH;CAGF,MAAM,OAAO,MAAM,MAAM,KAAK,EAAE,CAAC,IAAI,MAAM;AAC3C,KAAI,CAAC,KACH;AAGF,KAAI,KAAK,SAAS,OAAO,IAAI,KAAK,SAAS,MAAM,CAC/C,QAAO;AAET,KAAI,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,OAAO,IAAI,KAAK,SAAS,OAAO,CAC3E,QAAO;AAET,KAAI,KAAK,SAAS,QAAQ,IAAI,KAAK,SAAS,OAAO,IAAI,KAAK,SAAS,QAAQ,CAC3E,QAAO;AAET,KAAI,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,SAAS,CACpD,QAAO;AAET,KAAI,KAAK,SAAS,OAAO,IAAI,KAAK,SAAS,SAAS,CAClD,QAAO;AAET,KAAI,KAAK,SAAS,MAAM,IAAI,KAAK,SAAS,UAAU,IAAI,KAAK,SAAS,OAAO,CAC3E,QAAO;AAET,KAAI,KAAK,SAAS,QAAQ,IAAI,KAAK,SAAS,OAAO,IAAI,KAAK,SAAS,MAAM,CACzE,QAAO;AAET,KAAI,KAAK,SAAS,QAAQ,CACxB,QAAO;AAGT,QAAO;;AAGT,SAAS,uBAAuB,MAAqC;AACnE,QAAO,SAAS,UAAU,SAAS;;AAGrC,eAAe,wBAAwB,QAAoD;AAGzF,QAAO,MAAM,oBAAoB,EAC/B,QAAQ,wBAHO,OAAO,SAAS,SAAS,OAGC,IAF1B,cAAc,OAAO,IAAI,QAEc,YACvD,CAAC;;AAGJ,SAASE,2BAAkC;AACzC,QAAO,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO,MAAM;;AAG7D,SAAgB,wBAAwB,QAAwB,UAAmC;AACjG,QAAO,qBAAqB,WAAW,qBAAqB;;AAG9D,eAAsB,yBACpB,QACA,MACA,uBAAuD,QACnB;CACpC,MAAM,UAAU,OAAO,WAAW,EAAE;AACpC,KAAI,QAAQ,WAAW,EACrB,QAAO,WAAW;CAGpB,MAAM,cAAc,WAAW,SAAS,CAAC,cAAc,eAAe,CAAC;CACvE,MAAM,eAAe,WAAW,SAAS,CAAC,eAAe,gBAAgB,CAAC;AAE1E,KAAI,SAAS,eAAe;AAC1B,MAAI,YACF,QAAO,SAAS,YAAY,SAAS;AAEvC,SAAO,SAAS,QAAQ,GAAG,SAAS;;AAGtC,KAAI,SAAS,YAAY;AACvB,MAAI,aACF,QAAO,SAAS,aAAa,SAAS;AAExC,SAAO,WAAW;;AAIpB,KAAI,uBADS,cAAc,OAAO,CACF,IAAI,YAClC,QAAO,SAAS,YAAY,SAAS;AAGvC,KAAI,CAACA,0BAAwB,EAAE;AAC7B,MAAI,yBAAyB,OAC3B,OAAM,IAAI,kCAAkC;AAE9C,MAAI,aACF,QAAO,SAAS,aAAa,SAAS;AAExC,SAAO,WAAW;;CAGpB,MAAM,WAAW,MAAM,wBAAwB,OAAO;AACtD,KAAI,YAAY,YACd,QAAO,SAAS,YAAY,SAAS;AAEvC,KAAI,CAAC,YAAY,aACf,QAAO,SAAS,aAAa,SAAS;AAExC,QAAO,WAAW;;AAGpB,SAAgB,2BACd,QACA,UACoB;AACpB,KAAI,SAAS,QAAQ,YAAY,WAC/B,QAAO;CAGT,MAAM,mBAAmB,SAAS,QAAQ;CAC1C,MAAM,iBAAiB,OAAO,QAAQ,MAAM,WAAW,OAAO,aAAa,iBAAiB;AAE5F,KAAI,CAAC,eACH,QAAO;AAGT,KAAI,eAAe,SAAS,gBAAgB,eAAe,SAAS,eAClE,QAAO;AAGT,QAAO;;;;ACxKT,SAAS,oBAAoB,KAAwB,KAAiC;CACpF,MAAM,aAAa,OAAO,KAAK,IAAI,CAAC,MAAM,UAAU,MAAM,aAAa,KAAK,IAAI;AAChF,QAAO,aAAa,IAAI,cAAc,KAAA;;AAGxC,SAAS,sBACP,SACA,MAAyB,QAAQ,KACb;CACpB,MAAM,cAAc,oBAAoB,KAAK,UAAU,IAAI,uBACxD,MAAM,IAAI,CACV,KAAK,UAAU,MAAM,MAAM,CAAC,aAAa,CAAC,CAC1C,QAAQ,UAAU,MAAM,SAAS,EAAE;CAEtC,MAAM,aADmB,KAAK,QAAQ,QAAQ,CAE3B,SAAS,IACtB,CAAC,QAAQ,GACT,WAAW,KAAK,cAAc,GAAG,UAAU,YAAY;AAG7D,KAFgB,QAAQ,SAAS,IAAI,IAAI,QAAQ,SAAS,KAAK,IAAI,KAAK,WAAW,QAAQ,CAGzF,QAAO,WAAW,MAAM,cAAc,GAAG,WAAW,UAAU,CAAC;CAGjE,MAAM,YAAY,oBAAoB,KAAK,OAAO;AAClD,KAAI,CAAC,UACH;AAGF,MAAK,MAAM,aAAa,UAAU,MAAM,IAAI,EAAE;EAC5C,MAAM,mBAAmB,UAAU,MAAM;AACzC,MAAI,iBAAiB,WAAW,EAC9B;AAEF,OAAK,MAAM,aAAa,YAAY;GAClC,MAAM,WAAW,KAAK,KAAK,kBAAkB,UAAU;AACvD,OAAI,GAAG,WAAW,SAAS,CACzB,QAAO;;;;AAQf,SAAS,2BACP,SACA,WAA4B,QAAQ,UACpC,MAAyB,QAAQ,KACxB;AACT,KAAI,aAAa,QACf,QAAO;CAET,MAAM,kBAAkB,sBAAsB,SAAS,IAAI,IAAI;CAC/D,MAAM,MAAM,KAAK,QAAQ,gBAAgB,CAAC,aAAa;AACvD,QAAO,QAAQ,UAAU,QAAQ;;AAGnC,SAAgB,yBACd,SACA,SACA,WAA4B,QAAQ,UACpC,MAAyB,QAAQ,KACJ;AAC7B,KAAI,CAAC,2BAA2B,SAAS,UAAU,IAAI,CACrD,QAAO;AAET,QAAO;EACL,GAAG;EACH,OAAO;EACR;;;;ACjEH,SAAgBC,WAAiB;AAC/B,yBAAO,IAAI,MAAM,EAAC,aAAa;;AAGjC,SAAgBC,eAAa,OAAoC;AAC/D,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,gBAAgB;AACpB,SAAM,IAAI,SAAS,QAAQ;AAC3B,YAAS;;EAEX,MAAM,WAAW,UAAiB;AAChC,SAAM,IAAI,SAAS,QAAQ;AAC3B,UAAO,MAAM;;AAGf,QAAM,KAAK,SAAS,QAAQ;AAC5B,QAAM,KAAK,SAAS,QAAQ;GAC5B;;AAGJ,SAAgB,sBAAsB,OAA8B;AAClE,QAAO,MAAM,YAAY,QAAQ,MAAM,cAAc;;AAGvD,SAAgB,kBACd,OACmD;AACnD,KAAI,CAAC,MAAM,SAAS,CAAC,MAAM,UAAU,CAAC,MAAM,OAC1C,OAAM,IAAI,MAAM,2DAA2D;AAE7E,QAAO;;AAGT,SAAgB,iBACd,OACA,WACkB;AAClB,KAAI,CAAC,sBAAsB,MAAM,CAC/B,QAAO,QAAQ,QAAQ,KAAK;AAG9B,QAAO,IAAI,SAAkB,YAAY;EACvC,IAAI,UAAU;EACd,MAAM,QAAQ,iBACN;AACJ,UAAO,MAAM;KAEf,KAAK,IAAI,GAAG,UAAU,CACvB;EAED,MAAM,UAAU,UAAmB;AACjC,OAAI,QACF;AAEF,aAAU;AACV,SAAM,IAAI,SAAS,WAAW;AAC9B,SAAM,IAAI,QAAQ,WAAW;AAC7B,gBAAa,MAAM;AACnB,WAAQ,MAAM;;EAGhB,MAAM,mBAAmB;AACvB,UAAO,KAAK;;AAGd,QAAM,KAAK,SAAS,WAAW;AAC/B,QAAM,KAAK,QAAQ,WAAW;GAC9B;;AAGJ,SAAgB,iBAAiB,OAA6B;CAC5D,MAAM,QAAkB,EAAE;CAC1B,IAAI,UAAU;CACd,IAAI,QAA0B;CAC9B,IAAI,WAAW;AAEf,MAAK,MAAM,MAAM,OAAO;AACtB,MAAI,UAAU;AACZ,cAAW;AACX,cAAW;AACX;;AAGF,MAAI,OAAO,QAAQ,UAAU,KAAK;AAChC,cAAW;AACX;;AAGF,MAAI,OAAO;AACT,OAAI,OAAO,MACT,SAAQ;OAER,YAAW;AAEb;;AAGF,MAAI,OAAO,OAAO,OAAO,MAAK;AAC5B,WAAQ;AACR;;AAGF,MAAI,KAAK,KAAK,GAAG,EAAE;AACjB,OAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,QAAQ;AACnB,cAAU;;AAEZ;;AAGF,aAAW;;AAGb,KAAI,SACF,YAAW;AAGb,KAAI,MACF,OAAM,IAAI,MAAM,8CAA8C;AAGhE,KAAI,QAAQ,SAAS,EACnB,OAAM,KAAK,QAAQ;AAGrB,KAAI,MAAM,WAAW,EACnB,OAAM,IAAI,MAAM,yCAAyC;AAG3D,QAAO;EACL,SAAS,MAAM;EACf,MAAM,MAAM,MAAM,EAAE;EACrB;;AAGH,SAAgB,cAAc,KAAqB;AACjD,QAAO,KAAK,QAAQ,IAAI;;AAG1B,SAAgB,cAAc,OAAuB;AACnD,QAAO,KACJ,SAAS,MAAM,CACf,aAAa,CACb,QAAQ,qBAAqB,GAAG;;;;AClJrC,MAAM,yCAAyC;AAC/C,MAAM,uCAAuC;AAC7C,MAAM,gCAAgC;AACtC,MAAM,uCAAuC;AAC7C,MAAM,4BAA4B;AAClC,MAAM,0BAA0B;CAAC;CAAG;CAAI;CAAE;AAC1C,MAAM,0BAA0B;AAOhC,MAAM,4BAA4B,IAAI,IAAI,CACxC,uDACA,gCACD,CAAC;AAEF,SAAgB,iCAAiC,cAA8B;CAC7E,MAAM,EAAE,YAAY,iBAAiB,aAAa;AAClD,QAAO,cAAc,QAAQ,KAAK,aAC9B,uCACA;;AAGN,SAAgB,mCACd,cACA,aACS;CACT,MAAM,EAAE,YAAY,iBAAiB,aAAa;AAClD,QAAO,cAAc,QAAQ,KAAK,cAAc,0BAA0B,IAAI,YAAY;;AAG5F,SAAgB,mBAAmB,SAAiB,MAAkC;AACpF,QACE,cAAc,QAAQ,KAAK,aAC1B,KAAK,SAAS,QAAQ,IAAI,KAAK,SAAS,qBAAqB;;AAIlE,SAAgB,mBAAmB,SAAiB,MAAkC;AAEpF,KADqB,cAAc,QAAQ,KACtB,mBACnB,QAAO;AAET,QAAO,KAAK,MAAM,QAAQ,IAAI,SAAS,mBAAmB,CAAC;;AAG7D,SAAgB,oBAAoB,SAAiB,MAAkC;AACrF,QAAO,cAAc,QAAQ,KAAK,aAAa,KAAK,SAAS,QAAQ;;AAGvE,SAAgB,kBAAkB,SAAiB,MAAkC;AACnF,QAAO,cAAc,QAAQ,KAAK,cAAc,KAAK,SAAS,QAAQ;;AAGxE,SAAS,eAAe,MAAyB,UAA2B;AAC1E,QAAO,KAAK,MAAM,QAAQ,QAAQ,YAAY,IAAI,WAAW,GAAG,SAAS,GAAG,CAAC;;AAG/E,SAAS,8BAA8B,MAAsB;AAC3D,SAAQ,KAAK,MAAM,CAAC,aAAa,EAAjC;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,QACH,QAAO,KAAK,MAAM,CAAC,aAAa;EAClC,QACE,QAAO,KAAK,MAAM;;;AAIxB,SAAgB,yBACd,aACA,SACU;CACV,MAAM,OAAO,CAAC,GAAG,YAAY;CAC7B,MAAM,iBAAiB,QAAQ;AAE/B,KAAI,OAAO,gBAAgB,aAAa,YAAY,CAAC,eAAe,MAAM,cAAc,CACtF,MAAK,KAAK,eAAe,eAAe,WAAW;AAGrD,KACE,MAAM,QAAQ,gBAAgB,aAAa,IAC3C,CAAC,eAAe,MAAM,kBAAkB,IACxC,CAAC,eAAe,MAAM,qBAAqB,EAC3C;EACA,MAAM,eAAe,eAAe,aAAa,IAAI,8BAA8B,CAAC,KAAK,IAAI;AAC7F,OAAK,KAAK,mBAAmB,eAAe;;AAG9C,QAAO;;AAGT,SAAgB,mCAA2C;CACzD,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,OAAO,QAAQ,YAAY,IAAI,MAAM,CAAC,SAAS,GAAG;EACpD,MAAM,SAAS,OAAO,IAAI;AAC1B,MAAI,OAAO,SAAS,OAAO,IAAI,SAAS,EACtC,QAAO,KAAK,MAAM,OAAO;;AAG7B,QAAO;;AAGT,SAAgB,yCAAiD;CAC/D,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,OAAO,QAAQ,YAAY,IAAI,MAAM,CAAC,SAAS,GAAG;EACpD,MAAM,SAAS,OAAO,IAAI;AAC1B,MAAI,OAAO,SAAS,OAAO,IAAI,SAAS,EACtC,QAAO,KAAK,MAAM,OAAO;;AAG7B,QAAO;;AAGT,SAAS,mBAAmB,OAAsD;AAChF,KAAI,OAAO,UAAU,SACnB;CAGF,MAAM,aAAa,MAAM,MAAM;CAC/B,MAAM,QAAQ,WAAW,MAAM,sBAAsB;AACrD,KAAI,CAAC,MACH;AAGF,QAAO;EACL,KAAK;EACL,OAAO;GAAC,OAAO,MAAM,GAAG;GAAE,OAAO,MAAM,GAAG;GAAE,OAAO,MAAM,GAAG;GAAC;EAC9D;;AAGH,SAAS,oBAAoB,MAAyB,OAAkC;AACtF,MAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,IAAI,KAAK,QAAQ,MAAM,OAAO,EAAE,SAAS,GAAG;EAC3E,MAAM,WAAW,KAAK,UAAU;EAChC,MAAM,YAAY,MAAM,UAAU;AAClC,MAAI,aAAa,UACf,QAAO,WAAW;;AAGtB,QAAO;;AAGT,eAAe,oBAAoB,SAAqD;AACtF,QAAO,MAAM,IAAI,SAAoC,YAAY;EAC/D,MAAM,QAAQ,MACZ,SACA,CAAC,YAAY,EACb,yBAAyB,SAAS;GAChC,OAAO;IAAC;IAAU;IAAQ;IAAO;GACjC,aAAa;GACd,CAAC,CACH;EAED,IAAI,SAAS;EACb,IAAI,SAAS;EACb,IAAI,UAAU;EACd,MAAM,UAAU,UAAqC;AACnD,OAAI,QACF;AAEF,aAAU;AACV,gBAAa,MAAM;AACnB,SAAM,oBAAoB;AAC1B,SAAM,QAAQ,oBAAoB;AAClC,SAAM,QAAQ,oBAAoB;AAClC,WAAQ,MAAM;;EAEhB,MAAM,QAAQ,iBAAiB;AAC7B,SAAM,KAAK,UAAU;AACrB,UAAO,KAAA,EAAU;KAChB,0BAA0B;AAE7B,QAAM,QAAQ,YAAY,OAAO;AACjC,QAAM,QAAQ,YAAY,OAAO;AACjC,QAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,aAAU;IACV;AACF,QAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,aAAU;IACV;AACF,QAAM,KAAK,eAAe;AACxB,UAAO,KAAA,EAAU;IACjB;AACF,QAAM,KAAK,eAAe;AAKxB,UAAO,mBAJa,GAAG,OAAO,IAAI,SAC/B,MAAM,QAAQ,CACd,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,MAAM,SAAS,gBAAgB,KAAK,KAAK,CAAC,CACP,CAAC;IACvC;GACF;;AAGJ,eAAsB,yBACpB,SACA,MACmB;AACnB,KAAI,cAAc,QAAQ,KAAK,YAAY,CAAC,KAAK,SAAS,QAAQ,CAChE,QAAO,CAAC,GAAG,KAAK;CAGlB,MAAM,UAAU,MAAM,oBAAoB,QAAQ;AAClD,KAAI,WAAW,oBAAoB,QAAQ,OAAO,wBAAwB,GAAG,EAC3E,QAAO,KAAK,KAAK,QAAS,QAAQ,UAAU,uBAAuB,IAAK;AAG1E,QAAO,CAAC,GAAG,KAAK;;AAGlB,eAAe,kBACb,SACA,MACA,WAC6B;AAC7B,QAAO,MAAM,IAAI,SAA6B,YAAY;EACxD,MAAM,QAAQ,MACZ,SACA,CAAC,GAAG,KAAK,EACT,yBAAyB,SAAS;GAChC,OAAO;IAAC;IAAU;IAAQ;IAAO;GACjC,aAAa;GACd,CAAC,CACH;EAED,IAAI,SAAS;EACb,IAAI,SAAS;EACb,IAAI,UAAU;EACd,MAAM,UAAU,UAA8B;AAC5C,OAAI,QACF;AAEF,aAAU;AACV,gBAAa,MAAM;AACnB,SAAM,oBAAoB;AAC1B,SAAM,QAAQ,oBAAoB;AAClC,SAAM,QAAQ,oBAAoB;AAClC,WAAQ,MAAM;;EAEhB,MAAM,QAAQ,iBAAiB;AAC7B,SAAM,KAAK,UAAU;AACrB,UAAO,KAAA,EAAU;KAChB,UAAU;AAEb,QAAM,QAAQ,YAAY,OAAO;AACjC,QAAM,QAAQ,YAAY,OAAO;AACjC,QAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,aAAU;IACV;AACF,QAAM,QAAQ,GAAG,SAAS,UAAkB;AAC1C,aAAU;IACV;AACF,QAAM,KAAK,eAAe;AACxB,UAAO,KAAA,EAAU;IACjB;AACF,QAAM,KAAK,eAAe;AACxB,UAAO,GAAG,OAAO,IAAI,SAAS;IAC9B;GACF;;AAGJ,eAAsB,oCAAoC,SAAkC;CAC1F,MAAM,QAAQ,CACZ,iEACA,uHACD;CAED,MAAM,UAAU,MAAM,oBAAoB,QAAQ;AAClD,KAAI,QACF,OAAM,KAAK,gCAAgC,QAAQ,IAAI,GAAG;AAG5D,KAAI,CAAC,QAAQ,IAAI,kBAAkB,CAAC,QAAQ,IAAI,eAC9C,OAAM,KAAK,wEAAwE;AAGrF,OAAM,KAAK,sFAAsF;AACjG,QAAO,MAAM,KAAK,IAAI;;AAGxB,SAAgB,4CAAoD;AAClE,QAAO;EACL;EACA;EACA;EACD,CAAC,KAAK,IAAI;;AAGb,eAAe,kCAAkC,SAAkC;CACjF,MAAM,QAAQ,CACZ,uFACA,0EACD;CAED,MAAM,aAAa,MAAM,kBAAkB,SAAS,CAAC,SAAS,EAAE,wBAAwB;AACxF,KAAI,OAAO,eAAe,YAAY,CAAC,WAAW,SAAS,QAAQ,CACjE,OAAM,KAAK,wDAAwD;AAGrE,OAAM,KACJ,sIACD;AACD,QAAO,MAAM,KAAK,IAAI;;AAGxB,eAAsB,wBAAwB,SAAgC;CAC5E,MAAM,aAAa,MAAM,kBAAkB,SAAS,CAAC,SAAS,EAAE,wBAAwB;AACxF,KAAI,OAAO,eAAe,YAAY,CAAC,WAAW,SAAS,QAAQ,CACjE,OAAM,IAAI,2BAA2B,MAAM,kCAAkC,QAAQ,EAAE,EACrF,WAAW,OACZ,CAAC;;AAIN,SAAgB,2BACd,SACqC;AACrC,KAAI,CAAC,QACH;CAGF,MAAM,oBAA6C,EAAE;AACrD,KAAI,OAAO,QAAQ,UAAU,YAAY,QAAQ,MAAM,MAAM,CAAC,SAAS,EACrE,mBAAkB,QAAQ,QAAQ;AAEpC,KAAI,MAAM,QAAQ,QAAQ,aAAa,CACrC,mBAAkB,eAAe,CAAC,GAAG,QAAQ,aAAa;AAE5D,KAAI,OAAO,QAAQ,aAAa,SAC9B,mBAAkB,WAAW,QAAQ;AAGvC,KAAI,OAAO,KAAK,kBAAkB,CAAC,WAAW,EAC5C;AAGF,QAAO,EACL,YAAY,EACV,SAAS,mBACV,EACF;;;;AC5VH,SAAS,WAAW,OAAuB;AACzC,QAAO,MACJ,MAAM,CACN,QAAQ,kBAAkB,IAAI,CAC9B,QAAQ,YAAY,GAAG,CACvB,aAAa;;AAGlB,SAAS,iBAAiB,UAA4B;CACpD,MAAM,QAAQ,WAAW,SAAS;CAClC,MAAM,OAAO,IAAI,IAAY,CAAC,SAAS,CAAC;AACxC,KAAI,OAAO;AACT,OAAK,IAAI,MAAM;AACf,OAAK,IAAI,aAAa,QAAQ;;AAEhC,QAAO,CAAC,GAAG,KAAK;;AAGlB,MAAM,mCAAmB,IAAI,KAAuB;AAEpD,SAAS,YAAY,UAA4B;CAC/C,MAAM,SAAS,iBAAiB,IAAI,SAAS;AAC7C,KAAI,OACF,QAAO;CAET,MAAM,OAAO,iBAAiB,SAAS;AACvC,kBAAiB,IAAI,UAAU,KAAK;AACpC,QAAO;;AAGT,SAAgB,kBAAkB,UAAsC;AACtE,MAAK,MAAM,OAAO,YAAY,SAAS,EAAE;EACvC,MAAM,QAAQ,QAAQ,IAAI;AAC1B,MAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EACrD,QAAO;;;AAMb,SAAS,sBACP,iBACmB;CACnB,MAAM,MAAyB,EAAE,GAAG,QAAQ,KAAK;AACjD,KAAI,CAAC,gBACH,QAAO;AAGT,MAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAAQ,gBAAgB,EAAE;AACpE,MAAI,OAAO,eAAe,YAAY,WAAW,MAAM,CAAC,WAAW,EACjE;AAGF,MAAI,CAAC,SAAS,SAAS,IAAI,IAAI,CAAC,SAAS,SAAS,KAAS,IAAI,IAAI,aAAa,KAC9E,KAAI,YAAY;EAGlB,MAAM,aAAa,WAAW,SAAS;AACvC,MAAI,YAAY;GACd,MAAM,WAAW,aAAa;AAC9B,OAAI,IAAI,aAAa,KACnB,KAAI,YAAY;AAElB,OAAI,IAAI,eAAe,KACrB,KAAI,cAAc;;;AAKxB,QAAO;;AAGT,SAAgB,gCACd,UACA,iBACoB;CACpB,MAAM,oBAAoB,mBAAmB,EAAE;AAC/C,QAAO,kBAAkB,aAAa,kBAAkB,WAAW,SAAS;;AAG9E,SAAgB,uBACd,KACA,iBAMA;AACA,QAAO;EACL;EACA,KAAK,sBAAsB,gBAAgB;EAC3C,OAAO;GAAC;GAAQ;GAAQ;GAAO;EAC/B,aAAa;EACd;;;;AC9FH,MAAM,wCAAwC,IAAI,IAAI,CAAC,QAAQ,OAAO,CAAC;AAEvE,SAASC,WAAS,OAAqD;AACrE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D;AAEF,QAAO;;AAGT,SAAS,uCAAuC,KAIpC;AACV,KAAI,sCAAsC,IAAI,IAAI,KAAK,CACrD,QAAO;AAGT,KAAI,IAAI,SAAS,OACf,QAAO;CAGT,MAAM,UAAUA,WAAS,IAAI,KAAK,EAAE;AACpC,QAAO,OAAO,YAAY,YAAY,QAAQ,aAAa,CAAC,SAAS,iBAAiB;;AAGxF,SAAgB,+BAA+B,KAIpC;CACT,MAAM,UAAUA,WAAS,IAAI,KAAK,EAAE;AACpC,KAAI,OAAO,YAAY,YAAY,QAAQ,MAAM,CAAC,SAAS,EACzD,QAAO,GAAG,QAAQ,MAAM,CAAC,QAAQ,IAAI,KAAK,sBAAsB,IAAI,QAAQ;AAE9E,QAAO,GAAG,IAAI,QAAQ,QAAQ,IAAI,KAAK;;AAGzC,SAAgB,6BACd,QACA,OACA,SACS;CACT,MAAM,MAAM,gBAAgB,MAAM;AAClC,KAAI,CAAC,OAAO,CAAC,uCAAuC,IAAI,CACtD,QAAO;CAGT,MAAM,aAAa,+BAA+B,IAAI;CAEtD,MAAM,UACJ,kBAAkB,SAFE,UAAU,IAAI,YAAY,GAEL,IAAI,WAAW,kCACvB,OAAO;CAC1C,MAAM,UAAU,IAAI,MAAM,SAAS,EACjC,OAAO,iBAAiB,QAAQ,QAAQ,KAAA,GACzC,CAAC;AAGF,SAAQ,MAAM;AACd,QAAO;;;;ACzCT,MAAM,sCAAsC,KAAK;AACjD,MAAM,wBAAwB;AA8B9B,SAAS,SAAiB;AACxB,yBAAO,IAAI,MAAM,EAAC,aAAa;;AAGjC,SAAS,cAAc,SAAiB,MAAoC;CAC1E,MAAM,gBAAgB,QAAQ,EAAE,EAAE,KAAK,QAAQ,KAAK,UAAU,IAAI,CAAC,CAAC,KAAK,IAAI;AAC7E,QAAO,aAAa,SAAS,IAAI,GAAG,QAAQ,GAAG,iBAAiB;;AAGlE,SAAS,YAAY,KAAkE;AACrF,KAAI,CAAC,OAAO,IAAI,WAAW,EACzB;CAGF,MAAM,SAA4B,EAAE,GAAG,QAAQ,KAAK;AACpD,MAAK,MAAM,SAAS,IAClB,QAAO,MAAM,QAAQ,MAAM;AAE7B,QAAO;;AAGT,SAAgB,0BACd,SACA,KACA,KACA,WAA4B,QAAQ,UACd;CACtB,MAAM,cAAc,YAAY,IAAI;AAOpC,QAAO,yBACL,SAPoC;EACpC;EACA,KAAK;EACL,OAAO;GAAC;GAAU;GAAQ;GAAO;EACjC,aAAa;EACd,EAIC,UACA,eAAe,QAAQ,IACxB;;AAGH,SAAS,mBAAmB,QAAgB,OAAuB;AACjE,KAAI,SAAS,EACX,QAAO,OAAO,MAAM,EAAE;AAExB,KAAI,OAAO,UAAU,MACnB,QAAO;CAGT,IAAI,QAAQ,OAAO,SAAS;AAC5B,QAAO,QAAQ,OAAO,WAAW,OAAO,SAAS,SAAiB,IAChE,UAAS;AAGX,KAAI,SAAS,OAAO,OAClB,SAAQ,OAAO,SAAS;AAE1B,QAAO,OAAO,SAAS,MAAM;;AAG/B,SAAS,aAAa,SAAuE;AAC3F,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,gBAAgB;AACpB,WAAQ,IAAI,SAAS,QAAQ;AAC7B,YAAS;;EAEX,MAAM,WAAW,UAAiB;AAChC,WAAQ,IAAI,SAAS,QAAQ;AAC7B,UAAO,MAAM;;AAGf,UAAQ,KAAK,SAAS,QAAQ;AAC9B,UAAQ,KAAK,SAAS,QAAQ;GAC9B;;AAGJ,eAAe,sBAAsB,aAAuC;AAC1E,QAAO,MAAM,oBAAoB,EAC/B,QAAQ,0CAA0C,YAAY,YAC/D,CAAC;;AAGJ,SAAS,yBAAkC;AACzC,QAAO,QAAQ,QAAQ,MAAM,SAAS,QAAQ,OAAO,MAAM;;AAG7D,SAAS,OAAO,IAA2B;AACzC,QAAO,IAAI,SAAe,YAAY;AACpC,aAAW,SAAS,KAAK,IAAI,GAAG,GAAG,CAAC;GACpC;;AAGJ,IAAa,kBAAb,MAA6B;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;CACA,4BAA6B,IAAI,KAA8B;CAE/D,YAAY,SAAiC;AAC3C,OAAK,MAAM,QAAQ;AACnB,OAAK,iBAAiB,QAAQ;AAC9B,OAAK,4BAA4B,QAAQ,6BAA6B;AACtE,OAAK,cAAc,QAAQ;AAC3B,OAAK,4BAA4B,QAAQ,kBAAkB;AAC3D,OAAK,iBAAiB,QAAQ,kBAAkB;AAChD,OAAK,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,eAAe,sBAAsB,CAAC;;CAG1F,uBACE,gBACA,2BACM;AACN,OAAK,iBAAiB;AACtB,OAAK,4BAA4B,6BAA6B;;CAGhE,MAAM,eAAe,QAAgE;EACnF,MAAM,cAAc,cAAc,OAAO,SAAS,OAAO,KAAK;EAC9D,MAAM,UAAU,oBAAoB;AAEpC,OAAK,cAAc;GACjB,QAAQ;GACR,QAAQ;GACR;GACA,WAAW,QAAQ;GACpB,CAAC;AAEF,MAAI;AACF,OAAI,CAAE,MAAM,KAAK,kBAAkB,YAAY,CAC7C,OAAM,IAAI,sBAAsB,wCAAwC;GAG1E,MAAM,kBAAkB,KAAK,IAC3B,GACA,KAAK,MAAM,OAAO,mBAAmB,oCAAoC,CAC1E;GACD,MAAM,OAAO,MACX,OAAO,SACP,OAAO,QAAQ,EAAE,EACjB,0BAA0B,OAAO,SAAS,OAAO,OAAO,KAAK,KAAK,OAAO,IAAI,CAC9E;AACD,SAAM,aAAa,KAAK;GAExB,IAAI,oBAAqE;GACzE,MAAM,cAAc,IAAI,SAAsC,YAAY;AACxE,kBAAc;KACd;GAEF,MAAM,WAA4B;IAChC,SAAS;IACT,QAAQ,OAAO,MAAM,EAAE;IACvB,WAAW;IACX;IACA,UAAU,KAAA;IACV,QAAQ,KAAA;IACR;IACA;IACD;GAED,MAAM,gBAAgB,UAAiC;IACrD,MAAM,QAAQ,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAM;AACjE,QAAI,MAAM,WAAW,EACnB;AAGF,aAAS,SAAS,OAAO,OAAO,CAAC,SAAS,QAAQ,MAAM,CAAC;AACzD,QAAI,SAAS,OAAO,SAAS,SAAS,iBAAiB;AACrD,cAAS,SAAS,mBAAmB,SAAS,QAAQ,SAAS,gBAAgB;AAC/E,cAAS,YAAY;;;AAIzB,QAAK,OAAO,GAAG,QAAQ,aAAa;AACpC,QAAK,OAAO,GAAG,QAAQ,aAAa;AACpC,QAAK,KAAK,SAAS,UAAU,WAAW;AACtC,aAAS,WAAW;AACpB,aAAS,SAAS;AAClB,aAAS,YAAY;KACnB,UAAU,YAAY;KACtB,QAAQ,UAAU;KACnB,CAAC;KACF;GAEF,MAAM,aAAa,YAAY;AAC/B,QAAK,UAAU,IAAI,YAAY,SAAS;AAExC,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS,cAAc;IACvB,WAAW,QAAQ;IACpB,CAAC;AACF,UAAO,EAAE,YAAY;WACd,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS;IACT,WAAW,QAAQ;IACpB,CAAC;AACF,SAAM;;;CAIV,MAAM,eAAe,QAAgE;EACnF,MAAM,WAAW,KAAK,YAAY,OAAO,WAAW;AACpD,MAAI,CAAC,SACH,OAAM,IAAI,MAAM,qBAAqB,OAAO,aAAa;EAG3D,MAAM,gBAAgB,SAAS,aAAa,KAAA,KAAa,SAAS,WAAW,KAAA;AAE7E,OAAK,cAAc;GACjB,QAAQ;GACR,QAAQ;GACR,SAAS,oBAAoB,OAAO;GACpC,WAAW,QAAQ;GACpB,CAAC;AAEF,SAAO;GACL,QAAQ,SAAS,OAAO,SAAS,OAAO;GACxC,WAAW,SAAS;GACpB,YAAY,gBACR;IACE,UAAU,SAAS,YAAY;IAC/B,QAAQ,SAAS,UAAU;IAC5B,GACD,KAAA;GACL;;CAGH,MAAM,oBACJ,QACsC;EACtC,MAAM,WAAW,KAAK,YAAY,OAAO,WAAW;AACpD,MAAI,CAAC,SACH,OAAM,IAAI,MAAM,qBAAqB,OAAO,aAAa;EAG3D,MAAM,WAAW,MAAM,SAAS;AAChC,OAAK,cAAc;GACjB,QAAQ;GACR,QAAQ;GACR,SAAS,2BAA2B,OAAO;GAC3C,SAAS,YAAY,SAAS,YAAY,OAAO,WAAW,SAAS,UAAU;GAC/E,WAAW,QAAQ;GACpB,CAAC;AACF,SAAO;;CAGT,MAAM,aAAa,QAA4D;EAC7E,MAAM,WAAW,KAAK,YAAY,OAAO,WAAW;AACpD,MAAI,CAAC,SACH,OAAM,IAAI,MAAM,qBAAqB,OAAO,aAAa;EAG3D,MAAM,UAAU,kBAAkB,OAAO;AACzC,OAAK,cAAc;GACjB,QAAQ;GACR,QAAQ;GACR;GACA,WAAW,QAAQ;GACpB,CAAC;AAEF,MAAI;AACF,SAAM,KAAK,YAAY,SAAS;AAChC,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,WAAW,QAAQ;IACpB,CAAC;AACF,UAAO,EAAE;WACF,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS;IACT,WAAW,QAAQ;IACpB,CAAC;AACF,SAAM;;;CAIV,MAAM,gBAAgB,QAAkE;EACtF,MAAM,UAAU,qBAAqB,OAAO;AAC5C,OAAK,cAAc;GACjB,QAAQ;GACR,QAAQ;GACR;GACA,WAAW,QAAQ;GACpB,CAAC;EAEF,MAAM,WAAW,KAAK,YAAY,OAAO,WAAW;AACpD,MAAI,CAAC,UAAU;AACb,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS;IACT,WAAW,QAAQ;IACpB,CAAC;AACF,UAAO,EAAE;;AAGX,MAAI;AACF,SAAM,KAAK,YAAY,SAAS;AAChC,SAAM,SAAS,YAAY,YAAY,GAErC;AACF,YAAS,SAAS,OAAO,MAAM,EAAE;AACjC,QAAK,UAAU,OAAO,OAAO,WAAW;AAExC,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,WAAW,QAAQ;IACpB,CAAC;AACF,UAAO,EAAE;WACF,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAK,cAAc;IACjB,QAAQ;IACR,QAAQ;IACR;IACA,SAAS;IACT,WAAW,QAAQ;IACpB,CAAC;AACF,SAAM;;;CAIV,MAAM,WAA0B;AAC9B,OAAK,MAAM,cAAc,MAAM,KAAK,KAAK,UAAU,MAAM,CAAC,CACxD,OAAM,KAAK,gBAAgB;GAAE;GAAY,WAAW;GAAY,CAAC;;CAIrE,YAAoB,YAAiD;AACnE,SAAO,KAAK,UAAU,IAAI,WAAW;;CAGvC,cAAsB,WAAkC;AACtD,OAAK,cAAc,UAAU;;CAG/B,MAAc,kBAAkB,aAAuC;AACrE,MAAI,KAAK,mBAAmB,cAC1B,QAAO;AAET,MAAI,KAAK,mBAAmB,WAC1B,QAAO;AAET,MACE,KAAK,6BACL,KAAK,8BAA8B,UACnC,CAAC,wBAAwB,CAEzB,OAAM,IAAI,kCAAkC;AAE9C,SAAO,MAAM,KAAK,eAAe,YAAY;;CAG/C,UAAkB,UAAoC;AACpD,SAAO,SAAS,aAAa,KAAA,KAAa,SAAS,WAAW,KAAA;;CAGhE,MAAc,YAAY,UAA0C;AAClE,MAAI,CAAC,KAAK,UAAU,SAAS,CAC3B;AAGF,MAAI;AACF,YAAS,QAAQ,KAAK,UAAU;UAC1B;AACN;;AAQF,MALwB,MAAM,QAAQ,KAAK,CACzC,SAAS,YAAY,WAAW,KAAK,EACrC,OAAO,KAAK,YAAY,CAAC,WAAW,MAAM,CAC3C,CAAC,IAEqB,CAAC,KAAK,UAAU,SAAS,CAC9C;AAGF,MAAI;AACF,YAAS,QAAQ,KAAK,UAAU;UAC1B;AACN;;AAGF,QAAM,QAAQ,KAAK,CAAC,SAAS,YAAY,WAAW,KAAA,EAAU,EAAE,OAAO,KAAK,YAAY,CAAC,CAAC;;;;;ACrW9F,MAAM,iBAAiB;AACvB,MAAM,0BAA0B;AAChC,MAAM,yBAAyB;AAC/B,MAAM,4BAA4B;AAClC,MAAM,4BAA4B;AAiDlC,SAAS,8BAA8B,MAA0B;AAC/D,KAAI,KAAK,WAAW,EAClB,QAAO;AAET,QAAO,OAAO,KAAK,OAAO,YAAY,KAAK,OAAO;;AAGpD,SAAS,oCAAgD;CACvD,MAAM,uBAA2C,QAAQ;AACzD,SAAQ,SAAS,GAAG,SAAoB;AACtC,MAAI,8BAA8B,KAAK,CACrC;AAEF,uBAAqB,GAAG,KAAK;;AAE/B,cAAa;AACX,UAAQ,QAAQ;;;AAIpB,SAAS,0BACP,cACA,QACA,OAIA;CACA,MAAM,cAAc,IAAI,aAAa;CACrC,MAAM,cAAc,IAAI,aAAa;AAkDrC,QAAO;EAAE,UAhDQ,IAAI,eAA2B,EAC9C,MAAM,MAAM,YAAY;GACtB,IAAI,UAAU;GACd,MAAM,SAAS,MAAM,WAAW;AAChC,OAAI;AACF,WAAO,MAAM;KACX,MAAM,EAAE,OAAO,SAAS,MAAM,OAAO,MAAM;AAC3C,SAAI,KACF;AAEF,SAAI,CAAC,MACH;AAEF,gBAAW,YAAY,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;KACtD,MAAM,QAAQ,QAAQ,MAAM,KAAK;AACjC,eAAU,MAAM,KAAK,IAAI;AACzB,UAAK,MAAM,QAAQ,OAAO;MACxB,MAAM,cAAc,KAAK,MAAM;AAC/B,UAAI,CAAC,eAAe,mCAAmC,cAAc,YAAY,CAC/E;AAEF,UAAI;OACF,MAAM,UAAU,KAAK,MAAM,YAAY;AACvC,kBAAW,QAAQ,QAAQ;eACpB,KAAK;AACZ,eAAQ,MAAM,iCAAiC,aAAa,IAAI;;;;aAI9D;AACR,WAAO,aAAa;AACpB,eAAW,OAAO;;KAGvB,CAAC;EAciB,UAZF,IAAI,eAA2B,EAC9C,MAAM,MAAM,SAAS;GACnB,MAAM,UAAU,KAAK,UAAU,QAAQ,GAAG;GAC1C,MAAM,SAAS,OAAO,WAAW;AACjC,OAAI;AACF,UAAM,OAAO,MAAM,YAAY,OAAO,QAAQ,CAAC;aACvC;AACR,WAAO,aAAa;;KAGzB,CAAC;EAE2B;;AAG/B,IAAa,YAAb,MAAuB;CACrB;CACA;CACA;CACA;CACA;CACA;CAIA,kBAAoD;EAClD,WAAW;EACX,UAAU;EACV,QAAQ;EACR,WAAW;EACZ;CACD;CACA;CACA,qBAA4C,QAAQ,SAAS;CAC7D,yBAAiC;CACjC,0BAAkC;CAClC,yBAAiC;CACjC,sCAA8C;CAC9C;CAIA,uCAAwC,IAAI,KAAa;CACzD,UAAkB;CAClB;CACA;CACA;CACA,2CAA4C,IAAI,KAA+C;CAC/F,4CAA6C,IAAI,KAA+B;CAEhF,YAAY,SAA2B;AACrC,OAAK,UAAU;GACb,GAAG;GACH,KAAK,cAAc,QAAQ,IAAI;GAC/B,YAAY,QAAQ,cAAc;GACnC;AACD,OAAK,gBAAgB;GACnB,cAAc,KAAK,QAAQ;GAC3B,oBAAoB,KAAK,QAAQ;GACjC,iBAAiB,KAAK,QAAQ;GAC9B,mBAAmB,KAAK,QAAQ;GACjC;AAED,OAAK,aAAa,IAAI,mBAAmB;GACvC,KAAK,KAAK,QAAQ;GAClB,gBAAgB,KAAK,QAAQ;GAC7B,2BAA2B,KAAK,QAAQ;GACxC,cAAc,cAAc;AAC1B,SAAK,cAAc,oBAAoB,UAAU;;GAEpD,CAAC;AACF,OAAK,kBAAkB,IAAI,gBAAgB;GACzC,KAAK,KAAK,QAAQ;GAClB,gBAAgB,KAAK,QAAQ;GAC7B,2BAA2B,KAAK,QAAQ;GACxC,cAAc,cAAc;AAC1B,SAAK,cAAc,oBAAoB,UAAU;;GAEpD,CAAC;;CAGJ,IAAI,mBAAmD;AACrD,SAAO,KAAK;;CAGd,cAAkC;AAChC,SAAO,KAAK,OAAO,OAAO,KAAK;;CAGjC,qBAAsC;AACpC,SAAO,EAAE,GAAG,KAAK,iBAAiB;;CAGpC,4BAAoD;EAClD,MAAM,MAAM,KAAK,OAAO,OAAO,KAAK;EACpC,MAAM,UACJ,QAAQ,KAAK,MAAM,IACnB,KAAK,OAAO,YAAY,QACxB,KAAK,OAAO,cAAc,QAC1B,CAAC,KAAK,OAAO;AACf,SAAO;GACL;GACA,WAAW,KAAK;GAChB;GACA,UAAU,KAAK,gBAAgB,EAAE,GAAG,KAAK,eAAe,GAAG,KAAA;GAC5D;;CAGH,sBAA+B;AAC7B,SAAO,QAAQ,KAAK,YAAY,mBAAmB,YAAY;;CAGjE,iBACE,UAIM;AACN,OAAK,gBAAgB,EAAE,GAAG,UAAU;;CAGtC,qBAA2B;AACzB,OAAK,gBAAgB,EAAE;;CAGzB,qBAAqB,SAKZ;AACP,MAAI,QAAQ,eACV,MAAK,QAAQ,iBAAiB,QAAQ;AAExC,MAAI,QAAQ,8BAA8B,KAAA,EACxC,MAAK,QAAQ,4BAA4B,QAAQ;AAEnD,MAAI,QAAQ,kBAAkB,QAAQ,8BAA8B,KAAA,GAAW;AAC7E,QAAK,WAAW,uBACd,KAAK,QAAQ,gBACb,KAAK,QAAQ,0BACd;AACD,QAAK,gBAAgB,uBACnB,KAAK,QAAQ,gBACb,KAAK,QAAQ,0BACd;;AAEH,MAAI,QAAQ,6BAA6B,KAAA,EACvC,MAAK,QAAQ,2BAA2B,QAAQ;AAElD,MAAI,QAAQ,YAAY,KAAA,EACtB,MAAK,QAAQ,UAAU,QAAQ;;CAInC,mBAAmB,WAA4B;AAC7C,SACE,KAAK,cAAc,QACnB,KAAK,SAAS,QACd,sBAAsB,KAAK,MAAM,IACjC,KAAK,oBAAoB;;CAI7B,gBAAgB,WAA6B;AAC3C,MAAI,CAAC,KAAK,aACR,QAAO;AAET,MAAI,aAAa,KACf,QAAO;AAET,SAAO,KAAK,aAAa,cAAc;;CAGzC,MAAM,QAAuB;AAC3B,MAAI,KAAK,cAAc,KAAK,SAAS,sBAAsB,KAAK,MAAM,CACpE;AAEF,MAAI,KAAK,cAAc,KAAK,MAC1B,OAAM,KAAK,OAAO;EAGpB,MAAM,EAAE,SAAS,MAAM,gBAAgB,iBAAiB,KAAK,QAAQ,aAAa;EAClF,IAAI,OAAO,MAAM,yBAAyB,SAAS,YAAY;AAC/D,MAAI,kBAAkB,SAAS,KAAK,CAClC,QAAO,yBAAyB,MAAM,KAAK,QAAQ;AAErD,OAAK,IAAI,mBAAmB,QAAQ,GAAG,KAAK,KAAK,IAAI,GAAG;EACxD,MAAM,YAAY,mBAAmB,SAAS,KAAK;AAGnD,MAFmB,oBAAoB,SAAS,KAAK,CAGnD,OAAM,wBAAwB,QAAQ;EAGxC,MAAM,eAAe,MACnB,SACA,MACA,yBACE,SACA,uBAAuB,KAAK,QAAQ,KAAK,KAAK,QAAQ,gBAAgB,CACvE,CACF;AAED,MAAI;AACF,SAAMC,eAAa,aAAa;WACzB,OAAO;AACd,SAAM,IAAI,gBAAgB,KAAK,QAAQ,cAAc,MAAM;;EAE7D,MAAM,QAAQ,kBAAkB,aAAa;AAC7C,OAAK,UAAU;AACf,OAAK,iBAAiBC,UAAQ;AAC9B,OAAK,gBAAgB,KAAA;AACrB,OAAK,eAAe,MAAM,OAAO,KAAA;AACjC,OAAK,8BAA8B,MAAM;AAEzC,QAAM,OAAO,GAAG,SAAS,UAA2B;AAClD,OAAI,CAAC,KAAK,QAAQ,QAChB;AAEF,WAAQ,OAAO,MAAM,MAAM;IAC3B;EAEF,MAAM,QAAQ,SAAS,MAAM,MAAM,MAAM;EACzC,MAAM,SAAS,SAAS,MAAM,MAAM,OAAO;EAK3C,MAAM,aAAa,IAAI,4BACd;GACL,eAAe,OAAO,WAAgC;AACpD,UAAM,KAAK,oBAAoB,OAAO;;GAExC,mBAAmB,OACjB,WACuC;AACvC,WAAO,KAAK,wBAAwB,OAAO;;GAE7C,cAAc,OAAO,WAA+D;AAClF,WAAO,KAAK,mBAAmB,OAAO;;GAExC,eAAe,OAAO,WAAiE;AACrF,WAAO,KAAK,oBAAoB,OAAO;;GAEzC,gBAAgB,OAAO,WAAmE;AACxF,WAAO,KAAK,qBAAqB,OAAO;;GAE1C,gBAAgB,OAAO,WAAmE;AACxF,WAAO,KAAK,qBAAqB,OAAO;;GAE1C,qBAAqB,OACnB,WACyC;AACzC,WAAO,KAAK,0BAA0B,OAAO;;GAE/C,cAAc,OAAO,WAA+D;AAClF,WAAO,KAAK,mBAAmB,OAAO;;GAExC,iBAAiB,OACf,WACqC;AACrC,WAAO,KAAK,sBAAsB,OAAO;;GAE5C,GAvCY,KAAK,mBAClB,0BAA0B,KAAK,QAAQ,cAAc,OAAO,OAAO,CACpE,CAuCA;AACD,aAAW,OAAO,iBAChB,eACM;AACJ,QAAK,gBAAgB,oBAAoB,MAAM,YAAY,MAAM,MAAM,cAAc,KAAK;KAE5F,EAAE,MAAM,MAAM,CACf;AAED,MAAI;GACF,MAAM,oBAAoB,WAAW,WAAW;IAC9C,iBAAiB;IACjB,oBAAoB;KAClB,IAAI;MACF,cAAc;MACd,eAAe;MAChB;KACD,UAAU;KACX;IACD,YAAY;KACV,MAAM;KACN,SAAS;KACV;IACF,CAAC;GACF,MAAM,aAAa,YACf,MAAM,YAAY,mBAAmB,kCAAkC,CAAC,GACxE,MAAM;AAEV,SAAM,KAAK,uBAAuB,YAAY,WAAW,eAAe,EAAE,CAAC;AAE3E,QAAK,aAAa;AAClB,QAAK,QAAQ;AACb,QAAK,aAAa;AAClB,QAAK,IAAI,gCAAgC,WAAW,kBAAkB;WAC/D,OAAO;AACd,SAAM,MAAM;AACZ,OAAI,aAAa,iBAAiB,aAChC,OAAM,IAAI,6BAA6B,MAAM,oCAAoC,QAAQ,EAAE;IACzF,OAAO;IACP,WAAW;IACZ,CAAC;AAEJ,SAAM;;;CAIV,mBAA2B,MAMzB;EACA,MAAM,qBAAqB,KAAK,cAAc;EAC9C,MAAM,2BAA2B,KAAK,cAAc;EAEpD,MAAM,4CAA4C,YAAiC;AACjF,UAAO,KAAK,uCAAuC,4BAA4B,QAAQ;;AAyCzF,SAAO;GAAE,UAtCQ,IAAI,eAA2B,EAC9C,MAAM,MAAM,YAAY;IACtB,MAAM,SAAS,KAAK,SAAS,WAAW;AACxC,QAAI;AACF,YAAO,MAAM;MACX,MAAM,EAAE,OAAO,SAAS,MAAM,OAAO,MAAM;AAC3C,UAAI,KACF;AAEF,UAAI,CAAC,MACH;AAEF,UAAI,CAAC,yCAAyC,MAAM,EAAE;AACpD,2BAAoB,GAAG,WAAW,MAAM;AACxC,qBAAc,GAAG,WAAW,MAAM;;AAEpC,iBAAW,QAAQ,MAAM;;cAEnB;AACR,YAAO,aAAa;AACpB,gBAAW,OAAO;;MAGvB,CAAC;GAeiB,UAbF,IAAI,eAA2B,EAC9C,MAAM,MAAM,SAAS;AACnB,wBAAoB,GAAG,YAAY,QAAQ;AAC3C,kBAAc,GAAG,YAAY,QAAQ;IACrC,MAAM,SAAS,KAAK,SAAS,WAAW;AACxC,QAAI;AACF,WAAM,OAAO,MAAM,QAAQ;cACnB;AACR,YAAO,aAAa;;MAGzB,CAAC;GAE2B;;CAG/B,MAAM,cAAc,MAAM,KAAK,QAAQ,KAAmC;EACxE,MAAM,aAAa,KAAK,eAAe;EACvC,MAAM,EAAE,SAAS,SAAS,iBAAiB,KAAK,QAAQ,aAAa;EACrE,MAAM,YAAY,mBAAmB,SAAS,KAAK;EAEnD,IAAI;AACJ,MAAI;GACF,MAAM,gBAAgB,KAAK,2BACzB,WAAW,WAAW;IACpB,KAAK,cAAc,IAAI;IACvB,YAAY,KAAK,QAAQ,cAAc,EAAE;IACzC,OAAO,2BAA2B,KAAK,QAAQ,eAAe;IAC/D,CAAC,CACH;AACD,YAAS,YACL,MAAM,YAAY,eAAe,wCAAwC,CAAC,GAC1E,MAAM;WACH,OAAO;AACd,OAAI,aAAa,iBAAiB,aAChC,OAAM,IAAI,mCAAmC,2CAA2C,EAAE;IACxF,OAAO;IACP,WAAW;IACZ,CAAC;AAEJ,SAAM;;AAGR,OAAK,kBAAkB,OAAO;AAE9B,SAAO;GACL,WAAW,OAAO;GAClB,gBAAgB,wBAAwB,OAAO,MAAM;GACrD,QAAQ,OAAO,UAAU,KAAA;GAC1B;;CAGH,MAAM,YAAY,WAAmB,MAAM,KAAK,QAAQ,KAAiC;AACvF,OAAK,eAAe;AACpB,SAAO,MAAM,KAAK,uBAAuB,WAAW,KAAK,EAAE,CAAC;;CAG9D,MAAM,uBACJ,WACA,MAAM,KAAK,QAAQ,KACnB,UAA8B,EAAE,EACJ;EAC5B,MAAM,aAAa,KAAK,eAAe;EACvC,MAAM,sBAAsB,KAAK;EACjC,MAAM,4BAA4B,KAAK;AACvC,OAAK,yBAAyB,uBAAuB,QAAQ,QAAQ,sBAAsB;AAC3F,OAAK,sCACH,6BAA6B,QAAQ,QAAQ,sBAAsB;EAErE,IAAI;AAEJ,MAAI;AACF,cAAW,MAAM,KAAK,2BACpB,WAAW,YAAY;IACrB;IACA,KAAK,cAAc,IAAI;IACvB,YAAY,KAAK,QAAQ,cAAc,EAAE;IAC1C,CAAC,CACH;AAED,SAAM,KAAK,0BACT,QAAQ,gBAAgB,gBACxB,QAAQ,wBAAwB,wBACjC;YACO;AACR,QAAK,yBAAyB;AAC9B,QAAK,sCAAsC;;AAG7C,OAAK,kBAAkB;AAEvB,SAAO;GACL,gBAAgB,wBAAwB,UAAU,MAAM;GACxD,QAAQ,UAAU,UAAU,KAAA;GAC7B;;CAGH,MAAM,OAAO,WAAmB,QAAuD;EACrF,MAAM,aAAa,KAAK,eAAe;EACvC,MAAM,sBAAsB,KAAK,QAAQ,2BACrC,mCAAmC,GACnC,KAAA;EAEJ,IAAI;AACJ,MAAI;AACF,mBAAgB,KAAK,2BACnB,WAAW,OAAO;IAChB;IACA,QAAQ,OAAO,WAAW,WAAW,WAAW,OAAO,GAAG;IAC3D,CAAC,CACH;WACM,OAAO;AACd,0BAAuB;AACvB,SAAM;;AAGR,OAAK,eAAe;GAClB;GACA,SAAS;GACV;AAED,MAAI;GACF,MAAM,WAAW,MAAM;GACvB,MAAM,oBAAoB,KAAK,+BAA+B,UAAU;AACxE,OAAI,kBACF,OAAM;AAER,UAAO;WACA,OAAO;GACd,MAAM,oBAAoB,KAAK,+BAA+B,UAAU;AACxE,OAAI,kBACF,OAAM;AAER,SAAM;YACE;AACR,0BAAuB;AACvB,OAAI,KAAK,cAAc,YAAY,cACjC,MAAK,eAAe,KAAA;AAEtB,QAAK,qBAAqB,OAAO,UAAU;AAC3C,QAAK,yBAAyB,OAAO,UAAU;;;CAInD,MAAM,eAAe,WAAmB,QAA+B;EACrE,MAAM,aAAa,KAAK,eAAe;AACvC,MAAI;AACF,SAAM,KAAK,2BACT,WAAW,eAAe;IACxB;IACA;IACD,CAAC,CACH;WACM,OAAO;AACd,SAAM,6BAA6B,oBAAoB,OAAO,aAAa,OAAO,GAAG;;;CAIzF,MAAM,uBACJ,WACA,UACA,OACyC;EACzC,MAAM,aAAa,KAAK,eAAe;AACvC,MAAI;AACF,UAAO,MAAM,KAAK,2BAChB,WAAW,uBAAuB;IAChC;IACA;IACA;IACD,CAAC,CACH;WACM,OAAO;AACd,SAAM,6BACJ,6BACA,OACA,QAAQ,SAAS,KAAK,MAAM,GAC7B;;;CAIL,MAAM,gBAAgB,WAAmB,SAAgC;EACvE,MAAM,aAAa,KAAK,eAAe;AACvC,MAAI;AACF,SAAM,KAAK,2BACT,WAAW,yBAAyB;IAClC;IACA;IACD,CAAC,CACH;WACM,OAAO;GACd,MAAM,UAAU,6BACd,qBACA,OACA,cAAc,QAAQ,GACvB;AACD,OAAI,YAAY,MACd,OAAM;GAER,MAAM,MAAM,gBAAgB,MAAM;GAClC,MAAM,UAAU,MACZ,+BAA+B,IAAI,GACnC,iBAAiB,QACf,MAAM,UACN,OAAO,MAAM;AACnB,OAAI,iBAAiB,MACnB,OAAM,IAAI,MAAM,uCAAuC,QAAQ,KAAK,WAAW,EAC7E,OAAO,OACR,CAAC;AAEJ,SAAM,IAAI,MAAM,uCAAuC,QAAQ,KAAK,WAAW,EAC7E,OAAO,OACR,CAAC;;;CAIN,MAAM,OAAO,WAAkC;EAC7C,MAAM,aAAa,KAAK,eAAe;AACvC,OAAK,qBAAqB,IAAI,UAAU;AACxC,QAAM,KAAK,2BACT,WAAW,OAAO,EAChB,WACD,CAAC,CACH;;CAGH,MAAM,4BAA8C;EAClD,MAAM,SAAS,KAAK;AACpB,MAAI,CAAC,OACH,QAAO;AAET,QAAM,KAAK,OAAO,OAAO,UAAU;AACnC,SAAO;;CAGT,MAAM,mBAAmB,SAAS,MAA4C;EAC5E,MAAM,SAAS,KAAK;AACpB,MAAI,CAAC,OACH;AAGF,MAAI;AACF,SAAM,KAAK,OAAO,OAAO,UAAU;WAC5B,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAK,IAAI,kCAAkC,UAAU;;AAGvD,MAAI,UAAU,EACZ;EAGF,IAAI;EACJ,MAAM,iBAAiB,IAAI,SAAoB,YAAY;AACzD,WAAQ,WAAW,SAAS,OAAO;IACnC;AAEF,MAAI;AACF,UAAO,MAAM,QAAQ,KAAK,CACxB,OAAO,QAAQ,MACZ,aAAa,gBACR,KAAA,EACP,EACD,eACD,CAAC;YACM;AACR,OAAI,MACF,cAAa,MAAM;;;CAKzB,MAAM,QAAuB;AAC3B,OAAK,UAAU;AAEf,QAAM,KAAK,gBAAgB,UAAU;EAErC,MAAM,QAAQ,KAAK;AACnB,MAAI,MACF,OAAM,KAAK,sBAAsB,MAAM;AAEzC,MAAI,KAAK,0BAA0B,OAAO,EACxC,MAAK,gCACH,KAAK,gBACD,IAAI,uBACF,KAAK,cAAc,QACnB,KAAK,cAAc,UACnB,KAAK,cAAc,QACnB,EACE,sBAAsB,QAAQ,KAAK,aAAa,EACjD,CACF,GACD,IAAI,uBAAuB,oBAAoB,MAAM,MAAM,EACzD,sBAAsB,QAAQ,KAAK,aAAa,EACjD,CAAC,CACP;AAGH,OAAK,qBAAqB,QAAQ,SAAS;AAC3C,OAAK,yBAAyB;AAC9B,OAAK,0BAA0B;AAC/B,OAAK,yBAAyB;AAC9B,OAAK,sCAAsC;AAC3C,OAAK,eAAe,KAAA;AACpB,OAAK,qBAAqB,OAAO;AACjC,OAAK,yBAAyB,OAAO;AACrC,OAAK,kBAAkB,KAAA;AACvB,OAAK,aAAa,KAAA;AAClB,OAAK,aAAa,KAAA;AAClB,OAAK,QAAQ,KAAA;;CAGf,MAAc,sBACZ,OACe;EACf,MAAM,oBAAoB,iCAAiC,KAAK,QAAQ,aAAa;AAGrF,MAAI,CAAC,MAAM,MAAM,UACf,KAAI;AACF,SAAM,MAAM,KAAK;UACX;EAKV,IAAI,SAAS,MAAM,iBAAiB,OAAO,kBAAkB;AAC7D,MAAI,CAAC,UAAU,sBAAsB,MAAM,EAAE;AAC3C,OAAI;AACF,UAAM,KAAK,UAAU;WACf;AAGR,YAAS,MAAM,iBAAiB,OAAO,0BAA0B;;AAGnE,MAAI,CAAC,UAAU,sBAAsB,MAAM,EAAE;AAC3C,QAAK,IAAI,4BAA4B,0BAA0B,qBAAqB;AACpF,OAAI;AACF,UAAM,KAAK,UAAU;WACf;AAGR,YAAS,MAAM,iBAAiB,OAAO,0BAA0B;;AAInE,OAAK,mBAAmB,OAAO,CAAC,OAAO;;CAGzC,mBAA2B,OAAqB,OAAsB;EACpE,MAAM,QAAQ,MAAM;EACpB,MAAM,SAAS,MAAM;EACrB,MAAM,SAAS,MAAM;AAErB,SAAO,SAAS;AAChB,UAAQ,SAAS;AACjB,UAAQ,SAAS;AAEjB,MAAI,MACF,KAAI;AACF,SAAM,OAAO;UACP;;CAMZ,gBAA8C;AAC5C,MAAI,CAAC,KAAK,WACR,OAAM,IAAI,MAAM,yBAAyB;AAE3C,SAAO,KAAK;;CAGd,IAAY,SAAuB;AACjC,MAAI,CAAC,KAAK,QAAQ,QAChB;AAEF,UAAQ,OAAO,MAAM,UAAU,QAAQ,IAAI;;CAG7C,iBAAyB,SAAkD;AACzE,OAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,gBAAgB,kBAAkB,OAAO,GAAG;AAClD,OAAI,cACF,QAAO;IACL,UAAU,OAAO;IACjB,YAAY;IACZ,QAAQ;IACT;GAGH,MAAM,mBAAmB,gCACvB,OAAO,IACP,KAAK,QAAQ,gBACd;AACD,OAAI,OAAO,qBAAqB,YAAY,iBAAiB,MAAM,CAAC,SAAS,EAC3E,QAAO;IACL,UAAU,OAAO;IACjB,YAAY;IACZ,QAAQ;IACT;;;CAOP,MAAc,uBACZ,YACA,SACe;AACf,MAAI,QAAQ,WAAW,EACrB;EAGF,MAAM,WAAW,KAAK,iBAAiB,QAAQ;AAC/C,MAAI,CAAC,UAAU;AACb,OAAI,KAAK,QAAQ,eAAe,OAC9B,OAAM,IAAI,gBACR,kCAAkC,QAAQ,KAAK,MAAM,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,qCACvE;AAGH,QAAK,IACH,kCAAkC,QAAQ,KAAK,MAAM,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,mFACvE;AACD;;AAGF,QAAM,WAAW,aAAa,EAC5B,UAAU,SAAS,UACpB,CAAC;AAEF,OAAK,IAAI,6BAA6B,SAAS,SAAS,IAAI,SAAS,OAAO,GAAG;;CAGjF,MAAc,wBACZ,QACoC;AACpC,MAAI,KAAK,qBAAqB,IAAI,OAAO,UAAU,CACjD,QAAO,EACL,SAAS,EACP,SAAS,aACV,EACF;EAGH,IAAI;AACJ,MAAI;AACF,cAAW,MAAM,yBACf,QACA,KAAK,QAAQ,gBACb,KAAK,QAAQ,6BAA6B,OAC3C;WACM,OAAO;AACd,OAAI,iBAAiB,kCAAkC;AACrD,SAAK,4BAA4B,OAAO,WAAW,MAAM;AACzD,SAAK,yBAAyB,YAAY;AAC1C,WAAO,EACL,SAAS,EACP,SAAS,aACV,EACF;;AAEH,SAAM;;EAGR,MAAM,WAAW,2BAA2B,QAAQ,SAAS;AAC7D,OAAK,yBAAyB,SAAS;AAEvC,SAAO;;CAGT,8BACE,OACM;AACN,QAAM,KAAK,SAAS,UAAU,WAAW;AACvC,QAAK,gBAAgB,gBAAgB,UAAU,OAAO;IACtD;AAEF,QAAM,KAAK,UAAU,UAAU,WAAW;AACxC,QAAK,gBAAgB,iBAAiB,UAAU,OAAO;IACvD;AAEF,QAAM,OAAO,KAAK,eAAe;AAC/B,QAAK,gBAAgB,cAAc,MAAM,YAAY,MAAM,MAAM,cAAc,KAAK;IACpF;;CAGJ,gBACE,QACA,UACA,QACM;AACN,MAAI,KAAK,cACP;AAGF,OAAK,gBAAgB;GACnB;GACA;GACA,UAAUA,UAAQ;GAClB;GACA,wBAAwB,CAAC,KAAK,WAAW,QAAQ,KAAK,aAAa;GACpE;AACD,OAAK,gCACH,IAAI,uBAAuB,QAAQ,UAAU,QAAQ,EACnD,sBAAsB,QAAQ,KAAK,aAAa,EACjD,CAAC,CACH;;CAGH,4BACE,WACA,OACM;AACN,MAAI,CAAC,KAAK,yBAAyB,IAAI,UAAU,CAC/C,MAAK,yBAAyB,IAAI,WAAW,MAAM;;CAIvD,+BACE,WAC8C;EAC9C,MAAM,QAAQ,KAAK,yBAAyB,IAAI,UAAU;AAC1D,MAAI,MACF,MAAK,yBAAyB,OAAO,UAAU;AAEjD,SAAO;;CAGT,MAAc,qBAAwB,KAAmC;AACvE,SAAO,MAAM,IAAI,SAAY,SAAS,WAAW;GAC/C,MAAM,UAAoC;IACxC,SAAS;IACT;IACD;GAED,MAAM,UAAU,OAAmB;AACjC,QAAI,QAAQ,QACV;AAEF,YAAQ,UAAU;AAClB,SAAK,0BAA0B,OAAO,QAAQ;AAC9C,QAAI;;AAGN,QAAK,0BAA0B,IAAI,QAAQ;AACtC,WAAQ,SAAS,CACnB,KAAK,IAAI,CACT,MACE,UAAU,aAAa,QAAQ,MAAM,CAAC,GACtC,UAAU,aAAa,OAAO,MAAM,CAAC,CACvC;IACH;;CAGJ,gCAAwC,OAAsB;AAC5D,OAAK,MAAM,WAAW,KAAK,2BAA2B;AACpD,OAAI,QAAQ,SAAS;AACnB,SAAK,0BAA0B,OAAO,QAAQ;AAC9C;;AAEF,WAAQ,UAAU;AAClB,QAAK,0BAA0B,OAAO,QAAQ;AAC9C,WAAQ,OAAO,MAAM;;;CAIzB,MAAc,mBAAmB,QAA4D;AAC3F,MAAI;AACF,UAAO,MAAM,KAAK,WAAW,aAAa,OAAO;WAC1C,OAAO;AACd,QAAK,sBAAsB,OAAO,WAAW,MAAM;AACnD,SAAM;;;CAIV,MAAc,oBAAoB,QAA8D;AAC9F,MAAI;AACF,UAAO,MAAM,KAAK,WAAW,cAAc,OAAO;WAC3C,OAAO;AACd,QAAK,sBAAsB,OAAO,WAAW,MAAM;AACnD,SAAM;;;CAIV,MAAc,qBACZ,QACiC;AACjC,MAAI;AACF,UAAO,MAAM,KAAK,gBAAgB,eAAe,OAAO;WACjD,OAAO;AACd,QAAK,sBAAsB,OAAO,WAAW,MAAM;AACnD,SAAM;;;CAIV,MAAc,qBACZ,QACiC;AACjC,SAAO,MAAM,KAAK,gBAAgB,eAAe,OAAO;;CAG1D,MAAc,0BACZ,QACsC;AACtC,SAAO,MAAM,KAAK,gBAAgB,oBAAoB,OAAO;;CAG/D,MAAc,mBAAmB,QAA4D;AAC3F,SAAO,MAAM,KAAK,gBAAgB,aAAa,OAAO;;CAGxD,MAAc,sBACZ,QACkC;AAClC,SAAO,MAAM,KAAK,gBAAgB,gBAAgB,OAAO;;CAG3D,yBAAiC,UAAqD;AACpF,OAAK,gBAAgB,aAAa;AAClC,MAAI,aAAa,YAAY;AAC3B,QAAK,gBAAgB,YAAY;AACjC;;AAEF,MAAI,aAAa,UAAU;AACzB,QAAK,gBAAgB,UAAU;AAC/B;;AAEF,OAAK,gBAAgB,aAAa;;CAGpC,sBAA8B,WAAmB,OAAsB;AACrE,MAAI,iBAAiB,kCAAkC;AACrD,QAAK,4BAA4B,WAAW,MAAM;AAClD,QAAK,yBAAyB,YAAY;AAC1C;;AAEF,MAAI,iBAAiB,sBACnB,MAAK,yBAAyB,SAAS;;CAI3C,MAAc,oBAAoB,cAAkD;EAClF,MAAM,WAAW,EAAE,KAAK;AACxB,OAAK,qBAAqB,KAAK,mBAAmB,KAAK,YAAY;AACjE,OAAI;AACF,QAAI,CAAC,KAAK,uBACR,MAAK,cAAc,kBAAkB,aAAa;YAE7C,OAAO;IACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,SAAK,IAAI,kCAAkC,UAAU;aAC7C;AACR,SAAK,0BAA0B;;IAEjC;AAEF,QAAM,KAAK;;CAGb,MAAc,0BAA0B,QAAgB,WAAkC;EACxF,MAAM,mBAAmB,KAAK,IAAI,GAAG,OAAO;EAC5C,MAAM,sBAAsB,KAAK,IAAI,kBAAkB,UAAU;EACjE,MAAM,WAAW,KAAK,KAAK,GAAG;EAC9B,IAAI,eAAe,KAAK;EACxB,IAAI,YAAY,KAAK,KAAK;AAE1B,SAAO,KAAK,KAAK,IAAI,UAAU;GAC7B,MAAM,WAAW,KAAK;AACtB,OAAI,aAAa,cAAc;AAC7B,mBAAe;AACf,gBAAY,KAAK,KAAK;;AAGxB,OACE,KAAK,4BAA4B,KAAK,0BACtC,KAAK,KAAK,GAAG,aAAa,kBAC1B;AACA,UAAM,KAAK;AACX,QAAI,KAAK,4BAA4B,KAAK,uBACxC;;AAIJ,SAAM,IAAI,SAAe,YAAY;AACnC,eAAW,SAAS,uBAAuB;KAC3C;;AAGJ,QAAM,IAAI,MAAM,oDAAoD,oBAAoB,IAAI;;CAG9F,MAAM,0BAA0B,SAGd;AAChB,QAAM,KAAK,0BAA0B,SAAS,UAAU,GAAG,SAAS,aAAa,EAAE;;;;;ACttCvF,MAAM,uBAAuB;AAC7B,MAAM,+BAA+B;AACrC,MAAM,6BAA6B;AACnC,MAAM,4BAA4B;AAClC,MAAM,kCAAkC;AAExC,SAAS,SAAiB;AACxB,yBAAO,IAAI,MAAM,EAAC,aAAa;;AAGjC,SAAS,UAAa,OAAa;AACjC,KAAI;AACF,SAAO,gBAAgB,MAAM;SACvB;AACN,SAAO;;;AAIX,SAAS,OAAO,QAAgB,KAAsB;AACpD,QAAO,OAAO,UAAU,eAAe,KAAK,QAAQ,IAAI;;AAG1D,SAAS,mBAAmB,OAAoC;AAC9D,KAAI,OAAO,UAAU,SACnB;CAEF,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,SAAS,YAAY,SAA2C;AAC9D,KAAI,QAAQ,SAAS,OACnB,QAAO,QAAQ;AAGjB,KAAI,QAAQ,SAAS,gBACnB,QAAO,QAAQ,SAAS,QAAQ,QAAQ,QAAQ;AAGlD,KAAI,QAAQ,SAAS,YAAY;AAC/B,MAAI,UAAU,QAAQ,YAAY,OAAO,QAAQ,SAAS,SAAS,SACjE,QAAO,QAAQ,SAAS;AAE1B,SAAO,QAAQ,SAAS;;;AAM5B,SAAS,qBAAqB,SAAuD;AACnF,KAAI,QAAQ,SAAS,OACnB,QAAO,EACL,MAAM,QAAQ,MACf;AAGH,KAAI,QAAQ,SAAS,iBAAiB;EACpC,MAAM,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,QAAQ;AACvD,SAAO,EACL,SAAS;GACP,KAAK,QAAQ;GACb,SAAS;GACV,EACF;;AAGH,KAAI,QAAQ,SAAS,YAAY;AAC/B,MAAI,UAAU,QAAQ,YAAY,OAAO,QAAQ,SAAS,SAAS,SACjE,QAAO,EACL,MAAM,QAAQ,SAAS,MACxB;AAGH,SAAO,EACL,SAAS;GACP,KAAK,QAAQ,SAAS;GACtB,SAAS,QAAQ,SAAS;GAC3B,EACF;;AAGH,KAAI,QAAQ,SAAS,QACnB,QAAO,EACL,OAAO;EACL,QAAQ,QAAQ;EAChB,MAAM;EACP,EACF;;AAML,SAAS,oBAA4B;AACnC,QAAO,YAAY;;AAGrB,SAAS,cAAc,SAMrB;AACA,QAAO,OAAO,YAAY,YAAY,YAAY,QAAQ,OAAO,SAAS,OAAO;;AAGnF,SAAS,eAAe,SAAoE;AAC1F,QAAO,OAAO,YAAY,YAAY,YAAY,QAAQ,OAAO,SAAS,QAAQ;;AAGpF,SAAS,mBAAmB,SAA2D;AACrF,QAAO,OAAO,SAAS,OAAO;;AAGhC,SAAS,uBACP,SACsE;AACtE,QAAO,OAAO,SAAS,WAAW;;AAGpC,SAAS,sBACP,SACwC;AACxC,QAAO,OAAO,SAAS,UAAU;;AAGnC,SAAS,4BAA4B,cAAmC,WAAyB;AAC/F,cAAa,aAAa;;AAG5B,SAAS,mBAAmB,cAAwD;CAClF,MAAM,OAAO,aAAa,SAAS,GAAG,GAAG;AACzC,KAAI,QAAQ,eAAe,KAAK,CAC9B,QAAO,KAAK;CAGd,MAAM,UAA+B;EACnC,SAAS,EAAE;EACX,cAAc,EAAE;EACjB;AACD,cAAa,SAAS,KAAK,EAAE,OAAO,SAAS,CAAC;AAC9C,QAAO;;AAGT,SAAS,gBAAgB,OAA4B,MAAoB;AACvE,KAAI,CAAC,KAAK,MAAM,CACd;CAGF,MAAM,OAAO,MAAM,QAAQ,GAAG,GAAG;AACjC,KAAI,QAAQ,mBAAmB,KAAK,EAAE;AACpC,OAAK,OAAO,gBAAgB,GAAG,KAAK,OAAO,QAAQ,6BAA6B;AAChF;;CAGF,MAAM,OAA4B,EAChC,MAAM,MACP;AACD,OAAM,QAAQ,KAAK,KAAK;;AAG1B,SAAS,oBAAoB,OAA4B,MAAoB;AAC3E,KAAI,CAAC,KAAK,MAAM,CACd;CAGF,MAAM,OAAO,MAAM,QAAQ,GAAG,GAAG;AACjC,KAAI,QAAQ,uBAAuB,KAAK,EAAE;AACxC,OAAK,SAAS,OAAO,gBACnB,GAAG,KAAK,SAAS,OAAO,QACxB,2BACD;AACD;;CAGF,MAAM,OAA4B,EAChC,UAAU;EACR;EACA,WAAW;EACZ,EACF;AACD,OAAM,QAAQ,KAAK,KAAK;;AAG1B,SAAS,gBAAgB,OAAe,UAA0B;AAChE,KAAI,MAAM,UAAU,SAClB,QAAO;AAET,QAAO,GAAG,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,WAAW,EAAE,CAAC,CAAC;;AAGtD,SAAS,wBAAwB,QAA0B;AACzD,KAAI,OAAO,WAAW,SACpB,QAAO;CAET,MAAM,aAAa,OAAO,aAAa;AACvC,QACE,WAAW,SAAS,WAAW,IAC/B,WAAW,SAAS,OAAO,IAC3B,WAAW,SAAS,UAAU,IAC9B,WAAW,SAAS,SAAS,IAC7B,WAAW,SAAS,QAAQ,IAC5B,WAAW,SAAS,SAAS;;AAIjC,SAAS,qBAAqB,QAA0B;AACtD,KAAI,OAAO,WAAW,SACpB,QAAO;CAET,MAAM,aAAa,OAAO,aAAa;AACvC,QAAO,WAAW,SAAS,OAAO,IAAI,WAAW,SAAS,QAAQ;;AAGpE,SAAS,oBAAoB,OAA0C;AACrE,KAAI,OAAO,UAAU,SACnB,QAAO,EAAE,MAAM,gBAAgB,OAAO,0BAA0B,EAAE;AAGpE,KAAI,SAAS,KACX,KAAI;AACF,SAAO,EAAE,MAAM,gBAAgB,KAAK,UAAU,MAAM,EAAE,0BAA0B,EAAE;SAC5E;AACN,SAAO,EAAE,MAAM,0BAA0B;;AAI7C,QAAO,EAAE,MAAM,IAAI;;AAGrB,SAAS,WAAW,OAAwB;AAC1C,KAAI,OAAO,UAAU,SACnB,QAAO,gBAAgB,OAAO,0BAA0B;AAG1D,KAAI;AACF,SAAO,gBAAgB,KAAK,UAAU,SAAS,EAAE,CAAC,EAAE,0BAA0B;SACxE;AACN,SAAO,SAAS,OAAO,KAAK;;;AAIhC,SAAS,qBAAqB,OAA4B,YAAoC;AAC5F,MAAK,MAAM,WAAW,MAAM,QAC1B,KAAI,sBAAsB,QAAQ,IAAI,QAAQ,QAAQ,OAAO,WAC3D,QAAO,QAAQ;CAInB,MAAM,UAA0B;EAC9B,IAAI;EACJ,MAAM;EACN,WAAW;EACX,OAAO,EAAE;EACT,mBAAmB;EACnB,mBAAmB;EACpB;AACD,OAAM,QAAQ,KAAK,EAAE,SAAS,SAAS,CAAC;AACxC,QAAO;;AAGT,SAAS,iBACP,OACA,YACA,OACM;CACN,MAAM,WAAW,MAAM,aAAa;CACpC,MAAM,OAA0B;EAC9B,aAAa;EACb,WAAW,MAAM,aAAa,UAAU,aAAa;EACrD,UAAU,MAAM,YAAY,UAAU,YAAY;EAClD,SAAS,MAAM,WAAW,UAAU,WAAW,EAAE,MAAM,IAAI;EAC3D,QAAQ,MAAM,UAAU,UAAU;EACnC;AACD,OAAM,aAAa,cAAc;;AAGnC,SAAS,oBAAoB,OAA4B,QAAyC;CAChG,MAAM,OAAO,qBAAqB,OAAO,OAAO,WAAW;AAE3D,KAAI,OAAO,QAAQ,QAAQ,CACzB,MAAK,OACH,mBAAoB,OAA+B,MAAM,IAAI,KAAK,QAAQ;AAG9E,KAAI,OAAO,QAAQ,OAAO,EAAE;EAC1B,MAAM,WAAW,mBAAoB,OAA8B,KAAK;AACxE,MAAI,CAAC,KAAK,QAAQ,KAAK,SAAS,YAC9B,MAAK,OAAO,YAAY,KAAK;;AAIjC,KAAI,OAAO,QAAQ,WAAW,EAAE;EAC9B,MAAM,WAAW,UAAW,OAAkC,SAAS;AACvE,OAAK,QAAQ,YAAY,EAAE;AAC3B,OAAK,YAAY,WAAW,SAAS;;AAGvC,KAAI,OAAO,QAAQ,SAAS,CAC1B,MAAK,oBAAoB,wBAAyB,OAAgC,OAAO;AAG3F,KACE,OAAO,QAAQ,YAAY,IAC3B,OAAO,QAAQ,SAAS,IACxB,OAAO,QAAQ,QAAQ,IACvB,OAAO,QAAQ,OAAO,EACtB;EACA,MAAM,SAAU,OAAgC;EAChD,MAAM,SAAS,OAAO,QAAQ,YAAY,GACtC,UAAW,OAAmC,UAAU,GACxD,KAAA;AAEJ,mBAAiB,OAAO,OAAO,YAAY;GACzC,WAAW,KAAK;GAChB,UAAU,qBAAqB,OAAO;GACtC,SAAS,WAAW,KAAA,IAAY,KAAA,IAAY,oBAAoB,OAAO;GACvE;GACD,CAAC;;;AAIN,SAAS,SAAS,OAAqD;AACrE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D;AAEF,QAAO;;AAGT,SAAS,YAAY,QAAiC,MAA6C;AACjG,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,OAAO;AACrB,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,IAAI,SAAS,EAClE,QAAO;;;AAMb,SAAS,kBAAkB,QAAoD;CAC7E,MAAM,eAAe,SAAS,OAAO;CACrC,MAAM,YAAY,SAAS,cAAc,MAAM,EAAE;CACjD,MAAM,SAAS,SAAS,UAAU,IAAI;AACtC,KAAI,CAAC,OACH;CAGF,MAAM,aAAgC;EACpC,cAAc,YAAY,QAAQ,CAAC,gBAAgB,cAAc,CAAC;EAClE,eAAe,YAAY,QAAQ,CAAC,iBAAiB,eAAe,CAAC;EACrE,6BAA6B,YAAY,QAAQ;GAC/C;GACA;GACA;GACD,CAAC;EACF,yBAAyB,YAAY,QAAQ;GAC3C;GACA;GACA;GACD,CAAC;EACH;AAED,KACE,WAAW,iBAAiB,KAAA,KAC5B,WAAW,kBAAkB,KAAA,KAC7B,WAAW,gCAAgC,KAAA,KAC3C,WAAW,4BAA4B,KAAA,EAEvC;AAGF,QAAO;;AAGT,SAASC,kBAAgB,OAAuD;AAC9E,QAAO,SAAS,EAAE;;AAGpB,SAAS,kBAAkB,cAAuD;AAChF,MAAK,IAAI,QAAQ,aAAa,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EACzE,MAAM,UAAU,aAAa,SAAS;AACtC,MAAI,WAAW,cAAc,QAAQ,CACnC,QAAO,QAAQ,KAAK;;;AAM1B,SAAgB,0BAA0B,YAAY,QAAQ,EAAuB;AACnF,QAAO;EACL,OAAO;EACP,UAAU,EAAE;EACZ,YAAY;EACZ,wBAAwB,EAAE;EAC1B,qBAAqB,EAAE;EACxB;;AAGH,SAAgB,yBACd,cACqB;AACrB,KAAI,CAAC,aACH,QAAO,2BAA2B;AAGpC,QAAO;EACL,OAAO,aAAa;EACpB,UAAU,UAAU,aAAa,YAAY,EAAE,CAAC;EAChD,YAAY,aAAa;EACzB,wBAAwB,UAAU,aAAa,0BAA0B,EAAE,CAAC;EAC5E,qBAAqB,UAAU,aAAa,uBAAuB,EAAE,CAAC;EACvE;;AAGH,SAAgB,sBACd,OAC8B;AAC9B,KAAI,CAAC,MACH;AAGF,QAAO;EACL,iBAAiB,MAAM;EACvB,iBAAiB,MAAM;EACvB,kBAAkB,MAAM;EACxB,kBAAkB,MAAM,mBAAmB,CAAC,GAAG,MAAM,iBAAiB,GAAG,KAAA;EACzE,oBAAoB,MAAM,qBAAqB,CAAC,GAAG,MAAM,mBAAmB,GAAG,KAAA;EAC/E,gBAAgB,MAAM,iBAAiB,UAAU,MAAM,eAAe,GAAG,KAAA;EACzE,iBAAiB,MAAM,kBACnB;GACE,OAAO,MAAM,gBAAgB;GAC7B,eAAe,MAAM,gBAAgB,gBACjC,CAAC,GAAG,MAAM,gBAAgB,cAAc,GACxC,KAAA;GACJ,WAAW,MAAM,gBAAgB;GAClC,GACD,KAAA;EACL;;AAiCH,SAAgB,uBACd,cACA,QACA,YAAY,QAAQ,EACA;CAEpB,MAAM,eADmB,OAAO,WAAW,WAAW,WAAW,OAAO,GAAG,QAExE,KAAK,YAAY,qBAAqB,QAAQ,CAAC,CAC/C,QAAQ,YAAY,YAAY,KAAA,EAAU;AAC7C,KAAI,YAAY,WAAW,EACzB;CAGF,MAAM,kBAAkB,mBAAmB;AAC3C,cAAa,SAAS,KAAK,EACzB,MAAM;EACJ,IAAI;EACJ,SAAS,YAAY,KAAK,YAAY;AACpC,OAAI,UAAU,QACZ,QAAO,EACL,MAAM,gBAAgB,QAAQ,MAAM,6BAA6B,EAClE;AAEH,UAAO;IACP;EACH,EACF,CAAC;AACF,6BAA4B,cAAc,UAAU;AACpD,4BAA2B,aAAa;AACxC,QAAO;;AAGT,SAAS,6BAA6B,SAAuC;AAC3E,QAAO,QAAQ,QAAQ,SAAS,KAAK,OAAO,KAAK,QAAQ,aAAa,CAAC,SAAS;;AAGlF,SAAgB,yBACd,cACA,iBACS;CACT,IAAI,YAAY;AAEhB,MAAK,MAAM,WAAW,aAAa,UAAU;AAC3C,MAAI,CAAC,WAAW;AACd,OAAI,cAAc,QAAQ,IAAI,QAAQ,KAAK,OAAO,gBAChD,aAAY;AAEd;;AAGF,MAAI,eAAe,QAAQ,IAAI,6BAA6B,QAAQ,MAAM,CACxE,QAAO;;AAIX,QAAO;;AAGT,SAAgB,oBACd,cACA,OACA,cACA,YAAY,QAAQ,EACF;CAClB,MAAM,OAAOA,kBAAgB,MAAM;CAEnC,MAAM,SAAwB,aAAa;AAC3C,SAAQ,OAAO,eAAf;EACE,KAAK,sBAAsB;GACzB,MAAM,cAAc,qBAAqB,OAAO,QAAQ;AACxD,OAAI,YACF,cAAa,SAAS,KAAK,EACzB,MAAM;IACJ,IAAI,mBAAmB;IACvB,SAAS,CAAC,YAAY;IACvB,EACF,CAAC;AAEJ;;EAEF,KAAK,uBAAuB;GAC1B,MAAM,OAAO,YAAY,OAAO,QAAQ;AACxC,OAAI,KAEF,iBADc,mBAAmB,aAAa,EACvB,KAAK;AAE9B;;EAEF,KAAK,uBAAuB;GAC1B,MAAM,OAAO,YAAY,OAAO,QAAQ;AACxC,OAAI,KAEF,qBADc,mBAAmB,aAAa,EACnB,KAAK;AAElC;;EAEF,KAAK;EACL,KAAK;AAEH,uBADc,mBAAmB,aAAa,EACnB,OAAO;AAClC;EAEF,KAAK,gBAAgB;GACnB,MAAM,QAAQ,kBAAkB,OAAO;AACvC,OAAI,OAAO;AACT,iBAAa,yBAAyB;IACtC,MAAM,SAAS,kBAAkB,aAAa;AAC9C,QAAI,OACF,cAAa,oBAAoB,UAAU;;AAG/C;;EAEF,KAAK;AACH,OAAI,OAAO,QAAQ,QAAQ,CACzB,cAAa,QAAQ,OAAO,SAAS;AAEvC,OAAI,OAAO,QAAQ,YAAY,CAC7B,cAAa,aAAa,OAAO,aAAa,aAAa;AAE7D;EAEF,KAAK;AACH,QAAK,qBAAqB,OAAO,kBAC9B,KAAK,UAAU,MAAM,KAAK,CAC1B,QAAQ,UAAU,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,EAAE;AAC1E;EAEF,KAAK;AACH,QAAK,kBAAkB,OAAO;AAC9B;EAEF,KAAK;AACH,QAAK,iBAAiB,UAAU,OAAO,cAAc;AACrD;EAEF,QACE;;AAGJ,6BAA4B,cAAc,UAAU;AACpD,4BAA2B,aAAa;AACxC,QAAO;;AAGT,SAAgB,sBACd,cACA,OACA,WACA,YAAY,QAAQ,EACF;CAClB,MAAM,OAAOA,kBAAgB,MAAM;AACnC,6BAA4B,cAAc,UAAU;AACpD,4BAA2B,aAAa;AACxC,QAAO;;AAGT,SAAgB,2BAA2B,cAAyC;AAClF,KAAI,aAAa,SAAS,SAAS,qBACjC,cAAa,WAAW,aAAa,SAAS,MAAM,CAAC,qBAAqB;AAG5E,MAAK,MAAM,WAAW,aAAa,UAAU;AAC3C,MAAI,CAAC,eAAe,QAAQ,EAAE;AAC5B,OAAI,cAAc,QAAQ,CACxB,SAAQ,KAAK,UAAU,QAAQ,KAAK,QAAQ,KAAK,YAAY;AAC3D,QAAI,UAAU,QACZ,QAAO,EACL,MAAM,gBAAgB,QAAQ,MAAM,6BAA6B,EAClE;AAEH,WAAO;KACP;AAEJ;;AAGF,OAAK,MAAM,WAAW,QAAQ,MAAM,QAClC,KAAI,UAAU,QACZ,SAAQ,OAAO,gBAAgB,QAAQ,MAAM,6BAA6B;WACjE,cAAc,QACvB,SAAQ,SAAS,OAAO,gBAAgB,QAAQ,SAAS,MAAM,2BAA2B;WACjF,aAAa,QACtB,SAAQ,QAAQ,YAAY,gBAC1B,QAAQ,QAAQ,WAChB,0BACD;AAIL,OAAK,MAAM,UAAU,OAAO,OAAO,QAAQ,MAAM,aAAa,EAAE;AAC9D,OAAI,UAAU,OAAO,QACnB,QAAO,QAAQ,OAAO,gBAAgB,OAAO,QAAQ,MAAM,0BAA0B;AAEvF,OAAI,OAAO,OAAO,WAAW,SAC3B,QAAO,SAAS,gBAAgB,OAAO,QAAQ,0BAA0B;;;CAK/E,MAAM,sBAAsB,OAAO,QAAQ,aAAa,oBAAoB;AAC5E,KAAI,oBAAoB,SAAS,gCAC/B,cAAa,sBAAsB,OAAO,YACxC,oBAAoB,MAAM,CAAC,gCAAgC,CAC5D;;;;AC/rBL,SAAS,gBAAgB,OAAuD;AAC9E,QAAO,SAAS,EAAE;;AAGpB,SAAgB,gBAAgB,QAAgD;AAC9E,KAAI,OAAO,WAAW,SACpB;CAEF,MAAM,UAAU,OAAO,MAAM;AAC7B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,SAAS,iBAAiB,SAAiD;AACzE,KAAI,OAAO,YAAY,SACrB;CAEF,MAAM,UAAU,QAAQ,MAAM;AAC9B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,SAAgB,iBAAiB,OAAyD;AACxF,QAAO,gBAAgB,OAAO,gBAAgB;;AAGhD,SAAgB,iBAAiB,QAAuB,QAAkC;CACxF,MAAM,OAAO,gBAAgB,OAAO,KAAK;CACzC,MAAM,aAAa,gBAAgB,OAAO;AAE1C,KAAI,WACF,MAAK,kBAAkB;KAEvB,QAAO,KAAK;AAGd,QAAO,OAAO;;AAGhB,SAAgB,kBAAkB,OAAyD;AACzF,QAAO,iBAAiB,OAAO,iBAAiB,MAAM;;AAGxD,SAAgB,kBAAkB,QAAuB,SAAmC;CAC1F,MAAM,OAAO,gBAAgB,OAAO,KAAK;CACzC,MAAM,aAAa,iBAAiB,QAAQ;CAC5C,MAAM,iBAAiB,EAAE,GAAG,KAAK,iBAAiB;AAElD,KAAI,WACF,gBAAe,QAAQ;KAEvB,QAAO,eAAe;AAGxB,KACE,OAAO,eAAe,UAAU,YAChC,MAAM,QAAQ,eAAe,cAAc,IAC3C,OAAO,eAAe,cAAc,SAEpC,MAAK,kBAAkB;KAEvB,QAAO,KAAK;AAGd,QAAO,OAAO;;AAGhB,SAAgB,kBAAkB,QAAuB,SAAmC;CAC1F,MAAM,OAAO,gBAAgB,OAAO,KAAK;CACzC,MAAM,aAAa,iBAAiB,QAAQ;AAE5C,KAAI,WACF,MAAK,mBAAmB;KAExB,QAAO,KAAK;AAGd,QAAO,OAAO;;AAGhB,SAAgB,yBACd,QACA,QACM;AACN,KAAI,CAAC,OACH;CAGF,MAAM,OAAO,gBAAgB,OAAO,KAAK;AACzC,MAAK,mBAAmB,OAAO;AAC/B,MAAK,mBAAmB,OAAO,gBAAgB,KAAK,UAAU,MAAM,QAAQ;AAC5E,QAAO,OAAO;;;;ACxFhB,SAAgB,+BACd,QACA,UACM;AACN,KAAI,CAAC,SACH;AAGF,QAAO,MAAM,SAAS;AACtB,QAAO,iBAAiB,SAAS;AAEjC,KAAI,SAAS,UAAU;AACrB,SAAO,oBAAoB,SAAS,SAAS;AAC7C,SAAO,sBAAsB,SAAS,SAAS;AAC/C,SAAO,kBAAkB,SAAS,SAAS;AAC3C,SAAO,4BAA4B,SAAS,SAAS;AACrD;;AAGF,QAAO,oBAAoB,KAAA;AAC3B,QAAO,sBAAsB,KAAA;AAC7B,QAAO,kBAAkB,KAAA;AACzB,QAAO,4BAA4B,KAAA;;AAGrC,SAAgB,wBACd,QACA,gBACM;CACN,MAAM,aAAa,0BAA0B,eAAe;AAC5D,KAAI,CAAC,WACH;AAGF,QAAO,iBAAiB;;AAG1B,SAAgB,wBACd,sBACS;AACT,QAAO,qBAAqB,SAAS,MAClC,YAAY,OAAO,YAAY,YAAY,YAAY,QAAQ,WAAW,QAC5E;;AAGH,SAAgB,kBAAkB,QAAuB,cAAyC;AAChG,QAAO,QAAQ,aAAa;AAC5B,QAAO,aAAa,aAAa;AACjC,QAAO,WAAW,aAAa;AAC/B,QAAO,yBAAyB,aAAa;AAC7C,QAAO,sBAAsB,aAAa;;;;AChB5C,SAAS,eAAe,KAAkC;AACxD,KAAI,CAAC,OAAO,CAAC,OAAO,UAAU,IAAI,IAAI,OAAO,KAAK,QAAQ,QAAQ,IAChE,QAAO;AAGT,KAAI;AACF,UAAQ,KAAK,KAAK,EAAE;AACpB,SAAO;SACD;AACN,SAAO;;;AAuBX,MAAM,iCAAiC,IAAI,IAAI,CAAC,QAAQ,OAAO,CAAC;AAEhE,SAAS,2BAA2B,OAAgB,QAAgC;AAClF,KAAI,iBAAiB,gBAAgB,iBAAiB,iBACpD,QAAO;AAGT,KAAI,2BAA2B,MAAM,CACnC,QAAO;CAGT,MAAM,MAAM,gBAAgB,MAAM;AAClC,KAAI,OAAO,+BAA+B,IAAI,IAAI,KAAK,CACrD,QAAO;AAGT,KAAI,CAAC,wBAAwB,OAAO,EAAE;AACpC,MAAI,oCAAoC,MAAM,CAC5C,QAAO;AAGT,MAAI,KAAK,SAAS,OAChB,QAAO;;AAIX,QAAO;;AAGT,SAAS,oBAAoB,cAAwD;AACnF,QAAO,iBAAiB;;AAG1B,SAAS,+BAA+B,QAIT;AAC7B,QAAO,IAAI,2BACT,0BAA0B,OAAO,OAAO,aAAa,yBAAyB,OAAO,UACrF,EACE,OAAO,OAAO,iBAAiB,QAAQ,OAAO,QAAQ,KAAA,GACvD,CACF;;AAGH,eAAe,kBAAkB,QAOf;AAChB,KAAI,CAAC,OAAO,cACV;AAGF,KAAI;AACF,QAAM,YACJ,OAAO,OAAO,eAAe,OAAO,WAAW,OAAO,cAAc,EACpE,OAAO,UACR;AACD,MAAI,OAAO,QACT,SAAQ,OAAO,MACb,gCAAgC,OAAO,cAAc,wBAAwB,OAAO,UAAU,aAAa,OAAO,kBAAkB,KACrI;UAEI,OAAO;AACd,QAAM,IAAI,uBACR,uCAAuC,OAAO,cAAc,wBAAwB,OAAO,UAAU,IAAI,mBAAmB,MAAM,IAClI;GACE,OAAO,iBAAiB,QAAQ,QAAQ,KAAA;GACxC,WAAW;GACZ,CACF;;;AAIL,eAAe,mBAAmB,QAQhB;AAChB,KAAI,CAAC,OAAO,kBAAkB,CAAC,OAAO,OACpC;AAEF,KAAI,OAAO,OAAO,mBAAmB,OAAO,eAC1C;AAGF,KAAI;AACF,QAAM,YACJ,OAAO,OAAO,gBAAgB,OAAO,WAAW,OAAO,eAAe,EACtE,OAAO,UACR;AACD,MAAI,OAAO,QACT,SAAQ,OAAO,MACb,iCAAiC,OAAO,eAAe,wBAAwB,OAAO,UAAU,aAAa,OAAO,kBAAkB,KACvI;UAEI,OAAO;AACd,QAAM,IAAI,wBACR,wCAAwC,OAAO,eAAe,wBAAwB,OAAO,UAAU,IAAI,mBAAmB,MAAM,IACpI;GACE,OAAO,iBAAiB,QAAQ,QAAQ,KAAA;GACxC,WAAW;GACZ,CACF;;;AAIL,SAAS,4BAA4B,QAI5B;AACP,QAAO,OAAO,eAAe,OAAO;AACpC,QAAO,OAAO,iBAAiB,OAAO;;AAGxC,eAAsB,sBACpB,SACsC;CACtC,MAAM,SAAS,QAAQ;CACvB,MAAM,SAAS,QAAQ;CACvB,MAAM,kBAAkB,oBAAoB,QAAQ,aAAa;CACjE,MAAM,oBAAoB,OAAO;CACjC,MAAM,yBAAyB,OAAO;CACtC,MAAM,gBAAgB,iBAAiB,OAAO,KAAK;CACnD,MAAM,iBAAiB,kBAAkB,OAAO,KAAK;CACrD,MAAM,qBAAqB,eAAe,OAAO,IAAI;CACrD,MAAM,kBAAkB,QAAQ,OAAO,IAAI,IAAI,CAAC;AAEhD,KAAI,QAAQ;MACN,mBACF,SAAQ,OAAO,MACb,4BAA4B,OAAO,IAAI,8CACxC;WACQ,gBACT,SAAQ,OAAO,MACb,4BAA4B,OAAO,IAAI,0DACxC;;CAIL,MAAM,uBAAuB,OAAO,mBAAmB,OAAO,aAAa;AAC3E,KAAI,qBACF,sBAAqB,0CAA0C;KAE/D,OAAM,YAAY,OAAO,OAAO,EAAE,QAAQ,UAAU;AAEtD,SAAQ,oBAAoB,QAAQ,iBAAiB;AACrD,gCAA+B,QAAQ,OAAO,2BAA2B,CAAC;AAC1E,QAAO,SAAS;AAChB,QAAO,WAAW,KAAA;AAClB,SAAQ,oBAAoB,OAAO;CAEnC,IAAI,UAAU;CACd,IAAI;CACJ,IAAI,YAAY,OAAO;CACvB,IAAI,sBAAsB;CAC1B,IAAI,wBAAwB,OAAO;CACnC,IAAI;AAEJ,KAAI,qBACF,WAAU;UACD,OAAO,qBAAqB,CACrC,KAAI;EACF,MAAM,aAAa,MAAM,YACvB,OAAO,uBAAuB,OAAO,cAAc,OAAO,KAAK,EAC7D,uBAAuB,MACxB,CAAC,EACF,QAAQ,UACT;AACD,0BAAwB,QAAQ,WAAW,eAAe;AAC1D,kBAAgB,WAAW;AAC3B,YAAU;UACH,OAAO;AACd,cAAY,mBAAmB,MAAM;AACrC,MAAI,gBACF,OAAM,+BAA+B;GACnC;GACA,QAAQ;GACR,OAAO;GACR,CAAC;AAEJ,MAAI,CAAC,2BAA2B,OAAO,OAAO,CAC5C,OAAM;EAER,MAAM,iBAAiB,MAAM,YAAY,OAAO,cAAc,OAAO,IAAI,EAAE,QAAQ,UAAU;AAC7F,cAAY,eAAe;AAC3B,wBAAsB;AACtB,0BAAwB,eAAe;AACvC,kBAAgB,eAAe;;MAE5B;AACL,MAAI,gBACF,OAAM,+BAA+B;GACnC;GACA,QAAQ;GACT,CAAC;EAEJ,MAAM,iBAAiB,MAAM,YAAY,OAAO,cAAc,OAAO,IAAI,EAAE,QAAQ,UAAU;AAC7F,cAAY,eAAe;AAC3B,wBAAsB;AACtB,0BAAwB,eAAe;AACvC,kBAAgB,eAAe;;AAGjC,KAAI,qBAAqB;AACvB,MAAI;AACF,SAAM,kBAAkB;IACtB;IACA;IACA;IACA,mBAAmB;IACnB,WAAW,QAAQ;IACnB,SAAS,QAAQ;IAClB,CAAC;AACF,SAAM,mBAAmB;IACvB;IACA;IACA;IACA,mBAAmB;IACnB,QAAQ;IACR,WAAW,QAAQ;IACnB,SAAS,QAAQ;IAClB,CAAC;WACK,OAAO;AACd,+BAA4B;IAC1B;IACA,WAAW;IACX,gBAAgB;IACjB,CAAC;AACF,OAAI,QAAQ,QACV,SAAQ,OAAO,MAAM,UAAU,mBAAmB,MAAM,CAAC,IAAI;AAE/D,SAAM;;AAGR,SAAO,eAAe;AACtB,0BAAwB,QAAQ,sBAAsB;;AAGxD,0BAAyB,QAAQ,cAAc;AAC/C,KAAI,uBAAuB,kBAAkB,cAC3C,mBAAkB,QAAQ,eAAe;AAG3C,SAAQ,sBAAsB,UAAU;AAExC,QAAO;EACL;EACA,gBAAgB,OAAO;EACvB;EACA;EACD;;;;ACnUH,SAAgB,yBAAyB,QAAwD;CAC/F,MAAM,SAAS,OAAO,MAAM;AAC5B,KAAI,CAAC,OACH;CAGF,MAAM,iBAAsC,EAAE;AAE9C,KAAI,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,MAAM,CAAC,SAAS,EACnE,gBAAe,QAAQ,OAAO;AAEhC,KAAI,MAAM,QAAQ,OAAO,cAAc,CACrC,gBAAe,eAAe,CAAC,GAAG,OAAO,cAAc;AAEzD,KAAI,OAAO,OAAO,cAAc,SAC9B,gBAAe,WAAW,OAAO;AAGnC,QAAO,OAAO,KAAK,eAAe,CAAC,SAAS,IAAI,iBAAiB,KAAA;;;;ACkCnE,SAAS,8BAA8B,QAGJ;CACjC,MAAM,2BAA2B,OAAO,oBAAoB;AAC5D,QAAO;EACL,uBAAuB,OAAO,OAAO,iBAAiB;EACtD,2BAA2B,YAAY,MAAM,OAAO,OAAO,2BAA2B;EACtF,gBAAgB,OAAO,WAAmB;AACxC,SAAM,OAAO,OAAO,eAAe,oBAAoB,EAAE,OAAO;;EAElE,iBAAiB,OAAO,YAAoB;AAC1C,SAAM,OAAO,OAAO,gBAAgB,oBAAoB,EAAE,QAAQ;;EAEpE,wBAAwB,OAAO,UAAkB,UAAkB;AACjE,UAAO,MAAM,OAAO,OAAO,uBAAuB,oBAAoB,EAAE,UAAU,MAAM;;EAE3F;;AAGH,eAAsB,qBACpB,SACwC;CACxC,MAAM,SAAS,MAAM,QAAQ,WAAW,QAAQ,gBAAgB;CAChE,MAAM,SACJ,QAAQ,eAAe;EACrB,cAAc,OAAO;EACrB,KAAK,aAAa,OAAO,IAAI;EAC7B,YAAY,QAAQ;EACpB,gBAAgB,QAAQ,kBAAkB;EAC1C,2BAA2B,QAAQ;EACnC,iBAAiB,QAAQ;EACzB,YAAY,QAAQ;EACpB,SAAS,QAAQ;EACjB,gBAAgB,yBAAyB,OAAO;EACjD,CAAC,IACF,IAAI,UAAU;EACZ,cAAc,OAAO;EACrB,KAAK,aAAa,OAAO,IAAI;EAC7B,YAAY,QAAQ;EACpB,gBAAgB,QAAQ,kBAAkB;EAC1C,2BAA2B,QAAQ;EACnC,iBAAiB,QAAQ;EACzB,YAAY,QAAQ;EACpB,SAAS,QAAQ;EACjB,gBAAgB,yBAAyB,OAAO;EACjD,CAAC;CACJ,IAAI,4BAA4B,OAAO;CACvC,IAAI,0BAA0B;CAC9B,MAAM,mBAAmB,8BAA8B;EACrD;EACA,0BAA0B;EAC3B,CAAC;AAEF,KAAI;AACF,SAAO,MAAM,cACX,YAAY;GACV,MAAM,EAAE,WAAW,SAAS,cAAc,MAAM,sBAAsB;IACpE;IACA;IACA,cAAc,QAAQ;IACtB,WAAW,QAAQ;IACnB,SAAS,QAAQ;IACjB;IACA,oBAAoB,eAAe;AACjC,aAAQ,oBAAoB,WAA6C;AACzE,+BAA0B;;IAE5B,mBAAmB,QAAQ;IAC3B,sBAAsB,mBAAmB;AACvC,iCAA4B;;IAE/B,CAAC;GAEF,MAAM,QAAQ,MAAM,QAAQ,IAAI;IAC9B;IACA;IACA;IACA;IACA;IACA;IACD,CAAC;AAGF,UAAO,aADKC,UAAQ;AAEpB,UAAO,SAAS;AAChB,UAAO,WAAW,KAAA;AAClB,UAAO,kBAAkB,OAAO,kBAAkB;AAClD,UAAO,oBAAoB,OAAO,kBAAkB;AACpD,kCAA+B,QAAQ,OAAO,2BAA2B,CAAC;AAC1E,SAAM,QAAQ,WAAW,OAAO;AAEhC,UAAO;IACL;IACA;IACA;IACA;IACD;KAEH,YAAY;AACV,OAAI,QAAQ,YACV,OAAM,QAAQ,YAAY;IAAE;IAAQ;IAAQ,CAAC;OAE7C,OAAM,OAAO,mBAAmB,KAAM;AAExC,kCAA+B,QAAQ,OAAO,2BAA2B,CAAC;AAC1E,UAAO,aAAaA,UAAQ;AAC5B,SAAM,QAAQ,WAAW,OAAO,CAAC,YAAY,GAE3C;AACF,SAAM,OAAO,OAAO;IAEvB;WACO;AACR,MAAI,wBACF,SAAQ,kBAAkB;AAE5B,QAAM,OAAO,OAAO;AACpB,iCAA+B,QAAQ,OAAO,2BAA2B,CAAC;AAC1E,QAAM,QAAQ,WAAW,OAAO,CAAC,YAAY,GAE3C;;;;;ACjLN,MAAM,wBAAwB;AAC9B,MAAM,iCAAiC;AAUvC,eAAsB,cAAc,QAQkD;AACpF,KAAI;EACF,MAAM,gBAAgB,OAAO,OAAO,OAAO,OAAO,WAAW,OAAO,OAAO;AAC3E,QAAM,OAAO,mBAAmB;AAEhC,SAAO;GACL,aAFe,MAAM,YAAY,eAAe,OAAO,UAAU,EAE5C;GACrB,QAAQ;GACT;UACM,OAAO;AACd,MAAI,EAAE,iBAAiB,iBAAiB,CAAC,OAAO,gBAC9C,OAAM;AAGR,QAAM,OAAO,OACV,4BAA4B;GAC3B,QAAQ;GACR,WAAW;GACZ,CAAC,CACD,YAAY,GAEX;AAEJ,MAAI,yBAAyB,OAAO,cAAc,OAAO,gBAAgB,CACvE,QAAO;GACL,YAAY;GACZ,QAAQ;GACT;AAGH,QAAM"}
|