@elqnt/chat 2.0.8 → 3.0.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/README.md +386 -0
- package/dist/api/index.d.mts +250 -8
- package/dist/api/index.d.ts +250 -8
- package/dist/api/index.js +115 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +109 -0
- package/dist/api/index.mjs.map +1 -1
- package/dist/hooks/index.d.mts +78 -0
- package/dist/hooks/index.d.ts +78 -0
- package/dist/hooks/index.js +709 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +683 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +4 -109
- package/dist/index.d.ts +4 -109
- package/dist/index.js +699 -2039
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +690 -2016
- package/dist/index.mjs.map +1 -1
- package/dist/models/index.d.mts +76 -6
- package/dist/models/index.d.ts +76 -6
- package/dist/models/index.js +21 -0
- package/dist/models/index.js.map +1 -1
- package/dist/models/index.mjs +14 -0
- package/dist/models/index.mjs.map +1 -1
- package/dist/transport/index.d.mts +243 -0
- package/dist/transport/index.d.ts +243 -0
- package/dist/transport/index.js +875 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/index.mjs +843 -0
- package/dist/transport/index.mjs.map +1 -0
- package/dist/types-BB5nRdZs.d.mts +222 -0
- package/dist/types-CNvuxtcv.d.ts +222 -0
- package/package.json +20 -38
- package/dist/hooks/use-websocket-chat-admin.d.mts +0 -17
- package/dist/hooks/use-websocket-chat-admin.d.ts +0 -17
- package/dist/hooks/use-websocket-chat-admin.js +0 -1196
- package/dist/hooks/use-websocket-chat-admin.js.map +0 -1
- package/dist/hooks/use-websocket-chat-admin.mjs +0 -1172
- package/dist/hooks/use-websocket-chat-admin.mjs.map +0 -1
- package/dist/hooks/use-websocket-chat-base.d.mts +0 -81
- package/dist/hooks/use-websocket-chat-base.d.ts +0 -81
- package/dist/hooks/use-websocket-chat-base.js +0 -1025
- package/dist/hooks/use-websocket-chat-base.js.map +0 -1
- package/dist/hooks/use-websocket-chat-base.mjs +0 -1001
- package/dist/hooks/use-websocket-chat-base.mjs.map +0 -1
- package/dist/hooks/use-websocket-chat-customer.d.mts +0 -24
- package/dist/hooks/use-websocket-chat-customer.d.ts +0 -24
- package/dist/hooks/use-websocket-chat-customer.js +0 -1092
- package/dist/hooks/use-websocket-chat-customer.js.map +0 -1
- package/dist/hooks/use-websocket-chat-customer.mjs +0 -1068
- package/dist/hooks/use-websocket-chat-customer.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../transport/index.ts","../../transport/types.ts","../../transport/sse.ts","../../transport/sse-fetch.ts","../../transport/whatsapp.ts"],"sourcesContent":["/**\n * Transport Layer\n *\n * Platform-agnostic transport abstractions for chat communication.\n *\n * @example Browser (SSE)\n * ```typescript\n * import { createSSETransport } from \"@elqnt/chat/transport\";\n *\n * const transport = createSSETransport({ debug: true });\n * await transport.connect({ baseUrl, orgId, userId, clientType: \"customer\" });\n *\n * transport.onMessage((event) => {\n * console.log(\"Received:\", event);\n * });\n * ```\n *\n * @example React Native (Fetch-based SSE)\n * ```typescript\n * import { createFetchSSETransport } from \"@elqnt/chat/transport\";\n *\n * const transport = createFetchSSETransport();\n * await transport.connect({ baseUrl, orgId, userId, clientType: \"customer\" });\n * ```\n *\n * @example Custom Transport\n * ```typescript\n * import type { ChatTransport } from \"@elqnt/chat/transport\";\n *\n * const customTransport: ChatTransport = {\n * connect: async (config) => { ... },\n * disconnect: () => { ... },\n * send: async (event) => { ... },\n * sendMessage: async (message) => { ... },\n * onMessage: (handler) => { ... },\n * on: (eventType, handler) => { ... },\n * getState: () => { ... },\n * getMetrics: () => { ... },\n * getError: () => { ... },\n * clearError: () => { ... },\n * };\n * ```\n */\n\n// Types\nexport type {\n ChatTransport,\n TransportConfig,\n TransportState,\n TransportError,\n TransportFactory,\n TransportLogger,\n ConnectionMetrics,\n EventHandler,\n Unsubscribe,\n RetryConfig,\n SendMessageOptions,\n CreateChatOptions,\n LoadChatOptions,\n EndChatOptions,\n} from \"./types\";\n\nexport {\n createLogger,\n calculateRetryInterval,\n DEFAULT_RETRY_CONFIG,\n} from \"./types\";\n\n// Browser SSE transport\nexport { createSSETransport } from \"./sse\";\nexport type { SSETransportOptions } from \"./sse\";\n\n// Fetch-based SSE transport (React Native)\nexport { createFetchSSETransport } from \"./sse-fetch\";\nexport type { FetchSSETransportOptions } from \"./sse-fetch\";\n\n// WhatsApp Business API transport (stub)\nexport {\n createWhatsAppTransport,\n mapWhatsAppToChatEvent,\n} from \"./whatsapp\";\nexport type {\n WhatsAppTransportConfig,\n WhatsAppTransportOptions,\n WhatsAppMessageType,\n WhatsAppWebhookPayload,\n} from \"./whatsapp\";\n","/**\n * Transport Abstraction Layer Types\n *\n * Platform-agnostic transport interfaces for chat communication.\n * Supports browser SSE, React Native fetch-based SSE, and extensible\n * transports like WhatsApp Business API.\n */\n\nimport type { ChatEvent, ChatMessage } from \"../models\";\n\n/**\n * Transport connection state\n */\nexport type TransportState =\n | \"disconnected\"\n | \"connecting\"\n | \"connected\"\n | \"reconnecting\";\n\n/**\n * Transport error with retry information\n */\nexport interface TransportError {\n code:\n | \"CONNECTION_FAILED\"\n | \"PARSE_ERROR\"\n | \"SEND_FAILED\"\n | \"TIMEOUT\"\n | \"NETWORK_ERROR\"\n | \"AUTH_FAILED\";\n message: string;\n retryable: boolean;\n timestamp: number;\n originalError?: unknown;\n}\n\n/**\n * Configuration for transport connection\n */\nexport interface TransportConfig {\n /** Base URL for the chat server */\n baseUrl: string;\n /** Organization ID */\n orgId: string;\n /** User ID for authentication */\n userId: string;\n /** Client type for routing */\n clientType: \"customer\" | \"humanAgent\" | \"observer\";\n /** Optional current chat key for reconnection */\n chatKey?: string;\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Retry configuration for connection attempts\n */\nexport interface RetryConfig {\n /** Maximum number of retry attempts */\n maxRetries?: number;\n /** Initial retry intervals in milliseconds */\n intervals?: number[];\n /** Multiplier for exponential backoff */\n backoffMultiplier?: number;\n /** Maximum backoff time in milliseconds */\n maxBackoffTime?: number;\n}\n\n/**\n * Connection metrics for monitoring\n */\nexport interface ConnectionMetrics {\n /** Round-trip latency in milliseconds */\n latency: number;\n /** Total messages sent */\n messagesSent: number;\n /** Total messages received */\n messagesReceived: number;\n /** Messages waiting to be sent */\n messagesQueued: number;\n /** Number of reconnection attempts */\n reconnectCount: number;\n /** Last error encountered */\n lastError?: TransportError;\n /** Timestamp when connection was established */\n connectedAt?: number;\n /** Timestamp of last message */\n lastMessageAt?: number;\n /** Current transport type */\n transportType?: string;\n}\n\n/**\n * Event handler function type\n */\nexport type EventHandler<T = ChatEvent> = (event: T) => void;\n\n/**\n * Unsubscribe function returned by event subscription\n */\nexport type Unsubscribe = () => void;\n\n/**\n * Send message options\n */\nexport interface SendMessageOptions {\n /** Message content */\n content: string;\n /** Optional attachments */\n attachments?: unknown[];\n /** Optional message metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Create chat options\n */\nexport interface CreateChatOptions {\n /** Organization ID */\n orgId: string;\n /** User ID */\n userId: string;\n /** Optional chat metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Load chat options\n */\nexport interface LoadChatOptions {\n /** Organization ID */\n orgId: string;\n /** Chat key to load */\n chatKey: string;\n /** User ID */\n userId: string;\n}\n\n/**\n * End chat options\n */\nexport interface EndChatOptions {\n /** Organization ID */\n orgId: string;\n /** Chat key to end */\n chatKey: string;\n /** User ID */\n userId: string;\n /** Optional end reason */\n reason?: string;\n}\n\n/**\n * Core transport interface\n *\n * Implementations must handle:\n * - Connection lifecycle (connect, disconnect, reconnect)\n * - Message sending (POST requests)\n * - Event receiving (SSE stream)\n * - Error handling and recovery\n */\nexport interface ChatTransport {\n /**\n * Connect to the chat server\n * @param config - Transport configuration\n * @returns Promise that resolves when connected\n */\n connect(config: TransportConfig): Promise<void>;\n\n /**\n * Disconnect from the server\n * @param intentional - Whether disconnect was user-initiated\n */\n disconnect(intentional?: boolean): void;\n\n /**\n * Send a chat event to the server\n * @param event - Chat event to send\n */\n send(event: ChatEvent): Promise<void>;\n\n /**\n * Send a message in the current chat\n * @param message - Message to send\n */\n sendMessage(message: ChatMessage): Promise<void>;\n\n /**\n * Subscribe to incoming events\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n onMessage(handler: EventHandler): Unsubscribe;\n\n /**\n * Subscribe to specific event type\n * @param eventType - Type of event to listen for\n * @param handler - Event handler function\n * @returns Unsubscribe function\n */\n on(eventType: string, handler: EventHandler): Unsubscribe;\n\n /**\n * Get current connection state\n */\n getState(): TransportState;\n\n /**\n * Get connection metrics\n */\n getMetrics(): ConnectionMetrics;\n\n /**\n * Get last error\n */\n getError(): TransportError | undefined;\n\n /**\n * Clear error state\n */\n clearError(): void;\n}\n\n/**\n * Transport factory function type\n */\nexport type TransportFactory = (config?: Partial<TransportConfig>) => ChatTransport;\n\n/**\n * Logger interface for transport debugging\n */\nexport interface TransportLogger {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n}\n\n/**\n * Create a default logger\n * @param debug - Enable debug logging\n */\nexport function createLogger(debug: boolean = false): TransportLogger {\n return {\n debug: debug ? console.log.bind(console, \"[chat]\") : () => {},\n info: console.info.bind(console, \"[chat]\"),\n warn: console.warn.bind(console, \"[chat]\"),\n error: console.error.bind(console, \"[chat]\"),\n };\n}\n\n/**\n * Default retry configuration\n */\nexport const DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 10,\n intervals: [1000, 2000, 5000],\n backoffMultiplier: 1.5,\n maxBackoffTime: 30000,\n};\n\n/**\n * Calculate retry interval with exponential backoff\n * @param retryCount - Current retry attempt number\n * @param config - Retry configuration\n */\nexport function calculateRetryInterval(\n retryCount: number,\n config: RetryConfig = DEFAULT_RETRY_CONFIG\n): number {\n const {\n intervals = DEFAULT_RETRY_CONFIG.intervals,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n maxBackoffTime = DEFAULT_RETRY_CONFIG.maxBackoffTime,\n } = config;\n\n if (retryCount < intervals.length) {\n return intervals[retryCount];\n }\n\n const baseInterval = intervals[intervals.length - 1] || 5000;\n const backoffTime =\n baseInterval * Math.pow(backoffMultiplier, retryCount - intervals.length + 1);\n return Math.min(backoffTime, maxBackoffTime);\n}\n","/**\n * SSE Transport (Browser)\n *\n * Uses native EventSource for receiving server events and fetch POST for sending.\n * This is the default transport for browser environments.\n *\n * @example\n * ```typescript\n * import { createSSETransport } from \"@elqnt/chat/transport\";\n *\n * const transport = createSSETransport();\n * await transport.connect({ baseUrl, orgId, userId, clientType: \"customer\" });\n * ```\n */\n\nimport type { ChatEvent, ChatMessage } from \"../models\";\nimport type {\n ChatTransport,\n TransportConfig,\n TransportState,\n TransportError,\n ConnectionMetrics,\n EventHandler,\n Unsubscribe,\n RetryConfig,\n TransportLogger,\n} from \"./types\";\nimport { createLogger, calculateRetryInterval, DEFAULT_RETRY_CONFIG } from \"./types\";\n\n/**\n * SSE Transport options\n */\nexport interface SSETransportOptions {\n /** Retry configuration */\n retryConfig?: RetryConfig;\n /** Enable debug logging */\n debug?: boolean;\n /** Custom logger */\n logger?: TransportLogger;\n}\n\n/**\n * Create an SSE transport for browser environments\n */\nexport function createSSETransport(options: SSETransportOptions = {}): ChatTransport {\n const {\n retryConfig = DEFAULT_RETRY_CONFIG,\n debug = false,\n logger = createLogger(debug),\n } = options;\n\n // Internal state\n let eventSource: EventSource | undefined;\n let config: TransportConfig | undefined;\n let state: TransportState = \"disconnected\";\n let error: TransportError | undefined;\n let retryCount = 0;\n let reconnectTimeout: ReturnType<typeof setTimeout> | undefined;\n let intentionalDisconnect = false;\n\n // Metrics\n const metrics: ConnectionMetrics = {\n latency: 0,\n messagesSent: 0,\n messagesReceived: 0,\n messagesQueued: 0,\n reconnectCount: 0,\n transportType: \"sse\",\n };\n\n // Event handlers\n const globalHandlers = new Set<EventHandler>();\n const typeHandlers = new Map<string, Set<EventHandler>>();\n\n // Helper to emit events\n function emit(event: ChatEvent): void {\n // Update metrics\n metrics.messagesReceived++;\n metrics.lastMessageAt = Date.now();\n\n // Call global handlers\n globalHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n logger.error(\"Error in message handler:\", err);\n }\n });\n\n // Call type-specific handlers\n const handlers = typeHandlers.get(event.type);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n logger.error(`Error in ${event.type} handler:`, err);\n }\n });\n }\n }\n\n // REST API helper\n async function sendRest(endpoint: string, body: Record<string, unknown>): Promise<unknown> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n const url = `${config.baseUrl}/${endpoint}`;\n logger.debug(`POST ${endpoint}`, body);\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API error: ${response.status} - ${errorText}`);\n }\n\n return response.json();\n }\n\n // Handle SSE message\n function handleMessage(event: MessageEvent): void {\n if (!event.data || event.data === \"\") return;\n\n try {\n const data = JSON.parse(event.data) as ChatEvent;\n logger.debug(\"Received:\", data.type);\n emit(data);\n } catch (err) {\n logger.error(\"Failed to parse SSE message:\", err);\n }\n }\n\n // Setup SSE event listeners\n function setupEventListeners(es: EventSource): void {\n // Generic message handler\n es.addEventListener(\"message\", handleMessage);\n\n // Add handlers for known event types\n const eventTypes = [\n \"reconnected\", \"typing\", \"stopped_typing\", \"waiting\",\n \"waiting_for_agent\", \"human_agent_joined\", \"human_agent_left\",\n \"chat_ended\", \"chat_updated\", \"load_chat_response\",\n \"new_chat_created\", \"show_csat_survey\", \"csat_response\",\n \"user_suggested_actions\", \"agent_execution_started\",\n \"agent_execution_ended\", \"agent_context_update\",\n \"plan_pending_approval\", \"step_started\", \"step_completed\",\n \"step_failed\", \"plan_completed\", \"skills_changed\", \"summary_update\",\n ];\n\n eventTypes.forEach((type) => {\n es.addEventListener(type, handleMessage);\n });\n }\n\n // Schedule reconnect\n function scheduleReconnect(): void {\n if (intentionalDisconnect || !config) return;\n\n const maxRetries = retryConfig.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries;\n if (retryCount >= maxRetries) {\n logger.error(`Max retries (${maxRetries}) exceeded`);\n error = {\n code: \"CONNECTION_FAILED\",\n message: `Max retries (${maxRetries}) exceeded`,\n retryable: false,\n timestamp: Date.now(),\n };\n return;\n }\n\n const interval = calculateRetryInterval(retryCount, retryConfig);\n retryCount++;\n metrics.reconnectCount++;\n\n logger.info(`Reconnecting in ${interval}ms (attempt ${retryCount})`);\n state = \"reconnecting\";\n\n reconnectTimeout = setTimeout(() => {\n if (config) {\n transport.connect(config).catch((err) => {\n logger.error(\"Reconnect failed:\", err);\n });\n }\n }, interval);\n }\n\n const transport: ChatTransport = {\n async connect(cfg: TransportConfig): Promise<void> {\n config = cfg;\n intentionalDisconnect = false;\n\n // Clean up existing connection\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n if (reconnectTimeout) {\n clearTimeout(reconnectTimeout);\n reconnectTimeout = undefined;\n }\n\n state = retryCount > 0 ? \"reconnecting\" : \"connecting\";\n\n return new Promise((resolve, reject) => {\n const connectionStart = Date.now();\n const url = `${cfg.baseUrl}/stream?orgId=${cfg.orgId}&userId=${cfg.userId}&clientType=${cfg.clientType}${cfg.chatKey ? `&chatId=${cfg.chatKey}` : \"\"}`;\n\n logger.debug(\"Connecting to:\", url);\n const es = new EventSource(url);\n\n es.onopen = () => {\n const connectionTime = Date.now() - connectionStart;\n logger.info(`Connected in ${connectionTime}ms`);\n\n state = \"connected\";\n error = undefined;\n retryCount = 0;\n metrics.connectedAt = Date.now();\n metrics.latency = connectionTime;\n\n setupEventListeners(es);\n resolve();\n };\n\n es.onerror = () => {\n if (es.readyState === EventSource.CLOSED) {\n const sseError: TransportError = {\n code: \"CONNECTION_FAILED\",\n message: \"SSE connection failed\",\n retryable: true,\n timestamp: Date.now(),\n };\n error = sseError;\n metrics.lastError = sseError;\n state = \"disconnected\";\n\n if (!intentionalDisconnect) {\n scheduleReconnect();\n }\n\n // Only reject if this is the initial connection attempt\n if (retryCount === 0) {\n reject(sseError);\n }\n }\n };\n\n eventSource = es;\n });\n },\n\n disconnect(intentional = true): void {\n logger.info(\"Disconnecting\", { intentional });\n intentionalDisconnect = intentional;\n\n if (reconnectTimeout) {\n clearTimeout(reconnectTimeout);\n reconnectTimeout = undefined;\n }\n\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n state = \"disconnected\";\n retryCount = 0;\n },\n\n async send(event: ChatEvent): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n // Map event types to REST endpoints\n switch (event.type) {\n case \"message\":\n await sendRest(\"send\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n message: event.message,\n });\n break;\n\n case \"typing\":\n await sendRest(\"typing\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n typing: true,\n });\n break;\n\n case \"stopped_typing\":\n await sendRest(\"typing\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n typing: false,\n });\n break;\n\n case \"load_chat\":\n await sendRest(\"load\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n });\n break;\n\n case \"new_chat\":\n await sendRest(\"create\", {\n orgId: event.orgId,\n userId: event.userId,\n metadata: event.data,\n });\n break;\n\n case \"end_chat\":\n await sendRest(\"end\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n data: event.data,\n });\n break;\n\n default:\n // Generic event endpoint for other types\n await sendRest(\"event\", {\n type: event.type,\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n data: event.data,\n });\n }\n\n metrics.messagesSent++;\n },\n\n async sendMessage(message: ChatMessage): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n await sendRest(\"send\", {\n orgId: config.orgId,\n chatKey: config.chatKey,\n userId: config.userId,\n message,\n });\n\n metrics.messagesSent++;\n },\n\n onMessage(handler: EventHandler): Unsubscribe {\n globalHandlers.add(handler);\n return () => globalHandlers.delete(handler);\n },\n\n on(eventType: string, handler: EventHandler): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler);\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n getState(): TransportState {\n return state;\n },\n\n getMetrics(): ConnectionMetrics {\n return { ...metrics };\n },\n\n getError(): TransportError | undefined {\n return error;\n },\n\n clearError(): void {\n error = undefined;\n },\n };\n\n return transport;\n}\n","/**\n * SSE Transport (Fetch-based)\n *\n * Uses fetch with ReadableStream for receiving server events and fetch POST for sending.\n * Designed for React Native and environments without native EventSource support.\n *\n * @example\n * ```typescript\n * import { createFetchSSETransport } from \"@elqnt/chat/transport\";\n *\n * const transport = createFetchSSETransport();\n * await transport.connect({ baseUrl, orgId, userId, clientType: \"customer\" });\n * ```\n */\n\nimport type { ChatEvent, ChatMessage } from \"../models\";\nimport type {\n ChatTransport,\n TransportConfig,\n TransportState,\n TransportError,\n ConnectionMetrics,\n EventHandler,\n Unsubscribe,\n RetryConfig,\n TransportLogger,\n} from \"./types\";\nimport { createLogger, calculateRetryInterval, DEFAULT_RETRY_CONFIG } from \"./types\";\n\n/**\n * Fetch SSE Transport options\n */\nexport interface FetchSSETransportOptions {\n /** Retry configuration */\n retryConfig?: RetryConfig;\n /** Enable debug logging */\n debug?: boolean;\n /** Custom logger */\n logger?: TransportLogger;\n /** Custom fetch implementation (useful for React Native) */\n customFetch?: typeof fetch;\n}\n\n/**\n * Create a fetch-based SSE transport for React Native and polyfill environments\n */\nexport function createFetchSSETransport(options: FetchSSETransportOptions = {}): ChatTransport {\n const {\n retryConfig = DEFAULT_RETRY_CONFIG,\n debug = false,\n logger = createLogger(debug),\n customFetch = fetch,\n } = options;\n\n // Internal state\n let abortController: AbortController | undefined;\n let config: TransportConfig | undefined;\n let state: TransportState = \"disconnected\";\n let error: TransportError | undefined;\n let retryCount = 0;\n let reconnectTimeout: ReturnType<typeof setTimeout> | undefined;\n let intentionalDisconnect = false;\n\n // Metrics\n const metrics: ConnectionMetrics = {\n latency: 0,\n messagesSent: 0,\n messagesReceived: 0,\n messagesQueued: 0,\n reconnectCount: 0,\n transportType: \"sse-fetch\",\n };\n\n // Event handlers\n const globalHandlers = new Set<EventHandler>();\n const typeHandlers = new Map<string, Set<EventHandler>>();\n\n // Helper to emit events\n function emit(event: ChatEvent): void {\n metrics.messagesReceived++;\n metrics.lastMessageAt = Date.now();\n\n globalHandlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n logger.error(\"Error in message handler:\", err);\n }\n });\n\n const handlers = typeHandlers.get(event.type);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n logger.error(`Error in ${event.type} handler:`, err);\n }\n });\n }\n }\n\n // REST API helper\n async function sendRest(endpoint: string, body: Record<string, unknown>): Promise<unknown> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n const url = `${config.baseUrl}/${endpoint}`;\n logger.debug(`POST ${endpoint}`, body);\n\n const response = await customFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`API error: ${response.status} - ${errorText}`);\n }\n\n return response.json();\n }\n\n // Parse SSE data from a text chunk\n function parseSSEChunk(chunk: string): ChatEvent[] {\n const events: ChatEvent[] = [];\n const lines = chunk.split(\"\\n\");\n\n let eventType = \"message\";\n let data = \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"event:\")) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith(\"data:\")) {\n data = line.slice(5).trim();\n } else if (line === \"\" && data) {\n // End of event\n try {\n const parsed = JSON.parse(data) as ChatEvent;\n events.push(parsed);\n } catch {\n logger.warn(\"Failed to parse SSE data:\", data);\n }\n eventType = \"message\";\n data = \"\";\n }\n }\n\n return events;\n }\n\n // Start SSE stream using fetch\n async function startStream(cfg: TransportConfig): Promise<void> {\n const url = `${cfg.baseUrl}/stream?orgId=${cfg.orgId}&userId=${cfg.userId}&clientType=${cfg.clientType}${cfg.chatKey ? `&chatId=${cfg.chatKey}` : \"\"}`;\n\n logger.debug(\"Connecting to:\", url);\n\n abortController = new AbortController();\n\n const response = await customFetch(url, {\n method: \"GET\",\n headers: {\n Accept: \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n },\n signal: abortController.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Stream connection failed: ${response.status}`);\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null - ReadableStream not supported\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n // Read stream in background\n const readStream = async () => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n logger.info(\"Stream ended\");\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete events in buffer\n const lastNewline = buffer.lastIndexOf(\"\\n\\n\");\n if (lastNewline !== -1) {\n const complete = buffer.slice(0, lastNewline + 2);\n buffer = buffer.slice(lastNewline + 2);\n\n const events = parseSSEChunk(complete);\n events.forEach(emit);\n }\n }\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n logger.debug(\"Stream aborted\");\n return;\n }\n logger.error(\"Stream error:\", err);\n throw err;\n }\n\n // Stream closed - handle reconnection\n if (!intentionalDisconnect) {\n state = \"disconnected\";\n scheduleReconnect();\n }\n };\n\n // Start reading in background\n readStream().catch((err) => {\n if (!intentionalDisconnect) {\n error = {\n code: \"CONNECTION_FAILED\",\n message: err.message,\n retryable: true,\n timestamp: Date.now(),\n originalError: err,\n };\n metrics.lastError = error;\n state = \"disconnected\";\n scheduleReconnect();\n }\n });\n }\n\n // Schedule reconnect\n function scheduleReconnect(): void {\n if (intentionalDisconnect || !config) return;\n\n const maxRetries = retryConfig.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries;\n if (retryCount >= maxRetries) {\n logger.error(`Max retries (${maxRetries}) exceeded`);\n error = {\n code: \"CONNECTION_FAILED\",\n message: `Max retries (${maxRetries}) exceeded`,\n retryable: false,\n timestamp: Date.now(),\n };\n return;\n }\n\n const interval = calculateRetryInterval(retryCount, retryConfig);\n retryCount++;\n metrics.reconnectCount++;\n\n logger.info(`Reconnecting in ${interval}ms (attempt ${retryCount})`);\n state = \"reconnecting\";\n\n reconnectTimeout = setTimeout(() => {\n if (config) {\n transport.connect(config).catch((err) => {\n logger.error(\"Reconnect failed:\", err);\n });\n }\n }, interval);\n }\n\n const transport: ChatTransport = {\n async connect(cfg: TransportConfig): Promise<void> {\n config = cfg;\n intentionalDisconnect = false;\n\n // Clean up existing connection\n if (abortController) {\n abortController.abort();\n abortController = undefined;\n }\n if (reconnectTimeout) {\n clearTimeout(reconnectTimeout);\n reconnectTimeout = undefined;\n }\n\n state = retryCount > 0 ? \"reconnecting\" : \"connecting\";\n const connectionStart = Date.now();\n\n try {\n await startStream(cfg);\n\n const connectionTime = Date.now() - connectionStart;\n logger.info(`Connected in ${connectionTime}ms`);\n\n state = \"connected\";\n error = undefined;\n retryCount = 0;\n metrics.connectedAt = Date.now();\n metrics.latency = connectionTime;\n } catch (err) {\n const connectError: TransportError = {\n code: \"CONNECTION_FAILED\",\n message: (err as Error).message,\n retryable: true,\n timestamp: Date.now(),\n originalError: err,\n };\n error = connectError;\n metrics.lastError = connectError;\n state = \"disconnected\";\n\n if (!intentionalDisconnect) {\n scheduleReconnect();\n }\n\n throw connectError;\n }\n },\n\n disconnect(intentional = true): void {\n logger.info(\"Disconnecting\", { intentional });\n intentionalDisconnect = intentional;\n\n if (reconnectTimeout) {\n clearTimeout(reconnectTimeout);\n reconnectTimeout = undefined;\n }\n\n if (abortController) {\n abortController.abort();\n abortController = undefined;\n }\n\n state = \"disconnected\";\n retryCount = 0;\n },\n\n async send(event: ChatEvent): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n switch (event.type) {\n case \"message\":\n await sendRest(\"send\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n message: event.message,\n });\n break;\n\n case \"typing\":\n await sendRest(\"typing\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n typing: true,\n });\n break;\n\n case \"stopped_typing\":\n await sendRest(\"typing\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n typing: false,\n });\n break;\n\n case \"load_chat\":\n await sendRest(\"load\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n });\n break;\n\n case \"new_chat\":\n await sendRest(\"create\", {\n orgId: event.orgId,\n userId: event.userId,\n metadata: event.data,\n });\n break;\n\n case \"end_chat\":\n await sendRest(\"end\", {\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n data: event.data,\n });\n break;\n\n default:\n await sendRest(\"event\", {\n type: event.type,\n orgId: event.orgId,\n chatKey: event.chatKey,\n userId: event.userId,\n data: event.data,\n });\n }\n\n metrics.messagesSent++;\n },\n\n async sendMessage(message: ChatMessage): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n await sendRest(\"send\", {\n orgId: config.orgId,\n chatKey: config.chatKey,\n userId: config.userId,\n message,\n });\n\n metrics.messagesSent++;\n },\n\n onMessage(handler: EventHandler): Unsubscribe {\n globalHandlers.add(handler);\n return () => globalHandlers.delete(handler);\n },\n\n on(eventType: string, handler: EventHandler): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler);\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n getState(): TransportState {\n return state;\n },\n\n getMetrics(): ConnectionMetrics {\n return { ...metrics };\n },\n\n getError(): TransportError | undefined {\n return error;\n },\n\n clearError(): void {\n error = undefined;\n },\n };\n\n return transport;\n}\n","/**\n * WhatsApp Business API Transport (Stub)\n *\n * This module provides the interface for integrating with WhatsApp Business API.\n * The implementation connects to a webhook receiver that bridges WhatsApp messages\n * to the chat system.\n *\n * ## Integration Architecture\n *\n * ```\n * WhatsApp User → WhatsApp Cloud API → Your Webhook → Chat Service → SSE to Admin\n * ↓\n * NATS Events\n * ```\n *\n * ## Setup Requirements\n *\n * 1. Register a WhatsApp Business Account\n * 2. Create a Meta Business App with WhatsApp integration\n * 3. Configure webhook URL pointing to your chat service\n * 4. Set up message templates for outbound messages\n *\n * ## Backend Integration\n *\n * Your backend should expose webhook endpoints that:\n * - Verify webhook (GET /webhook with hub.verify_token)\n * - Receive messages (POST /webhook with message payload)\n * - Map WhatsApp user IDs to chat users\n * - Create/load chats for new conversations\n *\n * @example Backend Webhook Handler (Go)\n * ```go\n * func HandleWhatsAppWebhook(w http.ResponseWriter, r *http.Request) {\n * if r.Method == \"GET\" {\n * // Webhook verification\n * verifyToken := r.URL.Query().Get(\"hub.verify_token\")\n * if verifyToken == os.Getenv(\"WHATSAPP_VERIFY_TOKEN\") {\n * w.Write([]byte(r.URL.Query().Get(\"hub.challenge\")))\n * return\n * }\n * http.Error(w, \"Invalid verify token\", 403)\n * return\n * }\n *\n * // Handle incoming message\n * var payload WhatsAppPayload\n * json.NewDecoder(r.Body).Decode(&payload)\n *\n * // Map to chat event and publish to NATS\n * chatEvent := mapWhatsAppToChatEvent(payload)\n * natsClient.Publish(\"chat.events\", chatEvent)\n * }\n * ```\n *\n * @see https://developers.facebook.com/docs/whatsapp/cloud-api\n */\n\nimport type {\n ChatTransport,\n TransportConfig,\n TransportState,\n TransportError,\n ConnectionMetrics,\n EventHandler,\n Unsubscribe,\n TransportLogger,\n} from \"./types\";\nimport type { ChatEvent, ChatMessage, Attachment, AttachmentTypeTS } from \"../models\";\nimport { createLogger } from \"./types\";\n\n/**\n * WhatsApp transport configuration\n */\nexport interface WhatsAppTransportConfig extends TransportConfig {\n /** WhatsApp Business API access token */\n accessToken: string;\n /** Phone number ID from Meta Business */\n phoneNumberId: string;\n /** Webhook verify token for setup */\n verifyToken?: string;\n}\n\n/**\n * WhatsApp transport options\n */\nexport interface WhatsAppTransportOptions {\n /** Enable debug logging */\n debug?: boolean;\n /** Custom logger */\n logger?: TransportLogger;\n}\n\n/**\n * WhatsApp message types\n */\nexport type WhatsAppMessageType =\n | \"text\"\n | \"image\"\n | \"document\"\n | \"audio\"\n | \"video\"\n | \"sticker\"\n | \"location\"\n | \"contacts\"\n | \"interactive\"\n | \"template\";\n\n/**\n * Create a WhatsApp Business API transport\n *\n * NOTE: This is a stub implementation. The actual WhatsApp integration\n * happens on the backend via webhooks. This transport is for:\n * - Type definitions\n * - Documentation\n * - Future client-side WhatsApp Web integration\n */\nexport function createWhatsAppTransport(\n options: WhatsAppTransportOptions = {}\n): ChatTransport {\n const { debug = false, logger = createLogger(debug) } = options;\n\n let state: TransportState = \"disconnected\";\n let error: TransportError | undefined;\n let config: WhatsAppTransportConfig | undefined;\n\n const metrics: ConnectionMetrics = {\n latency: 0,\n messagesSent: 0,\n messagesReceived: 0,\n messagesQueued: 0,\n reconnectCount: 0,\n transportType: \"whatsapp\",\n };\n\n const globalHandlers = new Set<EventHandler>();\n const typeHandlers = new Map<string, Set<EventHandler>>();\n\n const transport: ChatTransport = {\n async connect(cfg: TransportConfig): Promise<void> {\n logger.warn(\n \"WhatsApp transport is a stub. WhatsApp integration happens via backend webhooks.\"\n );\n logger.info(\n \"See transport/whatsapp.ts for integration documentation.\"\n );\n\n config = cfg as WhatsAppTransportConfig;\n\n // In a real implementation, this would:\n // 1. Validate WhatsApp Business API credentials\n // 2. Register webhook endpoints\n // 3. Set up SSE connection to receive webhook-relayed events\n\n state = \"connected\";\n metrics.connectedAt = Date.now();\n },\n\n disconnect(): void {\n state = \"disconnected\";\n },\n\n async send(event: ChatEvent): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n logger.warn(\"WhatsApp send is a stub. Implement backend webhook relay.\");\n\n // In a real implementation, this would:\n // 1. Convert ChatEvent to WhatsApp message format\n // 2. Call WhatsApp Cloud API to send message\n // 3. Handle delivery receipts\n\n metrics.messagesSent++;\n },\n\n async sendMessage(message: ChatMessage): Promise<void> {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n logger.warn(\n \"WhatsApp sendMessage is a stub. Implement backend webhook relay.\"\n );\n\n // In a real implementation:\n // POST https://graph.facebook.com/v17.0/{phone_number_id}/messages\n // {\n // \"messaging_product\": \"whatsapp\",\n // \"to\": \"{recipient_phone}\",\n // \"type\": \"text\",\n // \"text\": { \"body\": message.content }\n // }\n\n metrics.messagesSent++;\n },\n\n onMessage(handler: EventHandler): Unsubscribe {\n globalHandlers.add(handler);\n return () => globalHandlers.delete(handler);\n },\n\n on(eventType: string, handler: EventHandler): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler);\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n getState(): TransportState {\n return state;\n },\n\n getMetrics(): ConnectionMetrics {\n return { ...metrics };\n },\n\n getError(): TransportError | undefined {\n return error;\n },\n\n clearError(): void {\n error = undefined;\n },\n };\n\n return transport;\n}\n\n/**\n * Helper: Convert WhatsApp webhook payload to ChatEvent\n *\n * Use this in your backend webhook handler to map incoming\n * WhatsApp messages to the chat system format.\n */\nexport interface WhatsAppWebhookPayload {\n object: \"whatsapp_business_account\";\n entry: Array<{\n id: string;\n changes: Array<{\n value: {\n messaging_product: \"whatsapp\";\n metadata: {\n display_phone_number: string;\n phone_number_id: string;\n };\n contacts?: Array<{\n profile: { name: string };\n wa_id: string;\n }>;\n messages?: Array<{\n from: string;\n id: string;\n timestamp: string;\n type: WhatsAppMessageType;\n text?: { body: string };\n image?: { id: string; mime_type: string; sha256: string };\n document?: { id: string; mime_type: string; filename: string };\n audio?: { id: string; mime_type: string };\n video?: { id: string; mime_type: string };\n location?: { latitude: number; longitude: number; name?: string };\n }>;\n statuses?: Array<{\n id: string;\n status: \"sent\" | \"delivered\" | \"read\" | \"failed\";\n timestamp: string;\n recipient_id: string;\n }>;\n };\n }>;\n }>;\n}\n\n/**\n * Example: Map WhatsApp payload to ChatEvent (for backend use)\n *\n * @example\n * ```typescript\n * // In your backend webhook handler\n * import { mapWhatsAppToChatEvent } from \"@elqnt/chat/transport\";\n *\n * app.post(\"/webhook/whatsapp\", (req, res) => {\n * const events = mapWhatsAppToChatEvent(req.body, orgId);\n * events.forEach(event => publishToChatService(event));\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function mapWhatsAppToChatEvent(\n payload: WhatsAppWebhookPayload,\n orgId: string\n): ChatEvent[] {\n const events: ChatEvent[] = [];\n\n for (const entry of payload.entry) {\n for (const change of entry.changes) {\n const value = change.value;\n\n // Handle incoming messages\n if (value.messages) {\n for (const msg of value.messages) {\n const contact = value.contacts?.find((c) => c.wa_id === msg.from);\n\n events.push({\n type: \"message\",\n orgId,\n chatKey: `wa_${msg.from}`, // Use phone number as chat key\n userId: msg.from,\n timestamp: parseInt(msg.timestamp) * 1000,\n message: {\n id: msg.id,\n role: \"user\",\n content: msg.text?.body || \"\",\n time: parseInt(msg.timestamp) * 1000,\n status: \"delivered\",\n senderId: msg.from,\n senderName: contact?.profile.name,\n createdAt: parseInt(msg.timestamp) * 1000,\n // Map attachments if present\n attachments: mapWhatsAppAttachments(msg),\n },\n });\n }\n }\n\n // Handle message status updates\n if (value.statuses) {\n for (const status of value.statuses) {\n events.push({\n type: \"message_status_update\",\n orgId,\n chatKey: `wa_${status.recipient_id}`,\n userId: status.recipient_id,\n timestamp: parseInt(status.timestamp) * 1000,\n data: {\n messageId: status.id,\n status: status.status,\n },\n });\n }\n }\n }\n }\n\n return events;\n}\n\n// Helper to map WhatsApp attachments\nfunction mapWhatsAppAttachments(msg: {\n type: WhatsAppMessageType;\n image?: { id: string };\n document?: { id: string; filename: string };\n audio?: { id: string };\n video?: { id: string };\n location?: { latitude: number; longitude: number; name?: string };\n}): Attachment[] | undefined {\n switch (msg.type) {\n case \"image\":\n return msg.image\n ? [{ type: \"image\" as AttachmentTypeTS, url: `whatsapp://media/${msg.image.id}` }]\n : undefined;\n case \"document\":\n return msg.document\n ? [\n {\n type: \"document\" as AttachmentTypeTS,\n url: `whatsapp://media/${msg.document.id}`,\n },\n ]\n : undefined;\n case \"audio\":\n return msg.audio\n ? [{ type: \"audio\" as AttachmentTypeTS, url: `whatsapp://media/${msg.audio.id}` }]\n : undefined;\n case \"video\":\n return msg.video\n ? [{ type: \"video\" as AttachmentTypeTS, url: `whatsapp://media/${msg.video.id}` }]\n : undefined;\n case \"location\":\n return msg.location\n ? [\n {\n type: \"location\" as AttachmentTypeTS,\n url: `geo:${msg.location.latitude},${msg.location.longitude}`,\n },\n ]\n : undefined;\n default:\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACkPO,SAAS,aAAa,QAAiB,OAAwB;AACpE,SAAO;AAAA,IACL,OAAO,QAAQ,QAAQ,IAAI,KAAK,SAAS,QAAQ,IAAI,MAAM;AAAA,IAAC;AAAA,IAC5D,MAAM,QAAQ,KAAK,KAAK,SAAS,QAAQ;AAAA,IACzC,MAAM,QAAQ,KAAK,KAAK,SAAS,QAAQ;AAAA,IACzC,OAAO,QAAQ,MAAM,KAAK,SAAS,QAAQ;AAAA,EAC7C;AACF;AAKO,IAAM,uBAA8C;AAAA,EACzD,YAAY;AAAA,EACZ,WAAW,CAAC,KAAM,KAAM,GAAI;AAAA,EAC5B,mBAAmB;AAAA,EACnB,gBAAgB;AAClB;AAOO,SAAS,uBACd,YACA,SAAsB,sBACd;AACR,QAAM;AAAA,IACJ,YAAY,qBAAqB;AAAA,IACjC,oBAAoB,qBAAqB;AAAA,IACzC,iBAAiB,qBAAqB;AAAA,EACxC,IAAI;AAEJ,MAAI,aAAa,UAAU,QAAQ;AACjC,WAAO,UAAU,UAAU;AAAA,EAC7B;AAEA,QAAM,eAAe,UAAU,UAAU,SAAS,CAAC,KAAK;AACxD,QAAM,cACJ,eAAe,KAAK,IAAI,mBAAmB,aAAa,UAAU,SAAS,CAAC;AAC9E,SAAO,KAAK,IAAI,aAAa,cAAc;AAC7C;;;AChPO,SAAS,mBAAmB,UAA+B,CAAC,GAAkB;AACnF,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,SAAS,aAAa,KAAK;AAAA,EAC7B,IAAI;AAGJ,MAAI;AACJ,MAAI;AACJ,MAAI,QAAwB;AAC5B,MAAI;AACJ,MAAI,aAAa;AACjB,MAAI;AACJ,MAAI,wBAAwB;AAG5B,QAAM,UAA6B;AAAA,IACjC,SAAS;AAAA,IACT,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAGA,QAAM,iBAAiB,oBAAI,IAAkB;AAC7C,QAAM,eAAe,oBAAI,IAA+B;AAGxD,WAAS,KAAK,OAAwB;AAEpC,YAAQ;AACR,YAAQ,gBAAgB,KAAK,IAAI;AAGjC,mBAAe,QAAQ,CAAC,YAAY;AAClC,UAAI;AACF,gBAAQ,KAAK;AAAA,MACf,SAAS,KAAK;AACZ,eAAO,MAAM,6BAA6B,GAAG;AAAA,MAC/C;AAAA,IACF,CAAC;AAGD,UAAM,WAAW,aAAa,IAAI,MAAM,IAAI;AAC5C,QAAI,UAAU;AACZ,eAAS,QAAQ,CAAC,YAAY;AAC5B,YAAI;AACF,kBAAQ,KAAK;AAAA,QACf,SAAS,KAAK;AACZ,iBAAO,MAAM,YAAY,MAAM,IAAI,aAAa,GAAG;AAAA,QACrD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAGA,iBAAe,SAAS,UAAkB,MAAiD;AACzF,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAEA,UAAM,MAAM,GAAG,OAAO,OAAO,IAAI,QAAQ;AACzC,WAAO,MAAM,QAAQ,QAAQ,IAAI,IAAI;AAErC,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,YAAM,IAAI,MAAM,cAAc,SAAS,MAAM,MAAM,SAAS,EAAE;AAAA,IAChE;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAGA,WAAS,cAAc,OAA2B;AAChD,QAAI,CAAC,MAAM,QAAQ,MAAM,SAAS,GAAI;AAEtC,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAClC,aAAO,MAAM,aAAa,KAAK,IAAI;AACnC,WAAK,IAAI;AAAA,IACX,SAAS,KAAK;AACZ,aAAO,MAAM,gCAAgC,GAAG;AAAA,IAClD;AAAA,EACF;AAGA,WAAS,oBAAoB,IAAuB;AAElD,OAAG,iBAAiB,WAAW,aAAa;AAG5C,UAAM,aAAa;AAAA,MACjB;AAAA,MAAe;AAAA,MAAU;AAAA,MAAkB;AAAA,MAC3C;AAAA,MAAqB;AAAA,MAAsB;AAAA,MAC3C;AAAA,MAAc;AAAA,MAAgB;AAAA,MAC9B;AAAA,MAAoB;AAAA,MAAoB;AAAA,MACxC;AAAA,MAA0B;AAAA,MAC1B;AAAA,MAAyB;AAAA,MACzB;AAAA,MAAyB;AAAA,MAAgB;AAAA,MACzC;AAAA,MAAe;AAAA,MAAkB;AAAA,MAAkB;AAAA,IACrD;AAEA,eAAW,QAAQ,CAAC,SAAS;AAC3B,SAAG,iBAAiB,MAAM,aAAa;AAAA,IACzC,CAAC;AAAA,EACH;AAGA,WAAS,oBAA0B;AACjC,QAAI,yBAAyB,CAAC,OAAQ;AAEtC,UAAM,aAAa,YAAY,cAAc,qBAAqB;AAClE,QAAI,cAAc,YAAY;AAC5B,aAAO,MAAM,gBAAgB,UAAU,YAAY;AACnD,cAAQ;AAAA,QACN,MAAM;AAAA,QACN,SAAS,gBAAgB,UAAU;AAAA,QACnC,WAAW;AAAA,QACX,WAAW,KAAK,IAAI;AAAA,MACtB;AACA;AAAA,IACF;AAEA,UAAM,WAAW,uBAAuB,YAAY,WAAW;AAC/D;AACA,YAAQ;AAER,WAAO,KAAK,mBAAmB,QAAQ,eAAe,UAAU,GAAG;AACnE,YAAQ;AAER,uBAAmB,WAAW,MAAM;AAClC,UAAI,QAAQ;AACV,kBAAU,QAAQ,MAAM,EAAE,MAAM,CAAC,QAAQ;AACvC,iBAAO,MAAM,qBAAqB,GAAG;AAAA,QACvC,CAAC;AAAA,MACH;AAAA,IACF,GAAG,QAAQ;AAAA,EACb;AAEA,QAAM,YAA2B;AAAA,IAC/B,MAAM,QAAQ,KAAqC;AACjD,eAAS;AACT,8BAAwB;AAGxB,UAAI,aAAa;AACf,oBAAY,MAAM;AAClB,sBAAc;AAAA,MAChB;AACA,UAAI,kBAAkB;AACpB,qBAAa,gBAAgB;AAC7B,2BAAmB;AAAA,MACrB;AAEA,cAAQ,aAAa,IAAI,iBAAiB;AAE1C,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,kBAAkB,KAAK,IAAI;AACjC,cAAM,MAAM,GAAG,IAAI,OAAO,iBAAiB,IAAI,KAAK,WAAW,IAAI,MAAM,eAAe,IAAI,UAAU,GAAG,IAAI,UAAU,WAAW,IAAI,OAAO,KAAK,EAAE;AAEpJ,eAAO,MAAM,kBAAkB,GAAG;AAClC,cAAM,KAAK,IAAI,YAAY,GAAG;AAE9B,WAAG,SAAS,MAAM;AAChB,gBAAM,iBAAiB,KAAK,IAAI,IAAI;AACpC,iBAAO,KAAK,gBAAgB,cAAc,IAAI;AAE9C,kBAAQ;AACR,kBAAQ;AACR,uBAAa;AACb,kBAAQ,cAAc,KAAK,IAAI;AAC/B,kBAAQ,UAAU;AAElB,8BAAoB,EAAE;AACtB,kBAAQ;AAAA,QACV;AAEA,WAAG,UAAU,MAAM;AACjB,cAAI,GAAG,eAAe,YAAY,QAAQ;AACxC,kBAAM,WAA2B;AAAA,cAC/B,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,cACX,WAAW,KAAK,IAAI;AAAA,YACtB;AACA,oBAAQ;AACR,oBAAQ,YAAY;AACpB,oBAAQ;AAER,gBAAI,CAAC,uBAAuB;AAC1B,gCAAkB;AAAA,YACpB;AAGA,gBAAI,eAAe,GAAG;AACpB,qBAAO,QAAQ;AAAA,YACjB;AAAA,UACF;AAAA,QACF;AAEA,sBAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IAEA,WAAW,cAAc,MAAY;AACnC,aAAO,KAAK,iBAAiB,EAAE,YAAY,CAAC;AAC5C,8BAAwB;AAExB,UAAI,kBAAkB;AACpB,qBAAa,gBAAgB;AAC7B,2BAAmB;AAAA,MACrB;AAEA,UAAI,aAAa;AACf,oBAAY,MAAM;AAClB,sBAAc;AAAA,MAChB;AAEA,cAAQ;AACR,mBAAa;AAAA,IACf;AAAA,IAEA,MAAM,KAAK,OAAiC;AAC1C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAGA,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AACH,gBAAM,SAAS,QAAQ;AAAA,YACrB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,SAAS,MAAM;AAAA,UACjB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,UAAU;AAAA,YACvB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,QAAQ;AAAA,UACV,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,UAAU;AAAA,YACvB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,QAAQ;AAAA,UACV,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,QAAQ;AAAA,YACrB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,UAChB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,UAAU;AAAA,YACvB,OAAO,MAAM;AAAA,YACb,QAAQ,MAAM;AAAA,YACd,UAAU,MAAM;AAAA,UAClB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,OAAO;AAAA,YACpB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,MAAM,MAAM;AAAA,UACd,CAAC;AACD;AAAA,QAEF;AAEE,gBAAM,SAAS,SAAS;AAAA,YACtB,MAAM,MAAM;AAAA,YACZ,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,MAAM,MAAM;AAAA,UACd,CAAC;AAAA,MACL;AAEA,cAAQ;AAAA,IACV;AAAA,IAEA,MAAM,YAAY,SAAqC;AACrD,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAEA,YAAM,SAAS,QAAQ;AAAA,QACrB,OAAO,OAAO;AAAA,QACd,SAAS,OAAO;AAAA,QAChB,QAAQ,OAAO;AAAA,QACf;AAAA,MACF,CAAC;AAED,cAAQ;AAAA,IACV;AAAA,IAEA,UAAU,SAAoC;AAC5C,qBAAe,IAAI,OAAO;AAC1B,aAAO,MAAM,eAAe,OAAO,OAAO;AAAA,IAC5C;AAAA,IAEA,GAAG,WAAmB,SAAoC;AACxD,UAAI,CAAC,aAAa,IAAI,SAAS,GAAG;AAChC,qBAAa,IAAI,WAAW,oBAAI,IAAI,CAAC;AAAA,MACvC;AACA,mBAAa,IAAI,SAAS,EAAG,IAAI,OAAO;AACxC,aAAO,MAAM;AACX,cAAM,WAAW,aAAa,IAAI,SAAS;AAC3C,YAAI,UAAU;AACZ,mBAAS,OAAO,OAAO;AACvB,cAAI,SAAS,SAAS,GAAG;AACvB,yBAAa,OAAO,SAAS;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,WAA2B;AACzB,aAAO;AAAA,IACT;AAAA,IAEA,aAAgC;AAC9B,aAAO,EAAE,GAAG,QAAQ;AAAA,IACtB;AAAA,IAEA,WAAuC;AACrC,aAAO;AAAA,IACT;AAAA,IAEA,aAAmB;AACjB,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;;;ACpWO,SAAS,wBAAwB,UAAoC,CAAC,GAAkB;AAC7F,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,SAAS,aAAa,KAAK;AAAA,IAC3B,cAAc;AAAA,EAChB,IAAI;AAGJ,MAAI;AACJ,MAAI;AACJ,MAAI,QAAwB;AAC5B,MAAI;AACJ,MAAI,aAAa;AACjB,MAAI;AACJ,MAAI,wBAAwB;AAG5B,QAAM,UAA6B;AAAA,IACjC,SAAS;AAAA,IACT,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAGA,QAAM,iBAAiB,oBAAI,IAAkB;AAC7C,QAAM,eAAe,oBAAI,IAA+B;AAGxD,WAAS,KAAK,OAAwB;AACpC,YAAQ;AACR,YAAQ,gBAAgB,KAAK,IAAI;AAEjC,mBAAe,QAAQ,CAAC,YAAY;AAClC,UAAI;AACF,gBAAQ,KAAK;AAAA,MACf,SAAS,KAAK;AACZ,eAAO,MAAM,6BAA6B,GAAG;AAAA,MAC/C;AAAA,IACF,CAAC;AAED,UAAM,WAAW,aAAa,IAAI,MAAM,IAAI;AAC5C,QAAI,UAAU;AACZ,eAAS,QAAQ,CAAC,YAAY;AAC5B,YAAI;AACF,kBAAQ,KAAK;AAAA,QACf,SAAS,KAAK;AACZ,iBAAO,MAAM,YAAY,MAAM,IAAI,aAAa,GAAG;AAAA,QACrD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAGA,iBAAe,SAAS,UAAkB,MAAiD;AACzF,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAEA,UAAM,MAAM,GAAG,OAAO,OAAO,IAAI,QAAQ;AACzC,WAAO,MAAM,QAAQ,QAAQ,IAAI,IAAI;AAErC,UAAM,WAAW,MAAM,YAAY,KAAK;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,YAAM,IAAI,MAAM,cAAc,SAAS,MAAM,MAAM,SAAS,EAAE;AAAA,IAChE;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAGA,WAAS,cAAc,OAA4B;AACjD,UAAM,SAAsB,CAAC;AAC7B,UAAM,QAAQ,MAAM,MAAM,IAAI;AAE9B,QAAI,YAAY;AAChB,QAAI,OAAO;AAEX,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,oBAAY,KAAK,MAAM,CAAC,EAAE,KAAK;AAAA,MACjC,WAAW,KAAK,WAAW,OAAO,GAAG;AACnC,eAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAAA,MAC5B,WAAW,SAAS,MAAM,MAAM;AAE9B,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,iBAAO,KAAK,MAAM;AAAA,QACpB,QAAQ;AACN,iBAAO,KAAK,6BAA6B,IAAI;AAAA,QAC/C;AACA,oBAAY;AACZ,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAGA,iBAAe,YAAY,KAAqC;AAC9D,UAAM,MAAM,GAAG,IAAI,OAAO,iBAAiB,IAAI,KAAK,WAAW,IAAI,MAAM,eAAe,IAAI,UAAU,GAAG,IAAI,UAAU,WAAW,IAAI,OAAO,KAAK,EAAE;AAEpJ,WAAO,MAAM,kBAAkB,GAAG;AAElC,sBAAkB,IAAI,gBAAgB;AAEtC,UAAM,WAAW,MAAM,YAAY,KAAK;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,iBAAiB;AAAA,MACnB;AAAA,MACA,QAAQ,gBAAgB;AAAA,IAC1B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,EAAE;AAAA,IAChE;AAEA,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAEA,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AAGb,UAAM,aAAa,YAAY;AAC7B,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAE1C,cAAI,MAAM;AACR,mBAAO,KAAK,cAAc;AAC1B;AAAA,UACF;AAEA,oBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAGhD,gBAAM,cAAc,OAAO,YAAY,MAAM;AAC7C,cAAI,gBAAgB,IAAI;AACtB,kBAAM,WAAW,OAAO,MAAM,GAAG,cAAc,CAAC;AAChD,qBAAS,OAAO,MAAM,cAAc,CAAC;AAErC,kBAAM,SAAS,cAAc,QAAQ;AACrC,mBAAO,QAAQ,IAAI;AAAA,UACrB;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,YAAK,IAAc,SAAS,cAAc;AACxC,iBAAO,MAAM,gBAAgB;AAC7B;AAAA,QACF;AACA,eAAO,MAAM,iBAAiB,GAAG;AACjC,cAAM;AAAA,MACR;AAGA,UAAI,CAAC,uBAAuB;AAC1B,gBAAQ;AACR,0BAAkB;AAAA,MACpB;AAAA,IACF;AAGA,eAAW,EAAE,MAAM,CAAC,QAAQ;AAC1B,UAAI,CAAC,uBAAuB;AAC1B,gBAAQ;AAAA,UACN,MAAM;AAAA,UACN,SAAS,IAAI;AAAA,UACb,WAAW;AAAA,UACX,WAAW,KAAK,IAAI;AAAA,UACpB,eAAe;AAAA,QACjB;AACA,gBAAQ,YAAY;AACpB,gBAAQ;AACR,0BAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAGA,WAAS,oBAA0B;AACjC,QAAI,yBAAyB,CAAC,OAAQ;AAEtC,UAAM,aAAa,YAAY,cAAc,qBAAqB;AAClE,QAAI,cAAc,YAAY;AAC5B,aAAO,MAAM,gBAAgB,UAAU,YAAY;AACnD,cAAQ;AAAA,QACN,MAAM;AAAA,QACN,SAAS,gBAAgB,UAAU;AAAA,QACnC,WAAW;AAAA,QACX,WAAW,KAAK,IAAI;AAAA,MACtB;AACA;AAAA,IACF;AAEA,UAAM,WAAW,uBAAuB,YAAY,WAAW;AAC/D;AACA,YAAQ;AAER,WAAO,KAAK,mBAAmB,QAAQ,eAAe,UAAU,GAAG;AACnE,YAAQ;AAER,uBAAmB,WAAW,MAAM;AAClC,UAAI,QAAQ;AACV,kBAAU,QAAQ,MAAM,EAAE,MAAM,CAAC,QAAQ;AACvC,iBAAO,MAAM,qBAAqB,GAAG;AAAA,QACvC,CAAC;AAAA,MACH;AAAA,IACF,GAAG,QAAQ;AAAA,EACb;AAEA,QAAM,YAA2B;AAAA,IAC/B,MAAM,QAAQ,KAAqC;AACjD,eAAS;AACT,8BAAwB;AAGxB,UAAI,iBAAiB;AACnB,wBAAgB,MAAM;AACtB,0BAAkB;AAAA,MACpB;AACA,UAAI,kBAAkB;AACpB,qBAAa,gBAAgB;AAC7B,2BAAmB;AAAA,MACrB;AAEA,cAAQ,aAAa,IAAI,iBAAiB;AAC1C,YAAM,kBAAkB,KAAK,IAAI;AAEjC,UAAI;AACF,cAAM,YAAY,GAAG;AAErB,cAAM,iBAAiB,KAAK,IAAI,IAAI;AACpC,eAAO,KAAK,gBAAgB,cAAc,IAAI;AAE9C,gBAAQ;AACR,gBAAQ;AACR,qBAAa;AACb,gBAAQ,cAAc,KAAK,IAAI;AAC/B,gBAAQ,UAAU;AAAA,MACpB,SAAS,KAAK;AACZ,cAAM,eAA+B;AAAA,UACnC,MAAM;AAAA,UACN,SAAU,IAAc;AAAA,UACxB,WAAW;AAAA,UACX,WAAW,KAAK,IAAI;AAAA,UACpB,eAAe;AAAA,QACjB;AACA,gBAAQ;AACR,gBAAQ,YAAY;AACpB,gBAAQ;AAER,YAAI,CAAC,uBAAuB;AAC1B,4BAAkB;AAAA,QACpB;AAEA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,WAAW,cAAc,MAAY;AACnC,aAAO,KAAK,iBAAiB,EAAE,YAAY,CAAC;AAC5C,8BAAwB;AAExB,UAAI,kBAAkB;AACpB,qBAAa,gBAAgB;AAC7B,2BAAmB;AAAA,MACrB;AAEA,UAAI,iBAAiB;AACnB,wBAAgB,MAAM;AACtB,0BAAkB;AAAA,MACpB;AAEA,cAAQ;AACR,mBAAa;AAAA,IACf;AAAA,IAEA,MAAM,KAAK,OAAiC;AAC1C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAEA,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AACH,gBAAM,SAAS,QAAQ;AAAA,YACrB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,SAAS,MAAM;AAAA,UACjB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,UAAU;AAAA,YACvB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,QAAQ;AAAA,UACV,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,UAAU;AAAA,YACvB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,QAAQ;AAAA,UACV,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,QAAQ;AAAA,YACrB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,UAChB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,UAAU;AAAA,YACvB,OAAO,MAAM;AAAA,YACb,QAAQ,MAAM;AAAA,YACd,UAAU,MAAM;AAAA,UAClB,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,SAAS,OAAO;AAAA,YACpB,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,MAAM,MAAM;AAAA,UACd,CAAC;AACD;AAAA,QAEF;AACE,gBAAM,SAAS,SAAS;AAAA,YACtB,MAAM,MAAM;AAAA,YACZ,OAAO,MAAM;AAAA,YACb,SAAS,MAAM;AAAA,YACf,QAAQ,MAAM;AAAA,YACd,MAAM,MAAM;AAAA,UACd,CAAC;AAAA,MACL;AAEA,cAAQ;AAAA,IACV;AAAA,IAEA,MAAM,YAAY,SAAqC;AACrD,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAEA,YAAM,SAAS,QAAQ;AAAA,QACrB,OAAO,OAAO;AAAA,QACd,SAAS,OAAO;AAAA,QAChB,QAAQ,OAAO;AAAA,QACf;AAAA,MACF,CAAC;AAED,cAAQ;AAAA,IACV;AAAA,IAEA,UAAU,SAAoC;AAC5C,qBAAe,IAAI,OAAO;AAC1B,aAAO,MAAM,eAAe,OAAO,OAAO;AAAA,IAC5C;AAAA,IAEA,GAAG,WAAmB,SAAoC;AACxD,UAAI,CAAC,aAAa,IAAI,SAAS,GAAG;AAChC,qBAAa,IAAI,WAAW,oBAAI,IAAI,CAAC;AAAA,MACvC;AACA,mBAAa,IAAI,SAAS,EAAG,IAAI,OAAO;AACxC,aAAO,MAAM;AACX,cAAM,WAAW,aAAa,IAAI,SAAS;AAC3C,YAAI,UAAU;AACZ,mBAAS,OAAO,OAAO;AACvB,cAAI,SAAS,SAAS,GAAG;AACvB,yBAAa,OAAO,SAAS;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,WAA2B;AACzB,aAAO;AAAA,IACT;AAAA,IAEA,aAAgC;AAC9B,aAAO,EAAE,GAAG,QAAQ;AAAA,IACtB;AAAA,IAEA,WAAuC;AACrC,aAAO;AAAA,IACT;AAAA,IAEA,aAAmB;AACjB,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;;;AC3VO,SAAS,wBACd,UAAoC,CAAC,GACtB;AACf,QAAM,EAAE,QAAQ,OAAO,SAAS,aAAa,KAAK,EAAE,IAAI;AAExD,MAAI,QAAwB;AAC5B,MAAI;AACJ,MAAI;AAEJ,QAAM,UAA6B;AAAA,IACjC,SAAS;AAAA,IACT,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAEA,QAAM,iBAAiB,oBAAI,IAAkB;AAC7C,QAAM,eAAe,oBAAI,IAA+B;AAExD,QAAM,YAA2B;AAAA,IAC/B,MAAM,QAAQ,KAAqC;AACjD,aAAO;AAAA,QACL;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,MACF;AAEA,eAAS;AAOT,cAAQ;AACR,cAAQ,cAAc,KAAK,IAAI;AAAA,IACjC;AAAA,IAEA,aAAmB;AACjB,cAAQ;AAAA,IACV;AAAA,IAEA,MAAM,KAAK,OAAiC;AAC1C,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAEA,aAAO,KAAK,2DAA2D;AAOvE,cAAQ;AAAA,IACV;AAAA,IAEA,MAAM,YAAY,SAAqC;AACrD,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAEA,aAAO;AAAA,QACL;AAAA,MACF;AAWA,cAAQ;AAAA,IACV;AAAA,IAEA,UAAU,SAAoC;AAC5C,qBAAe,IAAI,OAAO;AAC1B,aAAO,MAAM,eAAe,OAAO,OAAO;AAAA,IAC5C;AAAA,IAEA,GAAG,WAAmB,SAAoC;AACxD,UAAI,CAAC,aAAa,IAAI,SAAS,GAAG;AAChC,qBAAa,IAAI,WAAW,oBAAI,IAAI,CAAC;AAAA,MACvC;AACA,mBAAa,IAAI,SAAS,EAAG,IAAI,OAAO;AACxC,aAAO,MAAM;AACX,cAAM,WAAW,aAAa,IAAI,SAAS;AAC3C,YAAI,UAAU;AACZ,mBAAS,OAAO,OAAO;AACvB,cAAI,SAAS,SAAS,GAAG;AACvB,yBAAa,OAAO,SAAS;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,WAA2B;AACzB,aAAO;AAAA,IACT;AAAA,IAEA,aAAgC;AAC9B,aAAO,EAAE,GAAG,QAAQ;AAAA,IACtB;AAAA,IAEA,WAAuC;AACrC,aAAO;AAAA,IACT;AAAA,IAEA,aAAmB;AACjB,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;AA6DO,SAAS,uBACd,SACA,OACa;AACb,QAAM,SAAsB,CAAC;AAE7B,aAAW,SAAS,QAAQ,OAAO;AACjC,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,QAAQ,OAAO;AAGrB,UAAI,MAAM,UAAU;AAClB,mBAAW,OAAO,MAAM,UAAU;AAChC,gBAAM,UAAU,MAAM,UAAU,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI,IAAI;AAEhE,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN;AAAA,YACA,SAAS,MAAM,IAAI,IAAI;AAAA;AAAA,YACvB,QAAQ,IAAI;AAAA,YACZ,WAAW,SAAS,IAAI,SAAS,IAAI;AAAA,YACrC,SAAS;AAAA,cACP,IAAI,IAAI;AAAA,cACR,MAAM;AAAA,cACN,SAAS,IAAI,MAAM,QAAQ;AAAA,cAC3B,MAAM,SAAS,IAAI,SAAS,IAAI;AAAA,cAChC,QAAQ;AAAA,cACR,UAAU,IAAI;AAAA,cACd,YAAY,SAAS,QAAQ;AAAA,cAC7B,WAAW,SAAS,IAAI,SAAS,IAAI;AAAA;AAAA,cAErC,aAAa,uBAAuB,GAAG;AAAA,YACzC;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAI,MAAM,UAAU;AAClB,mBAAW,UAAU,MAAM,UAAU;AACnC,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN;AAAA,YACA,SAAS,MAAM,OAAO,YAAY;AAAA,YAClC,QAAQ,OAAO;AAAA,YACf,WAAW,SAAS,OAAO,SAAS,IAAI;AAAA,YACxC,MAAM;AAAA,cACJ,WAAW,OAAO;AAAA,cAClB,QAAQ,OAAO;AAAA,YACjB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,uBAAuB,KAOH;AAC3B,UAAQ,IAAI,MAAM;AAAA,IAChB,KAAK;AACH,aAAO,IAAI,QACP,CAAC,EAAE,MAAM,SAA6B,KAAK,oBAAoB,IAAI,MAAM,EAAE,GAAG,CAAC,IAC/E;AAAA,IACN,KAAK;AACH,aAAO,IAAI,WACP;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,KAAK,oBAAoB,IAAI,SAAS,EAAE;AAAA,QAC1C;AAAA,MACF,IACA;AAAA,IACN,KAAK;AACH,aAAO,IAAI,QACP,CAAC,EAAE,MAAM,SAA6B,KAAK,oBAAoB,IAAI,MAAM,EAAE,GAAG,CAAC,IAC/E;AAAA,IACN,KAAK;AACH,aAAO,IAAI,QACP,CAAC,EAAE,MAAM,SAA6B,KAAK,oBAAoB,IAAI,MAAM,EAAE,GAAG,CAAC,IAC/E;AAAA,IACN,KAAK;AACH,aAAO,IAAI,WACP;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,KAAK,OAAO,IAAI,SAAS,QAAQ,IAAI,IAAI,SAAS,SAAS;AAAA,QAC7D;AAAA,MACF,IACA;AAAA,IACN;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
|