@aomi-labs/react 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/backend/sse.ts","../src/backend/client.ts","../src/runtime/aomi-runtime.tsx","../src/contexts/control-context.tsx","../src/utils/uuid.ts","../src/state/thread-store.ts","../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/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":["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\";\nconst API_KEY_HEADER = \"X-API-Key\";\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 apiKey?: string,\n): Promise<T> {\n const query = toQueryString(payload);\n const url = `${backendUrl}${path}${query}`;\n\n const headers = new Headers(withSessionHeader(sessionId));\n if (apiKey) {\n headers.set(API_KEY_HEADER, apiKey);\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\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 namespace: string,\n publicKey?: string,\n apiKey?: string,\n ): Promise<ApiChatResponse> {\n const payload: Record<string, unknown> = { message, namespace };\n if (publicKey) {\n payload.public_key = publicKey;\n }\n\n return postState<ApiChatResponse>(\n this.backendUrl,\n \"/api/chat\",\n payload,\n sessionId,\n apiKey,\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 // ===========================================================================\n // Control API\n // ===========================================================================\n\n /**\n * Get allowed namespaces for the current request context.\n */\n async getNamespaces(\n sessionId: string,\n publicKey?: string,\n apiKey?: string,\n ): Promise<string[]> {\n const url = new URL(\"/api/control/namespaces\", this.backendUrl);\n if (publicKey) {\n url.searchParams.set(\"public_key\", publicKey);\n }\n\n console.log(\"[BackendApi.getNamespaces]\", {\n backendUrl: this.backendUrl,\n fullUrl: url.toString(),\n sessionId,\n publicKey,\n });\n\n const headers = new Headers(withSessionHeader(sessionId));\n if (apiKey) {\n headers.set(API_KEY_HEADER, apiKey);\n }\n\n const response = await fetch(url.toString(), { headers });\n\n if (!response.ok) {\n throw new Error(`Failed to get namespaces: HTTP ${response.status}`);\n }\n\n return (await response.json()) as string[];\n }\n\n /**\n * Get available models.\n */\n async getModels(sessionId: string): Promise<string[]> {\n const url = new URL(\"/api/control/models\", this.backendUrl);\n\n console.log(\"[BackendApi.getModels]\", {\n backendUrl: this.backendUrl,\n fullUrl: url.toString(),\n sessionId,\n });\n\n const response = await fetch(url.toString(), {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get models: HTTP ${response.status}`);\n }\n\n return (await response.json()) as string[];\n }\n\n /**\n * Set the model selection for a session.\n */\n async setModel(\n sessionId: string,\n rig: string,\n namespace?: string,\n apiKey?: string,\n ): Promise<{\n success: boolean;\n rig: string;\n baml: string;\n created: boolean;\n }> {\n const payload: Record<string, unknown> = { rig };\n if (namespace) {\n payload.namespace = namespace;\n }\n\n return postState<{\n success: boolean;\n rig: string;\n baml: string;\n created: boolean;\n }>(this.backendUrl, \"/api/control/model\", payload, sessionId, apiKey);\n }\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\n\nimport { BackendApi } from \"../backend/client\";\nimport { ControlContextProvider } from \"../contexts/control-context\";\nimport { EventContextProvider } from \"../contexts/event-context\";\nimport { NotificationContextProvider } from \"../contexts/notification-context\";\nimport {\n ThreadContextProvider,\n useThreadContext,\n} from \"../contexts/thread-context\";\nimport { UserContextProvider, useUser } 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 and UserContext)\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 const { user } = useUser();\n\n return (\n <ControlContextProvider\n backendApi={backendApi}\n sessionId={threadContext.currentThreadId}\n publicKey={user.address ?? undefined}\n getThreadMetadata={threadContext.getThreadMetadata}\n updateThreadMetadata={threadContext.updateThreadMetadata}\n >\n <EventContextProvider\n backendApi={backendApi}\n sessionId={threadContext.currentThreadId}\n >\n <AomiRuntimeCore backendApi={backendApi}>{children}</AomiRuntimeCore>\n </EventContextProvider>\n </ControlContextProvider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useRef,\n useState,\n useEffect,\n type ReactNode,\n} from \"react\";\nimport type { BackendApi } from \"../backend/client\";\nimport type { ThreadMetadata, ThreadControlState } from \"../state/thread-store\";\nimport { initThreadControl } from \"../state/thread-store\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** Global control state (shared across all threads) */\nexport type ControlState = {\n /** API key for authenticated requests */\n apiKey: string | null;\n /** Available models fetched from backend */\n availableModels: string[];\n /** Authorized namespaces fetched from backend */\n authorizedNamespaces: string[];\n /** Default model (first from availableModels) */\n defaultModel: string | null;\n /** Default namespace (from authorizedNamespaces) */\n defaultNamespace: string | null;\n};\n\nexport type ControlContextApi = {\n /** Global state (apiKey, available models/namespaces) */\n state: ControlState;\n /** Update global state (apiKey only) */\n setApiKey: (apiKey: string | null) => void;\n /** Fetch available models from backend */\n getAvailableModels: () => Promise<string[]>;\n /** Fetch authorized namespaces from backend */\n getAuthorizedNamespaces: () => Promise<string[]>;\n /** Get current thread's control state */\n getCurrentThreadControl: () => ThreadControlState;\n /** Select a model for the current thread (updates metadata + calls backend) */\n onModelSelect: (model: string) => Promise<void>;\n /** Select a namespace for the current thread (updates metadata only) */\n onNamespaceSelect: (namespace: string) => void;\n /** Whether the current thread is processing (disables control switching) */\n isProcessing: boolean;\n /** Mark control state as synced (called after chat starts) */\n markControlSynced: () => void;\n /** Get global control state */\n getControlState: () => ControlState;\n /** Subscribe to global state changes */\n onControlStateChange: (callback: (state: ControlState) => void) => () => void;\n\n // Legacy compatibility\n /** @deprecated Use getCurrentThreadControl().namespace instead */\n setState: (\n updates: Partial<{ namespace: string | null; apiKey: string | null }>,\n ) => void;\n};\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst API_KEY_STORAGE_KEY = \"aomi_api_key\";\n\n// =============================================================================\n// Context\n// =============================================================================\n\nconst ControlContext = createContext<ControlContextApi | null>(null);\n\n// =============================================================================\n// Hook\n// =============================================================================\n\nexport function useControl(): ControlContextApi {\n const ctx = useContext(ControlContext);\n if (!ctx) {\n throw new Error(\"useControl must be used within ControlContextProvider\");\n }\n return ctx;\n}\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nexport type ControlContextProviderProps = {\n children: ReactNode;\n backendApi: BackendApi;\n sessionId: string;\n publicKey?: string;\n /** Get metadata for a thread */\n getThreadMetadata: (threadId: string) => ThreadMetadata | undefined;\n /** Update metadata for a thread */\n updateThreadMetadata: (\n threadId: string,\n updates: Partial<ThreadMetadata>,\n ) => void;\n};\n\nexport function ControlContextProvider({\n children,\n backendApi,\n sessionId,\n publicKey,\n getThreadMetadata,\n updateThreadMetadata,\n}: ControlContextProviderProps) {\n const [state, setStateInternal] = useState<ControlState>(() => ({\n apiKey: null,\n availableModels: [],\n authorizedNamespaces: [],\n defaultModel: null,\n defaultNamespace: null,\n }));\n\n const stateRef = useRef(state);\n stateRef.current = state;\n\n const backendApiRef = useRef(backendApi);\n backendApiRef.current = backendApi;\n\n const sessionIdRef = useRef(sessionId);\n sessionIdRef.current = sessionId;\n\n const publicKeyRef = useRef(publicKey);\n publicKeyRef.current = publicKey;\n\n const getThreadMetadataRef = useRef(getThreadMetadata);\n getThreadMetadataRef.current = getThreadMetadata;\n\n const updateThreadMetadataRef = useRef(updateThreadMetadata);\n updateThreadMetadataRef.current = updateThreadMetadata;\n\n const callbacks = useRef<Set<(state: ControlState) => void>>(new Set());\n\n // Compute isProcessing from current thread's control state\n const currentThreadMetadata = getThreadMetadata(sessionId);\n const isProcessing = currentThreadMetadata?.control?.isProcessing ?? false;\n\n // Load API key from localStorage on mount\n useEffect(() => {\n try {\n const storedApiKey =\n globalThis.localStorage?.getItem(API_KEY_STORAGE_KEY) ?? null;\n if (storedApiKey) {\n setStateInternal((prev) => ({ ...prev, apiKey: storedApiKey }));\n }\n } catch {\n // localStorage not available\n }\n }, []);\n\n // Persist API key to localStorage\n useEffect(() => {\n try {\n if (state.apiKey) {\n globalThis.localStorage?.setItem(API_KEY_STORAGE_KEY, state.apiKey);\n } else {\n globalThis.localStorage?.removeItem(API_KEY_STORAGE_KEY);\n }\n } catch {\n // localStorage not available\n }\n }, [state.apiKey]);\n\n // Fetch namespaces when apiKey changes\n useEffect(() => {\n const fetchNamespaces = async () => {\n try {\n const namespaces = await backendApiRef.current.getNamespaces(\n sessionIdRef.current,\n publicKeyRef.current,\n stateRef.current.apiKey ?? undefined,\n );\n const defaultNs = namespaces.includes(\"default\")\n ? \"default\"\n : (namespaces[0] ?? null);\n setStateInternal((prev) => ({\n ...prev,\n authorizedNamespaces: namespaces,\n defaultNamespace: defaultNs,\n }));\n } catch (error) {\n console.error(\"Failed to fetch namespaces:\", error);\n setStateInternal((prev) => ({\n ...prev,\n authorizedNamespaces: [\"default\"],\n defaultNamespace: \"default\",\n }));\n }\n };\n void fetchNamespaces();\n }, [state.apiKey]);\n\n // Fetch models on mount\n useEffect(() => {\n const fetchModels = async () => {\n try {\n const models = await backendApiRef.current.getModels(\n sessionIdRef.current,\n );\n setStateInternal((prev) => ({\n ...prev,\n availableModels: models,\n defaultModel: models[0] ?? null,\n }));\n } catch (error) {\n console.error(\"Failed to fetch models:\", error);\n }\n };\n void fetchModels();\n }, []);\n\n // ---------------------------------------------------------------------------\n // API Key\n // ---------------------------------------------------------------------------\n const setApiKey = useCallback((apiKey: string | null) => {\n setStateInternal((prev) => {\n const next = { ...prev, apiKey: apiKey === \"\" ? null : apiKey };\n callbacks.current.forEach((cb) => cb(next));\n return next;\n });\n }, []);\n\n // ---------------------------------------------------------------------------\n // Fetch available options\n // ---------------------------------------------------------------------------\n const getAvailableModels = useCallback(async (): Promise<string[]> => {\n try {\n const models = await backendApiRef.current.getModels(\n sessionIdRef.current,\n );\n setStateInternal((prev) => ({\n ...prev,\n availableModels: models,\n defaultModel: prev.defaultModel ?? models[0] ?? null,\n }));\n return models;\n } catch (error) {\n console.error(\"Failed to fetch models:\", error);\n return [];\n }\n }, []);\n\n const getAuthorizedNamespaces = useCallback(async (): Promise<string[]> => {\n try {\n const namespaces = await backendApiRef.current.getNamespaces(\n sessionIdRef.current,\n publicKeyRef.current,\n stateRef.current.apiKey ?? undefined,\n );\n const defaultNs = namespaces.includes(\"default\")\n ? \"default\"\n : (namespaces[0] ?? null);\n setStateInternal((prev) => ({\n ...prev,\n authorizedNamespaces: namespaces,\n defaultNamespace: defaultNs,\n }));\n return namespaces;\n } catch (error) {\n console.error(\"Failed to fetch namespaces:\", error);\n setStateInternal((prev) => ({\n ...prev,\n authorizedNamespaces: [\"default\"],\n defaultNamespace: \"default\",\n }));\n return [\"default\"];\n }\n }, []);\n\n // ---------------------------------------------------------------------------\n // Per-thread control state\n // ---------------------------------------------------------------------------\n const getCurrentThreadControl = useCallback((): ThreadControlState => {\n const metadata = getThreadMetadataRef.current(sessionIdRef.current);\n return metadata?.control ?? initThreadControl();\n }, []);\n\n const onModelSelect = useCallback(async (model: string) => {\n const threadId = sessionIdRef.current;\n const currentControl =\n getThreadMetadataRef.current(threadId)?.control ??\n initThreadControl();\n const isProcessing = currentControl.isProcessing;\n\n console.log(\"[control-context] onModelSelect called\", {\n model,\n isProcessing,\n threadId,\n });\n\n if (isProcessing) {\n console.warn(\"[control-context] Cannot switch model while processing\");\n return;\n }\n\n const namespace =\n currentControl.namespace ??\n stateRef.current.defaultNamespace ??\n \"default\";\n\n console.log(\"[control-context] onModelSelect updating metadata\", {\n threadId,\n model,\n namespace,\n currentControl,\n });\n\n // Update thread metadata with new model and mark as dirty\n updateThreadMetadataRef.current(threadId, {\n control: {\n ...currentControl,\n model,\n namespace,\n controlDirty: true,\n },\n });\n\n console.log(\"[control-context] onModelSelect calling backend setModel\", {\n threadId,\n model,\n namespace,\n backendUrl: backendApiRef.current,\n });\n\n try {\n const result = await backendApiRef.current.setModel(\n threadId,\n model,\n namespace,\n stateRef.current.apiKey ?? undefined,\n );\n console.log(\"[control-context] onModelSelect backend result\", result);\n } catch (err) {\n console.error(\"[control-context] setModel failed:\", err);\n throw err;\n }\n }, []);\n\n const onNamespaceSelect = useCallback((namespace: string) => {\n const threadId = sessionIdRef.current;\n const currentControl =\n getThreadMetadataRef.current(threadId)?.control ??\n initThreadControl();\n const isProcessing = currentControl.isProcessing;\n\n console.log(\"[control-context] onNamespaceSelect called\", {\n namespace,\n isProcessing,\n threadId,\n });\n\n if (isProcessing) {\n console.warn(\n \"[control-context] Cannot switch namespace while processing\",\n );\n return;\n }\n\n console.log(\"[control-context] onNamespaceSelect updating metadata\", {\n threadId,\n namespace,\n currentControl,\n });\n\n // Update thread metadata with new namespace and mark as dirty\n updateThreadMetadataRef.current(threadId, {\n control: {\n ...currentControl,\n namespace,\n controlDirty: true,\n },\n });\n\n console.log(\"[control-context] onNamespaceSelect metadata updated\");\n }, []);\n\n const markControlSynced = useCallback(() => {\n const threadId = sessionIdRef.current;\n const currentControl =\n getThreadMetadataRef.current(threadId)?.control ??\n initThreadControl();\n\n if (currentControl.controlDirty) {\n updateThreadMetadataRef.current(threadId, {\n control: {\n ...currentControl,\n controlDirty: false,\n },\n });\n }\n }, []);\n\n // ---------------------------------------------------------------------------\n // Global state access\n // ---------------------------------------------------------------------------\n const getControlState = useCallback(() => stateRef.current, []);\n\n const onControlStateChange = useCallback(\n (callback: (state: ControlState) => void) => {\n callbacks.current.add(callback);\n return () => {\n callbacks.current.delete(callback);\n };\n },\n [],\n );\n\n // ---------------------------------------------------------------------------\n // Legacy compatibility\n // ---------------------------------------------------------------------------\n const setState = useCallback(\n (updates: Partial<{ namespace: string | null; apiKey: string | null }>) => {\n if (\"apiKey\" in updates) {\n setApiKey(updates.apiKey ?? null);\n }\n if (\n \"namespace\" in updates &&\n updates.namespace !== undefined &&\n updates.namespace !== null\n ) {\n onNamespaceSelect(updates.namespace);\n }\n },\n [setApiKey, onNamespaceSelect],\n );\n\n return (\n <ControlContext.Provider\n value={{\n state,\n setApiKey,\n getAvailableModels,\n getAuthorizedNamespaces,\n getCurrentThreadControl,\n onModelSelect,\n onNamespaceSelect,\n isProcessing,\n markControlSynced,\n getControlState,\n onControlStateChange,\n setState,\n }}\n >\n {children}\n </ControlContext.Provider>\n );\n}\n","// UUID polyfill for Safari and older browsers\nexport function generateUUID(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n \n // Fallback for browsers without crypto.randomUUID\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n","import { generateUUID } from \"../utils/uuid\";\nimport 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 ThreadControlState = {\n /** Selected model for this thread (human-readable label) */\n model: string | null;\n /** Selected namespace for this thread */\n namespace: string | null;\n /** Whether control state has changed but chat hasn't started yet */\n controlDirty: boolean;\n /** Whether this thread is currently processing (assistant generating) */\n isProcessing: boolean;\n};\n\nexport type ThreadMetadata = {\n title: string;\n status: ThreadStatus;\n lastActiveAt?: string | number;\n /** Per-thread control state (model, namespace selection) */\n control: ThreadControlState;\n};\n\n/** Create default control state for a new thread */\nexport function initThreadControl(): ThreadControlState {\n return {\n model: null,\n namespace: null,\n controlDirty: false,\n isProcessing: false,\n };\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 ?? generateUUID();\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 control: initThreadControl(),\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 control: initThreadControl(),\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 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","\"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 { useControl } from \"../contexts/control-context\";\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\";\nimport { initThreadControl } from \"../state/thread-store\";\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 const { getControlState, getCurrentThreadControl } = useControl();\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 getNamespace: () =>\n getCurrentThreadControl().namespace ??\n getControlState().defaultNamespace ??\n \"default\",\n getApiKey: () => getControlState().apiKey,\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 // Sync isRunning to thread metadata for control context\n useEffect(() => {\n const threadId = threadContext.currentThreadId;\n const currentMeta = threadContext.getThreadMetadata(threadId);\n if (currentMeta && currentMeta.control.isProcessing !== isRunning) {\n threadContext.updateThreadMetadata(threadId, {\n control: {\n ...currentMeta.control,\n isProcessing: isRunning,\n },\n });\n }\n }, [isRunning, threadContext]);\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 const existingControl = newMetadata.get(thread.session_id)?.control;\n newMetadata.set(thread.session_id, {\n title,\n status: thread.is_archived ? \"archived\" : \"regular\",\n lastActiveAt: lastActive,\n control: existingControl ?? initThreadControl(),\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 getNamespace: () =>\n getCurrentThreadControl().namespace ??\n getControlState().defaultNamespace ??\n \"default\",\n getApiKey: () => getControlState().apiKey,\n }),\n [\n backendApiRef,\n polling,\n user.address,\n backendStateRef,\n setIsRunning,\n threadContext,\n threadContext.currentThreadId,\n threadContext.allThreadsMetadata,\n getControlState,\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 control: existing?.control ?? initThreadControl(),\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 // TODO: Disable it for now, we don't need async execution\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 getNamespace: () => string;\n getApiKey?: () => string | null;\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 getNamespace: options.getNamespace,\n getApiKey: options.getApiKey,\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 getNamespace: () => string;\n getApiKey?: () => string | null;\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 namespace = this.config.getNamespace();\n const publicKey = this.config.getPublicKey?.();\n const apiKey = this.config.getApiKey?.() ?? undefined;\n\n try {\n this.markRunning(threadId, true);\n const response = await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n namespace,\n publicKey,\n apiKey,\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 namespace = this.config.getNamespace();\n const publicKey = this.config.getPublicKey?.();\n const apiKey = this.config.getApiKey?.() ?? undefined;\n\n for (const text of pending) {\n try {\n await this.config.backendApiRef.current.postChatMessage(\n backendThreadId,\n text,\n namespace,\n publicKey,\n apiKey,\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 { generateUUID } from \"../utils/uuid\";\nimport 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 {\n initThreadControl,\n type ThreadMetadata,\n} 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 getNamespace: () => string;\n getApiKey?: () => string | null;\n};\n\nexport function buildThreadListAdapter({\n backendStateRef,\n backendApiRef,\n threadContext,\n currentThreadIdRef,\n polling,\n userAddress,\n setIsRunning,\n getNamespace,\n getApiKey,\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 control: initThreadControl(),\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(backendState.creatingThreadId ?? generateUUID());\n return;\n }\n\n const threadId = generateUUID();\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 control: existing?.control ?? initThreadControl(),\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 const namespace = getNamespace();\n const apiKey = getApiKey?.() ?? undefined;\n for (const text of pendingMessages) {\n try {\n await backendApiRef.current.postChatMessage(\n backendId,\n text,\n namespace,\n userAddress,\n apiKey,\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 ?? 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 control: initThreadControl(),\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":";;;;;;;;;;;;;;;;;;;;;AA8BA,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;AAC1B,IAAM,iBAAiB;AAEvB,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,WACA,QACY;AACZ,QAAM,QAAQ,cAAc,OAAO;AACnC,QAAM,MAAM,GAAG,UAAU,GAAG,IAAI,GAAG,KAAK;AAExC,QAAM,UAAU,IAAI,QAAQ,kBAAkB,SAAS,CAAC;AACxD,MAAI,QAAQ;AACV,YAAQ,IAAI,gBAAgB,MAAM;AAAA,EACpC;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR;AAAA,EACF,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,WACA,WACA,QAC0B;AAC1B,UAAM,UAAmC,EAAE,SAAS,UAAU;AAC9D,QAAI,WAAW;AACb,cAAQ,aAAa;AAAA,IACvB;AAEA,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,WACA,WACA,QACmB;AACnB,UAAM,MAAM,IAAI,IAAI,2BAA2B,KAAK,UAAU;AAC9D,QAAI,WAAW;AACb,UAAI,aAAa,IAAI,cAAc,SAAS;AAAA,IAC9C;AAEA,YAAQ,IAAI,8BAA8B;AAAA,MACxC,YAAY,KAAK;AAAA,MACjB,SAAS,IAAI,SAAS;AAAA,MACtB;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,UAAU,IAAI,QAAQ,kBAAkB,SAAS,CAAC;AACxD,QAAI,QAAQ;AACV,cAAQ,IAAI,gBAAgB,MAAM;AAAA,IACpC;AAEA,UAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG,EAAE,QAAQ,CAAC;AAExD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,EAAE;AAAA,IACrE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,WAAsC;AACpD,UAAM,MAAM,IAAI,IAAI,uBAAuB,KAAK,UAAU;AAE1D,YAAQ,IAAI,0BAA0B;AAAA,MACpC,YAAY,KAAK;AAAA,MACjB,SAAS,IAAI,SAAS;AAAA,MACtB;AAAA,IACF,CAAC;AAED,UAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,MAC3C,SAAS,kBAAkB,SAAS;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,8BAA8B,SAAS,MAAM,EAAE;AAAA,IACjE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SACJ,WACA,KACA,WACA,QAMC;AACD,UAAM,UAAmC,EAAE,IAAI;AAC/C,QAAI,WAAW;AACb,cAAQ,YAAY;AAAA,IACtB;AAEA,WAAO,UAKJ,KAAK,YAAY,sBAAsB,SAAS,WAAW,MAAM;AAAA,EACtE;AACF;;;AC9VA,SAAS,WAAAE,gBAAe;;;ACAxB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;;;ACTA,SAAS,eAAuB;AACrC,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;AAC5E,WAAO,OAAO,WAAW;AAAA,EAC3B;AAGA,SAAO,uCAAuC,QAAQ,SAAS,CAAC,MAAM;AACpE,UAAM,IAAK,KAAK,OAAO,IAAI,KAAM;AACjC,UAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAO;AACtC,WAAO,EAAE,SAAS,EAAE;AAAA,EACtB,CAAC;AACH;;;ACPA,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;AAwBO,SAAS,oBAAwC;AACtD,SAAO;AAAA,IACL,OAAO;AAAA,IACP,WAAW;AAAA,IACX,cAAc;AAAA,IACd,cAAc;AAAA,EAChB;AACF;AAcO,IAAM,cAAN,MAAkB;AAAA,EAKvB,YAAY,SAA8B;AAH1C,SAAQ,YAAY,oBAAI,IAAgB;AA0BxC,qBAAY,CAAC,aAAuC;AAClD,WAAK,UAAU,IAAI,QAAQ;AAC3B,aAAO,MAAM;AACX,aAAK,UAAU,OAAO,QAAQ;AAAA,MAChC;AAAA,IACF;AAEA,uBAAc,MAAqB,KAAK;AA0DxC,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;AAnNjE;AAoNI,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;AAxOF;AA6EI,UAAM,mBAAkB,wCAAS,oBAAT,YAA4B,aAAa;AACjE,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,YACrC,SAAS,kBAAkB;AAAA,UAC7B;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,QACrC,SAAS,kBAAkB;AAAA,MAC7B,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;;;AF2MI;AAhXJ,IAAM,sBAAsB;AAM5B,IAAM,iBAAiB,cAAwC,IAAI;AAM5D,SAAS,aAAgC;AAC9C,QAAM,MAAM,WAAW,cAAc;AACrC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,SAAO;AACT;AAoBO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgC;AAjHhC;AAkHE,QAAM,CAAC,OAAO,gBAAgB,IAAI,SAAuB,OAAO;AAAA,IAC9D,QAAQ;AAAA,IACR,iBAAiB,CAAC;AAAA,IAClB,sBAAsB,CAAC;AAAA,IACvB,cAAc;AAAA,IACd,kBAAkB;AAAA,EACpB,EAAE;AAEF,QAAM,WAAW,OAAO,KAAK;AAC7B,WAAS,UAAU;AAEnB,QAAM,gBAAgB,OAAO,UAAU;AACvC,gBAAc,UAAU;AAExB,QAAM,eAAe,OAAO,SAAS;AACrC,eAAa,UAAU;AAEvB,QAAM,eAAe,OAAO,SAAS;AACrC,eAAa,UAAU;AAEvB,QAAM,uBAAuB,OAAO,iBAAiB;AACrD,uBAAqB,UAAU;AAE/B,QAAM,0BAA0B,OAAO,oBAAoB;AAC3D,0BAAwB,UAAU;AAElC,QAAM,YAAY,OAA2C,oBAAI,IAAI,CAAC;AAGtE,QAAM,wBAAwB,kBAAkB,SAAS;AACzD,QAAM,gBAAe,0EAAuB,YAAvB,mBAAgC,iBAAhC,YAAgD;AAGrE,YAAU,MAAM;AAnJlB,QAAAC,KAAAC;AAoJI,QAAI;AACF,YAAM,gBACJA,OAAAD,MAAA,WAAW,iBAAX,gBAAAA,IAAyB,QAAQ,yBAAjC,OAAAC,MAAyD;AAC3D,UAAI,cAAc;AAChB,yBAAiB,CAAC,SAAU,iCAAK,OAAL,EAAW,QAAQ,aAAa,EAAE;AAAA,MAChE;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AAhKlB,QAAAD,KAAAC;AAiKI,QAAI;AACF,UAAI,MAAM,QAAQ;AAChB,SAAAD,MAAA,WAAW,iBAAX,gBAAAA,IAAyB,QAAQ,qBAAqB,MAAM;AAAA,MAC9D,OAAO;AACL,SAAAC,MAAA,WAAW,iBAAX,gBAAAA,IAAyB,WAAW;AAAA,MACtC;AAAA,IACF,SAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,MAAM,MAAM,CAAC;AAGjB,YAAU,MAAM;AACd,UAAM,kBAAkB,YAAY;AA9KxC,UAAAD,KAAAC;AA+KM,UAAI;AACF,cAAM,aAAa,MAAM,cAAc,QAAQ;AAAA,UAC7C,aAAa;AAAA,UACb,aAAa;AAAA,WACbD,MAAA,SAAS,QAAQ,WAAjB,OAAAA,MAA2B;AAAA,QAC7B;AACA,cAAM,YAAY,WAAW,SAAS,SAAS,IAC3C,aACCC,MAAA,WAAW,CAAC,MAAZ,OAAAA,MAAiB;AACtB,yBAAiB,CAAC,SAAU,iCACvB,OADuB;AAAA,UAE1B,sBAAsB;AAAA,UACtB,kBAAkB;AAAA,QACpB,EAAE;AAAA,MACJ,SAAS,OAAO;AACd,gBAAQ,MAAM,+BAA+B,KAAK;AAClD,yBAAiB,CAAC,SAAU,iCACvB,OADuB;AAAA,UAE1B,sBAAsB,CAAC,SAAS;AAAA,UAChC,kBAAkB;AAAA,QACpB,EAAE;AAAA,MACJ;AAAA,IACF;AACA,SAAK,gBAAgB;AAAA,EACvB,GAAG,CAAC,MAAM,MAAM,CAAC;AAGjB,YAAU,MAAM;AACd,UAAM,cAAc,YAAY;AAC9B,UAAI;AACF,cAAM,SAAS,MAAM,cAAc,QAAQ;AAAA,UACzC,aAAa;AAAA,QACf;AACA,yBAAiB,CAAC,SAAM;AAhNhC,cAAAD;AAgNoC,kDACvB,OADuB;AAAA,YAE1B,iBAAiB;AAAA,YACjB,eAAcA,MAAA,OAAO,CAAC,MAAR,OAAAA,MAAa;AAAA,UAC7B;AAAA,SAAE;AAAA,MACJ,SAAS,OAAO;AACd,gBAAQ,MAAM,2BAA2B,KAAK;AAAA,MAChD;AAAA,IACF;AACA,SAAK,YAAY;AAAA,EACnB,GAAG,CAAC,CAAC;AAKL,QAAM,YAAY,YAAY,CAAC,WAA0B;AACvD,qBAAiB,CAAC,SAAS;AACzB,YAAM,OAAO,iCAAK,OAAL,EAAW,QAAQ,WAAW,KAAK,OAAO,OAAO;AAC9D,gBAAU,QAAQ,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;AAC1C,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAKL,QAAM,qBAAqB,YAAY,YAA+B;AACpE,QAAI;AACF,YAAM,SAAS,MAAM,cAAc,QAAQ;AAAA,QACzC,aAAa;AAAA,MACf;AACA,uBAAiB,CAAC,SAAM;AA/O9B,YAAAA,KAAAC;AA+OkC,gDACvB,OADuB;AAAA,UAE1B,iBAAiB;AAAA,UACjB,eAAcA,OAAAD,MAAA,KAAK,iBAAL,OAAAA,MAAqB,OAAO,CAAC,MAA7B,OAAAC,MAAkC;AAAA,QAClD;AAAA,OAAE;AACF,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,2BAA2B,KAAK;AAC9C,aAAO,CAAC;AAAA,IACV;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,0BAA0B,YAAY,YAA+B;AA3P7E,QAAAD,KAAAC;AA4PI,QAAI;AACF,YAAM,aAAa,MAAM,cAAc,QAAQ;AAAA,QAC7C,aAAa;AAAA,QACb,aAAa;AAAA,SACbD,MAAA,SAAS,QAAQ,WAAjB,OAAAA,MAA2B;AAAA,MAC7B;AACA,YAAM,YAAY,WAAW,SAAS,SAAS,IAC3C,aACCC,MAAA,WAAW,CAAC,MAAZ,OAAAA,MAAiB;AACtB,uBAAiB,CAAC,SAAU,iCACvB,OADuB;AAAA,QAE1B,sBAAsB;AAAA,QACtB,kBAAkB;AAAA,MACpB,EAAE;AACF,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,+BAA+B,KAAK;AAClD,uBAAiB,CAAC,SAAU,iCACvB,OADuB;AAAA,QAE1B,sBAAsB,CAAC,SAAS;AAAA,QAChC,kBAAkB;AAAA,MACpB,EAAE;AACF,aAAO,CAAC,SAAS;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,CAAC;AAKL,QAAM,0BAA0B,YAAY,MAA0B;AAzRxE,QAAAD;AA0RI,UAAM,WAAW,qBAAqB,QAAQ,aAAa,OAAO;AAClE,YAAOA,MAAA,qCAAU,YAAV,OAAAA,MAAqB,kBAAkB;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,YAAY,OAAO,UAAkB;AA9R7D,QAAAA,KAAAC,KAAA;AA+RI,UAAM,WAAW,aAAa;AAC9B,UAAM,kBACJA,OAAAD,MAAA,qBAAqB,QAAQ,QAAQ,MAArC,gBAAAA,IAAwC,YAAxC,OAAAC,MACA,kBAAkB;AACpB,UAAMC,gBAAe,eAAe;AAEpC,YAAQ,IAAI,0CAA0C;AAAA,MACpD;AAAA,MACA,cAAAA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAIA,eAAc;AAChB,cAAQ,KAAK,wDAAwD;AACrE;AAAA,IACF;AAEA,UAAM,aACJ,0BAAe,cAAf,YACA,SAAS,QAAQ,qBADjB,YAEA;AAEF,YAAQ,IAAI,qDAAqD;AAAA,MAC/D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,4BAAwB,QAAQ,UAAU;AAAA,MACxC,SAAS,iCACJ,iBADI;AAAA,QAEP;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,4DAA4D;AAAA,MACtE;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,cAAc;AAAA,IAC5B,CAAC;AAED,QAAI;AACF,YAAM,SAAS,MAAM,cAAc,QAAQ;AAAA,QACzC;AAAA,QACA;AAAA,QACA;AAAA,SACA,cAAS,QAAQ,WAAjB,YAA2B;AAAA,MAC7B;AACA,cAAQ,IAAI,kDAAkD,MAAM;AAAA,IACtE,SAAS,KAAK;AACZ,cAAQ,MAAM,sCAAsC,GAAG;AACvD,YAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,YAAY,CAAC,cAAsB;AA3V/D,QAAAF,KAAAC;AA4VI,UAAM,WAAW,aAAa;AAC9B,UAAM,kBACJA,OAAAD,MAAA,qBAAqB,QAAQ,QAAQ,MAArC,gBAAAA,IAAwC,YAAxC,OAAAC,MACA,kBAAkB;AACpB,UAAMC,gBAAe,eAAe;AAEpC,YAAQ,IAAI,8CAA8C;AAAA,MACxD;AAAA,MACA,cAAAA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAIA,eAAc;AAChB,cAAQ;AAAA,QACN;AAAA,MACF;AACA;AAAA,IACF;AAEA,YAAQ,IAAI,yDAAyD;AAAA,MACnE;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,4BAAwB,QAAQ,UAAU;AAAA,MACxC,SAAS,iCACJ,iBADI;AAAA,QAEP;AAAA,QACA,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,sDAAsD;AAAA,EACpE,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAoB,YAAY,MAAM;AAjY9C,QAAAF,KAAAC;AAkYI,UAAM,WAAW,aAAa;AAC9B,UAAM,kBACJA,OAAAD,MAAA,qBAAqB,QAAQ,QAAQ,MAArC,gBAAAA,IAAwC,YAAxC,OAAAC,MACA,kBAAkB;AAEpB,QAAI,eAAe,cAAc;AAC/B,8BAAwB,QAAQ,UAAU;AAAA,QACxC,SAAS,iCACJ,iBADI;AAAA,UAEP,cAAc;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,CAAC;AAKL,QAAM,kBAAkB,YAAY,MAAM,SAAS,SAAS,CAAC,CAAC;AAE9D,QAAM,uBAAuB;AAAA,IAC3B,CAAC,aAA4C;AAC3C,gBAAU,QAAQ,IAAI,QAAQ;AAC9B,aAAO,MAAM;AACX,kBAAU,QAAQ,OAAO,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAKA,QAAM,WAAW;AAAA,IACf,CAAC,YAA0E;AApa/E,UAAAD;AAqaM,UAAI,YAAY,SAAS;AACvB,mBAAUA,MAAA,QAAQ,WAAR,OAAAA,MAAkB,IAAI;AAAA,MAClC;AACA,UACE,eAAe,WACf,QAAQ,cAAc,UACtB,QAAQ,cAAc,MACtB;AACA,0BAAkB,QAAQ,SAAS;AAAA,MACrC;AAAA,IACF;AAAA,IACA,CAAC,WAAW,iBAAiB;AAAA,EAC/B;AAEA,SACE;AAAA,IAAC,eAAe;AAAA,IAAf;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;AGrcA;AAAA,EACE,iBAAAG;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OACK;;;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,gBAAAC,YAAA;AAlKJ,IAAM,oBAAoBC,eAAmC,IAAI;AAM1D,SAAS,kBAAgC;AAC9C,QAAM,UAAUC,YAAW,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,YAAYC,QAA2B,IAAI;AACjD,MAAI,CAAC,UAAU,SAAS;AACtB,cAAU,UAAU,kBAAkB;AAAA,EACxC;AACA,QAAM,SAAS,UAAU;AAEzB,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAoB,cAAc;AAKpE,EAAAC,WAAU,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,oBAAoBC;AAAA,IACxB,CAAC,MAAc,aAA8B;AAC3C,aAAO,UAAkB,QAAQ,MAAM,QAAQ;AAAA,IACjD;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,eAAeA;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,uBAAuBA;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,gBAAAP,KAAC,kBAAkB,UAAlB,EAA2B,OAAO,cAChC,UACH;AAEJ;;;AGnNA;AAAA,EACE,iBAAAQ;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,YAAAC;AAAA,OAEK;AA+FH,gBAAAC,YAAA;AA7DJ,IAAM,sBAAsBC,eAA6C,IAAI;AAMtE,SAAS,kBAA0C;AACxD,QAAM,UAAUC,YAAW,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,IAAIC,UAAyB,CAAC,CAAC;AAErE,QAAM,mBAAmBC,aAAY,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,sBAAsBA,aAAY,CAAC,OAAe;AACtD,qBAAiB,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAAA,EAC5D,GAAG,CAAC,CAAC;AAEL,QAAM,WAAWA,aAAY,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,gBAAAJ,KAAC,oBAAoB,UAApB,EAA6B,OAC3B,UACH;AAEJ;;;ACzGA;AAAA,EACE,iBAAAK;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,UAAAC;AAAA,EACA;AAAA,OACK;AA+DH,gBAAAC,YAAA;AA7BJ,IAAM,qBAAqBC,eAAoC,IAAI;AAE5D,SAAS,mBAAkC;AAChD,QAAM,UAAUC,YAAW,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,WAAWC,QAA2B,IAAI;AAChD,MAAI,CAAC,SAAS,SAAS;AACrB,aAAS,UAAU,IAAI,YAAY,EAAE,gBAAgB,CAAC;AAAA,EACxD;AACA,QAAM,QAAQ,SAAS;AACvB,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,SACE,gBAAAH,KAAC,mBAAmB,UAAnB,EAA4B,OAC1B,UACH;AAEJ;AAEO,SAAS,2BAAgD;AAC9D,QAAM,EAAE,iBAAiB,kBAAkB,IAAI,iBAAiB;AAChE,SAAO;AAAA,IACL,MAAM,kBAAkB,eAAe;AAAA,IACvC,CAAC,iBAAiB,iBAAiB;AAAA,EACrC;AACF;AAEO,SAAS,2BAAuD;AACrE,QAAM,EAAE,iBAAiB,kBAAkB,IAAI,iBAAiB;AAChE,SAAO;AAAA,IACL,MAAM,kBAAkB,eAAe;AAAA,IACvC,CAAC,iBAAiB,iBAAiB;AAAA,EACrC;AACF;;;ACzFA;AAAA,EACE,iBAAAI;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAEK;AAiFH,gBAAAC,YAAA;AAjEJ,IAAM,cAAcC,eAA4C,MAAS;AAElE,SAAS,UAAU;AACxB,QAAM,UAAUC,YAAW,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,IAAIC,UAAoB;AAAA,IAC/C,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAGD,QAAM,UAAUC,QAAO,IAAI;AAC3B,UAAQ,UAAU;AAGlB,QAAM,uBAAuBA;AAAA,IAC3B,oBAAI,IAAI;AAAA,EACV;AAEA,QAAM,UAAUC,aAAY,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,eAAeA,aAAY,MAAM,QAAQ,SAAS,CAAC,CAAC;AAG1D,QAAM,oBAAoBA;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,gBAAAL;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,SAAS,eAAAM,cAAa,aAAAC,YAAW,WAAAC,UAAS,UAAAC,eAAc;AAExD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;;;ACPP,SAAS,eAAAC,cAAa,UAAAC,SAAQ,YAAAC,iBAAgB;;;ACI9C,SAAS,YAA6B;AACtC,SAAS,eAAe;AAMjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,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;;;AC7CO,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;AAzD3D;AA0DI,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,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,aAAY,gBAAK,QAAO,iBAAZ;AAClB,UAAM,UAAS,sBAAK,QAAO,cAAZ,4CAA6B;AAE5C,QAAI;AACF,WAAK,YAAY,UAAU,IAAI;AAC/B,YAAM,WAAW,MAAM,KAAK,OAAO,cAAc,QAAQ;AAAA,QACvD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAGA,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;AA9H3C;AA+HI,UAAM,eAAe,KAAK,OAAO,gBAAgB;AACjD,UAAM,UAAU,mBAAmB,cAAc,QAAQ;AACzD,QAAI,CAAC,QAAQ,OAAQ;AACrB,UAAM,kBAAkB,gBAAgB,cAAc,QAAQ;AAC9D,UAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAM,aAAY,gBAAK,QAAO,iBAAZ;AAClB,UAAM,UAAS,sBAAK,QAAO,cAAZ,4CAA6B;AAE5C,eAAW,QAAQ,SAAS;AAC1B,UAAI;AACF,cAAM,KAAK,OAAO,cAAc,QAAQ;AAAA,UACtC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;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;AAvJjC;AAwJI,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;AA3K1D;AA4KI,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;;;AC5JO,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;;;AJ7EO,SAAS,uBACd,YACA,SACA;AACA,QAAM,gBAAgB,iBAAiB;AACvC,QAAM,mBAAmBE,QAAsB,aAAa;AAC5D,mBAAiB,UAAU;AAC3B,QAAM,gBAAgBA,QAAO,UAAU;AACvC,gBAAc,UAAU;AACxB,QAAM,kBAAkBA,QAAqB,mBAAmB,CAAC;AAEjE,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAEhD,QAAM,uBACJD,QAAO,IAAI;AACb,QAAM,aAAyDA,QAAO,IAAI;AAC1E,QAAM,iBAAiBA,QAAoB,oBAAI,IAAI,CAAC;AAEpD,MAAI,CAAC,WAAW,SAAS;AACvB,eAAW,UAAU,IAAI,kBAAkB;AAAA,MACzC;AAAA,MACA;AAAA,MACA,eAAe,CAAC,UAAkB,SAAgC;AAnDxE;AAoDQ,mCAAqB,YAArB,mBAA8B,QAAQ,UAAU;AAAA,MAClD;AAAA,MACA,cAAc,QAAQ;AAAA,MACtB,cAAc,QAAQ;AAAA,MACtB,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,QAAQ;AAAA,MACtB,cAAc,QAAQ;AAAA,MACtB,WAAW,QAAQ;AAAA,MACnB,cAAc,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AAEA,QAAM,qBAAqBE,aAAY,OAAO,aAAqB;AAnFrE;AAoFI,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,aAAQ,iBAAR;AAClB,YAAM,QAAQ,MAAM,cAAc,QAAQ;AAAA,QACxC;AAAA,QACA;AAAA,MACF;AACA,iCAAqB,YAArB,mBAA8B,QAAQ,UAAU,MAAM;AACtD,YAAI,WAAM,kBAAN,mBAAqB,WAAU,QAAQ,cAAc;AACvD,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;AAkBO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;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,QACrC,SAAS,kBAAkB;AAAA,MAC7B,CAAC;AAAA,IACH;AACA,kBAAc,kBAAkB,UAAU,CAAC,CAAC;AAC5C,kBAAc,mBAAmB,QAAQ;AACzC,iBAAa,KAAK;AAClB,kBAAc,kBAAkB;AAAA,EAClC;AAEA,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;AAEA,SAAO;AAAA,IACL,UAAU,cAAc;AAAA,IACxB,SAAS;AAAA,IACT;AAAA,IAEA,qBAAqB,YAAY;AAzIrC;AA0IM,YAAM,YAAY,oBAAoB;AACtC,UAAI,WAAW;AACb,6BAAqB,SAAS;AAC9B;AAAA,MACF;AAEA,UAAI,aAAa,qBAAqB;AACpC,8BAAqB,kBAAa,qBAAb,YAAiC,aAAa,CAAC;AACpE;AAAA,MACF;AAEA,YAAM,WAAW,aAAa;AAC9B,2BAAqB,QAAQ;AAE7B,YAAM,gBAAgB,cAAc,QACjC,aAAa,UAAU,WAAW,EAClC,KAAK,OAAO,cAAc;AA1JnC,YAAAC,KAAA;AA2JU,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;AAtKpD,cAAAA,KAAAC,KAAA;AAuKY,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,gBAAM,WAAW,KAAK,IAAI,UAAU;AACpC,gBAAM,cACJ,qCAAU,YAAW,aAAa,aAAa;AACjD,eAAK,IAAI,YAAY;AAAA,YACnB,QAAOD,MAAA,qCAAU,UAAV,OAAAA,MAAmB;AAAA,YAC1B,QAAQ;AAAA,YACR,eAAcC,MAAA,qCAAU,iBAAV,OAAAA,OAA0B,oBAAI,KAAK,GAAE,YAAY;AAAA,YAC/D,UAAS,0CAAU,YAAV,YAAqB,kBAAkB;AAAA,UAClD,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,gBAAM,YAAY,aAAa;AAC/B,gBAAM,UAAS,8DAAiB;AAChC,qBAAW,QAAQ,iBAAiB;AAClC,gBAAI;AACF,oBAAM,cAAc,QAAQ;AAAA,gBAC1B;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF,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/M1B,YAAAD;AAgNU,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;AA3O5D;AA4OM,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,gBACrC,SAAS,kBAAkB;AAAA,cAC7B,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;;;ACjUA,SAAS,iBAAAE,gBAAe,cAAAC,mBAAkB;AA6F1C,IAAM,qBAAqBD,eAAqC,IAAI;AAE7D,IAAM,yBAAyB,mBAAmB;AAkClD,SAAS,iBAAiC;AAC/C,QAAM,UAAUC,YAAW,kBAAkB;AAC7C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;;;AP8XM,gBAAAC,YAAA;AAleC,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;AAC1D,QAAM,EAAE,iBAAiB,wBAAwB,IAAI,WAAW;AAEhE,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,IACA,cAAc,MAAG;AA/DrB;AAgEM,iDAAwB,EAAE,cAA1B,YACA,gBAAgB,EAAE,qBADlB,YAEA;AAAA;AAAA,IACF,WAAW,MAAM,gBAAgB,EAAE;AAAA,EACrC,CAAC;AAKD,EAAAC,WAAU,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,mBAAmBC,QAAO,aAAa;AAC7C,mBAAiB,UAAU;AAE3B,QAAM,qBAAqBA,QAAO,cAAc,eAAe;AAC/D,EAAAD,WAAU,MAAM;AACd,uBAAmB,UAAU,cAAc;AAAA,EAC7C,GAAG,CAAC,cAAc,eAAe,CAAC;AAKlC,EAAAA,WAAU,MAAM;AACd,SAAK,mBAAmB,cAAc,eAAe;AAAA,EACvD,GAAG,CAAC,oBAAoB,cAAc,eAAe,CAAC;AAEtD,EAAAA,WAAU,MAAM;AACd,UAAM,WAAW,cAAc;AAC/B,iBAAa,gBAAgB,gBAAgB,SAAS,QAAQ,CAAC;AAAA,EACjE,GAAG,CAAC,iBAAiB,cAAc,cAAc,eAAe,CAAC;AAGjE,EAAAA,WAAU,MAAM;AACd,UAAM,WAAW,cAAc;AAC/B,UAAM,cAAc,cAAc,kBAAkB,QAAQ;AAC5D,QAAI,eAAe,YAAY,QAAQ,iBAAiB,WAAW;AACjE,oBAAc,qBAAqB,UAAU;AAAA,QAC3C,SAAS,iCACJ,YAAY,UADR;AAAA,UAEP,cAAc;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,WAAW,aAAa,CAAC;AAE7B,QAAM,kBAAkB,cAAc;AAAA,IACpC,cAAc;AAAA,EAChB;AACA,QAAM,oBAAoBE;AAAA,IACxB,MACE,gBAAgB,gBAAgB,SAAS,cAAc,eAAe;AAAA,IACxE;AAAA,MACE;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,IAChB;AAAA,EACF;AAKA,EAAAF,WAAU,MAAM;AACd,UAAM,cAAc,KAAK;AACzB,QAAI,CAAC,YAAa;AAElB,UAAM,kBAAkB,YAAY;AApJxC;AAqJM,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,gBAAM,mBAAkB,iBAAY,IAAI,OAAO,UAAU,MAAjC,mBAAoC;AAC5D,sBAAY,IAAI,OAAO,YAAY;AAAA,YACjC;AAAA,YACA,QAAQ,OAAO,cAAc,aAAa;AAAA,YAC1C,cAAc;AAAA,YACd,SAAS,4CAAmB,kBAAkB;AAAA,UAChD,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,oBAAoBE;AAAA,IACxB,MACE,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,KAAK;AAAA,MAClB;AAAA,MACA,cAAc,MAAG;AA5MzB;AA6MU,mDAAwB,EAAE,cAA1B,YACA,gBAAgB,EAAE,qBADlB,YAEA;AAAA;AAAA,MACF,WAAW,MAAM,gBAAgB,EAAE;AAAA,IACrC,CAAC;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAKA,EAAAF,WAAU,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;AArQ/D;AAsQY,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,cAC/D,UAAS,0CAAU,YAAV,YAAqB,kBAAkB;AAAA,YAClD,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,EAAAA,WAAU,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,EAAAA,WAAU,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,EAAAA,WAAU,MAAM;AACd,UAAM,cAAc,aAAa,UAAU,iBAAiB,CAAC,UAAU;AACrE,YAAM,UAAU,MAAM;AACtB,YAAM,UAAU,mCAAS;AAAA,IAQ3B,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,cAAc,mBAAmB,CAAC;AAKtC,QAAM,UAAU,wBAAwB;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,EAAAA,WAAU,MAAM;AACd,WAAO,MAAM;AACX,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAKZ,QAAM,cAAc,QAAQ;AAE5B,QAAM,cAAcG;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,mBAAmBA,aAAY,MAAM;AACzC,sBAAkB,OAAO,cAAc,eAAe;AAAA,EACxD,GAAG,CAAC,mBAAmB,cAAc,eAAe,CAAC;AAErD,QAAM,cAAcA;AAAA,IAClB,CAAC,aAAsB;AACrB,YAAM,KAAK,8BAAY,cAAc;AACrC,aAAO,cAAc,kBAAkB,EAAE;AAAA,IAC3C;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,eAAeA,aAAY,YAA6B;AAC5D,UAAM,kBAAkB,oBAAoB;AAC5C,WAAO,iBAAiB,QAAQ;AAAA,EAClC,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,eAAeA;AAAA,IACnB,OAAO,aAAqB;AAC1B,YAAM,kBAAkB,SAAS,QAAQ;AAAA,IAC3C;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AAEA,QAAM,eAAeA;AAAA,IACnB,OAAO,UAAkB,UAAkB;AACzC,YAAM,kBAAkB,SAAS,UAAU,KAAK;AAAA,IAClD;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AAEA,QAAM,gBAAgBA;AAAA,IACpB,OAAO,aAAqB;AAC1B,YAAM,kBAAkB,UAAU,QAAQ;AAAA,IAC5C;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AAEA,QAAM,eAAeA;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,iBAAiCD;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,gBAAAH,KAAC,0BAAuB,OAAO,gBAC7B,0BAAAA,KAAC,4BAAyB,SACvB,UACH,GACF;AAEJ;;;AVxeU,gBAAAK,YAAA;AAVH,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,aAAa;AACf,GAAuC;AACrC,QAAM,aAAaC,SAAQ,MAAM,IAAI,WAAW,UAAU,GAAG,CAAC,UAAU,CAAC;AAEzE,SACE,gBAAAD,KAAC,yBACC,0BAAAA,KAAC,+BACC,0BAAAA,KAAC,uBACC,0BAAAA,KAAC,oBAAiB,YACf,UACH,GACF,GACF,GACF;AAEJ;AAWA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AACF,GAAoC;AA5DpC;AA6DE,QAAM,gBAAgB,iBAAiB;AACvC,QAAM,EAAE,KAAK,IAAI,QAAQ;AAEzB,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,cAAc;AAAA,MACzB,YAAW,UAAK,YAAL,YAAgB;AAAA,MAC3B,mBAAmB,cAAc;AAAA,MACjC,sBAAsB,cAAc;AAAA,MAEpC,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAW,cAAc;AAAA,UAEzB,0BAAAA,KAAC,mBAAgB,YAAyB,UAAS;AAAA;AAAA,MACrD;AAAA;AAAA,EACF;AAEJ;;;AkB9EA,SAAS,eAAAE,cAAa,aAAAC,YAAW,YAAAC,iBAAgB;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,IAAIC;AAAA,IAChD,CAAC;AAAA,EACH;AAMA,EAAAC,WAAU,MAAM;AACd,UAAM,cAAcF;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,EAAAE,WAAU,MAAM;AACd,UAAM,cAAcF;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,iBAAiBG;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,uBAAuBA;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,iBAAiBA,aAAY,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,SAAS,eAAAC,cAAa,aAAAC,YAAW,YAAAC,iBAAgB;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,IAAIC,UAAyB,CAAC,CAAC;AAKrE,EAAAC,WAAU,MAAM;AACd,UAAM,cAAcF,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,cAAcG,aAAY,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","useMemo","_a","_b","isProcessing","createContext","useCallback","useContext","useEffect","useRef","useState","jsx","createContext","useContext","useRef","useState","useEffect","useCallback","sessionId","createContext","useCallback","useContext","useState","jsx","createContext","useContext","useState","useCallback","createContext","useContext","useRef","jsx","createContext","useContext","useRef","createContext","useCallback","useContext","useRef","useState","jsx","createContext","useContext","useState","useRef","useCallback","useCallback","useEffect","useMemo","useRef","useCallback","useRef","useState","_a","_b","useRef","useState","useCallback","_a","_b","createContext","useContext","jsx","useEffect","useRef","useMemo","useCallback","jsx","useMemo","useCallback","useEffect","useState","subscribe","useState","useEffect","useCallback","useCallback","useEffect","useState","notificationIdCounter","subscribe","useState","useEffect","useCallback"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aomi-labs/react",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Runtime, state, and utilities for the Aomi widget.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",