@btraut/browser-bridge 0.1.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/background.ts"],
4
+ "sourcesContent": ["import type {\n DebuggerCommandParams,\n DebuggerEvent,\n DebuggerRequest,\n DriveRequest,\n DriveErrorInfo,\n DriveEvent,\n DriveHelloParams,\n DriveResponse,\n DriveTabInfo,\n DriveTabListResult,\n ExtensionMessage,\n ExtensionRequest,\n} from './protocol.js';\n\ntype ContentResult =\n | { ok: true; result?: unknown }\n | { ok: false; error: DriveErrorInfo };\n\ntype ContentRequest = {\n action: string;\n params?: Record<string, unknown>;\n};\n\ntype DebuggerTarget = {\n tabId?: number;\n};\n\ntype DebuggerSession = {\n attached: boolean;\n attachPromise?: Promise<void>;\n idleTimer?: number;\n lastActivityAt: string;\n initialized?: boolean;\n};\n\nconst DEFAULT_CORE_PORT = 3210;\nconst CORE_PORT_KEY = 'corePort';\nconst CORE_WS_PATH = '/drive';\n\nconst DEBUGGER_PROTOCOL_VERSION = '1.3';\nconst DEBUGGER_IDLE_TIMEOUT_KEY = 'debuggerIdleTimeoutMs';\nconst DEFAULT_DEBUGGER_IDLE_TIMEOUT_MS = 15000;\nconst DEFAULT_DEBUGGER_COMMAND_TIMEOUT_MS = 10000;\n\nconst nowIso = (): string => new Date().toISOString();\n\nconst makeEventId = (() => {\n let counter = 0;\n return () => `evt-${Date.now()}-${(counter += 1)}`;\n})();\n\nconst lastActiveAtByTab = new Map<number, string>();\n\nconst ensureLastActiveAt = (tabId: number): string => {\n const existing = lastActiveAtByTab.get(tabId);\n if (existing) {\n return existing;\n }\n const timestamp = nowIso();\n lastActiveAtByTab.set(tabId, timestamp);\n return timestamp;\n};\n\nconst markTabActive = (tabId: number): string => {\n const timestamp = nowIso();\n lastActiveAtByTab.set(tabId, timestamp);\n return timestamp;\n};\n\nconst wrapChromeCallback = <T>(\n invoker: (callback: (value: T) => void) => void\n): Promise<T> =>\n new Promise<T>((resolve, reject) => {\n invoker((value: T) => {\n const error = chrome.runtime.lastError;\n if (error) {\n reject(new Error(error.message));\n return;\n }\n resolve(value);\n });\n });\n\nconst wrapChromeVoid = (\n invoker: (callback: () => void) => void\n): Promise<void> => {\n return new Promise<void>((resolve, reject) => {\n invoker(() => {\n const error = chrome.runtime.lastError;\n if (error) {\n reject(new Error(error.message));\n return;\n }\n resolve();\n });\n });\n};\n\nconst readCorePort = async (): Promise<number> => {\n return await new Promise<number>((resolve) => {\n chrome.storage.local.get(\n [CORE_PORT_KEY],\n (result: Record<string, unknown>) => {\n const raw = result?.[CORE_PORT_KEY];\n if (typeof raw === 'number' && Number.isFinite(raw)) {\n resolve(raw);\n return;\n }\n if (typeof raw === 'string') {\n const parsed = Number(raw);\n if (Number.isFinite(parsed)) {\n resolve(parsed);\n return;\n }\n }\n resolve(DEFAULT_CORE_PORT);\n }\n );\n });\n};\n\nconst readDebuggerIdleTimeoutMs = async (): Promise<number> => {\n return await new Promise<number>((resolve) => {\n chrome.storage.local.get(\n [DEBUGGER_IDLE_TIMEOUT_KEY],\n (result: Record<string, unknown>) => {\n const raw = result?.[DEBUGGER_IDLE_TIMEOUT_KEY];\n if (typeof raw === 'number' && Number.isFinite(raw) && raw > 0) {\n resolve(raw);\n return;\n }\n if (typeof raw === 'string') {\n const parsed = Number(raw);\n if (Number.isFinite(parsed) && parsed > 0) {\n resolve(parsed);\n return;\n }\n }\n resolve(DEFAULT_DEBUGGER_IDLE_TIMEOUT_MS);\n }\n );\n });\n};\n\nconst RESTRICTED_URL_PREFIXES = [\n 'chrome://',\n 'chrome-extension://',\n 'chrome-devtools://',\n 'devtools://',\n 'edge://',\n 'brave://',\n 'view-source:',\n];\n\nconst isRestrictedUrl = (url?: string): boolean => {\n if (!url || typeof url !== 'string') {\n return false;\n }\n const lowered = url.toLowerCase();\n if (RESTRICTED_URL_PREFIXES.some((prefix) => lowered.startsWith(prefix))) {\n return true;\n }\n try {\n const parsed = new URL(url);\n if (parsed.hostname === 'chromewebstore.google.com') {\n return true;\n }\n if (parsed.hostname === 'chrome.google.com') {\n return parsed.pathname.startsWith('/webstore');\n }\n } catch (error) {\n console.debug('Ignoring invalid URL in restriction check.', error);\n }\n return false;\n};\n\nconst mapDebuggerErrorMessage = (\n message: string,\n fallbackCode = 'INSPECT_UNAVAILABLE'\n): DriveErrorInfo => {\n const normalized = message.toLowerCase();\n if (\n normalized.includes('already attached') ||\n normalized.includes('another debugger') ||\n normalized.includes('attached to this target')\n ) {\n return {\n code: 'DEBUGGER_IN_USE',\n message:\n 'Debugger already attached. Close DevTools on the target tab and retry.',\n retryable: true,\n details: {\n reason: 'debugger_in_use',\n hint: 'Close DevTools on the target tab and retry.',\n original_message: message,\n },\n };\n }\n if (\n normalized.includes('no tab') ||\n normalized.includes('no target') ||\n normalized.includes('tab id')\n ) {\n return {\n code: 'TAB_NOT_FOUND',\n message,\n retryable: false,\n };\n }\n if (\n normalized.includes('not allowed') ||\n normalized.includes('permission') ||\n normalized.includes('denied')\n ) {\n return {\n code: 'ATTACH_DENIED',\n message,\n retryable: false,\n };\n }\n if (\n normalized.includes('cannot access') ||\n normalized.includes('not supported') ||\n normalized.includes('disallowed')\n ) {\n return {\n code: 'NOT_SUPPORTED',\n message,\n retryable: false,\n };\n }\n return {\n code: fallbackCode,\n message,\n retryable: false,\n };\n};\n\nconst buildTabInfo = (tab: Record<string, unknown>): DriveTabInfo | null => {\n const tabId = tab.id;\n const windowId = tab.windowId;\n if (typeof tabId !== 'number' || typeof windowId !== 'number') {\n return null;\n }\n return {\n tab_id: tabId,\n window_id: windowId,\n url: typeof tab.url === 'string' ? tab.url : undefined,\n title: typeof tab.title === 'string' ? tab.title : undefined,\n active: typeof tab.active === 'boolean' ? tab.active : undefined,\n last_active_at: ensureLastActiveAt(tabId),\n };\n};\n\nconst queryTabs = async (): Promise<DriveTabInfo[]> => {\n const tabs = await wrapChromeCallback<Record<string, unknown>[]>((callback) =>\n chrome.tabs.query({}, callback)\n );\n const result: DriveTabInfo[] = [];\n for (const tab of tabs) {\n const info = buildTabInfo(tab);\n if (info) {\n result.push(info);\n }\n }\n return result;\n};\n\nconst getTab = async (tabId: number): Promise<Record<string, unknown>> => {\n return await wrapChromeCallback<Record<string, unknown>>((callback) =>\n chrome.tabs.get(tabId, callback)\n );\n};\n\nconst getActiveTabId = async (): Promise<number> => {\n const tabs = await wrapChromeCallback<Record<string, unknown>[]>((callback) =>\n chrome.tabs.query({ active: true, lastFocusedWindow: true }, callback)\n );\n const first = tabs[0];\n if (first && typeof first.id === 'number') {\n return first.id;\n }\n throw new Error('No active tab found.');\n};\n\nconst sendToTab = async (\n tabId: number,\n action: string,\n params?: Record<string, unknown>\n): Promise<ContentResult> => {\n return await new Promise<ContentResult>((resolve) => {\n const message: ContentRequest = { action, params };\n chrome.tabs.sendMessage(tabId, message, (response: ContentResult) => {\n const error = chrome.runtime.lastError;\n if (error) {\n resolve({\n ok: false,\n error: {\n code: 'EVALUATION_FAILED',\n message: error.message,\n retryable: false,\n },\n });\n return;\n }\n if (!response || typeof response !== 'object') {\n resolve({\n ok: false,\n error: {\n code: 'EVALUATION_FAILED',\n message: 'Empty response from content script.',\n retryable: false,\n },\n });\n return;\n }\n resolve(response);\n });\n });\n};\n\nconst waitForDomContentLoaded = async (\n tabId: number,\n timeoutMs: number\n): Promise<void> => {\n return await new Promise<void>((resolve, reject) => {\n let timeout: number | undefined;\n const cleanup = () => {\n if (timeout !== undefined) {\n clearTimeout(timeout);\n }\n chrome.webNavigation.onDOMContentLoaded.removeListener(listener);\n };\n\n const listener = (details: { tabId: number; frameId: number }) => {\n if (details.tabId !== tabId || details.frameId !== 0) {\n return;\n }\n cleanup();\n resolve();\n };\n\n chrome.webNavigation.onDOMContentLoaded.addListener(listener);\n timeout = self.setTimeout(() => {\n cleanup();\n reject(new Error('Timed out waiting for domcontentloaded.'));\n }, timeoutMs);\n });\n};\n\nconst getWsUrl = async (): Promise<string> => {\n const port = await readCorePort();\n return `ws://127.0.0.1:${port}${CORE_WS_PATH}`;\n};\n\nclass DriveSocket {\n private socket: WebSocket | null = null;\n private reconnectTimer: number | null = null;\n private reconnectDelayMs = 1000;\n private readonly maxReconnectDelayMs = 10000;\n private keepAliveTimer: number | null = null;\n private readonly keepAliveIntervalMs = 30000;\n private readonly debuggerSessions = new Map<number, DebuggerSession>();\n private debuggerIdleTimeoutMs: number | null = null;\n\n start(): void {\n void this.connect().catch((error) => {\n console.error('DriveSocket connect failed:', error);\n });\n }\n\n stop(): void {\n if (this.reconnectTimer !== null) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.stopKeepAlive();\n if (this.socket) {\n this.socket.close();\n this.socket = null;\n }\n }\n\n sendTabReport(): void {\n void this.emitTabReport().catch((error) => {\n console.error('DriveSocket emitTabReport failed:', error);\n });\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer !== null) {\n return;\n }\n const delay = this.reconnectDelayMs;\n this.reconnectTimer = self.setTimeout(() => {\n this.reconnectTimer = null;\n void this.connect().catch((error) => {\n console.error('DriveSocket reconnect failed:', error);\n });\n }, delay);\n this.reconnectDelayMs = Math.min(\n this.maxReconnectDelayMs,\n this.reconnectDelayMs * 2\n );\n }\n\n private async connect(): Promise<void> {\n const url = await getWsUrl();\n try {\n const socket = new WebSocket(url);\n this.socket = socket;\n\n socket.addEventListener('open', () => {\n this.reconnectDelayMs = 1000;\n this.startKeepAlive();\n void this.sendHello().catch((error) => {\n console.error('DriveSocket hello failed:', error);\n });\n });\n\n socket.addEventListener('message', (event) => {\n this.handleMessage(event.data);\n });\n\n socket.addEventListener('close', () => {\n this.socket = null;\n this.stopKeepAlive();\n this.scheduleReconnect();\n });\n\n socket.addEventListener('error', () => {\n this.socket = null;\n this.stopKeepAlive();\n this.scheduleReconnect();\n });\n } catch (error) {\n console.debug('DriveSocket connect failed, scheduling reconnect.', error);\n this.scheduleReconnect();\n }\n }\n\n private async sendHello(): Promise<void> {\n const manifest = chrome.runtime.getManifest();\n let tabs: DriveTabInfo[] = [];\n try {\n tabs = await queryTabs();\n } catch (error) {\n console.debug('DriveSocket sendHello failed to read tabs.', error);\n tabs = [];\n }\n const params: DriveHelloParams = {\n version: manifest.version,\n tabs,\n };\n this.sendEvent('drive.hello', params);\n }\n\n private async emitTabReport(): Promise<void> {\n try {\n const tabs = await queryTabs();\n this.sendEvent('drive.tab_report', { tabs });\n } catch (error) {\n console.debug('DriveSocket emitTabReport failed.', error);\n }\n }\n\n private sendEvent(\n action: DriveEvent['action'],\n params: DriveEvent['params']\n ): void {\n const message: DriveEvent = {\n id: makeEventId(),\n action,\n status: 'event',\n params,\n };\n this.sendMessage(message);\n }\n\n private startKeepAlive(): void {\n this.stopKeepAlive();\n this.keepAliveTimer = self.setInterval(() => {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n return;\n }\n this.sendEvent('drive.keepalive', {});\n }, this.keepAliveIntervalMs);\n }\n\n private stopKeepAlive(): void {\n if (this.keepAliveTimer !== null) {\n clearInterval(this.keepAliveTimer);\n this.keepAliveTimer = null;\n }\n }\n\n private sendDebuggerEvent(params: DebuggerEvent['params']): void {\n const message: DebuggerEvent = {\n id: makeEventId(),\n action: 'debugger.event',\n status: 'event',\n params,\n };\n this.sendMessage(message);\n }\n\n private sendMessage(message: ExtensionMessage): void {\n if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {\n return;\n }\n this.socket.send(JSON.stringify(message));\n }\n\n private handleMessage(raw: unknown): void {\n if (typeof raw !== 'string') {\n return;\n }\n let message: ExtensionMessage | null = null;\n try {\n message = JSON.parse(raw) as ExtensionMessage;\n } catch (error) {\n console.debug('DriveSocket received invalid JSON message.', error);\n return;\n }\n if (!message || typeof message !== 'object') {\n return;\n }\n if (message.status === 'request') {\n void this.handleRequest(message as ExtensionRequest).catch((error) => {\n console.error('DriveSocket handleRequest failed:', error);\n });\n }\n }\n\n private async handleRequest(message: ExtensionRequest): Promise<void> {\n let driveMessage: DriveRequest | null = null;\n const respondOk = (result?: unknown): void => {\n if (!driveMessage) {\n return;\n }\n const response: DriveResponse = {\n id: driveMessage.id,\n action: driveMessage.action,\n status: 'ok',\n result,\n };\n this.sendMessage(response);\n };\n\n const respondError = (error: DriveErrorInfo): void => {\n if (!driveMessage) {\n return;\n }\n const response: DriveResponse = {\n id: driveMessage.id,\n action: driveMessage.action,\n status: 'error',\n error,\n };\n this.sendMessage(response);\n };\n\n try {\n if (\n !message ||\n typeof message !== 'object' ||\n typeof message.id !== 'string' ||\n typeof message.action !== 'string'\n ) {\n return;\n }\n if (message.action.startsWith('debugger.')) {\n await this.handleDebuggerRequest(message as DebuggerRequest);\n return;\n }\n\n if (!message.action.startsWith('drive.')) {\n return;\n }\n\n driveMessage = message as DriveRequest;\n switch (message.action) {\n case 'drive.ping': {\n respondOk({ ok: true });\n return;\n }\n case 'drive.navigate': {\n const params = (message.params ?? {}) as Record<string, unknown>;\n const url = params.url;\n if (typeof url !== 'string' || url.length === 0) {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'url must be a non-empty string.',\n retryable: false,\n });\n return;\n }\n let tabId = params.tab_id;\n if (tabId !== undefined && typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number when provided.',\n retryable: false,\n });\n return;\n }\n if (tabId === undefined) {\n tabId = await getActiveTabId();\n }\n const waitMode =\n params.wait === 'none' || params.wait === 'domcontentloaded'\n ? params.wait\n : 'domcontentloaded';\n await wrapChromeVoid((callback) =>\n chrome.tabs.update(tabId as number, { url }, () => callback())\n );\n markTabActive(tabId as number);\n if (waitMode === 'domcontentloaded') {\n try {\n await waitForDomContentLoaded(tabId as number, 30000);\n } catch (error) {\n respondError({\n code: 'TIMEOUT',\n message:\n error instanceof Error ? error.message : 'Timed out waiting.',\n retryable: true,\n });\n return;\n }\n }\n respondOk({ ok: true });\n return;\n }\n case 'drive.go_back':\n case 'drive.back':\n case 'drive.go_forward':\n case 'drive.forward': {\n const params = (message.params ?? {}) as Record<string, unknown>;\n let tabId = params.tab_id;\n if (tabId !== undefined && typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number when provided.',\n retryable: false,\n });\n return;\n }\n if (tabId === undefined) {\n tabId = await getActiveTabId();\n }\n try {\n const isBack =\n message.action === 'drive.go_back' ||\n message.action === 'drive.back';\n await wrapChromeVoid((callback) => {\n if (isBack) {\n chrome.tabs.goBack(tabId as number, () => callback());\n } else {\n chrome.tabs.goForward(tabId as number, () => callback());\n }\n });\n } catch (error) {\n respondError({\n code: 'FAILED_PRECONDITION',\n message:\n error instanceof Error ? error.message : 'No history entry.',\n retryable: false,\n });\n return;\n }\n markTabActive(tabId as number);\n try {\n await waitForDomContentLoaded(tabId as number, 30000);\n } catch (error) {\n respondError({\n code: 'TIMEOUT',\n message:\n error instanceof Error ? error.message : 'Timed out waiting.',\n retryable: true,\n });\n return;\n }\n respondOk({ ok: true });\n return;\n }\n case 'drive.tab_list': {\n const tabs = await queryTabs();\n const result: DriveTabListResult = { tabs };\n respondOk(result);\n return;\n }\n case 'drive.tab_activate': {\n const tabId = (message.params as Record<string, unknown> | undefined)\n ?.tab_id;\n if (typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number.',\n retryable: false,\n });\n return;\n }\n const tab = await getTab(tabId);\n await wrapChromeVoid((callback) =>\n chrome.tabs.update(tabId, { active: true }, () => callback())\n );\n const windowId = tab.windowId;\n if (typeof windowId === 'number') {\n await wrapChromeVoid((callback) =>\n chrome.windows.update(windowId, { focused: true }, () =>\n callback()\n )\n );\n }\n markTabActive(tabId);\n respondOk({ ok: true });\n this.sendTabReport();\n return;\n }\n case 'drive.tab_close': {\n const tabId = (message.params as Record<string, unknown> | undefined)\n ?.tab_id;\n if (typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number.',\n retryable: false,\n });\n return;\n }\n await wrapChromeVoid((callback) =>\n chrome.tabs.remove(tabId, () => callback())\n );\n lastActiveAtByTab.delete(tabId);\n respondOk({ ok: true });\n this.sendTabReport();\n return;\n }\n case 'drive.handle_dialog': {\n const params = (message.params ?? {}) as Record<string, unknown>;\n const action = params.action;\n if (action !== 'accept' && action !== 'dismiss') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'action must be accept or dismiss.',\n retryable: false,\n });\n return;\n }\n const promptText = params.promptText;\n if (promptText !== undefined && typeof promptText !== 'string') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'promptText must be a string when provided.',\n retryable: false,\n });\n return;\n }\n let tabId = params.tab_id;\n if (tabId !== undefined && typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number when provided.',\n retryable: false,\n });\n return;\n }\n if (tabId === undefined) {\n tabId = await getActiveTabId();\n }\n\n const error = await this.ensureDebuggerAttached(tabId as number);\n if (error) {\n respondError(error);\n return;\n }\n\n try {\n await this.sendDebuggerCommand(\n tabId as number,\n 'Page.handleJavaScriptDialog',\n {\n accept: action === 'accept',\n ...(promptText ? { promptText } : {}),\n },\n DEFAULT_DEBUGGER_COMMAND_TIMEOUT_MS\n );\n this.touchDebuggerSession(tabId as number);\n respondOk({ ok: true });\n } catch (error) {\n const info = mapDebuggerErrorMessage(\n error instanceof Error ? error.message : 'Dialog handling failed.'\n );\n respondError(info);\n }\n return;\n }\n case 'drive.click':\n case 'drive.hover':\n case 'drive.select':\n case 'drive.type':\n case 'drive.fill_form':\n case 'drive.drag':\n case 'drive.key':\n case 'drive.key_press':\n case 'drive.scroll':\n case 'drive.wait_for': {\n const params = (message.params ?? {}) as Record<string, unknown>;\n let tabId = params.tab_id;\n if (tabId !== undefined && typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number when provided.',\n retryable: false,\n });\n return;\n }\n if (tabId === undefined) {\n tabId = await getActiveTabId();\n }\n const result = await sendToTab(\n tabId as number,\n message.action,\n params\n );\n if (result.ok) {\n respondOk(result.result ?? { ok: true });\n } else {\n respondError(result.error);\n }\n return;\n }\n default:\n respondError({\n code: 'NOT_IMPLEMENTED',\n message: `${message.action} not implemented in extension yet.`,\n retryable: false,\n });\n }\n } catch (error) {\n const messageText =\n error instanceof Error ? error.message : 'Unknown error';\n respondError({\n code: 'EVALUATION_FAILED',\n message: messageText,\n retryable: false,\n });\n }\n }\n\n private async handleDebuggerRequest(message: DebuggerRequest): Promise<void> {\n const respondAck = (result?: unknown): void => {\n this.sendMessage({\n id: message.id,\n action: message.action,\n status: 'ack',\n result,\n });\n };\n\n const respondError = (error: DriveErrorInfo): void => {\n this.sendMessage({\n id: message.id,\n action: message.action,\n status: 'error',\n error,\n });\n };\n\n try {\n switch (message.action) {\n case 'debugger.attach': {\n const params = (message.params ?? {}) as { tab_id?: unknown };\n const tabId = params.tab_id;\n if (typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number.',\n retryable: false,\n });\n return;\n }\n\n const error = await this.ensureDebuggerAttached(tabId);\n if (error) {\n respondError(error);\n return;\n }\n respondAck({ ok: true });\n return;\n }\n case 'debugger.detach': {\n const params = (message.params ?? {}) as { tab_id?: unknown };\n const tabId = params.tab_id;\n if (typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number.',\n retryable: false,\n });\n return;\n }\n const error = await this.detachDebugger(tabId);\n if (error) {\n respondError(error);\n return;\n }\n respondAck({ ok: true });\n return;\n }\n case 'debugger.command': {\n const params = (message.params ?? {}) as DebuggerCommandParams;\n const tabId = params.tab_id;\n if (typeof tabId !== 'number') {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'tab_id must be a number.',\n retryable: false,\n });\n return;\n }\n if (typeof params.method !== 'string' || params.method.length === 0) {\n respondError({\n code: 'INVALID_ARGUMENT',\n message: 'method must be a non-empty string.',\n retryable: false,\n });\n return;\n }\n\n const session = this.debuggerSessions.get(tabId);\n if (session?.attachPromise) {\n try {\n await session.attachPromise;\n } catch (error) {\n const info = mapDebuggerErrorMessage(\n error instanceof Error\n ? error.message\n : 'Debugger attach failed.'\n );\n this.clearDebuggerSession(tabId);\n respondError(info);\n return;\n }\n }\n\n const attachedSession = this.debuggerSessions.get(tabId);\n if (!attachedSession?.attached) {\n respondError({\n code: 'FAILED_PRECONDITION',\n message: 'Debugger is not attached to the requested tab.',\n retryable: false,\n });\n return;\n }\n\n try {\n const result = await this.sendDebuggerCommand(\n tabId,\n params.method,\n params.params,\n DEFAULT_DEBUGGER_COMMAND_TIMEOUT_MS\n );\n this.touchDebuggerSession(tabId);\n respondAck(result);\n } catch (error) {\n if (error instanceof DebuggerTimeoutError) {\n respondError({\n code: 'TIMEOUT',\n message: error.message,\n retryable: true,\n });\n return;\n }\n const info = mapDebuggerErrorMessage(\n error instanceof Error\n ? error.message\n : 'Debugger command failed.'\n );\n respondError(info);\n }\n return;\n }\n default:\n respondError({\n code: 'NOT_IMPLEMENTED',\n message: `${message.action} not implemented in extension yet.`,\n retryable: false,\n });\n }\n } catch (error) {\n const messageText =\n error instanceof Error ? error.message : 'Unexpected debugger error.';\n respondError({\n code: 'INSPECT_UNAVAILABLE',\n message: messageText,\n retryable: false,\n });\n }\n }\n\n async handleDebuggerEvent(\n source: DebuggerTarget,\n method: string,\n params?: Record<string, unknown>\n ): Promise<void> {\n const tabId = source.tabId;\n if (typeof tabId !== 'number') {\n return;\n }\n this.touchDebuggerSession(tabId);\n this.sendDebuggerEvent({\n tab_id: tabId,\n method,\n params,\n timestamp: nowIso(),\n });\n }\n\n async handleDebuggerDetach(\n source: DebuggerTarget,\n reason?: string\n ): Promise<void> {\n const tabId = source.tabId;\n if (typeof tabId !== 'number') {\n return;\n }\n this.clearDebuggerSession(tabId);\n this.sendDebuggerEvent({\n tab_id: tabId,\n method: 'Debugger.detached',\n params: { reason: reason ?? 'unknown' },\n timestamp: nowIso(),\n });\n }\n\n private async ensureDebuggerAttached(\n tabId: number\n ): Promise<DriveErrorInfo | null> {\n const existing = this.debuggerSessions.get(tabId);\n if (existing?.attached) {\n this.touchDebuggerSession(tabId);\n return null;\n }\n\n if (existing?.attachPromise) {\n try {\n await existing.attachPromise;\n } catch (error) {\n const info = mapDebuggerErrorMessage(\n error instanceof Error ? error.message : 'Debugger attach failed.'\n );\n this.clearDebuggerSession(tabId);\n return info;\n }\n if (existing.attached) {\n this.touchDebuggerSession(tabId);\n return null;\n }\n }\n\n const preflightError = await this.checkDebuggerTarget(tabId);\n if (preflightError) {\n return preflightError;\n }\n\n const session: DebuggerSession = {\n attached: false,\n lastActivityAt: nowIso(),\n };\n this.debuggerSessions.set(tabId, session);\n\n session.attachPromise = wrapChromeVoid((callback) =>\n chrome.debugger.attach({ tabId }, DEBUGGER_PROTOCOL_VERSION, () =>\n callback()\n )\n );\n\n try {\n await session.attachPromise;\n session.attached = true;\n session.attachPromise = undefined;\n const initError = await this.initializeDebuggerDomains(tabId);\n if (initError) {\n await this.detachDebugger(tabId);\n return initError;\n }\n session.initialized = true;\n this.touchDebuggerSession(tabId);\n return null;\n } catch (error) {\n const info = mapDebuggerErrorMessage(\n error instanceof Error ? error.message : 'Debugger attach failed.'\n );\n this.clearDebuggerSession(tabId);\n return info;\n }\n }\n\n private async initializeDebuggerDomains(\n tabId: number\n ): Promise<DriveErrorInfo | null> {\n // Some CDP features (notably JS dialog handling + console/network events)\n // require domains to be enabled first. This must happen before a dialog\n // opens, otherwise Page.handleJavaScriptDialog can return \"No dialog is showing\".\n const methods: Array<[string, Record<string, unknown> | undefined]> = [\n ['Page.enable', undefined],\n ['Runtime.enable', undefined],\n ['Log.enable', undefined],\n ['Network.enable', undefined],\n ];\n\n try {\n for (const [method, params] of methods) {\n await this.sendDebuggerCommand(\n tabId,\n method,\n params,\n DEFAULT_DEBUGGER_COMMAND_TIMEOUT_MS\n );\n }\n return null;\n } catch (error) {\n return mapDebuggerErrorMessage(\n error instanceof Error\n ? error.message\n : 'Debugger initialization failed.'\n );\n }\n }\n\n private async checkDebuggerTarget(\n tabId: number\n ): Promise<DriveErrorInfo | null> {\n try {\n const tab = await getTab(tabId);\n const url = typeof tab.url === 'string' ? tab.url : undefined;\n if (isRestrictedUrl(url)) {\n return {\n code: 'NOT_SUPPORTED',\n message: 'Debugger cannot attach to restricted pages.',\n retryable: false,\n details: { url },\n };\n }\n } catch (error) {\n return mapDebuggerErrorMessage(\n error instanceof Error ? error.message : 'Failed to locate tab.',\n 'TAB_NOT_FOUND'\n );\n }\n return null;\n }\n\n private async detachDebugger(tabId: number): Promise<DriveErrorInfo | null> {\n const session = this.debuggerSessions.get(tabId);\n if (!session) {\n return null;\n }\n if (session.attachPromise) {\n try {\n await session.attachPromise;\n } catch (error) {\n console.debug('Debugger attach promise failed before detach.', error);\n this.clearDebuggerSession(tabId);\n return null;\n }\n }\n if (!session.attached) {\n this.clearDebuggerSession(tabId);\n return null;\n }\n try {\n await wrapChromeVoid((callback) =>\n chrome.debugger.detach({ tabId }, () => callback())\n );\n } catch (error) {\n return mapDebuggerErrorMessage(\n error instanceof Error ? error.message : 'Debugger detach failed.'\n );\n } finally {\n this.clearDebuggerSession(tabId);\n }\n return null;\n }\n\n private async sendDebuggerCommand(\n tabId: number,\n method: string,\n params: Record<string, unknown> | undefined,\n timeoutMs: number\n ): Promise<unknown> {\n return await new Promise((resolve, reject) => {\n let finished = false;\n const timeout = self.setTimeout(() => {\n finished = true;\n reject(new DebuggerTimeoutError(timeoutMs));\n }, timeoutMs);\n\n chrome.debugger.sendCommand(\n { tabId },\n method,\n params ?? {},\n (result: unknown) => {\n if (finished) {\n return;\n }\n finished = true;\n clearTimeout(timeout);\n const error = chrome.runtime.lastError;\n if (error) {\n reject(new Error(error.message));\n return;\n }\n resolve(result);\n }\n );\n });\n }\n\n private touchDebuggerSession(tabId: number): void {\n const session = this.debuggerSessions.get(tabId);\n if (!session) {\n return;\n }\n session.lastActivityAt = nowIso();\n void this.refreshDebuggerIdleTimer(tabId).catch((error) => {\n console.error('DriveSocket refreshDebuggerIdleTimer failed:', error);\n });\n }\n\n private async refreshDebuggerIdleTimer(tabId: number): Promise<void> {\n const session = this.debuggerSessions.get(tabId);\n if (!session) {\n return;\n }\n if (session.idleTimer) {\n clearTimeout(session.idleTimer);\n }\n const timeoutMs = await this.getDebuggerIdleTimeoutMs();\n session.idleTimer = self.setTimeout(() => {\n void this.detachDebugger(tabId).catch((error) => {\n console.error('DriveSocket detachDebugger failed:', error);\n });\n }, timeoutMs);\n }\n\n private clearDebuggerSession(tabId: number): void {\n const session = this.debuggerSessions.get(tabId);\n if (!session) {\n return;\n }\n if (session.idleTimer) {\n clearTimeout(session.idleTimer);\n }\n this.debuggerSessions.delete(tabId);\n }\n\n private async getDebuggerIdleTimeoutMs(): Promise<number> {\n if (this.debuggerIdleTimeoutMs !== null) {\n return this.debuggerIdleTimeoutMs;\n }\n const timeout = await readDebuggerIdleTimeoutMs();\n this.debuggerIdleTimeoutMs = timeout;\n return timeout;\n }\n}\n\nclass DebuggerTimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Debugger command timed out after ${timeoutMs}ms.`);\n this.name = 'DebuggerTimeoutError';\n }\n}\n\nconst socket = new DriveSocket();\n\nchrome.tabs.onActivated.addListener((activeInfo: { tabId: number }) => {\n markTabActive(activeInfo.tabId);\n socket.sendTabReport();\n});\n\nchrome.tabs.onCreated.addListener((tab: Record<string, unknown>) => {\n if (typeof tab.id === 'number') {\n ensureLastActiveAt(tab.id);\n }\n socket.sendTabReport();\n});\n\nchrome.tabs.onUpdated.addListener(\n (\n tabId: number,\n changeInfo: Record<string, unknown>,\n tab: Record<string, unknown>\n ) => {\n const shouldReport =\n Boolean(changeInfo.url) ||\n Boolean(changeInfo.title) ||\n changeInfo.status === 'complete';\n if (!shouldReport) {\n return;\n }\n if (tab && tab.active) {\n markTabActive(tabId);\n }\n socket.sendTabReport();\n }\n);\n\nchrome.tabs.onRemoved.addListener((tabId: number) => {\n lastActiveAtByTab.delete(tabId);\n socket.sendTabReport();\n});\n\nchrome.debugger.onEvent.addListener(\n (source: DebuggerTarget, method: string, params: Record<string, unknown>) => {\n void socket.handleDebuggerEvent(source, method, params).catch((error) => {\n console.error('DriveSocket handleDebuggerEvent failed:', error);\n });\n }\n);\n\nchrome.debugger.onDetach.addListener(\n (source: DebuggerTarget, reason?: string) => {\n void socket.handleDebuggerDetach(source, reason).catch((error) => {\n console.error('DriveSocket handleDebuggerDetach failed:', error);\n });\n }\n);\n\nsocket.start();\n"],
5
+ "mappings": ";AAoCA,IAAM,oBAAoB;AAC1B,IAAM,gBAAgB;AACtB,IAAM,eAAe;AAErB,IAAM,4BAA4B;AAClC,IAAM,4BAA4B;AAClC,IAAM,mCAAmC;AACzC,IAAM,sCAAsC;AAE5C,IAAM,SAAS,OAAc,oBAAI,KAAK,GAAE,YAAY;AAEpD,IAAM,cAAe,uBAAM;AACzB,MAAI,UAAU;AACd,SAAO,MAAM,OAAO,KAAK,IAAI,CAAC,IAAK,WAAW,CAAE;AAClD,GAAG;AAEH,IAAM,oBAAoB,oBAAI,IAAoB;AAElD,IAAM,qBAAqB,CAAC,UAA0B;AACpD,QAAM,WAAW,kBAAkB,IAAI,KAAK;AAC5C,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AACA,QAAM,YAAY,OAAO;AACzB,oBAAkB,IAAI,OAAO,SAAS;AACtC,SAAO;AACT;AAEA,IAAM,gBAAgB,CAAC,UAA0B;AAC/C,QAAM,YAAY,OAAO;AACzB,oBAAkB,IAAI,OAAO,SAAS;AACtC,SAAO;AACT;AAEA,IAAM,qBAAqB,CACzB,YAEA,IAAI,QAAW,CAAC,SAAS,WAAW;AAClC,UAAQ,CAAC,UAAa;AACpB,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,OAAO;AACT,aAAO,IAAI,MAAM,MAAM,OAAO,CAAC;AAC/B;AAAA,IACF;AACA,YAAQ,KAAK;AAAA,EACf,CAAC;AACH,CAAC;AAEH,IAAM,iBAAiB,CACrB,YACkB;AAClB,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,YAAQ,MAAM;AACZ,YAAM,QAAQ,OAAO,QAAQ;AAC7B,UAAI,OAAO;AACT,eAAO,IAAI,MAAM,MAAM,OAAO,CAAC;AAC/B;AAAA,MACF;AACA,cAAQ;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,IAAM,eAAe,YAA6B;AAChD,SAAO,MAAM,IAAI,QAAgB,CAAC,YAAY;AAC5C,WAAO,QAAQ,MAAM;AAAA,MACnB,CAAC,aAAa;AAAA,MACd,CAAC,WAAoC;AACnC,cAAM,MAAM,SAAS,aAAa;AAClC,YAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG,GAAG;AACnD,kBAAQ,GAAG;AACX;AAAA,QACF;AACA,YAAI,OAAO,QAAQ,UAAU;AAC3B,gBAAM,SAAS,OAAO,GAAG;AACzB,cAAI,OAAO,SAAS,MAAM,GAAG;AAC3B,oBAAQ,MAAM;AACd;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,iBAAiB;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,IAAM,4BAA4B,YAA6B;AAC7D,SAAO,MAAM,IAAI,QAAgB,CAAC,YAAY;AAC5C,WAAO,QAAQ,MAAM;AAAA,MACnB,CAAC,yBAAyB;AAAA,MAC1B,CAAC,WAAoC;AACnC,cAAM,MAAM,SAAS,yBAAyB;AAC9C,YAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG,KAAK,MAAM,GAAG;AAC9D,kBAAQ,GAAG;AACX;AAAA,QACF;AACA,YAAI,OAAO,QAAQ,UAAU;AAC3B,gBAAM,SAAS,OAAO,GAAG;AACzB,cAAI,OAAO,SAAS,MAAM,KAAK,SAAS,GAAG;AACzC,oBAAQ,MAAM;AACd;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,gCAAgC;AAAA,MAC1C;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,kBAAkB,CAAC,QAA0B;AACjD,MAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,WAAO;AAAA,EACT;AACA,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,wBAAwB,KAAK,CAAC,WAAW,QAAQ,WAAW,MAAM,CAAC,GAAG;AACxE,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,QAAI,OAAO,aAAa,6BAA6B;AACnD,aAAO;AAAA,IACT;AACA,QAAI,OAAO,aAAa,qBAAqB;AAC3C,aAAO,OAAO,SAAS,WAAW,WAAW;AAAA,IAC/C;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,8CAA8C,KAAK;AAAA,EACnE;AACA,SAAO;AACT;AAEA,IAAM,0BAA0B,CAC9B,SACA,eAAe,0BACI;AACnB,QAAM,aAAa,QAAQ,YAAY;AACvC,MACE,WAAW,SAAS,kBAAkB,KACtC,WAAW,SAAS,kBAAkB,KACtC,WAAW,SAAS,yBAAyB,GAC7C;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SACE;AAAA,MACF,WAAW;AAAA,MACX,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACA,MACE,WAAW,SAAS,QAAQ,KAC5B,WAAW,SAAS,WAAW,KAC/B,WAAW,SAAS,QAAQ,GAC5B;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,WAAW;AAAA,IACb;AAAA,EACF;AACA,MACE,WAAW,SAAS,aAAa,KACjC,WAAW,SAAS,YAAY,KAChC,WAAW,SAAS,QAAQ,GAC5B;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,WAAW;AAAA,IACb;AAAA,EACF;AACA,MACE,WAAW,SAAS,eAAe,KACnC,WAAW,SAAS,eAAe,KACnC,WAAW,SAAS,YAAY,GAChC;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,WAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,WAAW;AAAA,EACb;AACF;AAEA,IAAM,eAAe,CAAC,QAAsD;AAC1E,QAAM,QAAQ,IAAI;AAClB,QAAM,WAAW,IAAI;AACrB,MAAI,OAAO,UAAU,YAAY,OAAO,aAAa,UAAU;AAC7D,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,KAAK,OAAO,IAAI,QAAQ,WAAW,IAAI,MAAM;AAAA,IAC7C,OAAO,OAAO,IAAI,UAAU,WAAW,IAAI,QAAQ;AAAA,IACnD,QAAQ,OAAO,IAAI,WAAW,YAAY,IAAI,SAAS;AAAA,IACvD,gBAAgB,mBAAmB,KAAK;AAAA,EAC1C;AACF;AAEA,IAAM,YAAY,YAAqC;AACrD,QAAM,OAAO,MAAM;AAAA,IAA8C,CAAC,aAChE,OAAO,KAAK,MAAM,CAAC,GAAG,QAAQ;AAAA,EAChC;AACA,QAAM,SAAyB,CAAC;AAChC,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,aAAa,GAAG;AAC7B,QAAI,MAAM;AACR,aAAO,KAAK,IAAI;AAAA,IAClB;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,SAAS,OAAO,UAAoD;AACxE,SAAO,MAAM;AAAA,IAA4C,CAAC,aACxD,OAAO,KAAK,IAAI,OAAO,QAAQ;AAAA,EACjC;AACF;AAEA,IAAM,iBAAiB,YAA6B;AAClD,QAAM,OAAO,MAAM;AAAA,IAA8C,CAAC,aAChE,OAAO,KAAK,MAAM,EAAE,QAAQ,MAAM,mBAAmB,KAAK,GAAG,QAAQ;AAAA,EACvE;AACA,QAAM,QAAQ,KAAK,CAAC;AACpB,MAAI,SAAS,OAAO,MAAM,OAAO,UAAU;AACzC,WAAO,MAAM;AAAA,EACf;AACA,QAAM,IAAI,MAAM,sBAAsB;AACxC;AAEA,IAAM,YAAY,OAChB,OACA,QACA,WAC2B;AAC3B,SAAO,MAAM,IAAI,QAAuB,CAAC,YAAY;AACnD,UAAM,UAA0B,EAAE,QAAQ,OAAO;AACjD,WAAO,KAAK,YAAY,OAAO,SAAS,CAAC,aAA4B;AACnE,YAAM,QAAQ,OAAO,QAAQ;AAC7B,UAAI,OAAO;AACT,gBAAQ;AAAA,UACN,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS,MAAM;AAAA,YACf,WAAW;AAAA,UACb;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACA,UAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,gBAAQ;AAAA,UACN,IAAI;AAAA,UACJ,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,YACT,WAAW;AAAA,UACb;AAAA,QACF,CAAC;AACD;AAAA,MACF;AACA,cAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,IAAM,0BAA0B,OAC9B,OACA,cACkB;AAClB,SAAO,MAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAClD,QAAI;AACJ,UAAM,UAAU,MAAM;AACpB,UAAI,YAAY,QAAW;AACzB,qBAAa,OAAO;AAAA,MACtB;AACA,aAAO,cAAc,mBAAmB,eAAe,QAAQ;AAAA,IACjE;AAEA,UAAM,WAAW,CAAC,YAAgD;AAChE,UAAI,QAAQ,UAAU,SAAS,QAAQ,YAAY,GAAG;AACpD;AAAA,MACF;AACA,cAAQ;AACR,cAAQ;AAAA,IACV;AAEA,WAAO,cAAc,mBAAmB,YAAY,QAAQ;AAC5D,cAAU,KAAK,WAAW,MAAM;AAC9B,cAAQ;AACR,aAAO,IAAI,MAAM,yCAAyC,CAAC;AAAA,IAC7D,GAAG,SAAS;AAAA,EACd,CAAC;AACH;AAEA,IAAM,WAAW,YAA6B;AAC5C,QAAM,OAAO,MAAM,aAAa;AAChC,SAAO,kBAAkB,IAAI,GAAG,YAAY;AAC9C;AAEA,IAAM,cAAN,MAAkB;AAAA,EAAlB;AACE,SAAQ,SAA2B;AACnC,SAAQ,iBAAgC;AACxC,SAAQ,mBAAmB;AAC3B,SAAiB,sBAAsB;AACvC,SAAQ,iBAAgC;AACxC,SAAiB,sBAAsB;AACvC,SAAiB,mBAAmB,oBAAI,IAA6B;AACrE,SAAQ,wBAAuC;AAAA;AAAA,EAE/C,QAAc;AACZ,SAAK,KAAK,QAAQ,EAAE,MAAM,CAAC,UAAU;AACnC,cAAQ,MAAM,+BAA+B,KAAK;AAAA,IACpD,CAAC;AAAA,EACH;AAAA,EAEA,OAAa;AACX,QAAI,KAAK,mBAAmB,MAAM;AAChC,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AACA,SAAK,cAAc;AACnB,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,MAAM;AAClB,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,gBAAsB;AACpB,SAAK,KAAK,cAAc,EAAE,MAAM,CAAC,UAAU;AACzC,cAAQ,MAAM,qCAAqC,KAAK;AAAA,IAC1D,CAAC;AAAA,EACH;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,mBAAmB,MAAM;AAChC;AAAA,IACF;AACA,UAAM,QAAQ,KAAK;AACnB,SAAK,iBAAiB,KAAK,WAAW,MAAM;AAC1C,WAAK,iBAAiB;AACtB,WAAK,KAAK,QAAQ,EAAE,MAAM,CAAC,UAAU;AACnC,gBAAQ,MAAM,iCAAiC,KAAK;AAAA,MACtD,CAAC;AAAA,IACH,GAAG,KAAK;AACR,SAAK,mBAAmB,KAAK;AAAA,MAC3B,KAAK;AAAA,MACL,KAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,MAAc,UAAyB;AACrC,UAAM,MAAM,MAAM,SAAS;AAC3B,QAAI;AACF,YAAMA,UAAS,IAAI,UAAU,GAAG;AAChC,WAAK,SAASA;AAEd,MAAAA,QAAO,iBAAiB,QAAQ,MAAM;AACpC,aAAK,mBAAmB;AACxB,aAAK,eAAe;AACpB,aAAK,KAAK,UAAU,EAAE,MAAM,CAAC,UAAU;AACrC,kBAAQ,MAAM,6BAA6B,KAAK;AAAA,QAClD,CAAC;AAAA,MACH,CAAC;AAED,MAAAA,QAAO,iBAAiB,WAAW,CAAC,UAAU;AAC5C,aAAK,cAAc,MAAM,IAAI;AAAA,MAC/B,CAAC;AAED,MAAAA,QAAO,iBAAiB,SAAS,MAAM;AACrC,aAAK,SAAS;AACd,aAAK,cAAc;AACnB,aAAK,kBAAkB;AAAA,MACzB,CAAC;AAED,MAAAA,QAAO,iBAAiB,SAAS,MAAM;AACrC,aAAK,SAAS;AACd,aAAK,cAAc;AACnB,aAAK,kBAAkB;AAAA,MACzB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,qDAAqD,KAAK;AACxE,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAc,YAA2B;AACvC,UAAM,WAAW,OAAO,QAAQ,YAAY;AAC5C,QAAI,OAAuB,CAAC;AAC5B,QAAI;AACF,aAAO,MAAM,UAAU;AAAA,IACzB,SAAS,OAAO;AACd,cAAQ,MAAM,8CAA8C,KAAK;AACjE,aAAO,CAAC;AAAA,IACV;AACA,UAAM,SAA2B;AAAA,MAC/B,SAAS,SAAS;AAAA,MAClB;AAAA,IACF;AACA,SAAK,UAAU,eAAe,MAAM;AAAA,EACtC;AAAA,EAEA,MAAc,gBAA+B;AAC3C,QAAI;AACF,YAAM,OAAO,MAAM,UAAU;AAC7B,WAAK,UAAU,oBAAoB,EAAE,KAAK,CAAC;AAAA,IAC7C,SAAS,OAAO;AACd,cAAQ,MAAM,qCAAqC,KAAK;AAAA,IAC1D;AAAA,EACF;AAAA,EAEQ,UACN,QACA,QACM;AACN,UAAM,UAAsB;AAAA,MAC1B,IAAI,YAAY;AAAA,MAChB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACF;AACA,SAAK,YAAY,OAAO;AAAA,EAC1B;AAAA,EAEQ,iBAAuB;AAC7B,SAAK,cAAc;AACnB,SAAK,iBAAiB,KAAK,YAAY,MAAM;AAC3C,UAAI,CAAC,KAAK,UAAU,KAAK,OAAO,eAAe,UAAU,MAAM;AAC7D;AAAA,MACF;AACA,WAAK,UAAU,mBAAmB,CAAC,CAAC;AAAA,IACtC,GAAG,KAAK,mBAAmB;AAAA,EAC7B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,mBAAmB,MAAM;AAChC,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,kBAAkB,QAAuC;AAC/D,UAAM,UAAyB;AAAA,MAC7B,IAAI,YAAY;AAAA,MAChB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,IACF;AACA,SAAK,YAAY,OAAO;AAAA,EAC1B;AAAA,EAEQ,YAAY,SAAiC;AACnD,QAAI,CAAC,KAAK,UAAU,KAAK,OAAO,eAAe,UAAU,MAAM;AAC7D;AAAA,IACF;AACA,SAAK,OAAO,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,EAC1C;AAAA,EAEQ,cAAc,KAAoB;AACxC,QAAI,OAAO,QAAQ,UAAU;AAC3B;AAAA,IACF;AACA,QAAI,UAAmC;AACvC,QAAI;AACF,gBAAU,KAAK,MAAM,GAAG;AAAA,IAC1B,SAAS,OAAO;AACd,cAAQ,MAAM,8CAA8C,KAAK;AACjE;AAAA,IACF;AACA,QAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C;AAAA,IACF;AACA,QAAI,QAAQ,WAAW,WAAW;AAChC,WAAK,KAAK,cAAc,OAA2B,EAAE,MAAM,CAAC,UAAU;AACpE,gBAAQ,MAAM,qCAAqC,KAAK;AAAA,MAC1D,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,cAAc,SAA0C;AACpE,QAAI,eAAoC;AACxC,UAAM,YAAY,CAAC,WAA2B;AAC5C,UAAI,CAAC,cAAc;AACjB;AAAA,MACF;AACA,YAAM,WAA0B;AAAA,QAC9B,IAAI,aAAa;AAAA,QACjB,QAAQ,aAAa;AAAA,QACrB,QAAQ;AAAA,QACR;AAAA,MACF;AACA,WAAK,YAAY,QAAQ;AAAA,IAC3B;AAEA,UAAM,eAAe,CAAC,UAAgC;AACpD,UAAI,CAAC,cAAc;AACjB;AAAA,MACF;AACA,YAAM,WAA0B;AAAA,QAC9B,IAAI,aAAa;AAAA,QACjB,QAAQ,aAAa;AAAA,QACrB,QAAQ;AAAA,QACR;AAAA,MACF;AACA,WAAK,YAAY,QAAQ;AAAA,IAC3B;AAEA,QAAI;AACF,UACE,CAAC,WACD,OAAO,YAAY,YACnB,OAAO,QAAQ,OAAO,YACtB,OAAO,QAAQ,WAAW,UAC1B;AACA;AAAA,MACF;AACA,UAAI,QAAQ,OAAO,WAAW,WAAW,GAAG;AAC1C,cAAM,KAAK,sBAAsB,OAA0B;AAC3D;AAAA,MACF;AAEA,UAAI,CAAC,QAAQ,OAAO,WAAW,QAAQ,GAAG;AACxC;AAAA,MACF;AAEA,qBAAe;AACf,cAAQ,QAAQ,QAAQ;AAAA,QACtB,KAAK,cAAc;AACjB,oBAAU,EAAE,IAAI,KAAK,CAAC;AACtB;AAAA,QACF;AAAA,QACA,KAAK,kBAAkB;AACrB,gBAAM,SAAU,QAAQ,UAAU,CAAC;AACnC,gBAAM,MAAM,OAAO;AACnB,cAAI,OAAO,QAAQ,YAAY,IAAI,WAAW,GAAG;AAC/C,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,cAAI,QAAQ,OAAO;AACnB,cAAI,UAAU,UAAa,OAAO,UAAU,UAAU;AACpD,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,cAAI,UAAU,QAAW;AACvB,oBAAQ,MAAM,eAAe;AAAA,UAC/B;AACA,gBAAM,WACJ,OAAO,SAAS,UAAU,OAAO,SAAS,qBACtC,OAAO,OACP;AACN,gBAAM;AAAA,YAAe,CAAC,aACpB,OAAO,KAAK,OAAO,OAAiB,EAAE,IAAI,GAAG,MAAM,SAAS,CAAC;AAAA,UAC/D;AACA,wBAAc,KAAe;AAC7B,cAAI,aAAa,oBAAoB;AACnC,gBAAI;AACF,oBAAM,wBAAwB,OAAiB,GAAK;AAAA,YACtD,SAAS,OAAO;AACd,2BAAa;AAAA,gBACX,MAAM;AAAA,gBACN,SACE,iBAAiB,QAAQ,MAAM,UAAU;AAAA,gBAC3C,WAAW;AAAA,cACb,CAAC;AACD;AAAA,YACF;AAAA,UACF;AACA,oBAAU,EAAE,IAAI,KAAK,CAAC;AACtB;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK,iBAAiB;AACpB,gBAAM,SAAU,QAAQ,UAAU,CAAC;AACnC,cAAI,QAAQ,OAAO;AACnB,cAAI,UAAU,UAAa,OAAO,UAAU,UAAU;AACpD,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,cAAI,UAAU,QAAW;AACvB,oBAAQ,MAAM,eAAe;AAAA,UAC/B;AACA,cAAI;AACF,kBAAM,SACJ,QAAQ,WAAW,mBACnB,QAAQ,WAAW;AACrB,kBAAM,eAAe,CAAC,aAAa;AACjC,kBAAI,QAAQ;AACV,uBAAO,KAAK,OAAO,OAAiB,MAAM,SAAS,CAAC;AAAA,cACtD,OAAO;AACL,uBAAO,KAAK,UAAU,OAAiB,MAAM,SAAS,CAAC;AAAA,cACzD;AAAA,YACF,CAAC;AAAA,UACH,SAAS,OAAO;AACd,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SACE,iBAAiB,QAAQ,MAAM,UAAU;AAAA,cAC3C,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,wBAAc,KAAe;AAC7B,cAAI;AACF,kBAAM,wBAAwB,OAAiB,GAAK;AAAA,UACtD,SAAS,OAAO;AACd,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SACE,iBAAiB,QAAQ,MAAM,UAAU;AAAA,cAC3C,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,oBAAU,EAAE,IAAI,KAAK,CAAC;AACtB;AAAA,QACF;AAAA,QACA,KAAK,kBAAkB;AACrB,gBAAM,OAAO,MAAM,UAAU;AAC7B,gBAAM,SAA6B,EAAE,KAAK;AAC1C,oBAAU,MAAM;AAChB;AAAA,QACF;AAAA,QACA,KAAK,sBAAsB;AACzB,gBAAM,QAAS,QAAQ,QACnB;AACJ,cAAI,OAAO,UAAU,UAAU;AAC7B,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,gBAAM,MAAM,MAAM,OAAO,KAAK;AAC9B,gBAAM;AAAA,YAAe,CAAC,aACpB,OAAO,KAAK,OAAO,OAAO,EAAE,QAAQ,KAAK,GAAG,MAAM,SAAS,CAAC;AAAA,UAC9D;AACA,gBAAM,WAAW,IAAI;AACrB,cAAI,OAAO,aAAa,UAAU;AAChC,kBAAM;AAAA,cAAe,CAAC,aACpB,OAAO,QAAQ;AAAA,gBAAO;AAAA,gBAAU,EAAE,SAAS,KAAK;AAAA,gBAAG,MACjD,SAAS;AAAA,cACX;AAAA,YACF;AAAA,UACF;AACA,wBAAc,KAAK;AACnB,oBAAU,EAAE,IAAI,KAAK,CAAC;AACtB,eAAK,cAAc;AACnB;AAAA,QACF;AAAA,QACA,KAAK,mBAAmB;AACtB,gBAAM,QAAS,QAAQ,QACnB;AACJ,cAAI,OAAO,UAAU,UAAU;AAC7B,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,gBAAM;AAAA,YAAe,CAAC,aACpB,OAAO,KAAK,OAAO,OAAO,MAAM,SAAS,CAAC;AAAA,UAC5C;AACA,4BAAkB,OAAO,KAAK;AAC9B,oBAAU,EAAE,IAAI,KAAK,CAAC;AACtB,eAAK,cAAc;AACnB;AAAA,QACF;AAAA,QACA,KAAK,uBAAuB;AAC1B,gBAAM,SAAU,QAAQ,UAAU,CAAC;AACnC,gBAAM,SAAS,OAAO;AACtB,cAAI,WAAW,YAAY,WAAW,WAAW;AAC/C,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,gBAAM,aAAa,OAAO;AAC1B,cAAI,eAAe,UAAa,OAAO,eAAe,UAAU;AAC9D,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,cAAI,QAAQ,OAAO;AACnB,cAAI,UAAU,UAAa,OAAO,UAAU,UAAU;AACpD,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,cAAI,UAAU,QAAW;AACvB,oBAAQ,MAAM,eAAe;AAAA,UAC/B;AAEA,gBAAM,QAAQ,MAAM,KAAK,uBAAuB,KAAe;AAC/D,cAAI,OAAO;AACT,yBAAa,KAAK;AAClB;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,KAAK;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,gBACE,QAAQ,WAAW;AAAA,gBACnB,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,cACrC;AAAA,cACA;AAAA,YACF;AACA,iBAAK,qBAAqB,KAAe;AACzC,sBAAU,EAAE,IAAI,KAAK,CAAC;AAAA,UACxB,SAASC,QAAO;AACd,kBAAM,OAAO;AAAA,cACXA,kBAAiB,QAAQA,OAAM,UAAU;AAAA,YAC3C;AACA,yBAAa,IAAI;AAAA,UACnB;AACA;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK,kBAAkB;AACrB,gBAAM,SAAU,QAAQ,UAAU,CAAC;AACnC,cAAI,QAAQ,OAAO;AACnB,cAAI,UAAU,UAAa,OAAO,UAAU,UAAU;AACpD,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,cAAI,UAAU,QAAW;AACvB,oBAAQ,MAAM,eAAe;AAAA,UAC/B;AACA,gBAAM,SAAS,MAAM;AAAA,YACnB;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,UACF;AACA,cAAI,OAAO,IAAI;AACb,sBAAU,OAAO,UAAU,EAAE,IAAI,KAAK,CAAC;AAAA,UACzC,OAAO;AACL,yBAAa,OAAO,KAAK;AAAA,UAC3B;AACA;AAAA,QACF;AAAA,QACA;AACE,uBAAa;AAAA,YACX,MAAM;AAAA,YACN,SAAS,GAAG,QAAQ,MAAM;AAAA,YAC1B,WAAW;AAAA,UACb,CAAC;AAAA,MACL;AAAA,IACF,SAAS,OAAO;AACd,YAAM,cACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,mBAAa;AAAA,QACX,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,sBAAsB,SAAyC;AAC3E,UAAM,aAAa,CAAC,WAA2B;AAC7C,WAAK,YAAY;AAAA,QACf,IAAI,QAAQ;AAAA,QACZ,QAAQ,QAAQ;AAAA,QAChB,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,eAAe,CAAC,UAAgC;AACpD,WAAK,YAAY;AAAA,QACf,IAAI,QAAQ;AAAA,QACZ,QAAQ,QAAQ;AAAA,QAChB,QAAQ;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI;AACF,cAAQ,QAAQ,QAAQ;AAAA,QACtB,KAAK,mBAAmB;AACtB,gBAAM,SAAU,QAAQ,UAAU,CAAC;AACnC,gBAAM,QAAQ,OAAO;AACrB,cAAI,OAAO,UAAU,UAAU;AAC7B,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AAEA,gBAAM,QAAQ,MAAM,KAAK,uBAAuB,KAAK;AACrD,cAAI,OAAO;AACT,yBAAa,KAAK;AAClB;AAAA,UACF;AACA,qBAAW,EAAE,IAAI,KAAK,CAAC;AACvB;AAAA,QACF;AAAA,QACA,KAAK,mBAAmB;AACtB,gBAAM,SAAU,QAAQ,UAAU,CAAC;AACnC,gBAAM,QAAQ,OAAO;AACrB,cAAI,OAAO,UAAU,UAAU;AAC7B,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,gBAAM,QAAQ,MAAM,KAAK,eAAe,KAAK;AAC7C,cAAI,OAAO;AACT,yBAAa,KAAK;AAClB;AAAA,UACF;AACA,qBAAW,EAAE,IAAI,KAAK,CAAC;AACvB;AAAA,QACF;AAAA,QACA,KAAK,oBAAoB;AACvB,gBAAM,SAAU,QAAQ,UAAU,CAAC;AACnC,gBAAM,QAAQ,OAAO;AACrB,cAAI,OAAO,UAAU,UAAU;AAC7B,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AACA,cAAI,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,WAAW,GAAG;AACnE,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AAEA,gBAAM,UAAU,KAAK,iBAAiB,IAAI,KAAK;AAC/C,cAAI,SAAS,eAAe;AAC1B,gBAAI;AACF,oBAAM,QAAQ;AAAA,YAChB,SAAS,OAAO;AACd,oBAAM,OAAO;AAAA,gBACX,iBAAiB,QACb,MAAM,UACN;AAAA,cACN;AACA,mBAAK,qBAAqB,KAAK;AAC/B,2BAAa,IAAI;AACjB;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,kBAAkB,KAAK,iBAAiB,IAAI,KAAK;AACvD,cAAI,CAAC,iBAAiB,UAAU;AAC9B,yBAAa;AAAA,cACX,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb,CAAC;AACD;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,SAAS,MAAM,KAAK;AAAA,cACxB;AAAA,cACA,OAAO;AAAA,cACP,OAAO;AAAA,cACP;AAAA,YACF;AACA,iBAAK,qBAAqB,KAAK;AAC/B,uBAAW,MAAM;AAAA,UACnB,SAAS,OAAO;AACd,gBAAI,iBAAiB,sBAAsB;AACzC,2BAAa;AAAA,gBACX,MAAM;AAAA,gBACN,SAAS,MAAM;AAAA,gBACf,WAAW;AAAA,cACb,CAAC;AACD;AAAA,YACF;AACA,kBAAM,OAAO;AAAA,cACX,iBAAiB,QACb,MAAM,UACN;AAAA,YACN;AACA,yBAAa,IAAI;AAAA,UACnB;AACA;AAAA,QACF;AAAA,QACA;AACE,uBAAa;AAAA,YACX,MAAM;AAAA,YACN,SAAS,GAAG,QAAQ,MAAM;AAAA,YAC1B,WAAW;AAAA,UACb,CAAC;AAAA,MACL;AAAA,IACF,SAAS,OAAO;AACd,YAAM,cACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,mBAAa;AAAA,QACX,MAAM;AAAA,QACN,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,oBACJ,QACA,QACA,QACe;AACf,UAAM,QAAQ,OAAO;AACrB,QAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,IACF;AACA,SAAK,qBAAqB,KAAK;AAC/B,SAAK,kBAAkB;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,WAAW,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,qBACJ,QACA,QACe;AACf,UAAM,QAAQ,OAAO;AACrB,QAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,IACF;AACA,SAAK,qBAAqB,KAAK;AAC/B,SAAK,kBAAkB;AAAA,MACrB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ,EAAE,QAAQ,UAAU,UAAU;AAAA,MACtC,WAAW,OAAO;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,uBACZ,OACgC;AAChC,UAAM,WAAW,KAAK,iBAAiB,IAAI,KAAK;AAChD,QAAI,UAAU,UAAU;AACtB,WAAK,qBAAqB,KAAK;AAC/B,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,eAAe;AAC3B,UAAI;AACF,cAAM,SAAS;AAAA,MACjB,SAAS,OAAO;AACd,cAAM,OAAO;AAAA,UACX,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAC3C;AACA,aAAK,qBAAqB,KAAK;AAC/B,eAAO;AAAA,MACT;AACA,UAAI,SAAS,UAAU;AACrB,aAAK,qBAAqB,KAAK;AAC/B,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM,KAAK,oBAAoB,KAAK;AAC3D,QAAI,gBAAgB;AAClB,aAAO;AAAA,IACT;AAEA,UAAM,UAA2B;AAAA,MAC/B,UAAU;AAAA,MACV,gBAAgB,OAAO;AAAA,IACzB;AACA,SAAK,iBAAiB,IAAI,OAAO,OAAO;AAExC,YAAQ,gBAAgB;AAAA,MAAe,CAAC,aACtC,OAAO,SAAS;AAAA,QAAO,EAAE,MAAM;AAAA,QAAG;AAAA,QAA2B,MAC3D,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAQ;AACd,cAAQ,WAAW;AACnB,cAAQ,gBAAgB;AACxB,YAAM,YAAY,MAAM,KAAK,0BAA0B,KAAK;AAC5D,UAAI,WAAW;AACb,cAAM,KAAK,eAAe,KAAK;AAC/B,eAAO;AAAA,MACT;AACA,cAAQ,cAAc;AACtB,WAAK,qBAAqB,KAAK;AAC/B,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,OAAO;AAAA,QACX,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AACA,WAAK,qBAAqB,KAAK;AAC/B,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,0BACZ,OACgC;AAIhC,UAAM,UAAgE;AAAA,MACpE,CAAC,eAAe,MAAS;AAAA,MACzB,CAAC,kBAAkB,MAAS;AAAA,MAC5B,CAAC,cAAc,MAAS;AAAA,MACxB,CAAC,kBAAkB,MAAS;AAAA,IAC9B;AAEA,QAAI;AACF,iBAAW,CAAC,QAAQ,MAAM,KAAK,SAAS;AACtC,cAAM,KAAK;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO;AAAA,QACL,iBAAiB,QACb,MAAM,UACN;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,oBACZ,OACgC;AAChC,QAAI;AACF,YAAM,MAAM,MAAM,OAAO,KAAK;AAC9B,YAAM,MAAM,OAAO,IAAI,QAAQ,WAAW,IAAI,MAAM;AACpD,UAAI,gBAAgB,GAAG,GAAG;AACxB,eAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW;AAAA,UACX,SAAS,EAAE,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,OAA+C;AAC1E,UAAM,UAAU,KAAK,iBAAiB,IAAI,KAAK;AAC/C,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,eAAe;AACzB,UAAI;AACF,cAAM,QAAQ;AAAA,MAChB,SAAS,OAAO;AACd,gBAAQ,MAAM,iDAAiD,KAAK;AACpE,aAAK,qBAAqB,KAAK;AAC/B,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,CAAC,QAAQ,UAAU;AACrB,WAAK,qBAAqB,KAAK;AAC/B,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM;AAAA,QAAe,CAAC,aACpB,OAAO,SAAS,OAAO,EAAE,MAAM,GAAG,MAAM,SAAS,CAAC;AAAA,MACpD;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AAAA,IACF,UAAE;AACA,WAAK,qBAAqB,KAAK;AAAA,IACjC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,oBACZ,OACA,QACA,QACA,WACkB;AAClB,WAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC5C,UAAI,WAAW;AACf,YAAM,UAAU,KAAK,WAAW,MAAM;AACpC,mBAAW;AACX,eAAO,IAAI,qBAAqB,SAAS,CAAC;AAAA,MAC5C,GAAG,SAAS;AAEZ,aAAO,SAAS;AAAA,QACd,EAAE,MAAM;AAAA,QACR;AAAA,QACA,UAAU,CAAC;AAAA,QACX,CAAC,WAAoB;AACnB,cAAI,UAAU;AACZ;AAAA,UACF;AACA,qBAAW;AACX,uBAAa,OAAO;AACpB,gBAAM,QAAQ,OAAO,QAAQ;AAC7B,cAAI,OAAO;AACT,mBAAO,IAAI,MAAM,MAAM,OAAO,CAAC;AAC/B;AAAA,UACF;AACA,kBAAQ,MAAM;AAAA,QAChB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,qBAAqB,OAAqB;AAChD,UAAM,UAAU,KAAK,iBAAiB,IAAI,KAAK;AAC/C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,YAAQ,iBAAiB,OAAO;AAChC,SAAK,KAAK,yBAAyB,KAAK,EAAE,MAAM,CAAC,UAAU;AACzD,cAAQ,MAAM,gDAAgD,KAAK;AAAA,IACrE,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,yBAAyB,OAA8B;AACnE,UAAM,UAAU,KAAK,iBAAiB,IAAI,KAAK;AAC/C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,QAAI,QAAQ,WAAW;AACrB,mBAAa,QAAQ,SAAS;AAAA,IAChC;AACA,UAAM,YAAY,MAAM,KAAK,yBAAyB;AACtD,YAAQ,YAAY,KAAK,WAAW,MAAM;AACxC,WAAK,KAAK,eAAe,KAAK,EAAE,MAAM,CAAC,UAAU;AAC/C,gBAAQ,MAAM,sCAAsC,KAAK;AAAA,MAC3D,CAAC;AAAA,IACH,GAAG,SAAS;AAAA,EACd;AAAA,EAEQ,qBAAqB,OAAqB;AAChD,UAAM,UAAU,KAAK,iBAAiB,IAAI,KAAK;AAC/C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,QAAI,QAAQ,WAAW;AACrB,mBAAa,QAAQ,SAAS;AAAA,IAChC;AACA,SAAK,iBAAiB,OAAO,KAAK;AAAA,EACpC;AAAA,EAEA,MAAc,2BAA4C;AACxD,QAAI,KAAK,0BAA0B,MAAM;AACvC,aAAO,KAAK;AAAA,IACd;AACA,UAAM,UAAU,MAAM,0BAA0B;AAChD,SAAK,wBAAwB;AAC7B,WAAO;AAAA,EACT;AACF;AAEA,IAAM,uBAAN,cAAmC,MAAM;AAAA,EACvC,YAAY,WAAmB;AAC7B,UAAM,oCAAoC,SAAS,KAAK;AACxD,SAAK,OAAO;AAAA,EACd;AACF;AAEA,IAAM,SAAS,IAAI,YAAY;AAE/B,OAAO,KAAK,YAAY,YAAY,CAAC,eAAkC;AACrE,gBAAc,WAAW,KAAK;AAC9B,SAAO,cAAc;AACvB,CAAC;AAED,OAAO,KAAK,UAAU,YAAY,CAAC,QAAiC;AAClE,MAAI,OAAO,IAAI,OAAO,UAAU;AAC9B,uBAAmB,IAAI,EAAE;AAAA,EAC3B;AACA,SAAO,cAAc;AACvB,CAAC;AAED,OAAO,KAAK,UAAU;AAAA,EACpB,CACE,OACA,YACA,QACG;AACH,UAAM,eACJ,QAAQ,WAAW,GAAG,KACtB,QAAQ,WAAW,KAAK,KACxB,WAAW,WAAW;AACxB,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AACA,QAAI,OAAO,IAAI,QAAQ;AACrB,oBAAc,KAAK;AAAA,IACrB;AACA,WAAO,cAAc;AAAA,EACvB;AACF;AAEA,OAAO,KAAK,UAAU,YAAY,CAAC,UAAkB;AACnD,oBAAkB,OAAO,KAAK;AAC9B,SAAO,cAAc;AACvB,CAAC;AAED,OAAO,SAAS,QAAQ;AAAA,EACtB,CAAC,QAAwB,QAAgB,WAAoC;AAC3E,SAAK,OAAO,oBAAoB,QAAQ,QAAQ,MAAM,EAAE,MAAM,CAAC,UAAU;AACvE,cAAQ,MAAM,2CAA2C,KAAK;AAAA,IAChE,CAAC;AAAA,EACH;AACF;AAEA,OAAO,SAAS,SAAS;AAAA,EACvB,CAAC,QAAwB,WAAoB;AAC3C,SAAK,OAAO,qBAAqB,QAAQ,MAAM,EAAE,MAAM,CAAC,UAAU;AAChE,cAAQ,MAAM,4CAA4C,KAAK;AAAA,IACjE,CAAC;AAAA,EACH;AACF;AAEA,OAAO,MAAM;",
6
+ "names": ["socket", "error"]
7
+ }