@aomi-labs/react 0.1.0 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/api/client.ts","../src/runtime/aomi-runtime.tsx","../src/runtime/hooks.ts","../src/runtime/orchestrator.ts","../src/state/thread-context.tsx","../src/state/thread-store.ts","../src/utils/conversion.ts","../src/runtime/utils.ts","../src/runtime/backend-state.ts","../src/runtime/message-controller.ts","../src/runtime/polling-controller.ts","../src/lib/notification-context.tsx","../src/utils/wallet.ts","../src/runtime/wallet-handler.ts","../src/runtime/event-controller.ts","../src/lib/utils.ts"],"sourcesContent":["export { BackendApi } from \"./api/client\";\nexport type {\n BackendSessionResponse,\n BackendThreadMetadata,\n CreateThreadResponse,\n SessionMessage,\n SessionResponsePayload,\n SystemResponsePayload,\n SystemUpdate,\n SystemUpdateNotification,\n SystemEvent,\n} from \"./api/types\";\n\nexport {\n AomiRuntimeProvider,\n AomiRuntimeProviderWithNotifications,\n} from \"./runtime/aomi-runtime\";\nexport type { AomiRuntimeProviderProps } from \"./runtime/aomi-runtime\";\nexport { useRuntimeActions, RuntimeActionsProvider } from \"./runtime/hooks\";\n\nexport {\n ThreadContextProvider,\n useThreadContext,\n useCurrentThreadMetadata,\n useCurrentThreadMessages,\n} from \"./state/thread-context\";\nexport type { ThreadMetadata, ThreadStatus } from \"./state/types\";\n\nexport {\n toInboundSystem as constructSystemMessage,\n toInboundMessage as constructThreadMessage,\n} from \"./utils/conversion\";\nexport {\n WalletSystemMessageEmitter,\n formatAddress,\n getNetworkName,\n normalizeWalletError,\n toHexQuantity,\n pickInjectedProvider,\n} from \"./utils/wallet\";\nexport type {\n WalletButtonState,\n WalletFooterProps,\n WalletTxRequestPayload,\n WalletTxRequestHandler,\n WalletTxRequestContext,\n Eip1193Provider,\n} from \"./utils/wallet\";\n\nexport { cn } from \"./lib/utils\";\n\n// Notification system (logic only)\nexport {\n NotificationProvider,\n useNotification,\n} from \"./lib/notification-context\";\nexport type {\n Notification,\n NotificationType,\n NotificationIconType,\n} from \"./lib/notification-context\";\n","import type {\n BackendSessionResponse,\n BackendThreadMetadata,\n CreateThreadResponse,\n SessionMessage,\n SessionResponsePayload,\n SystemEvent,\n SystemResponsePayload,\n SystemUpdateNotification,\n} from \"./types\";\n\nfunction toQueryString(payload: Record<string, unknown>): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(payload)) {\n if (value === undefined || value === null) continue;\n params.set(key, String(value));\n }\n const qs = params.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nasync function postState<T>(\n backendUrl: string,\n path: string,\n payload: Record<string, unknown>\n): Promise<T> {\n const query = toQueryString(payload);\n const url = `${backendUrl}${path}${query}`;\n console.log(\"🔵 [postState] URL:\", url);\n console.log(\"🔵 [postState] Payload:\", payload);\n\n const response = await fetch(url, {\n method: \"POST\",\n });\n console.log(\"🔵 [postState] Response status:\", response.status);\n\n if (!response.ok) {\n console.error(\"🔴 [postState] Error:\", response.status, response.statusText);\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const data = (await response.json()) as T;\n console.log(\"🟢 [postState] Success:\", data);\n return data;\n}\n\nexport class BackendApi {\n private connectionStatus = false;\n private eventSource: EventSource | null = null;\n private updatesEventSources = new Map<\n string,\n {\n eventSource: EventSource | null;\n retries: number;\n retryTimer: ReturnType<typeof setTimeout> | null;\n stopped: boolean;\n cleanup: () => void;\n }\n >();\n\n constructor(private readonly backendUrl: string) {}\n\n async fetchState(\n sessionId: string,\n options?: { signal?: AbortSignal }\n ): Promise<SessionResponsePayload> {\n console.log(\"🔵 [fetchState] Called with sessionId:\", sessionId);\n const url = `${this.backendUrl}/api/state?session_id=${encodeURIComponent(sessionId)}`;\n console.log(\"🔵 [fetchState] URL:\", url);\n\n const response = await fetch(url, { signal: options?.signal });\n console.log(\"🔵 [fetchState] Response status:\", response.status, response.statusText);\n\n if (!response.ok) {\n console.error(\"🔴 [fetchState] Error:\", response.status, response.statusText);\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const data = (await response.json()) as SessionResponsePayload;\n console.log(\"🟢 [fetchState] Success:\", data);\n return data;\n }\n\n async postChatMessage(\n sessionId: string,\n message: string,\n publicKey?: string\n ): Promise<SessionResponsePayload> {\n console.log(\"🔵 [postChatMessage] Called with sessionId:\", sessionId, \"message:\", message);\n const result = await postState<SessionResponsePayload>(this.backendUrl, \"/api/chat\", {\n message,\n session_id: sessionId,\n public_key: publicKey,\n });\n console.log(\"🟢 [postChatMessage] Success:\", result);\n return result;\n }\n\n async postSystemMessage(sessionId: string, message: string): Promise<SystemResponsePayload> {\n console.log(\"🔵 [postSystemMessage] Called with sessionId:\", sessionId, \"message:\", message);\n const result = await postState<SystemResponsePayload>(this.backendUrl, \"/api/system\", {\n message,\n session_id: sessionId,\n });\n console.log(\"🟢 [postSystemMessage] Success:\", result);\n return result;\n }\n\n async postInterrupt(sessionId: string): Promise<SessionResponsePayload> {\n console.log(\"🔵 [postInterrupt] Called with sessionId:\", sessionId);\n const result = await postState<SessionResponsePayload>(this.backendUrl, \"/api/interrupt\", {\n session_id: sessionId,\n });\n console.log(\"🟢 [postInterrupt] Success:\", result);\n return result;\n }\n\n disconnectSSE(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n this.setConnectionStatus(false);\n }\n\n setConnectionStatus(on: boolean): void {\n this.connectionStatus = on;\n }\n\n async connectSSE(sessionId: string, publicKey?: string) {\n this.disconnectSSE();\n\n try {\n const url = new URL(`${this.backendUrl}/api/chat/stream`);\n url.searchParams.set(\"session_id\", sessionId);\n if (publicKey) {\n url.searchParams.set(\"public_key\", publicKey);\n }\n\n this.eventSource = new EventSource(url.toString());\n\n this.eventSource.onopen = () => {\n console.log(\"🌐 SSE connection opened to:\", url.toString());\n this.setConnectionStatus(true);\n };\n\n this.eventSource.onmessage = (event) => {\n try {\n JSON.parse(event.data);\n } catch (error) {\n console.error(\"Failed to parse SSE data:\", error);\n }\n };\n\n this.eventSource.onerror = (error) => {\n console.error(\"SSE connection error:\", error);\n };\n } catch (error) {\n console.error(\"Failed to establish SSE connection:\", error);\n this.handleConnectionError(sessionId, publicKey);\n }\n }\n\n private handleConnectionError(sessionId: string, publicKey?: string): void {\n this.setConnectionStatus(false);\n let attempt = 0;\n const total = 3;\n if (attempt < total) {\n attempt++;\n console.log(`Attempting to reconnect (${attempt}/${total})...`);\n\n setTimeout(() => {\n this.connectSSE(sessionId, publicKey);\n }, 100);\n } else {\n console.error(\"Max reconnection attempts reached\");\n this.setConnectionStatus(false);\n }\n }\n\n private subscribeToUpdatesInternal<T>(\n sessionId: string,\n onUpdate: (update: T) => void,\n onError: ((error: unknown) => void) | undefined,\n logLabel: string\n ): () => void {\n const updatesUrl = new URL(\"/api/updates\", this.backendUrl);\n updatesUrl.searchParams.set(\"session_id\", sessionId);\n const updatesUrlString = updatesUrl.toString();\n\n const existing = this.updatesEventSources.get(sessionId);\n if (existing) {\n existing.cleanup();\n this.updatesEventSources.delete(sessionId);\n }\n\n const subscription = {\n eventSource: null as EventSource | null,\n retries: 0,\n retryTimer: null as ReturnType<typeof setTimeout> | null,\n stopped: false,\n cleanup: () => {\n subscription.stopped = true;\n if (subscription.retryTimer) {\n clearTimeout(subscription.retryTimer);\n subscription.retryTimer = null;\n }\n if (subscription.eventSource) {\n subscription.eventSource.close();\n subscription.eventSource = null;\n }\n },\n };\n\n const scheduleRetry = () => {\n subscription.retries += 1;\n const delayMs = Math.min(500 * 2 ** (subscription.retries - 1), 10000);\n console.warn(\n `🔁 [${logLabel}] retrying in ${delayMs}ms (attempt ${subscription.retries})`,\n { sessionId }\n );\n subscription.retryTimer = setTimeout(() => {\n open();\n }, delayMs);\n };\n\n const open = () => {\n if (subscription.stopped) return;\n if (subscription.retryTimer) {\n clearTimeout(subscription.retryTimer);\n subscription.retryTimer = null;\n }\n if (subscription.eventSource) {\n subscription.eventSource.close();\n }\n\n const updatesEventSource = new EventSource(updatesUrlString);\n subscription.eventSource = updatesEventSource;\n\n console.log(`🔔 [updates] subscribed`, updatesUrlString);\n\n updatesEventSource.onopen = () => {\n subscription.retries = 0;\n console.log(\"🔔 [updates] open\", updatesUrlString);\n };\n\n updatesEventSource.onmessage = (event) => {\n try {\n console.log(\"🔔 [updates] message\", { url: updatesUrlString, data: event.data });\n const parsed = JSON.parse(event.data) as T;\n onUpdate(parsed);\n } catch (error) {\n console.error(\"Failed to parse system update SSE:\", error);\n onError?.(error);\n }\n };\n\n updatesEventSource.onerror = (error) => {\n console.error(\"System updates SSE error:\", {\n url: updatesUrlString,\n readyState: updatesEventSource.readyState,\n error,\n });\n onError?.(error);\n if (subscription.stopped) return;\n updatesEventSource.close();\n scheduleRetry();\n };\n };\n\n this.updatesEventSources.set(sessionId, subscription);\n open();\n\n return () => {\n const current = this.updatesEventSources.get(sessionId);\n if (current === subscription) {\n current.cleanup();\n this.updatesEventSources.delete(sessionId);\n } else {\n subscription.cleanup();\n }\n };\n }\n\n subscribeToUpdates(\n sessionId: string,\n onUpdate: (update: SystemUpdateNotification) => void,\n onError?: (error: unknown) => void\n ): () => void {\n return this.subscribeToUpdatesInternal(\n sessionId,\n onUpdate,\n onError,\n \"subscribeToUpdates\"\n );\n }\n\n async fetchThreads(publicKey: string): Promise<BackendThreadMetadata[]> {\n console.log(\"🔵 [fetchThreads] Called with publicKey:\", publicKey);\n const url = `${this.backendUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;\n console.log(\"🔵 [fetchThreads] URL:\", url);\n\n const response = await fetch(url);\n console.log(\"🔵 [fetchThreads] Response status:\", response.status);\n\n if (!response.ok) {\n console.error(\"🔴 [fetchThreads] Error:\", response.status);\n throw new Error(`Failed to fetch threads: HTTP ${response.status}`);\n }\n\n const data = (await response.json()) as BackendThreadMetadata[];\n console.log(\"🟢 [fetchThreads] Success:\", data);\n return data;\n }\n\n async createThread(publicKey?: string, title?: string): Promise<CreateThreadResponse> {\n console.log(\"🔵 [createThread] Called with publicKey:\", publicKey, \"title:\", title);\n const body: Record<string, string> = {};\n if (publicKey) {\n body.public_key = publicKey;\n }\n if (title) {\n body.title = title;\n }\n console.log(\"🔵 [createThread] Request body:\", body);\n\n const url = `${this.backendUrl}/api/sessions`;\n console.log(\"🔵 [createThread] URL:\", url);\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n console.log(\"🔵 [createThread] Response status:\", response.status);\n\n if (!response.ok) {\n console.error(\"🔴 [createThread] Error:\", response.status);\n throw new Error(`Failed to create thread: HTTP ${response.status}`);\n }\n\n const data = (await response.json()) as CreateThreadResponse;\n console.log(\"🟢 [createThread] Success:\", data);\n return data;\n }\n\n async archiveThread(sessionId: string): Promise<void> {\n console.log(\"🔵 [archiveThread] Called with sessionId:\", sessionId);\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;\n console.log(\"🔵 [archiveThread] URL:\", url);\n\n const response = await fetch(url, { method: \"POST\" });\n console.log(\"🔵 [archiveThread] Response status:\", response.status);\n\n if (!response.ok) {\n console.error(\"🔴 [archiveThread] Error:\", response.status);\n throw new Error(`Failed to archive thread: HTTP ${response.status}`);\n }\n console.log(\"🟢 [archiveThread] Success\");\n }\n\n async unarchiveThread(sessionId: string): Promise<void> {\n console.log(\"🔵 [unarchiveThread] Called with sessionId:\", sessionId);\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;\n console.log(\"🔵 [unarchiveThread] URL:\", url);\n\n const response = await fetch(url, { method: \"POST\" });\n console.log(\"🔵 [unarchiveThread] Response status:\", response.status);\n\n if (!response.ok) {\n console.error(\"🔴 [unarchiveThread] Error:\", response.status);\n throw new Error(`Failed to unarchive thread: HTTP ${response.status}`);\n }\n console.log(\"🟢 [unarchiveThread] Success\");\n }\n\n async deleteThread(sessionId: string): Promise<void> {\n console.log(\"🔵 [deleteThread] Called with sessionId:\", sessionId);\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n console.log(\"🔵 [deleteThread] URL:\", url);\n\n const response = await fetch(url, { method: \"DELETE\" });\n console.log(\"🔵 [deleteThread] Response status:\", response.status);\n\n if (!response.ok) {\n console.error(\"🔴 [deleteThread] Error:\", response.status);\n throw new Error(`Failed to delete thread: HTTP ${response.status}`);\n }\n console.log(\"🟢 [deleteThread] Success\");\n }\n\n async renameThread(sessionId: string, newTitle: string): Promise<void> {\n console.log(\"🔵 [renameThread] Called with sessionId:\", sessionId, \"newTitle:\", newTitle);\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n console.log(\"🔵 [renameThread] URL:\", url);\n\n const response = await fetch(url, {\n method: \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ title: newTitle }),\n });\n console.log(\"🔵 [renameThread] Response status:\", response.status);\n\n if (!response.ok) {\n console.error(\"🔴 [renameThread] Error:\", response.status);\n throw new Error(`Failed to rename thread: HTTP ${response.status}`);\n }\n console.log(\"🟢 [renameThread] Success\");\n }\n\n async fetchEventsAfter(\n sessionId: string,\n afterId = 0,\n limit = 100\n ): Promise<SystemEvent[]> {\n const url = new URL(\"/api/events\", this.backendUrl);\n url.searchParams.set(\"session_id\", sessionId);\n if (afterId > 0) url.searchParams.set(\"after_id\", String(afterId));\n if (limit) url.searchParams.set(\"limit\", String(limit));\n\n console.log(\"🔵 [fetchEventsAfter] URL:\", url.toString());\n\n const response = await fetch(url.toString());\n if (!response.ok) {\n throw new Error(`Failed to fetch events: HTTP ${response.status}`);\n }\n return (await response.json()) as SystemEvent[];\n }\n\n subscribeToUpdatesWithNotification(\n sessionId: string,\n onUpdate: (update: SystemUpdateNotification) => void,\n onError?: (error: unknown) => void\n ): () => void {\n return this.subscribeToUpdatesInternal(\n sessionId,\n onUpdate,\n onError,\n \"subscribeToUpdatesWithNotification\"\n );\n }\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n AssistantRuntimeProvider,\n type ExternalStoreThreadData,\n useExternalStoreRuntime,\n type AppendMessage,\n} from \"@assistant-ui/react\";\n\nimport { RuntimeActionsProvider } from \"./hooks\";\nimport { useRuntimeOrchestrator } from \"./orchestrator\";\nimport {\n findTempIdForBackendId,\n isThreadReady,\n isThreadRunning,\n markSkipInitialFetch,\n resolveThreadId,\n setBackendMapping,\n} from \"./backend-state\";\nimport { isPlaceholderTitle, isTempThreadId, parseTimestamp } from \"./utils\";\nimport { useThreadContext } from \"../state/thread-context\";\nimport type { ThreadMetadata } from \"../state/types\";\nimport type { WalletTxRequestHandler } from \"../utils/wallet\";\nimport { useNotification, NotificationProvider } from \"../lib/notification-context\";\nimport { WalletHandler } from \"./wallet-handler\";\nimport { EventController } from \"./event-controller\";\n\nconst sortByLastActiveDesc = (\n [, metaA]: [string, ThreadMetadata],\n [, metaB]: [string, ThreadMetadata]\n) => {\n const tsA = parseTimestamp(metaA.lastActiveAt);\n const tsB = parseTimestamp(metaB.lastActiveAt);\n return tsB - tsA;\n};\n\nfunction buildThreadLists(threadMetadata: Map<string, ThreadMetadata>) {\n const entries = Array.from(threadMetadata.entries()).filter(\n ([, meta]) => !isPlaceholderTitle(meta.title)\n );\n\n const regularThreads = entries\n .filter(([, meta]) => meta.status === \"regular\")\n .sort(sortByLastActiveDesc)\n .map(([id, meta]): ExternalStoreThreadData<\"regular\"> => ({\n id,\n title: meta.title || \"New Chat\",\n status: \"regular\",\n }));\n\n const archivedThreads = entries\n .filter(([, meta]) => meta.status === \"archived\")\n .sort(sortByLastActiveDesc)\n .map(([id, meta]): ExternalStoreThreadData<\"archived\"> => ({\n id,\n title: meta.title || \"New Chat\",\n status: \"archived\",\n }));\n\n return { regularThreads, archivedThreads };\n}\n\nexport type AomiRuntimeProviderProps = {\n children: ReactNode;\n backendUrl?: string;\n publicKey?: string;\n onWalletTxRequest?: WalletTxRequestHandler;\n};\n\nexport function AomiRuntimeProvider({\n children,\n backendUrl = \"http://localhost:8080\",\n publicKey,\n onWalletTxRequest,\n}: Readonly<AomiRuntimeProviderProps>) {\n const threadContext = useThreadContext();\n const threadContextRef = useRef(threadContext);\n threadContextRef.current = threadContext;\n\n const currentThreadIdRef = useRef(threadContext.currentThreadId);\n useEffect(() => {\n currentThreadIdRef.current = threadContext.currentThreadId;\n }, [threadContext.currentThreadId]);\n\n const publicKeyRef = useRef(publicKey);\n useEffect(() => {\n publicKeyRef.current = publicKey;\n }, [publicKey]);\n\n const getPublicKey = useCallback(() => publicKeyRef.current, []);\n\n const lastSubscribedThreadRef = useRef<string | null>(null);\n\n const { showNotification } = useNotification();\n\n // Declare refs early so they can be used in orchestrator\n const eventControllerRef = useRef<EventController | null>(null);\n const walletHandlerRef = useRef<WalletHandler | null>(null);\n\n const {\n backendStateRef,\n polling,\n messageController,\n isRunning,\n setIsRunning,\n ensureInitialState,\n setSystemEventsHandler,\n backendApiRef,\n } = useRuntimeOrchestrator(backendUrl, { getPublicKey });\n\n // Create wallet handler\n if (!walletHandlerRef.current) {\n walletHandlerRef.current = new WalletHandler({\n backendApiRef,\n onWalletTxRequest,\n publicKey,\n showNotification,\n applySessionMessagesToThread: (threadId, msgs) => {\n messageController.inbound(threadId, msgs);\n },\n getCurrentThreadId: () => currentThreadIdRef.current,\n });\n }\n\n // Create event controller\n if (!eventControllerRef.current) {\n eventControllerRef.current = new EventController({\n backendApiRef,\n backendStateRef,\n showNotification,\n handleWalletTxRequest: (sessionId, threadId, request) => {\n walletHandlerRef.current?.handleRequest(sessionId, threadId, request);\n },\n setThreadMetadata: threadContext.setThreadMetadata,\n });\n }\n\n const handleSystemEvents = useCallback(\n (sessionId: string, threadId: string, events?: unknown[] | null) => {\n eventControllerRef.current?.handleBackendSystemEvents(sessionId, threadId, events);\n },\n []\n );\n\n useEffect(() => {\n setSystemEventsHandler(handleSystemEvents);\n return () => {\n setSystemEventsHandler(null);\n };\n }, [handleSystemEvents, setSystemEventsHandler]);\n\n const [updateSubscriptionsTick, setUpdateSubscriptionsTick] = useState(0);\n const bumpUpdateSubscriptions = useCallback(() => {\n setUpdateSubscriptionsTick((prev) => prev + 1);\n }, []);\n\n useEffect(() => {\n void ensureInitialState(threadContext.currentThreadId);\n }, [ensureInitialState, threadContext.currentThreadId]);\n\n // Sync isRunning when thread changes - check if it's currently running\n // This ensures isRunning is correct when switching threads\n useEffect(() => {\n const threadId = threadContext.currentThreadId;\n const isCurrentlyRunning = isThreadRunning(backendStateRef.current, threadId);\n setIsRunning(isCurrentlyRunning);\n }, [threadContext.currentThreadId, setIsRunning]);\n\n const currentMessages = threadContext.getThreadMessages(threadContext.currentThreadId);\n\n useEffect(() => {\n if (!publicKey) return;\n\n const fetchThreadList = async () => {\n try {\n const threadList = await backendApiRef.current.fetchThreads(publicKey);\n const currentContext = threadContextRef.current;\n const newMetadata = new Map(currentContext.threadMetadata);\n let maxChatNum = currentContext.threadCnt;\n\n for (const thread of threadList) {\n const rawTitle = thread.title ?? \"\";\n const title = isPlaceholderTitle(rawTitle) ? \"\" : rawTitle;\n const lastActive =\n thread.last_active_at ||\n thread.updated_at ||\n thread.created_at ||\n newMetadata.get(thread.session_id)?.lastActiveAt ||\n new Date().toISOString();\n newMetadata.set(thread.session_id, {\n title,\n status: thread.is_archived ? \"archived\" : \"regular\",\n lastActiveAt: lastActive,\n });\n\n const match = title.match(/^Chat (\\d+)$/);\n if (match) {\n const num = parseInt(match[1], 10);\n if (num > maxChatNum) {\n maxChatNum = num;\n }\n }\n }\n\n currentContext.setThreadMetadata(newMetadata);\n if (maxChatNum > currentContext.threadCnt) {\n currentContext.setThreadCnt(maxChatNum);\n }\n } catch (error) {\n console.error(\"Failed to fetch thread list:\", error);\n }\n };\n\n void fetchThreadList();\n }, [publicKey]);\n\n const threadListAdapter = useMemo(() => {\n const backendState = backendStateRef.current;\n const { regularThreads, archivedThreads } = buildThreadLists(threadContext.threadMetadata);\n\n const preparePendingThread = (threadId: string) => {\n const previousPendingId = backendState.creatingThreadId;\n if (previousPendingId && previousPendingId !== threadId) {\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n next.delete(previousPendingId);\n return next;\n });\n threadContext.setThreads((prev) => {\n const next = new Map(prev);\n next.delete(previousPendingId);\n return next;\n });\n backendState.pendingChat.delete(previousPendingId);\n backendState.pendingSystem.delete(previousPendingId);\n backendState.tempToBackendId.delete(previousPendingId);\n backendState.skipInitialFetch.delete(previousPendingId);\n }\n backendState.creatingThreadId = threadId;\n backendState.pendingChat.delete(threadId);\n backendState.pendingSystem.delete(threadId);\n threadContext.setThreadMetadata((prev) =>\n new Map(prev).set(threadId, {\n title: \"New Chat\",\n status: \"pending\",\n lastActiveAt: new Date().toISOString(),\n })\n );\n threadContext.setThreadMessages(threadId, []);\n threadContext.setCurrentThreadId(threadId);\n setIsRunning(false);\n threadContext.bumpThreadViewKey();\n };\n\n const findPendingThreadId = () => {\n if (backendState.creatingThreadId) return backendState.creatingThreadId;\n for (const [id, meta] of threadContext.threadMetadata.entries()) {\n if (meta.status === \"pending\") return id;\n }\n return null;\n };\n\n return {\n threadId: threadContext.currentThreadId,\n threads: regularThreads,\n archivedThreads,\n\n onSwitchToNewThread: async () => {\n const previousThreadId = currentThreadIdRef.current;\n\n // Stop polling and interrupt if currently running\n polling.stopAll();\n if (isRunning && isThreadReady(backendState, previousThreadId)) {\n const backendId = resolveThreadId(backendState, previousThreadId);\n void backendApiRef.current.postInterrupt(backendId);\n }\n\n const pendingId = findPendingThreadId();\n if (pendingId) {\n preparePendingThread(pendingId);\n return;\n }\n\n if (backendState.createThreadPromise) {\n preparePendingThread(backendState.creatingThreadId ?? `temp-${crypto.randomUUID()}`);\n return;\n }\n\n const tempId = `temp-${crypto.randomUUID()}`;\n preparePendingThread(tempId);\n\n const createPromise = backendApiRef.current\n .createThread(publicKey, undefined)\n .then(async (newThread) => {\n const uiThreadId = backendState.creatingThreadId ?? tempId;\n const backendId = newThread.session_id;\n\n setBackendMapping(backendState, uiThreadId, backendId);\n markSkipInitialFetch(backendState, uiThreadId);\n\n bumpUpdateSubscriptions();\n\n const backendTitle = newThread.title;\n if (backendTitle && !isPlaceholderTitle(backendTitle)) {\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n const existing = next.get(uiThreadId);\n const nextStatus = existing?.status === \"archived\" ? \"archived\" : \"regular\";\n next.set(uiThreadId, {\n title: backendTitle,\n status: nextStatus,\n lastActiveAt: existing?.lastActiveAt ?? new Date().toISOString(),\n });\n return next;\n });\n }\n\n if (backendState.creatingThreadId === uiThreadId) {\n backendState.creatingThreadId = null;\n }\n\n const pendingMessages = backendState.pendingChat.get(uiThreadId);\n if (pendingMessages?.length) {\n backendState.pendingChat.delete(uiThreadId);\n for (const text of pendingMessages) {\n try {\n const activePublicKey = publicKeyRef.current;\n if (activePublicKey) {\n await backendApiRef.current.postChatMessage(\n backendId,\n text,\n activePublicKey\n );\n } else {\n await backendApiRef.current.postChatMessage(backendId, text);\n }\n } catch (error) {\n console.error(\"Failed to send queued message:\", error);\n }\n }\n if (currentThreadIdRef.current === uiThreadId) {\n polling?.start(uiThreadId);\n }\n }\n })\n .catch((error) => {\n console.error(\"Failed to create new thread:\", error);\n const failedId = backendState.creatingThreadId ?? tempId;\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n next.delete(failedId);\n return next;\n });\n threadContext.setThreads((prev) => {\n const next = new Map(prev);\n next.delete(failedId);\n return next;\n });\n if (backendState.creatingThreadId === failedId) {\n backendState.creatingThreadId = null;\n }\n })\n .finally(() => {\n backendState.createThreadPromise = null;\n });\n\n backendState.createThreadPromise = createPromise;\n },\n\n onSwitchToThread: (threadId: string) => {\n const previousThreadId = currentThreadIdRef.current;\n\n // Stop polling and interrupt if currently running\n polling.stopAll();\n if (isRunning && isThreadReady(backendState, previousThreadId)) {\n const backendId = resolveThreadId(backendState, previousThreadId);\n void backendApiRef.current.postInterrupt(backendId);\n }\n\n threadContext.setCurrentThreadId(threadId);\n },\n\n onRename: async (threadId: string, newTitle: string) => {\n const previousTitle = threadContext.getThreadMetadata(threadId)?.title ?? \"\";\n const normalizedTitle = isPlaceholderTitle(newTitle) ? \"\" : newTitle;\n threadContext.updateThreadMetadata(threadId, {\n title: normalizedTitle,\n });\n\n try {\n await backendApiRef.current.renameThread(threadId, newTitle);\n } catch (error) {\n console.error(\"Failed to rename thread:\", error);\n threadContext.updateThreadMetadata(threadId, { title: previousTitle });\n }\n },\n\n onArchive: async (threadId: string) => {\n threadContext.updateThreadMetadata(threadId, { status: \"archived\" });\n\n try {\n await backendApiRef.current.archiveThread(threadId);\n } catch (error) {\n console.error(\"Failed to archive thread:\", error);\n threadContext.updateThreadMetadata(threadId, { status: \"regular\" });\n }\n },\n\n onUnarchive: async (threadId: string) => {\n threadContext.updateThreadMetadata(threadId, { status: \"regular\" });\n\n try {\n await backendApiRef.current.unarchiveThread(threadId);\n } catch (error) {\n console.error(\"Failed to unarchive thread:\", error);\n threadContext.updateThreadMetadata(threadId, { status: \"archived\" });\n }\n },\n\n onDelete: async (threadId: string) => {\n try {\n await backendApiRef.current.deleteThread(threadId);\n\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n next.delete(threadId);\n return next;\n });\n threadContext.setThreads((prev) => {\n const next = new Map(prev);\n next.delete(threadId);\n return next;\n });\n backendState.pendingChat.delete(threadId);\n backendState.pendingSystem.delete(threadId);\n backendState.tempToBackendId.delete(threadId);\n backendState.skipInitialFetch.delete(threadId);\n backendState.runningThreads.delete(threadId);\n if (backendState.creatingThreadId === threadId) {\n backendState.creatingThreadId = null;\n }\n\n if (threadContext.currentThreadId === threadId) {\n const firstRegularThread = Array.from(threadContext.threadMetadata.entries()).find(\n ([id, meta]) => meta.status === \"regular\" && id !== threadId\n );\n\n if (firstRegularThread) {\n threadContext.setCurrentThreadId(firstRegularThread[0]);\n } else {\n const defaultId = \"default-session\";\n threadContext.setThreadMetadata((prev) =>\n new Map(prev).set(defaultId, {\n title: \"New Chat\",\n status: \"regular\",\n lastActiveAt: new Date().toISOString(),\n })\n );\n threadContext.setThreadMessages(defaultId, []);\n threadContext.setCurrentThreadId(defaultId);\n }\n }\n } catch (error) {\n console.error(\"Failed to delete thread:\", error);\n throw error;\n }\n },\n };\n }, [\n backendApiRef,\n polling,\n publicKey,\n backendStateRef,\n setIsRunning,\n threadContext,\n threadContext.currentThreadId,\n threadContext.threadMetadata,\n bumpUpdateSubscriptions,\n ]);\n\n\n useEffect(() => {\n const threadId = threadContext.currentThreadId;\n if (!isTempThreadId(threadId)) return;\n if (!isThreadReady(backendStateRef.current, threadId)) return;\n void messageController.flushPendingChat(threadId);\n }, [messageController, backendStateRef, threadContext.currentThreadId]);\n\n const runtime = useExternalStoreRuntime({\n messages: currentMessages,\n setMessages: (msgs) =>\n threadContext.setThreadMessages(threadContext.currentThreadId, [...msgs]),\n isRunning,\n onNew: (message: AppendMessage) =>\n messageController.outbound(message, threadContext.currentThreadId),\n onCancel: () => messageController.cancel(threadContext.currentThreadId),\n convertMessage: (msg) => msg,\n adapters: { threadList: threadListAdapter },\n });\n\n useEffect(() => {\n const threadId = threadContext.currentThreadId;\n if (isTempThreadId(threadId)) return;\n const hasUserMessages = currentMessages.some((msg) => msg.role === \"user\");\n if (hasUserMessages) {\n void messageController.flushPendingSystem(threadId);\n }\n }, [currentMessages, messageController, threadContext.currentThreadId]);\n\n useEffect(() => {\n return () => {\n polling.stopAll();\n eventControllerRef.current?.cleanup();\n };\n }, [polling]);\n\n // Update event controller subscription when current thread changes\n useEffect(() => {\n const backendState = backendStateRef.current;\n const threadId = threadContext.currentThreadId;\n const isReady = isThreadReady(backendState, threadId);\n if (!isReady) {\n lastSubscribedThreadRef.current = null;\n eventControllerRef.current?.setSubscribableSessionId(null);\n return;\n }\n\n const isCurrentlyRunning = isThreadRunning(backendState, threadId);\n if (isCurrentlyRunning) {\n const sessionId = resolveThreadId(backendState, threadId);\n eventControllerRef.current?.setSubscribableSessionId(sessionId);\n lastSubscribedThreadRef.current = threadId;\n return;\n }\n\n if (lastSubscribedThreadRef.current !== threadId) {\n eventControllerRef.current?.setSubscribableSessionId(null);\n }\n }, [backendStateRef, threadContext.currentThreadId, updateSubscriptionsTick, isRunning]);\n\n return (\n <RuntimeActionsProvider\n value={{\n sendSystemMessage: (message: string) =>\n messageController.outboundSystem(threadContext.currentThreadId, message),\n }}\n >\n <AssistantRuntimeProvider runtime={runtime}>{children}</AssistantRuntimeProvider>\n </RuntimeActionsProvider>\n );\n}\n\n// Wrapper component that provides NotificationProvider\nexport function AomiRuntimeProviderWithNotifications(\n props: Readonly<AomiRuntimeProviderProps>\n) {\n return (\n <NotificationProvider>\n <AomiRuntimeProvider {...props} />\n </NotificationProvider>\n );\n}\n","\"use client\";\n\nimport { createContext, useContext } from \"react\";\n\nexport type RuntimeActions = {\n sendSystemMessage: (message: string) => Promise<void>;\n};\n\nconst RuntimeActionsContext = createContext<RuntimeActions | undefined>(undefined);\n\nexport const RuntimeActionsProvider = RuntimeActionsContext.Provider;\n\nexport function useRuntimeActions(): RuntimeActions {\n const context = useContext(RuntimeActionsContext);\n if (!context) {\n throw new Error(\"useRuntimeActions must be used within AomiRuntimeProvider\");\n }\n return context;\n}\n","import type { MutableRefObject } from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { BackendApi } from \"../api/client\";\nimport type { SessionMessage } from \"../api/types\";\nimport { useThreadContext, type ThreadContext } from \"../state/thread-context\";\nimport { MessageController } from \"./message-controller\";\nimport { PollingController } from \"./polling-controller\";\nimport {\n clearSkipInitialFetch,\n createBakendState,\n isThreadReady,\n resolveThreadId,\n shouldSkipInitialFetch,\n type BakendState,\n} from \"./backend-state\";\n\ntype SystemEventsHandler = (\n sessionId: string,\n threadId: string,\n events?: unknown[] | null\n) => void;\n\nexport function useRuntimeOrchestrator(\n backendUrl: string,\n options?: { getPublicKey?: () => string | undefined }\n) {\n const threadContext = useThreadContext();\n const threadContextRef = useRef<ThreadContext>(threadContext);\n threadContextRef.current = threadContext;\n const backendApiRef = useRef(new BackendApi(backendUrl));\n const backendStateRef = useRef<BakendState>(createBakendState());\n\n const [isRunning, setIsRunning] = useState(false);\n\n const messageControllerRef: MutableRefObject<MessageController | null> = useRef(null);\n const pollingRef: MutableRefObject<PollingController | null> = useRef(null);\n const systemEventsHandlerRef = useRef<SystemEventsHandler | null>(null);\n const inFlightRef = useRef<Map<string, AbortController>>(new Map());\n\n if (!pollingRef.current) {\n pollingRef.current = new PollingController({\n backendApiRef,\n backendStateRef,\n applyMessages: (threadId: string, msgs?: SessionMessage[] | null) => {\n messageControllerRef.current?.inbound(threadId, msgs);\n },\n onStart: (threadId: string) => {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(true);\n }\n },\n onStop: (threadId: string) => {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n },\n });\n }\n\n if (!messageControllerRef.current) {\n messageControllerRef.current = new MessageController({\n backendApiRef,\n backendStateRef,\n threadContextRef,\n polling: pollingRef.current,\n setGlobalIsRunning: setIsRunning,\n getPublicKey: options?.getPublicKey,\n });\n }\n\n const setSystemEventsHandler = useCallback((handler: SystemEventsHandler | null) => {\n systemEventsHandlerRef.current = handler;\n pollingRef.current?.setSystemEventsHandler(handler ?? undefined);\n }, []);\n\n useEffect(() => {\n return () => {\n for (const controller of inFlightRef.current.values()) {\n controller.abort();\n }\n inFlightRef.current.clear();\n };\n }, []);\n\n const ensureInitialState = useCallback(\n async (threadId: string) => {\n const backendState = backendStateRef.current;\n if (shouldSkipInitialFetch(backendState, threadId)) {\n clearSkipInitialFetch(backendState, threadId);\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n return;\n }\n\n if (!isThreadReady(backendState, threadId)) {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n return;\n }\n\n if (inFlightRef.current.has(threadId)) {\n return;\n }\n\n const backendThreadId = resolveThreadId(backendState, threadId);\n const controller = new AbortController();\n inFlightRef.current.set(threadId, controller);\n try {\n console.log(\"🔵 [Orchestrator] Fetching initial state for threadId:\", threadId);\n const state = await backendApiRef.current.fetchState(backendThreadId, {\n signal: controller.signal,\n });\n messageControllerRef.current?.inbound(threadId, state.messages);\n // Handle system events if handler is provided\n if (systemEventsHandlerRef.current && state.system_events) {\n systemEventsHandlerRef.current(backendThreadId, threadId, state.system_events);\n }\n if (state.is_processing) {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(true);\n }\n pollingRef.current?.start(threadId);\n } else {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n }\n } catch (error) {\n if (controller.signal.aborted) {\n return;\n }\n console.error(\"Failed to fetch initial state:\", error);\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n } finally {\n if (inFlightRef.current.get(threadId) === controller) {\n inFlightRef.current.delete(threadId);\n }\n }\n },\n [backendApiRef, backendStateRef, pollingRef, messageControllerRef, setIsRunning]\n );\n\n return {\n backendStateRef,\n polling: pollingRef.current!,\n messageController: messageControllerRef.current!,\n isRunning,\n setIsRunning,\n ensureInitialState,\n setSystemEventsHandler,\n backendApiRef,\n };\n}\n","\"use client\";\n\nimport { createContext, useContext, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { ThreadMessageLike } from \"@assistant-ui/react\";\n\nimport type { ThreadMetadata } from \"./types\";\nimport { ThreadStore, type ThreadContext as ThreadContextValue } from \"./thread-store\";\n\nexport type ThreadContext = ThreadContextValue;\n\nexport type ThreadContextProviderProps = {\n children: ReactNode;\n initialThreadId?: string;\n};\n\nconst ThreadContextState = createContext<ThreadContextValue | null>(null);\n\nexport function useThreadContext(): ThreadContext {\n const context = useContext(ThreadContextState);\n if (!context) {\n throw new Error(\n \"useThreadContext must be used within ThreadContextProvider. \" +\n \"Wrap your app with <ThreadContextProvider>...</ThreadContextProvider>\"\n );\n }\n return context;\n}\n\nexport function ThreadContextProvider({\n children,\n initialThreadId,\n}: ThreadContextProviderProps) {\n const storeRef = useRef<ThreadStore | null>(null);\n if (!storeRef.current) {\n storeRef.current = new ThreadStore({ initialThreadId });\n }\n const store = storeRef.current;\n const value = useSyncExternalStore(store.subscribe, store.getSnapshot);\n\n return (\n <ThreadContextState.Provider value={value}>{children}</ThreadContextState.Provider>\n );\n}\n\nexport function useCurrentThreadMessages(): ThreadMessageLike[] {\n const { currentThreadId, getThreadMessages } = useThreadContext();\n return useMemo(() => getThreadMessages(currentThreadId), [currentThreadId, getThreadMessages]);\n}\n\nexport function useCurrentThreadMetadata(): ThreadMetadata | undefined {\n const { currentThreadId, getThreadMetadata } = useThreadContext();\n return useMemo(() => getThreadMetadata(currentThreadId), [currentThreadId, getThreadMetadata]);\n}\n","import type { SetStateAction } from \"react\";\nimport type { ThreadMessageLike } from \"@assistant-ui/react\";\n\nimport type { ThreadMetadata } from \"./types\";\n\nexport type ThreadContext = {\n currentThreadId: string;\n setCurrentThreadId: (id: string) => void;\n threadViewKey: number;\n bumpThreadViewKey: () => void;\n threads: Map<string, ThreadMessageLike[]>;\n setThreads: (updater: SetStateAction<Map<string, ThreadMessageLike[]>>) => void;\n threadMetadata: Map<string, ThreadMetadata>;\n setThreadMetadata: (updater: SetStateAction<Map<string, ThreadMetadata>>) => void;\n threadCnt: number;\n setThreadCnt: (updater: SetStateAction<number>) => void;\n getThreadMessages: (threadId: string) => ThreadMessageLike[];\n setThreadMessages: (threadId: string, messages: ThreadMessageLike[]) => void;\n getThreadMetadata: (threadId: string) => ThreadMetadata | undefined;\n updateThreadMetadata: (threadId: string, updates: Partial<ThreadMetadata>) => void;\n};\n\ntype ThreadStoreState = {\n currentThreadId: string;\n threadViewKey: number;\n threadCnt: number;\n threads: Map<string, ThreadMessageLike[]>;\n threadMetadata: Map<string, ThreadMetadata>;\n};\n\ntype ThreadStoreOptions = {\n initialThreadId?: string;\n};\n\nexport class ThreadStore {\n private state: ThreadStoreState;\n private listeners = new Set<() => void>();\n private snapshot: ThreadContext;\n\n constructor(options?: ThreadStoreOptions) {\n const initialThreadId = options?.initialThreadId ?? crypto.randomUUID();\n this.state = {\n currentThreadId: initialThreadId,\n threadViewKey: 0,\n threadCnt: 1,\n threads: new Map([[initialThreadId, []]]),\n threadMetadata: new Map([\n [\n initialThreadId,\n {\n title: \"New Chat\",\n status: \"pending\",\n lastActiveAt: new Date().toISOString(),\n },\n ],\n ]),\n };\n\n this.snapshot = this.buildSnapshot();\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): ThreadContext => this.snapshot;\n\n private emit() {\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n private resolveStateAction<T>(updater: SetStateAction<T>, current: T): T {\n return typeof updater === \"function\" ? (updater as (prev: T) => T)(current) : updater;\n }\n\n private ensureThreadExists(threadId: string) {\n if (!this.state.threadMetadata.has(threadId)) {\n const nextMetadata = new Map(this.state.threadMetadata);\n nextMetadata.set(threadId, {\n title: \"New Chat\",\n status: \"regular\",\n lastActiveAt: new Date().toISOString(),\n });\n this.state = { ...this.state, threadMetadata: nextMetadata };\n }\n\n if (!this.state.threads.has(threadId)) {\n const nextThreads = new Map(this.state.threads);\n nextThreads.set(threadId, []);\n this.state = { ...this.state, threads: nextThreads };\n }\n }\n\n private updateState(partial: Partial<ThreadStoreState>) {\n this.state = { ...this.state, ...partial };\n this.snapshot = this.buildSnapshot();\n this.emit();\n }\n\n private buildSnapshot(): ThreadContext {\n return {\n currentThreadId: this.state.currentThreadId,\n setCurrentThreadId: this.setCurrentThreadId,\n threadViewKey: this.state.threadViewKey,\n bumpThreadViewKey: this.bumpThreadViewKey,\n threads: this.state.threads,\n setThreads: this.setThreads,\n threadMetadata: this.state.threadMetadata,\n setThreadMetadata: this.setThreadMetadata,\n threadCnt: this.state.threadCnt,\n setThreadCnt: this.setThreadCnt,\n getThreadMessages: this.getThreadMessages,\n setThreadMessages: this.setThreadMessages,\n getThreadMetadata: this.getThreadMetadata,\n updateThreadMetadata: this.updateThreadMetadata,\n };\n }\n\n setCurrentThreadId = (threadId: string) => {\n this.ensureThreadExists(threadId);\n this.updateState({ currentThreadId: threadId });\n };\n\n bumpThreadViewKey = () => {\n this.updateState({ threadViewKey: this.state.threadViewKey + 1 });\n };\n\n setThreadCnt = (updater: SetStateAction<number>) => {\n const nextCnt = this.resolveStateAction(updater, this.state.threadCnt);\n this.updateState({ threadCnt: nextCnt });\n };\n\n setThreads = (updater: SetStateAction<Map<string, ThreadMessageLike[]>>) => {\n const nextThreads = this.resolveStateAction(updater, this.state.threads);\n this.updateState({ threads: new Map(nextThreads) });\n };\n\n setThreadMetadata = (updater: SetStateAction<Map<string, ThreadMetadata>>) => {\n const nextMetadata = this.resolveStateAction(updater, this.state.threadMetadata);\n this.updateState({ threadMetadata: new Map(nextMetadata) });\n };\n\n setThreadMessages = (threadId: string, messages: ThreadMessageLike[]) => {\n this.ensureThreadExists(threadId);\n const nextThreads = new Map(this.state.threads);\n nextThreads.set(threadId, messages);\n this.updateState({ threads: nextThreads });\n };\n\n getThreadMessages = (threadId: string): ThreadMessageLike[] => {\n return this.state.threads.get(threadId) ?? [];\n };\n\n getThreadMetadata = (threadId: string): ThreadMetadata | undefined => {\n return this.state.threadMetadata.get(threadId);\n };\n\n updateThreadMetadata = (threadId: string, updates: Partial<ThreadMetadata>) => {\n const existing = this.state.threadMetadata.get(threadId);\n if (!existing) {\n return;\n }\n const nextMetadata = new Map(this.state.threadMetadata);\n nextMetadata.set(threadId, { ...existing, ...updates });\n this.updateState({ threadMetadata: nextMetadata });\n };\n}\n","import type { ThreadMessageLike } from \"@assistant-ui/react\";\n\nimport type { SessionMessage } from \"../api/types\";\n\ntype MessageContentPart = Exclude<ThreadMessageLike[\"content\"], string> extends readonly (infer U)[] ? U : never;\n\nexport function toInboundMessage(msg: SessionMessage): ThreadMessageLike | null {\n if (msg.sender === \"system\") return null;\n\n const content: MessageContentPart[] = [];\n const role: ThreadMessageLike[\"role\"] = msg.sender === \"user\" ? \"user\" : \"assistant\";\n\n if (msg.content) {\n content.push({ type: \"text\" as const, text: msg.content });\n }\n\n const [topic, toolContent] = parseToolStream(msg.tool_stream) ?? [];\n if (topic && toolContent) {\n content.push({\n type: \"tool-call\" as const,\n toolCallId: `tool_${Date.now()}`,\n toolName: topic,\n args: undefined,\n result: (() => {\n try {\n return JSON.parse(toolContent);\n } catch {\n return { args: toolContent };\n }\n })(),\n });\n }\n\n const threadMessage = {\n role,\n content: (content.length > 0 ? content : [{ type: \"text\" as const, text: \"\" }]) as ThreadMessageLike[\"content\"],\n ...(msg.timestamp && { createdAt: new Date(msg.timestamp) }),\n } satisfies ThreadMessageLike;\n\n return threadMessage;\n}\n\nexport function toInboundSystem(msg: SessionMessage): ThreadMessageLike | null {\n const [topic] = parseToolStream(msg.tool_stream) ?? [];\n const messageText = topic || msg.content || \"\";\n const timestamp = parseTimestamp(msg.timestamp);\n\n if (!messageText.trim()) return null;\n\n return {\n role: \"system\",\n content: [{ type: \"text\", text: messageText }],\n ...(timestamp && { createdAt: timestamp }),\n } satisfies ThreadMessageLike;\n}\n\nexport function constructUITool(): string {\n return \"\";\n}\n\nfunction parseTimestamp(timestamp?: string) {\n if (!timestamp) return undefined;\n const parsed = new Date(timestamp);\n return Number.isNaN(parsed.valueOf()) ? undefined : parsed;\n}\n\nfunction parseToolStream(toolStream: SessionMessage[\"tool_stream\"]): [string, string] | null {\n if (!toolStream) return null;\n\n if (Array.isArray(toolStream) && toolStream.length === 2) {\n const [topic, content] = toolStream;\n return [String(topic), content];\n }\n\n if (typeof toolStream === \"object\") {\n const topic = (toolStream as { topic?: unknown }).topic;\n const content = (toolStream as { content?: unknown }).content;\n return topic ? [String(topic), String(content)] : null;\n }\n\n return null;\n}\n","export const isTempThreadId = (id: string) => id.startsWith(\"temp-\");\n\nexport const parseTimestamp = (value?: string | number) => {\n if (value === undefined || value === null) return 0;\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? (value < 1e12 ? value * 1000 : value) : 0;\n }\n\n const numeric = Number(value);\n if (!Number.isNaN(numeric)) {\n return numeric < 1e12 ? numeric * 1000 : numeric;\n }\n\n const ts = Date.parse(value);\n return Number.isNaN(ts) ? 0 : ts;\n};\n\nexport const isPlaceholderTitle = (title?: string) => {\n const normalized = title?.trim() ?? \"\";\n return !normalized || normalized.startsWith(\"#[\");\n};\n","import { isTempThreadId } from \"./utils\";\n\nexport type BakendState = {\n tempToBackendId: Map<string, string>;\n skipInitialFetch: Set<string>;\n pendingChat: Map<string, string[]>;\n pendingSystem: Map<string, string[]>;\n runningThreads: Set<string>;\n creatingThreadId: string | null;\n createThreadPromise: Promise<void> | null;\n};\n\nexport function createBakendState(): BakendState {\n return {\n tempToBackendId: new Map(),\n skipInitialFetch: new Set(),\n pendingChat: new Map(),\n pendingSystem: new Map(),\n runningThreads: new Set(),\n creatingThreadId: null,\n createThreadPromise: null,\n };\n}\n\nexport function resolveThreadId(state: BakendState, threadId: string): string {\n return state.tempToBackendId.get(threadId) ?? threadId;\n}\n\nexport function isThreadReady(state: BakendState, threadId: string): boolean {\n if (!isTempThreadId(threadId)) return true;\n return state.tempToBackendId.has(threadId);\n}\n\nexport function setBackendMapping(\n state: BakendState,\n tempId: string,\n backendId: string\n) {\n state.tempToBackendId.set(tempId, backendId);\n}\n\nexport function findTempIdForBackendId(\n state: BakendState,\n backendId: string\n): string | undefined {\n for (const [tempId, id] of state.tempToBackendId.entries()) {\n if (id === backendId) return tempId;\n }\n return undefined;\n}\n\nexport function markSkipInitialFetch(state: BakendState, threadId: string) {\n state.skipInitialFetch.add(threadId);\n}\n\nexport function shouldSkipInitialFetch(\n state: BakendState,\n threadId: string\n): boolean {\n return state.skipInitialFetch.has(threadId);\n}\n\nexport function clearSkipInitialFetch(state: BakendState, threadId: string) {\n state.skipInitialFetch.delete(threadId);\n}\n\nexport function setThreadRunning(state: BakendState, threadId: string, running: boolean) {\n if (running) {\n state.runningThreads.add(threadId);\n } else {\n state.runningThreads.delete(threadId);\n }\n}\n\nexport function isThreadRunning(state: BakendState, threadId: string): boolean {\n return state.runningThreads.has(threadId);\n}\n\nexport function enqueuePendingChat(state: BakendState, threadId: string, text: string) {\n const existing = state.pendingChat.get(threadId) ?? [];\n state.pendingChat.set(threadId, [...existing, text]);\n}\n\nexport function dequeuePendingChat(state: BakendState, threadId: string): string[] {\n const pending = state.pendingChat.get(threadId) ?? [];\n state.pendingChat.delete(threadId);\n return pending;\n}\n\nexport function hasPendingChat(state: BakendState, threadId: string): boolean {\n return (state.pendingChat.get(threadId)?.length ?? 0) > 0;\n}\n\nexport function enqueuePendingSystem(state: BakendState, threadId: string, text: string) {\n const existing = state.pendingSystem.get(threadId) ?? [];\n state.pendingSystem.set(threadId, [...existing, text]);\n}\n\nexport function dequeuePendingSystem(state: BakendState, threadId: string): string[] {\n const pending = state.pendingSystem.get(threadId) ?? [];\n state.pendingSystem.delete(threadId);\n return pending;\n}\n\nexport function hasPendingSystem(state: BakendState, threadId: string): boolean {\n return (state.pendingSystem.get(threadId)?.length ?? 0) > 0;\n}\n","import type { MutableRefObject } from \"react\";\nimport type { AppendMessage, ThreadMessageLike } from \"@assistant-ui/react\";\n\nimport type { BackendApi } from \"../api/client\";\nimport type { SessionMessage } from \"../api/types\";\nimport { toInboundSystem, toInboundMessage } from \"../utils/conversion\";\nimport type { ThreadContext } from \"../state/thread-context\";\nimport type { PollingController } from \"./polling-controller\";\nimport {\n dequeuePendingChat,\n dequeuePendingSystem,\n enqueuePendingChat,\n enqueuePendingSystem,\n hasPendingChat,\n isThreadReady,\n resolveThreadId,\n setThreadRunning,\n type BakendState,\n} from \"./backend-state\";\n\ntype MessageControllerConfig = {\n backendApiRef: MutableRefObject<BackendApi>;\n backendStateRef: MutableRefObject<BakendState>;\n threadContextRef: MutableRefObject<ThreadContext>;\n polling: PollingController;\n setGlobalIsRunning?: (running: boolean) => void;\n getPublicKey?: () => string | undefined;\n};\n\ntype ThreadContextApi = Pick<\n ThreadContext,\n \"getThreadMessages\" | \"setThreadMessages\" | \"updateThreadMetadata\"\n>;\n\nexport class MessageController {\n constructor(private readonly config: MessageControllerConfig) {}\n\n inbound(threadId: string, msgs?: SessionMessage[] | null) {\n const backendState = this.config.backendStateRef.current;\n if (!msgs) return;\n if (hasPendingChat(backendState, threadId)) {\n // Avoid overwriting optimistic UI when pending user messages exist.\n return;\n }\n\n const threadMessages: ThreadMessageLike[] = [];\n for (const msg of msgs) {\n if (msg.sender === \"system\") {\n const systemMessage = toInboundSystem(msg);\n if (systemMessage) {\n threadMessages.push(systemMessage);\n }\n continue;\n }\n const threadMessage = toInboundMessage(msg);\n if (threadMessage) {\n threadMessages.push(threadMessage);\n }\n }\n\n this.getThreadContextApi().setThreadMessages(threadId, threadMessages);\n }\n\n async outbound(message: AppendMessage, threadId: string) {\n const backendState = this.config.backendStateRef.current;\n const text = message.content\n .filter((part): part is Extract<typeof part, { type: \"text\" }> => part.type === \"text\")\n .map((part: Extract<typeof message.content[number], { type: \"text\" }>) => part.text)\n .join(\"\\n\");\n\n if (!text) return;\n\n const threadState = this.getThreadContextApi();\n const existingMessages = threadState.getThreadMessages(threadId);\n const userMessage: ThreadMessageLike = {\n role: \"user\",\n content: [{ type: \"text\", text }],\n createdAt: new Date(),\n };\n\n threadState.setThreadMessages(threadId, [...existingMessages, userMessage]);\n threadState.updateThreadMetadata(threadId, { lastActiveAt: new Date().toISOString() });\n\n if (!isThreadReady(backendState, threadId)) {\n this.markRunning(threadId, true);\n enqueuePendingChat(backendState, threadId, text);\n return;\n }\n\n const backendThreadId = resolveThreadId(backendState, threadId);\n const publicKey = this.config.getPublicKey?.();\n\n try {\n this.markRunning(threadId, true);\n if (publicKey) {\n await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n publicKey\n );\n } else {\n await this.config.backendApiRef.current.postChatMessage(backendThreadId, text);\n }\n await this.flushPendingSystem(threadId);\n this.config.polling.start(threadId);\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n this.markRunning(threadId, false);\n }\n }\n\n async outboundSystem(threadId: string, text: string) {\n const backendState = this.config.backendStateRef.current;\n if (!isThreadReady(backendState, threadId)) return;\n const threadMessages = this.getThreadContextApi().getThreadMessages(threadId);\n const hasUserMessages = threadMessages.some((msg) => msg.role === \"user\");\n\n if (!hasUserMessages) {\n enqueuePendingSystem(backendState, threadId, text);\n return;\n }\n\n await this.outboundSystemInner(threadId, text);\n }\n\n async outboundSystemInner(threadId: string, text: string) {\n const backendState = this.config.backendStateRef.current;\n const threadState = this.getThreadContextApi();\n const backendThreadId = resolveThreadId(backendState, threadId);\n this.markRunning(threadId, true);\n try {\n const response = await this.config.backendApiRef.current.postSystemMessage(backendThreadId, text);\n if (response.res) {\n const systemMessage = toInboundSystem(response.res);\n if (systemMessage) {\n const updatedMessages = [...threadState.getThreadMessages(threadId), systemMessage];\n threadState.setThreadMessages(threadId, updatedMessages);\n }\n }\n await this.flushPendingSystem(threadId);\n this.config.polling.start(threadId);\n } catch (error) {\n console.error(\"Failed to send system message:\", error);\n this.markRunning(threadId, false);\n }\n }\n\n async flushPendingSystem(threadId: string) {\n const backendState = this.config.backendStateRef.current;\n const pending = dequeuePendingSystem(backendState, threadId);\n if (!pending.length) return;\n for (const pendingMessage of pending) {\n await this.outboundSystemInner(threadId, pendingMessage);\n }\n }\n\n async flushPendingChat(threadId: string) {\n const backendState = this.config.backendStateRef.current;\n const pending = dequeuePendingChat(backendState, threadId);\n if (!pending.length) return;\n const backendThreadId = resolveThreadId(backendState, threadId);\n const publicKey = this.config.getPublicKey?.();\n for (const text of pending) {\n try {\n if (publicKey) {\n await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n publicKey\n );\n } else {\n await this.config.backendApiRef.current.postChatMessage(backendThreadId, text);\n }\n } catch (error) {\n console.error(\"Failed to send queued message:\", error);\n }\n }\n this.config.polling.start(threadId);\n }\n\n async cancel(threadId: string) {\n const backendState = this.config.backendStateRef.current;\n if (!isThreadReady(backendState, threadId)) return;\n this.config.polling.stop(threadId);\n const backendThreadId = resolveThreadId(backendState, threadId);\n try {\n await this.config.backendApiRef.current.postInterrupt(backendThreadId);\n this.markRunning(threadId, false);\n } catch (error) {\n console.error(\"Failed to cancel:\", error);\n }\n }\n\n private markRunning(threadId: string, running: boolean) {\n setThreadRunning(this.config.backendStateRef.current, threadId, running);\n if (this.config.threadContextRef.current.currentThreadId === threadId) {\n this.config.setGlobalIsRunning?.(running);\n }\n }\n\n private getThreadContextApi(): ThreadContextApi {\n const { getThreadMessages, setThreadMessages, updateThreadMetadata } =\n this.config.threadContextRef.current;\n return { getThreadMessages, setThreadMessages, updateThreadMetadata };\n }\n}\n","import type { MutableRefObject } from \"react\";\n\nimport type { BackendApi } from \"../api/client\";\nimport type { SessionMessage, SessionResponsePayload } from \"../api/types\";\nimport {\n isThreadReady,\n resolveThreadId,\n setThreadRunning,\n type BakendState,\n} from \"./backend-state\";\n\ntype PollingConfig = {\n backendApiRef: MutableRefObject<BackendApi>;\n backendStateRef: MutableRefObject<BakendState>;\n applyMessages: (threadId: string, messages?: SessionMessage[] | null) => void;\n handleSystemEvents?: (\n sessionId: string,\n threadId: string,\n events?: unknown[] | null\n ) => void;\n onStart?: (threadId: string) => void;\n onStop?: (threadId: string) => void;\n intervalMs?: number;\n};\n\nexport class PollingController {\n private intervals = new Map<string, ReturnType<typeof setInterval>>();\n private intervalMs: number;\n private handleSystemEvents?: (\n sessionId: string,\n threadId: string,\n events?: unknown[] | null\n ) => void;\n\n constructor(private readonly config: PollingConfig) {\n this.intervalMs = config.intervalMs ?? 500;\n this.handleSystemEvents = config.handleSystemEvents;\n }\n\n setSystemEventsHandler(\n handler?: (sessionId: string, threadId: string, events?: unknown[] | null) => void\n ) {\n this.handleSystemEvents = handler;\n }\n\n start(threadId: string) {\n const backendState = this.config.backendStateRef.current;\n if (!isThreadReady(backendState, threadId)) return;\n // Prevent starting if already polling\n if (this.intervals.has(threadId)) {\n return;\n }\n\n const backendThreadId = resolveThreadId(backendState, threadId);\n setThreadRunning(backendState, threadId, true);\n\n const tick = async () => {\n // Check if polling was stopped before proceeding (handles race conditions)\n if (!this.intervals.has(threadId)) {\n return;\n }\n\n try {\n console.log(\"🔵 [PollingController] Fetching state for threadId:\", threadId);\n const state = await this.config.backendApiRef.current.fetchState(backendThreadId);\n \n // Check again after async operation (polling might have been stopped)\n if (!this.intervals.has(threadId)) {\n return;\n }\n \n this.handleState(threadId, state);\n } catch (error) {\n console.error(\"Polling error:\", error);\n this.stop(threadId);\n }\n };\n\n const intervalId = setInterval(tick, this.intervalMs);\n this.intervals.set(threadId, intervalId);\n \n // Trigger onStart if provided (for setting isRunning state)\n if (this.config.onStart) {\n this.config.onStart(threadId);\n }\n }\n\n stop(threadId: string) {\n const intervalId = this.intervals.get(threadId);\n if (intervalId) {\n clearInterval(intervalId);\n this.intervals.delete(threadId);\n }\n // Update state immediately to prevent any queued ticks from proceeding\n setThreadRunning(this.config.backendStateRef.current, threadId, false);\n this.config.onStop?.(threadId);\n }\n\n isPolling(threadId: string): boolean {\n return this.intervals.has(threadId);\n }\n\n stopAll() {\n for (const threadId of this.intervals.keys()) {\n this.stop(threadId);\n }\n }\n\n private handleState(threadId: string, state: SessionResponsePayload) {\n if (state.session_exists === false) {\n this.stop(threadId);\n return;\n }\n\n const backendState = this.config.backendStateRef.current;\n const backendThreadId = resolveThreadId(backendState, threadId);\n\n // Handle system events if handler is provided\n if (this.handleSystemEvents && state.system_events) {\n this.handleSystemEvents(backendThreadId, threadId, state.system_events);\n }\n\n this.config.applyMessages(threadId, state.messages);\n\n // Stop polling if backend explicitly indicates processing is complete\n // or the flag is omitted.\n if (!state.is_processing) {\n this.stop(threadId);\n }\n }\n}\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useState,\n type ReactNode,\n} from \"react\";\n\nexport type NotificationType = \"error\" | \"notice\" | \"success\";\n\nexport type NotificationIconType =\n | \"error\"\n | \"success\"\n | \"notice\"\n | \"wallet\"\n | \"transaction\"\n | \"network\"\n | \"warning\";\n\nexport type Notification = {\n id: string;\n type: NotificationType;\n title: string;\n message: string;\n iconType?: NotificationIconType;\n duration?: number; // in milliseconds, default 5000\n};\n\ntype NotificationContextValue = {\n showNotification: (notification: Omit<Notification, \"id\">) => void;\n notifications: Notification[];\n dismissNotification: (id: string) => void;\n};\n\nconst NotificationContext = createContext<NotificationContextValue | undefined>(\n undefined\n);\n\nexport function useNotification() {\n const context = useContext(NotificationContext);\n if (!context) {\n throw new Error(\"useNotification must be used within NotificationProvider\");\n }\n return context;\n}\n\nexport function NotificationProvider({ children }: { children: ReactNode }) {\n const [notifications, setNotifications] = useState<Notification[]>([]);\n\n const showNotification = useCallback(\n (notification: Omit<Notification, \"id\">) => {\n const id = `notification-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newNotification: Notification = {\n ...notification,\n id,\n duration: notification.duration ?? 5000,\n };\n\n setNotifications((prev) => [newNotification, ...prev]);\n\n // Auto-dismiss after duration\n const duration = newNotification.duration ?? 5000;\n if (duration > 0) {\n setTimeout(() => {\n setNotifications((prev) => prev.filter((n) => n.id !== id));\n }, duration);\n }\n },\n []\n );\n\n const dismissNotification = useCallback((id: string) => {\n setNotifications((prev) => prev.filter((n) => n.id !== id));\n }, []);\n\n return (\n <NotificationContext.Provider\n value={{ showNotification, notifications, dismissNotification }}\n >\n {children}\n </NotificationContext.Provider>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nimport { useRuntimeActions } from \"../runtime/hooks\";\n\n// ==================== Wallet Button State ====================\n\nexport type WalletButtonState = {\n address?: string;\n chainId?: number;\n isConnected: boolean;\n ensName?: string;\n};\n\nexport type WalletFooterProps = {\n wallet: WalletButtonState;\n setWallet: (data: Partial<WalletButtonState>) => void;\n};\n\n// ==================== Wallet Transaction Types ====================\n\nexport type WalletTxRequestPayload = {\n to: string;\n value: string; // wei as decimal string\n data: string; // 0x-prefixed hex\n gas?: string | null;\n gas_limit?: string | null;\n description?: string;\n topic?: string;\n timestamp?: string;\n};\n\nexport type WalletTxRequestContext = {\n sessionId: string;\n threadId: string;\n publicKey?: string;\n};\n\n// Return the transaction hash (0x...) or throw on failure/rejection.\nexport type WalletTxRequestHandler = (\n request: WalletTxRequestPayload,\n context: WalletTxRequestContext\n) => Promise<string>;\n\nexport type Eip1193Provider = {\n request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;\n};\n\n// ==================== Network Utilities ====================\n\nexport const getNetworkName = (chainId: number | string | undefined): string => {\n if (chainId === undefined) return \"\";\n const id = typeof chainId === \"string\" ? Number(chainId) : chainId;\n switch (id) {\n case 1:\n return \"ethereum\";\n case 137:\n return \"polygon\";\n case 42161:\n return \"arbitrum\";\n case 8453:\n return \"base\";\n case 10:\n return \"optimism\";\n case 11155111:\n return \"sepolia\";\n case 1337:\n case 31337:\n return \"testnet\";\n case 59140:\n return \"linea-sepolia\";\n case 59144:\n return \"linea\";\n default:\n return \"testnet\";\n }\n};\n\nexport const formatAddress = (addr?: string): string =>\n addr ? `${addr.slice(0, 6)}...${addr.slice(-4)}` : \"Connect Wallet\";\n\n// ==================== Wallet Error Handling ====================\n\nexport function normalizeWalletError(error: unknown): {\n rejected: boolean;\n message: string;\n} {\n const e = error as {\n code?: unknown;\n name?: unknown;\n message?: unknown;\n shortMessage?: unknown;\n cause?: unknown;\n };\n const cause = (e?.cause ?? null) as\n | { code?: unknown; name?: unknown; message?: unknown; shortMessage?: unknown }\n | null;\n\n const code =\n (typeof e?.code === \"number\" ? e.code : undefined) ??\n (typeof cause?.code === \"number\" ? cause.code : undefined);\n const name =\n (typeof e?.name === \"string\" ? e.name : undefined) ??\n (typeof cause?.name === \"string\" ? cause.name : undefined);\n const msg =\n (typeof e?.shortMessage === \"string\" ? e.shortMessage : undefined) ??\n (typeof cause?.shortMessage === \"string\" ? cause.shortMessage : undefined) ??\n (typeof e?.message === \"string\" ? e.message : undefined) ??\n (typeof cause?.message === \"string\" ? cause.message : undefined) ??\n \"Unknown wallet error\";\n\n const rejected =\n code === 4001 ||\n name === \"UserRejectedRequestError\" ||\n name === \"RejectedRequestError\" ||\n /user rejected|rejected the request|denied|request rejected|canceled|cancelled/i.test(\n msg\n );\n\n return { rejected, message: msg };\n}\n\n// ==================== Hex Conversion ====================\n\nexport function toHexQuantity(value: string): string {\n const trimmed = value.trim();\n const asBigInt = BigInt(trimmed);\n return `0x${asBigInt.toString(16)}`;\n}\n\n// ==================== Provider Detection ====================\n\nexport async function pickInjectedProvider(\n publicKey?: string\n): Promise<Eip1193Provider | undefined> {\n const ethereum = (globalThis as unknown as { ethereum?: unknown }).ethereum as\n | (Eip1193Provider & { providers?: unknown[] })\n | undefined;\n if (!ethereum?.request) return undefined;\n\n const candidates: Eip1193Provider[] = Array.isArray(ethereum.providers)\n ? (ethereum.providers.filter(\n (p): p is Eip1193Provider => !!(p as Eip1193Provider)?.request\n ) as Eip1193Provider[])\n : [ethereum];\n\n const target = publicKey?.toLowerCase();\n if (target) {\n for (const candidate of candidates) {\n try {\n const accounts = (await candidate.request({\n method: \"eth_accounts\",\n })) as unknown;\n const list = Array.isArray(accounts)\n ? (accounts as unknown[]).map((a) => String(a).toLowerCase())\n : [];\n if (list.includes(target)) return candidate;\n } catch {\n // Ignore providers that error on eth_accounts.\n }\n }\n }\n\n return candidates[0];\n}\n\n// ==================== Wallet System Message Emitter ====================\n\ntype WalletSystemMessageEmitterProps = {\n wallet: WalletButtonState;\n};\n\nexport function WalletSystemMessageEmitter({\n wallet,\n}: WalletSystemMessageEmitterProps) {\n const { sendSystemMessage } = useRuntimeActions();\n const lastWalletRef = useRef<{\n isConnected: boolean;\n address?: string;\n chainId?: number;\n }>({ isConnected: false });\n\n useEffect(() => {\n const prev = lastWalletRef.current;\n const { address, chainId, isConnected } = wallet;\n const normalizedAddress = address?.toLowerCase();\n\n if (\n isConnected &&\n normalizedAddress &&\n chainId &&\n (!prev.isConnected || prev.address !== normalizedAddress)\n ) {\n const networkName = getNetworkName(chainId);\n const message = `User connected wallet with address ${normalizedAddress} on ${networkName} network (Chain ID: ${chainId}). Ready to help with transactions.`;\n console.log(message);\n void sendSystemMessage(message);\n lastWalletRef.current = {\n isConnected: true,\n address: normalizedAddress,\n chainId,\n };\n return;\n }\n\n if (!isConnected && prev.isConnected) {\n void sendSystemMessage(\"Wallet disconnected by user.\");\n console.log(\"Wallet disconnected by user.\");\n lastWalletRef.current = { isConnected: false };\n return;\n }\n\n if (\n isConnected &&\n normalizedAddress &&\n chainId &&\n prev.isConnected &&\n prev.address === normalizedAddress &&\n prev.chainId !== chainId\n ) {\n const networkName = getNetworkName(chainId);\n const message = `User switched wallet to ${networkName} network (Chain ID: ${chainId}).`;\n console.log(message);\n void sendSystemMessage(message);\n lastWalletRef.current = {\n isConnected: true,\n address: normalizedAddress,\n chainId,\n };\n }\n }, [wallet, sendSystemMessage]);\n\n return null;\n}\n","import type { MutableRefObject } from \"react\";\n\nimport type { BackendApi } from \"../api/client\";\nimport type { SessionMessage } from \"../api/types\";\nimport type { Notification } from \"../lib/notification-context\";\nimport {\n normalizeWalletError,\n pickInjectedProvider,\n toHexQuantity,\n type WalletTxRequestHandler,\n type WalletTxRequestPayload,\n} from \"../utils/wallet\";\n\ntype WalletHandlerConfig = {\n backendApiRef: MutableRefObject<BackendApi>;\n onWalletTxRequest?: WalletTxRequestHandler;\n publicKey?: string;\n showNotification: (notification: Omit<Notification, \"id\">) => void;\n applySessionMessagesToThread: (\n threadId: string,\n msgs?: SessionMessage[] | null\n ) => void;\n getCurrentThreadId: () => string;\n};\n\nexport class WalletHandler {\n private handledRequests = new Set<string>();\n private queue: Array<{\n sessionId: string;\n threadId: string;\n request: WalletTxRequestPayload;\n }> = [];\n private inFlight = false;\n\n constructor(private readonly config: WalletHandlerConfig) {}\n\n handleRequest(\n sessionId: string,\n threadId: string,\n request: WalletTxRequestPayload\n ) {\n // Only pop the wallet if the user is currently viewing this thread.\n if (this.config.getCurrentThreadId() !== threadId) return;\n\n const description =\n request.description || request.topic || \"Wallet transaction requested\";\n this.config.showNotification({\n type: \"notice\",\n iconType: \"wallet\",\n title: \"Transaction Request\",\n message: description,\n });\n\n this.enqueue(sessionId, threadId, request);\n void this.drain();\n }\n\n private enqueue(\n sessionId: string,\n threadId: string,\n request: WalletTxRequestPayload\n ) {\n const key = `${sessionId}:${request.timestamp ?? JSON.stringify(request)}`;\n if (this.handledRequests.has(key)) return;\n this.handledRequests.add(key);\n this.queue.push({ sessionId, threadId, request });\n }\n\n private async drain() {\n if (this.inFlight) return;\n const next = this.queue.shift();\n if (!next) return;\n this.inFlight = true;\n\n try {\n if (this.config.onWalletTxRequest) {\n const txHash = await this.config.onWalletTxRequest(next.request, {\n sessionId: next.sessionId,\n threadId: next.threadId,\n publicKey: this.config.publicKey,\n });\n this.config.showNotification({\n type: \"success\",\n iconType: \"transaction\",\n title: \"Transaction Sent\",\n message: `Hash: ${txHash}`,\n });\n await this.config.backendApiRef.current.postSystemMessage(\n next.sessionId,\n `Transaction sent: ${txHash}`\n );\n await this.refreshThreadIfCurrent(next.sessionId, next.threadId);\n return;\n }\n\n const activeProvider = await pickInjectedProvider(this.config.publicKey);\n if (!activeProvider?.request) {\n this.config.showNotification({\n type: \"error\",\n iconType: \"wallet\",\n title: \"Wallet Not Found\",\n message: \"No wallet provider found (window.ethereum missing).\",\n });\n await this.config.backendApiRef.current.postSystemMessage(\n next.sessionId,\n \"No wallet provider found (window.ethereum missing).\"\n );\n return;\n }\n\n const accounts = (await activeProvider.request({\n method: \"eth_accounts\",\n })) as unknown;\n const addresses = Array.isArray(accounts)\n ? (accounts as unknown[]).map(String)\n : [];\n const from = this.config.publicKey || addresses[0];\n\n if (!from) {\n await activeProvider.request({ method: \"eth_requestAccounts\" });\n }\n\n const fromAddress =\n this.config.publicKey ||\n ((await activeProvider.request({ method: \"eth_accounts\" })) as unknown);\n const resolvedFrom =\n this.config.publicKey ||\n (Array.isArray(fromAddress)\n ? String((fromAddress as unknown[])[0] ?? \"\")\n : \"\");\n\n if (!resolvedFrom) {\n this.config.showNotification({\n type: \"error\",\n iconType: \"wallet\",\n title: \"Wallet Not Connected\",\n message: \"Please connect a wallet to sign the requested transaction.\",\n });\n await this.config.backendApiRef.current.postSystemMessage(\n next.sessionId,\n \"Wallet is not connected; please connect a wallet to sign the requested transaction.\"\n );\n return;\n }\n\n const gas = next.request.gas ?? next.request.gas_limit ?? undefined;\n let valueHex: string | undefined;\n let gasHex: string | undefined;\n try {\n valueHex = toHexQuantity(next.request.value);\n if (gas) gasHex = toHexQuantity(gas);\n } catch (error) {\n this.config.showNotification({\n type: \"error\",\n iconType: \"transaction\",\n title: \"Invalid Transaction\",\n message: (error as Error).message,\n });\n await this.config.backendApiRef.current.postSystemMessage(\n next.sessionId,\n `Invalid wallet transaction request payload: ${(error as Error).message}`\n );\n return;\n }\n\n const txParams: Record<string, string> = {\n from: resolvedFrom,\n to: next.request.to,\n value: valueHex,\n data: next.request.data,\n ...(gasHex ? { gas: gasHex } : {}),\n };\n\n const txHash = (await activeProvider.request({\n method: \"eth_sendTransaction\",\n params: [txParams],\n })) as string;\n\n this.config.showNotification({\n type: \"success\",\n title: \"Transaction sent\",\n message: `Transaction hash: ${txHash}`,\n });\n await this.config.backendApiRef.current.postSystemMessage(\n next.sessionId,\n `Transaction sent: ${txHash}`\n );\n await this.refreshThreadIfCurrent(next.sessionId, next.threadId);\n } catch (error) {\n const normalized = normalizeWalletError(error);\n const final = normalized.rejected\n ? \"Transaction rejected by user.\"\n : `Transaction failed: ${normalized.message}`;\n\n this.config.showNotification({\n type: normalized.rejected ? \"notice\" : \"error\",\n iconType: normalized.rejected ? \"transaction\" : \"error\",\n title: normalized.rejected ? \"Transaction Rejected\" : \"Transaction Failed\",\n message: normalized.rejected\n ? \"Transaction was rejected by user.\"\n : normalized.message,\n });\n\n try {\n await this.config.backendApiRef.current.postSystemMessage(\n next.sessionId,\n final\n );\n await this.refreshThreadIfCurrent(next.sessionId, next.threadId);\n } catch (postError) {\n console.error(\"Failed to report wallet tx result to backend:\", postError);\n }\n } finally {\n this.inFlight = false;\n void this.drain();\n }\n }\n\n private async refreshThreadIfCurrent(sessionId: string, threadId: string) {\n if (this.config.getCurrentThreadId() !== threadId) return;\n try {\n const state = await this.config.backendApiRef.current.fetchState(sessionId);\n this.config.applySessionMessagesToThread(threadId, state.messages);\n } catch (refreshError) {\n console.error(\"Failed to refresh state after wallet tx:\", refreshError);\n }\n }\n}\n\n","import type { MutableRefObject } from \"react\";\n\nimport type { BackendApi } from \"../api/client\";\nimport type { Notification } from \"../lib/notification-context\";\nimport type { WalletTxRequestPayload } from \"../utils/wallet\";\nimport type { ThreadMetadata } from \"../state/types\";\nimport { isPlaceholderTitle } from \"./utils\";\nimport type { BakendState } from \"./backend-state\";\nimport { findTempIdForBackendId } from \"./backend-state\";\n\nexport type BackendSystemEvent =\n | { InlineDisplay: unknown }\n | { SystemNotice: string }\n | { SystemError: string }\n | { AsyncUpdate: unknown };\n\ntype EventControllerConfig = {\n backendApiRef: MutableRefObject<BackendApi>;\n backendStateRef: MutableRefObject<BakendState>;\n showNotification: (notification: Omit<Notification, \"id\">) => void;\n handleWalletTxRequest: (\n sessionId: string,\n threadId: string,\n request: WalletTxRequestPayload\n ) => void;\n setThreadMetadata: (\n updater: (prev: Map<string, ThreadMetadata>) => Map<string, ThreadMetadata>\n ) => void;\n};\n\nexport class EventController {\n private lastEventIdBySession = new Map<string, number>();\n private eventsInFlight = new Set<string>();\n private updateSubscriptions = new Map<string, () => void>();\n private subscribableSessionId: string | null = null;\n\n constructor(private readonly config: EventControllerConfig) {}\n\n setSubscribableSessionId(sessionId: string | null) {\n console.log(\"🔔 [updates] setSubscribableSessionId\", { sessionId });\n this.subscribableSessionId = sessionId;\n this.syncSubscriptions();\n }\n\n private syncSubscriptions() {\n console.log(\"🔔 [updates] syncSubscriptions\", {\n subscribableSessionId: this.subscribableSessionId,\n active: Array.from(this.updateSubscriptions.keys()),\n });\n const nextSessions = new Set<string>();\n if (this.subscribableSessionId) {\n nextSessions.add(this.subscribableSessionId);\n }\n\n // Remove subscriptions for sessions no longer needed\n for (const sessionId of this.updateSubscriptions.keys()) {\n if (!nextSessions.has(sessionId)) {\n this.removeSubscription(sessionId);\n }\n }\n\n // Add subscriptions for new sessions\n for (const sessionId of nextSessions) {\n this.ensureSubscription(sessionId);\n }\n }\n\n private ensureSubscription(sessionId: string) {\n if (this.updateSubscriptions.has(sessionId)) return;\n console.log(\"🔔 [updates] ensureSubscription\", { sessionId });\n\n const unsubscribe = this.config.backendApiRef.current.subscribeToUpdates(\n sessionId,\n (update) => {\n console.log(\"🔔 [updates] event_available\", {\n sessionId: update.session_id,\n eventId: update.event_id,\n eventType: update.event_type,\n });\n if (update.type !== \"event_available\") return;\n void this.drainEvents(update.session_id);\n },\n (error) => {\n console.error(\"Failed to handle system update SSE:\", error);\n }\n );\n\n this.updateSubscriptions.set(sessionId, unsubscribe);\n }\n\n private removeSubscription(sessionId: string) {\n const unsubscribe = this.updateSubscriptions.get(sessionId);\n if (!unsubscribe) return;\n unsubscribe();\n this.updateSubscriptions.delete(sessionId);\n }\n\n async drainEvents(sessionId: string) {\n if (this.eventsInFlight.has(sessionId)) {\n console.log(\"⏳ [events] drain already in flight\", { sessionId });\n return;\n }\n this.eventsInFlight.add(sessionId);\n\n try {\n let afterId = this.lastEventIdBySession.get(sessionId) ?? 0;\n console.log(\"📥 [events] start drain\", { sessionId, afterId });\n for (;;) {\n const requestAfterId = afterId;\n const events = await this.config.backendApiRef.current.fetchEventsAfter(\n sessionId,\n requestAfterId,\n 200\n );\n console.log(\"📥 [events] fetched batch\", {\n sessionId,\n afterId: requestAfterId,\n count: events.length,\n });\n if (!events.length) break;\n\n for (const event of events) {\n const eventId =\n typeof event.event_id === \"number\"\n ? event.event_id\n : Number(event.event_id);\n if (Number.isFinite(eventId)) afterId = Math.max(afterId, eventId);\n\n if (event.type === \"title_changed\" && typeof event.new_title === \"string\") {\n console.log(\"🏷️ [events] title_changed\", {\n sessionId,\n eventId,\n newTitle: event.new_title,\n });\n this.applyTitleChanged(sessionId, event.new_title as string);\n }\n\n if (event.type === \"wallet_tx_request\") {\n const payload = (event as unknown as { payload?: unknown }).payload;\n if (payload && typeof payload === \"object\") {\n const req = payload as Record<string, unknown>;\n if (\n typeof req.to === \"string\" &&\n typeof req.value === \"string\" &&\n typeof req.data === \"string\"\n ) {\n const threadId =\n findTempIdForBackendId(\n this.config.backendStateRef.current,\n sessionId\n ) || sessionId;\n this.config.handleWalletTxRequest(\n sessionId,\n threadId,\n req as unknown as WalletTxRequestPayload\n );\n }\n }\n }\n }\n\n // If we hit the limit, keep draining in case more events are waiting.\n if (events.length < 200) break;\n }\n\n console.log(\"📥 [events] drain complete\", { sessionId, afterId });\n this.lastEventIdBySession.set(sessionId, afterId);\n } catch (error) {\n console.error(\"Failed to fetch async events:\", error);\n } finally {\n this.eventsInFlight.delete(sessionId);\n }\n }\n\n private applyTitleChanged(sessionId: string, newTitle: string) {\n const backendState = this.config.backendStateRef.current;\n const tempId = findTempIdForBackendId(backendState, sessionId);\n const threadIdToUpdate = tempId || sessionId;\n\n console.log(\"🏷️ [title] applying\", {\n sessionId,\n threadId: threadIdToUpdate,\n newTitle,\n });\n this.config.setThreadMetadata((prev) => {\n const next = new Map(prev);\n const existing = next.get(threadIdToUpdate);\n const normalizedTitle = isPlaceholderTitle(newTitle) ? \"\" : newTitle;\n const nextStatus = existing?.status === \"archived\" ? \"archived\" : \"regular\";\n next.set(threadIdToUpdate, {\n title: normalizedTitle,\n status: nextStatus,\n lastActiveAt: existing?.lastActiveAt ?? new Date().toISOString(),\n });\n return next;\n });\n\n if (!isPlaceholderTitle(newTitle) && backendState.creatingThreadId === threadIdToUpdate) {\n backendState.creatingThreadId = null;\n }\n }\n\n handleBackendSystemEvents(\n sessionId: string,\n threadId: string,\n rawEvents?: unknown[] | null\n ) {\n if (!rawEvents?.length) return;\n\n for (const raw of rawEvents) {\n const parsed = this.parseBackendSystemEvent(raw);\n if (!parsed) continue;\n\n if (\"InlineDisplay\" in parsed) {\n const payload = parsed.InlineDisplay;\n if (!payload || typeof payload !== \"object\") continue;\n const type = (payload as Record<string, unknown>).type;\n if (type !== \"wallet_tx_request\") continue;\n const requestValue = (payload as Record<string, unknown>).payload;\n if (!requestValue || typeof requestValue !== \"object\") continue;\n const req = requestValue as Record<string, unknown>;\n if (\n typeof req.to !== \"string\" ||\n typeof req.value !== \"string\" ||\n typeof req.data !== \"string\"\n ) {\n continue;\n }\n this.config.handleWalletTxRequest(\n sessionId,\n threadId,\n req as unknown as WalletTxRequestPayload\n );\n }\n\n if (\"SystemError\" in parsed) {\n this.config.showNotification({\n type: \"error\",\n iconType: \"error\",\n title: \"Error\",\n message: parsed.SystemError,\n });\n }\n\n if (\"SystemNotice\" in parsed) {\n this.config.showNotification({\n type: \"notice\",\n iconType: \"notice\",\n title: \"Notice\",\n message: parsed.SystemNotice,\n });\n }\n }\n }\n\n private parseBackendSystemEvent(value: unknown): BackendSystemEvent | null {\n if (!value || typeof value !== \"object\") return null;\n const entries = Object.entries(value as Record<string, unknown>);\n if (entries.length !== 1) return null;\n const [key, payload] = entries[0];\n switch (key) {\n case \"InlineDisplay\":\n return { InlineDisplay: payload };\n case \"SystemNotice\":\n return {\n SystemNotice: typeof payload === \"string\" ? payload : String(payload),\n };\n case \"SystemError\":\n return {\n SystemError: typeof payload === \"string\" ? payload : String(payload),\n };\n case \"AsyncUpdate\":\n return { AsyncUpdate: payload };\n default:\n return null;\n }\n }\n\n cleanup() {\n for (const unsubscribe of this.updateSubscriptions.values()) {\n unsubscribe();\n }\n this.updateSubscriptions.clear();\n }\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","parseTimestamp","import_react","import_jsx_runtime","import_react","txHash","import_jsx_runtime","parseTimestamp","_a"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/backend/sse.ts","../src/backend/client.ts","../src/runtime/aomi-runtime.tsx","../src/contexts/event-context.tsx","../src/backend/types.ts","../src/state/event-buffer.ts","../src/contexts/notification-context.tsx","../src/contexts/thread-context.tsx","../src/state/thread-store.ts","../src/contexts/user-context.tsx","../src/runtime/core.tsx","../src/runtime/orchestrator.ts","../src/runtime/utils.ts","../src/state/backend-state.ts","../src/runtime/message-controller.ts","../src/runtime/polling-controller.ts","../src/runtime/threadlist-adapter.ts","../src/interface.tsx","../src/handlers/wallet-handler.ts","../src/handlers/notification-handler.ts"],"sourcesContent":["// =============================================================================\n// Backend API Client\n// =============================================================================\nexport { BackendApi } from \"./backend/client\";\nexport type {\n AomiMessage,\n ApiChatResponse,\n ApiCreateThreadResponse,\n ApiInterruptResponse,\n ApiSSEEvent,\n ApiStateResponse,\n ApiSystemEvent,\n ApiSystemResponse,\n ApiThread,\n} from \"./backend/types\";\n\n// =============================================================================\n// Runtime Provider\n// =============================================================================\nexport { AomiRuntimeProvider } from \"./runtime/aomi-runtime\";\nexport type { AomiRuntimeProviderProps } from \"./runtime/aomi-runtime\";\n\n// =============================================================================\n// Unified Runtime API\n// =============================================================================\nexport { useAomiRuntime } from \"./interface\";\nexport type { AomiRuntimeApi } from \"./interface\";\n\n// =============================================================================\n// Event System (follows RUNTIME-ARCH.md)\n// =============================================================================\nexport {\n useEventContext,\n EventContextProvider,\n} from \"./contexts/event-context\";\nexport type {\n EventContext,\n EventContextProviderProps,\n} from \"./contexts/event-context\";\n\nexport type {\n InboundEvent,\n OutboundEvent,\n SSEStatus,\n EventSubscriber,\n EventBuffer,\n} from \"./state/event-buffer\";\n\n// =============================================================================\n// Handler Hooks\n// =============================================================================\nexport { useWalletHandler } from \"./handlers/wallet-handler\";\nexport { useNotificationHandler } from \"./handlers/notification-handler\";\nexport type {\n WalletTxRequest,\n WalletTxComplete,\n WalletConnectionStatus,\n WalletHandlerConfig,\n WalletHanderApi,\n} from \"./handlers/wallet-handler\";\nexport type {\n Notification as HandlerNotification,\n NotificationHandlerConfig,\n NotificationApi,\n} from \"./handlers/notification-handler\";\n\n// =============================================================================\n// User Context (wallet/user state)\n// =============================================================================\nexport {\n useUser,\n UserContextProvider,\n type UserState,\n} from \"./contexts/user-context\";\n\n// Backwards compatibility alias\nexport type { UserState as WalletButtonState } from \"./contexts/user-context\";\n\n// User config type (for render prop pattern)\nexport type { UserConfig } from \"./runtime/utils\";\n\n// =============================================================================\n// Thread Context (for UI components)\n// =============================================================================\nexport {\n useThreadContext,\n useCurrentThreadMessages,\n useCurrentThreadMetadata,\n ThreadContextProvider,\n} from \"./contexts/thread-context\";\nexport type { ThreadContext } from \"./contexts/thread-context\";\nexport type { ThreadMetadata } from \"./state/thread-store\";\n\n// =============================================================================\n// Utilities\n// =============================================================================\nexport { cn, formatAddress, getNetworkName } from \"./runtime/utils\";\n\n// =============================================================================\n// Notification Context (for toast UI)\n// =============================================================================\nexport {\n useNotification,\n NotificationContextProvider,\n type Notification,\n type NotificationType,\n type NotificationData as ShowNotificationParams,\n type NotificationContextApi as NotificationContextValue,\n type NotificationContextProviderProps,\n} from \"./contexts/notification-context\";\n","import type { ApiSSEEvent } from \"./types\";\n\nexport type SseSubscriber = {\n subscribe: (\n sessionId: string,\n onUpdate: (event: ApiSSEEvent) => void,\n onError?: (error: unknown) => void,\n ) => () => void;\n};\n\ntype SseSubscriberOptions = {\n backendUrl: string;\n getHeaders: (sessionId: string) => HeadersInit;\n shouldLog?: boolean;\n};\n\ntype SseSubscription = {\n abortController: AbortController | null;\n retries: number;\n retryTimer: ReturnType<typeof setTimeout> | null;\n stopped: boolean;\n listeners: Set<SseListener>;\n stop: (reason?: string) => void;\n};\n\ntype SseListener = {\n onUpdate: (event: ApiSSEEvent) => void;\n onError?: (error: unknown) => void;\n};\n\nfunction extractSseData(rawEvent: string): string | null {\n const dataLines = rawEvent\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"data:\"))\n .map((line) => line.slice(5).trimStart());\n if (!dataLines.length) return null;\n return dataLines.join(\"\\n\");\n}\n\nasync function readSseStream(\n stream: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n onMessage: (data: string) => void,\n): Promise<void> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (!signal.aborted) {\n const { value, done } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n buffer = buffer.replace(/\\r/g, \"\");\n\n let separatorIndex = buffer.indexOf(\"\\n\\n\");\n while (separatorIndex >= 0) {\n const rawEvent = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + 2);\n const data = extractSseData(rawEvent);\n if (data) {\n onMessage(data);\n }\n separatorIndex = buffer.indexOf(\"\\n\\n\");\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function createSseSubscriber({\n backendUrl,\n getHeaders,\n shouldLog = process.env.NODE_ENV !== \"production\",\n}: SseSubscriberOptions): SseSubscriber {\n const subscriptions = new Map<string, SseSubscription>();\n\n const subscribe: SseSubscriber[\"subscribe\"] = (\n sessionId,\n onUpdate,\n onError,\n ) => {\n const existing = subscriptions.get(sessionId);\n const listener: SseListener = { onUpdate, onError };\n if (existing) {\n existing.listeners.add(listener);\n if (shouldLog) {\n console.debug(\"[aomi][sse] listener added\", {\n sessionId,\n listeners: existing.listeners.size,\n });\n }\n return () => {\n existing.listeners.delete(listener);\n if (shouldLog) {\n console.debug(\"[aomi][sse] listener removed\", {\n sessionId,\n listeners: existing.listeners.size,\n });\n }\n if (existing.listeners.size === 0) {\n existing.stop(\"unsubscribe\");\n if (subscriptions.get(sessionId) === existing) {\n subscriptions.delete(sessionId);\n }\n }\n };\n }\n\n const subscription: SseSubscription = {\n abortController: null,\n retries: 0,\n retryTimer: null,\n stopped: false,\n listeners: new Set([listener]),\n stop: (reason?: string) => {\n subscription.stopped = true;\n if (subscription.retryTimer) {\n clearTimeout(subscription.retryTimer);\n subscription.retryTimer = null;\n }\n subscription.abortController?.abort();\n subscription.abortController = null;\n if (shouldLog) {\n console.debug(\"[aomi][sse] stop\", {\n sessionId,\n reason,\n retries: subscription.retries,\n });\n }\n },\n };\n\n const scheduleRetry = () => {\n if (subscription.stopped) return;\n subscription.retries += 1;\n const delayMs = Math.min(500 * 2 ** (subscription.retries - 1), 10000);\n if (shouldLog) {\n console.debug(\"[aomi][sse] retry scheduled\", {\n sessionId,\n delayMs,\n retries: subscription.retries,\n });\n }\n subscription.retryTimer = setTimeout(() => {\n void open();\n }, delayMs);\n };\n\n const open = async () => {\n if (subscription.stopped) return;\n if (subscription.retryTimer) {\n clearTimeout(subscription.retryTimer);\n subscription.retryTimer = null;\n }\n\n const controller = new AbortController();\n subscription.abortController = controller;\n const openedAt = Date.now();\n\n try {\n const response = await fetch(`${backendUrl}/api/updates`, {\n headers: getHeaders(sessionId),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(\n `SSE HTTP ${response.status}: ${response.statusText}`,\n );\n }\n\n if (!response.body) {\n throw new Error(\"SSE response missing body\");\n }\n\n subscription.retries = 0;\n\n await readSseStream(response.body, controller.signal, (data) => {\n let parsed: ApiSSEEvent;\n try {\n parsed = JSON.parse(data) as ApiSSEEvent;\n } catch (error) {\n for (const item of subscription.listeners) {\n item.onError?.(error);\n }\n return;\n }\n\n for (const item of subscription.listeners) {\n try {\n item.onUpdate(parsed);\n } catch (error) {\n item.onError?.(error);\n }\n }\n });\n if (shouldLog) {\n console.debug(\"[aomi][sse] stream ended\", {\n sessionId,\n aborted: controller.signal.aborted,\n stopped: subscription.stopped,\n durationMs: Date.now() - openedAt,\n });\n }\n } catch (error) {\n if (!controller.signal.aborted && !subscription.stopped) {\n for (const item of subscription.listeners) {\n item.onError?.(error);\n }\n }\n }\n\n if (!subscription.stopped) {\n scheduleRetry();\n }\n };\n\n subscriptions.set(sessionId, subscription);\n void open();\n\n return () => {\n subscription.listeners.delete(listener);\n if (shouldLog) {\n console.debug(\"[aomi][sse] listener removed\", {\n sessionId,\n listeners: subscription.listeners.size,\n });\n }\n if (subscription.listeners.size === 0) {\n subscription.stop(\"unsubscribe\");\n if (subscriptions.get(sessionId) === subscription) {\n subscriptions.delete(sessionId);\n }\n }\n };\n };\n\n return { subscribe };\n}\n","import type {\n ApiChatResponse,\n ApiCreateThreadResponse,\n ApiInterruptResponse,\n ApiSSEEvent,\n ApiStateResponse,\n ApiSystemEvent,\n ApiSystemResponse,\n ApiThread,\n} from \"./types\";\nimport { createSseSubscriber, type SseSubscriber } from \"./sse\";\nimport type { UserState } from \"../contexts/user-context\";\n\nconst SESSION_ID_HEADER = \"X-Session-Id\";\n\nfunction toQueryString(payload: Record<string, unknown>): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(payload)) {\n if (value === undefined || value === null) continue;\n params.set(key, String(value));\n }\n const qs = params.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nfunction withSessionHeader(sessionId: string, init?: HeadersInit): HeadersInit {\n const headers = new Headers(init);\n headers.set(SESSION_ID_HEADER, sessionId);\n return headers;\n}\n\nasync function postState<T>(\n backendUrl: string,\n path: string,\n payload: Record<string, unknown>,\n sessionId: string,\n): Promise<T> {\n const query = toQueryString(payload);\n const url = `${backendUrl}${path}${query}`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as T;\n}\n\nexport class BackendApi {\n private sseSubscriber: SseSubscriber;\n\n constructor(private readonly backendUrl: string) {\n this.sseSubscriber = createSseSubscriber({\n backendUrl,\n getHeaders: (sessionId) =>\n withSessionHeader(sessionId, { Accept: \"text/event-stream\" }),\n });\n }\n\n async fetchState(\n sessionId: string,\n userState?: UserState,\n ): Promise<ApiStateResponse> {\n const url = new URL(\"/api/state\", this.backendUrl);\n if (userState) {\n url.searchParams.set(\"user_state\", JSON.stringify(userState));\n }\n\n const response = await fetch(url.toString(), {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as ApiStateResponse;\n }\n\n async postChatMessage(\n sessionId: string,\n message: string,\n publicKey?: string,\n ): Promise<ApiChatResponse> {\n return postState<ApiChatResponse>(\n this.backendUrl,\n \"/api/chat\",\n {\n message,\n public_key: publicKey,\n },\n sessionId,\n );\n }\n\n async postSystemMessage(\n sessionId: string,\n message: string,\n ): Promise<ApiSystemResponse> {\n return postState<ApiSystemResponse>(\n this.backendUrl,\n \"/api/system\",\n {\n message,\n },\n sessionId,\n );\n }\n\n async postInterrupt(sessionId: string): Promise<ApiInterruptResponse> {\n return postState<ApiInterruptResponse>(\n this.backendUrl,\n \"/api/interrupt\",\n {},\n sessionId,\n );\n }\n\n /**\n * Subscribe to SSE updates for a session.\n * Uses fetch streaming and reconnects on disconnects.\n * Returns an unsubscribe function.\n */\n subscribeSSE(\n sessionId: string,\n onUpdate: (event: ApiSSEEvent) => void,\n onError?: (error: unknown) => void,\n ): () => void {\n return this.sseSubscriber.subscribe(sessionId, onUpdate, onError);\n }\n\n async fetchThreads(publicKey: string): Promise<ApiThread[]> {\n const url = `${this.backendUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch threads: HTTP ${response.status}`);\n }\n\n return (await response.json()) as ApiThread[];\n }\n\n async fetchThread(sessionId: string): Promise<ApiThread> {\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n const response = await fetch(url, {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as ApiThread;\n }\n\n async createThread(\n threadId: string,\n publicKey?: string,\n ): Promise<ApiCreateThreadResponse> {\n const body: Record<string, string> = {};\n if (publicKey) body.public_key = publicKey;\n\n const url = `${this.backendUrl}/api/sessions`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: withSessionHeader(threadId, {\n \"Content-Type\": \"application/json\",\n }),\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create thread: HTTP ${response.status}`);\n }\n\n return (await response.json()) as ApiCreateThreadResponse;\n }\n\n async archiveThread(sessionId: string): Promise<void> {\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to archive thread: HTTP ${response.status}`);\n }\n }\n\n async unarchiveThread(sessionId: string): Promise<void> {\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to unarchive thread: HTTP ${response.status}`);\n }\n }\n\n async deleteThread(sessionId: string): Promise<void> {\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n const response = await fetch(url, {\n method: \"DELETE\",\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to delete thread: HTTP ${response.status}`);\n }\n }\n\n async renameThread(sessionId: string, newTitle: string): Promise<void> {\n const url = `${this.backendUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n const response = await fetch(url, {\n method: \"PATCH\",\n headers: withSessionHeader(sessionId, {\n \"Content-Type\": \"application/json\",\n }),\n body: JSON.stringify({ title: newTitle }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to rename thread: HTTP ${response.status}`);\n }\n }\n\n async getSystemEvents(\n sessionId: string,\n count?: number,\n ): Promise<ApiSystemEvent[]> {\n const url = new URL(\"/api/events\", this.backendUrl);\n if (count !== undefined) {\n url.searchParams.set(\"count\", String(count));\n }\n const response = await fetch(url.toString(), {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n if (response.status === 404) return [];\n throw new Error(`Failed to get system events: HTTP ${response.status}`);\n }\n\n return (await response.json()) as ApiSystemEvent[];\n }\n\n // fetchEventsAfter removed: /api/events only supports count now\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { BackendApi } from \"../backend/client\";\nimport { EventContextProvider } from \"../contexts/event-context\";\nimport { NotificationContextProvider } from \"../contexts/notification-context\";\nimport {\n ThreadContextProvider,\n useThreadContext,\n} from \"../contexts/thread-context\";\nimport { UserContextProvider } from \"../contexts/user-context\";\nimport { AomiRuntimeCore } from \"./core\";\n\n// =============================================================================\n// Props\n// =============================================================================\n\nexport type AomiRuntimeProviderProps = {\n children: ReactNode;\n backendUrl?: string;\n};\n\n// =============================================================================\n// Provider Shell\n// =============================================================================\n\nexport function AomiRuntimeProvider({\n children,\n backendUrl = \"http://localhost:8080\",\n}: Readonly<AomiRuntimeProviderProps>) {\n const backendApi = useMemo(() => new BackendApi(backendUrl), [backendUrl]);\n\n return (\n <ThreadContextProvider>\n <NotificationContextProvider>\n <UserContextProvider>\n <AomiRuntimeInner backendApi={backendApi}>\n {children}\n </AomiRuntimeInner>\n </UserContextProvider>\n </NotificationContextProvider>\n </ThreadContextProvider>\n );\n}\n\n// =============================================================================\n// Inner Provider (needs ThreadContext)\n// =============================================================================\n\ntype AomiRuntimeInnerProps = {\n children: ReactNode;\n backendApi: BackendApi;\n};\n\nfunction AomiRuntimeInner({\n children,\n backendApi,\n}: Readonly<AomiRuntimeInnerProps>) {\n const threadContext = useThreadContext();\n\n return (\n <EventContextProvider\n backendApi={backendApi}\n sessionId={threadContext.currentThreadId}\n >\n <AomiRuntimeCore backendApi={backendApi}>{children}</AomiRuntimeCore>\n </EventContextProvider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport type { BackendApi } from \"../backend/client\";\nimport type { ApiSSEEvent, ApiSystemEvent } from \"../backend/types\";\nimport {\n isInlineCall,\n isSystemNotice,\n isSystemError,\n isAsyncCallback,\n} from \"../backend/types\";\nimport {\n createEventBuffer,\n dispatch,\n enqueueInbound,\n setSSEStatus,\n subscribe as subscribeToBuffer,\n type EventBuffer,\n type EventSubscriber,\n type InboundEvent,\n type OutboundEvent,\n type SSEStatus,\n} from \"../state/event-buffer\";\n// =============================================================================\n// Context Type\n// =============================================================================\n\nexport type EventContext = {\n /** Subscribe to inbound events by type. Returns unsubscribe function. */\n subscribe: (type: string, callback: EventSubscriber) => () => void;\n /** Send an outbound event to backend immediately */\n sendOutboundSystem: (event: Omit<OutboundEvent, \"timestamp\">) => void;\n /** Dispatch system events from HTTP polling into the event buffer */\n dispatchInboundSystem: (sessionId: string, events: ApiSystemEvent[]) => void;\n /** Current SSE connection status */\n sseStatus: SSEStatus;\n};\n\nconst EventContextState = createContext<EventContext | null>(null);\n\n// =============================================================================\n// Hook\n// =============================================================================\n\nexport function useEventContext(): EventContext {\n const context = useContext(EventContextState);\n if (!context) {\n throw new Error(\n \"useEventContext must be used within EventContextProvider. \" +\n \"Wrap your app with <EventContextProvider>...</EventContextProvider>\",\n );\n }\n return context;\n}\n\n// =============================================================================\n// Provider Props\n// =============================================================================\n\nexport type EventContextProviderProps = {\n children: ReactNode;\n backendApi: BackendApi;\n sessionId: string;\n};\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nexport function EventContextProvider({\n children,\n backendApi,\n sessionId,\n}: EventContextProviderProps) {\n const bufferRef = useRef<EventBuffer | null>(null);\n if (!bufferRef.current) {\n bufferRef.current = createEventBuffer();\n }\n const buffer = bufferRef.current!;\n\n const [sseStatus, setSseStatus] = useState<SSEStatus>(\"disconnected\");\n\n // ---------------------------------------------------------------------------\n // SSE Subscription (reconnects when sessionId changes)\n // ---------------------------------------------------------------------------\n useEffect(() => {\n setSSEStatus(buffer, \"connecting\");\n setSseStatus(\"connecting\");\n\n const unsubscribe = backendApi.subscribeSSE(\n sessionId,\n (event: ApiSSEEvent) => {\n enqueueInbound(buffer, {\n type: event.type,\n sessionId: event.session_id,\n payload: event,\n });\n\n const inboundEvent: InboundEvent = {\n type: event.type,\n sessionId: event.session_id,\n payload: event,\n status: \"fetched\",\n timestamp: Date.now(),\n };\n dispatch(buffer, inboundEvent);\n },\n (error) => {\n console.error(\"SSE error:\", error);\n setSSEStatus(buffer, \"disconnected\");\n setSseStatus(\"disconnected\");\n },\n );\n\n setSSEStatus(buffer, \"connected\");\n setSseStatus(\"connected\");\n\n return () => {\n unsubscribe();\n setSSEStatus(buffer, \"disconnected\");\n setSseStatus(\"disconnected\");\n };\n }, [backendApi, sessionId, buffer]);\n\n // ---------------------------------------------------------------------------\n // Context Value\n // ---------------------------------------------------------------------------\n const subscribeCallback = useCallback(\n (type: string, callback: EventSubscriber) => {\n return subscribeToBuffer(buffer, type, callback);\n },\n [buffer],\n );\n\n const sendOutbound = useCallback(\n async (event: Omit<OutboundEvent, \"timestamp\">) => {\n try {\n const message = JSON.stringify({\n type: event.type,\n payload: event.payload,\n });\n await backendApi.postSystemMessage(event.sessionId, message);\n } catch (error) {\n console.error(\"Failed to send outbound event:\", error);\n }\n },\n [backendApi],\n );\n\n const dispatchSystemEvents = useCallback(\n (sessionId: string, events: ApiSystemEvent[]) => {\n for (const event of events) {\n let eventType: string;\n let payload: unknown;\n\n // Unwrap the tagged enum from backend serialization\n if (isInlineCall(event)) {\n // InlineCall has inner type like \"wallet_tx_request\"\n eventType = event.InlineCall.type;\n payload = event.InlineCall.payload ?? event.InlineCall;\n } else if (isSystemNotice(event)) {\n eventType = \"system_notice\";\n payload = { message: event.SystemNotice };\n } else if (isSystemError(event)) {\n eventType = \"system_error\";\n payload = { message: event.SystemError };\n } else if (isAsyncCallback(event)) {\n eventType = \"async_callback\";\n payload = event.AsyncCallback;\n } else {\n console.warn(\"Unknown system event type:\", event);\n continue;\n }\n\n const inboundEvent: InboundEvent = {\n type: eventType,\n sessionId,\n payload,\n status: \"fetched\",\n timestamp: Date.now(),\n };\n enqueueInbound(buffer, {\n type: eventType,\n sessionId,\n payload,\n });\n dispatch(buffer, inboundEvent);\n }\n },\n [buffer],\n );\n\n const contextValue: EventContext = {\n subscribe: subscribeCallback,\n sendOutboundSystem: sendOutbound,\n dispatchInboundSystem: dispatchSystemEvents,\n sseStatus,\n };\n\n return (\n <EventContextState.Provider value={contextValue}>\n {children}\n </EventContextState.Provider>\n );\n}\n","// =============================================================================\n// Base Types\n// =============================================================================\n\nexport interface AomiMessage {\n sender?: \"user\" | \"agent\" | \"system\" | string;\n content?: string;\n timestamp?: string;\n is_streaming?: boolean;\n tool_result?: [string, string] | null;\n}\n\n// =============================================================================\n// API Response Types\n// =============================================================================\n\n/**\n * GET /api/state\n * Fetches current session state including messages and processing status\n */\nexport interface ApiStateResponse {\n messages?: AomiMessage[] | null;\n system_events?: ApiSystemEvent[] | null;\n title?: string | null;\n is_processing?: boolean;\n}\n\n/**\n * POST /api/chat\n * Sends a chat message and returns updated session state\n */\nexport interface ApiChatResponse {\n messages?: AomiMessage[] | null;\n system_events?: ApiSystemEvent[] | null;\n title?: string | null;\n is_processing?: boolean;\n}\n\n/**\n * POST /api/system\n * Sends a system message and returns the response message\n */\nexport interface ApiSystemResponse {\n res?: AomiMessage | null;\n}\n\n/**\n * POST /api/interrupt\n * Interrupts current processing and returns updated session state\n */\nexport type ApiInterruptResponse = ApiChatResponse;\n\n/**\n * GET /api/sessions\n * Returns array of ApiThread\n */\nexport interface ApiThread {\n session_id: string;\n title: string;\n is_archived?: boolean;\n}\n\n/**\n * POST /api/sessions\n * Creates a new thread/session\n */\nexport interface ApiCreateThreadResponse {\n session_id: string;\n title?: string;\n}\n\n// =============================================================================\n// SSE Event Types (/api/updates)\n// =============================================================================\n\n/**\n * Base SSE event - all events have session_id and type\n */\nexport type ApiSSEEvent = {\n type:\n | \"title_changed\"\n | \"tool_update\"\n | \"tool_complete\"\n | \"system_notice\"\n | string;\n session_id: string;\n new_title?: string;\n [key: string]: unknown;\n};\n\nexport type ApiSSEEventType =\n | \"title_changed\"\n | \"tool_update\"\n | \"tool_complete\"\n | \"system_notice\";\n\n// =============================================================================\n// System Events (/api/events)\n// =============================================================================\n\n/**\n * Backend SystemEvent enum serializes as tagged JSON:\n * - InlineCall: {\"InlineCall\": {\"type\": \"wallet_tx_request\", \"payload\": {...}}}\n * - SystemNotice: {\"SystemNotice\": \"message\"}\n * - SystemError: {\"SystemError\": \"message\"}\n * - AsyncCallback: {\"AsyncCallback\": {...}} (not sent over HTTP)\n */\nexport type ApiSystemEvent =\n | { InlineCall: { type: string; payload?: unknown; [key: string]: unknown } }\n | { SystemNotice: string }\n | { SystemError: string }\n | { AsyncCallback: Record<string, unknown> };\n\n/**\n * Type guard for InlineCall events\n */\nexport function isInlineCall(\n event: ApiSystemEvent,\n): event is { InlineCall: { type: string; payload?: unknown } } {\n return \"InlineCall\" in event;\n}\n\n/**\n * Type guard for SystemNotice events\n */\nexport function isSystemNotice(\n event: ApiSystemEvent,\n): event is { SystemNotice: string } {\n return \"SystemNotice\" in event;\n}\n\n/**\n * Type guard for SystemError events\n */\nexport function isSystemError(\n event: ApiSystemEvent,\n): event is { SystemError: string } {\n return \"SystemError\" in event;\n}\n\n/**\n * Type guard for AsyncCallback events\n */\nexport function isAsyncCallback(\n event: ApiSystemEvent,\n): event is { AsyncCallback: Record<string, unknown> } {\n return \"AsyncCallback\" in event;\n}\n\n/**\n * Type guard for AsyncCallback events\n */\n","export type InboundEvent = {\n type: string;\n sessionId: string;\n payload?: unknown;\n status: \"pending\" | \"fetched\";\n timestamp: number;\n};\n\nexport type OutboundEvent = {\n type: string;\n sessionId: string;\n payload: unknown;\n timestamp: number;\n};\n\nexport type SSEStatus = \"connected\" | \"connecting\" | \"disconnected\";\n\nexport type EventSubscriber = (event: InboundEvent) => void;\n\nexport type EventBuffer = {\n inboundQueue: InboundEvent[];\n outboundQueue: OutboundEvent[];\n sseStatus: SSEStatus;\n lastEventId: string | null;\n subscribers: Map<string, Set<EventSubscriber>>;\n};\n\nexport function createEventBuffer(): EventBuffer {\n return {\n inboundQueue: [],\n outboundQueue: [],\n sseStatus: \"disconnected\",\n lastEventId: null,\n subscribers: new Map(),\n };\n}\n\n// =============================================================================\n// Inbound Queue Helpers\n// =============================================================================\n\nexport function enqueueInbound(\n state: EventBuffer,\n event: Omit<InboundEvent, \"status\" | \"timestamp\">,\n): void {\n state.inboundQueue.push({\n ...event,\n status: \"pending\",\n timestamp: Date.now(),\n });\n}\n\nexport function dequeueInbound(state: EventBuffer): InboundEvent | null {\n return state.inboundQueue.shift() ?? null;\n}\n\nexport function peekInbound(state: EventBuffer): InboundEvent | null {\n return state.inboundQueue[0] ?? null;\n}\n\nexport function markFetched(\n state: EventBuffer,\n event: InboundEvent,\n payload: unknown,\n): void {\n event.status = \"fetched\";\n event.payload = payload;\n}\n\nexport function hasInbound(state: EventBuffer): boolean {\n return state.inboundQueue.length > 0;\n}\n\n// =============================================================================\n// Outbound Queue Helpers\n// =============================================================================\n\nexport function enqueueOutbound(\n state: EventBuffer,\n event: Omit<OutboundEvent, \"timestamp\">,\n): void {\n state.outboundQueue.push({\n ...event,\n timestamp: Date.now(),\n });\n}\n\nexport function drainOutbound(state: EventBuffer): OutboundEvent[] {\n const events = [...state.outboundQueue];\n state.outboundQueue = [];\n return events;\n}\n\nexport function hasOutbound(state: EventBuffer): boolean {\n return state.outboundQueue.length > 0;\n}\n\n// =============================================================================\n// Subscription Helpers\n// =============================================================================\n\nexport function subscribe(\n state: EventBuffer,\n type: string,\n callback: EventSubscriber,\n): () => void {\n if (!state.subscribers.has(type)) {\n state.subscribers.set(type, new Set());\n }\n state.subscribers.get(type)!.add(callback);\n\n // Return unsubscribe function\n return () => {\n state.subscribers.get(type)?.delete(callback);\n };\n}\n\nexport function subscribeAll(\n state: EventBuffer,\n callback: EventSubscriber,\n): () => void {\n return subscribe(state, \"*\", callback);\n}\n\nexport function dispatch(state: EventBuffer, event: InboundEvent): void {\n // Dispatch to specific type subscribers\n const typeSubscribers = state.subscribers.get(event.type);\n if (typeSubscribers) {\n for (const callback of typeSubscribers) {\n callback(event);\n }\n }\n\n // Dispatch to wildcard subscribers\n const allSubscribers = state.subscribers.get(\"*\");\n if (allSubscribers) {\n for (const callback of allSubscribers) {\n callback(event);\n }\n }\n}\n\n// =============================================================================\n// SSE Status Helpers\n// =============================================================================\n\nexport function setSSEStatus(state: EventBuffer, status: SSEStatus): void {\n state.sseStatus = status;\n}\n\nexport function setLastEventId(state: EventBuffer, id: string): void {\n state.lastEventId = id;\n}\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useState,\n type ReactNode,\n} from \"react\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type NotificationType = \"notice\" | \"success\" | \"error\" | \"wallet\";\n\nexport type Notification = {\n id: string;\n type: NotificationType;\n title: string;\n message?: string;\n duration?: number;\n timestamp: number;\n};\n\nexport type NotificationData = Omit<Notification, \"id\" | \"timestamp\">;\n\nexport type NotificationContextApi = {\n /** All active notifications */\n notifications: Notification[];\n /** Show a new notification */\n showNotification: (params: NotificationData) => string;\n /** Dismiss a notification by ID */\n dismissNotification: (id: string) => void;\n /** Clear all notifications */\n clearAll: () => void;\n};\n\n// =============================================================================\n// Context\n// =============================================================================\n\nconst NotificationContext = createContext<NotificationContextApi | null>(null);\n\n// =============================================================================\n// Hook\n// =============================================================================\n\nexport function useNotification(): NotificationContextApi {\n const context = useContext(NotificationContext);\n if (!context) {\n throw new Error(\n \"useNotification must be used within NotificationContextProvider\",\n );\n }\n return context;\n}\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nlet notificationIdCounter = 0;\nfunction generateId(): string {\n return `notif-${Date.now()}-${++notificationIdCounter}`;\n}\n\nexport type NotificationContextProviderProps = {\n children: ReactNode;\n};\n\nexport function NotificationContextProvider({\n children,\n}: NotificationContextProviderProps) {\n const [notifications, setNotifications] = useState<Notification[]>([]);\n\n const showNotification = useCallback((params: NotificationData) => {\n const id = generateId();\n const notification: Notification = {\n ...params,\n id,\n timestamp: Date.now(),\n };\n setNotifications((prev) => [notification, ...prev]);\n return id;\n }, []);\n\n const dismissNotification = useCallback((id: string) => {\n setNotifications((prev) => prev.filter((n) => n.id !== id));\n }, []);\n\n const clearAll = useCallback(() => {\n setNotifications([]);\n }, []);\n\n const value: NotificationContextApi = {\n notifications,\n showNotification,\n dismissNotification,\n clearAll,\n };\n\n return (\n <NotificationContext.Provider value={value}>\n {children}\n </NotificationContext.Provider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport type { ReactNode, SetStateAction } from \"react\";\nimport type { ThreadMessageLike } from \"@assistant-ui/react\";\nimport { ThreadMetadata, ThreadStore } from \"../state/thread-store\";\n\nexport type ThreadContext = {\n currentThreadId: string;\n setCurrentThreadId: (id: string) => void;\n threadViewKey: number;\n bumpThreadViewKey: () => void;\n allThreads: Map<string, ThreadMessageLike[]>;\n setThreads: (\n updater: SetStateAction<Map<string, ThreadMessageLike[]>>,\n ) => void;\n allThreadsMetadata: Map<string, ThreadMetadata>;\n setThreadMetadata: (\n updater: SetStateAction<Map<string, ThreadMetadata>>,\n ) => void;\n threadCnt: number;\n setThreadCnt: (updater: SetStateAction<number>) => void;\n getThreadMessages: (threadId: string) => ThreadMessageLike[];\n setThreadMessages: (threadId: string, messages: ThreadMessageLike[]) => void;\n getThreadMetadata: (threadId: string) => ThreadMetadata | undefined;\n updateThreadMetadata: (\n threadId: string,\n updates: Partial<ThreadMetadata>,\n ) => void;\n};\n\nexport type ThreadContextProviderProps = {\n children: ReactNode;\n initialThreadId?: string;\n};\n\nconst ThreadContextState = createContext<ThreadContext | null>(null);\n\nexport function useThreadContext(): ThreadContext {\n const context = useContext(ThreadContextState);\n if (!context) {\n throw new Error(\n \"useThreadContext must be used within ThreadContextProvider. \" +\n \"Wrap your app with <ThreadContextProvider>...</ThreadContextProvider>\",\n );\n }\n return context;\n}\n\nexport function ThreadContextProvider({\n children,\n initialThreadId,\n}: ThreadContextProviderProps) {\n const storeRef = useRef<ThreadStore | null>(null);\n if (!storeRef.current) {\n storeRef.current = new ThreadStore({ initialThreadId });\n }\n const store = storeRef.current;\n const value = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n\n return (\n <ThreadContextState.Provider value={value}>\n {children}\n </ThreadContextState.Provider>\n );\n}\n\nexport function useCurrentThreadMessages(): ThreadMessageLike[] {\n const { currentThreadId, getThreadMessages } = useThreadContext();\n return useMemo(\n () => getThreadMessages(currentThreadId),\n [currentThreadId, getThreadMessages],\n );\n}\n\nexport function useCurrentThreadMetadata(): ThreadMetadata | undefined {\n const { currentThreadId, getThreadMetadata } = useThreadContext();\n return useMemo(\n () => getThreadMetadata(currentThreadId),\n [currentThreadId, getThreadMetadata],\n );\n}\n","import type { SetStateAction } from \"react\";\nimport type { ThreadMessageLike } from \"@assistant-ui/react\";\nimport { ThreadContext } from \"../contexts/thread-context\";\n\nconst shouldLogThreadUpdates = process.env.NODE_ENV !== \"production\";\n\nconst logThreadMetadataChange = (\n source: string,\n threadId: string,\n prev: ThreadMetadata | undefined,\n next: ThreadMetadata | undefined,\n) => {\n if (!shouldLogThreadUpdates) return;\n if (!prev && !next) return;\n if (!prev || !next) {\n console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });\n return;\n }\n if (\n prev.title !== next.title ||\n prev.status !== next.status ||\n prev.lastActiveAt !== next.lastActiveAt\n ) {\n console.debug(`[aomi][thread:${source}]`, { threadId, prev, next });\n }\n};\n\nexport type ThreadStatus = \"regular\" | \"archived\" | \"pending\";\n\nexport type ThreadMetadata = {\n title: string;\n status: ThreadStatus;\n lastActiveAt?: string | number;\n};\n\ntype ThreadStoreState = {\n currentThreadId: string;\n threadViewKey: number;\n threadCnt: number;\n threads: Map<string, ThreadMessageLike[]>;\n threadMetadata: Map<string, ThreadMetadata>;\n};\n\ntype ThreadStoreOptions = {\n initialThreadId?: string;\n};\n\nexport class ThreadStore {\n private state: ThreadStoreState;\n private listeners = new Set<() => void>();\n private snapshot: ThreadContext;\n\n constructor(options?: ThreadStoreOptions) {\n const initialThreadId = options?.initialThreadId ?? crypto.randomUUID();\n this.state = {\n currentThreadId: initialThreadId,\n threadViewKey: 0,\n threadCnt: 1,\n threads: new Map([[initialThreadId, []]]),\n threadMetadata: new Map([\n [\n initialThreadId,\n {\n title: \"New Chat\",\n status: \"pending\",\n lastActiveAt: new Date().toISOString(),\n },\n ],\n ]),\n };\n\n this.snapshot = this.buildSnapshot();\n }\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): ThreadContext => this.snapshot;\n\n private emit() {\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n private resolveStateAction<T>(updater: SetStateAction<T>, current: T): T {\n return typeof updater === \"function\"\n ? (updater as (prev: T) => T)(current)\n : updater;\n }\n\n private ensureThreadExists(threadId: string) {\n if (!this.state.threadMetadata.has(threadId)) {\n const nextMetadata = new Map(this.state.threadMetadata);\n nextMetadata.set(threadId, {\n title: \"New Chat\",\n status: \"regular\",\n lastActiveAt: new Date().toISOString(),\n });\n this.state = { ...this.state, threadMetadata: nextMetadata };\n }\n\n if (!this.state.threads.has(threadId)) {\n const nextThreads = new Map(this.state.threads);\n nextThreads.set(threadId, []);\n this.state = { ...this.state, threads: nextThreads };\n }\n }\n\n private updateState(partial: Partial<ThreadStoreState>) {\n this.state = { ...this.state, ...partial };\n this.snapshot = this.buildSnapshot();\n this.emit();\n }\n\n private buildSnapshot(): ThreadContext {\n return {\n currentThreadId: this.state.currentThreadId,\n setCurrentThreadId: this.setCurrentThreadId,\n threadViewKey: this.state.threadViewKey,\n bumpThreadViewKey: this.bumpThreadViewKey,\n allThreads: this.state.threads,\n setThreads: this.setThreads,\n allThreadsMetadata: this.state.threadMetadata,\n setThreadMetadata: this.setThreadMetadata,\n threadCnt: this.state.threadCnt,\n setThreadCnt: this.setThreadCnt,\n getThreadMessages: this.getThreadMessages,\n setThreadMessages: this.setThreadMessages,\n getThreadMetadata: this.getThreadMetadata,\n updateThreadMetadata: this.updateThreadMetadata,\n };\n }\n\n setCurrentThreadId = (threadId: string) => {\n this.ensureThreadExists(threadId);\n this.updateState({ currentThreadId: threadId });\n };\n\n bumpThreadViewKey = () => {\n this.updateState({ threadViewKey: this.state.threadViewKey + 1 });\n };\n\n setThreadCnt = (updater: SetStateAction<number>) => {\n const nextCnt = this.resolveStateAction(updater, this.state.threadCnt);\n this.updateState({ threadCnt: nextCnt });\n };\n\n setThreads = (updater: SetStateAction<Map<string, ThreadMessageLike[]>>) => {\n const nextThreads = this.resolveStateAction(updater, this.state.threads);\n this.updateState({ threads: new Map(nextThreads) });\n };\n\n setThreadMetadata = (\n updater: SetStateAction<Map<string, ThreadMetadata>>,\n ) => {\n const prevMetadata = this.state.threadMetadata;\n const nextMetadata = this.resolveStateAction(updater, prevMetadata);\n for (const [threadId, next] of nextMetadata.entries()) {\n logThreadMetadataChange(\n \"setThreadMetadata\",\n threadId,\n prevMetadata.get(threadId),\n next,\n );\n }\n for (const [threadId, prev] of prevMetadata.entries()) {\n if (!nextMetadata.has(threadId)) {\n logThreadMetadataChange(\"setThreadMetadata\", threadId, prev, undefined);\n }\n }\n this.updateState({ threadMetadata: new Map(nextMetadata) });\n };\n\n setThreadMessages = (threadId: string, messages: ThreadMessageLike[]) => {\n this.ensureThreadExists(threadId);\n const nextThreads = new Map(this.state.threads);\n nextThreads.set(threadId, messages);\n this.updateState({ threads: nextThreads });\n };\n\n getThreadMessages = (threadId: string): ThreadMessageLike[] => {\n return this.state.threads.get(threadId) ?? [];\n };\n\n getThreadMetadata = (threadId: string): ThreadMetadata | undefined => {\n return this.state.threadMetadata.get(threadId);\n };\n\n updateThreadMetadata = (\n threadId: string,\n updates: Partial<ThreadMetadata>,\n ) => {\n const existing = this.state.threadMetadata.get(threadId);\n if (!existing) {\n return;\n }\n const next = { ...existing, ...updates };\n const nextMetadata = new Map(this.state.threadMetadata);\n nextMetadata.set(threadId, next);\n logThreadMetadataChange(\"updateThreadMetadata\", threadId, existing, next);\n this.updateState({ threadMetadata: nextMetadata });\n };\n}\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nexport type UserState = {\n address?: string;\n chainId?: number;\n isConnected: boolean;\n ensName?: string;\n};\n\ntype UserContextValue = {\n user: UserState;\n setUser: (data: Partial<UserState>) => void;\n getUserState: () => UserState;\n onUserStateChange: (callback: (user: UserState) => void) => () => void;\n};\n\nconst UserContext = createContext<UserContextValue | undefined>(undefined);\n\nexport function useUser() {\n const context = useContext(UserContext);\n if (!context) {\n throw new Error(\"useUser must be used within UserContextProvider\");\n }\n // Return only the public API\n return {\n user: context.user,\n setUser: context.setUser,\n getUserState: context.getUserState,\n onUserStateChange: context.onUserStateChange,\n };\n}\n\n// ==================== Provider ====================\n\nexport function UserContextProvider({ children }: { children: ReactNode }) {\n const [user, setUserState] = useState<UserState>({\n isConnected: false,\n address: undefined,\n chainId: undefined,\n ensName: undefined,\n });\n\n // Refs for stable getter functions\n const userRef = useRef(user);\n userRef.current = user;\n\n // Store callbacks in a ref\n const StateChangeCallbacks = useRef<Set<(user: UserState) => void>>(\n new Set(),\n );\n\n const setUser = useCallback((data: Partial<UserState>) => {\n setUserState((prev) => {\n const next = { ...prev, ...data };\n\n // Notify all subscribers\n StateChangeCallbacks.current.forEach((callback) => {\n callback(next);\n });\n\n return next;\n });\n }, []);\n\n // Stable getters that runtime classes can call\n const getUserState = useCallback(() => userRef.current, []);\n\n // Subscribe to user state changes\n const onUserStateChange = useCallback(\n (callback: (user: UserState) => void) => {\n StateChangeCallbacks.current.add(callback);\n\n // Return unsubscribe function\n return () => {\n StateChangeCallbacks.current.delete(callback);\n };\n },\n [],\n );\n\n return (\n <UserContext.Provider\n value={{\n user,\n setUser,\n getUserState,\n onUserStateChange,\n }}\n >\n {children}\n </UserContext.Provider>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport {\n AssistantRuntimeProvider,\n useExternalStoreRuntime,\n type AppendMessage,\n} from \"@assistant-ui/react\";\n\nimport type { BackendApi } from \"../backend/client\";\nimport { useEventContext } from \"../contexts/event-context\";\nimport { useUser } from \"../contexts/user-context\";\nimport { useThreadContext } from \"../contexts/thread-context\";\nimport { useNotification } from \"../contexts/notification-context\";\nimport { useRuntimeOrchestrator } from \"./orchestrator\";\nimport {\n isThreadRunning,\n isThreadReady,\n resolveThreadId,\n} from \"../state/backend-state\";\nimport { isPlaceholderTitle } from \"./utils\";\nimport { buildThreadListAdapter } from \"./threadlist-adapter\";\nimport { AomiRuntimeApiProvider, type AomiRuntimeApi } from \"../interface\";\n\n// =============================================================================\n// Core Props\n// =============================================================================\n\nexport type AomiRuntimeCoreProps = {\n children: ReactNode;\n backendApi: BackendApi;\n};\n\n// =============================================================================\n// Core Component\n// =============================================================================\n\nexport function AomiRuntimeCore({\n children,\n backendApi,\n}: Readonly<AomiRuntimeCoreProps>) {\n const threadContext = useThreadContext();\n const eventContext = useEventContext();\n const notificationContext = useNotification();\n const { dispatchInboundSystem: dispatchSystemEvents } = eventContext;\n const { user, onUserStateChange, getUserState } = useUser();\n\n const {\n backendStateRef,\n polling,\n messageController,\n isRunning,\n setIsRunning,\n ensureInitialState,\n backendApiRef,\n } = useRuntimeOrchestrator(backendApi, {\n onSyncEvents: dispatchSystemEvents,\n getPublicKey: () => getUserState().address,\n getUserState,\n });\n\n // ---------------------------------------------------------------------------\n // Send wallet state changes to backend\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const unsubscribe = onUserStateChange(async (newUser) => {\n const sessionId = threadContext.currentThreadId;\n const message = JSON.stringify({\n type: \"wallet:state_changed\",\n payload: {\n address: newUser.address,\n chainId: newUser.chainId,\n isConnected: newUser.isConnected,\n ensName: newUser.ensName,\n },\n });\n await backendApiRef.current.postSystemMessage(sessionId, message);\n });\n\n return unsubscribe;\n }, [onUserStateChange, backendApiRef, threadContext.currentThreadId]);\n\n // ---------------------------------------------------------------------------\n // Refs for stable access\n // ---------------------------------------------------------------------------\n const threadContextRef = useRef(threadContext);\n threadContextRef.current = threadContext;\n\n const currentThreadIdRef = useRef(threadContext.currentThreadId);\n useEffect(() => {\n currentThreadIdRef.current = threadContext.currentThreadId;\n }, [threadContext.currentThreadId]);\n\n // ---------------------------------------------------------------------------\n // Initial state fetch on thread change\n // ---------------------------------------------------------------------------\n useEffect(() => {\n void ensureInitialState(threadContext.currentThreadId);\n }, [ensureInitialState, threadContext.currentThreadId]);\n\n useEffect(() => {\n const threadId = threadContext.currentThreadId;\n setIsRunning(isThreadRunning(backendStateRef.current, threadId));\n }, [backendStateRef, setIsRunning, threadContext.currentThreadId]);\n\n const currentMessages = threadContext.getThreadMessages(\n threadContext.currentThreadId,\n );\n const resolvedSessionId = useMemo(\n () =>\n resolveThreadId(backendStateRef.current, threadContext.currentThreadId),\n [\n backendStateRef,\n threadContext.currentThreadId,\n threadContext.allThreadsMetadata,\n ],\n );\n\n // ---------------------------------------------------------------------------\n // Fetch thread list when user connects\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const userAddress = user.address;\n if (!userAddress) return;\n\n const fetchThreadList = async () => {\n try {\n const threadList =\n await backendApiRef.current.fetchThreads(userAddress);\n const currentContext = threadContextRef.current;\n const newMetadata = new Map(currentContext.allThreadsMetadata);\n let maxChatNum = currentContext.threadCnt;\n\n for (const thread of threadList) {\n const rawTitle = thread.title ?? \"\";\n const title = isPlaceholderTitle(rawTitle) ? \"\" : rawTitle;\n const lastActive =\n newMetadata.get(thread.session_id)?.lastActiveAt ||\n new Date().toISOString();\n newMetadata.set(thread.session_id, {\n title,\n status: thread.is_archived ? \"archived\" : \"regular\",\n lastActiveAt: lastActive,\n });\n\n const match = title.match(/^Chat (\\d+)$/);\n if (match) {\n const num = parseInt(match[1], 10);\n if (num > maxChatNum) {\n maxChatNum = num;\n }\n }\n }\n\n currentContext.setThreadMetadata(newMetadata);\n if (maxChatNum > currentContext.threadCnt) {\n currentContext.setThreadCnt(maxChatNum);\n }\n } catch (error) {\n console.error(\"Failed to fetch thread list:\", error);\n }\n };\n\n void fetchThreadList();\n }, [user.address, backendApiRef]);\n\n // ---------------------------------------------------------------------------\n // Thread list adapter\n // ---------------------------------------------------------------------------\n const threadListAdapter = useMemo(\n () =>\n buildThreadListAdapter({\n backendStateRef,\n backendApiRef,\n threadContext,\n currentThreadIdRef,\n polling,\n userAddress: user.address,\n setIsRunning,\n }),\n [\n backendApiRef,\n polling,\n user.address,\n backendStateRef,\n setIsRunning,\n threadContext,\n threadContext.currentThreadId,\n threadContext.allThreadsMetadata,\n ],\n );\n\n // ---------------------------------------------------------------------------\n // SSE subscription for title changes\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const backendState = backendStateRef.current;\n const currentSessionId = threadContext.currentThreadId;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[aomi][sse] subscribe\", {\n currentSessionId,\n resolvedSessionId,\n hasMapping: currentSessionId !== resolvedSessionId,\n });\n }\n\n const unsubscribe = backendApiRef.current.subscribeSSE(\n resolvedSessionId,\n (event) => {\n const eventType = event.type as string;\n const sessionId = event.session_id;\n\n if (eventType === \"title_changed\") {\n const newTitle = event.new_title as string;\n const targetThreadId = resolveThreadId(backendState, sessionId);\n const normalizedTitle = isPlaceholderTitle(newTitle) ? \"\" : newTitle;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[aomi][sse] title_changed\", {\n sessionId,\n newTitle,\n normalizedTitle,\n currentThreadId: threadContextRef.current.currentThreadId,\n targetThreadId,\n hasMapping: sessionId !== targetThreadId,\n creatingThreadId: backendState.creatingThreadId,\n });\n }\n\n threadContextRef.current.setThreadMetadata((prev) => {\n const next = new Map(prev);\n const existing = next.get(targetThreadId);\n const nextStatus =\n existing?.status === \"archived\" ? \"archived\" : \"regular\";\n next.set(targetThreadId, {\n title: normalizedTitle,\n status: nextStatus,\n lastActiveAt: existing?.lastActiveAt ?? new Date().toISOString(),\n });\n return next;\n });\n if (\n !isPlaceholderTitle(newTitle) &&\n backendState.creatingThreadId === targetThreadId\n ) {\n backendState.creatingThreadId = null;\n }\n }\n },\n );\n\n return () => {\n unsubscribe?.();\n };\n }, [\n backendApiRef,\n backendStateRef,\n threadContext.currentThreadId,\n resolvedSessionId,\n ]);\n\n // ---------------------------------------------------------------------------\n // Flush pending chat when thread becomes ready\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const threadId = threadContext.currentThreadId;\n if (!isThreadReady(backendStateRef.current, threadId)) return;\n void messageController.flushPendingChat(threadId);\n }, [messageController, backendStateRef, threadContext.currentThreadId]);\n\n // ---------------------------------------------------------------------------\n // Show notifications for tool updates/completions (SSE events)\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const showToolNotification =\n (eventType: \"tool_update\" | \"tool_complete\") =>\n (event: { payload?: unknown }) => {\n const payload = event.payload as Record<string, unknown> | undefined;\n const toolName =\n typeof payload?.tool_name === \"string\"\n ? payload.tool_name\n : undefined;\n const title = toolName\n ? `${eventType === \"tool_update\" ? \"Tool update\" : \"Tool complete\"}: ${toolName}`\n : eventType === \"tool_update\"\n ? \"Tool update\"\n : \"Tool complete\";\n const message =\n typeof payload?.message === \"string\"\n ? payload.message\n : typeof payload?.result === \"string\"\n ? payload.result\n : undefined;\n\n notificationContext.showNotification({\n type: \"notice\",\n title,\n message,\n });\n };\n\n const unsubscribeUpdate = eventContext.subscribe(\n \"tool_update\",\n showToolNotification(\"tool_update\"),\n );\n const unsubscribeComplete = eventContext.subscribe(\n \"tool_complete\",\n showToolNotification(\"tool_complete\"),\n );\n\n return () => {\n unsubscribeUpdate();\n unsubscribeComplete();\n };\n }, [eventContext, notificationContext]);\n\n // ---------------------------------------------------------------------------\n // Show notifications for system notices (SSE events)\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const unsubscribe = eventContext.subscribe(\"system_notice\", (event) => {\n const payload = event.payload as { message?: string } | undefined;\n const message = payload?.message;\n\n notificationContext.showNotification({\n type: \"notice\",\n title: \"System notice\",\n message,\n });\n });\n\n return unsubscribe;\n }, [eventContext, notificationContext]);\n\n // ---------------------------------------------------------------------------\n // External store runtime\n // ---------------------------------------------------------------------------\n const runtime = useExternalStoreRuntime({\n messages: currentMessages,\n setMessages: (msgs) =>\n threadContext.setThreadMessages(threadContext.currentThreadId, [...msgs]),\n isRunning,\n onNew: (message: AppendMessage) =>\n messageController.outbound(message, threadContext.currentThreadId),\n onCancel: () => messageController.cancel(threadContext.currentThreadId),\n convertMessage: (msg) => msg,\n adapters: { threadList: threadListAdapter },\n });\n\n // ---------------------------------------------------------------------------\n // Cleanup polling on unmount\n // ---------------------------------------------------------------------------\n useEffect(() => {\n return () => {\n polling.stopAll();\n };\n }, [polling]);\n\n // ---------------------------------------------------------------------------\n // Build AomiRuntimeApi\n // ---------------------------------------------------------------------------\n const userContext = useUser();\n\n const sendMessage = useCallback(\n async (text: string) => {\n // Build a minimal AppendMessage - the message controller only extracts text from content\n // Using unknown cast because AppendMessage has complex metadata requirements we don't need\n const appendMessage = {\n role: \"user\",\n content: [{ type: \"text\", text }],\n } as unknown as AppendMessage;\n await messageController.outbound(\n appendMessage,\n threadContext.currentThreadId,\n );\n },\n [messageController, threadContext.currentThreadId],\n );\n\n const cancelGeneration = useCallback(() => {\n messageController.cancel(threadContext.currentThreadId);\n }, [messageController, threadContext.currentThreadId]);\n\n const getMessages = useCallback(\n (threadId?: string) => {\n const id = threadId ?? threadContext.currentThreadId;\n return threadContext.getThreadMessages(id);\n },\n [threadContext],\n );\n\n const createThread = useCallback(async (): Promise<string> => {\n await threadListAdapter.onSwitchToNewThread();\n return threadContextRef.current.currentThreadId;\n }, [threadListAdapter]);\n\n const deleteThread = useCallback(\n async (threadId: string) => {\n await threadListAdapter.onDelete(threadId);\n },\n [threadListAdapter],\n );\n\n const renameThread = useCallback(\n async (threadId: string, title: string) => {\n await threadListAdapter.onRename(threadId, title);\n },\n [threadListAdapter],\n );\n\n const archiveThread = useCallback(\n async (threadId: string) => {\n await threadListAdapter.onArchive(threadId);\n },\n [threadListAdapter],\n );\n\n const selectThread = useCallback(\n (threadId: string) => {\n // Check if thread exists\n if (threadContext.allThreadsMetadata.has(threadId)) {\n threadListAdapter.onSwitchToThread(threadId);\n } else {\n // Thread doesn't exist, create a new one\n void threadListAdapter.onSwitchToNewThread();\n }\n },\n [threadContext.allThreadsMetadata, threadListAdapter],\n );\n\n const aomiRuntimeApi: AomiRuntimeApi = useMemo(\n () => ({\n // User API\n user: userContext.user,\n getUserState: userContext.getUserState,\n setUser: userContext.setUser,\n onUserStateChange: userContext.onUserStateChange,\n\n // Thread API\n currentThreadId: threadContext.currentThreadId,\n threadViewKey: threadContext.threadViewKey,\n threadMetadata: threadContext.allThreadsMetadata,\n getThreadMetadata: threadContext.getThreadMetadata,\n createThread,\n deleteThread,\n renameThread,\n archiveThread,\n selectThread,\n\n // Chat API\n isRunning,\n getMessages,\n sendMessage,\n cancelGeneration,\n\n // Notification API\n notifications: notificationContext.notifications,\n showNotification: notificationContext.showNotification,\n dismissNotification: notificationContext.dismissNotification,\n clearAllNotifications: notificationContext.clearAll,\n\n // Event API\n subscribe: eventContext.subscribe,\n sendSystemCommand: eventContext.sendOutboundSystem,\n sseStatus: eventContext.sseStatus,\n }),\n [\n userContext,\n threadContext.currentThreadId,\n threadContext.threadViewKey,\n threadContext.allThreadsMetadata,\n threadContext.getThreadMetadata,\n createThread,\n deleteThread,\n renameThread,\n archiveThread,\n selectThread,\n isRunning,\n getMessages,\n sendMessage,\n cancelGeneration,\n notificationContext,\n eventContext,\n ],\n );\n\n return (\n <AomiRuntimeApiProvider value={aomiRuntimeApi}>\n <AssistantRuntimeProvider runtime={runtime}>\n {children}\n </AssistantRuntimeProvider>\n </AomiRuntimeApiProvider>\n );\n}\n","import type { MutableRefObject } from \"react\";\nimport { useCallback, useRef, useState } from \"react\";\n\nimport type { BackendApi } from \"../backend/client\";\nimport type { AomiMessage, ApiSystemEvent } from \"../backend/types\";\nimport type { UserState } from \"../contexts/user-context\";\nimport {\n useThreadContext,\n type ThreadContext,\n} from \"../contexts/thread-context\";\nimport { MessageController } from \"./message-controller\";\nimport { PollingController } from \"./polling-controller\";\nimport {\n clearSkipInitialFetch,\n createBackendState,\n isThreadReady,\n resolveThreadId,\n shouldSkipInitialFetch,\n type BackendState,\n} from \"../state/backend-state\";\n\ntype OrchestratorOptions = {\n getPublicKey?: () => string | undefined;\n getUserState?: () => UserState;\n onSyncEvents?: (sessionId: string, events: ApiSystemEvent[]) => void;\n};\n\nexport function useRuntimeOrchestrator(\n backendApi: BackendApi,\n options?: OrchestratorOptions,\n) {\n const threadContext = useThreadContext();\n const threadContextRef = useRef<ThreadContext>(threadContext);\n threadContextRef.current = threadContext;\n const backendApiRef = useRef(backendApi);\n backendApiRef.current = backendApi;\n const backendStateRef = useRef<BackendState>(createBackendState());\n\n const [isRunning, setIsRunning] = useState(false);\n\n const messageControllerRef: MutableRefObject<MessageController | null> =\n useRef(null);\n const pollingRef: MutableRefObject<PollingController | null> = useRef(null);\n const pendingFetches = useRef<Set<string>>(new Set());\n\n if (!pollingRef.current) {\n pollingRef.current = new PollingController({\n backendApiRef,\n backendStateRef,\n applyMessages: (threadId: string, msgs?: AomiMessage[] | null) => {\n messageControllerRef.current?.inbound(threadId, msgs);\n },\n onSyncEvents: options?.onSyncEvents,\n getUserState: options?.getUserState,\n onStart: (threadId: string) => {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(true);\n }\n },\n onStop: (threadId: string) => {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n },\n });\n }\n\n if (!messageControllerRef.current) {\n messageControllerRef.current = new MessageController({\n backendApiRef,\n backendStateRef,\n threadContextRef,\n polling: pollingRef.current,\n setGlobalIsRunning: setIsRunning,\n getPublicKey: options?.getPublicKey,\n onSyncEvents: options?.onSyncEvents,\n });\n }\n\n const ensureInitialState = useCallback(async (threadId: string) => {\n const backendState = backendStateRef.current;\n\n if (shouldSkipInitialFetch(backendState, threadId)) {\n clearSkipInitialFetch(backendState, threadId);\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n return;\n }\n\n if (!isThreadReady(backendState, threadId)) {\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n return;\n }\n\n // Skip if already fetching this thread\n if (pendingFetches.current.has(threadId)) return;\n\n const backendThreadId = resolveThreadId(backendState, threadId);\n pendingFetches.current.add(threadId);\n\n try {\n const userState = options?.getUserState?.();\n const state = await backendApiRef.current.fetchState(\n backendThreadId,\n userState,\n );\n messageControllerRef.current?.inbound(threadId, state.messages);\n if (state.system_events?.length && options?.onSyncEvents) {\n options.onSyncEvents(backendThreadId, state.system_events);\n }\n\n if (threadContextRef.current.currentThreadId === threadId) {\n if (state.is_processing) {\n setIsRunning(true);\n pollingRef.current?.start(threadId);\n } else {\n setIsRunning(false);\n }\n }\n } catch (error) {\n console.error(\"Failed to fetch initial state:\", error);\n if (threadContextRef.current.currentThreadId === threadId) {\n setIsRunning(false);\n }\n } finally {\n pendingFetches.current.delete(threadId);\n }\n }, []);\n\n return {\n backendStateRef,\n polling: pollingRef.current!,\n messageController: messageControllerRef.current!,\n isRunning,\n setIsRunning,\n ensureInitialState,\n backendApiRef,\n };\n}\n","import type { ThreadMessageLike } from \"@assistant-ui/react\";\n\nimport type { AomiMessage } from \"../backend/types\";\nimport type { UserState } from \"../contexts/user-context\";\n\nimport { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Utility function to merge Tailwind CSS classes with conflict resolution.\n * Combines clsx for conditional classes and tailwind-merge for deduplication.\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\n// ==================== Thread Utilities ====================\n\nexport const parseTimestamp = (value?: string | number) => {\n if (value === undefined || value === null) return 0;\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? (value < 1e12 ? value * 1000 : value) : 0;\n }\n\n const numeric = Number(value);\n if (!Number.isNaN(numeric)) {\n return numeric < 1e12 ? numeric * 1000 : numeric;\n }\n\n const ts = Date.parse(value);\n return Number.isNaN(ts) ? 0 : ts;\n};\n\nexport const isPlaceholderTitle = (title?: string) => {\n const normalized = title?.trim() ?? \"\";\n return !normalized || normalized.startsWith(\"#[\");\n};\n\n// ==================== Message Conversion ====================\n\ntype MessageContentPart =\n Exclude<ThreadMessageLike[\"content\"], string> extends readonly (infer U)[]\n ? U\n : never;\n\nexport function toInboundMessage(msg: AomiMessage): ThreadMessageLike | null {\n if (msg.sender === \"system\") return null;\n\n const content: MessageContentPart[] = [];\n const role: ThreadMessageLike[\"role\"] =\n msg.sender === \"user\" ? \"user\" : \"assistant\";\n\n if (msg.content) {\n content.push({ type: \"text\" as const, text: msg.content });\n }\n\n const [topic, toolContent] = parseToolPayload(msg) ?? [];\n if (topic && toolContent) {\n content.push({\n type: \"tool-call\" as const,\n toolCallId: `tool_${Date.now()}`,\n toolName: topic,\n args: undefined,\n result: (() => {\n try {\n return JSON.parse(toolContent);\n } catch {\n return { args: toolContent };\n }\n })(),\n });\n }\n\n const threadMessage = {\n role,\n content: (content.length > 0\n ? content\n : [{ type: \"text\" as const, text: \"\" }]) as ThreadMessageLike[\"content\"],\n ...(msg.timestamp && { createdAt: new Date(msg.timestamp) }),\n } satisfies ThreadMessageLike;\n\n return threadMessage;\n}\n\nfunction parseToolPayload(msg: AomiMessage): [string, string] | null {\n return parseToolResult(msg.tool_result);\n}\n\nexport function constructUITool(): string {\n return \"\";\n}\n\nfunction parseMessageTimestamp(timestamp?: string) {\n if (!timestamp) return undefined;\n const parsed = new Date(timestamp);\n return Number.isNaN(parsed.valueOf()) ? undefined : parsed;\n}\n\nfunction parseToolResult(\n toolResult: AomiMessage[\"tool_result\"],\n): [string, string] | null {\n if (!toolResult) return null;\n\n if (Array.isArray(toolResult) && toolResult.length === 2) {\n const [topic, content] = toolResult;\n return [String(topic), String(content ?? \"\")];\n }\n\n return null;\n}\n\n// ==================== Wallet Utilities ====================\n\n/**\n * User configuration props for footer components.\n * Provides user state and setter from UserContext.\n */\nexport type UserConfig = {\n user: UserState;\n setUser: (data: Partial<UserState>) => void;\n};\n\nexport type Eip1193Provider = {\n request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;\n};\n\nexport const getNetworkName = (\n chainId: number | string | undefined,\n): string => {\n if (chainId === undefined) return \"\";\n const id = typeof chainId === \"string\" ? Number(chainId) : chainId;\n switch (id) {\n case 1:\n return \"ethereum\";\n case 137:\n return \"polygon\";\n case 42161:\n return \"arbitrum\";\n case 8453:\n return \"base\";\n case 10:\n return \"optimism\";\n case 11155111:\n return \"sepolia\";\n case 1337:\n case 31337:\n return \"testnet\";\n case 59140:\n return \"linea-sepolia\";\n case 59144:\n return \"linea\";\n default:\n return \"testnet\";\n }\n};\n\nexport const formatAddress = (addr?: string): string =>\n addr ? `${addr.slice(0, 6)}...${addr.slice(-4)}` : \"Connect Wallet\";\n\nexport function normalizeWalletError(error: unknown): {\n rejected: boolean;\n message: string;\n} {\n const e = error as {\n code?: unknown;\n name?: unknown;\n message?: unknown;\n shortMessage?: unknown;\n cause?: unknown;\n };\n const cause = (e?.cause ?? null) as {\n code?: unknown;\n name?: unknown;\n message?: unknown;\n shortMessage?: unknown;\n } | null;\n\n const code =\n (typeof e?.code === \"number\" ? e.code : undefined) ??\n (typeof cause?.code === \"number\" ? cause.code : undefined);\n const name =\n (typeof e?.name === \"string\" ? e.name : undefined) ??\n (typeof cause?.name === \"string\" ? cause.name : undefined);\n const msg =\n (typeof e?.shortMessage === \"string\" ? e.shortMessage : undefined) ??\n (typeof cause?.shortMessage === \"string\"\n ? cause.shortMessage\n : undefined) ??\n (typeof e?.message === \"string\" ? e.message : undefined) ??\n (typeof cause?.message === \"string\" ? cause.message : undefined) ??\n \"Unknown wallet error\";\n\n const rejected =\n code === 4001 ||\n name === \"UserRejectedRequestError\" ||\n name === \"RejectedRequestError\" ||\n /user rejected|rejected the request|denied|request rejected|canceled|cancelled/i.test(\n msg,\n );\n\n return { rejected, message: msg };\n}\n\nexport function toHexQuantity(value: string): string {\n const trimmed = value.trim();\n const asBigInt = BigInt(trimmed);\n return `0x${asBigInt.toString(16)}`;\n}\n\nexport async function pickInjectedProvider(\n publicKey?: string,\n): Promise<Eip1193Provider | undefined> {\n const ethereum = (globalThis as unknown as { ethereum?: unknown })\n .ethereum as (Eip1193Provider & { providers?: unknown[] }) | undefined;\n if (!ethereum?.request) return undefined;\n\n const candidates: Eip1193Provider[] = Array.isArray(ethereum.providers)\n ? (ethereum.providers.filter(\n (p): p is Eip1193Provider => !!(p as Eip1193Provider)?.request,\n ) as Eip1193Provider[])\n : [ethereum];\n\n const target = publicKey?.toLowerCase();\n if (target) {\n for (const candidate of candidates) {\n try {\n const accounts = (await candidate.request({\n method: \"eth_accounts\",\n })) as unknown;\n const list = Array.isArray(accounts)\n ? (accounts as unknown[]).map((a) => String(a).toLowerCase())\n : [];\n if (list.includes(target)) return candidate;\n } catch {\n // Ignore providers that error on eth_accounts.\n }\n }\n }\n\n return candidates[0];\n}\n","export type BackendState = {\n skipInitialFetch: Set<string>;\n pendingChat: Map<string, string[]>;\n runningThreads: Set<string>;\n creatingThreadId: string | null;\n createThreadPromise: Promise<void> | null;\n};\n\nexport function createBackendState(): BackendState {\n return {\n skipInitialFetch: new Set(),\n pendingChat: new Map(),\n runningThreads: new Set(),\n creatingThreadId: null,\n createThreadPromise: null,\n };\n}\n\nexport function resolveThreadId(state: BackendState, threadId: string): string {\n return threadId;\n}\n\nexport function isThreadReady(state: BackendState, threadId: string): boolean {\n return state.creatingThreadId !== threadId;\n}\n\nexport function markSkipInitialFetch(state: BackendState, threadId: string) {\n state.skipInitialFetch.add(threadId);\n}\n\nexport function shouldSkipInitialFetch(\n state: BackendState,\n threadId: string,\n): boolean {\n return state.skipInitialFetch.has(threadId);\n}\n\nexport function clearSkipInitialFetch(state: BackendState, threadId: string) {\n state.skipInitialFetch.delete(threadId);\n}\n\nexport function setThreadRunning(\n state: BackendState,\n threadId: string,\n running: boolean,\n) {\n if (running) {\n state.runningThreads.add(threadId);\n } else {\n state.runningThreads.delete(threadId);\n }\n}\n\nexport function isThreadRunning(\n state: BackendState,\n threadId: string,\n): boolean {\n return state.runningThreads.has(threadId);\n}\n\nexport function enqueuePendingChat(\n state: BackendState,\n threadId: string,\n text: string,\n) {\n const existing = state.pendingChat.get(threadId) ?? [];\n state.pendingChat.set(threadId, [...existing, text]);\n}\n\nexport function dequeuePendingChat(\n state: BackendState,\n threadId: string,\n): string[] {\n const pending = state.pendingChat.get(threadId) ?? [];\n state.pendingChat.delete(threadId);\n return pending;\n}\n\nexport function hasPendingChat(state: BackendState, threadId: string): boolean {\n return (state.pendingChat.get(threadId)?.length ?? 0) > 0;\n}\n","import type { MutableRefObject } from \"react\";\nimport type { AppendMessage, ThreadMessageLike } from \"@assistant-ui/react\";\n\nimport type { BackendApi } from \"../backend/client\";\nimport type { AomiMessage, ApiSystemEvent } from \"../backend/types\";\nimport { toInboundMessage } from \"./utils\";\nimport type { ThreadContext } from \"../contexts/thread-context\";\nimport type { PollingController } from \"./polling-controller\";\nimport {\n dequeuePendingChat,\n enqueuePendingChat,\n hasPendingChat,\n isThreadReady,\n resolveThreadId,\n setThreadRunning,\n type BackendState,\n} from \"../state/backend-state\";\n\ntype MessageControllerConfig = {\n backendApiRef: MutableRefObject<BackendApi>;\n backendStateRef: MutableRefObject<BackendState>;\n threadContextRef: MutableRefObject<ThreadContext>;\n polling: PollingController;\n setGlobalIsRunning?: (running: boolean) => void;\n getPublicKey?: () => string | undefined;\n onSyncEvents?: (sessionId: string, events: ApiSystemEvent[]) => void;\n};\n\ntype ThreadContextApi = Pick<\n ThreadContext,\n \"getThreadMessages\" | \"setThreadMessages\" | \"updateThreadMetadata\"\n>;\n\nexport class MessageController {\n constructor(private readonly config: MessageControllerConfig) {}\n\n inbound(threadId: string, msgs?: AomiMessage[] | null) {\n const backendState = this.config.backendStateRef.current;\n if (!msgs) return;\n if (hasPendingChat(backendState, threadId)) {\n // Avoid overwriting optimistic UI when pending user messages exist.\n return;\n }\n\n const threadMessages: ThreadMessageLike[] = [];\n for (const msg of msgs) {\n const threadMessage = toInboundMessage(msg);\n if (threadMessage) {\n threadMessages.push(threadMessage);\n }\n }\n\n this.getThreadContextApi().setThreadMessages(threadId, threadMessages);\n }\n\n async outbound(message: AppendMessage, threadId: string) {\n const backendState = this.config.backendStateRef.current;\n const text = message.content\n .filter(\n (part): part is Extract<typeof part, { type: \"text\" }> =>\n part.type === \"text\",\n )\n .map(\n (part: Extract<(typeof message.content)[number], { type: \"text\" }>) =>\n part.text,\n )\n .join(\"\\n\");\n\n if (!text) return;\n\n const threadState = this.getThreadContextApi();\n const existingMessages = threadState.getThreadMessages(threadId);\n const userMessage: ThreadMessageLike = {\n role: \"user\",\n content: [{ type: \"text\", text }],\n createdAt: new Date(),\n };\n\n threadState.setThreadMessages(threadId, [...existingMessages, userMessage]);\n threadState.updateThreadMetadata(threadId, {\n lastActiveAt: new Date().toISOString(),\n });\n\n if (!isThreadReady(backendState, threadId)) {\n this.markRunning(threadId, true);\n enqueuePendingChat(backendState, threadId, text);\n return;\n }\n\n const backendThreadId = resolveThreadId(backendState, threadId);\n const publicKey = this.config.getPublicKey?.();\n\n try {\n this.markRunning(threadId, true);\n const response = publicKey\n ? await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n publicKey,\n )\n : await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n );\n\n // Apply the latest messages immediately so sync tool results appear without waiting for polling.\n if (response?.messages) {\n this.inbound(threadId, response.messages);\n }\n\n if (response?.system_events?.length && this.config.onSyncEvents) {\n this.config.onSyncEvents(backendThreadId, response.system_events);\n }\n\n if (response?.is_processing) {\n this.config.polling.start(threadId);\n } else if (!this.config.polling.isPolling(threadId)) {\n this.markRunning(threadId, false);\n }\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n this.markRunning(threadId, false);\n }\n }\n\n async flushPendingChat(threadId: string) {\n const backendState = this.config.backendStateRef.current;\n const pending = dequeuePendingChat(backendState, threadId);\n if (!pending.length) return;\n const backendThreadId = resolveThreadId(backendState, threadId);\n const publicKey = this.config.getPublicKey?.();\n for (const text of pending) {\n try {\n if (publicKey) {\n await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n publicKey,\n );\n } else {\n await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n );\n }\n } catch (error) {\n console.error(\"Failed to send queued message:\", error);\n }\n }\n this.config.polling.start(threadId);\n }\n\n async cancel(threadId: string) {\n const backendState = this.config.backendStateRef.current;\n if (!isThreadReady(backendState, threadId)) return;\n this.config.polling.stop(threadId);\n const backendThreadId = resolveThreadId(backendState, threadId);\n try {\n const response =\n await this.config.backendApiRef.current.postInterrupt(backendThreadId);\n if (response?.messages) {\n this.inbound(threadId, response.messages);\n }\n if (response?.system_events?.length && this.config.onSyncEvents) {\n this.config.onSyncEvents(backendThreadId, response.system_events);\n }\n this.markRunning(threadId, false);\n } catch (error) {\n console.error(\"Failed to cancel:\", error);\n }\n }\n\n private markRunning(threadId: string, running: boolean) {\n setThreadRunning(this.config.backendStateRef.current, threadId, running);\n if (this.config.threadContextRef.current.currentThreadId === threadId) {\n this.config.setGlobalIsRunning?.(running);\n }\n }\n\n private getThreadContextApi(): ThreadContextApi {\n const { getThreadMessages, setThreadMessages, updateThreadMetadata } =\n this.config.threadContextRef.current;\n return { getThreadMessages, setThreadMessages, updateThreadMetadata };\n }\n}\n","import type { MutableRefObject } from \"react\";\n\nimport type { BackendApi } from \"../backend/client\";\nimport type {\n AomiMessage,\n ApiStateResponse,\n ApiSystemEvent,\n} from \"../backend/types\";\nimport type { UserState } from \"../contexts/user-context\";\nimport {\n isThreadReady,\n resolveThreadId,\n setThreadRunning,\n type BackendState,\n} from \"../state/backend-state\";\n\ntype PollingConfig = {\n backendApiRef: MutableRefObject<BackendApi>;\n backendStateRef: MutableRefObject<BackendState>;\n applyMessages: (threadId: string, messages?: AomiMessage[] | null) => void;\n onSyncEvents?: (sessionId: string, events: ApiSystemEvent[]) => void;\n getUserState?: () => UserState;\n onStart?: (threadId: string) => void;\n onStop?: (threadId: string) => void;\n intervalMs?: number;\n};\n\nexport class PollingController {\n private intervals = new Map<string, ReturnType<typeof setInterval>>();\n private intervalMs: number;\n\n constructor(private readonly config: PollingConfig) {\n this.intervalMs = config.intervalMs ?? 500;\n }\n\n start(threadId: string) {\n const backendState = this.config.backendStateRef.current;\n if (!isThreadReady(backendState, threadId)) return;\n if (this.intervals.has(threadId)) return;\n\n const backendThreadId = resolveThreadId(backendState, threadId);\n setThreadRunning(backendState, threadId, true);\n\n const tick = async () => {\n if (!this.intervals.has(threadId)) return;\n\n try {\n console.log(\n \"[PollingController] Fetching state for threadId:\",\n threadId,\n );\n const userState = this.config.getUserState?.();\n const state = await this.config.backendApiRef.current.fetchState(\n backendThreadId,\n userState,\n );\n\n if (!this.intervals.has(threadId)) return;\n\n this.handleState(threadId, state);\n } catch (error) {\n console.error(\"Polling error:\", error);\n this.stop(threadId);\n }\n };\n\n const intervalId = setInterval(tick, this.intervalMs);\n this.intervals.set(threadId, intervalId);\n\n this.config.onStart?.(threadId);\n }\n\n stop(threadId: string) {\n const intervalId = this.intervals.get(threadId);\n if (intervalId) {\n clearInterval(intervalId);\n this.intervals.delete(threadId);\n }\n setThreadRunning(this.config.backendStateRef.current, threadId, false);\n this.config.onStop?.(threadId);\n }\n\n isPolling(threadId: string): boolean {\n return this.intervals.has(threadId);\n }\n\n stopAll() {\n for (const threadId of this.intervals.keys()) {\n this.stop(threadId);\n }\n }\n\n private handleState(threadId: string, state: ApiStateResponse) {\n // Dispatch system events (wallet_tx_request, errors, etc.)\n if (state.system_events?.length && this.config.onSyncEvents) {\n const backendState = this.config.backendStateRef.current;\n const sessionId = resolveThreadId(backendState, threadId);\n this.config.onSyncEvents(sessionId, state.system_events);\n }\n\n this.config.applyMessages(threadId, state.messages);\n\n if (!state.is_processing) {\n this.stop(threadId);\n }\n }\n}\n","import type { MutableRefObject } from \"react\";\nimport type { ExternalStoreThreadData } from \"@assistant-ui/react\";\n\nimport type { BackendApi } from \"../backend/client\";\nimport type { ThreadContext } from \"../contexts/thread-context\";\nimport type { ThreadMetadata } from \"../state/thread-store\";\nimport {\n markSkipInitialFetch,\n type BackendState,\n} from \"../state/backend-state\";\nimport type { PollingController } from \"./polling-controller\";\nimport { isPlaceholderTitle, parseTimestamp } from \"./utils\";\n\n// =============================================================================\n// Thread List Helpers\n// =============================================================================\n\nconst sortByLastActiveDesc = (\n [, metaA]: [string, ThreadMetadata],\n [, metaB]: [string, ThreadMetadata],\n) => {\n const tsA = parseTimestamp(metaA.lastActiveAt);\n const tsB = parseTimestamp(metaB.lastActiveAt);\n return tsB - tsA;\n};\n\nfunction buildThreadLists(threadMetadata: Map<string, ThreadMetadata>) {\n const entries = Array.from(threadMetadata.entries()).filter(\n ([, meta]) => !isPlaceholderTitle(meta.title),\n );\n\n const regularThreads = entries\n .filter(([, meta]) => meta.status !== \"archived\")\n .sort(sortByLastActiveDesc)\n .map(\n ([id, meta]): ExternalStoreThreadData<\"regular\"> => ({\n id,\n title: meta.title || \"New Chat\",\n status: \"regular\",\n }),\n );\n\n const archivedThreads = entries\n .filter(([, meta]) => meta.status === \"archived\")\n .sort(sortByLastActiveDesc)\n .map(\n ([id, meta]): ExternalStoreThreadData<\"archived\"> => ({\n id,\n title: meta.title || \"New Chat\",\n status: \"archived\",\n }),\n );\n\n return { regularThreads, archivedThreads };\n}\n\n// =============================================================================\n// Adapter Builder\n// =============================================================================\n\nexport type ThreadListAdapterConfig = {\n backendStateRef: MutableRefObject<BackendState>;\n backendApiRef: MutableRefObject<BackendApi>;\n threadContext: ThreadContext;\n currentThreadIdRef: MutableRefObject<string>;\n polling: PollingController;\n userAddress?: string;\n setIsRunning: (running: boolean) => void;\n};\n\nexport function buildThreadListAdapter({\n backendStateRef,\n backendApiRef,\n threadContext,\n currentThreadIdRef,\n polling,\n userAddress,\n setIsRunning,\n}: ThreadListAdapterConfig) {\n const backendState = backendStateRef.current;\n const { regularThreads, archivedThreads } = buildThreadLists(\n threadContext.allThreadsMetadata,\n );\n\n const preparePendingThread = (threadId: string) => {\n const previousPendingId = backendState.creatingThreadId;\n if (previousPendingId && previousPendingId !== threadId) {\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n next.delete(previousPendingId);\n return next;\n });\n threadContext.setThreads((prev) => {\n const next = new Map(prev);\n next.delete(previousPendingId);\n return next;\n });\n backendState.pendingChat.delete(previousPendingId);\n backendState.skipInitialFetch.delete(previousPendingId);\n }\n backendState.creatingThreadId = threadId;\n backendState.pendingChat.delete(threadId);\n threadContext.setThreadMetadata((prev) =>\n new Map(prev).set(threadId, {\n title: \"New Chat\",\n status: \"pending\",\n lastActiveAt: new Date().toISOString(),\n }),\n );\n threadContext.setThreadMessages(threadId, []);\n threadContext.setCurrentThreadId(threadId);\n setIsRunning(false);\n threadContext.bumpThreadViewKey();\n };\n\n const findPendingThreadId = () => {\n if (backendState.creatingThreadId) return backendState.creatingThreadId;\n for (const [id, meta] of threadContext.allThreadsMetadata.entries()) {\n if (meta.status === \"pending\") return id;\n }\n return null;\n };\n\n return {\n threadId: threadContext.currentThreadId,\n threads: regularThreads,\n archivedThreads,\n\n onSwitchToNewThread: async () => {\n const pendingId = findPendingThreadId();\n if (pendingId) {\n preparePendingThread(pendingId);\n return;\n }\n\n if (backendState.createThreadPromise) {\n preparePendingThread(\n backendState.creatingThreadId ?? crypto.randomUUID(),\n );\n return;\n }\n\n const threadId = crypto.randomUUID();\n preparePendingThread(threadId);\n\n const createPromise = backendApiRef.current\n .createThread(threadId, userAddress)\n .then(async (newThread) => {\n const uiThreadId = backendState.creatingThreadId ?? threadId;\n const backendId = newThread.session_id;\n\n if (uiThreadId !== backendId) {\n console.warn(\"[aomi][thread] backend id mismatch\", {\n uiThreadId,\n backendId,\n });\n }\n markSkipInitialFetch(backendState, uiThreadId);\n\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n const existing = next.get(uiThreadId);\n const nextStatus =\n existing?.status === \"archived\" ? \"archived\" : \"regular\";\n next.set(uiThreadId, {\n title: existing?.title ?? \"New Chat\",\n status: nextStatus,\n lastActiveAt: existing?.lastActiveAt ?? new Date().toISOString(),\n });\n return next;\n });\n\n if (backendState.creatingThreadId === uiThreadId) {\n backendState.creatingThreadId = null;\n }\n\n const pendingMessages = backendState.pendingChat.get(uiThreadId);\n if (pendingMessages?.length) {\n backendState.pendingChat.delete(uiThreadId);\n for (const text of pendingMessages) {\n try {\n await backendApiRef.current.postChatMessage(backendId, text);\n } catch (error) {\n console.error(\"Failed to send queued message:\", error);\n }\n }\n if (currentThreadIdRef.current === uiThreadId) {\n polling?.start(uiThreadId);\n }\n }\n })\n .catch((error) => {\n console.error(\"Failed to create new thread:\", error);\n const failedId = backendState.creatingThreadId ?? threadId;\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n next.delete(failedId);\n return next;\n });\n threadContext.setThreads((prev) => {\n const next = new Map(prev);\n next.delete(failedId);\n return next;\n });\n if (backendState.creatingThreadId === failedId) {\n backendState.creatingThreadId = null;\n }\n })\n .finally(() => {\n backendState.createThreadPromise = null;\n });\n\n backendState.createThreadPromise = createPromise;\n },\n\n onSwitchToThread: (threadId: string) => {\n threadContext.setCurrentThreadId(threadId);\n },\n\n onRename: async (threadId: string, newTitle: string) => {\n const previousTitle =\n threadContext.getThreadMetadata(threadId)?.title ?? \"\";\n const normalizedTitle = isPlaceholderTitle(newTitle) ? \"\" : newTitle;\n threadContext.updateThreadMetadata(threadId, {\n title: normalizedTitle,\n });\n\n try {\n await backendApiRef.current.renameThread(threadId, newTitle);\n } catch (error) {\n console.error(\"Failed to rename thread:\", error);\n threadContext.updateThreadMetadata(threadId, {\n title: previousTitle,\n });\n }\n },\n\n onArchive: async (threadId: string) => {\n threadContext.updateThreadMetadata(threadId, { status: \"archived\" });\n\n try {\n await backendApiRef.current.archiveThread(threadId);\n } catch (error) {\n console.error(\"Failed to archive thread:\", error);\n threadContext.updateThreadMetadata(threadId, { status: \"regular\" });\n }\n },\n\n onUnarchive: async (threadId: string) => {\n threadContext.updateThreadMetadata(threadId, { status: \"regular\" });\n\n try {\n await backendApiRef.current.unarchiveThread(threadId);\n } catch (error) {\n console.error(\"Failed to unarchive thread:\", error);\n threadContext.updateThreadMetadata(threadId, { status: \"archived\" });\n }\n },\n\n onDelete: async (threadId: string) => {\n try {\n await backendApiRef.current.deleteThread(threadId);\n\n threadContext.setThreadMetadata((prev) => {\n const next = new Map(prev);\n next.delete(threadId);\n return next;\n });\n threadContext.setThreads((prev) => {\n const next = new Map(prev);\n next.delete(threadId);\n return next;\n });\n backendState.pendingChat.delete(threadId);\n backendState.skipInitialFetch.delete(threadId);\n backendState.runningThreads.delete(threadId);\n if (backendState.creatingThreadId === threadId) {\n backendState.creatingThreadId = null;\n }\n\n if (threadContext.currentThreadId === threadId) {\n const firstRegularThread = Array.from(\n threadContext.allThreadsMetadata.entries(),\n ).find(([id, meta]) => meta.status === \"regular\" && id !== threadId);\n\n if (firstRegularThread) {\n threadContext.setCurrentThreadId(firstRegularThread[0]);\n } else {\n const defaultId = \"default-session\";\n threadContext.setThreadMetadata((prev) =>\n new Map(prev).set(defaultId, {\n title: \"New Chat\",\n status: \"regular\",\n lastActiveAt: new Date().toISOString(),\n }),\n );\n threadContext.setThreadMessages(defaultId, []);\n threadContext.setCurrentThreadId(defaultId);\n }\n }\n } catch (error) {\n console.error(\"Failed to delete thread:\", error);\n throw error;\n }\n },\n };\n}\n","\"use client\";\n\nimport { createContext, useContext } from \"react\";\nimport type { ThreadMessageLike } from \"@assistant-ui/react\";\n\nimport type { UserState } from \"./contexts/user-context\";\nimport type { ThreadMetadata } from \"./state/thread-store\";\nimport type {\n EventSubscriber,\n OutboundEvent,\n SSEStatus,\n} from \"./state/event-buffer\";\nimport type {\n Notification,\n NotificationData,\n} from \"./contexts/notification-context\";\n\n// =============================================================================\n// AomiRuntimeApi Type\n// =============================================================================\n\nexport type AomiRuntimeApi = {\n // -------------------------------------------------------------------------\n // USER API\n // -------------------------------------------------------------------------\n /** Current user state (wallet connection, address, chain, etc.) */\n user: UserState;\n /** Get current user state synchronously (useful in callbacks) */\n getUserState: () => UserState;\n /** Update user state (partial updates merged with existing state) */\n setUser: (data: Partial<UserState>) => void;\n /** Subscribe to user state changes. Returns unsubscribe function. */\n onUserStateChange: (callback: (user: UserState) => void) => () => void;\n\n // -------------------------------------------------------------------------\n // THREAD API\n // -------------------------------------------------------------------------\n /** ID of the currently active thread */\n currentThreadId: string;\n /** Key that changes when thread view should remount (use for React key prop) */\n threadViewKey: number;\n /** Metadata for all threads (title, status, lastActiveAt) */\n threadMetadata: Map<string, ThreadMetadata>;\n /** Get metadata for a specific thread */\n getThreadMetadata: (threadId: string) => ThreadMetadata | undefined;\n /** Create a new thread and return its ID */\n createThread: () => Promise<string>;\n /** Delete a thread by ID */\n deleteThread: (threadId: string) => Promise<void>;\n /** Rename a thread */\n renameThread: (threadId: string, title: string) => Promise<void>;\n /** Archive a thread */\n archiveThread: (threadId: string) => Promise<void>;\n /** Switch to a thread. If thread doesn't exist, creates a new one. */\n selectThread: (threadId: string) => void;\n\n // -------------------------------------------------------------------------\n // CHAT API\n // -------------------------------------------------------------------------\n /** Whether the assistant is currently generating a response */\n isRunning: boolean;\n /** Get messages for a thread (defaults to currentThreadId) */\n getMessages: (threadId?: string) => ThreadMessageLike[];\n /** Send a message to the current thread */\n sendMessage: (text: string) => Promise<void>;\n /** Cancel the current generation */\n cancelGeneration: () => void;\n\n // -------------------------------------------------------------------------\n // NOTIFICATION API\n // -------------------------------------------------------------------------\n /** All active notifications */\n notifications: Notification[];\n /** Show a notification. Returns the notification ID. */\n showNotification: (params: NotificationData) => string;\n /** Dismiss a notification by ID */\n dismissNotification: (id: string) => void;\n /** Clear all notifications */\n clearAllNotifications: () => void;\n\n // -------------------------------------------------------------------------\n // EVENT API\n // -------------------------------------------------------------------------\n /** Subscribe to inbound events by type. Returns unsubscribe function. */\n subscribe: (type: string, callback: EventSubscriber) => () => void;\n /** Send a system command to the backend */\n sendSystemCommand: (event: Omit<OutboundEvent, \"timestamp\">) => void;\n /** Current SSE connection status */\n sseStatus: SSEStatus;\n};\n\n// =============================================================================\n// Context\n// =============================================================================\n\nconst AomiRuntimeContext = createContext<AomiRuntimeApi | null>(null);\n\nexport const AomiRuntimeApiProvider = AomiRuntimeContext.Provider;\n\n// =============================================================================\n// Hook\n// =============================================================================\n\n/**\n * Unified hook that provides access to all Aomi runtime APIs.\n *\n * This is the primary way to interact with the Aomi runtime from consumer code.\n * It combines user, thread, chat, notification, and event APIs into a single interface.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const aomi = useAomiRuntime();\n *\n * // User API\n * const { user, setUser } = aomi;\n *\n * // Thread API\n * const { currentThreadId, createThread, selectThread } = aomi;\n *\n * // Chat API\n * const { isRunning, sendMessage, cancelGeneration } = aomi;\n *\n * // Notification API\n * const { showNotification } = aomi;\n *\n * // Event API\n * const { subscribe, sendSystemCommand } = aomi;\n * }\n * ```\n */\nexport function useAomiRuntime(): AomiRuntimeApi {\n const context = useContext(AomiRuntimeContext);\n if (!context) {\n throw new Error(\n \"useAomiRuntime must be used within AomiRuntimeProvider. \" +\n \"Wrap your app with <AomiRuntimeProvider>...</AomiRuntimeProvider>\",\n );\n }\n return context;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useEventContext } from \"../contexts/event-context\";\nimport { useUser } from \"../contexts/user-context\";\nimport type { InboundEvent } from \"../state/event-buffer\";\n\nexport type WalletTxRequest = {\n to: string;\n value?: string;\n data?: string;\n chainId?: number;\n};\n\nexport type WalletTxComplete = {\n txHash: string;\n status: \"success\" | \"failed\";\n amount?: string;\n token?: string;\n};\n\nexport type WalletConnectionStatus = \"connected\" | \"disconnected\";\n\nexport type WalletHandlerConfig = {\n sessionId: string;\n onTxRequest?: (request: WalletTxRequest) => void;\n};\n\nexport type WalletHanderApi = {\n /** Send transaction completion event to backend */\n sendTxComplete: (tx: WalletTxComplete) => void;\n /** Send wallet connection status change and update user state */\n sendConnectionChange: (\n status: WalletConnectionStatus,\n address?: string,\n chainId?: number,\n ) => void;\n /** Pending transaction requests from AI */\n pendingTxRequests: WalletTxRequest[];\n /** Clear a pending request after handling */\n clearTxRequest: (index: number) => void;\n};\n\nexport function useWalletHandler({\n sessionId,\n onTxRequest,\n}: WalletHandlerConfig): WalletHanderApi {\n const { subscribe, sendOutboundSystem: sendOutbound } = useEventContext();\n const { setUser, getUserState } = useUser();\n const [pendingTxRequests, setPendingTxRequests] = useState<WalletTxRequest[]>(\n [],\n );\n\n // ---------------------------------------------------------------------------\n // Subscribe to wallet-related inbound events\n // Backend sends InlineCall with type: \"wallet_tx_request\"\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const unsubscribe = subscribe(\n \"wallet_tx_request\",\n (event: InboundEvent) => {\n const request = event.payload as WalletTxRequest;\n\n // Add to pending requests\n setPendingTxRequests((prev) => [...prev, request]);\n\n // Call optional callback\n onTxRequest?.(request);\n },\n );\n\n return unsubscribe;\n }, [subscribe, onTxRequest]);\n\n // ---------------------------------------------------------------------------\n // Subscribe to wallet-related inbound events\n // Backend sends InlineCall with type: \"user_state_response\"\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const unsubscribe = subscribe(\n \"user_state_request\",\n (event: InboundEvent) => {\n sendOutbound({\n type: \"user_state_response\",\n sessionId,\n payload: getUserState(),\n });\n },\n );\n\n return unsubscribe;\n }, [subscribe, onTxRequest]);\n\n // ---------------------------------------------------------------------------\n // Outbound: Send transaction completion\n // ---------------------------------------------------------------------------\n const sendTxComplete = useCallback(\n (tx: WalletTxComplete) => {\n sendOutbound({\n type: \"wallet:tx_complete\",\n sessionId,\n payload: tx,\n });\n },\n [sendOutbound, sessionId],\n );\n\n // ---------------------------------------------------------------------------\n // Outbound: Send connection status change and update user state\n // ---------------------------------------------------------------------------\n const sendConnectionChange = useCallback(\n (status: WalletConnectionStatus, address?: string, chainId?: number) => {\n // Update user state\n if (status === \"connected\") {\n setUser({\n isConnected: true,\n address,\n chainId,\n });\n } else {\n setUser({\n isConnected: false,\n address: undefined,\n chainId: undefined,\n });\n }\n\n // Send event to backend (optional - only if you still want events)\n sendOutbound({\n type:\n status === \"connected\" ? \"wallet:connected\" : \"wallet:disconnected\",\n sessionId,\n payload: { status, address },\n });\n },\n [setUser, sendOutbound, sessionId],\n );\n\n // ---------------------------------------------------------------------------\n // Clear handled request\n // ---------------------------------------------------------------------------\n const clearTxRequest = useCallback((index: number) => {\n setPendingTxRequests((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n return {\n sendTxComplete,\n sendConnectionChange,\n pendingTxRequests,\n clearTxRequest,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useEventContext } from \"../contexts/event-context\";\nimport type { InboundEvent } from \"../state/event-buffer\";\n\nexport type Notification = {\n id: string;\n type: string;\n title: string;\n body?: unknown; // Could be JSON object or string\n handled: boolean;\n timestamp: number;\n sessionId: string;\n};\n\nexport type NotificationHandlerConfig = {\n /** Callback when new notification arrives */\n onNotification?: (notification: Notification) => void;\n};\n\nexport type NotificationApi = {\n /** All notifications */\n notifications: Notification[];\n /** Unhandled count */\n unhandledCount: number;\n /** Mark notification as handled */\n markDone: (id: string) => void;\n};\n\nlet notificationIdCounter = 0;\nfunction generateNotificationId(): string {\n return `notif-${Date.now()}-${++notificationIdCounter}`;\n}\n\nexport function useNotificationHandler({\n onNotification,\n}: NotificationHandlerConfig = {}): NotificationApi {\n const { subscribe } = useEventContext();\n const [notifications, setNotifications] = useState<Notification[]>([]);\n\n // ---------------------------------------------------------------------------\n // Subscribe to notification events\n // ---------------------------------------------------------------------------\n useEffect(() => {\n const unsubscribe = subscribe(\"notification\", (event: InboundEvent) => {\n const payload = event.payload as Record<string, unknown>;\n\n const notification: Notification = {\n id: generateNotificationId(),\n type: (payload.type as string) ?? \"notification\",\n title: (payload.title as string) ?? \"Notification\",\n body: payload.body,\n handled: false,\n timestamp: event.timestamp,\n sessionId: event.sessionId,\n };\n\n setNotifications((prev) => [notification, ...prev]);\n onNotification?.(notification);\n });\n\n return unsubscribe;\n }, [subscribe, onNotification]);\n\n // ---------------------------------------------------------------------------\n // Computed: unhandled count\n // ---------------------------------------------------------------------------\n const unhandledCount = notifications.filter((n) => !n.handled).length;\n\n // ---------------------------------------------------------------------------\n // Actions\n // ---------------------------------------------------------------------------\n const markHandled = useCallback((id: string) => {\n setNotifications((prev) =>\n prev.map((n) => (n.id === id ? { ...n, handled: true } : n)),\n );\n }, []);\n\n return {\n notifications,\n unhandledCount,\n markDone: markHandled,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC8BA,SAAS,eAAe,UAAiC;AACvD,QAAM,YAAY,SACf,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,KAAK,WAAW,OAAO,CAAC,EACzC,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC,EAAE,UAAU,CAAC;AAC1C,MAAI,CAAC,UAAU,OAAQ,QAAO;AAC9B,SAAO,UAAU,KAAK,IAAI;AAC5B;AAEA,eAAe,cACb,QACA,QACA,WACe;AACf,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AAEb,MAAI;AACF,WAAO,CAAC,OAAO,SAAS;AACtB,YAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,eAAS,OAAO,QAAQ,OAAO,EAAE;AAEjC,UAAI,iBAAiB,OAAO,QAAQ,MAAM;AAC1C,aAAO,kBAAkB,GAAG;AAC1B,cAAM,WAAW,OAAO,MAAM,GAAG,cAAc;AAC/C,iBAAS,OAAO,MAAM,iBAAiB,CAAC;AACxC,cAAM,OAAO,eAAe,QAAQ;AACpC,YAAI,MAAM;AACR,oBAAU,IAAI;AAAA,QAChB;AACA,yBAAiB,OAAO,QAAQ,MAAM;AAAA,MACxC;AAAA,IACF;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACF;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA,YAAY,QAAQ,IAAI,aAAa;AACvC,GAAwC;AACtC,QAAM,gBAAgB,oBAAI,IAA6B;AAEvD,QAAMA,aAAwC,CAC5C,WACA,UACA,YACG;AACH,UAAM,WAAW,cAAc,IAAI,SAAS;AAC5C,UAAM,WAAwB,EAAE,UAAU,QAAQ;AAClD,QAAI,UAAU;AACZ,eAAS,UAAU,IAAI,QAAQ;AAC/B,UAAI,WAAW;AACb,gBAAQ,MAAM,8BAA8B;AAAA,UAC1C;AAAA,UACA,WAAW,SAAS,UAAU;AAAA,QAChC,CAAC;AAAA,MACH;AACA,aAAO,MAAM;AACX,iBAAS,UAAU,OAAO,QAAQ;AAClC,YAAI,WAAW;AACb,kBAAQ,MAAM,gCAAgC;AAAA,YAC5C;AAAA,YACA,WAAW,SAAS,UAAU;AAAA,UAChC,CAAC;AAAA,QACH;AACA,YAAI,SAAS,UAAU,SAAS,GAAG;AACjC,mBAAS,KAAK,aAAa;AAC3B,cAAI,cAAc,IAAI,SAAS,MAAM,UAAU;AAC7C,0BAAc,OAAO,SAAS;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAAgC;AAAA,MACpC,iBAAiB;AAAA,MACjB,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,WAAW,oBAAI,IAAI,CAAC,QAAQ,CAAC;AAAA,MAC7B,MAAM,CAAC,WAAoB;AArHjC;AAsHQ,qBAAa,UAAU;AACvB,YAAI,aAAa,YAAY;AAC3B,uBAAa,aAAa,UAAU;AACpC,uBAAa,aAAa;AAAA,QAC5B;AACA,2BAAa,oBAAb,mBAA8B;AAC9B,qBAAa,kBAAkB;AAC/B,YAAI,WAAW;AACb,kBAAQ,MAAM,oBAAoB;AAAA,YAChC;AAAA,YACA;AAAA,YACA,SAAS,aAAa;AAAA,UACxB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM;AAC1B,UAAI,aAAa,QAAS;AAC1B,mBAAa,WAAW;AACxB,YAAM,UAAU,KAAK,IAAI,MAAM,MAAM,aAAa,UAAU,IAAI,GAAK;AACrE,UAAI,WAAW;AACb,gBAAQ,MAAM,+BAA+B;AAAA,UAC3C;AAAA,UACA;AAAA,UACA,SAAS,aAAa;AAAA,QACxB,CAAC;AAAA,MACH;AACA,mBAAa,aAAa,WAAW,MAAM;AACzC,aAAK,KAAK;AAAA,MACZ,GAAG,OAAO;AAAA,IACZ;AAEA,UAAM,OAAO,YAAY;AAvJ7B;AAwJM,UAAI,aAAa,QAAS;AAC1B,UAAI,aAAa,YAAY;AAC3B,qBAAa,aAAa,UAAU;AACpC,qBAAa,aAAa;AAAA,MAC5B;AAEA,YAAM,aAAa,IAAI,gBAAgB;AACvC,mBAAa,kBAAkB;AAC/B,YAAM,WAAW,KAAK,IAAI;AAE1B,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,GAAG,UAAU,gBAAgB;AAAA,UACxD,SAAS,WAAW,SAAS;AAAA,UAC7B,QAAQ,WAAW;AAAA,QACrB,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI;AAAA,YACR,YAAY,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,UACrD;AAAA,QACF;AAEA,YAAI,CAAC,SAAS,MAAM;AAClB,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC7C;AAEA,qBAAa,UAAU;AAEvB,cAAM,cAAc,SAAS,MAAM,WAAW,QAAQ,CAAC,SAAS;AApLxE,cAAAC,KAAA;AAqLU,cAAI;AACJ,cAAI;AACF,qBAAS,KAAK,MAAM,IAAI;AAAA,UAC1B,SAAS,OAAO;AACd,uBAAW,QAAQ,aAAa,WAAW;AACzC,eAAAA,MAAA,KAAK,YAAL,gBAAAA,IAAA,WAAe;AAAA,YACjB;AACA;AAAA,UACF;AAEA,qBAAW,QAAQ,aAAa,WAAW;AACzC,gBAAI;AACF,mBAAK,SAAS,MAAM;AAAA,YACtB,SAAS,OAAO;AACd,yBAAK,YAAL,8BAAe;AAAA,YACjB;AAAA,UACF;AAAA,QACF,CAAC;AACD,YAAI,WAAW;AACb,kBAAQ,MAAM,4BAA4B;AAAA,YACxC;AAAA,YACA,SAAS,WAAW,OAAO;AAAA,YAC3B,SAAS,aAAa;AAAA,YACtB,YAAY,KAAK,IAAI,IAAI;AAAA,UAC3B,CAAC;AAAA,QACH;AAAA,MACF,SAAS,OAAO;AACd,YAAI,CAAC,WAAW,OAAO,WAAW,CAAC,aAAa,SAAS;AACvD,qBAAW,QAAQ,aAAa,WAAW;AACzC,uBAAK,YAAL,8BAAe;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,aAAa,SAAS;AACzB,sBAAc;AAAA,MAChB;AAAA,IACF;AAEA,kBAAc,IAAI,WAAW,YAAY;AACzC,SAAK,KAAK;AAEV,WAAO,MAAM;AACX,mBAAa,UAAU,OAAO,QAAQ;AACtC,UAAI,WAAW;AACb,gBAAQ,MAAM,gCAAgC;AAAA,UAC5C;AAAA,UACA,WAAW,aAAa,UAAU;AAAA,QACpC,CAAC;AAAA,MACH;AACA,UAAI,aAAa,UAAU,SAAS,GAAG;AACrC,qBAAa,KAAK,aAAa;AAC/B,YAAI,cAAc,IAAI,SAAS,MAAM,cAAc;AACjD,wBAAc,OAAO,SAAS;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,WAAAD,WAAU;AACrB;;;ACpOA,IAAM,oBAAoB;AAE1B,SAAS,cAAc,SAA0C;AAC/D,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,WAAO,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,EAC/B;AACA,QAAM,KAAK,OAAO,SAAS;AAC3B,SAAO,KAAK,IAAI,EAAE,KAAK;AACzB;AAEA,SAAS,kBAAkB,WAAmB,MAAiC;AAC7E,QAAM,UAAU,IAAI,QAAQ,IAAI;AAChC,UAAQ,IAAI,mBAAmB,SAAS;AACxC,SAAO;AACT;AAEA,eAAe,UACb,YACA,MACA,SACA,WACY;AACZ,QAAM,QAAQ,cAAc,OAAO;AACnC,QAAM,MAAM,GAAG,UAAU,GAAG,IAAI,GAAG,KAAK;AAExC,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS,kBAAkB,SAAS;AAAA,EACtC,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,EACnE;AAEA,SAAQ,MAAM,SAAS,KAAK;AAC9B;AAEO,IAAM,aAAN,MAAiB;AAAA,EAGtB,YAA6B,YAAoB;AAApB;AAC3B,SAAK,gBAAgB,oBAAoB;AAAA,MACvC;AAAA,MACA,YAAY,CAAC,cACX,kBAAkB,WAAW,EAAE,QAAQ,oBAAoB,CAAC;AAAA,IAChE,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WACJ,WACA,WAC2B;AAC3B,UAAM,MAAM,IAAI,IAAI,cAAc,KAAK,UAAU;AACjD,QAAI,WAAW;AACb,UAAI,aAAa,IAAI,cAAc,KAAK,UAAU,SAAS,CAAC;AAAA,IAC9D;AAEA,UAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,MAC3C,SAAS,kBAAkB,SAAS;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,IACnE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,gBACJ,WACA,SACA,WAC0B;AAC1B,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,QACE;AAAA,QACA,YAAY;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,kBACJ,WACA,SAC4B;AAC5B,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,QACE;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,WAAkD;AACpE,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aACE,WACA,UACA,SACY;AACZ,WAAO,KAAK,cAAc,UAAU,WAAW,UAAU,OAAO;AAAA,EAClE;AAAA,EAEA,MAAM,aAAa,WAAyC;AAC1D,UAAM,MAAM,GAAG,KAAK,UAAU,4BAA4B,mBAAmB,SAAS,CAAC;AACvF,UAAM,WAAW,MAAM,MAAM,GAAG;AAEhC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,IACpE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,YAAY,WAAuC;AACvD,UAAM,MAAM,GAAG,KAAK,UAAU,iBAAiB,mBAAmB,SAAS,CAAC;AAC5E,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,SAAS,kBAAkB,SAAS;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,IACnE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,aACJ,UACA,WACkC;AAClC,UAAM,OAA+B,CAAC;AACtC,QAAI,UAAW,MAAK,aAAa;AAEjC,UAAM,MAAM,GAAG,KAAK,UAAU;AAC9B,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,kBAAkB,UAAU;AAAA,QACnC,gBAAgB;AAAA,MAClB,CAAC;AAAA,MACD,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,IACpE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,cAAc,WAAkC;AACpD,UAAM,MAAM,GAAG,KAAK,UAAU,iBAAiB,mBAAmB,SAAS,CAAC;AAC5E,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,kBAAkB,SAAS;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,EAAE;AAAA,IACrE;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,WAAkC;AACtD,UAAM,MAAM,GAAG,KAAK,UAAU,iBAAiB,mBAAmB,SAAS,CAAC;AAC5E,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,kBAAkB,SAAS;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,oCAAoC,SAAS,MAAM,EAAE;AAAA,IACvE;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,WAAkC;AACnD,UAAM,MAAM,GAAG,KAAK,UAAU,iBAAiB,mBAAmB,SAAS,CAAC;AAC5E,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,kBAAkB,SAAS;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,WAAmB,UAAiC;AACrE,UAAM,MAAM,GAAG,KAAK,UAAU,iBAAiB,mBAAmB,SAAS,CAAC;AAC5E,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,QAAQ;AAAA,MACR,SAAS,kBAAkB,WAAW;AAAA,QACpC,gBAAgB;AAAA,MAClB,CAAC;AAAA,MACD,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,IAC1C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,EAAE;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAM,gBACJ,WACA,OAC2B;AAC3B,UAAM,MAAM,IAAI,IAAI,eAAe,KAAK,UAAU;AAClD,QAAI,UAAU,QAAW;AACvB,UAAI,aAAa,IAAI,SAAS,OAAO,KAAK,CAAC;AAAA,IAC7C;AACA,UAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,MAC3C,SAAS,kBAAkB,SAAS;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,SAAS,WAAW,IAAK,QAAO,CAAC;AACrC,YAAM,IAAI,MAAM,qCAAqC,SAAS,MAAM,EAAE;AAAA,IACxE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAGF;;;AC5PA,IAAAE,gBAAwB;;;ACAxB,mBAOO;;;AC2GA,SAAS,aACd,OAC8D;AAC9D,SAAO,gBAAgB;AACzB;AAKO,SAAS,eACd,OACmC;AACnC,SAAO,kBAAkB;AAC3B;AAKO,SAAS,cACd,OACkC;AAClC,SAAO,iBAAiB;AAC1B;AAKO,SAAS,gBACd,OACqD;AACrD,SAAO,mBAAmB;AAC5B;;;ACxHO,SAAS,oBAAiC;AAC/C,SAAO;AAAA,IACL,cAAc,CAAC;AAAA,IACf,eAAe,CAAC;AAAA,IAChB,WAAW;AAAA,IACX,aAAa;AAAA,IACb,aAAa,oBAAI,IAAI;AAAA,EACvB;AACF;AAMO,SAAS,eACd,OACA,OACM;AACN,QAAM,aAAa,KAAK,iCACnB,QADmB;AAAA,IAEtB,QAAQ;AAAA,IACR,WAAW,KAAK,IAAI;AAAA,EACtB,EAAC;AACH;AAmDO,SAAS,UACd,OACA,MACA,UACY;AACZ,MAAI,CAAC,MAAM,YAAY,IAAI,IAAI,GAAG;AAChC,UAAM,YAAY,IAAI,MAAM,oBAAI,IAAI,CAAC;AAAA,EACvC;AACA,QAAM,YAAY,IAAI,IAAI,EAAG,IAAI,QAAQ;AAGzC,SAAO,MAAM;AAhHf;AAiHI,gBAAM,YAAY,IAAI,IAAI,MAA1B,mBAA6B,OAAO;AAAA,EACtC;AACF;AASO,SAAS,SAAS,OAAoB,OAA2B;AAEtE,QAAM,kBAAkB,MAAM,YAAY,IAAI,MAAM,IAAI;AACxD,MAAI,iBAAiB;AACnB,eAAW,YAAY,iBAAiB;AACtC,eAAS,KAAK;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,iBAAiB,MAAM,YAAY,IAAI,GAAG;AAChD,MAAI,gBAAgB;AAClB,eAAW,YAAY,gBAAgB;AACrC,eAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAMO,SAAS,aAAa,OAAoB,QAAyB;AACxE,QAAM,YAAY;AACpB;;;AF6DI;AAlKJ,IAAM,wBAAoB,4BAAmC,IAAI;AAM1D,SAAS,kBAAgC;AAC9C,QAAM,cAAU,yBAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;AAgBO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,gBAAY,qBAA2B,IAAI;AACjD,MAAI,CAAC,UAAU,SAAS;AACtB,cAAU,UAAU,kBAAkB;AAAA,EACxC;AACA,QAAM,SAAS,UAAU;AAEzB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAoB,cAAc;AAKpE,8BAAU,MAAM;AACd,iBAAa,QAAQ,YAAY;AACjC,iBAAa,YAAY;AAEzB,UAAM,cAAc,WAAW;AAAA,MAC7B;AAAA,MACA,CAAC,UAAuB;AACtB,uBAAe,QAAQ;AAAA,UACrB,MAAM,MAAM;AAAA,UACZ,WAAW,MAAM;AAAA,UACjB,SAAS;AAAA,QACX,CAAC;AAED,cAAM,eAA6B;AAAA,UACjC,MAAM,MAAM;AAAA,UACZ,WAAW,MAAM;AAAA,UACjB,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,WAAW,KAAK,IAAI;AAAA,QACtB;AACA,iBAAS,QAAQ,YAAY;AAAA,MAC/B;AAAA,MACA,CAAC,UAAU;AACT,gBAAQ,MAAM,cAAc,KAAK;AACjC,qBAAa,QAAQ,cAAc;AACnC,qBAAa,cAAc;AAAA,MAC7B;AAAA,IACF;AAEA,iBAAa,QAAQ,WAAW;AAChC,iBAAa,WAAW;AAExB,WAAO,MAAM;AACX,kBAAY;AACZ,mBAAa,QAAQ,cAAc;AACnC,mBAAa,cAAc;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,YAAY,WAAW,MAAM,CAAC;AAKlC,QAAM,wBAAoB;AAAA,IACxB,CAAC,MAAc,aAA8B;AAC3C,aAAO,UAAkB,QAAQ,MAAM,QAAQ;AAAA,IACjD;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,mBAAe;AAAA,IACnB,OAAO,UAA4C;AACjD,UAAI;AACF,cAAM,UAAU,KAAK,UAAU;AAAA,UAC7B,MAAM,MAAM;AAAA,UACZ,SAAS,MAAM;AAAA,QACjB,CAAC;AACD,cAAM,WAAW,kBAAkB,MAAM,WAAW,OAAO;AAAA,MAC7D,SAAS,OAAO;AACd,gBAAQ,MAAM,kCAAkC,KAAK;AAAA,MACvD;AAAA,IACF;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AAEA,QAAM,2BAAuB;AAAA,IAC3B,CAACC,YAAmB,WAA6B;AA/JrD;AAgKM,iBAAW,SAAS,QAAQ;AAC1B,YAAI;AACJ,YAAI;AAGJ,YAAI,aAAa,KAAK,GAAG;AAEvB,sBAAY,MAAM,WAAW;AAC7B,qBAAU,WAAM,WAAW,YAAjB,YAA4B,MAAM;AAAA,QAC9C,WAAW,eAAe,KAAK,GAAG;AAChC,sBAAY;AACZ,oBAAU,EAAE,SAAS,MAAM,aAAa;AAAA,QAC1C,WAAW,cAAc,KAAK,GAAG;AAC/B,sBAAY;AACZ,oBAAU,EAAE,SAAS,MAAM,YAAY;AAAA,QACzC,WAAW,gBAAgB,KAAK,GAAG;AACjC,sBAAY;AACZ,oBAAU,MAAM;AAAA,QAClB,OAAO;AACL,kBAAQ,KAAK,8BAA8B,KAAK;AAChD;AAAA,QACF;AAEA,cAAM,eAA6B;AAAA,UACjC,MAAM;AAAA,UACN,WAAAA;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,WAAW,KAAK,IAAI;AAAA,QACtB;AACA,uBAAe,QAAQ;AAAA,UACrB,MAAM;AAAA,UACN,WAAAA;AAAA,UACA;AAAA,QACF,CAAC;AACD,iBAAS,QAAQ,YAAY;AAAA,MAC/B;AAAA,IACF;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,eAA6B;AAAA,IACjC,WAAW;AAAA,IACX,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB;AAAA,EACF;AAEA,SACE,4CAAC,kBAAkB,UAAlB,EAA2B,OAAO,cAChC,UACH;AAEJ;;;AGnNA,IAAAC,gBAMO;AA+FH,IAAAC,sBAAA;AA7DJ,IAAM,0BAAsB,6BAA6C,IAAI;AAMtE,SAAS,kBAA0C;AACxD,QAAM,cAAU,0BAAW,mBAAmB;AAC9C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAMA,IAAI,wBAAwB;AAC5B,SAAS,aAAqB;AAC5B,SAAO,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,qBAAqB;AACvD;AAMO,SAAS,4BAA4B;AAAA,EAC1C;AACF,GAAqC;AACnC,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAyB,CAAC,CAAC;AAErE,QAAM,uBAAmB,2BAAY,CAAC,WAA6B;AACjE,UAAM,KAAK,WAAW;AACtB,UAAM,eAA6B,iCAC9B,SAD8B;AAAA,MAEjC;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,IACtB;AACA,qBAAiB,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC;AAClD,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,0BAAsB,2BAAY,CAAC,OAAe;AACtD,qBAAiB,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EAC5D,GAAG,CAAC,CAAC;AAEL,QAAM,eAAW,2BAAY,MAAM;AACjC,qBAAiB,CAAC,CAAC;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,QAAM,QAAgC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SACE,6CAAC,oBAAoB,UAApB,EAA6B,OAC3B,UACH;AAEJ;;;ACzGA,IAAAC,gBAMO;;;ACJP,IAAM,yBAAyB,QAAQ,IAAI,aAAa;AAExD,IAAM,0BAA0B,CAC9B,QACA,UACA,MACA,SACG;AACH,MAAI,CAAC,uBAAwB;AAC7B,MAAI,CAAC,QAAQ,CAAC,KAAM;AACpB,MAAI,CAAC,QAAQ,CAAC,MAAM;AAClB,YAAQ,MAAM,iBAAiB,MAAM,KAAK,EAAE,UAAU,MAAM,KAAK,CAAC;AAClE;AAAA,EACF;AACA,MACE,KAAK,UAAU,KAAK,SACpB,KAAK,WAAW,KAAK,UACrB,KAAK,iBAAiB,KAAK,cAC3B;AACA,YAAQ,MAAM,iBAAiB,MAAM,KAAK,EAAE,UAAU,MAAM,KAAK,CAAC;AAAA,EACpE;AACF;AAsBO,IAAM,cAAN,MAAkB;AAAA,EAKvB,YAAY,SAA8B;AAH1C,SAAQ,YAAY,oBAAI,IAAgB;AAyBxC,qBAAY,CAAC,aAAuC;AAClD,WAAK,UAAU,IAAI,QAAQ;AAC3B,aAAO,MAAM;AACX,aAAK,UAAU,OAAO,QAAQ;AAAA,MAChC;AAAA,IACF;AAEA,uBAAc,MAAqB,KAAK;AAyDxC,8BAAqB,CAAC,aAAqB;AACzC,WAAK,mBAAmB,QAAQ;AAChC,WAAK,YAAY,EAAE,iBAAiB,SAAS,CAAC;AAAA,IAChD;AAEA,6BAAoB,MAAM;AACxB,WAAK,YAAY,EAAE,eAAe,KAAK,MAAM,gBAAgB,EAAE,CAAC;AAAA,IAClE;AAEA,wBAAe,CAAC,YAAoC;AAClD,YAAM,UAAU,KAAK,mBAAmB,SAAS,KAAK,MAAM,SAAS;AACrE,WAAK,YAAY,EAAE,WAAW,QAAQ,CAAC;AAAA,IACzC;AAEA,sBAAa,CAAC,YAA8D;AAC1E,YAAM,cAAc,KAAK,mBAAmB,SAAS,KAAK,MAAM,OAAO;AACvE,WAAK,YAAY,EAAE,SAAS,IAAI,IAAI,WAAW,EAAE,CAAC;AAAA,IACpD;AAEA,6BAAoB,CAClB,YACG;AACH,YAAM,eAAe,KAAK,MAAM;AAChC,YAAM,eAAe,KAAK,mBAAmB,SAAS,YAAY;AAClE,iBAAW,CAAC,UAAU,IAAI,KAAK,aAAa,QAAQ,GAAG;AACrD;AAAA,UACE;AAAA,UACA;AAAA,UACA,aAAa,IAAI,QAAQ;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AACA,iBAAW,CAAC,UAAU,IAAI,KAAK,aAAa,QAAQ,GAAG;AACrD,YAAI,CAAC,aAAa,IAAI,QAAQ,GAAG;AAC/B,kCAAwB,qBAAqB,UAAU,MAAM,MAAS;AAAA,QACxE;AAAA,MACF;AACA,WAAK,YAAY,EAAE,gBAAgB,IAAI,IAAI,YAAY,EAAE,CAAC;AAAA,IAC5D;AAEA,6BAAoB,CAAC,UAAkB,aAAkC;AACvE,WAAK,mBAAmB,QAAQ;AAChC,YAAM,cAAc,IAAI,IAAI,KAAK,MAAM,OAAO;AAC9C,kBAAY,IAAI,UAAU,QAAQ;AAClC,WAAK,YAAY,EAAE,SAAS,YAAY,CAAC;AAAA,IAC3C;AAEA,6BAAoB,CAAC,aAA0C;AAzLjE;AA0LI,cAAO,UAAK,MAAM,QAAQ,IAAI,QAAQ,MAA/B,YAAoC,CAAC;AAAA,IAC9C;AAEA,6BAAoB,CAAC,aAAiD;AACpE,aAAO,KAAK,MAAM,eAAe,IAAI,QAAQ;AAAA,IAC/C;AAEA,gCAAuB,CACrB,UACA,YACG;AACH,YAAM,WAAW,KAAK,MAAM,eAAe,IAAI,QAAQ;AACvD,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AACA,YAAM,OAAO,kCAAK,WAAa;AAC/B,YAAM,eAAe,IAAI,IAAI,KAAK,MAAM,cAAc;AACtD,mBAAa,IAAI,UAAU,IAAI;AAC/B,8BAAwB,wBAAwB,UAAU,UAAU,IAAI;AACxE,WAAK,YAAY,EAAE,gBAAgB,aAAa,CAAC;AAAA,IACnD;AA9MF;AAqDI,UAAM,mBAAkB,wCAAS,oBAAT,YAA4B,OAAO,WAAW;AACtE,SAAK,QAAQ;AAAA,MACX,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,WAAW;AAAA,MACX,SAAS,oBAAI,IAAI,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AAAA,MACxC,gBAAgB,oBAAI,IAAI;AAAA,QACtB;AAAA,UACE;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,UACvC;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,SAAK,WAAW,KAAK,cAAc;AAAA,EACrC;AAAA,EAWQ,OAAO;AACb,eAAW,YAAY,KAAK,WAAW;AACrC,eAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEQ,mBAAsB,SAA4B,SAAe;AACvE,WAAO,OAAO,YAAY,aACrB,QAA2B,OAAO,IACnC;AAAA,EACN;AAAA,EAEQ,mBAAmB,UAAkB;AAC3C,QAAI,CAAC,KAAK,MAAM,eAAe,IAAI,QAAQ,GAAG;AAC5C,YAAM,eAAe,IAAI,IAAI,KAAK,MAAM,cAAc;AACtD,mBAAa,IAAI,UAAU;AAAA,QACzB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACvC,CAAC;AACD,WAAK,QAAQ,iCAAK,KAAK,QAAV,EAAiB,gBAAgB,aAAa;AAAA,IAC7D;AAEA,QAAI,CAAC,KAAK,MAAM,QAAQ,IAAI,QAAQ,GAAG;AACrC,YAAM,cAAc,IAAI,IAAI,KAAK,MAAM,OAAO;AAC9C,kBAAY,IAAI,UAAU,CAAC,CAAC;AAC5B,WAAK,QAAQ,iCAAK,KAAK,QAAV,EAAiB,SAAS,YAAY;AAAA,IACrD;AAAA,EACF;AAAA,EAEQ,YAAY,SAAoC;AACtD,SAAK,QAAQ,kCAAK,KAAK,QAAU;AACjC,SAAK,WAAW,KAAK,cAAc;AACnC,SAAK,KAAK;AAAA,EACZ;AAAA,EAEQ,gBAA+B;AACrC,WAAO;AAAA,MACL,iBAAiB,KAAK,MAAM;AAAA,MAC5B,oBAAoB,KAAK;AAAA,MACzB,eAAe,KAAK,MAAM;AAAA,MAC1B,mBAAmB,KAAK;AAAA,MACxB,YAAY,KAAK,MAAM;AAAA,MACvB,YAAY,KAAK;AAAA,MACjB,oBAAoB,KAAK,MAAM;AAAA,MAC/B,mBAAmB,KAAK;AAAA,MACxB,WAAW,KAAK,MAAM;AAAA,MACtB,cAAc,KAAK;AAAA,MACnB,mBAAmB,KAAK;AAAA,MACxB,mBAAmB,KAAK;AAAA,MACxB,mBAAmB,KAAK;AAAA,MACxB,sBAAsB,KAAK;AAAA,IAC7B;AAAA,EACF;AAuEF;;;ADxII,IAAAC,sBAAA;AA7BJ,IAAM,yBAAqB,6BAAoC,IAAI;AAE5D,SAAS,mBAAkC;AAChD,QAAM,cAAU,0BAAW,kBAAkB;AAC7C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,eAAW,sBAA2B,IAAI;AAChD,MAAI,CAAC,SAAS,SAAS;AACrB,aAAS,UAAU,IAAI,YAAY,EAAE,gBAAgB,CAAC;AAAA,EACxD;AACA,QAAM,QAAQ,SAAS;AACvB,QAAM,YAAQ;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,SACE,6CAAC,mBAAmB,UAAnB,EAA4B,OAC1B,UACH;AAEJ;AAEO,SAAS,2BAAgD;AAC9D,QAAM,EAAE,iBAAiB,kBAAkB,IAAI,iBAAiB;AAChE,aAAO;AAAA,IACL,MAAM,kBAAkB,eAAe;AAAA,IACvC,CAAC,iBAAiB,iBAAiB;AAAA,EACrC;AACF;AAEO,SAAS,2BAAuD;AACrE,QAAM,EAAE,iBAAiB,kBAAkB,IAAI,iBAAiB;AAChE,aAAO;AAAA,IACL,MAAM,kBAAkB,eAAe;AAAA,IACvC,CAAC,iBAAiB,iBAAiB;AAAA,EACrC;AACF;;;AEzFA,IAAAC,gBAOO;AAiFH,IAAAC,sBAAA;AAjEJ,IAAM,kBAAc,6BAA4C,MAAS;AAElE,SAAS,UAAU;AACxB,QAAM,cAAU,0BAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ;AAAA,IACtB,mBAAmB,QAAQ;AAAA,EAC7B;AACF;AAIO,SAAS,oBAAoB,EAAE,SAAS,GAA4B;AACzE,QAAM,CAAC,MAAM,YAAY,QAAI,wBAAoB;AAAA,IAC/C,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAGD,QAAM,cAAU,sBAAO,IAAI;AAC3B,UAAQ,UAAU;AAGlB,QAAM,2BAAuB;AAAA,IAC3B,oBAAI,IAAI;AAAA,EACV;AAEA,QAAM,cAAU,2BAAY,CAAC,SAA6B;AACxD,iBAAa,CAAC,SAAS;AACrB,YAAM,OAAO,kCAAK,OAAS;AAG3B,2BAAqB,QAAQ,QAAQ,CAAC,aAAa;AACjD,iBAAS,IAAI;AAAA,MACf,CAAC;AAED,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAGL,QAAM,mBAAe,2BAAY,MAAM,QAAQ,SAAS,CAAC,CAAC;AAG1D,QAAM,wBAAoB;AAAA,IACxB,CAAC,aAAwC;AACvC,2BAAqB,QAAQ,IAAI,QAAQ;AAGzC,aAAO,MAAM;AACX,6BAAqB,QAAQ,OAAO,QAAQ;AAAA,MAC9C;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;ACnGA,IAAAC,gBAAwD;AAExD,IAAAA,gBAIO;;;ACPP,IAAAC,gBAA8C;;;ACI9C,kBAAsC;AACtC,4BAAwB;AAMjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;AAIO,IAAM,iBAAiB,CAAC,UAA4B;AACzD,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,SAAS,KAAK,IAAK,QAAQ,OAAO,QAAQ,MAAO,QAAS;AAAA,EAC1E;AAEA,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,CAAC,OAAO,MAAM,OAAO,GAAG;AAC1B,WAAO,UAAU,OAAO,UAAU,MAAO;AAAA,EAC3C;AAEA,QAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,SAAO,OAAO,MAAM,EAAE,IAAI,IAAI;AAChC;AAEO,IAAM,qBAAqB,CAAC,UAAmB;AAjCtD;AAkCE,QAAM,cAAa,oCAAO,WAAP,YAAiB;AACpC,SAAO,CAAC,cAAc,WAAW,WAAW,IAAI;AAClD;AASO,SAAS,iBAAiB,KAA4C;AA7C7E;AA8CE,MAAI,IAAI,WAAW,SAAU,QAAO;AAEpC,QAAM,UAAgC,CAAC;AACvC,QAAM,OACJ,IAAI,WAAW,SAAS,SAAS;AAEnC,MAAI,IAAI,SAAS;AACf,YAAQ,KAAK,EAAE,MAAM,QAAiB,MAAM,IAAI,QAAQ,CAAC;AAAA,EAC3D;AAEA,QAAM,CAAC,OAAO,WAAW,KAAI,sBAAiB,GAAG,MAApB,YAAyB,CAAC;AACvD,MAAI,SAAS,aAAa;AACxB,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,MAC9B,UAAU;AAAA,MACV,MAAM;AAAA,MACN,SAAS,MAAM;AACb,YAAI;AACF,iBAAO,KAAK,MAAM,WAAW;AAAA,QAC/B,SAAQ;AACN,iBAAO,EAAE,MAAM,YAAY;AAAA,QAC7B;AAAA,MACF,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,SAAU,QAAQ,SAAS,IACvB,UACA,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,CAAC;AAAA,KACpC,IAAI,aAAa,EAAE,WAAW,IAAI,KAAK,IAAI,SAAS,EAAE;AAG5D,SAAO;AACT;AAEA,SAAS,iBAAiB,KAA2C;AACnE,SAAO,gBAAgB,IAAI,WAAW;AACxC;AAYA,SAAS,gBACP,YACyB;AACzB,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI,MAAM,QAAQ,UAAU,KAAK,WAAW,WAAW,GAAG;AACxD,UAAM,CAAC,OAAO,OAAO,IAAI;AACzB,WAAO,CAAC,OAAO,KAAK,GAAG,OAAO,4BAAW,EAAE,CAAC;AAAA,EAC9C;AAEA,SAAO;AACT;AAiBO,IAAM,iBAAiB,CAC5B,YACW;AACX,MAAI,YAAY,OAAW,QAAO;AAClC,QAAM,KAAK,OAAO,YAAY,WAAW,OAAO,OAAO,IAAI;AAC3D,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,IAAM,gBAAgB,CAAC,SAC5B,OAAO,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC,KAAK;;;ACrJ9C,SAAS,qBAAmC;AACjD,SAAO;AAAA,IACL,kBAAkB,oBAAI,IAAI;AAAA,IAC1B,aAAa,oBAAI,IAAI;AAAA,IACrB,gBAAgB,oBAAI,IAAI;AAAA,IACxB,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,EACvB;AACF;AAEO,SAAS,gBAAgB,OAAqB,UAA0B;AAC7E,SAAO;AACT;AAEO,SAAS,cAAc,OAAqB,UAA2B;AAC5E,SAAO,MAAM,qBAAqB;AACpC;AAEO,SAAS,qBAAqB,OAAqB,UAAkB;AAC1E,QAAM,iBAAiB,IAAI,QAAQ;AACrC;AAEO,SAAS,uBACd,OACA,UACS;AACT,SAAO,MAAM,iBAAiB,IAAI,QAAQ;AAC5C;AAEO,SAAS,sBAAsB,OAAqB,UAAkB;AAC3E,QAAM,iBAAiB,OAAO,QAAQ;AACxC;AAEO,SAAS,iBACd,OACA,UACA,SACA;AACA,MAAI,SAAS;AACX,UAAM,eAAe,IAAI,QAAQ;AAAA,EACnC,OAAO;AACL,UAAM,eAAe,OAAO,QAAQ;AAAA,EACtC;AACF;AAEO,SAAS,gBACd,OACA,UACS;AACT,SAAO,MAAM,eAAe,IAAI,QAAQ;AAC1C;AAEO,SAAS,mBACd,OACA,UACA,MACA;AAhEF;AAiEE,QAAM,YAAW,WAAM,YAAY,IAAI,QAAQ,MAA9B,YAAmC,CAAC;AACrD,QAAM,YAAY,IAAI,UAAU,CAAC,GAAG,UAAU,IAAI,CAAC;AACrD;AAEO,SAAS,mBACd,OACA,UACU;AAxEZ;AAyEE,QAAM,WAAU,WAAM,YAAY,IAAI,QAAQ,MAA9B,YAAmC,CAAC;AACpD,QAAM,YAAY,OAAO,QAAQ;AACjC,SAAO;AACT;AAEO,SAAS,eAAe,OAAqB,UAA2B;AA9E/E;AA+EE,WAAQ,iBAAM,YAAY,IAAI,QAAQ,MAA9B,mBAAiC,WAAjC,YAA2C,KAAK;AAC1D;;;AC/CO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,QAAiC;AAAjC;AAAA,EAAkC;AAAA,EAE/D,QAAQ,UAAkB,MAA6B;AACrD,UAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,QAAI,CAAC,KAAM;AACX,QAAI,eAAe,cAAc,QAAQ,GAAG;AAE1C;AAAA,IACF;AAEA,UAAM,iBAAsC,CAAC;AAC7C,eAAW,OAAO,MAAM;AACtB,YAAM,gBAAgB,iBAAiB,GAAG;AAC1C,UAAI,eAAe;AACjB,uBAAe,KAAK,aAAa;AAAA,MACnC;AAAA,IACF;AAEA,SAAK,oBAAoB,EAAE,kBAAkB,UAAU,cAAc;AAAA,EACvE;AAAA,EAEA,MAAM,SAAS,SAAwB,UAAkB;AAvD3D;AAwDI,UAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,UAAM,OAAO,QAAQ,QAClB;AAAA,MACC,CAAC,SACC,KAAK,SAAS;AAAA,IAClB,EACC;AAAA,MACC,CAAC,SACC,KAAK;AAAA,IACT,EACC,KAAK,IAAI;AAEZ,QAAI,CAAC,KAAM;AAEX,UAAM,cAAc,KAAK,oBAAoB;AAC7C,UAAM,mBAAmB,YAAY,kBAAkB,QAAQ;AAC/D,UAAM,cAAiC;AAAA,MACrC,MAAM;AAAA,MACN,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,MAChC,WAAW,oBAAI,KAAK;AAAA,IACtB;AAEA,gBAAY,kBAAkB,UAAU,CAAC,GAAG,kBAAkB,WAAW,CAAC;AAC1E,gBAAY,qBAAqB,UAAU;AAAA,MACzC,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACvC,CAAC;AAED,QAAI,CAAC,cAAc,cAAc,QAAQ,GAAG;AAC1C,WAAK,YAAY,UAAU,IAAI;AAC/B,yBAAmB,cAAc,UAAU,IAAI;AAC/C;AAAA,IACF;AAEA,UAAM,kBAAkB,gBAAgB,cAAc,QAAQ;AAC9D,UAAM,aAAY,gBAAK,QAAO,iBAAZ;AAElB,QAAI;AACF,WAAK,YAAY,UAAU,IAAI;AAC/B,YAAM,WAAW,YACb,MAAM,KAAK,OAAO,cAAc,QAAQ;AAAA,QACtC;AAAA,QACA;AAAA,QACA;AAAA,MACF,IACA,MAAM,KAAK,OAAO,cAAc,QAAQ;AAAA,QACtC;AAAA,QACA;AAAA,MACF;AAGJ,UAAI,qCAAU,UAAU;AACtB,aAAK,QAAQ,UAAU,SAAS,QAAQ;AAAA,MAC1C;AAEA,YAAI,0CAAU,kBAAV,mBAAyB,WAAU,KAAK,OAAO,cAAc;AAC/D,aAAK,OAAO,aAAa,iBAAiB,SAAS,aAAa;AAAA,MAClE;AAEA,UAAI,qCAAU,eAAe;AAC3B,aAAK,OAAO,QAAQ,MAAM,QAAQ;AAAA,MACpC,WAAW,CAAC,KAAK,OAAO,QAAQ,UAAU,QAAQ,GAAG;AACnD,aAAK,YAAY,UAAU,KAAK;AAAA,MAClC;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,2BAA2B,KAAK;AAC9C,WAAK,YAAY,UAAU,KAAK;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,UAAkB;AA7H3C;AA8HI,UAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,UAAM,UAAU,mBAAmB,cAAc,QAAQ;AACzD,QAAI,CAAC,QAAQ,OAAQ;AACrB,UAAM,kBAAkB,gBAAgB,cAAc,QAAQ;AAC9D,UAAM,aAAY,gBAAK,QAAO,iBAAZ;AAClB,eAAW,QAAQ,SAAS;AAC1B,UAAI;AACF,YAAI,WAAW;AACb,gBAAM,KAAK,OAAO,cAAc,QAAQ;AAAA,YACtC;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,OAAO;AACL,gBAAM,KAAK,OAAO,cAAc,QAAQ;AAAA,YACtC;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,kCAAkC,KAAK;AAAA,MACvD;AAAA,IACF;AACA,SAAK,OAAO,QAAQ,MAAM,QAAQ;AAAA,EACpC;AAAA,EAEA,MAAM,OAAO,UAAkB;AAxJjC;AAyJI,UAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,QAAI,CAAC,cAAc,cAAc,QAAQ,EAAG;AAC5C,SAAK,OAAO,QAAQ,KAAK,QAAQ;AACjC,UAAM,kBAAkB,gBAAgB,cAAc,QAAQ;AAC9D,QAAI;AACF,YAAM,WACJ,MAAM,KAAK,OAAO,cAAc,QAAQ,cAAc,eAAe;AACvE,UAAI,qCAAU,UAAU;AACtB,aAAK,QAAQ,UAAU,SAAS,QAAQ;AAAA,MAC1C;AACA,YAAI,0CAAU,kBAAV,mBAAyB,WAAU,KAAK,OAAO,cAAc;AAC/D,aAAK,OAAO,aAAa,iBAAiB,SAAS,aAAa;AAAA,MAClE;AACA,WAAK,YAAY,UAAU,KAAK;AAAA,IAClC,SAAS,OAAO;AACd,cAAQ,MAAM,qBAAqB,KAAK;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,YAAY,UAAkB,SAAkB;AA5K1D;AA6KI,qBAAiB,KAAK,OAAO,gBAAgB,SAAS,UAAU,OAAO;AACvE,QAAI,KAAK,OAAO,iBAAiB,QAAQ,oBAAoB,UAAU;AACrE,uBAAK,QAAO,uBAAZ,4BAAiC;AAAA,IACnC;AAAA,EACF;AAAA,EAEQ,sBAAwC;AAC9C,UAAM,EAAE,mBAAmB,mBAAmB,qBAAqB,IACjE,KAAK,OAAO,iBAAiB;AAC/B,WAAO,EAAE,mBAAmB,mBAAmB,qBAAqB;AAAA,EACtE;AACF;;;AC7JO,IAAM,oBAAN,MAAwB;AAAA,EAI7B,YAA6B,QAAuB;AAAvB;AAH7B,SAAQ,YAAY,oBAAI,IAA4C;AA5BtE;AAgCI,SAAK,cAAa,YAAO,eAAP,YAAqB;AAAA,EACzC;AAAA,EAEA,MAAM,UAAkB;AAnC1B;AAoCI,UAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,QAAI,CAAC,cAAc,cAAc,QAAQ,EAAG;AAC5C,QAAI,KAAK,UAAU,IAAI,QAAQ,EAAG;AAElC,UAAM,kBAAkB,gBAAgB,cAAc,QAAQ;AAC9D,qBAAiB,cAAc,UAAU,IAAI;AAE7C,UAAM,OAAO,YAAY;AA3C7B,UAAAC,KAAAC;AA4CM,UAAI,CAAC,KAAK,UAAU,IAAI,QAAQ,EAAG;AAEnC,UAAI;AACF,gBAAQ;AAAA,UACN;AAAA,UACA;AAAA,QACF;AACA,cAAM,aAAYA,OAAAD,MAAA,KAAK,QAAO,iBAAZ,gBAAAC,IAAA,KAAAD;AAClB,cAAM,QAAQ,MAAM,KAAK,OAAO,cAAc,QAAQ;AAAA,UACpD;AAAA,UACA;AAAA,QACF;AAEA,YAAI,CAAC,KAAK,UAAU,IAAI,QAAQ,EAAG;AAEnC,aAAK,YAAY,UAAU,KAAK;AAAA,MAClC,SAAS,OAAO;AACd,gBAAQ,MAAM,kBAAkB,KAAK;AACrC,aAAK,KAAK,QAAQ;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,aAAa,YAAY,MAAM,KAAK,UAAU;AACpD,SAAK,UAAU,IAAI,UAAU,UAAU;AAEvC,qBAAK,QAAO,YAAZ,4BAAsB;AAAA,EACxB;AAAA,EAEA,KAAK,UAAkB;AAxEzB;AAyEI,UAAM,aAAa,KAAK,UAAU,IAAI,QAAQ;AAC9C,QAAI,YAAY;AACd,oBAAc,UAAU;AACxB,WAAK,UAAU,OAAO,QAAQ;AAAA,IAChC;AACA,qBAAiB,KAAK,OAAO,gBAAgB,SAAS,UAAU,KAAK;AACrE,qBAAK,QAAO,WAAZ,4BAAqB;AAAA,EACvB;AAAA,EAEA,UAAU,UAA2B;AACnC,WAAO,KAAK,UAAU,IAAI,QAAQ;AAAA,EACpC;AAAA,EAEA,UAAU;AACR,eAAW,YAAY,KAAK,UAAU,KAAK,GAAG;AAC5C,WAAK,KAAK,QAAQ;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,YAAY,UAAkB,OAAyB;AA5FjE;AA8FI,UAAI,WAAM,kBAAN,mBAAqB,WAAU,KAAK,OAAO,cAAc;AAC3D,YAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,YAAM,YAAY,gBAAgB,cAAc,QAAQ;AACxD,WAAK,OAAO,aAAa,WAAW,MAAM,aAAa;AAAA,IACzD;AAEA,SAAK,OAAO,cAAc,UAAU,MAAM,QAAQ;AAElD,QAAI,CAAC,MAAM,eAAe;AACxB,WAAK,KAAK,QAAQ;AAAA,IACpB;AAAA,EACF;AACF;;;AJ/EO,SAAS,uBACd,YACA,SACA;AACA,QAAM,gBAAgB,iBAAiB;AACvC,QAAM,uBAAmB,sBAAsB,aAAa;AAC5D,mBAAiB,UAAU;AAC3B,QAAM,oBAAgB,sBAAO,UAAU;AACvC,gBAAc,UAAU;AACxB,QAAM,sBAAkB,sBAAqB,mBAAmB,CAAC;AAEjE,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAEhD,QAAM,2BACJ,sBAAO,IAAI;AACb,QAAM,iBAAyD,sBAAO,IAAI;AAC1E,QAAM,qBAAiB,sBAAoB,oBAAI,IAAI,CAAC;AAEpD,MAAI,CAAC,WAAW,SAAS;AACvB,eAAW,UAAU,IAAI,kBAAkB;AAAA,MACzC;AAAA,MACA;AAAA,MACA,eAAe,CAAC,UAAkB,SAAgC;AAjDxE;AAkDQ,mCAAqB,YAArB,mBAA8B,QAAQ,UAAU;AAAA,MAClD;AAAA,MACA,cAAc,mCAAS;AAAA,MACvB,cAAc,mCAAS;AAAA,MACvB,SAAS,CAAC,aAAqB;AAC7B,YAAI,iBAAiB,QAAQ,oBAAoB,UAAU;AACzD,uBAAa,IAAI;AAAA,QACnB;AAAA,MACF;AAAA,MACA,QAAQ,CAAC,aAAqB;AAC5B,YAAI,iBAAiB,QAAQ,oBAAoB,UAAU;AACzD,uBAAa,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI,CAAC,qBAAqB,SAAS;AACjC,yBAAqB,UAAU,IAAI,kBAAkB;AAAA,MACnD;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,WAAW;AAAA,MACpB,oBAAoB;AAAA,MACpB,cAAc,mCAAS;AAAA,MACvB,cAAc,mCAAS;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,QAAM,yBAAqB,2BAAY,OAAO,aAAqB;AA/ErE;AAgFI,UAAM,eAAe,gBAAgB;AAErC,QAAI,uBAAuB,cAAc,QAAQ,GAAG;AAClD,4BAAsB,cAAc,QAAQ;AAC5C,UAAI,iBAAiB,QAAQ,oBAAoB,UAAU;AACzD,qBAAa,KAAK;AAAA,MACpB;AACA;AAAA,IACF;AAEA,QAAI,CAAC,cAAc,cAAc,QAAQ,GAAG;AAC1C,UAAI,iBAAiB,QAAQ,oBAAoB,UAAU;AACzD,qBAAa,KAAK;AAAA,MACpB;AACA;AAAA,IACF;AAGA,QAAI,eAAe,QAAQ,IAAI,QAAQ,EAAG;AAE1C,UAAM,kBAAkB,gBAAgB,cAAc,QAAQ;AAC9D,mBAAe,QAAQ,IAAI,QAAQ;AAEnC,QAAI;AACF,YAAM,aAAY,wCAAS,iBAAT;AAClB,YAAM,QAAQ,MAAM,cAAc,QAAQ;AAAA,QACxC;AAAA,QACA;AAAA,MACF;AACA,iCAAqB,YAArB,mBAA8B,QAAQ,UAAU,MAAM;AACtD,YAAI,WAAM,kBAAN,mBAAqB,YAAU,mCAAS,eAAc;AACxD,gBAAQ,aAAa,iBAAiB,MAAM,aAAa;AAAA,MAC3D;AAEA,UAAI,iBAAiB,QAAQ,oBAAoB,UAAU;AACzD,YAAI,MAAM,eAAe;AACvB,uBAAa,IAAI;AACjB,2BAAW,YAAX,mBAAoB,MAAM;AAAA,QAC5B,OAAO;AACL,uBAAa,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,kCAAkC,KAAK;AACrD,UAAI,iBAAiB,QAAQ,oBAAoB,UAAU;AACzD,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF,UAAE;AACA,qBAAe,QAAQ,OAAO,QAAQ;AAAA,IACxC;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA,SAAS,WAAW;AAAA,IACpB,mBAAmB,qBAAqB;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AK5HA,IAAM,uBAAuB,CAC3B,CAAC,EAAE,KAAK,GACR,CAAC,EAAE,KAAK,MACL;AACH,QAAM,MAAM,eAAe,MAAM,YAAY;AAC7C,QAAM,MAAM,eAAe,MAAM,YAAY;AAC7C,SAAO,MAAM;AACf;AAEA,SAAS,iBAAiB,gBAA6C;AACrE,QAAM,UAAU,MAAM,KAAK,eAAe,QAAQ,CAAC,EAAE;AAAA,IACnD,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,mBAAmB,KAAK,KAAK;AAAA,EAC9C;AAEA,QAAM,iBAAiB,QACpB,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,WAAW,UAAU,EAC/C,KAAK,oBAAoB,EACzB;AAAA,IACC,CAAC,CAAC,IAAI,IAAI,OAA2C;AAAA,MACnD;AAAA,MACA,OAAO,KAAK,SAAS;AAAA,MACrB,QAAQ;AAAA,IACV;AAAA,EACF;AAEF,QAAM,kBAAkB,QACrB,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,WAAW,UAAU,EAC/C,KAAK,oBAAoB,EACzB;AAAA,IACC,CAAC,CAAC,IAAI,IAAI,OAA4C;AAAA,MACpD;AAAA,MACA,OAAO,KAAK,SAAS;AAAA,MACrB,QAAQ;AAAA,IACV;AAAA,EACF;AAEF,SAAO,EAAE,gBAAgB,gBAAgB;AAC3C;AAgBO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,eAAe,gBAAgB;AACrC,QAAM,EAAE,gBAAgB,gBAAgB,IAAI;AAAA,IAC1C,cAAc;AAAA,EAChB;AAEA,QAAM,uBAAuB,CAAC,aAAqB;AACjD,UAAM,oBAAoB,aAAa;AACvC,QAAI,qBAAqB,sBAAsB,UAAU;AACvD,oBAAc,kBAAkB,CAAC,SAAS;AACxC,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,aAAK,OAAO,iBAAiB;AAC7B,eAAO;AAAA,MACT,CAAC;AACD,oBAAc,WAAW,CAAC,SAAS;AACjC,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,aAAK,OAAO,iBAAiB;AAC7B,eAAO;AAAA,MACT,CAAC;AACD,mBAAa,YAAY,OAAO,iBAAiB;AACjD,mBAAa,iBAAiB,OAAO,iBAAiB;AAAA,IACxD;AACA,iBAAa,mBAAmB;AAChC,iBAAa,YAAY,OAAO,QAAQ;AACxC,kBAAc;AAAA,MAAkB,CAAC,SAC/B,IAAI,IAAI,IAAI,EAAE,IAAI,UAAU;AAAA,QAC1B,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACvC,CAAC;AAAA,IACH;AACA,kBAAc,kBAAkB,UAAU,CAAC,CAAC;AAC5C,kBAAc,mBAAmB,QAAQ;AACzC,iBAAa,KAAK;AAClB,kBAAc,kBAAkB;AAAA,EAClC;AAEE,QAAM,sBAAsB,MAAM;AAChC,QAAI,aAAa,iBAAkB,QAAO,aAAa;AACvD,eAAW,CAAC,IAAI,IAAI,KAAK,cAAc,mBAAmB,QAAQ,GAAG;AACnE,UAAI,KAAK,WAAW,UAAW,QAAO;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAEF,SAAO;AAAA,IACL,UAAU,cAAc;AAAA,IACxB,SAAS;AAAA,IACT;AAAA,IAEA,qBAAqB,YAAY;AAhIrC;AAiIM,YAAM,YAAY,oBAAoB;AACtC,UAAI,WAAW;AACb,6BAAqB,SAAS;AAC9B;AAAA,MACF;AAEA,UAAI,aAAa,qBAAqB;AACpC;AAAA,WACE,kBAAa,qBAAb,YAAiC,OAAO,WAAW;AAAA,QACrD;AACA;AAAA,MACF;AAEA,YAAM,WAAW,OAAO,WAAW;AACnC,2BAAqB,QAAQ;AAE7B,YAAM,gBAAgB,cAAc,QACjC,aAAa,UAAU,WAAW,EAClC,KAAK,OAAO,cAAc;AAnJnC,YAAAE;AAoJU,cAAM,cAAaA,MAAA,aAAa,qBAAb,OAAAA,MAAiC;AACpD,cAAM,YAAY,UAAU;AAE5B,YAAI,eAAe,WAAW;AAC5B,kBAAQ,KAAK,sCAAsC;AAAA,YACjD;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AACA,6BAAqB,cAAc,UAAU;AAE7C,sBAAc,kBAAkB,CAAC,SAAS;AA/JpD,cAAAA,KAAA;AAgKY,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,gBAAM,WAAW,KAAK,IAAI,UAAU;AACpC,gBAAM,cACJ,qCAAU,YAAW,aAAa,aAAa;AACjD,eAAK,IAAI,YAAY;AAAA,YACnB,QAAOA,MAAA,qCAAU,UAAV,OAAAA,MAAmB;AAAA,YAC1B,QAAQ;AAAA,YACR,eAAc,0CAAU,iBAAV,aAA0B,oBAAI,KAAK,GAAE,YAAY;AAAA,UACjE,CAAC;AACD,iBAAO;AAAA,QACT,CAAC;AAED,YAAI,aAAa,qBAAqB,YAAY;AAChD,uBAAa,mBAAmB;AAAA,QAClC;AAEA,cAAM,kBAAkB,aAAa,YAAY,IAAI,UAAU;AAC/D,YAAI,mDAAiB,QAAQ;AAC3B,uBAAa,YAAY,OAAO,UAAU;AAC1C,qBAAW,QAAQ,iBAAiB;AAClC,gBAAI;AACF,oBAAM,cAAc,QAAQ,gBAAgB,WAAW,IAAI;AAAA,YAC7D,SAAS,OAAO;AACd,sBAAQ,MAAM,kCAAkC,KAAK;AAAA,YACvD;AAAA,UACF;AACA,cAAI,mBAAmB,YAAY,YAAY;AAC7C,+CAAS,MAAM;AAAA,UACjB;AAAA,QACF;AAAA,MACF,CAAC,EACA,MAAM,CAAC,UAAU;AA/L1B,YAAAA;AAgMU,gBAAQ,MAAM,gCAAgC,KAAK;AACnD,cAAM,YAAWA,MAAA,aAAa,qBAAb,OAAAA,MAAiC;AAClD,sBAAc,kBAAkB,CAAC,SAAS;AACxC,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,eAAK,OAAO,QAAQ;AACpB,iBAAO;AAAA,QACT,CAAC;AACD,sBAAc,WAAW,CAAC,SAAS;AACjC,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,eAAK,OAAO,QAAQ;AACpB,iBAAO;AAAA,QACT,CAAC;AACD,YAAI,aAAa,qBAAqB,UAAU;AAC9C,uBAAa,mBAAmB;AAAA,QAClC;AAAA,MACF,CAAC,EACA,QAAQ,MAAM;AACb,qBAAa,sBAAsB;AAAA,MACrC,CAAC;AAEH,mBAAa,sBAAsB;AAAA,IACrC;AAAA,IAEA,kBAAkB,CAAC,aAAqB;AACtC,oBAAc,mBAAmB,QAAQ;AAAA,IAC3C;AAAA,IAEA,UAAU,OAAO,UAAkB,aAAqB;AA3N5D;AA4NM,YAAM,iBACJ,yBAAc,kBAAkB,QAAQ,MAAxC,mBAA2C,UAA3C,YAAoD;AACtD,YAAM,kBAAkB,mBAAmB,QAAQ,IAAI,KAAK;AAC5D,oBAAc,qBAAqB,UAAU;AAAA,QAC3C,OAAO;AAAA,MACT,CAAC;AAED,UAAI;AACF,cAAM,cAAc,QAAQ,aAAa,UAAU,QAAQ;AAAA,MAC7D,SAAS,OAAO;AACd,gBAAQ,MAAM,4BAA4B,KAAK;AAC/C,sBAAc,qBAAqB,UAAU;AAAA,UAC3C,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,WAAW,OAAO,aAAqB;AACrC,oBAAc,qBAAqB,UAAU,EAAE,QAAQ,WAAW,CAAC;AAEnE,UAAI;AACF,cAAM,cAAc,QAAQ,cAAc,QAAQ;AAAA,MACpD,SAAS,OAAO;AACd,gBAAQ,MAAM,6BAA6B,KAAK;AAChD,sBAAc,qBAAqB,UAAU,EAAE,QAAQ,UAAU,CAAC;AAAA,MACpE;AAAA,IACF;AAAA,IAEA,aAAa,OAAO,aAAqB;AACvC,oBAAc,qBAAqB,UAAU,EAAE,QAAQ,UAAU,CAAC;AAElE,UAAI;AACF,cAAM,cAAc,QAAQ,gBAAgB,QAAQ;AAAA,MACtD,SAAS,OAAO;AACd,gBAAQ,MAAM,+BAA+B,KAAK;AAClD,sBAAc,qBAAqB,UAAU,EAAE,QAAQ,WAAW,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,IAEA,UAAU,OAAO,aAAqB;AACpC,UAAI;AACF,cAAM,cAAc,QAAQ,aAAa,QAAQ;AAEjD,sBAAc,kBAAkB,CAAC,SAAS;AACxC,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,eAAK,OAAO,QAAQ;AACpB,iBAAO;AAAA,QACT,CAAC;AACD,sBAAc,WAAW,CAAC,SAAS;AACjC,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,eAAK,OAAO,QAAQ;AACpB,iBAAO;AAAA,QACT,CAAC;AACD,qBAAa,YAAY,OAAO,QAAQ;AACxC,qBAAa,iBAAiB,OAAO,QAAQ;AAC7C,qBAAa,eAAe,OAAO,QAAQ;AAC3C,YAAI,aAAa,qBAAqB,UAAU;AAC9C,uBAAa,mBAAmB;AAAA,QAClC;AAEA,YAAI,cAAc,oBAAoB,UAAU;AAC9C,gBAAM,qBAAqB,MAAM;AAAA,YAC/B,cAAc,mBAAmB,QAAQ;AAAA,UAC3C,EAAE,KAAK,CAAC,CAAC,IAAI,IAAI,MAAM,KAAK,WAAW,aAAa,OAAO,QAAQ;AAEnE,cAAI,oBAAoB;AACtB,0BAAc,mBAAmB,mBAAmB,CAAC,CAAC;AAAA,UACxD,OAAO;AACL,kBAAM,YAAY;AAClB,0BAAc;AAAA,cAAkB,CAAC,SAC/B,IAAI,IAAI,IAAI,EAAE,IAAI,WAAW;AAAA,gBAC3B,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,cACvC,CAAC;AAAA,YACH;AACA,0BAAc,kBAAkB,WAAW,CAAC,CAAC;AAC7C,0BAAc,mBAAmB,SAAS;AAAA,UAC5C;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,4BAA4B,KAAK;AAC/C,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;AChTA,IAAAC,gBAA0C;AA6F1C,IAAM,yBAAqB,6BAAqC,IAAI;AAE7D,IAAM,yBAAyB,mBAAmB;AAkClD,SAAS,iBAAiC;AAC/C,QAAM,cAAU,0BAAW,kBAAkB;AAC7C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;;;AP8VM,IAAAC,sBAAA;AApcC,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,gBAAgB,iBAAiB;AACvC,QAAM,eAAe,gBAAgB;AACrC,QAAM,sBAAsB,gBAAgB;AAC5C,QAAM,EAAE,uBAAuB,qBAAqB,IAAI;AACxD,QAAM,EAAE,MAAM,mBAAmB,aAAa,IAAI,QAAQ;AAE1D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,uBAAuB,YAAY;AAAA,IACrC,cAAc;AAAA,IACd,cAAc,MAAM,aAAa,EAAE;AAAA,IACnC;AAAA,EACF,CAAC;AAKD,+BAAU,MAAM;AACd,UAAM,cAAc,kBAAkB,OAAO,YAAY;AACvD,YAAM,YAAY,cAAc;AAChC,YAAM,UAAU,KAAK,UAAU;AAAA,QAC7B,MAAM;AAAA,QACN,SAAS;AAAA,UACP,SAAS,QAAQ;AAAA,UACjB,SAAS,QAAQ;AAAA,UACjB,aAAa,QAAQ;AAAA,UACrB,SAAS,QAAQ;AAAA,QACnB;AAAA,MACF,CAAC;AACD,YAAM,cAAc,QAAQ,kBAAkB,WAAW,OAAO;AAAA,IAClE,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,mBAAmB,eAAe,cAAc,eAAe,CAAC;AAKpE,QAAM,uBAAmB,sBAAO,aAAa;AAC7C,mBAAiB,UAAU;AAE3B,QAAM,yBAAqB,sBAAO,cAAc,eAAe;AAC/D,+BAAU,MAAM;AACd,uBAAmB,UAAU,cAAc;AAAA,EAC7C,GAAG,CAAC,cAAc,eAAe,CAAC;AAKlC,+BAAU,MAAM;AACd,SAAK,mBAAmB,cAAc,eAAe;AAAA,EACvD,GAAG,CAAC,oBAAoB,cAAc,eAAe,CAAC;AAEtD,+BAAU,MAAM;AACd,UAAM,WAAW,cAAc;AAC/B,iBAAa,gBAAgB,gBAAgB,SAAS,QAAQ,CAAC;AAAA,EACjE,GAAG,CAAC,iBAAiB,cAAc,cAAc,eAAe,CAAC;AAEjE,QAAM,kBAAkB,cAAc;AAAA,IACpC,cAAc;AAAA,EAChB;AACA,QAAM,wBAAoB;AAAA,IACxB,MACE,gBAAgB,gBAAgB,SAAS,cAAc,eAAe;AAAA,IACxE;AAAA,MACE;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,IAChB;AAAA,EACF;AAKA,+BAAU,MAAM;AACd,UAAM,cAAc,KAAK;AACzB,QAAI,CAAC,YAAa;AAElB,UAAM,kBAAkB,YAAY;AA9HxC;AA+HM,UAAI;AACF,cAAM,aACJ,MAAM,cAAc,QAAQ,aAAa,WAAW;AACtD,cAAM,iBAAiB,iBAAiB;AACxC,cAAM,cAAc,IAAI,IAAI,eAAe,kBAAkB;AAC7D,YAAI,aAAa,eAAe;AAEhC,mBAAW,UAAU,YAAY;AAC/B,gBAAM,YAAW,YAAO,UAAP,YAAgB;AACjC,gBAAM,QAAQ,mBAAmB,QAAQ,IAAI,KAAK;AAClD,gBAAM,eACJ,iBAAY,IAAI,OAAO,UAAU,MAAjC,mBAAoC,kBACpC,oBAAI,KAAK,GAAE,YAAY;AACzB,sBAAY,IAAI,OAAO,YAAY;AAAA,YACjC;AAAA,YACA,QAAQ,OAAO,cAAc,aAAa;AAAA,YAC1C,cAAc;AAAA,UAChB,CAAC;AAED,gBAAM,QAAQ,MAAM,MAAM,cAAc;AACxC,cAAI,OAAO;AACT,kBAAM,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE;AACjC,gBAAI,MAAM,YAAY;AACpB,2BAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAEA,uBAAe,kBAAkB,WAAW;AAC5C,YAAI,aAAa,eAAe,WAAW;AACzC,yBAAe,aAAa,UAAU;AAAA,QACxC;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,gCAAgC,KAAK;AAAA,MACrD;AAAA,IACF;AAEA,SAAK,gBAAgB;AAAA,EACvB,GAAG,CAAC,KAAK,SAAS,aAAa,CAAC;AAKhC,QAAM,wBAAoB;AAAA,IACxB,MACE,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,KAAK;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,IAChB;AAAA,EACF;AAKA,+BAAU,MAAM;AACd,UAAM,eAAe,gBAAgB;AACrC,UAAM,mBAAmB,cAAc;AAEvC,QAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,cAAQ,MAAM,yBAAyB;AAAA,QACrC;AAAA,QACA;AAAA,QACA,YAAY,qBAAqB;AAAA,MACnC,CAAC;AAAA,IACH;AAEA,UAAM,cAAc,cAAc,QAAQ;AAAA,MACxC;AAAA,MACA,CAAC,UAAU;AACT,cAAM,YAAY,MAAM;AACxB,cAAM,YAAY,MAAM;AAExB,YAAI,cAAc,iBAAiB;AACjC,gBAAM,WAAW,MAAM;AACvB,gBAAM,iBAAiB,gBAAgB,cAAc,SAAS;AAC9D,gBAAM,kBAAkB,mBAAmB,QAAQ,IAAI,KAAK;AAE5D,cAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,oBAAQ,MAAM,6BAA6B;AAAA,cACzC;AAAA,cACA;AAAA,cACA;AAAA,cACA,iBAAiB,iBAAiB,QAAQ;AAAA,cAC1C;AAAA,cACA,YAAY,cAAc;AAAA,cAC1B,kBAAkB,aAAa;AAAA,YACjC,CAAC;AAAA,UACH;AAEA,2BAAiB,QAAQ,kBAAkB,CAAC,SAAS;AAvO/D;AAwOY,kBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,kBAAM,WAAW,KAAK,IAAI,cAAc;AACxC,kBAAM,cACJ,qCAAU,YAAW,aAAa,aAAa;AACjD,iBAAK,IAAI,gBAAgB;AAAA,cACvB,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,eAAc,0CAAU,iBAAV,aAA0B,oBAAI,KAAK,GAAE,YAAY;AAAA,YACjE,CAAC;AACD,mBAAO;AAAA,UACT,CAAC;AACD,cACE,CAAC,mBAAmB,QAAQ,KAC5B,aAAa,qBAAqB,gBAClC;AACA,yBAAa,mBAAmB;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM;AACX;AAAA,IACF;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,EACF,CAAC;AAKD,+BAAU,MAAM;AACd,UAAM,WAAW,cAAc;AAC/B,QAAI,CAAC,cAAc,gBAAgB,SAAS,QAAQ,EAAG;AACvD,SAAK,kBAAkB,iBAAiB,QAAQ;AAAA,EAClD,GAAG,CAAC,mBAAmB,iBAAiB,cAAc,eAAe,CAAC;AAKtE,+BAAU,MAAM;AACd,UAAM,uBACJ,CAAC,cACD,CAAC,UAAiC;AAChC,YAAM,UAAU,MAAM;AACtB,YAAM,WACJ,QAAO,mCAAS,eAAc,WAC1B,QAAQ,YACR;AACN,YAAM,QAAQ,WACV,GAAG,cAAc,gBAAgB,gBAAgB,eAAe,KAAK,QAAQ,KAC7E,cAAc,gBACZ,gBACA;AACN,YAAM,UACJ,QAAO,mCAAS,aAAY,WACxB,QAAQ,UACR,QAAO,mCAAS,YAAW,WACzB,QAAQ,SACR;AAER,0BAAoB,iBAAiB;AAAA,QACnC,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEF,UAAM,oBAAoB,aAAa;AAAA,MACrC;AAAA,MACA,qBAAqB,aAAa;AAAA,IACpC;AACA,UAAM,sBAAsB,aAAa;AAAA,MACvC;AAAA,MACA,qBAAqB,eAAe;AAAA,IACtC;AAEA,WAAO,MAAM;AACX,wBAAkB;AAClB,0BAAoB;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,cAAc,mBAAmB,CAAC;AAKtC,+BAAU,MAAM;AACd,UAAM,cAAc,aAAa,UAAU,iBAAiB,CAAC,UAAU;AACrE,YAAM,UAAU,MAAM;AACtB,YAAM,UAAU,mCAAS;AAEzB,0BAAoB,iBAAiB;AAAA,QACnC,MAAM;AAAA,QACN,OAAO;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,cAAc,mBAAmB,CAAC;AAKtC,QAAM,cAAU,uCAAwB;AAAA,IACtC,UAAU;AAAA,IACV,aAAa,CAAC,SACZ,cAAc,kBAAkB,cAAc,iBAAiB,CAAC,GAAG,IAAI,CAAC;AAAA,IAC1E;AAAA,IACA,OAAO,CAAC,YACN,kBAAkB,SAAS,SAAS,cAAc,eAAe;AAAA,IACnE,UAAU,MAAM,kBAAkB,OAAO,cAAc,eAAe;AAAA,IACtE,gBAAgB,CAAC,QAAQ;AAAA,IACzB,UAAU,EAAE,YAAY,kBAAkB;AAAA,EAC5C,CAAC;AAKD,+BAAU,MAAM;AACd,WAAO,MAAM;AACX,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAKZ,QAAM,cAAc,QAAQ;AAE5B,QAAM,kBAAc;AAAA,IAClB,OAAO,SAAiB;AAGtB,YAAM,gBAAgB;AAAA,QACpB,MAAM;AAAA,QACN,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,MAClC;AACA,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,mBAAmB,cAAc,eAAe;AAAA,EACnD;AAEA,QAAM,uBAAmB,2BAAY,MAAM;AACzC,sBAAkB,OAAO,cAAc,eAAe;AAAA,EACxD,GAAG,CAAC,mBAAmB,cAAc,eAAe,CAAC;AAErD,QAAM,kBAAc;AAAA,IAClB,CAAC,aAAsB;AACrB,YAAM,KAAK,8BAAY,cAAc;AACrC,aAAO,cAAc,kBAAkB,EAAE;AAAA,IAC3C;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,mBAAe,2BAAY,YAA6B;AAC5D,UAAM,kBAAkB,oBAAoB;AAC5C,WAAO,iBAAiB,QAAQ;AAAA,EAClC,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,mBAAe;AAAA,IACnB,OAAO,aAAqB;AAC1B,YAAM,kBAAkB,SAAS,QAAQ;AAAA,IAC3C;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AAEA,QAAM,mBAAe;AAAA,IACnB,OAAO,UAAkB,UAAkB;AACzC,YAAM,kBAAkB,SAAS,UAAU,KAAK;AAAA,IAClD;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AAEA,QAAM,oBAAgB;AAAA,IACpB,OAAO,aAAqB;AAC1B,YAAM,kBAAkB,UAAU,QAAQ;AAAA,IAC5C;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AAEA,QAAM,mBAAe;AAAA,IACnB,CAAC,aAAqB;AAEpB,UAAI,cAAc,mBAAmB,IAAI,QAAQ,GAAG;AAClD,0BAAkB,iBAAiB,QAAQ;AAAA,MAC7C,OAAO;AAEL,aAAK,kBAAkB,oBAAoB;AAAA,MAC7C;AAAA,IACF;AAAA,IACA,CAAC,cAAc,oBAAoB,iBAAiB;AAAA,EACtD;AAEA,QAAM,qBAAiC;AAAA,IACrC,OAAO;AAAA;AAAA,MAEL,MAAM,YAAY;AAAA,MAClB,cAAc,YAAY;AAAA,MAC1B,SAAS,YAAY;AAAA,MACrB,mBAAmB,YAAY;AAAA;AAAA,MAG/B,iBAAiB,cAAc;AAAA,MAC/B,eAAe,cAAc;AAAA,MAC7B,gBAAgB,cAAc;AAAA,MAC9B,mBAAmB,cAAc;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGA,eAAe,oBAAoB;AAAA,MACnC,kBAAkB,oBAAoB;AAAA,MACtC,qBAAqB,oBAAoB;AAAA,MACzC,uBAAuB,oBAAoB;AAAA;AAAA,MAG3C,WAAW,aAAa;AAAA,MACxB,mBAAmB,aAAa;AAAA,MAChC,WAAW,aAAa;AAAA,IAC1B;AAAA,IACA;AAAA,MACE;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SACE,6CAAC,0BAAuB,OAAO,gBAC7B,uDAAC,0CAAyB,SACvB,UACH,GACF;AAEJ;;;ARzcU,IAAAC,sBAAA;AAVH,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,aAAa;AACf,GAAuC;AACrC,QAAM,iBAAa,uBAAQ,MAAM,IAAI,WAAW,UAAU,GAAG,CAAC,UAAU,CAAC;AAEzE,SACE,6CAAC,yBACC,uDAAC,+BACC,uDAAC,uBACC,uDAAC,oBAAiB,YACf,UACH,GACF,GACF,GACF;AAEJ;AAWA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AACF,GAAoC;AAClC,QAAM,gBAAgB,iBAAiB;AAEvC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,cAAc;AAAA,MAEzB,uDAAC,mBAAgB,YAAyB,UAAS;AAAA;AAAA,EACrD;AAEJ;;;AgBpEA,IAAAC,iBAAiD;AAyC1C,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AACF,GAAyC;AACvC,QAAM,EAAE,WAAAC,YAAW,oBAAoB,aAAa,IAAI,gBAAgB;AACxE,QAAM,EAAE,SAAS,aAAa,IAAI,QAAQ;AAC1C,QAAM,CAAC,mBAAmB,oBAAoB,QAAI;AAAA,IAChD,CAAC;AAAA,EACH;AAMA,gCAAU,MAAM;AACd,UAAM,cAAcA;AAAA,MAClB;AAAA,MACA,CAAC,UAAwB;AACvB,cAAM,UAAU,MAAM;AAGtB,6BAAqB,CAAC,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC;AAGjD,mDAAc;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG,CAACA,YAAW,WAAW,CAAC;AAM3B,gCAAU,MAAM;AACd,UAAM,cAAcA;AAAA,MAClB;AAAA,MACA,CAAC,UAAwB;AACvB,qBAAa;AAAA,UACX,MAAM;AAAA,UACN;AAAA,UACA,SAAS,aAAa;AAAA,QACxB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG,CAACA,YAAW,WAAW,CAAC;AAK3B,QAAM,qBAAiB;AAAA,IACrB,CAAC,OAAyB;AACxB,mBAAa;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,IACA,CAAC,cAAc,SAAS;AAAA,EAC1B;AAKA,QAAM,2BAAuB;AAAA,IAC3B,CAAC,QAAgC,SAAkB,YAAqB;AAEtE,UAAI,WAAW,aAAa;AAC1B,gBAAQ;AAAA,UACN,aAAa;AAAA,UACb;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AACL,gBAAQ;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAGA,mBAAa;AAAA,QACX,MACE,WAAW,cAAc,qBAAqB;AAAA,QAChD;AAAA,QACA,SAAS,EAAE,QAAQ,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS,cAAc,SAAS;AAAA,EACnC;AAKA,QAAM,qBAAiB,4BAAY,CAAC,UAAkB;AACpD,yBAAqB,CAAC,SAAS,KAAK,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAAA,EACnE,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACrJA,IAAAC,iBAAiD;AA4BjD,IAAIC,yBAAwB;AAC5B,SAAS,yBAAiC;AACxC,SAAO,SAAS,KAAK,IAAI,CAAC,IAAI,EAAEA,sBAAqB;AACvD;AAEO,SAAS,uBAAuB;AAAA,EACrC;AACF,IAA+B,CAAC,GAAoB;AAClD,QAAM,EAAE,WAAAC,WAAU,IAAI,gBAAgB;AACtC,QAAM,CAAC,eAAe,gBAAgB,QAAI,yBAAyB,CAAC,CAAC;AAKrE,gCAAU,MAAM;AACd,UAAM,cAAcA,WAAU,gBAAgB,CAAC,UAAwB;AA7C3E;AA8CM,YAAM,UAAU,MAAM;AAEtB,YAAM,eAA6B;AAAA,QACjC,IAAI,uBAAuB;AAAA,QAC3B,OAAO,aAAQ,SAAR,YAA2B;AAAA,QAClC,QAAQ,aAAQ,UAAR,YAA4B;AAAA,QACpC,MAAM,QAAQ;AAAA,QACd,SAAS;AAAA,QACT,WAAW,MAAM;AAAA,QACjB,WAAW,MAAM;AAAA,MACnB;AAEA,uBAAiB,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC;AAClD,uDAAiB;AAAA,IACnB,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAACA,YAAW,cAAc,CAAC;AAK9B,QAAM,iBAAiB,cAAc,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE;AAK/D,QAAM,kBAAc,4BAAY,CAAC,OAAe;AAC9C;AAAA,MAAiB,CAAC,SAChB,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,KAAK,iCAAK,IAAL,EAAQ,SAAS,KAAK,KAAI,CAAE;AAAA,IAC7D;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ;AACF;","names":["subscribe","_a","import_react","sessionId","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","_a","_b","_a","import_react","import_jsx_runtime","import_jsx_runtime","import_react","subscribe","import_react","notificationIdCounter","subscribe"]}