@naculus/connect-appkit-react 0.1.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.
- package/LICENSE +21 -0
- package/api-extractor.json +21 -0
- package/dist/client.cjs +2 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
- package/src/chain-abstraction/index.ts +8 -0
- package/src/chain-abstraction/useCompareCosts.ts +137 -0
- package/src/chain-abstraction/useExecuteRoute.ts +129 -0
- package/src/chain-abstraction/useRouteQuote.ts +168 -0
- package/src/client.test.ts +242 -0
- package/src/client.ts +265 -0
- package/src/hooks/useAccount.test.ts +67 -0
- package/src/hooks/useAccount.ts +37 -0
- package/src/hooks/useBalance.test.ts +459 -0
- package/src/hooks/useBalance.ts +170 -0
- package/src/hooks/useChain.test.ts +160 -0
- package/src/hooks/useChain.ts +53 -0
- package/src/hooks/useConnect.test.ts +112 -0
- package/src/hooks/useConnect.ts +29 -0
- package/src/hooks/useDisconnect.test.ts +75 -0
- package/src/hooks/useDisconnect.ts +32 -0
- package/src/hooks/useERC20Allowance.ts +93 -0
- package/src/hooks/useERC20Approve.ts +220 -0
- package/src/hooks/useERC20Transfer.ts +134 -0
- package/src/hooks/useERC20TransferSimulation.ts +147 -0
- package/src/hooks/useEmbeddedWallet.test.ts +266 -0
- package/src/hooks/useEmbeddedWallet.ts +181 -0
- package/src/hooks/useLastTx.test.ts +117 -0
- package/src/hooks/useLastTx.ts +73 -0
- package/src/hooks/useLookupAddress.ts +131 -0
- package/src/hooks/useNotification.ts +308 -0
- package/src/hooks/useResolveName.ts +128 -0
- package/src/hooks/useSIWxLogin.test.ts +307 -0
- package/src/hooks/useSIWxLogin.ts +163 -0
- package/src/hooks/useSIWxSession.test.ts +481 -0
- package/src/hooks/useSIWxSession.ts +290 -0
- package/src/hooks/useSendCalls.ts +103 -0
- package/src/hooks/useSendTransaction.test.ts +175 -0
- package/src/hooks/useSendTransaction.ts +80 -0
- package/src/hooks/useSendUserOperation.ts +313 -0
- package/src/hooks/useSession.ts +96 -0
- package/src/hooks/useSessionKeys.ts +356 -0
- package/src/hooks/useSignInWithEthereum.test.ts +224 -0
- package/src/hooks/useSignInWithEthereum.ts +46 -0
- package/src/hooks/useSignInWithX.test.ts +210 -0
- package/src/hooks/useSignInWithX.ts +141 -0
- package/src/hooks/useSignMessage.test.ts +151 -0
- package/src/hooks/useSignMessage.ts +65 -0
- package/src/hooks/useSimulateTransfer.ts +165 -0
- package/src/hooks/useSiwxAuthSession.test.ts +456 -0
- package/src/hooks/useSiwxAuthSession.ts +163 -0
- package/src/hooks/useSmartAccount.ts +194 -0
- package/src/hooks/useSwitchChain.ts +68 -0
- package/src/hooks/useTokenBalance.test.ts +337 -0
- package/src/hooks/useTokenBalance.ts +210 -0
- package/src/hooks/useTransactionSimulation.ts +401 -0
- package/src/hooks/useTxHistory.test.ts +108 -0
- package/src/hooks/useTxHistory.ts +83 -0
- package/src/hooks/useTxMonitor.test.ts +127 -0
- package/src/hooks/useTxMonitor.ts +178 -0
- package/src/hooks/useUserOpStatus.ts +245 -0
- package/src/hooks/useValidateDestination.test.ts +96 -0
- package/src/hooks/useValidateDestination.ts +72 -0
- package/src/hooks/useViemClient.test.ts +155 -0
- package/src/hooks/useViemClient.ts +65 -0
- package/src/hooks/useWallet.test.ts +133 -0
- package/src/hooks/useWallet.ts +39 -0
- package/src/hooks/useWeb3ErrorHandler.ts +102 -0
- package/src/index.ts +186 -0
- package/src/provider/Web3ConnectProvider.test.tsx +178 -0
- package/src/provider/Web3ConnectProvider.tsx +530 -0
- package/src/token-list/TokenSelector.tsx +351 -0
- package/src/token-list/defaults.ts +39 -0
- package/src/token-list/index.ts +14 -0
- package/src/token-list/useTokenList.ts +119 -0
- package/src/token-list/useTokenSearch.ts +99 -0
- package/src/types/index.ts +99 -0
- package/src/utils/chains.ts +115 -0
- package/src/utils/errorMessages.ts +142 -0
- package/src/utils/i18n.ts +90 -0
- package/src/wc-generated/components.ts +377 -0
- package/test/setup.ts +17 -0
- package/test/test-utils.tsx +78 -0
- package/tsup.config.ts +18 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/provider/Web3ConnectProvider.tsx","../src/client.ts","../src/utils/chains.ts","../src/hooks/useWallet.ts","../src/hooks/useConnect.ts","../src/hooks/useDisconnect.ts","../src/hooks/useAccount.ts","../src/hooks/useChain.ts","../src/hooks/useSignMessage.ts","../src/hooks/useSendTransaction.ts","../src/hooks/useSendCalls.ts","../src/hooks/useBalance.ts","../src/hooks/useTokenBalance.ts","../src/hooks/useERC20Transfer.ts","../src/hooks/useViemClient.ts","../src/hooks/useERC20Approve.ts","../src/hooks/useERC20Allowance.ts","../src/hooks/useEmbeddedWallet.ts","../src/hooks/useValidateDestination.ts","../src/utils/i18n.ts","../src/hooks/useSignInWithX.ts","../src/hooks/useSignInWithEthereum.ts","../src/hooks/useSiwxAuthSession.ts","../src/hooks/useSIWxLogin.ts","../src/hooks/useSIWxSession.ts","../src/hooks/useSessionKeys.ts","../src/hooks/useResolveName.ts","../src/hooks/useLookupAddress.ts","../src/hooks/useSession.ts","../src/hooks/useSwitchChain.ts","../src/hooks/useWeb3ErrorHandler.ts","../src/utils/errorMessages.ts","../src/hooks/useTxMonitor.ts","../src/hooks/useTxHistory.ts","../src/hooks/useTransactionSimulation.ts","../src/hooks/useERC20TransferSimulation.ts","../src/hooks/useLastTx.ts","../src/hooks/useSmartAccount.ts","../src/hooks/useSendUserOperation.ts","../src/hooks/useUserOpStatus.ts","../src/token-list/useTokenList.ts","../src/token-list/useTokenSearch.ts","../src/token-list/defaults.ts","../src/token-list/TokenSelector.tsx","../src/hooks/useNotification.ts","../src/hooks/useSimulateTransfer.ts","../src/chain-abstraction/useRouteQuote.ts","../src/chain-abstraction/useExecuteRoute.ts","../src/chain-abstraction/useCompareCosts.ts","../src/wc-generated/components.ts"],"sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useReducer, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport type { UniversalWalletSession } from \"@naculus/connect-core\";\nimport type { Web3State, Web3Actions, Web3ConnectConfig, ConnectionStatus, WalletChain } from \"../types\";\nimport { createClient } from \"../client\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport {\n LocalStorageSessionStorage,\n WalletError,\n logger,\n SessionManager,\n createSessionManager,\n ConnectorManager,\n createConnectorManager,\n} from \"@naculus/connect-core\";\nimport type { PocketConnectorClass as EmbeddedWalletConnectorClass } from \"@naculus/connector-embedded\";\nimport { getDefaultChains } from \"../utils/chains\";\n\n// ── Timeout Helper ────────────────────────────────────────────────\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number, label: string = \"Operation\"): Promise<T> {\n return Promise.race([\n promise,\n new Promise<T>((_, reject) =>\n setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms)\n ),\n ]);\n}\n\n// ── Retry Helper ──────────────────────────────────────────────────\n\ninterface RetryOptions {\n maxRetries: number;\n baseDelay: number;\n label?: string;\n}\n\nasync function withRetry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<T> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= options.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n if (attempt < options.maxRetries) {\n const delay = options.baseDelay * (2 ** attempt);\n logger.warn(\"react/provider\", `Retry attempt ${attempt + 1}/${options.maxRetries} after ${delay}ms`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n throw lastError;\n}\n\ntype Web3Action =\n | { type: \"SET_STATUS\"; payload: ConnectionStatus }\n | { type: \"SET_SESSION\"; payload: Web3State[\"session\"] }\n | { type: \"SET_ACCOUNTS\"; payload: string[] }\n | { type: \"SET_CHAIN\"; payload: string | null }\n | { type: \"SET_ERROR\"; payload: Error | null }\n | { type: \"RESET\" };\n\nexport interface Web3ContextValue extends Web3State, Web3Actions {\n isConnected: boolean;\n chains: WalletChain[];\n /** SessionManager instance for multi-chain session management */\n sessionManager: SessionManager | null;\n}\n\nconst initialState: Web3State = {\n status: \"disconnected\",\n session: null,\n accounts: [],\n chainId: null,\n error: null\n};\n\nfunction web3Reducer(state: Web3State, action: Web3Action): Web3State {\n switch (action.type) {\n case \"SET_STATUS\":\n return { ...state, status: action.payload };\n case \"SET_SESSION\":\n return { ...state, session: action.payload };\n case \"SET_ACCOUNTS\":\n return { ...state, accounts: action.payload };\n case \"SET_CHAIN\":\n return { ...state, chainId: action.payload };\n case \"SET_ERROR\":\n return { ...state, error: action.payload };\n case \"RESET\":\n return initialState;\n default:\n return state;\n }\n}\n\nexport const Web3Context = createContext<Web3ContextValue | null>(null);\n\nexport interface Web3ConnectProviderProps {\n children: React.ReactNode;\n config: Web3ConnectConfig;\n autoConnect?: boolean;\n}\n\nexport function Web3ConnectProvider({\n children,\n config,\n autoConnect = true\n}: Web3ConnectProviderProps) {\n const [state, dispatch] = useReducer(web3Reducer, initialState);\n\n const chains = useMemo(() => config.chains ?? getDefaultChains(), [config.chains]);\n\n const connectionTimeout = config.connectionTimeout ?? 30000;\n const maxRetries = config.maxRetries ?? 2;\n\n const storage = useMemo(\n () => new LocalStorageSessionStorage(config.storageKey ?? \"naculus_web3_session\"),\n [config.storageKey]\n );\n\n const client = useMemo(() => {\n return createClient({\n projectId: config.projectId,\n metadata: config.metadata,\n enableEmbedded: config.enableEmbedded,\n enablePasskeys: config.enablePasskeys,\n enableSolana: config.enableSolana,\n solanaDefaultChain: config.solanaDefaultChain,\n });\n }, [config.projectId, config.metadata, config.enableEmbedded, config.enablePasskeys, config.enableSolana, config.solanaDefaultChain]);\n\n // ── SessionManager ───────────────────────────────────────────────\n\n const sessionManagerRef = useRef<SessionManager | null>(null);\n\n const sessionManager = useMemo(() => {\n // Build a connector manager that shares the client's connectors\n const cm = createConnectorManager();\n cm.register(client.connector.id, client.connector);\n\n // Build default RPC/currency configs from the configured chains\n const defaultRpcUrls: Record<string, string> = {};\n const defaultCurrencies: Record<string, { name: string; symbol: string; decimals: number }> = {};\n\n for (const chain of chains) {\n const caip2Id = `${chain.namespace}:${chain.id}`;\n if (chain.rpcUrl) {\n defaultRpcUrls[caip2Id] = chain.rpcUrl;\n }\n if (chain.token) {\n defaultCurrencies[caip2Id] = {\n name: chain.name,\n symbol: chain.token,\n decimals: 18,\n };\n }\n }\n\n const sm = createSessionManager(cm, {\n autoRefreshFeeOnSwitch: true,\n defaultRpcUrls,\n defaultCurrencies,\n encryptionKey: config.encryptionKey,\n });\n\n sessionManagerRef.current = sm;\n return sm;\n }, [client, chains]);\n\n // Sync SessionManager events to provider state\n useEffect(() => {\n const onConnected = (payload: { bundle: any }) => {\n const { walletSession } = payload.bundle;\n dispatch({ type: \"SET_SESSION\", payload: walletSession });\n\n const accounts: string[] = [];\n Object.values(walletSession.namespaces).forEach((ns: any) => {\n accounts.push(...ns.accounts);\n });\n dispatch({ type: \"SET_ACCOUNTS\", payload: accounts });\n dispatch({ type: \"SET_CHAIN\", payload: payload.bundle.activeChainId });\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n };\n\n const onDisconnected = () => {\n dispatch({ type: \"RESET\" });\n };\n\n const onChainChanged = (payload: { newChainId: string }) => {\n dispatch({ type: \"SET_CHAIN\", payload: payload.newChainId });\n };\n\n sessionManager.on(\"sessionConnected\", onConnected);\n sessionManager.on(\"sessionDisconnected\", onDisconnected);\n sessionManager.on(\"chainChanged\", onChainChanged);\n\n return () => {\n sessionManager.off(\"sessionConnected\", onConnected);\n sessionManager.off(\"sessionDisconnected\", onDisconnected);\n sessionManager.off(\"chainChanged\", onChainChanged);\n };\n }, [sessionManager]);\n\n useEffect(() => {\n const handler = () => {\n storage.clear();\n dispatch({ type: \"RESET\" });\n };\n client.connector.onSessionExpiry(handler);\n }, [client, storage]);\n\n const updateStateFromSession = useCallback((session: typeof state.session) => {\n dispatch({ type: \"SET_SESSION\", payload: session });\n\n if (session) {\n const accounts: string[] = [];\n Object.values(session.namespaces).forEach((ns) => {\n accounts.push(...ns.accounts);\n });\n dispatch({ type: \"SET_ACCOUNTS\", payload: accounts });\n\n const evmChain = session.namespaces[\"eip155\"]?.chains?.[0];\n const solChain = session.namespaces[\"solana\"]?.chains?.[0];\n const xrplChain = session.namespaces[\"xrpl\"]?.chains?.[0];\n dispatch({ type: \"SET_CHAIN\", payload: evmChain ?? solChain ?? xrplChain ?? null });\n } else {\n dispatch({ type: \"SET_ACCOUNTS\", payload: [] });\n dispatch({ type: \"SET_CHAIN\", payload: null });\n }\n }, []);\n\n // ── SIWx post-connection helper ──────────────────────────────────\n // Run after any connect method succeeds. Returns false if SIWx is\n // configured, required, and failed — the caller should abort without\n // setting status to \"connected\".\n const runSiwx = useCallback(async (session: UniversalWalletSession | null): Promise<boolean> => {\n if (!config.siwx || !session) return true;\n\n dispatch({ type: \"SET_STATUS\", payload: \"authenticating\" });\n\n try {\n const firstEvm = session.namespaces[\"eip155\"]?.accounts?.[0];\n const firstSol = session.namespaces[\"solana\"]?.accounts?.[0];\n const rawAddress = firstEvm ?? firstSol;\n if (!rawAddress) throw new WalletError(\"siwx_error\", \"No account found in session\");\n\n const chainId = firstEvm\n ? session.namespaces[\"eip155\"].chains?.[0] ?? \"eip155:1\"\n : session.namespaces[\"solana\"].chains?.[0] ?? \"solana:0\";\n\n const address = rawAddress.includes(\":\") ? rawAddress.split(\":\").pop()! : rawAddress;\n\n const message = await config.siwx.createMessage({ address, chainId });\n const signature = (await client.signMessage(session, {\n message,\n address,\n chainId,\n })) as string;\n\n if (config.siwx.handleSignComplete) {\n await config.siwx.handleSignComplete({ message, signature });\n }\n\n return true;\n } catch (siwxError) {\n logger.error(\"react/provider\", \"SIWx authentication failed:\", siwxError);\n\n if (config.siwx.required !== false) {\n await storage.clear();\n dispatch({ type: \"RESET\" });\n dispatch({\n type: \"SET_ERROR\",\n payload: siwxError instanceof Error ? siwxError : new Error(\"Wallet authentication failed\"),\n });\n return false;\n }\n\n return true;\n }\n }, [config.siwx, client, storage]);\n\n const connect = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await withTimeout(\n client.connect(),\n connectionTimeout,\n \"Wallet connect\"\n );\n await storage.save(session);\n updateStateFromSession(session);\n\n // Feed the session into SessionManager\n try {\n const sm = sessionManagerRef.current;\n if (sm && session.walletType) {\n const evmChain = session.namespaces[\"eip155\"]?.chains?.[0];\n const chainId = evmChain ?? \"eip155:1\";\n // Trigger SessionManager to build bundle from this session\n sm.connect(session.walletType, chainId);\n }\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager sync error:\", smError);\n }\n\n if (!await runSiwx(session)) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Connection failed\";\n dispatch({ type: \"SET_ERROR\", payload: error instanceof Error ? error : new Error(message) });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, connectionTimeout, runSiwx]);\n\n const connectEmbedded = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await client.connectEmbedded();\n await storage.save(session);\n updateStateFromSession(session);\n if (!await runSiwx(session)) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Embedded wallet connection failed\";\n dispatch({ type: \"SET_ERROR\", payload: error instanceof Error ? error : new Error(message) });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, runSiwx]);\n\n const connectPasskeys = useCallback(async (): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await client.connectPasskeys();\n await storage.save(session);\n updateStateFromSession(session);\n if (!await runSiwx(session)) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Passkeys connection failed\";\n dispatch({ type: \"SET_ERROR\", payload: error instanceof Error ? error : new Error(message) });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, runSiwx]);\n\n const disconnect = useCallback(async () => {\n if (!state.session) {\n dispatch({ type: \"RESET\" });\n return;\n }\n\n try {\n await client.disconnect(state.session);\n } catch (error) {\n logger.error(\"react/provider\", \"Disconnect error:\", error);\n }\n\n // Also disconnect via SessionManager\n try {\n const sm = sessionManagerRef.current;\n if (sm) {\n await sm.disconnect();\n }\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager disconnect error:\", smError);\n }\n\n await storage.clear();\n dispatch({ type: \"RESET\" });\n }, [client, state.session, storage]);\n\n const connectInjected = useCallback(async (walletId?: string): Promise<void> => {\n dispatch({ type: \"SET_STATUS\", payload: \"connecting\" });\n dispatch({ type: \"SET_ERROR\", payload: null });\n\n try {\n const session = await withTimeout(\n client.connectInjected(walletId),\n connectionTimeout,\n \"Injected wallet connect\"\n );\n await storage.save(session);\n updateStateFromSession(session);\n\n // Feed the session into SessionManager\n try {\n const sm = sessionManagerRef.current;\n if (sm) {\n const evmChain = session.namespaces[\"eip155\"]?.chains?.[0];\n const chainId = evmChain ?? \"eip155:1\";\n sm.connect(\"eip6963\", chainId);\n }\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager sync error:\", smError);\n }\n\n if (!await runSiwx(session)) return;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Connection failed\";\n dispatch({ type: \"SET_ERROR\", payload: error instanceof Error ? error : new Error(message) });\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n }\n }, [client, storage, updateStateFromSession, connectionTimeout, runSiwx]);\n\n const startPairing = useCallback(async () => {\n return client.startPairing();\n }, [client]);\n\n const completePairing = useCallback(async () => {\n const session = await client.completePairing();\n await storage.save(session);\n updateStateFromSession(session);\n if (!await runSiwx(session)) return session;\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n return session;\n }, [client, storage, updateStateFromSession, runSiwx]);\n\n const reconnect = useCallback(async () => {\n const savedSession = await storage.load();\n if (!savedSession) {\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n return;\n }\n\n dispatch({ type: \"SET_STATUS\", payload: \"reconnecting\" });\n\n try {\n const session = await withRetry(\n () => client.reconnect(savedSession),\n { maxRetries, baseDelay: 1000, label: \"reconnect\" }\n );\n updateStateFromSession(session);\n\n // Restore SessionManager from persistence\n try {\n const sm = sessionManagerRef.current;\n if (sm) {\n await sm.restoreFromPersistence();\n }\n } catch (smError) {\n logger.warn(\"react/provider\", \"SessionManager restore error:\", smError);\n }\n\n dispatch({ type: \"SET_STATUS\", payload: \"connected\" });\n } catch (error) {\n logger.error(\"react/provider\", \"Reconnect error:\", error);\n await storage.clear();\n dispatch({ type: \"SET_STATUS\", payload: \"disconnected\" });\n dispatch({ type: \"SET_SESSION\", payload: null });\n }\n }, [client, storage, updateStateFromSession, maxRetries]);\n\n const switchChain = useCallback(async (chainId: string) => {\n const sm = sessionManagerRef.current;\n if (sm) {\n // Use SessionManager's switchChain which handles fee sync + events\n await sm.switchChain(chainId);\n dispatch({ type: \"SET_CHAIN\", payload: chainId });\n return;\n }\n\n // Fallback to direct connector switching (no SessionManager)\n if (!state.session) {\n throw new Error(\"No active session\");\n }\n\n try {\n if (state.session.walletType === \"eip6963\" || state.session.id?.startsWith(\"eip6963-\")) {\n await eip6963Connector.switchChain(state.session, chainId);\n } else if (state.session.walletType === \"solana\" && client.solanaConnector) {\n await client.solanaConnector.switchChain?.(state.session, chainId);\n } else {\n await client.connector.switchChain(state.session, chainId);\n }\n dispatch({ type: \"SET_CHAIN\", payload: chainId });\n } catch (error) {\n throw new WalletError(\"chain_unsupported\", \"Failed to switch chain\", error);\n }\n }, [client, state.session]);\n\n useEffect(() => {\n if (autoConnect) {\n reconnect();\n }\n }, [autoConnect, reconnect]);\n\n const clearError = useCallback(() => {\n dispatch({ type: \"SET_ERROR\", payload: null });\n }, []);\n\nconst value = useMemo<Web3ContextValue>(\n () => ({\n ...state,\n connect,\n connectEmbedded,\n connectPasskeys,\n disconnect,\n reconnect,\n switchChain,\n startPairing,\n completePairing,\n connectInjected,\n clearError,\n isConnected: state.status === \"connected\",\n chains,\n sessionManager,\n }),\n [state, connect, connectEmbedded, connectPasskeys,\n disconnect, reconnect, switchChain,\n startPairing, completePairing, connectInjected, clearError, chains, sessionManager]\n );\n\n return <Web3Context.Provider value={value}>{children}</Web3Context.Provider>;\n}\n\nexport function useWeb3(): Web3ContextValue {\n const context = useContext(Web3Context);\n if (!context) {\n throw new Error(\"useWeb3 must be used within a Web3ConnectProvider\");\n }\n return context;\n}\n","import { WalletConnectConnector, createWalletConnectConnector } from \"@naculus/connector-walletconnect\";\nimport { eip6963Connector } from \"@naculus/connector-evm-injected\";\nimport { logger, WalletError } from \"@naculus/connect-core\";\nimport type { UniversalConnector, UniversalWalletSession, BatchCall, CallsStatus } from \"@naculus/connect-core\";\nimport type { PocketConnectorClass as EmbeddedWalletConnector } from \"@naculus/connector-embedded\";\nimport type PasskeysConnectorImpl from \"@naculus/connector-passkeys\";\n\nexport type ClientConfig = {\n projectId: string;\n metadata: {\n name: string;\n description: string;\n url: string;\n icons: string[];\n };\n /** Enable embedded (self-custodial) wallet */\n enableEmbedded?: boolean;\n\n /** Enable passkeys (WebAuthn) connector */\n enablePasskeys?: boolean;\n\n /** Enable Solana injected wallet connector (Phantom, Solflare) */\n enableSolana?: boolean;\n /** Default Solana chain (e.g. \"solana:0\"). Only used when enableSolana is true. */\n solanaDefaultChain?: string;\n};\n\nexport interface Web3Client {\n connector: WalletConnectConnector;\n embeddedConnector: EmbeddedWalletConnector | null;\n /** The Passkeys connector if enabled */\n passkeysConnector: PasskeysConnectorImpl | null;\n /** The Solana injected wallet connector if enabled */\n solanaConnector: UniversalConnector | null;\n connect: () => Promise<UniversalWalletSession>;\n /** Connect via EIP-6963 injected wallet */\n connectInjected: (walletId?: string) => Promise<UniversalWalletSession>;\n connectEmbedded: () => Promise<UniversalWalletSession>;\n /** Connect via passkeys (WebAuthn) */\n connectPasskeys: () => Promise<UniversalWalletSession>;\n reconnect: (session: UniversalWalletSession) => Promise<UniversalWalletSession>;\n disconnect: (session: UniversalWalletSession) => Promise<void>;\n /** Sign a message via the appropriate connector for the session */\n signMessage: (session: UniversalWalletSession, input: { message: string; address?: string; chainId?: string }) => Promise<unknown>;\n /** Send a transaction via the appropriate connector for the session */\n sendTransaction: (session: UniversalWalletSession, input: { transaction: Record<string, unknown>; chainId?: string }) => Promise<unknown>;\n /** Send batched calls (EIP-5792 wallet_sendCalls) via the appropriate connector */\n sendCalls: (session: UniversalWalletSession, calls: BatchCall[], chainId?: string) => Promise<string>;\n getCallsStatus: (session: UniversalWalletSession, bundleHash: string) => Promise<CallsStatus>;\n startPairing: () => Promise<string>;\n completePairing: () => Promise<UniversalWalletSession>;\n getAllConnectors: () => UniversalConnector[];\n /** @internal set embedded connector after lazy init */\n _setEmbeddedConnector: (conn: EmbeddedWalletConnector) => void;\n /** @internal set passkeys connector after lazy init */\n _setPasskeysConnector: (conn: PasskeysConnectorImpl) => void;\n /** @internal set solana connector after lazy init */\n _setSolanaConnector: (conn: UniversalConnector) => void;\n}\n\nlet clientInstance: Web3Client | null = null;\n\nexport function createClient(config: ClientConfig): Web3Client {\n if (clientInstance) return clientInstance;\n\n const connector = createWalletConnectConnector({\n projectId: config.projectId,\n metadata: config.metadata\n });\n\n let _embeddedConnector: EmbeddedWalletConnector | null = null;\n let embeddedInit: Promise<void> | null = null;\n\n if (config.enableEmbedded) {\n embeddedInit = import(\"@naculus/connector-embedded\").then((mod) => {\n const conn = mod.createPocketConnector();\n _embeddedConnector = conn;\n if (clientInstance) clientInstance._setEmbeddedConnector(_embeddedConnector);\n }).catch((err) => {\n logger.warn(\"react/client\", \"Embedded wallet connector not available:\", err);\n _embeddedConnector = null;\n });\n }\n\n let _passkeysConnector: PasskeysConnectorImpl | null = null;\n let passkeysInit: Promise<void> | null = null;\n\n if (config.enablePasskeys) {\n passkeysInit = import(\"@naculus/connector-passkeys\").then((mod) => {\n const conn = mod.createPasskeysConnector();\n _passkeysConnector = conn;\n if (clientInstance) clientInstance._setPasskeysConnector(_passkeysConnector);\n }).catch((err) => {\n logger.warn(\"react/client\", \"Passkeys connector not available:\", err);\n _passkeysConnector = null;\n });\n }\n\n let _solanaConnector: UniversalConnector | null = null;\n let solanaInit: Promise<void> | null = null;\n\n if (config.enableSolana) {\n solanaInit = import(\"@naculus/connector-solana\").then((mod: any) => {\n // Use the singleton instance so hooks (useSolanaAccount, etc.) and\n // the client routing share the same activeSession state.\n const conn = mod.solanaConnector as UniversalConnector;\n if (config.solanaDefaultChain && \"configure\" in conn) {\n (conn as any).configure({ defaultChain: config.solanaDefaultChain });\n }\n _solanaConnector = conn;\n if (typeof window !== \"undefined\" && \"startDiscovery\" in conn) {\n (conn as any).startDiscovery();\n }\n if (clientInstance) clientInstance._setSolanaConnector(_solanaConnector);\n }).catch((err) => {\n logger.warn(\"react/client\", \"Solana connector not available:\", err);\n _solanaConnector = null;\n });\n }\n\n // Start EIP-6963 discovery eagerly so wallets are available when user clicks connect\n if (typeof window !== \"undefined\") {\n eip6963Connector.startDiscovery();\n }\n\n clientInstance = {\n connector,\n get embeddedConnector() { return _embeddedConnector; },\n get passkeysConnector() { return _passkeysConnector; },\n get solanaConnector() { return _solanaConnector; },\n connect: () => connector.connect(),\n connectInjected: async (walletId?: string) => {\n return eip6963Connector.connect(walletId);\n },\n connectEmbedded: async () => {\n if (embeddedInit) await embeddedInit;\n if (!_embeddedConnector) {\n throw new Error(\"Embedded wallet not enabled. Set enableEmbedded: true in config.\");\n }\n return _embeddedConnector.connect();\n },\n connectPasskeys: async () => {\n if (passkeysInit) await passkeysInit;\n if (!_passkeysConnector) {\n throw new Error(\"Passkeys connector not enabled. Set enablePasskeys: true in config.\");\n }\n return _passkeysConnector.connect();\n },\n startPairing: () => connector.startPairing(),\n completePairing: () => connector.completePairing(),\n signMessage: async (session, input) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.signMessage(session as any, input);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.signMessage(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).signMessage(session as any, input);\n }\n throw new WalletError(\"wallet_unavailable\", \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\");\n }\n return connector.signMessage(session, input);\n },\n sendTransaction: async (session, input) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.sendTransaction(session as any, input);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).sendTransaction(session as any, input);\n }\n throw new WalletError(\"wallet_unavailable\", \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\");\n }\n return connector.sendTransaction(session, input);\n },\n sendCalls: async (session, calls, chainId) => {\n if (session.id?.startsWith(\"eip6963-\")) {\n return eip6963Connector.sendCalls!(session as any, calls, chainId);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector) {\n return _passkeysConnector.sendCalls(session as any, calls, chainId);\n }\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return (_solanaConnector as any).sendCalls(session as any, calls, chainId);\n }\n throw new WalletError(\"wallet_unavailable\", \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\");\n }\n if (session.walletType === \"embedded\" && _embeddedConnector && _embeddedConnector.sendCalls) {\n return _embeddedConnector.sendCalls(session as any, calls, chainId);\n }\n if (!connector.sendCalls) {\n throw new WalletError(\"method_not_allowed\", \"sendCalls not supported by this connector\");\n }\n return connector.sendCalls(session, calls, chainId);\n },\n getCallsStatus: async (session, bundleHash) => {\n if (session.id?.startsWith(\"eip6963-\") && eip6963Connector.getCallsStatus) {\n return eip6963Connector.getCallsStatus(session as any, bundleHash);\n }\n if (session.walletType === \"passkeys\" && _passkeysConnector?.getCallsStatus) {\n return _passkeysConnector.getCallsStatus(session as any, bundleHash);\n }\n if (!connector.getCallsStatus) {\n throw new WalletError(\"method_not_allowed\", \"getCallsStatus not supported by this connector\");\n }\n return connector.getCallsStatus(session, bundleHash);\n },\n reconnect: async (session) => {\n if (session.walletType === \"eip6963\") {\n return eip6963Connector.reconnect(session);\n }\n if (session.walletType === \"embedded\") {\n if (_embeddedConnector) {\n return _embeddedConnector.reconnect(session);\n }\n return session;\n }\n if (session.walletType === \"solana\") {\n // Solana injected wallet doesn't support reconnect (no persisted session).\n // Return the saved session as-is; signing ops require wallet reconnection.\n return session;\n }\n return connector.reconnect(session);\n },\n disconnect: async (session) => {\n if (session.walletType === \"solana\") {\n if (solanaInit) await solanaInit;\n if (_solanaConnector) {\n return _solanaConnector.disconnect(session);\n }\n throw new WalletError(\"wallet_unavailable\", \"Solana connector not available. Ensure enableSolana is true and @naculus/connector-solana is installed.\");\n }\n return connector.disconnect(session);\n },\n getAllConnectors: () => {\n const connectors: UniversalConnector[] = [connector];\n if (_embeddedConnector) connectors.push(_embeddedConnector);\n if (_passkeysConnector) connectors.push(_passkeysConnector);\n if (_solanaConnector) connectors.push(_solanaConnector);\n return connectors;\n },\n _setEmbeddedConnector: (conn: EmbeddedWalletConnector) => { _embeddedConnector = conn; },\n _setPasskeysConnector: (conn: PasskeysConnectorImpl) => { _passkeysConnector = conn; },\n _setSolanaConnector: (conn: UniversalConnector) => { _solanaConnector = conn; },\n };\n\n return clientInstance;\n}\n\nexport function getClient(): Web3Client | null {\n return clientInstance;\n}\n\nexport function clearClient(): void {\n clientInstance = null;\n}\n","import type { WalletChain } from \"../types\";\nimport { CHAINS, getRpcUrl, DEFAULT_RPC_URLS } from \"@naculus/connect-core\";\n\n// ─── Static Overrides ──────────────────────────────────────────────\n// Chains that exist in the old default list but are NOT in chain-registry.\n// These are deprecated testnets; keep for backward compatibility.\n\nconst STATIC_TESTNETS: WalletChain[] = [\n {\n id: 5,\n namespace: \"eip155\",\n name: \"Goerli\",\n rpcUrl: \"https://goerli.blockpi.network/v1/rpc/public\",\n explorerUrl: \"https://goerli.etherscan.io\",\n token: \"ETH\",\n },\n {\n id: 80001,\n namespace: \"eip155\",\n name: \"Mumbai\",\n rpcUrl: \"https://rpc-mumbai.maticvigil.com\",\n explorerUrl: \"https://mumbai.polygonscan.com\",\n token: \"MATIC\",\n },\n {\n id: 421613,\n namespace: \"eip155\",\n name: \"Arbitrum Goerli\",\n rpcUrl: \"https://goerli-rollup.arbitrum.io/rpc\",\n explorerUrl: \"https://goerli.arbiscan.io\",\n token: \"ETH\",\n },\n {\n id: 420,\n namespace: \"eip155\",\n name: \"Optimism Goerli\",\n rpcUrl: \"https://goerli.optimism.io\",\n explorerUrl: \"https://goerli-optimism.etherscan.io\",\n token: \"ETH\",\n },\n];\n\n// ─── Build from Registry ───────────────────────────────────────────\n// Derive WalletChain entries from the single-source-of-truth chain-registry\n// and the RPC URL defaults from rpc.ts.\n\nfunction toWalletChain(chainId: number): WalletChain | null {\n const info = CHAINS[chainId];\n if (!info) return null;\n\n // Only include chains with an explorer URL (meaningful for UI display)\n if (!info.explorerUrl) return null;\n\n const caip2Id = info.caip2Id;\n\n return {\n id: chainId,\n namespace: \"eip155\",\n name: info.name,\n rpcUrl: getRpcUrl(caip2Id, DEFAULT_RPC_URLS[caip2Id] ?? \"\"),\n explorerUrl: info.explorerUrl,\n token: info.nativeCurrency.symbol,\n };\n}\n\nfunction buildDefaultChains(): WalletChain[] {\n if (!CHAINS) return [];\n\n const registryChains: WalletChain[] = [];\n\n // Order by chain ID for deterministic output\n const chainIds = Object.keys(CHAINS)\n .map(Number)\n .sort((a, b) => a - b);\n\n for (const id of chainIds) {\n const chain = toWalletChain(id);\n if (chain) {\n registryChains.push(chain);\n }\n }\n\n // Append static testnets that aren't in the registry\n for (const testnet of STATIC_TESTNETS) {\n if (!CHAINS[testnet.id]) {\n registryChains.push(testnet);\n }\n }\n\n return registryChains;\n}\n\nexport const DEFAULT_EVM_CHAINS: WalletChain[] = buildDefaultChains();\n\n// ─── Helpers ───────────────────────────────────────────────────────\n\nexport function getChainById(chains: WalletChain[], chainId: string): WalletChain | undefined {\n return chains.find((chain) => {\n const chainNamespace = chainId.startsWith(\"eip155:\")\n ? \"eip155\"\n : null;\n\n if (!chainNamespace) return false;\n\n const chainNum = chainId.includes(\":\")\n ? parseInt(chainId.split(\":\")[1], 10)\n : parseInt(chainId, 10);\n\n return chain.namespace === chainNamespace && chain.id === chainNum;\n });\n}\n\nexport function getDefaultChains(): WalletChain[] {\n return [...DEFAULT_EVM_CHAINS];\n}\n","import { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport function useWallet() {\n const {\n status,\n session,\n accounts,\n chainId,\n error,\n connect,\n disconnect,\n reconnect,\n switchChain\n } = useWeb3();\n\n const isConnected = status === \"connected\";\n const isConnecting = status === \"connecting\";\n const isReconnecting = status === \"reconnecting\";\n\n const currentAccount = accounts[0] ?? null;\n const isDisconnected = status === \"disconnected\";\n\n return {\n status,\n session,\n accounts,\n chainId,\n error,\n isConnected,\n isConnecting,\n isReconnecting,\n isDisconnected,\n currentAccount,\n connect,\n disconnect,\n reconnect,\n switchChain\n };\n}","import { useCallback, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { WalletError } from \"@naculus/connect-core\";\n\nexport function useConnect() {\n const { connect, status } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleConnect = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n await connect();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Connection failed\";\n setError(err instanceof WalletError ? err : new Error(errorMessage));\n } finally {\n setIsLoading(false);\n }\n }, [connect]);\n\n return {\n connect: handleConnect,\n isConnecting: isLoading || status === \"connecting\",\n error\n };\n}","import { useCallback, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport function useDisconnect() {\n const { disconnect, status } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const handleDisconnect = useCallback(async () => {\n if (status === \"disconnected\") return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await disconnect();\n } catch (err) {\n if (!mountedRef.current) return;\n setError(err instanceof Error ? err : new Error(\"Disconnect failed\"));\n } finally {\n if (mountedRef.current) setIsLoading(false);\n }\n }, [disconnect, status]);\n\n return {\n disconnect: handleDisconnect,\n isDisconnecting: isLoading,\n error,\n cleanup: () => { mountedRef.current = false; },\n };\n}","import { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\n\nexport function useAccount() {\n const { accounts, session, isConnected } = useWeb3();\n\n const accountData = useMemo(() => {\n if (!isConnected || accounts.length === 0) {\n return null;\n }\n\n return accounts.map((address) => {\n // H12: Strengthened CAIP-10 / address detection\n // Valid formats:\n // CAIP-10: \"eip155:1:0x1234...5678\" (namespace:chainId:address)\n // Plain: \"0x1234...5678\" (42-char hex, 0x + 40 hex chars)\n const isCaip10 = /^eip155:\\d+:0x[0-9a-fA-F]{40}$/.test(address);\n const isPlainHex = /^0x[0-9a-fA-F]{40}$/.test(address);\n const isEvm = isCaip10 || isPlainHex;\n\n return {\n address,\n isEVM: isEvm,\n };\n });\n }, [accounts, isConnected]);\n\n const evmAccount = accountData?.find((a) => a.isEVM)?.address ?? null;\n\n return {\n accounts: accountData,\n evmAccount,\n primaryAccount: accounts[0] ?? null,\n isConnected,\n count: accounts.length\n };\n}\n","import { useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getChainById } from \"../utils/chains\";\nimport type { WalletChain, ChainInfo } from \"../types\";\n\nexport function useChain() {\n const { chainId, session, switchChain, chains } = useWeb3();\n\n const currentChain = useMemo(() => {\n if (!chainId) return null;\n return getChainById(chains, chainId) ?? null;\n }, [chainId, chains]);\n\n const chainInfo = useMemo<ChainInfo | null>(() => {\n if (!chainId || !session) return null;\n\n const namespace = chainId.startsWith(\"eip155:\")\n ? \"eip155\"\n : null;\n\n if (!namespace) return null;\n\n const chainNum = chainId.includes(\":\")\n ? parseInt(chainId.split(\":\")[1], 10)\n : parseInt(chainId, 10);\n\n const chain = chains.find((c) => c.namespace === namespace && c.id === chainNum);\n\n return {\n namespace,\n chainId,\n name: chain?.name ?? `Chain ${chainNum}`,\n selected: true\n };\n }, [chainId, session, chains]);\n\n const availableChains = useMemo<WalletChain[]>(() => {\n // Return all default EVM chains so users can see and switch to any supported chain\n // The session namespace only contains the current/approved chain, but we want to\n // make all configured chains available for switching.\n return chains;\n }, [chains]);\n\n return {\n chainId,\n currentChain,\n chainInfo,\n availableChains,\n chains: availableChains,\n isEvm: chainId?.startsWith(\"eip155:\"),\n switchChain\n };\n}\n","import { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\nimport { WalletError } from \"@naculus/connect-core\";\n\nexport function useSignMessage() {\n const { session, chainId } = useWeb3();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const signMessage = useCallback(\n async (message: string): Promise<string> => {\n // Precondition checks — set error state before throwing (consistent with useSendTransaction pattern)\n if (!session) {\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n const client = getClient();\n if (!client) {\n const err = new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n setError(err);\n throw err;\n }\n\n const address = Object.values(session.namespaces)\n .flatMap((ns) => ns.accounts)\n .find((acc) => acc.includes(\"0x\")) ?? Object.values(session.namespaces)[0]?.accounts[0];\n\n if (!address) {\n const err = new WalletError(\"wallet_unavailable\", \"No account found\");\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = (await client.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined\n })) as string;\n\n return result;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : \"Signing failed\";\n const error = err instanceof Error ? err : new Error(errorMessage);\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [session, chainId]\n );\n\n return {\n signMessage,\n isSigning: isLoading,\n error\n };\n}\n","import { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport type { EvmTransaction } from \"../types\";\n\nexport type SendTransactionStatus = \"idle\" | \"awaiting_approval\" | \"confirmed\" | \"failed\";\n\nexport function useSendTransaction() {\n const { session, chainId } = useWeb3();\n const [status, setStatus] = useState<SendTransactionStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n\n const sendTransaction = useCallback(\n async (transaction: EvmTransaction): Promise<string> => {\n if (!session) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n const client = getClient();\n if (!client) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n setError(err);\n throw err;\n }\n\n const evmAccount = Object.values(session.namespaces)\n .flatMap((ns) => ns.accounts)\n .find((acc) => acc.includes(\"0x\"));\n\n if (!evmAccount) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"No EVM account found\");\n setError(err);\n throw err;\n }\n\n setStatus(\"awaiting_approval\");\n setError(null);\n\n try {\n const txWithFrom = {\n ...transaction,\n from: transaction.from ?? evmAccount.split(\":\").pop()\n };\n\n const result = (await client.sendTransaction(session, {\n transaction: txWithFrom,\n chainId: chainId ?? undefined\n })) as string;\n\n setStatus(\"confirmed\");\n return result;\n } catch (err) {\n setStatus(\"failed\");\n const errorMessage = err instanceof Error ? err.message : \"Transaction failed\";\n setError(err instanceof Error ? err : new Error(errorMessage));\n throw err;\n }\n },\n [session, chainId]\n );\n\n const reset = useCallback(() => {\n setStatus(\"idle\");\n setError(null);\n }, []);\n\n return {\n sendTransaction,\n status,\n error,\n reset,\n isSending: status === \"awaiting_approval\"\n };\n}\n","import { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport type { BatchCall, CallsStatus } from \"@naculus/connect-core\";\n\nexport type SendCallsStatus = \"idle\" | \"awaiting_approval\" | \"confirmed\" | \"failed\";\n\nexport function useSendCalls() {\n const { session, chainId } = useWeb3();\n const [status, setStatus] = useState<SendCallsStatus>(\"idle\");\n const [error, setError] = useState<Error | null>(null);\n const [batchHash, setBatchHash] = useState<string | null>(null);\n const [callsStatus, setCallsStatus] = useState<CallsStatus | null>(null);\n\n const sendCalls = useCallback(\n async (calls: BatchCall[], options?: { chainId?: string }): Promise<string> => {\n if (!session) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"No active session\");\n setError(err);\n throw err;\n }\n\n const client = getClient();\n if (!client) {\n setStatus(\"failed\");\n const err = new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n setError(err);\n throw err;\n }\n\n if (calls.length === 0) {\n setStatus(\"failed\");\n const err = new WalletError(\"invalid_input\", \"At least one call is required\");\n setError(err);\n throw err;\n }\n\n setStatus(\"awaiting_approval\");\n setError(null);\n setBatchHash(null);\n\n try {\n const result = await client.sendCalls(\n session,\n calls,\n options?.chainId ?? chainId ?? undefined,\n );\n setStatus(\"confirmed\");\n setBatchHash(result);\n return result;\n } catch (err) {\n setStatus(\"failed\");\n const errorMessage = err instanceof Error ? err.message : \"sendCalls failed\";\n setError(err instanceof Error ? err : new Error(errorMessage));\n throw err;\n }\n },\n [session, chainId],\n );\n\n const getCallsStatus = useCallback(\n async (hash?: string): Promise<CallsStatus> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n const client = getClient();\n if (!client) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n\n const bundleHash = hash ?? batchHash;\n if (!bundleHash) {\n throw new WalletError(\"invalid_input\", \"No bundle hash available\");\n }\n\n const result = await client.getCallsStatus(session, bundleHash);\n setCallsStatus(result);\n return result;\n },\n [session, batchHash],\n );\n\n const reset = useCallback(() => {\n setStatus(\"idle\");\n setError(null);\n setBatchHash(null);\n setCallsStatus(null);\n }, []);\n\n return {\n sendCalls,\n getCallsStatus,\n status,\n error,\n batchHash,\n callsStatus,\n reset,\n isSending: status === \"awaiting_approval\",\n };\n}\n","import { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport { createPublicClient, http, formatEther, type PublicClient, type Address } from \"viem\";\nimport { getNativeTokenPriceUsd } from \"@naculus/connect-core\";\n\nexport interface UseBalanceOptions {\n /** Auto-refresh interval in milliseconds. Default: undefined (no auto-refresh). */\n refreshInterval?: number;\n}\n\nexport interface UseBalanceResult {\n /** Raw balance in wei (string), or null if not connected / error */\n balance: string | null;\n /** Human-readable formatted balance in ETH (or native token), or null */\n formatted: string | null;\n /** Native token symbol (e.g. \"ETH\", \"MATIC\") */\n symbol: string;\n /** USD price of one native token, or null if unavailable */\n usdPrice: number | null;\n /** Formatted USD value of the balance (e.g. \"$1,234.56\"), or null */\n usdValue: string | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n chain: { id: number; namespace: string; name: string; rpcUrl?: string; token?: string } | null;\n}\n\nexport function useBalance(options?: UseBalanceOptions): UseBalanceResult {\n const { evmAccount, isConnected } = useAccount();\n const { chainId, chains } = useWeb3();\n const [balance, setBalance] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [usdPrice, setUsdPrice] = useState<number | null>(null);\n const refreshInterval = options?.refreshInterval;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const currentChain = useMemo(() => {\n if (!chainId || !chains.length) return null;\n\n const namespace = chainId.startsWith(\"eip155:\") ? \"eip155\" : null;\n if (!namespace) return null;\n\n const chainPart = chainId.split(\":\")[1];\n const chainNum = Number(chainPart);\n if (!Number.isFinite(chainNum) || chainNum <= 0) return null; // H11: reject malformed chain IDs\n return chains.find((c) => c.namespace === namespace && c.id === chainNum) ?? null;\n }, [chainId, chains]);\n\n const tokenSymbol = useMemo(() => {\n return currentChain?.token ?? \"ETH\";\n }, [currentChain]);\n\n const [client, setClient] = useState<PublicClient | null>(null);\n\n useEffect(() => {\n if (!currentChain?.rpcUrl) {\n setClient(null);\n return;\n }\n\n const publicClient = createPublicClient({\n transport: http(currentChain.rpcUrl),\n chain: {\n id: currentChain.id,\n name: currentChain.name,\n nativeCurrency: {\n name: currentChain.token ?? \"ETH\",\n symbol: currentChain.token ?? \"ETH\",\n decimals: 18,\n },\n rpcUrls: {\n default: { http: [currentChain.rpcUrl] },\n public: { http: [currentChain.rpcUrl] },\n },\n },\n });\n\n setClient(publicClient);\n\n // H10: Cleanup previous client on chain change\n return () => {\n // viem PublicClient doesn't have a close method, but we clear the reference\n // to prevent stale state from being used in fetchBalance\n };\n }, [currentChain]);\n\n const fetchBalance = useCallback(async () => {\n if (!evmAccount || !client) {\n setBalance(null);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const address = evmAccount.includes(\":\") ? evmAccount.split(\":\").pop()! : evmAccount;\n const address_ = address as Address;\n const [balanceResult, price] = await Promise.all([\n client.getBalance({ address: address_ }),\n chainId ? getNativeTokenPriceUsd(chainId, currentChain?.rpcUrl).catch(() => null) : Promise.resolve(null),\n ]);\n setBalance(balanceResult.toString());\n setUsdPrice(price);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to fetch balance\"));\n setBalance(null);\n setUsdPrice(null);\n } finally {\n setIsLoading(false);\n }\n }, [evmAccount, client, chainId, currentChain?.rpcUrl]);\n\n // Initial fetch on connect / account change\n useEffect(() => {\n if (isConnected && evmAccount) {\n fetchBalance();\n }\n }, [isConnected, evmAccount, fetchBalance]);\n\n // Auto-refresh interval\n useEffect(() => {\n if (refreshInterval && refreshInterval > 0 && isConnected && evmAccount) {\n intervalRef.current = setInterval(fetchBalance, refreshInterval);\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [refreshInterval, isConnected, evmAccount, fetchBalance]);\n\n const formatted = useMemo(() => {\n if (balance === null) return null;\n try {\n return formatEther(BigInt(balance));\n } catch {\n return null;\n }\n }, [balance]);\n\n const usdValue = useMemo(() => {\n if (usdPrice === null || formatted === null) return null;\n const numericBalance = parseFloat(formatted);\n if (isNaN(numericBalance)) return null;\n const totalUsd = numericBalance * usdPrice;\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(totalUsd);\n }, [usdPrice, formatted]);\n\n return {\n balance,\n formatted,\n symbol: tokenSymbol,\n usdPrice,\n usdValue,\n isLoading,\n error,\n refetch: fetchBalance,\n chain: currentChain,\n };\n}\n","import { useState, useEffect, useCallback, useMemo, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport {\n createPublicClient,\n http,\n formatUnits,\n type PublicClient,\n type Address,\n} from \"viem\";\n\nexport interface TokenInfo {\n /** ERC-20 token contract address */\n address: Address;\n /** Token symbol (e.g. \"USDC\", \"LINK\") */\n symbol: string;\n /** Token decimals (e.g. 6 for USDC, 18 for most) */\n decimals: number;\n /** Optional display name */\n name?: string;\n}\n\nexport interface UseTokenBalanceOptions {\n /** ERC-20 token(s) to query */\n tokens: TokenInfo[];\n /** Auto-refresh interval in milliseconds. Default: undefined (no auto-refresh). */\n refreshInterval?: number;\n}\n\nexport interface TokenBalanceResult {\n address: Address;\n symbol: string;\n decimals: number;\n name?: string;\n /** Raw balance as string (in smallest unit), or null if not loaded */\n balance: string | null;\n /** Human-readable formatted balance, or null if not loaded */\n formatted: string | null;\n}\n\nexport function useTokenBalance(options: UseTokenBalanceOptions) {\n const { evmAccount, isConnected } = useAccount();\n const { chainId, chains } = useWeb3();\n const [tokenBalances, setTokenBalances] = useState<TokenBalanceResult[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const { tokens, refreshInterval } = options;\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n // Stable key for tokens to avoid infinite loops when array reference changes\n const tokensKey = useMemo(\n () => tokens.map(t => t.address.toLowerCase() + \"|\" + t.decimals + \"|\" + t.symbol).join(\",\"),\n [tokens]\n );\n\n const currentChain = useMemo(() => {\n if (!chainId || !chains.length) return null;\n const namespace = chainId.startsWith(\"eip155:\") ? \"eip155\" : null;\n if (!namespace) return null;\n const chainNum = parseInt(chainId.split(\":\")[1], 10);\n return chains.find((c) => c.namespace === namespace && c.id === chainNum) ?? null;\n }, [chainId, chains]);\n\n const [client, setClient] = useState<PublicClient | null>(null);\n\n useEffect(() => {\n if (!currentChain?.rpcUrl) {\n setClient(null);\n return;\n }\n\n const publicClient = createPublicClient({\n transport: http(currentChain.rpcUrl),\n chain: {\n id: currentChain.id,\n name: currentChain.name,\n nativeCurrency: {\n name: currentChain.token ?? \"ETH\",\n symbol: currentChain.token ?? \"ETH\",\n decimals: 18,\n },\n rpcUrls: {\n default: { http: [currentChain.rpcUrl] },\n public: { http: [currentChain.rpcUrl] },\n },\n },\n });\n\n setClient(publicClient);\n }, [currentChain]);\n\n // ERC-20 ABI fragment for balanceOf\n const erc20Abi = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"owner\", type: \"address\" }],\n outputs: [{ name: \"balance\", type: \"uint256\" }],\n },\n ] as const;\n\n const fetchTokenBalances = useCallback(async () => {\n if (!evmAccount || !client || tokens.length === 0) {\n setTokenBalances([]);\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const address = evmAccount.includes(\":\")\n ? (evmAccount.split(\":\").pop() as Address)\n : (evmAccount as Address);\n\n // Query all token balances with individual error handling\n const results = await Promise.allSettled(\n tokens.map(async (token) => {\n try {\n const balance = await client.readContract({\n address: token.address,\n abi: erc20Abi,\n functionName: \"balanceOf\",\n args: [address],\n });\n return {\n address: token.address,\n symbol: token.symbol,\n decimals: token.decimals,\n name: token.name,\n balance: balance.toString(),\n formatted: formatUnits(balance, token.decimals),\n } as TokenBalanceResult;\n } catch {\n return {\n address: token.address,\n symbol: token.symbol,\n decimals: token.decimals,\n name: token.name,\n balance: null,\n formatted: null,\n } as TokenBalanceResult;\n }\n })\n );\n\n const balances: TokenBalanceResult[] = results.map((r) => {\n if (r.status === \"fulfilled\") {\n return r.value;\n }\n // Fallback for rejected promises (shouldn't happen with inner catch)\n return {\n address: \"\" as Address,\n symbol: \"?\",\n decimals: 0,\n balance: null,\n formatted: null,\n };\n });\n\n setTokenBalances(balances);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to fetch token balances\"));\n } finally {\n setIsLoading(false);\n }\n }, [evmAccount, client, tokensKey]);\n\n // Initial fetch\n useEffect(() => {\n if (isConnected && evmAccount && tokens.length > 0) {\n fetchTokenBalances();\n }\n }, [isConnected, evmAccount, tokensKey, fetchTokenBalances]);\n\n // Auto-refresh interval\n useEffect(() => {\n if (refreshInterval && refreshInterval > 0 && isConnected && evmAccount && tokens.length > 0) {\n intervalRef.current = setInterval(fetchTokenBalances, refreshInterval);\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [refreshInterval, isConnected, evmAccount, tokensKey, fetchTokenBalances]);\n\n // Helper: get a single token balance by address\n const getTokenBalance = useCallback(\n (tokenAddress: Address): TokenBalanceResult | undefined => {\n return tokenBalances.find(\n (tb) => tb.address.toLowerCase() === tokenAddress.toLowerCase()\n );\n },\n [tokenBalances]\n );\n\n return {\n /** Array of token balance results */\n tokenBalances,\n isLoading,\n error,\n /** Re-fetch all token balances */\n refetch: fetchTokenBalances,\n /** Get a specific token balance by contract address */\n getTokenBalance,\n chain: currentChain,\n };\n}\n","import { useState, useCallback, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport { useViemClient } from \"./useViemClient\";\nimport { useSendTransaction } from \"./useSendTransaction\";\nimport { getClient } from \"../client\";\nimport { WalletError, ERC20_MIN_ABI, parseUnits } from \"@naculus/connect-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport type { Address, Hex } from \"viem\";\nimport { encodeFunctionData } from \"viem\";\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction toBareAddress(addr: string): Address {\n return (addr.includes(\":\") ? addr.split(\":\").pop()! : addr) as Address;\n}\n\nfunction encodeTransferCalldata(to: Address, amount: bigint): Hex {\n return encodeFunctionData({\n abi: ERC20_MIN_ABI,\n functionName: \"transfer\",\n args: [to, amount],\n });\n}\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20TransferOptions {\n token: TokenConfig;\n}\n\nexport interface UseERC20TransferReturn {\n /** Send a transfer. Returns tx hash on success. */\n sendTransfer: (to: Address, amount: string) => Promise<`0x${string}`>;\n isSending: boolean;\n error: Error | null;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Transfer(\n options: UseERC20TransferOptions,\n): UseERC20TransferReturn {\n const { publicClient, walletClient } = useViemClient();\n const { evmAccount, isConnected } = useAccount();\n const { session } = useWeb3();\n const { sendTransaction, isSending, error: sendTxError, reset } = useSendTransaction();\n const [localError, setLocalError] = useState<Error | null>(null);\n\n const decimalsRef = useRef<number | undefined>(options.token.decimals);\n const error = localError ?? sendTxError;\n\n const sendTransfer = useCallback(\n async (to: Address, amount: string): Promise<`0x${string}`> => {\n setLocalError(null);\n reset();\n\n if (!isConnected || !evmAccount) {\n const err = new WalletError(\"wallet_unavailable\", \"No connected account\");\n setLocalError(err);\n throw err;\n }\n\n if (!publicClient) {\n const err = new WalletError(\"wallet_unavailable\", \"No public client available\");\n setLocalError(err);\n throw err;\n }\n\n const address = toBareAddress(evmAccount);\n\n // Fetch decimals if not cached\n let decimals = decimalsRef.current;\n if (decimals === undefined) {\n decimals = await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n }) as number;\n decimalsRef.current = decimals;\n }\n\n const rawAmount = parseUnits(amount, decimals);\n const data = encodeTransferCalldata(to, rawAmount);\n\n try {\n // Strategy 1: session-based connector\n if (session) {\n const client = getClient();\n if (client) {\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n return txHash as `0x${string}`;\n }\n }\n\n // Strategy 2: embedded wallet via viem wallet client\n if (walletClient) {\n const { request } = await publicClient.simulateContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"transfer\",\n args: [to, rawAmount],\n account: address,\n });\n const txHash = await walletClient.writeContract(request);\n return txHash;\n }\n\n // Strategy 3: fallback to sendTransaction hook\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n return txHash as `0x${string}`;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Transfer failed\");\n setLocalError(error);\n throw error;\n }\n },\n [options.token, publicClient, walletClient, evmAccount, isConnected, session, sendTransaction, reset],\n );\n\n return {\n sendTransfer,\n isSending,\n error,\n };\n}\n","import { useMemo } from \"react\";\nimport { createPublicClient, http, createWalletClient, type PublicClient, type WalletClient } from \"viem\";\nimport type { WalletChain } from \"../types\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\n\nexport function useViemClient(): {\n publicClient: PublicClient | null;\n walletClient: WalletClient | null;\n chains: WalletChain[];\n} {\n const { evmAccount, isConnected } = useAccount();\n const { currentChain, chains } = useChain();\n\n const publicClient = useMemo<PublicClient | null>(() => {\n if (!currentChain?.rpcUrl) return null;\n\n return createPublicClient({\n transport: http(currentChain.rpcUrl),\n chain: {\n id: currentChain.id,\n name: currentChain.name,\n nativeCurrency: {\n name: currentChain.token ?? \"ETH\",\n symbol: currentChain.token ?? \"ETH\",\n decimals: 18\n },\n rpcUrls: {\n default: { http: [currentChain.rpcUrl] },\n public: { http: [currentChain.rpcUrl] }\n }\n }\n });\n }, [currentChain]);\n\n const walletClient = useMemo<WalletClient | null>(() => {\n if (!isConnected || !evmAccount || !currentChain?.rpcUrl) return null;\n\n const address = evmAccount.includes(\":\") ? evmAccount.split(\":\").pop()! : evmAccount;\n\n return createWalletClient({\n transport: http(currentChain.rpcUrl),\n chain: {\n id: currentChain.id,\n name: currentChain.name,\n nativeCurrency: {\n name: currentChain.token ?? \"ETH\",\n symbol: currentChain.token ?? \"ETH\",\n decimals: 18\n },\n rpcUrls: {\n default: { http: [currentChain.rpcUrl] },\n public: { http: [currentChain.rpcUrl] }\n }\n },\n account: address as `0x${string}`\n });\n }, [isConnected, evmAccount, currentChain]);\n\n return {\n publicClient,\n walletClient,\n chains\n };\n}","import { useState, useCallback, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport { useViemClient } from \"./useViemClient\";\nimport { useSendTransaction } from \"./useSendTransaction\";\nimport { getClient } from \"../client\";\nimport { WalletError, ERC20_MIN_ABI, parseUnits } from \"@naculus/connect-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport type { Address, Hex } from \"viem\";\nimport { encodeFunctionData } from \"viem\";\n\n// ── Helpers ───────────────────────────────────────────────────────\n\nfunction toBareAddress(addr: string): Address {\n return (addr.includes(\":\") ? addr.split(\":\").pop()! : addr) as Address;\n}\n\nfunction encodeApproveCalldata(spender: Address, amount: bigint): Hex {\n return encodeFunctionData({\n abi: ERC20_MIN_ABI,\n functionName: \"approve\",\n args: [spender, amount],\n });\n}\n\n// ── Constants ─────────────────────────────────────────────────────\n\nconst MAX_UINT256 = 2n ** 256n - 1n;\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20ApproveOptions {\n token: TokenConfig;\n spender: Address;\n}\n\nexport interface UseERC20ApproveReturn {\n /** Approve a specific amount */\n approve: (amount: string) => Promise<`0x${string}`>;\n /** Approve max (type(uint256).max — infinite approval) */\n approveMax: () => Promise<`0x${string}`>;\n /** Current allowance as raw bigint */\n allowanceRaw: bigint | null;\n /** Current allowance as human-readable string */\n allowance: string | null;\n /** Check if allowance >= required amount */\n hasAllowance: (required: string) => Promise<boolean>;\n isApproving: boolean;\n isFetchingAllowance: boolean;\n error: Error | null;\n refetchAllowance: () => Promise<void>;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Approve(\n options: UseERC20ApproveOptions,\n): UseERC20ApproveReturn {\n const { publicClient, walletClient } = useViemClient();\n const { evmAccount, isConnected } = useAccount();\n const { session } = useWeb3();\n const { sendTransaction, isSending, error: sendTxError, reset } = useSendTransaction();\n const [localError, setLocalError] = useState<Error | null>(null);\n const [allowanceRaw, setAllowanceRaw] = useState<bigint | null>(null);\n const [isFetchingAllowance, setIsFetchingAllowance] = useState(false);\n\n const decimalsRef = useRef<number | undefined>(options.token.decimals);\n const error = localError ?? sendTxError;\n\n const ownerAddress = (() => {\n if (!evmAccount) return null;\n return toBareAddress(evmAccount);\n })();\n\n const fetchAllowance = useCallback(async () => {\n if (!publicClient || !ownerAddress) return;\n\n setIsFetchingAllowance(true);\n try {\n const raw = await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"allowance\",\n args: [ownerAddress, options.spender],\n });\n setAllowanceRaw(raw as bigint);\n } catch {\n setAllowanceRaw(null);\n } finally {\n setIsFetchingAllowance(false);\n }\n }, [publicClient, ownerAddress, options.token.address, options.spender]);\n\n const allowance = (() => {\n if (allowanceRaw === null) return null;\n const decimals = decimalsRef.current ?? options.token.decimals ?? 18;\n const str = allowanceRaw.toString();\n const padded = str.padStart(decimals + 1, \"0\");\n const dotPos = padded.length - decimals;\n let intPart = padded.slice(0, dotPos).replace(/^0+/, \"\") || \"0\";\n let fracPart = padded.slice(dotPos).replace(/0+$/, \"\");\n return fracPart ? `${intPart}.${fracPart}` : intPart;\n })();\n\n const doApprove = useCallback(\n async (rawAmount: bigint): Promise<`0x${string}`> => {\n setLocalError(null);\n reset();\n\n if (!isConnected || !evmAccount) {\n const err = new WalletError(\"wallet_unavailable\", \"No connected account\");\n setLocalError(err);\n throw err;\n }\n\n if (!publicClient) {\n const err = new WalletError(\"wallet_unavailable\", \"No public client\");\n setLocalError(err);\n throw err;\n }\n\n const data = encodeApproveCalldata(options.spender, rawAmount);\n\n try {\n if (session) {\n const client = getClient();\n if (client) {\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n fetchAllowance();\n return txHash as `0x${string}`;\n }\n }\n\n if (walletClient) {\n const { request } = await publicClient.simulateContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"approve\",\n args: [options.spender, rawAmount],\n account: ownerAddress!,\n });\n const txHash = await walletClient.writeContract(request);\n fetchAllowance();\n return txHash;\n }\n\n const txHash = await sendTransaction({\n to: options.token.address,\n data,\n value: \"0\",\n });\n fetchAllowance();\n return txHash as `0x${string}`;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Approve failed\");\n setLocalError(error);\n throw error;\n }\n },\n [options, publicClient, walletClient, evmAccount, isConnected, session, ownerAddress, sendTransaction, reset, fetchAllowance],\n );\n\n const approveAmount = useCallback(\n async (amount: string): Promise<`0x${string}`> => {\n if (!publicClient) throw new WalletError(\"wallet_unavailable\", \"No public client\");\n\n let decimals = decimalsRef.current;\n if (decimals === undefined) {\n decimals = await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"decimals\",\n }) as number;\n decimalsRef.current = decimals;\n }\n\n const rawAmount = parseUnits(amount, decimals);\n return doApprove(rawAmount);\n },\n [options.token.address, publicClient, doApprove],\n );\n\n const approveMaxAmount = useCallback(async (): Promise<`0x${string}`> => {\n return doApprove(MAX_UINT256);\n }, [doApprove]);\n\n const checkAllowance = useCallback(\n async (required: string): Promise<boolean> => {\n if (allowanceRaw === null) {\n await fetchAllowance();\n }\n if (allowanceRaw === null) return false;\n\n let decimals = decimalsRef.current ?? options.token.decimals;\n if (decimals === undefined) {\n decimals = 18; // safe fallback\n }\n\n const requiredRaw = parseUnits(required, decimals);\n return allowanceRaw >= requiredRaw;\n },\n [allowanceRaw, fetchAllowance, options.token.decimals],\n );\n\n return {\n approve: approveAmount,\n approveMax: approveMaxAmount,\n allowance,\n allowanceRaw,\n hasAllowance: checkAllowance,\n isApproving: isSending,\n isFetchingAllowance,\n error,\n refetchAllowance: fetchAllowance,\n };\n}\n","import { useState, useCallback, useEffect, useRef, useMemo } from \"react\";\nimport { useViemClient } from \"./useViemClient\";\nimport { ERC20_MIN_ABI } from \"@naculus/connect-core\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport type { Address } from \"viem\";\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20AllowanceOptions {\n token: TokenConfig;\n owner: Address;\n spender: Address;\n refreshInterval?: number;\n}\n\nexport interface UseERC20AllowanceReturn {\n allowance: string | null;\n allowanceRaw: bigint | null;\n isFetching: boolean;\n error: Error | null;\n refetch: () => Promise<void>;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20Allowance(\n options: UseERC20AllowanceOptions,\n): UseERC20AllowanceReturn {\n const { publicClient } = useViemClient();\n const [allowanceRaw, setAllowanceRaw] = useState<bigint | null>(null);\n const [isFetching, setIsFetching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const fetchAllowance = useCallback(async () => {\n if (!publicClient) return;\n\n setIsFetching(true);\n setError(null);\n\n try {\n const raw = await publicClient.readContract({\n address: options.token.address,\n abi: ERC20_MIN_ABI,\n functionName: \"allowance\",\n args: [options.owner, options.spender],\n });\n setAllowanceRaw(raw as bigint);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to fetch allowance\"));\n setAllowanceRaw(null);\n } finally {\n setIsFetching(false);\n }\n }, [publicClient, options.token.address, options.owner, options.spender]);\n\n // Initial fetch\n useEffect(() => {\n fetchAllowance().catch((e) => console.warn(\"useERC20Allowance: initial fetch failed:\", e));\n }, [fetchAllowance]);\n\n // Auto-refresh interval\n useEffect(() => {\n if (options.refreshInterval && options.refreshInterval > 0) {\n intervalRef.current = setInterval(fetchAllowance, options.refreshInterval);\n }\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n };\n }, [options.refreshInterval, fetchAllowance]);\n\n const allowance = useMemo(() => {\n if (allowanceRaw === null) return null;\n const decimals = options.token.decimals ?? 18;\n const str = allowanceRaw.toString();\n const padded = str.padStart(decimals + 1, \"0\");\n const dotPos = padded.length - decimals;\n let intPart = padded.slice(0, dotPos).replace(/^0+/, \"\") || \"0\";\n let fracPart = padded.slice(dotPos).replace(/0+$/, \"\");\n return fracPart ? `${intPart}.${fracPart}` : intPart;\n }, [allowanceRaw, options.token.decimals]);\n\n return {\n allowance,\n allowanceRaw,\n isFetching,\n error,\n refetch: fetchAllowance,\n };\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\nimport type { WalletData } from \"@naculus/connector-embedded\";\nimport { WalletError } from \"@naculus/connect-core\";\n\nexport interface UseEmbeddedWalletReturn {\n connectEmbedded: () => Promise<void>;\n generateWallet: () => Promise<WalletData | null>;\n importFromMnemonic: (mnemonic: string) => Promise<WalletData | null>;\n importFromPrivateKey: (pk: `0x${string}`) => Promise<WalletData | null>;\n wipe: () => void;\n wallet: WalletData | null;\n hasWallet: boolean;\n address: string | null;\n /** @deprecated Use getSeedPhrase() instead. This field will be removed. */\n seedPhrase: string | null;\n /** Get seed phrase once and clear from memory. Returns mnemonic or null. */\n getSeedPhrase: () => string | null;\n backupPending: boolean;\n confirmBackup: () => void;\n isBusy: boolean;\n error: Error | null;\n clearError: () => void;\n /**\n * Storage security tier (1-4).\n * 1 = IndexedDB + AES-GCM, 2 = IndexedDB,\n * 3 = localStorage + AES-GCM, 4 = localStorage plaintext\n */\n storageSecurityLevel: number;\n}\n\nexport function useEmbeddedWallet(): UseEmbeddedWalletReturn {\n const { connectEmbedded: providerConnectEmbedded } = useWeb3();\n const [wallet, setWallet] = useState<WalletData | null>(null);\n const seedPhraseRef = useRef<string | null>(null);\n const [backupPending, setBackupPending] = useState(false);\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = () => setError(null);\n\n /** Get seed phrase once and immediately clear from memory */\n const getSeedPhrase = useCallback(() => {\n const phrase = seedPhraseRef.current;\n seedPhraseRef.current = null; // Clear immediately\n return phrase;\n }, []);\n\n const getEmbeddedConnector = () => {\n const client = getClient();\n if (!client?.embeddedConnector) {\n throw new WalletError(\"wallet_unavailable\", \"Embedded wallet not enabled.\");\n }\n return client.embeddedConnector;\n };\n\n const handleConnectEmbedded = async () => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = getEmbeddedConnector();\n const loaded = await connector.load();\n const w = connector.getWallet();\n if (loaded && w) {\n setWallet(w);\n seedPhraseRef.current = w.mnemonic || null;\n setBackupPending(!w.mnemonic);\n }\n await providerConnectEmbedded();\n const w2 = connector.getWallet();\n if (w2) {\n setWallet(w2);\n if (w2.mnemonic && !loaded) {\n seedPhraseRef.current = w2.mnemonic;\n setBackupPending(true);\n }\n }\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Embedded wallet connection failed\"));\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleGenerateWallet = async (): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = getEmbeddedConnector();\n const w = await connector.generateWallet();\n setWallet(w);\n seedPhraseRef.current = w.mnemonic;\n setBackupPending(true);\n return w;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to generate wallet\"));\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleImportFromMnemonic = async (mnemonic: string): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = getEmbeddedConnector();\n const w = await connector.importFromMnemonic(mnemonic);\n setWallet(w);\n seedPhraseRef.current = null;\n setBackupPending(false);\n return w;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to import wallet\"));\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleImportFromPrivateKey = async (pk: `0x${string}`): Promise<WalletData | null> => {\n setIsBusy(true);\n setError(null);\n try {\n const connector = getEmbeddedConnector();\n const w = await connector.importFromPrivateKey(pk);\n setWallet(w);\n seedPhraseRef.current = null;\n setBackupPending(false);\n return w;\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to import wallet\"));\n return null;\n } finally {\n setIsBusy(false);\n }\n };\n\n const handleWipe = () => {\n try {\n const connector = getEmbeddedConnector();\n connector.wipe();\n setWallet(null);\n seedPhraseRef.current = null;\n setBackupPending(false);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(\"Failed to wipe wallet\"));\n }\n };\n\n const handleConfirmBackup = () => {\n seedPhraseRef.current = null;\n setBackupPending(false);\n };\n\n return {\n connectEmbedded: handleConnectEmbedded,\n generateWallet: handleGenerateWallet,\n importFromMnemonic: handleImportFromMnemonic,\n importFromPrivateKey: handleImportFromPrivateKey,\n wipe: handleWipe,\n wallet,\n hasWallet: wallet !== null,\n address: wallet?.address ?? null,\n seedPhrase: seedPhraseRef.current, // backward compat (deprecated)\n getSeedPhrase,\n backupPending,\n confirmBackup: handleConfirmBackup,\n isBusy,\n error,\n clearError,\n storageSecurityLevel: (() => {\n try {\n return getEmbeddedConnector().getStorageSecurityLevel?.() ?? 4;\n } catch {\n return 4;\n }\n })(),\n };\n}\n","/**\n * useValidateDestination — address blackhole prevention hook.\n *\n * Validates that a destination address is not a known burn/zero address\n * before sending a transaction. Returns { isValid, warning, level }.\n *\n * Level: \"safe\" | \"warning\" | \"blocked\"\n */\n\nimport { useMemo } from \"react\";\nimport { t } from \"../utils/i18n\";\n\n// ── Known burn / zero addresses ─────────────────────────────────\n\nconst ZERO_ADDRESS = \"0x0000000000000000000000000000000000000000\";\nconst DEAD_ADDRESSES = new Set([\n ZERO_ADDRESS,\n \"0x0000000000000000000000000000000000000001\",\n \"0x000000000000000000000000000000000000dead\",\n \"0x000000000000000000000000000000000000dEaD\",\n]);\n\nfunction isBurnAddress(addr: string): boolean {\n const lower = addr.toLowerCase();\n if (DEAD_ADDRESSES.has(lower)) return true;\n return lower.includes(\"dead\") && lower.length >= 40;\n}\n\nfunction isZeroAddress(addr: string): boolean {\n return addr === ZERO_ADDRESS;\n}\n\nfunction isValidFormat(addr: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test(addr);\n}\n\nexport type AddressValidationLevel = \"safe\" | \"warning\" | \"blocked\";\n\nexport interface AddressValidationResult {\n isValid: boolean;\n level: AddressValidationLevel;\n warning: string | null;\n}\n\nexport function validateDestination(address: string): AddressValidationResult {\n if (!address) {\n return { isValid: false, level: \"blocked\", warning: t(\"address.empty\") };\n }\n if (!isValidFormat(address)) {\n return { isValid: false, level: \"blocked\", warning: t(\"address.invalid_format\") };\n }\n if (isZeroAddress(address)) {\n return { isValid: false, level: \"blocked\", warning: t(\"address.zero_address\") };\n }\n if (isBurnAddress(address)) {\n return { isValid: false, level: \"blocked\", warning: t(\"address.burn_address\") };\n }\n return { isValid: true, level: \"safe\", warning: null };\n}\n\nexport interface UseValidateDestinationOptions {\n address: string;\n}\n\nexport interface UseValidateDestinationReturn {\n validation: AddressValidationResult;\n}\n\nexport function useValidateDestination({ address }: UseValidateDestinationOptions): UseValidateDestinationReturn {\n const validation = useMemo(() => validateDestination(address), [address]);\n return { validation };\n}\n","/**\n * i18n — ponytail approach: static key-value map, no framework dependency.\n *\n * All UI strings go through here. No hardcoded text in components.\n * To add a language: copy this file and translate the values.\n */\n\nexport type Locale = \"en\" | \"zh\";\n\nconst en = {\n // Storage security\n \"storage.critical.title\": \"Insecure Storage Detected\",\n \"storage.critical.body\": \"Your browser does not support IndexedDB. Wallet data is stored in plaintext in localStorage and could be exposed to XSS attacks. We strongly recommend switching to a modern browser.\",\n \"storage.warning.title\": \"Storage Security Warning\",\n \"storage.warning.body\": \"Your browser does not support IndexedDB, but your wallet data is encrypted with AES-256-GCM. Consider switching browsers for better origin isolation.\",\n\n // Address validation\n \"address.empty\": \"Address is empty\",\n \"address.invalid_format\": \"Invalid address format (expected 0x + 40 hex chars)\",\n \"address.zero_address\": \"Address is the zero address — funds would be permanently lost\",\n \"address.burn_address\": \"Address appears to be a burn address — funds would be permanently lost\",\n\n // General wallet\n \"wallet.connect\": \"Connect Wallet\",\n \"wallet.disconnect\": \"Disconnect\",\n \"wallet.connecting\": \"Connecting...\",\n \"wallet.copy_address\": \"Copy address\",\n \"wallet.copied\": \"Copied!\",\n \"wallet.view_on_explorer\": \"View on Explorer\",\n \"wallet.retry\": \"Retry\",\n \"wallet.connection_failed\": \"Connection failed\",\n \"wallet.scan_qr\": \"Scan with your wallet app\",\n\n // Embedded wallet\n \"embedded.generate\": \"Create Wallet\",\n \"embedded.import\": \"Import Wallet\",\n \"embedded.backup_seed\": \"Back up your seed phrase\",\n \"embedded.backup_warning\": \"Anyone with your seed phrase can access your funds. Store it securely.\",\n \"embedded.backup_done\": \"I've saved my seed phrase\",\n \"embedded.wipe\": \"Remove Wallet\",\n \"embedded.wipe_confirm\": \"Are you sure? This cannot be undone.\",\n} as const;\n\nconst zh: Record<keyof typeof en, string> = {\n \"storage.critical.title\": \"偵測到不安全儲存\",\n \"storage.critical.body\": \"您的瀏覽器不支援 IndexedDB。錢包資料以明文儲存在 localStorage 中,可能暴露於 XSS 攻擊。強烈建議更換至現代瀏覽器。\",\n \"storage.warning.title\": \"儲存安全警告\",\n \"storage.warning.body\": \"您的瀏覽器不支援 IndexedDB,但錢包資料已使用 AES-256-GCM 加密。建議更換瀏覽器以獲得更好的隔離保護。\",\n\n \"address.empty\": \"地址為空\",\n \"address.invalid_format\": \"無效的地址格式(應為 0x + 40 個十六進位字元)\",\n \"address.zero_address\": \"此為零地址 — 資金將永久丟失\",\n \"address.burn_address\": \"此地址為燒毀地址 — 資金將永久丟失\",\n\n \"wallet.connect\": \"連接錢包\",\n \"wallet.disconnect\": \"斷開連線\",\n \"wallet.connecting\": \"連線中...\",\n \"wallet.copy_address\": \"複製地址\",\n \"wallet.copied\": \"已複製!\",\n \"wallet.view_on_explorer\": \"在瀏覽器查看\",\n \"wallet.retry\": \"重試\",\n \"wallet.connection_failed\": \"連線失敗\",\n \"wallet.scan_qr\": \"使用錢包 App 掃描\",\n\n \"embedded.generate\": \"建立錢包\",\n \"embedded.import\": \"匯入錢包\",\n \"embedded.backup_seed\": \"備份助記詞\",\n \"embedded.backup_warning\": \"任何人取得您的助記詞都可以存取您的資金。請安全儲存。\",\n \"embedded.backup_done\": \"我已儲存助記詞\",\n \"embedded.wipe\": \"移除錢包\",\n \"embedded.wipe_confirm\": \"確定要移除嗎?此操作無法復原。\",\n};\n\nconst locales = { en, zh } as const;\n\nlet currentLocale: Locale = \"en\";\n\nexport function setLocale(locale: Locale): void {\n currentLocale = locale;\n}\n\nexport function getLocale(): Locale {\n return currentLocale;\n}\n\nexport function t(key: keyof typeof en): string {\n return locales[currentLocale][key] ?? locales.en[key] ?? key;\n}\n\nexport { en, zh };\n","import { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n createSiwxMessage,\n generateNonce,\n nowISO,\n getBlockchainName,\n type SiwxResult,\n} from \"@naculus/siwx\";\n\nexport interface UseSignInWithXOptions {\n domain?: string;\n statement?: string;\n uri?: string;\n chainId?: string;\n expirySeconds?: number;\n resources?: string[];\n requestId?: string;\n}\n\nexport interface UseSignInWithXReturn {\n signIn: (options?: UseSignInWithXOptions) => Promise<SiwxResult>;\n isSigningIn: boolean;\n result: SiwxResult | null;\n error: Error | null;\n clearError: () => void;\n}\n\nfunction getDefaultDomain(): string {\n if (typeof window !== \"undefined\") return window.location.host;\n return \"localhost\";\n}\n\nfunction getDefaultUri(): string {\n if (typeof window !== \"undefined\") return window.location.origin;\n return \"http://localhost\";\n}\n\nexport function useSignInWithX(): UseSignInWithXReturn {\n const { session, chainId: currentChainId } = useWeb3();\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [result, setResult] = useState<SiwxResult | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const signIn = useCallback(\n async (options?: UseSignInWithXOptions): Promise<SiwxResult> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n const client = getClient();\n if (!client) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n\n const allAccounts = Object.entries(session.namespaces).flatMap(\n ([ns, info]) =>\n info.accounts.map((acc: string) => ({ ns, acc }))\n );\n\n if (allAccounts.length === 0) {\n throw new WalletError(\"wallet_unavailable\", \"No account found\");\n }\n\n const { acc: address } = allAccounts[0];\n const chainId = options?.chainId ?? currentChainId ?? \"eip155:1\";\n const domain = options?.domain ?? getDefaultDomain();\n const uri = options?.uri ?? getDefaultUri();\n const nonce = generateNonce();\n const issuedAt = nowISO();\n\n const message = createSiwxMessage({\n domain,\n address,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n statement: options?.statement,\n expirationTime: options?.expirySeconds\n ? new Date(Date.now() + options.expirySeconds * 1000).toISOString()\n : undefined,\n resources: options?.resources,\n requestId: options?.requestId,\n });\n\n setIsSigningIn(true);\n setError(null);\n\n try {\n const signature = (await client.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined,\n })) as string;\n\n const expirationTime = options?.expirySeconds\n ? new Date(Date.now() + options.expirySeconds * 1000).toISOString()\n : null;\n\n const siwxResult: SiwxResult = {\n message: {\n raw: message,\n domain,\n address,\n statement: options?.statement ?? null,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n blockchain: getBlockchainName(chainId),\n expirationTime,\n notBefore: null,\n resources: options?.resources ?? [],\n requestId: options?.requestId ?? null,\n },\n signature,\n };\n\n setResult(siwxResult);\n return siwxResult;\n } catch (err) {\n const wrappedErr =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrappedErr);\n throw wrappedErr;\n } finally {\n setIsSigningIn(false);\n }\n },\n [session, currentChainId]\n );\n\n return { signIn, isSigningIn, result, error, clearError };\n}\n","import { useSignInWithX } from \"./useSignInWithX\";\nimport type { UseSignInWithXOptions, UseSignInWithXReturn } from \"./useSignInWithX\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useCallback } from \"react\";\n\nexport interface UseSignInWithEthereumOptions extends UseSignInWithXOptions {}\n\nexport interface UseSignInWithEthereumReturn extends UseSignInWithXReturn {}\n\nfunction useEip155SessionGuard(): () => void {\n const { session } = useWeb3();\n return useCallback(() => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n const evmNamespace = session.namespaces[\"eip155\"];\n if (!evmNamespace || evmNamespace.accounts.length === 0) {\n throw new WalletError(\n \"namespace_mismatch\",\n \"No EVM (eip155) accounts found in session\"\n );\n }\n }, [session]);\n}\n\nexport function useSignInWithEthereum(): UseSignInWithEthereumReturn {\n const guard = useEip155SessionGuard();\n const siwx = useSignInWithX();\n\n const signIn = useCallback(\n async (options?: UseSignInWithEthereumOptions) => {\n guard();\n return siwx.signIn(options);\n },\n [guard, siwx.signIn]\n );\n\n return {\n signIn,\n isSigningIn: siwx.isSigningIn,\n result: siwx.result,\n error: siwx.error,\n clearError: siwx.clearError,\n };\n}\n","import { useState, useCallback, useEffect, useRef } from \"react\";\nimport { useSignInWithX } from \"./useSignInWithX\";\nimport type { UseSignInWithXOptions } from \"./useSignInWithX\";\nimport { LocalStorageAdapter, logger } from \"@naculus/connect-core\";\nimport type { SiwxResult } from \"@naculus/siwx\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSiwxAuthSessionOptions {\n /** Storage key prefix (default: \"naculus_\") */\n storagePrefix?: string;\n /** Auto-restore auth from storage on mount (default: true) */\n autoRestore?: boolean;\n}\n\nexport interface UseSiwxAuthSessionReturn {\n /** Whether a valid SIWx auth session exists */\n isSignedIn: boolean;\n /** Whether we're still checking persisted auth on mount */\n isRestoring: boolean;\n /** The persisted SIWx result, or null if not signed in */\n siwxResult: SiwxResult | null;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Last sign-in error */\n error: Error | null;\n /** Sign in with optional overrides. Persists result to storage on success. */\n signIn: (options?: UseSignInWithXOptions) => Promise<SiwxResult>;\n /** Sign out: clears persisted auth and resets state */\n signOut: () => void;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Constants ────────────────────────────────────────────────────\n\nconst SIWX_AUTH_KEY = \"siwx_auth\";\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction getStorage(prefix: string): LocalStorageAdapter {\n return new LocalStorageAdapter(prefix);\n}\n\nfunction isExpired(siwxResult: SiwxResult, now: Date): boolean {\n if (!siwxResult.message.expirationTime) return false;\n return new Date(siwxResult.message.expirationTime).getTime() <= now.getTime();\n}\n\nfunction isNotBeforeValid(siwxResult: SiwxResult, now: Date): boolean {\n if (!siwxResult.message.notBefore) return true;\n return new Date(siwxResult.message.notBefore).getTime() <= now.getTime();\n}\n\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSiwxAuthSession(\n options?: UseSiwxAuthSessionOptions\n): UseSiwxAuthSessionReturn {\n const { storagePrefix = \"naculus_\", autoRestore = true } = options ?? {};\n\n const [siwxResult, setSiwxResult] = useState<SiwxResult | null>(null);\n const [isRestoring, setIsRestoring] = useState(autoRestore);\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Use the generic SIWx hook for the underlying signing flow.\n const signInWithX = useSignInWithX();\n const storageRef = useRef(getStorage(storagePrefix));\n\n const clearError = useCallback(() => setError(null), []);\n\n // ── Restore persisted auth on mount ────────────────────────────\n\n useEffect(() => {\n if (!autoRestore) {\n setIsRestoring(false);\n return;\n }\n\n let cancelled = false;\n\n (async () => {\n try {\n const storage = storageRef.current;\n const saved = await storage.get<SiwxResult>(SIWX_AUTH_KEY);\n\n if (cancelled) return;\n\n if (saved && !isExpired(saved, new Date()) && isNotBeforeValid(saved, new Date())) {\n logger.info(\"react/useSiwxAuthSession\", \"Restored persisted SIWx auth session\");\n setSiwxResult(saved);\n setError(null);\n } else if (saved) {\n // Expired or not-yet-valid — clean up stale entry\n logger.info(\"react/useSiwxAuthSession\", \"Persisted SIWx auth expired, clearing\");\n await storage.remove(SIWX_AUTH_KEY);\n }\n } catch (err) {\n logger.warn(\"react/useSiwxAuthSession\", \"Failed to restore SIWx auth:\", err);\n } finally {\n if (!cancelled) setIsRestoring(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [autoRestore]);\n\n // ── Sign In ────────────────────────────────────────────────────\n\n const signIn = useCallback(\n async (signOptions?: UseSignInWithXOptions): Promise<SiwxResult> => {\n setIsSigningIn(true);\n setError(null);\n\n try {\n const result = await signInWithX.signIn(signOptions);\n\n // Persist to storage\n const storage = storageRef.current;\n await storage.set(SIWX_AUTH_KEY, result);\n\n setSiwxResult(result);\n setIsSigningIn(false);\n return result;\n } catch (err) {\n const wrapped = err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n },\n [signInWithX]\n );\n\n // ── Sign Out ───────────────────────────────────────────────────\n\n const signOut = useCallback(async () => {\n try {\n const storage = storageRef.current;\n await storage.remove(SIWX_AUTH_KEY);\n } catch (err) {\n logger.warn(\"react/useSiwxAuthSession\", \"Failed to clear SIWx auth:\", err);\n }\n setSiwxResult(null);\n setError(null);\n }, []);\n\n // ── Result ─────────────────────────────────────────────────────\n\n return {\n isSignedIn: siwxResult !== null,\n isRestoring,\n siwxResult,\n isSigningIn,\n error,\n signIn,\n signOut,\n clearError,\n };\n}\n","/**\n * useSIWxLogin — Trigger a SIWx sign-in flow.\n *\n * A simplified hook for initiating wallet sign-in.\n * Returns a `signIn()` function and loading/error state.\n */\n\nimport { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\nimport { WalletError } from \"@naculus/connect-core\";\nimport {\n createSiwxMessage,\n generateNonce,\n nowISO,\n getBlockchainName,\n type SiwxResult,\n type SiwxMessage,\n} from \"@naculus/siwx\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSIWxLoginOptions {\n /** Originating domain (default: window.location.host) */\n domain?: string;\n /** Human-readable statement */\n statement?: string;\n /** RFC 3986 URI (default: window.location.origin) */\n uri?: string;\n /** CAIP-2 chain ID (default: current chain from Web3 context) */\n chainId?: string;\n /** Session lifetime in seconds (default: 86400 = 24h) */\n expirySeconds?: number;\n /** URIs of resources the identity wishes to access */\n resources?: string[];\n /** CAIP-74 request ID */\n requestId?: string;\n}\n\nexport interface UseSIWxLoginReturn {\n /** Trigger the SIWx sign-in flow */\n signIn: (options?: UseSIWxLoginOptions) => Promise<SiwxResult>;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Last sign-in error */\n error: Error | null;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Defaults ─────────────────────────────────────────────────────\n\nconst DEFAULT_EXPIRY_SECONDS = 86_400; // 24h\n\nfunction getDefaultDomain(): string {\n if (typeof window !== \"undefined\") return window.location.host;\n return \"localhost\";\n}\n\nfunction getDefaultUri(): string {\n if (typeof window !== \"undefined\") return window.location.origin;\n return \"http://localhost\";\n}\n\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSIWxLogin(): UseSIWxLoginReturn {\n const { session, chainId: currentChainId } = useWeb3();\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const signIn = useCallback(\n async (options?: UseSIWxLoginOptions): Promise<SiwxResult> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active session\");\n }\n\n const client = getClient();\n if (!client) {\n throw new WalletError(\"wallet_unavailable\", \"Client not initialized\");\n }\n\n // Resolve the first available account and chain\n const allAccounts = Object.entries(session.namespaces).flatMap(\n ([ns, info]) =>\n info.accounts.map((acc: string) => ({ ns, acc }))\n );\n\n if (allAccounts.length === 0) {\n throw new WalletError(\"wallet_unavailable\", \"No account found\");\n }\n\n const { acc: address } = allAccounts[0];\n const chainId = options?.chainId ?? currentChainId ?? \"eip155:1\";\n const domain = options?.domain ?? getDefaultDomain();\n const uri = options?.uri ?? getDefaultUri();\n const nonce = generateNonce();\n const issuedAt = nowISO();\n const expirySeconds = options?.expirySeconds ?? DEFAULT_EXPIRY_SECONDS;\n const expirationTime = new Date(Date.now() + expirySeconds * 1000).toISOString();\n\n // Build the CAIP-122 message string\n const message = createSiwxMessage({\n domain,\n address,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n expirationTime,\n statement: options?.statement,\n resources: options?.resources,\n requestId: options?.requestId,\n });\n\n setIsSigningIn(true);\n setError(null);\n\n try {\n const signature = (await client.signMessage(session, {\n message,\n address,\n chainId: chainId ?? undefined,\n })) as string;\n\n const siwxResult: SiwxResult = {\n message: {\n raw: message,\n domain,\n address,\n statement: options?.statement ?? null,\n uri,\n version: 1,\n chainId,\n nonce,\n issuedAt,\n blockchain: getBlockchainName(chainId),\n expirationTime,\n notBefore: null,\n resources: options?.resources ?? [],\n requestId: options?.requestId ?? null,\n },\n signature,\n };\n\n setIsSigningIn(false);\n return siwxResult;\n } catch (err) {\n const wrappedErr =\n err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrappedErr);\n setIsSigningIn(false);\n throw wrappedErr;\n }\n },\n [session, currentChainId]\n );\n\n return { signIn, isSigningIn, error, clearError };\n}\n","/**\n * useSIWxSession — Unified SIWx session management hook.\n *\n * Combines the sign-in flow with session persistence, expiry tracking,\n * and automatic restoration. Replaces the older useSiwxAuthSession.\n *\n * Provides:\n * - signIn / signOut / refresh lifecycle\n * - Auto-restore from storage on mount\n * - isExpired / timeUntilExpiry query\n * - Loading/error state\n */\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { useSIWxLogin } from \"./useSIWxLogin\";\nimport type { UseSIWxLoginOptions } from \"./useSIWxLogin\";\nimport { LocalStorageAdapter, logger } from \"@naculus/connect-core\";\nimport type {\n SiwxResult,\n SiwxMessage,\n} from \"@naculus/siwx\";\nimport { checkSessionExpired, createLocalStorageSiwxSessionStorage, SiwxSessionManager } from \"@naculus/siwx\";\nimport type { SiwxSession } from \"@naculus/siwx\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\n\n// ── Constants ────────────────────────────────────────────────────\n\nconst SIWX_SESSION_KEY = \"naculus_siwx_session\";\n\n// ── Types ────────────────────────────────────────────────────────\n\nexport interface UseSIWxSessionOptions {\n /** Storage key prefix (default: \"naculus_\") */\n storagePrefix?: string;\n /** Auto-restore session from storage on mount (default: true) */\n autoRestore?: boolean;\n /** Default chain ID when signing in (default: current chain from context) */\n defaultChainId?: string;\n /** Default session lifetime in seconds (default: 86400 = 24h) */\n defaultExpirySeconds?: number;\n}\n\nexport interface UseSIWxSessionReturn {\n /** The current SIWx session, or null */\n session: SiwxSession | null;\n /** Whether a valid session exists */\n isAuthenticated: boolean;\n /** Whether we're still checking persisted auth on mount */\n isRestoring: boolean;\n /** Whether a sign-in is in progress */\n isSigningIn: boolean;\n /** Whether the current session has expired */\n isExpired: boolean;\n /** Milliseconds until session expires, or null */\n timeUntilExpiry: number | null;\n\n /** Sign in with optional overrides */\n signIn: (options?: UseSIWxLoginOptions) => Promise<SiwxSession>;\n /** Sign out: clears session from memory and storage */\n signOut: () => Promise<void>;\n /** Refresh the current session */\n refresh: () => Promise<SiwxSession>;\n\n /** Last error */\n error: Error | null;\n /** Clear the last error */\n clearError: () => void;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction siwxResultToSession(result: SiwxResult): SiwxSession {\n return {\n id: `siwx_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,\n chainId: result.message.chainId,\n address: result.message.address,\n domain: result.message.domain,\n message: result.message,\n signature: result.signature,\n issuedAt: result.message.issuedAt ?? new Date().toISOString(),\n expiresAt: result.message.expirationTime,\n refreshedAt: null,\n };\n}\n\n// ── Hook ─────────────────────────────────────────────────────────\n\nexport function useSIWxSession(\n options?: UseSIWxSessionOptions\n): UseSIWxSessionReturn {\n const {\n storagePrefix = \"naculus_\",\n autoRestore = true,\n defaultExpirySeconds = 86_400,\n } = options ?? {};\n\n const [session, setSession] = useState<SiwxSession | null>(null);\n const [isRestoring, setIsRestoring] = useState(autoRestore);\n const [isSigningIn, setIsSigningIn] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const { session: web3Session, chainId: currentChainId } = useWeb3();\n const login = useSIWxLogin();\n const storageRef = useRef(\n createLocalStorageSiwxSessionStorage(`${storagePrefix}siwx_session`)\n );\n\n const clearError = useCallback(() => setError(null), []);\n\n // ── Restore from storage on mount ──────────────────────────────\n\n useEffect(() => {\n if (!autoRestore) {\n setIsRestoring(false);\n return;\n }\n\n let cancelled = false;\n\n (async () => {\n try {\n const storage = storageRef.current;\n const saved = await storage.get();\n\n if (cancelled) return;\n\n if (saved) {\n logger.info(\"react/useSIWxSession\", \"Restored persisted SIWx session\");\n setSession(saved);\n setError(null);\n } else {\n // No valid session in storage\n setSession(null);\n }\n } catch (err) {\n logger.warn(\"react/useSIWxSession\", \"Failed to restore SIWx session:\", err);\n setSession(null);\n } finally {\n if (!cancelled) setIsRestoring(false);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [autoRestore]);\n\n // ── Expiry refresh timer ───────────────────────────────────────\n\n useEffect(() => {\n if (!session?.expiresAt) return;\n\n const timeUntilExpiry = new Date(session.expiresAt).getTime() - Date.now();\n if (timeUntilExpiry <= 0) {\n // Already expired — clear session\n setSession(null);\n return;\n }\n\n // Schedule clearing when expired\n const timer = setTimeout(() => {\n setSession((prev) => {\n if (prev && prev.id === session.id) {\n return null;\n }\n return prev;\n });\n }, timeUntilExpiry);\n\n return () => clearTimeout(timer);\n }, [session?.id, session?.expiresAt]);\n\n // ── Sign In ────────────────────────────────────────────────────\n\n const signIn = useCallback(\n async (signOptions?: UseSIWxLoginOptions): Promise<SiwxSession> => {\n setIsSigningIn(true);\n setError(null);\n\n try {\n // Merge default options with provided overrides\n const effectiveOptions: UseSIWxLoginOptions = {\n expirySeconds: defaultExpirySeconds,\n chainId: currentChainId ?? undefined,\n ...signOptions,\n };\n\n const result = await login.signIn(effectiveOptions);\n\n // Convert SiwxResult to SiwxSession\n const siwxSession = siwxResultToSession(result);\n\n // Persist to storage\n const storage = storageRef.current;\n await storage.set(siwxSession);\n\n setSession(siwxSession);\n setIsSigningIn(false);\n return siwxSession;\n } catch (err) {\n const wrapped = err instanceof Error ? err : new Error(\"SIWx sign-in failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n },\n [login, currentChainId, defaultExpirySeconds]\n );\n\n // ── Sign Out ───────────────────────────────────────────────────\n\n const signOut = useCallback(async () => {\n try {\n const storage = storageRef.current;\n await storage.remove();\n } catch (err) {\n logger.warn(\"react/useSIWxSession\", \"Failed to clear session:\", err);\n }\n setSession(null);\n setError(null);\n }, []);\n\n // ── Refresh ────────────────────────────────────────────────────\n\n const refresh = useCallback(async (): Promise<SiwxSession> => {\n if (!session) {\n throw new Error(\"No active session to refresh\");\n }\n\n setIsSigningIn(true);\n setError(null);\n\n try {\n // Re-sign with updated timestamps\n const result = await login.signIn({\n domain: session.domain,\n statement: session.message.statement ?? undefined,\n uri: session.message.uri,\n chainId: session.chainId,\n expirySeconds: defaultExpirySeconds,\n resources: session.message.resources.length > 0 ? session.message.resources : undefined,\n requestId: session.message.requestId ?? undefined,\n });\n\n const refreshedSession: SiwxSession = {\n ...siwxResultToSession(result),\n id: session.id, // preserve the original session ID\n refreshedAt: new Date().toISOString(),\n };\n\n // Persist\n const storage = storageRef.current;\n await storage.set(refreshedSession);\n\n setSession(refreshedSession);\n setIsSigningIn(false);\n return refreshedSession;\n } catch (err) {\n const wrapped = err instanceof Error ? err : new Error(\"Session refresh failed\");\n setError(wrapped);\n setIsSigningIn(false);\n throw wrapped;\n }\n }, [session, login, defaultExpirySeconds]);\n\n // ── Computed state ─────────────────────────────────────────────\n\n const isAuthenticated = session !== null && !checkSessionExpired(session);\n const expired = checkSessionExpired(session);\n const timeUntilExpiry = session?.expiresAt\n ? Math.max(0, new Date(session.expiresAt).getTime() - Date.now())\n : null;\n\n return {\n session: isAuthenticated ? session : null,\n isAuthenticated,\n isRestoring,\n isSigningIn,\n isExpired: expired,\n timeUntilExpiry,\n\n signIn,\n signOut,\n refresh,\n\n error,\n clearError,\n };\n}\n","\"use client\";\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { getClient } from \"../client\";\nimport { WalletError, SessionKeyManager, MemoryStorageAdapter } from \"@naculus/connect-core\";\nimport type {\n SessionKeyScope,\n SessionKeyInfo,\n SessionKeyManagerConfig,\n} from \"@naculus/connect-core\";\n\n// ─── Internal singleton for session key management ─────────────────────\n// In a full production setup, this would be injected via context or client config.\n\nlet globalSessionKeyManager: SessionKeyManager | null = null;\n\nfunction getSessionKeyManager(config?: SessionKeyManagerConfig): SessionKeyManager {\n if (!globalSessionKeyManager) {\n globalSessionKeyManager = new SessionKeyManager(\n config,\n // Use MemoryStorageAdapter for SSR safety; browser integration will use LocalStorageAdapter\n typeof window !== \"undefined\" ? undefined : new MemoryStorageAdapter(),\n );\n }\n return globalSessionKeyManager;\n}\n\n// ─── useSessionKeys ────────────────────────────────────────────────────\n\nexport interface UseSessionKeysReturn {\n /** All session keys (active, revoked, expired) */\n sessions: SessionKeyInfo[];\n /** Only active session keys */\n activeSessions: SessionKeyInfo[];\n /** Whether data is loading */\n loading: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Refresh the session list from storage */\n refresh: () => Promise<void>;\n /** Clear any error */\n clearError: () => void;\n /** Whether the storage backend is available */\n storageAvailable: boolean;\n}\n\n/**\n * Hook to list and manage session keys.\n *\n * @example\n * ```tsx\n * const { sessions, activeSessions, refresh } = useSessionKeys();\n * ```\n */\nexport function useSessionKeys(): UseSessionKeysReturn {\n const { session } = useWeb3();\n const [sessions, setSessions] = useState<SessionKeyInfo[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManager();\n const storageAvailable = manager.isStorageAvailable();\n\n const refresh = useCallback(async () => {\n if (!session) {\n setSessions([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const keys = await manager.listSessions();\n if (mountedRef.current) {\n setSessions(keys);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(\"Failed to load session keys\"));\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [session, manager]);\n\n // Load sessions on mount and on session change\n useEffect(() => {\n mountedRef.current = true;\n refresh();\n return () => {\n mountedRef.current = false;\n };\n }, [refresh]);\n\n const activeSessions = sessions.filter((s) => s.status === \"active\");\n\n return {\n sessions,\n activeSessions,\n loading,\n error,\n refresh,\n clearError,\n storageAvailable,\n };\n}\n\n// ─── useCreateSessionKey ───────────────────────────────────────────────\n\nexport interface UseCreateSessionKeyReturn {\n /** Create a new session key */\n createSessionKey: (\n scope?: Partial<SessionKeyScope>,\n signerAddress?: `0x${string}`,\n ) => Promise<SessionKeyInfo>;\n /** The last created session key info */\n lastCreated: SessionKeyInfo | null;\n /** Whether creation is in progress */\n isCreating: boolean;\n /** Error from last creation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to create new session keys.\n *\n * @example\n * ```tsx\n * const { createSessionKey, lastCreated, isCreating } = useCreateSessionKey();\n *\n * const handleCreate = async () => {\n * const session = await createSessionKey({\n * expiry: Math.floor(Date.now() / 1000) + 1800, // 30 min\n * maxTotalValue: parseEther(\"0.1\"),\n * });\n * };\n * ```\n */\nexport function useCreateSessionKey(): UseCreateSessionKeyReturn {\n const { session } = useWeb3();\n const [lastCreated, setLastCreated] = useState<SessionKeyInfo | null>(null);\n const [isCreating, setIsCreating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManager();\n\n const createSessionKey = useCallback(\n async (\n scope?: Partial<SessionKeyScope>,\n signerAddress?: `0x${string}`,\n ): Promise<SessionKeyInfo> => {\n if (!session) {\n throw new WalletError(\"wallet_unavailable\", \"No active wallet session\");\n }\n\n setIsCreating(true);\n setError(null);\n try {\n const resolvedSigner = signerAddress ?? undefined;\n const info = await manager.createSessionKey(scope, resolvedSigner);\n setLastCreated(info);\n return info;\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(\"Failed to create session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsCreating(false);\n }\n },\n [session, manager],\n );\n\n return {\n createSessionKey,\n lastCreated,\n isCreating,\n error,\n clearError,\n };\n}\n\n// ─── useRevokeSession ──────────────────────────────────────────────────\n\nexport interface UseRevokeSessionReturn {\n /** Revoke a session key by ID */\n revokeSession: (sessionId: string) => Promise<void>;\n /** Whether revoking is in progress */\n isRevoking: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to revoke a session key.\n *\n * @example\n * ```tsx\n * const { revokeSession, isRevoking } = useRevokeSession();\n * await revokeSession(sessionId);\n * ```\n */\nexport function useRevokeSession(): UseRevokeSessionReturn {\n const [isRevoking, setIsRevoking] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManager();\n\n const revokeSession = useCallback(\n async (sessionId: string): Promise<void> => {\n setIsRevoking(true);\n setError(null);\n try {\n await manager.revokeSession(sessionId);\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(\"Failed to revoke session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsRevoking(false);\n }\n },\n [manager],\n );\n\n return {\n revokeSession,\n isRevoking,\n error,\n clearError,\n };\n}\n\n// ─── useSendWithSession ────────────────────────────────────────────────\n\nexport interface UseSendWithSessionReturn {\n /** Sign a message hash using a session key */\n signWithSession: (sessionId: string, messageHash: `0x${string}`) => Promise<`0x${string}`>;\n /** Check if a transaction is within a session's scope */\n checkScope: (\n sessionId: string,\n tx: {\n to?: string;\n value?: string;\n data?: string;\n chainId?: number;\n gas?: string;\n },\n ) => Promise<{\n valid: boolean;\n reason?: string;\n remainingGas?: bigint;\n remainingValue?: bigint;\n remainingTxCount?: number;\n }>;\n /** Whether an operation is in progress */\n isBusy: boolean;\n /** Error from last operation */\n error: Error | null;\n /** Clear error */\n clearError: () => void;\n}\n\n/**\n * Hook to sign transactions using session keys and check scope.\n *\n * @example\n * ```tsx\n * const { signWithSession, checkScope } = useSendWithSession();\n *\n * const check = await checkScope(sessionId, tx);\n * if (check.valid) {\n * const sig = await signWithSession(sessionId, messageHash);\n * }\n * ```\n */\nexport function useSendWithSession(): UseSendWithSessionReturn {\n const [isBusy, setIsBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const clearError = useCallback(() => setError(null), []);\n\n const manager = getSessionKeyManager();\n\n const signWithSession = useCallback(\n async (sessionId: string, messageHash: `0x${string}`): Promise<`0x${string}`> => {\n setIsBusy(true);\n setError(null);\n try {\n return await manager.signWithSessionKey(sessionId, messageHash);\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(\"Failed to sign with session key\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsBusy(false);\n }\n },\n [manager],\n );\n\n const checkScope = useCallback(\n async (\n sessionId: string,\n tx: {\n to?: string;\n value?: string;\n data?: string;\n chainId?: number;\n gas?: string;\n },\n ) => {\n setIsBusy(true);\n setError(null);\n try {\n return await manager.checkSessionScope(sessionId, tx);\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error(\"Failed to check session scope\");\n setError(errorObj);\n throw errorObj;\n } finally {\n setIsBusy(false);\n }\n },\n [manager],\n );\n\n return {\n signWithSession,\n checkScope,\n isBusy,\n error,\n clearError,\n };\n}\n\n/**\n * Reset the global session key manager (useful for testing / cleanup).\n */\nexport function resetSessionKeyManager(): void {\n globalSessionKeyManager = null;\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\nimport { NameResolver } from \"@naculus/connect-core\";\nimport type { AddressResult, NameResolverConfig } from \"@naculus/connect-core\";\n\n/**\n * Options for the useResolveName hook.\n */\nexport interface UseResolveNameOptions {\n /** Whether to skip resolution (e.g. if input is invalid). Default: false. */\n skip?: boolean;\n /** Custom resolver configuration (overrides default RPC URLs). */\n resolverConfig?: NameResolverConfig;\n}\n\n/**\n * Result of a name resolution query.\n */\nexport interface UseResolveNameResult {\n /** Resolved address, or null if not found / not started. */\n data: AddressResult | null;\n /** Whether the resolution is in progress. */\n isLoading: boolean;\n /** Error that occurred during resolution, if any. */\n error: Error | null;\n /** Manually trigger re-resolution of the current name. */\n refetch: () => void;\n}\n\n// Lazy singleton resolver to avoid creating one per component instance.\nlet sharedResolver: NameResolver | null = null;\n\nfunction getResolver(config?: NameResolverConfig): NameResolver {\n if (config) {\n return new NameResolver(config);\n }\n if (!sharedResolver) {\n sharedResolver = new NameResolver();\n }\n return sharedResolver;\n}\n\n/**\n * React hook to resolve a human-readable name to a blockchain address.\n *\n * Supports ENS (.eth) and SNS (.sol) names.\n * Automatically detects the name service from the suffix.\n *\n * @example\n * ```tsx\n * function AddressInput() {\n * const { data, isLoading, error } = useResolveName('vitalik.eth');\n * return <div>{data?.address ?? 'Enter a name'}</div>;\n * }\n * ```\n */\nexport function useResolveName(\n name: string,\n options?: UseResolveNameOptions,\n): UseResolveNameResult {\n const [data, setData] = useState<AddressResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const skip = options?.skip ?? false;\n const resolverRef = useRef<NameResolver | null>(null);\n const activeNameRef = useRef<string>(\"\");\n const mountedRef = useRef(true);\n\n // Keep mounted ref current\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const resolver = resolverRef.current ?? getResolver(options?.resolverConfig);\n resolverRef.current = resolver;\n\n const resolve = useCallback(() => {\n const cleanName = name.trim();\n\n if (!cleanName || skip) {\n setData(null);\n setIsLoading(false);\n setError(null);\n return;\n }\n\n // Avoid re-resolving the same name\n if (activeNameRef.current === cleanName && data) {\n return;\n }\n\n activeNameRef.current = cleanName;\n setIsLoading(true);\n setError(null);\n\n resolver\n .resolveName(cleanName)\n .then((result) => {\n if (mountedRef.current) {\n setData(result);\n setIsLoading(false);\n }\n })\n .catch((err: unknown) => {\n if (mountedRef.current) {\n const resolutionError =\n err instanceof Error ? err : new Error(String(err));\n setError(resolutionError);\n setData(null);\n setIsLoading(false);\n }\n });\n }, [name, skip]);\n\n // Resolve when name changes\n useEffect(() => {\n resolve();\n }, [resolve]);\n\n const refetch = useCallback(() => {\n activeNameRef.current = \"\";\n resolve();\n }, [resolve]);\n\n return { data, isLoading, error, refetch };\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\nimport { NameResolver } from \"@naculus/connect-core\";\nimport type { NameResult, NameResolverConfig } from \"@naculus/connect-core\";\n\n/**\n * Options for the useLookupAddress hook.\n */\nexport interface UseLookupAddressOptions {\n /** Optional CAIP-2 chain ID to hint which provider to use. */\n chainId?: string;\n /** Whether to skip lookup. Default: false. */\n skip?: boolean;\n /** Custom resolver configuration (overrides default RPC URLs). */\n resolverConfig?: NameResolverConfig;\n}\n\n/**\n * Result of an address reverse-lookup query.\n */\nexport interface UseLookupAddressResult {\n /** Resolved name, or null if not found / not started. */\n data: NameResult | null;\n /** Whether the lookup is in progress. */\n isLoading: boolean;\n /** Error that occurred during lookup, if any. */\n error: Error | null;\n /** Manually trigger re-lookup of the current address. */\n refetch: () => void;\n}\n\n// Lazy singleton resolver to avoid creating one per component instance.\nlet sharedResolver: NameResolver | null = null;\n\nfunction getResolver(config?: NameResolverConfig): NameResolver {\n if (config) {\n return new NameResolver(config);\n }\n if (!sharedResolver) {\n sharedResolver = new NameResolver();\n }\n return sharedResolver;\n}\n\n/**\n * React hook to reverse-lookup a blockchain address to find its human-readable name.\n *\n * Supports ENS (.eth) and SNS (.sol) names.\n * Auto-detects the name service from the address format or chainId hint.\n *\n * @example\n * ```tsx\n * function TransactionRow({ address }: { address: string }) {\n * const { data, isLoading } = useLookupAddress(address);\n * return <span>{data?.name ?? address}</span>;\n * }\n * ```\n */\nexport function useLookupAddress(\n address: string,\n options?: UseLookupAddressOptions,\n): UseLookupAddressResult {\n const [data, setData] = useState<NameResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const chainId = options?.chainId;\n const skip = options?.skip ?? false;\n const resolverRef = useRef<NameResolver | null>(null);\n const activeAddrRef = useRef<string>(\"\");\n const mountedRef = useRef(true);\n\n // Keep mounted ref current\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const resolver = resolverRef.current ?? getResolver(options?.resolverConfig);\n resolverRef.current = resolver;\n\n const lookup = useCallback(() => {\n const cleanAddr = address.trim();\n\n if (!cleanAddr || skip) {\n setData(null);\n setIsLoading(false);\n setError(null);\n return;\n }\n\n // Avoid re-looking-up the same address\n if (activeAddrRef.current === cleanAddr && data) {\n return;\n }\n\n activeAddrRef.current = cleanAddr;\n setIsLoading(true);\n setError(null);\n\n resolver\n .lookupAddress(cleanAddr, chainId)\n .then((result) => {\n if (mountedRef.current) {\n setData(result);\n setIsLoading(false);\n }\n })\n .catch((err: unknown) => {\n if (mountedRef.current) {\n const resolutionError =\n err instanceof Error ? err : new Error(String(err));\n setError(resolutionError);\n setData(null);\n setIsLoading(false);\n }\n });\n }, [address, chainId, skip]);\n\n // Lookup when address or chainId changes\n useEffect(() => {\n lookup();\n }, [lookup]);\n\n const refetch = useCallback(() => {\n activeAddrRef.current = \"\";\n lookup();\n }, [lookup]);\n\n return { data, isLoading, error, refetch };\n}\n","/**\n * useSession Hook\n *\n * Provides access to the complete session state from SessionManager,\n * including all active chain sessions, the active chain ID, and\n * connection status.\n *\n * @see SRS-009 §7.2\n */\n\nimport { useSyncExternalStore, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport type { ChainSession, ActiveSessionBundle } from \"@naculus/connect-core\";\n\nexport interface UseSessionReturn {\n /** The raw wallet session (from the active bundle) */\n session: ActiveSessionBundle[\"walletSession\"] | null;\n /** All chain sessions within the active bundle */\n chainSessions: ChainSession[];\n /** The currently active chain ID */\n activeChainId: string | null;\n /** Whether a wallet is connected */\n isConnected: boolean;\n /** The connector/wallet type (e.g., \"eip6963\", \"walletconnect\") */\n connectorId: string | null;\n}\n\nfunction subscribeToSessionManager(\n sm: import(\"@naculus/connect-core\").SessionManager | null,\n callback: () => void,\n): () => void {\n if (!sm) return () => {};\n\n const handler = () => callback();\n sm.on(\"sessionConnected\", handler);\n sm.on(\"sessionDisconnected\", handler);\n sm.on(\"chainChanged\", handler);\n\n return () => {\n sm.off(\"sessionConnected\", handler);\n sm.off(\"sessionDisconnected\", handler);\n sm.off(\"chainChanged\", handler);\n };\n}\n\nfunction getSessionSnapshot(\n sm: import(\"@naculus/connect-core\").SessionManager | null,\n): UseSessionReturn {\n if (!sm) {\n return {\n session: null,\n chainSessions: [],\n activeChainId: null,\n isConnected: false,\n connectorId: null,\n };\n }\n\n const bundle = sm.getActiveBundle();\n if (!bundle) {\n return {\n session: null,\n chainSessions: [],\n activeChainId: null,\n isConnected: false,\n connectorId: null,\n };\n }\n\n return {\n session: bundle.walletSession,\n chainSessions: Array.from(bundle.chainSessions.values()),\n activeChainId: bundle.activeChainId,\n isConnected: true,\n connectorId: bundle.walletSession.walletType,\n };\n}\n\nexport function useSession(\n sessionManager?: import(\"@naculus/connect-core\").SessionManager | null,\n): UseSessionReturn {\n const web3 = useWeb3();\n const sm = sessionManager ?? web3.sessionManager ?? null;\n\n const subscribe = useCallback(\n (callback: () => void) => subscribeToSessionManager(sm, callback),\n [sm],\n );\n\n const getSnapshot = useCallback(\n () => getSessionSnapshot(sm),\n [sm],\n );\n\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","/**\n * useSwitchChain Hook\n *\n * Provides the switchChain method with loading/error state tracking.\n *\n * @see SRS-009 §7.2\n */\n\nimport { useState, useCallback } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { WalletError } from \"@naculus/connect-core\";\n\nexport interface UseSwitchChainReturn {\n /** Switch the active chain for the current session */\n switchChain: (chainId: string) => Promise<void>;\n /** Whether a chain switch is in progress */\n isSwitching: boolean;\n /** The currently active chain ID */\n currentChainId: string | null;\n /** The last error that occurred during chain switch (if any) */\n error: Error | null;\n /** Clear the error state */\n clearError: () => void;\n}\n\nexport function useSwitchChain(): UseSwitchChainReturn {\n const { switchChain: providerSwitchChain, chainId } = useWeb3();\n const [isSwitching, setIsSwitching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleSwitchChain = useCallback(\n async (targetChainId: string) => {\n setIsSwitching(true);\n setError(null);\n\n try {\n await providerSwitchChain(targetChainId);\n } catch (err) {\n const walletError =\n err instanceof WalletError\n ? err\n : new WalletError(\n \"chain_unsupported\",\n err instanceof Error\n ? err.message\n : \"Unknown error during chain switch\",\n );\n setError(walletError);\n throw walletError;\n } finally {\n setIsSwitching(false);\n }\n },\n [providerSwitchChain],\n );\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n return {\n switchChain: handleSwitchChain,\n isSwitching,\n currentChainId: chainId,\n error,\n clearError,\n };\n}\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport {\n getUserFriendlyError,\n isRetryableError,\n} from \"../utils/errorMessages\";\n\nexport interface UserFriendlyError {\n title: string;\n description: string;\n code?: string;\n}\n\nexport interface UseWeb3ErrorHandlerReturn {\n /** Current error from the provider */\n error: Error | null;\n /** User-friendly representation of the current error */\n friendlyError: UserFriendlyError | null;\n /** Clear the current error */\n clearError: () => void;\n /** Check if current error is retryable */\n isRetryable: boolean;\n /** Get a user-friendly version of any error */\n formatError: (error: unknown) => UserFriendlyError;\n /** Wraps an async function with error formatting */\n wrapAsync: <T>(fn: () => Promise<T>) => () => Promise<T>;\n}\n\n/**\n * Hook that provides user-friendly error handling for web3 operations.\n *\n * Features:\n * - Maps WalletError codes to human-readable messages\n * - Provides retry detection for transient errors\n * - Wraps async operations with consistent error formatting\n * - Exposes the current error state from Web3ConnectProvider\n *\n * @example\n * ```tsx\n * const { friendlyError, clearError, isRetryable, wrapAsync } = useWeb3ErrorHandler();\n *\n * // Show error in UI\n * if (friendlyError) {\n * return <ErrorDisplay title={friendlyError.title} message={friendlyError.description} />;\n * }\n *\n * // Wrap an operation\n * const safeConnect = wrapAsync(() => connect());\n * await safeConnect();\n * ```\n */\nexport function useWeb3ErrorHandler(): UseWeb3ErrorHandlerReturn {\n const { error, clearError: providerClearError } = useWeb3();\n\n const friendlyError: UserFriendlyError | null = useMemo(\n () => (error ? getUserFriendlyError(error) : null),\n [error]\n );\n\n const isRetryable = useMemo(\n () => (error ? isRetryableError(error) : false),\n [error]\n );\n\n const clearError = useCallback(() => {\n providerClearError();\n }, [providerClearError]);\n\n const formatError = useCallback(\n (err: unknown): UserFriendlyError => getUserFriendlyError(err),\n []\n );\n\n const wrapAsync = useCallback(\n <T,>(fn: () => Promise<T>): (() => Promise<T>) => {\n return async () => {\n try {\n return await fn();\n } catch (err) {\n // Re-throw with user-friendly information attached\n const friendly = getUserFriendlyError(err);\n const enhanced = new Error(friendly.description) as unknown as Record<string, unknown>;\n enhanced.title = friendly.title;\n enhanced.code = friendly.code;\n throw enhanced;\n }\n };\n },\n []\n );\n\n return {\n error,\n friendlyError,\n clearError,\n isRetryable,\n formatError,\n wrapAsync,\n };\n}\n","/**\n * User-friendly error messages for WalletError codes and common errors.\n * Maps internal error codes to human-readable messages that can be shown in toasts/UI.\n */\n\nimport type { WalletErrorCode } from \"@naculus/connect-core\";\n\n/**\n * User-friendly title for each WalletError code.\n */\nexport const WALLET_ERROR_TITLES: Record<string, string> = {\n wallet_unavailable: \"Wallet Not Detected\",\n user_rejected: \"Connection Rejected\",\n deeplink_timeout: \"Wallet Connection Timed Out\",\n session_expired: \"Session Expired\",\n intent_expired: \"Connection Request Expired\",\n namespace_mismatch: \"Network Mismatch\",\n chain_unsupported: \"Unsupported Network\",\n method_not_allowed: \"Action Not Allowed\",\n signature_rejected: \"Signature Rejected\",\n tx_failed: \"Transaction Failed\",\n};\n\n/**\n * User-friendly description for each WalletError code.\n */\nexport const WALLET_ERROR_DESCRIPTIONS: Record<string, string> = {\n wallet_unavailable:\n \"No wallet found. Please install a compatible wallet (e.g., MetaMask, WalletConnect) and try again.\",\n user_rejected: \"The connection request was declined in your wallet. You can try again whenever you're ready.\",\n deeplink_timeout:\n \"The wallet didn't respond in time. This can happen if the wallet app isn't installed or takes too long to open.\",\n session_expired:\n \"Your wallet session has expired. Please reconnect to continue.\",\n intent_expired:\n \"The connection request expired. Please try connecting again.\",\n namespace_mismatch:\n \"This wallet doesn't support the required network. Try using a different wallet or network.\",\n chain_unsupported:\n \"This network isn't supported. Please switch to a supported network in your wallet.\",\n method_not_allowed:\n \"This action isn't supported by your current wallet or network.\",\n signature_rejected: \"The signature request was declined in your wallet.\",\n tx_failed:\n \"The transaction couldn't be completed. This could be due to insufficient funds, network congestion, or a contract error.\",\n};\n\n/**\n * Default title for unknown errors.\n */\nexport const UNKNOWN_ERROR_TITLE = \"Something went wrong\";\n\n/**\n * Default description for unknown errors.\n */\nexport const UNKNOWN_ERROR_DESCRIPTION =\n \"An unexpected error occurred. Please try again. If the problem persists, check your connection and wallet configuration.\";\n\n/**\n * Get a user-friendly error message object from any error.\n */\nexport function getUserFriendlyError(\n error: unknown\n): { title: string; description: string; code?: string } {\n if (!error) {\n return { title: UNKNOWN_ERROR_TITLE, description: UNKNOWN_ERROR_DESCRIPTION };\n }\n\n // Check for WalletError with code\n const maybeWalletError = error as { name?: string; code?: string; message?: string };\n if (maybeWalletError.name === \"WalletError\" && maybeWalletError.code) {\n const code = maybeWalletError.code;\n const title = WALLET_ERROR_TITLES[code] ?? UNKNOWN_ERROR_TITLE;\n const description =\n WALLET_ERROR_DESCRIPTIONS[code] ?? maybeWalletError.message ?? UNKNOWN_ERROR_DESCRIPTION;\n return { title, description, code };\n }\n\n // Check for standard Error\n if (error instanceof Error) {\n const message = error.message;\n // Map common error patterns\n if (/user rejected/i.test(message) || /rejected/.test(message)) {\n return {\n title: \"Request Rejected\",\n description: \"The request was declined.\",\n code: \"user_rejected\",\n };\n }\n if (/timeout/i.test(message) || /timed? ?out/i.test(message)) {\n return {\n title: \"Request Timed Out\",\n description: \"The request took too long. Please try again.\",\n code: \"deeplink_timeout\",\n };\n }\n if (/network/i.test(message) || /chain/i.test(message)) {\n return {\n title: \"Network Error\",\n description: message,\n code: \"chain_unsupported\",\n };\n }\n if (/insufficient funds/i.test(message)) {\n return {\n title: \"Insufficient Funds\",\n description: \"You don't have enough funds to complete this transaction.\",\n code: \"tx_failed\",\n };\n }\n\n return {\n title: UNKNOWN_ERROR_TITLE,\n description: message || UNKNOWN_ERROR_DESCRIPTION,\n };\n }\n\n // String error\n if (typeof error === \"string\") {\n return {\n title: UNKNOWN_ERROR_TITLE,\n description: error || UNKNOWN_ERROR_DESCRIPTION,\n };\n }\n\n return { title: UNKNOWN_ERROR_TITLE, description: UNKNOWN_ERROR_DESCRIPTION };\n}\n\n/**\n * Check if an error is retryable (transient).\n */\nexport function isRetryableError(error: unknown): boolean {\n const maybe = error as { name?: string; code?: string; message?: string };\n if (maybe.name !== \"WalletError\" || !maybe.code) return false;\n const retryableCodes: WalletErrorCode[] = [\n \"deeplink_timeout\",\n \"session_expired\",\n \"intent_expired\",\n \"tx_failed\",\n ];\n return retryableCodes.includes(maybe.code as WalletErrorCode);\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\n\n// ── Types (standalone, to avoid dependency on wallet-engine) ──────\n\nexport type TxStatus =\n | \"pending\"\n | \"mined\"\n | \"confirmed\"\n | \"failed\"\n | \"unknown\";\n\nexport interface TxStatusEntry {\n hash: string;\n chainId: number;\n from: string;\n to: string;\n value: string;\n data?: string;\n nonce?: number;\n status: TxStatus;\n blockNumber?: number;\n blockHash?: string;\n gasUsed?: string;\n effectiveGasPrice?: string;\n createdAt: number;\n confirmedAt?: number;\n updatedAt: number;\n error?: string;\n label?: string;\n memo?: string;\n replacementCount?: number;\n}\n\n/** Minimal TxMonitor interface for React hooks */\nexport interface TxMonitorLike {\n watchTx(hash: string, chainId: number, options?: {\n requiredConfirmations?: number;\n pollInterval?: number;\n label?: string;\n memo?: string;\n initialEntry?: Partial<TxStatusEntry>;\n }): Promise<TxStatusEntry>;\n\n stopWatching(hash: string, chainId?: number): void;\n getTxStatus(hash: string, chainId?: number): TxStatusEntry | null;\n getTxHistory(address?: string, chainId?: number): Promise<TxStatusEntry[]>;\n refreshTx(hash: string, chainId?: number): Promise<void>;\n\n on(event: \"statusChange\", listener: (entry: TxStatusEntry) => void): this;\n on(event: \"confirmed\", listener: (entry: TxStatusEntry) => void): this;\n on(event: \"failed\", listener: (entry: TxStatusEntry) => void): this;\n off(event: string, listener: Function): this;\n}\n\n// ── Context for providing TxMonitor ───────────────────────────────\n\nimport { createContext, useContext } from \"react\";\n\nexport const TxMonitorContext = createContext<TxMonitorLike | null>(null);\n\nexport function useTxMonitorProvider(): TxMonitorLike | null {\n return useContext(TxMonitorContext);\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseTxMonitorResult {\n entry: TxStatusEntry | null;\n status: TxStatus | \"idle\";\n isLoading: boolean;\n isWatching: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n stopWatching: () => void;\n}\n\n/**\n * Monitor a single transaction's lifecycle.\n * When hash changes, automatically stops old watch and starts new one.\n */\nexport function useTxMonitor(\n hash?: string,\n chainId?: number,\n monitor?: TxMonitorLike,\n): UseTxMonitorResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [entry, setEntry] = useState<TxStatusEntry | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isWatching, setIsWatching] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const prevHashRef = useRef<string | undefined>(undefined);\n\n const refresh = useCallback(async () => {\n if (!effectiveMonitor || !hash) return;\n setIsLoading(true);\n setError(null);\n try {\n await effectiveMonitor.refreshTx(hash, chainId);\n const current = effectiveMonitor.getTxStatus(hash, chainId);\n if (current) setEntry(current);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [effectiveMonitor, hash, chainId]);\n\n const stopWatching = useCallback(() => {\n if (!effectiveMonitor || !hash) return;\n effectiveMonitor.stopWatching(hash, chainId);\n setIsWatching(false);\n }, [effectiveMonitor, hash, chainId]);\n\n useEffect(() => {\n if (!effectiveMonitor || !hash || !chainId) {\n setEntry(null);\n setIsWatching(false);\n return;\n }\n\n // Stop previous watch if hash changed\n if (prevHashRef.current && prevHashRef.current !== hash) {\n effectiveMonitor.stopWatching(prevHashRef.current);\n }\n prevHashRef.current = hash;\n\n let cancelled = false;\n setIsWatching(true);\n setIsLoading(true);\n setError(null);\n\n // Check if we already have status\n const current = effectiveMonitor.getTxStatus(hash, chainId);\n if (current) {\n setEntry(current);\n setIsLoading(false);\n }\n\n // Start watching\n effectiveMonitor.watchTx(hash, chainId, {}).then((initial) => {\n if (!cancelled) {\n setEntry(initial);\n setIsLoading(false);\n }\n }).catch((err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n }\n });\n\n // Listen for status changes\n const onStatusChange = (updated: TxStatusEntry) => {\n if (!cancelled) setEntry({ ...updated });\n };\n effectiveMonitor.on(\"statusChange\", onStatusChange);\n\n return () => {\n cancelled = true;\n setIsWatching(false);\n effectiveMonitor.off(\"statusChange\", onStatusChange);\n };\n }, [effectiveMonitor, hash, chainId]);\n\n const status: TxStatus | \"idle\" = entry?.status ?? \"idle\";\n\n return {\n entry,\n status,\n isLoading,\n isWatching,\n error,\n refresh,\n stopWatching,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\nimport type { TxMonitorLike, TxStatusEntry, TxStatus } from \"./useTxMonitor\";\nimport { useTxMonitorProvider } from \"./useTxMonitor\";\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseTxHistoryResult {\n entries: TxStatusEntry[];\n isLoading: boolean;\n error: Error | null;\n refresh: () => Promise<void>;\n summary: {\n pending: number;\n confirmed: number;\n failed: number;\n };\n}\n\n/**\n * Query transaction history.\n * address defaults to current wallet address; chainId defaults to current chain.\n */\nexport function useTxHistory(\n address?: string,\n chainId?: number,\n monitor?: TxMonitorLike,\n): UseTxHistoryResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [entries, setEntries] = useState<TxStatusEntry[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const refreshCounter = useRef(0);\n\n const refresh = useCallback(async () => {\n if (!effectiveMonitor) return;\n setIsLoading(true);\n setError(null);\n refreshCounter.current++;\n try {\n const results = await effectiveMonitor.getTxHistory(address, chainId);\n setEntries(results);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [effectiveMonitor, address, chainId]);\n\n useEffect(() => {\n refresh().catch(() => {});\n }, [refresh]);\n\n // Listen for status changes to update entries reactively\n useEffect(() => {\n if (!effectiveMonitor) return;\n\n const onStatusChange = () => {\n // Re-fetch on any status change\n refresh().catch(() => {});\n };\n effectiveMonitor.on(\"statusChange\", onStatusChange);\n\n return () => {\n effectiveMonitor.off(\"statusChange\", onStatusChange as any);\n };\n }, [effectiveMonitor, refresh]);\n\n const summary = {\n pending: entries.filter(e => e.status === \"pending\").length,\n confirmed: entries.filter(e => e.status === \"confirmed\").length,\n failed: entries.filter(e => e.status === \"failed\").length,\n };\n\n return {\n entries,\n isLoading,\n error,\n refresh,\n summary,\n };\n}\n","/**\n * useTransactionSimulation — React hook for simulating transactions\n * before signing/submitting.\n *\n * Provides a reactive SimulationResult that updates when tx parameters change.\n * Uses the simulation module from @naculus/connect-core.\n *\n * @see /docs/features/transaction-simulation.md\n */\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { useWeb3 } from \"../provider/Web3ConnectProvider\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport { useViemClient } from \"./useViemClient\";\n\nimport type { EvmTransaction } from \"../types\";\n\n// ── Types (mirrored from @naculus/connect-core simulation module) ──\n\nexport type SimulationStatus = \"success\" | \"reverted\" | \"unavailable\";\n\nexport type RiskLevel = \"safe\" | \"warning\" | \"malicious\" | \"unknown\";\n\nexport interface SimulationResult {\n status: SimulationStatus;\n revertReason?: string;\n balanceChanges: BalanceChange[];\n approvalChanges: ApprovalChange[];\n riskAssessment: RiskAssessment;\n gasInfo?: GasInfo;\n provider: string;\n summary?: string;\n changesDetected: boolean;\n}\n\nexport interface BalanceChange {\n tokenAddress: string;\n tokenSymbol: string;\n tokenDecimals: number;\n amount: string;\n direction: \"in\" | \"out\";\n from: string;\n to: string;\n humanReadable: string;\n}\n\nexport interface ApprovalChange {\n tokenAddress: string;\n tokenSymbol: string;\n owner: string;\n spender: string;\n amount: string;\n isUnlimited: boolean;\n humanReadable: string;\n}\n\nexport interface RiskAssessment {\n level: RiskLevel;\n score: number;\n warnings: RiskWarning[];\n}\n\nexport interface RiskWarning {\n category: string;\n severity: string;\n message: string;\n}\n\nexport interface GasInfo {\n gasLimit: bigint;\n gasPrice?: bigint;\n estimatedFeeEth?: string;\n estimatedFeeUsd?: string;\n}\n\n// ── Hook return type ──────────────────────────────────────────────\n\nexport interface UseTransactionSimulationReturn {\n /** Current simulation result (undefined until first run) */\n result: SimulationResult | undefined;\n /** Whether a simulation is in progress */\n isSimulating: boolean;\n /** Error from the last simulation attempt */\n error: Error | null;\n /** Manually trigger a simulation */\n simulate: () => Promise<SimulationResult>;\n /** Reset the simulation state */\n reset: () => void;\n}\n\n// ── Default owner address for eth_call ────────────────────────────\n\nfunction getNativeSymbol(chainId: number): string {\n const ethChains = [1, 5, 11155111, 10, 42161, 421614, 8453, 84532];\n const maticChains = [137, 80002];\n const bnbChains = [56, 97];\n\n if (ethChains.includes(chainId)) return \"ETH\";\n if (maticChains.includes(chainId)) return \"MATIC\";\n if (bnbChains.includes(chainId)) return \"BNB\";\n return \"ETH\";\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useTransactionSimulation(\n tx: EvmTransaction | undefined,\n chainId?: number,\n): UseTransactionSimulationReturn {\n const { session } = useWeb3();\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n const { publicClient } = useViemClient();\n\n const [result, setResult] = useState<SimulationResult | undefined>(undefined);\n const [isSimulating, setIsSimulating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Debounce ref to avoid rapid re-simulations\n const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n // ── Core simulation logic ───────────────────────────────────────\n\n const simulate = useCallback(async (): Promise<SimulationResult> => {\n if (!tx) {\n const noTxResult: SimulationResult = {\n status: \"unavailable\" as SimulationStatus,\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: { level: \"unknown\" as RiskLevel, score: 0, warnings: [] },\n provider: \"eth_call\",\n summary: \"No transaction to simulate\",\n changesDetected: false,\n };\n setResult(noTxResult);\n return noTxResult;\n }\n\n setIsSimulating(true);\n setError(null);\n\n try {\n // Determine the target chain ID\n const targetChainId = chainId ?? currentChain?.id ?? 1;\n\n // Determine RPC URL from the current chain context\n const rpcUrl = currentChain?.rpcUrl;\n\n // If we have a viem publicClient, use it for eth_call simulation\n if (publicClient) {\n try {\n const from = evmAccount?.includes(\":\")\n ? (evmAccount.split(\":\").pop() as `0x${string}`)\n : evmAccount;\n\n const callParams: any = {\n to: tx.to as `0x${string}`,\n data: (tx.data ?? \"0x\") as `0x${string}`,\n value: tx.value ? BigInt(tx.value) : 0n,\n };\n\n if (from) {\n callParams.from = from as `0x${string}`;\n }\n\n await publicClient.call(callParams);\n\n // eth_call succeeded — transaction won't revert\n const simResult: SimulationResult = {\n status: \"success\",\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: { level: \"unknown\", score: 0, warnings: [] },\n gasInfo: tx.gas\n ? { gasLimit: BigInt(tx.gas), estimatedFeeEth: \"0\" }\n : undefined,\n provider: \"eth_call\",\n summary: \"Transaction simulation succeeded (basic revert check only)\",\n changesDetected: true,\n };\n setResult(simResult);\n return simResult;\n } catch (callErr: any) {\n // eth_call reverted — extract reason\n let revertReason: string | undefined;\n const errMsg = callErr?.message ?? String(callErr);\n const errData = callErr?.data ?? callErr?.cause?.data;\n\n // Try to extract human-readable revert reason\n if (errData && typeof errData === \"string\") {\n const clean = errData.startsWith(\"0x\") ? errData.slice(2) : errData;\n if (clean.startsWith(\"08c379a0\") && clean.length > 138) {\n // Error(string) — ABI decode\n const length = parseInt(clean.slice(72, 136), 16);\n if (length > 0) {\n const msgHex = clean.slice(136, 136 + length * 2);\n const bytes = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n bytes[i] = parseInt(msgHex.slice(i * 2, i * 2 + 2), 16);\n }\n revertReason = new TextDecoder().decode(bytes);\n }\n } else if (clean.startsWith(\"4e487b71\")) {\n revertReason = `Panic: Built-in failure`;\n }\n }\n\n if (!revertReason) {\n revertReason = errMsg.includes(\"revert\")\n ? errMsg\n : \"Transaction reverted\";\n }\n\n const simResult: SimulationResult = {\n status: \"reverted\",\n revertReason,\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: {\n level: \"unknown\",\n score: 0,\n warnings: [\n {\n category: \"simulation_failed\",\n severity: \"high\",\n message: revertReason\n ? `Transaction would revert: ${revertReason}`\n : \"Transaction would revert\",\n },\n ],\n },\n provider: \"eth_call\",\n summary: revertReason\n ? `Transaction reverted: ${revertReason}`\n : \"Transaction reverted\",\n changesDetected: false,\n };\n setResult(simResult);\n return simResult;\n }\n }\n\n // Fallback: raw fetch eth_call\n if (rpcUrl) {\n try {\n const response = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: Date.now(),\n method: \"eth_call\",\n params: [\n {\n to: tx.to,\n from: evmAccount?.includes(\":\")\n ? evmAccount.split(\":\").pop()\n : evmAccount,\n data: tx.data ?? \"0x\",\n value: tx.value ?? \"0x0\",\n },\n \"latest\",\n ],\n }),\n });\n\n const json: any = await response.json();\n\n if (json.error) {\n const simResult: SimulationResult = {\n status: \"reverted\",\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: {\n level: \"unknown\",\n score: 0,\n warnings: [\n {\n category: \"simulation_failed\",\n severity: \"high\",\n message: `Transaction would revert: ${json.error.message}`,\n },\n ],\n },\n provider: \"eth_call\",\n summary: \"Transaction reverted\",\n changesDetected: false,\n };\n setResult(simResult);\n return simResult;\n }\n\n const simResult: SimulationResult = {\n status: \"success\",\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: { level: \"unknown\", score: 0, warnings: [] },\n provider: \"eth_call\",\n summary: \"Transaction simulation succeeded\",\n changesDetected: true,\n };\n setResult(simResult);\n return simResult;\n } catch (fetchErr: any) {\n // Network error\n const simResult: SimulationResult = {\n status: \"unavailable\",\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: {\n level: \"unknown\",\n score: 0,\n warnings: [\n {\n category: \"simulation_failed\",\n severity: \"medium\",\n message: `Network error: ${fetchErr?.message ?? \"Unknown\"}`,\n },\n ],\n },\n provider: \"eth_call\",\n summary: \"Simulation unavailable due to network error\",\n changesDetected: false,\n };\n setResult(simResult);\n return simResult;\n }\n }\n\n // No RPC URL available\n const simResult: SimulationResult = {\n status: \"unavailable\",\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: {\n level: \"unknown\",\n score: 0,\n warnings: [\n {\n category: \"simulation_failed\",\n severity: \"low\",\n message: \"No RPC URL or public client available for simulation\",\n },\n ],\n },\n provider: \"eth_call\",\n summary: \"Simulation unavailable: no RPC URL\",\n changesDetected: false,\n };\n setResult(simResult);\n return simResult;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Simulation failed\");\n setError(error);\n throw error;\n } finally {\n setIsSimulating(false);\n }\n }, [tx, chainId, currentChain, publicClient, evmAccount]);\n\n // ── Auto-simulate on tx change (debounced) ──────────────────────\n\n useEffect(() => {\n if (!tx) return;\n\n // Clear previous debounce\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n // Debounce: wait 300ms after last tx change before simulating\n debounceRef.current = setTimeout(() => {\n simulate().catch(() => {\n // Silently handle; errors are captured in state\n });\n }, 300);\n\n return () => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n };\n }, [tx, simulate]);\n\n // ── Reset ───────────────────────────────────────────────────────\n\n const reset = useCallback(() => {\n setResult(undefined);\n setError(null);\n setIsSimulating(false);\n }, []);\n\n return {\n result,\n isSimulating,\n error,\n simulate,\n reset,\n };\n}\n","/**\n * useERC20TransferSimulation — React hook for simulating ERC-20 token\n * transfers before signing/submitting.\n *\n * Wraps useTransactionSimulation with ERC-20 transfer calldata building,\n * so callers only need the token, recipient, and amount.\n *\n * @see /docs/features/transaction-simulation.md\n */\n\nimport { useMemo } from \"react\";\nimport {\n useTransactionSimulation,\n type UseTransactionSimulationReturn,\n type SimulationResult,\n} from \"./useTransactionSimulation\";\nimport { useAccount } from \"./useAccount\";\nimport { useChain } from \"./useChain\";\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport type { EvmTransaction } from \"../types\";\n\n// ── Constants ─────────────────────────────────────────────────────\n\n/**\n * ERC-20 transfer function selector (first 4 bytes of keccak256(\"transfer(address,uint256)\"))\n * We use this to build minimal calldata without importing viem for this hook.\n */\nconst ERC20_TRANSFER_SELECTOR = \"0xa9059cbb\";\n\n// ── Helper: Pad address to 32 bytes (left-padded zeros) ──────────\n\nfunction padAddress(addr: string): string {\n const clean = addr.startsWith(\"0x\") ? addr.slice(2) : addr;\n return clean.padStart(64, \"0\");\n}\n\n/**\n * Pad a hex value (bigint as hex) to 32 bytes (left-padded zeros).\n */\nfunction padHex(value: string, bytes: number = 32): string {\n const clean = value.startsWith(\"0x\") ? value.slice(2) : value;\n return clean.padStart(bytes * 2, \"0\");\n}\n\n/**\n * Convert a decimal-amount string to raw amount in smallest unit.\n * E.g. \"1.50\" with 6 decimals → \"1500000\" as decimal string.\n */\nfunction parseUnits(amount: string, decimals: number): bigint {\n // Split on decimal point\n const [whole = \"0\", fraction = \"\"] = amount.split(\".\");\n const padded = fraction.padEnd(decimals, \"0\").slice(0, decimals);\n return BigInt(whole + padded || \"0\");\n}\n\n// ── Build ERC-20 transfer calldata ────────────────────────────────\n\n/**\n * Build minimal ERC-20 transfer calldata without viem dependency.\n *\n * selector: 0xa9059cbb\n * args: (address to, uint256 amount)\n * encoding: abi-encoded as two 32-byte words\n *\n * @param to - Recipient address\n * @param amount - Raw transfer amount (smallest unit)\n */\nfunction buildTransferCalldata(\n to: `0x${string}`,\n amount: bigint,\n): `0x${string}` {\n return `${ERC20_TRANSFER_SELECTOR}${padAddress(to)}${padHex(amount.toString(16))}` as `0x${string}`;\n}\n\n// ── Types ─────────────────────────────────────────────────────────\n\nexport interface UseERC20TransferSimulationOptions {\n /** Token configuration (address, decimals, chainId) */\n token: TokenConfig;\n /** Recipient address */\n to: `0x${string}`;\n /** Amount in human-readable units (e.g. \"1.50\" for 1.5 USDC) */\n amount: string;\n}\n\nexport interface UseERC20TransferSimulationReturn\n extends Omit<UseTransactionSimulationReturn, \"simulate\"> {\n /** Simulation result for the built ERC-20 transfer */\n result: SimulationResult | undefined;\n /** Whether a simulation is in progress */\n isSimulating: boolean;\n /** Error from the last simulation attempt */\n error: Error | null;\n /** Re-run the simulation with current parameters */\n reSimulate: () => Promise<SimulationResult>;\n /** Reset simulation state */\n reset: () => void;\n}\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport function useERC20TransferSimulation(\n options: UseERC20TransferSimulationOptions,\n): UseERC20TransferSimulationReturn {\n const { evmAccount, isConnected } = useAccount();\n const { currentChain } = useChain();\n const chainId = options.token.chainId ?? currentChain?.id ?? 1;\n\n // Build the transaction descriptor from ERC-20 transfer params\n const tx: EvmTransaction | undefined = useMemo(() => {\n if (!isConnected || !evmAccount) return undefined;\n\n try {\n const decimals = options.token.decimals ?? 18;\n const rawAmount = parseUnits(options.amount, decimals);\n const data = buildTransferCalldata(options.to, rawAmount);\n\n return {\n to: options.token.address,\n data,\n value: \"0\",\n };\n } catch {\n // If amount parsing fails, return undefined\n return undefined;\n }\n }, [\n options.token.address,\n options.token.decimals,\n options.to,\n options.amount,\n evmAccount,\n isConnected,\n ]);\n\n // Use the base transaction simulation hook\n const sim = useTransactionSimulation(tx, chainId);\n\n // Alias simulate → reSimulate for semantic clarity\n return {\n result: sim.result,\n isSimulating: sim.isSimulating,\n error: sim.error,\n reSimulate: sim.simulate,\n reset: sim.reset,\n };\n}\n","import { useState, useCallback, useRef } from \"react\";\nimport type { TxMonitorLike, TxStatusEntry } from \"./useTxMonitor\";\nimport { useTxMonitorProvider } from \"./useTxMonitor\";\n\n// ── Hook ──────────────────────────────────────────────────────────\n\nexport interface UseLastTxResult {\n /** Most recent transaction by createdAt */\n lastTx: TxStatusEntry | null;\n /** Most recent confirmed transaction */\n lastConfirmedTx: TxStatusEntry | null;\n /** Most recent failed transaction */\n lastFailedTx: TxStatusEntry | null;\n /** Clear cached lastTx state */\n clear: () => void;\n}\n\n/**\n * Track the most recent transaction.\n * Automatically updates when a new transaction is sent (via statusChange events).\n */\nexport function useLastTx(monitor?: TxMonitorLike): UseLastTxResult {\n const ctxMonitor = useTxMonitorProvider();\n const effectiveMonitor = monitor ?? ctxMonitor;\n\n const [lastTx, setLastTx] = useState<TxStatusEntry | null>(null);\n const [lastConfirmedTx, setLastConfirmedTx] = useState<TxStatusEntry | null>(null);\n const [lastFailedTx, setLastFailedTx] = useState<TxStatusEntry | null>(null);\n const lastTxRef = useRef<{ createdAt: number } | null>(null);\n\n // Track confirmed and failed events\n const confirmedHandlerRef = useRef<((entry: TxStatusEntry) => void) | null>(null);\n const failedHandlerRef = useRef<((entry: TxStatusEntry) => void) | null>(null);\n\n // Set up listeners\n if (effectiveMonitor) {\n if (!confirmedHandlerRef.current) {\n confirmedHandlerRef.current = (entry: TxStatusEntry) => {\n setLastConfirmedTx(entry);\n if (!lastTxRef.current || entry.createdAt >= lastTxRef.current.createdAt) {\n setLastTx(entry);\n lastTxRef.current = entry;\n }\n };\n effectiveMonitor.on(\"confirmed\", confirmedHandlerRef.current);\n }\n\n if (!failedHandlerRef.current) {\n failedHandlerRef.current = (entry: TxStatusEntry) => {\n setLastFailedTx(entry);\n if (!lastTxRef.current || entry.createdAt >= lastTxRef.current.createdAt) {\n setLastTx(entry);\n lastTxRef.current = entry;\n }\n };\n effectiveMonitor.on(\"failed\", failedHandlerRef.current);\n }\n }\n\n const clear = useCallback(() => {\n setLastTx(null);\n setLastConfirmedTx(null);\n setLastFailedTx(null);\n lastTxRef.current = null;\n }, []);\n\n return {\n lastTx,\n lastConfirmedTx,\n lastFailedTx,\n clear,\n };\n}\n","/**\n * useSmartAccount\n *\n * React hook for ERC-4337 Smart Account lifecycle management.\n * Provides create, deploy, and address lookup for smart contract wallets.\n *\n * @example\n * ```tsx\n * const { address, isDeployed, createWallet, deployWallet, isLoading } = useSmartAccount({\n * rpcUrl: \"https://eth.llamarpc.com\",\n * bundlerUrl: \"https://api.pimlico.io/v2/1/rpc?apikey=...\",\n * });\n * ```\n */\n\nimport { useState, useCallback, useEffect, useRef } from \"react\";\nimport { useAccount } from \"./useAccount\";\nimport type {\n SmartAccountInfo,\n SmartAccountConfig,\n Address,\n} from \"@naculus/connect-core\";\n\nexport interface UseSmartAccountOptions {\n /** RPC URL for the target chain */\n rpcUrl?: string;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Chain ID (CAIP-2 format) */\n chainId?: string;\n /** Account type (default: \"simple\") */\n accountType?: \"simple\" | \"light\" | \"kernel\" | \"safe\";\n /** Optional salt for deterministic address */\n salt?: bigint;\n}\n\nexport interface UseSmartAccountReturn {\n /** Smart account address (null if not created) */\n address: Address | null;\n /** Whether the account is deployed on-chain */\n isDeployed: boolean;\n /** Smart account info object */\n accountInfo: SmartAccountInfo | null;\n /** Loading state */\n isLoading: boolean;\n /** Error state */\n error: Error | null;\n /** Create a new smart account (compute address) */\n createWallet: () => Promise<SmartAccountInfo | null>;\n /** Deploy the smart account to chain */\n deployWallet: () => Promise<Address | null>;\n /** Get the counterfactual address without creating */\n getAddress: () => Promise<Address | null>;\n}\n\n/**\n * Hook for managing a ERC-4337 Smart Contract Wallet lifecycle.\n *\n * @param options - Smart account configuration options\n * @returns Smart account state and actions\n */\nexport function useSmartAccount(options?: UseSmartAccountOptions): UseSmartAccountReturn {\n const { evmAccount } = useAccount();\n const [address, setAddress] = useState<Address | null>(null);\n const [isDeployed, setIsDeployed] = useState(false);\n const [accountInfo, setAccountInfo] = useState<SmartAccountInfo | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const managerRef = useRef<import(\"@naculus/connect-core\").SmartAccountManager | null>(null);\n\n // Initialize SmartAccountManager on config change (with cleanup to prevent race conditions)\n useEffect(() => {\n if (!options?.rpcUrl) {\n managerRef.current = null;\n return;\n }\n\n let cancelled = false;\n\n import(\"@naculus/connect-core\").then(({ SmartAccountManager }) => {\n if (cancelled) return; // prevent stale state update\n managerRef.current = new SmartAccountManager({\n rpcUrl: options.rpcUrl!,\n chainId: options.chainId ?? \"eip155:1\",\n bundlerClient: {\n url: options.bundlerUrl ?? \"\",\n },\n });\n }).catch((err) => {\n if (cancelled) return; // prevent stale state update\n setError(err instanceof Error ? err : new Error(\"Failed to load account-abstraction module\"));\n });\n\n return () => { cancelled = true; };\n }, [options?.rpcUrl, options?.bundlerUrl, options?.chainId]);\n\n // Get account config from options + connected EOA\n const getConfig = useCallback((): SmartAccountConfig | null => {\n const owner = evmAccount;\n if (!owner || !managerRef.current) return null;\n\n const address = owner.includes(\":\") ? owner.split(\":\").pop()! as Address : owner as Address;\n\n return {\n owner: address,\n accountType: options?.accountType ?? \"simple\",\n entryPoint: \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\" as Address, // v0.7\n chainId: options?.chainId ?? \"eip155:1\",\n salt: options?.salt,\n };\n }, [evmAccount, options?.accountType, options?.chainId, options?.salt]);\n\n // Create wallet (compute counterfactual address)\n const createWallet = useCallback(async (): Promise<SmartAccountInfo | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) {\n setError(new Error(\"Smart account not configured\"));\n return null;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const info = await managerRef.current.createAccount(config);\n setAddress(info.address);\n setIsDeployed(info.isDeployed);\n setAccountInfo(info);\n return info;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Failed to create smart account\");\n setError(e);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [getConfig]);\n\n // Deploy wallet\n const deployWallet = useCallback(async (): Promise<Address | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) {\n setError(new Error(\"Smart account not configured\"));\n return null;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const deployResult = await managerRef.current.deployAccount(config);\n\n // After deploy, update state\n if (deployResult) {\n const info = await managerRef.current.createAccount(config);\n setAddress(info.address);\n setIsDeployed(true);\n setAccountInfo(info);\n }\n\n return deployResult;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(\"Failed to deploy smart account\");\n setError(e);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [getConfig]);\n\n // Get counterfactual address\n const getAddress = useCallback(async (): Promise<Address | null> => {\n const config = getConfig();\n if (!config || !managerRef.current) return null;\n\n try {\n const addr = await managerRef.current.getAccountAddress(config);\n return addr;\n } catch {\n return null;\n }\n }, [getConfig]);\n\n return {\n address,\n isDeployed,\n accountInfo,\n isLoading,\n error,\n createWallet,\n deployWallet,\n getAddress,\n };\n}\n","/**\n * useSendUserOperation\n *\n * React hook for sending ERC-4337 UserOperations.\n * Handles construction, signing via connected wallet, and submission to bundler.\n *\n * @example\n * ```tsx\n * const { sendUserOp, userOpHash, receipt, isPending } = useSendUserOperation({\n * rpcUrl: \"https://eth.llamarpc.com\",\n * bundlerUrl: \"https://api.pimlico.io/v2/1/rpc?apikey=...\",\n * });\n *\n * const handleSend = async () => {\n * await sendUserOp([\n * { to: \"0x...\", value: 0n, data: \"0x...\" },\n * ]);\n * };\n * ```\n */\n\nimport { useState, useCallback, useRef } from \"react\";\nimport type {\n UserOperationResponse,\n UserOperationReceipt,\n UserOperation,\n Address,\n Hex,\n Call,\n SendUserOpOptions,\n SmartAccountConfig,\n} from \"@naculus/connect-core\";\n\nexport interface UseSendUserOperationOptions {\n /** RPC URL for the target chain */\n rpcUrl?: string;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Chain ID (CAIP-2 format) */\n chainId?: string;\n /** EntryPoint contract address */\n entryPoint?: Address;\n /** Optional signing function override */\n signer?: (hash: Hex) => Promise<Hex> | Hex;\n}\n\nexport interface UseSendUserOperationReturn {\n /** Send a UserOperation with the given calls */\n sendUserOp: (calls: Call[], options?: SendUserOpOptions) => Promise<UserOperationResponse | null>;\n /** The userOpHash from the last send */\n userOpHash: Hex | null;\n /** The receipt from the last UserOperation (null while pending) */\n receipt: UserOperationReceipt | null;\n /** Whether a UserOperation is currently being sent */\n isPending: boolean;\n /** Loading state for gas estimation phase */\n isEstimating: boolean;\n /** Error state */\n error: Error | null;\n /** Reset state */\n reset: () => void;\n}\n\n/**\n * Hook for sending ERC-4337 UserOperations to a bundler.\n *\n * @param options - Configuration for the bundler and chain\n * @returns UserOperation send states and actions\n */\nexport function useSendUserOperation(\n options?: UseSendUserOperationOptions,\n): UseSendUserOperationReturn {\n const [userOpHash, setUserOpHash] = useState<Hex | null>(null);\n const [receipt, setReceipt] = useState<UserOperationReceipt | null>(null);\n const [isPending, setIsPending] = useState(false);\n const [isEstimating, setIsEstimating] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n const sendUserOp = useCallback(\n async (\n calls: Call[],\n opts?: SendUserOpOptions,\n ): Promise<UserOperationResponse | null> => {\n if (!options?.bundlerUrl) {\n setError(new Error(\"Bundler URL not configured\"));\n return null;\n }\n\n if (!calls.length) {\n setError(new Error(\"At least one call is required\"));\n return null;\n }\n\n // Cancel any in-flight request\n abortRef.current?.abort();\n abortRef.current = new AbortController();\n\n setIsPending(true);\n setIsEstimating(true);\n setError(null);\n setUserOpHash(null);\n setReceipt(null);\n\n try {\n const { SmartAccountManager, buildCallData, signUserOperation, sendUserOperation, buildUserOperation } =\n await import(\"@naculus/connect-core\");\n\n // Build the UserOperation\n const callData = buildCallData(calls);\n\n // Estimate gas via bundler\n const entryPoint = options?.entryPoint ??\n \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\" as Address;\n\n let gasEstimate = {\n callGasLimit: 100_000n,\n verificationGasLimit: 100_000n,\n preVerificationGas: 50_000n,\n };\n\n setIsEstimating(false);\n\n try {\n const est = await import(\"@naculus/connect-core\").then(\n ({ estimateUserOperationGas }) =>\n estimateUserOperationGas(\n { callData, sender: \"0x0000000000000000000000000000000000000000\" as Address },\n entryPoint,\n options.bundlerUrl!,\n ),\n );\n gasEstimate = est;\n } catch {\n // Use defaults\n }\n\n // Get fee data\n let maxFeePerGas = 50_000_000_000n; // 50 gwei default\n let maxPriorityFeePerGas = 1_000_000_000n; // 1 gwei default\n\n if (options.rpcUrl) {\n try {\n const baseFee = await fetch(options.rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_getBlockByNumber\",\n params: [\"latest\", false],\n }),\n signal: abortRef.current.signal,\n }).then(r => r.json()).then(j => {\n if (j.result?.baseFeePerGas) return BigInt(j.result.baseFeePerGas);\n return null;\n });\n\n const priorityFee = await fetch(options.rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_maxPriorityFeePerGas\",\n params: [],\n }),\n signal: abortRef.current.signal,\n }).then(r => r.json()).then(j => {\n if (j.result) return BigInt(j.result);\n return null;\n });\n\n if (baseFee && priorityFee) {\n maxFeePerGas = baseFee * 2n + priorityFee;\n maxPriorityFeePerGas = priorityFee;\n }\n } catch {\n // Use defaults\n }\n }\n\n // Apply gas overrides\n if (opts?.gasOverrides?.callGasLimit) gasEstimate.callGasLimit = opts.gasOverrides.callGasLimit;\n if (opts?.gasOverrides?.verificationGasLimit) gasEstimate.verificationGasLimit = opts.gasOverrides.verificationGasLimit;\n if (opts?.gasOverrides?.preVerificationGas) gasEstimate.preVerificationGas = opts.gasOverrides.preVerificationGas;\n if (opts?.gasOverrides?.maxFeePerGas) maxFeePerGas = opts.gasOverrides.maxFeePerGas;\n if (opts?.gasOverrides?.maxPriorityFeePerGas) maxPriorityFeePerGas = opts.gasOverrides.maxPriorityFeePerGas;\n\n // Build partial UserOperation\n const userOp = buildUserOperation({\n sender: \"0x0000000000000000000000000000000000000000\" as Address,\n nonce: 0n,\n callData,\n accountGasLimits: `0x${gasEstimate.verificationGasLimit.toString(16).padStart(32, \"0\")}${gasEstimate.callGasLimit.toString(16).padStart(32, \"0\")}` as Hex,\n preVerificationGas: gasEstimate.preVerificationGas,\n maxFeePerGas,\n maxPriorityFeePerGas,\n });\n\n // Send to bundler\n const response = await sendUserOperation(\n userOp,\n options.bundlerUrl!,\n entryPoint,\n );\n\n setUserOpHash(response.userOpHash);\n\n // Start polling for receipt\n UserOpPoller(response.userOpHash, options.bundlerUrl!, entryPoint)\n .then((rcpt) => {\n if (rcpt) setReceipt(rcpt);\n })\n .catch(() => {\n // Silently handle polling errors\n });\n\n return response;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(\"Failed to send UserOperation\");\n setError(error);\n return null;\n } finally {\n setIsPending(false);\n setIsEstimating(false);\n }\n },\n [options],\n );\n\n const reset = useCallback(() => {\n setUserOpHash(null);\n setReceipt(null);\n setIsPending(false);\n setIsEstimating(false);\n setError(null);\n }, []);\n\n return {\n sendUserOp,\n userOpHash,\n receipt,\n isPending,\n isEstimating,\n error,\n reset,\n };\n}\n\n/**\n * Poll for a UserOperation receipt from the bundler.\n */\nasync function UserOpPoller(\n userOpHash: Hex,\n bundlerUrl: string,\n entryPoint: Address,\n maxRetries = 20,\n intervalMs = 2000,\n): Promise<UserOperationReceipt | null> {\n for (let i = 0; i < maxRetries; i++) {\n try {\n const response = await fetch(bundlerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_getUserOperationReceipt\",\n params: [userOpHash],\n }),\n });\n\n const json = await response.json() as {\n result?: {\n userOpHash: Hex;\n entryPoint: Address;\n sender: Address;\n nonce: string;\n paymaster?: Address;\n actualGasUsed: string;\n actualGasCost: string;\n success: boolean;\n transactionHash: Hex;\n logs: Array<{ address: Address; topics: Hex[]; data: Hex }>;\n };\n };\n\n if (json.result) {\n return {\n userOpHash: json.result.userOpHash,\n entryPoint: json.result.entryPoint,\n sender: json.result.sender,\n nonce: BigInt(json.result.nonce),\n paymaster: json.result.paymaster,\n actualGasUsed: BigInt(json.result.actualGasUsed),\n actualGasCost: BigInt(json.result.actualGasCost),\n success: json.result.success,\n transactionHash: json.result.transactionHash,\n logs: json.result.logs,\n };\n }\n } catch {\n // Continue polling\n }\n\n if (i < maxRetries - 1) {\n await new Promise(resolve => setTimeout(resolve, intervalMs));\n }\n }\n\n return null;\n}\n","/**\n * useUserOpStatus\n *\n * React hook for tracking ERC-4337 UserOperation lifecycle.\n * Polls the bundler for UserOperation receipt and reports status transitions.\n *\n * @example\n * ```tsx\n * const { userOpHash, status, receipt, error } = useUserOpStatus({\n * userOpHash: \"0x...\",\n * bundlerUrl: \"https://api.pimlico.io/v2/1/rpc?apikey=...\",\n * pollInterval: 2000,\n * });\n *\n * if (status === \"confirmed\") {\n * console.log(\"UserOp included in block!\");\n * }\n * ```\n */\n\nimport { useState, useEffect, useRef, useCallback } from \"react\";\nimport type {\n UserOperationReceipt,\n Address,\n Hex,\n} from \"@naculus/connect-core\";\n\nexport type UserOpStatus = \"idle\" | \"pending\" | \"confirmed\" | \"failed\" | \"not_found\";\n\nexport interface UseUserOpStatusOptions {\n /** The UserOperation hash to track */\n userOpHash?: Hex | null;\n /** Bundler RPC URL */\n bundlerUrl?: string;\n /** Polling interval in milliseconds (default: 2000) */\n pollInterval?: number;\n /** Maximum number of retries (default: 30) */\n maxRetries?: number;\n /** Auto-start polling when userOpHash is provided */\n autoStart?: boolean;\n}\n\nexport interface UseUserOpStatusReturn {\n /** Current status of the UserOperation */\n status: UserOpStatus;\n /** UserOperation receipt (available when confirmed or failed) */\n receipt: UserOperationReceipt | null;\n /** The userOpHash being tracked */\n userOpHash: Hex | null;\n /** Error state */\n error: Error | null;\n /** Whether polling is active */\n isPolling: boolean;\n /** Time elapsed since tracking started (ms) */\n elapsedMs: number;\n /** Number of poll attempts made */\n attempts: number;\n /** Start tracking a UserOperation */\n start: (hash: Hex) => void;\n /** Stop tracking */\n stop: () => void;\n /** Reset state */\n reset: () => void;\n}\n\n/**\n * Hook for tracking the lifecycle of an ERC-4337 UserOperation.\n *\n * @param options - Configuration for polling behavior\n * @returns UserOperation status, receipt, and lifecycle controls\n */\nexport function useUserOpStatus(\n options?: UseUserOpStatusOptions,\n): UseUserOpStatusReturn {\n const bundlerUrl = options?.bundlerUrl;\n const pollInterval = options?.pollInterval ?? 2000;\n const maxRetries = options?.maxRetries ?? 30;\n\n const [status, setStatus] = useState<UserOpStatus>(\"idle\");\n const [receipt, setReceipt] = useState<UserOperationReceipt | null>(null);\n const [userOpHash, setUserOpHash] = useState<Hex | null>(options?.userOpHash ?? null);\n const [error, setError] = useState<Error | null>(null);\n const [isPolling, setIsPolling] = useState(false);\n const [attempts, setAttempts] = useState(0);\n\n const startTimeRef = useRef<number>(0);\n const [elapsedMs, setElapsedMs] = useState(0);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const pollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Clear all timers\n const clearTimers = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n if (pollTimerRef.current) {\n clearTimeout(pollTimerRef.current);\n pollTimerRef.current = null;\n }\n }, []);\n\n // Poll the bundler for receipt\n const poll = useCallback(async (hash: Hex) => {\n if (!bundlerUrl) return;\n\n try {\n const response = await fetch(bundlerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_getUserOperationReceipt\",\n params: [hash],\n }),\n });\n\n if (!response.ok) return;\n\n const json = await response.json() as {\n result?: {\n userOpHash: Hex;\n entryPoint: Address;\n sender: Address;\n nonce: string;\n paymaster?: Address;\n actualGasUsed: string;\n actualGasCost: string;\n success: boolean;\n transactionHash: Hex;\n logs: Array<{ address: Address; topics: Hex[]; data: Hex }>;\n };\n };\n\n if (json.result) {\n const receiptData: UserOperationReceipt = {\n userOpHash: json.result.userOpHash,\n entryPoint: json.result.entryPoint,\n sender: json.result.sender,\n nonce: BigInt(json.result.nonce),\n paymaster: json.result.paymaster,\n actualGasUsed: BigInt(json.result.actualGasUsed),\n actualGasCost: BigInt(json.result.actualGasCost),\n success: json.result.success,\n transactionHash: json.result.transactionHash,\n logs: json.result.logs,\n };\n\n setReceipt(receiptData);\n setStatus(json.result.success ? \"confirmed\" : \"failed\");\n setIsPolling(false);\n clearTimers();\n\n return;\n }\n\n // No receipt yet; schedule next poll\n setAttempts(prev => prev + 1);\n setStatus(\"pending\");\n\n if (attempts < maxRetries) {\n pollTimerRef.current = setTimeout(() => poll(hash), pollInterval);\n } else {\n setStatus(\"not_found\");\n setIsPolling(false);\n clearTimers();\n setError(new Error(\"UserOperation not included after maximum retries\"));\n }\n } catch {\n // Network error; retry\n setAttempts(prev => prev + 1);\n if (attempts < maxRetries) {\n pollTimerRef.current = setTimeout(() => poll(hash), pollInterval);\n }\n }\n }, [bundlerUrl, pollInterval, maxRetries, attempts, clearTimers]);\n\n // Start tracking\n const start = useCallback((hash: Hex) => {\n clearTimers();\n setUserOpHash(hash);\n setStatus(\"pending\");\n setReceipt(null);\n setError(null);\n setAttempts(0);\n setIsPolling(true);\n startTimeRef.current = Date.now();\n\n // Start elapsed timer\n intervalRef.current = setInterval(() => {\n setElapsedMs(Date.now() - startTimeRef.current);\n }, 1000);\n\n // Start polling\n poll(hash);\n }, [clearTimers, poll]);\n\n // Stop tracking\n const stop = useCallback(() => {\n clearTimers();\n setIsPolling(false);\n }, [clearTimers]);\n\n // Reset state\n const reset = useCallback(() => {\n clearTimers();\n setUserOpHash(null);\n setStatus(\"idle\");\n setReceipt(null);\n setError(null);\n setIsPolling(false);\n setAttempts(0);\n setElapsedMs(0);\n }, [clearTimers]);\n\n // Auto-start if userOpHash provided on mount\n useEffect(() => {\n if (options?.userOpHash && options?.autoStart !== false) {\n start(options.userOpHash);\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n clearTimers();\n };\n }, [clearTimers]);\n\n return {\n status,\n receipt,\n userOpHash,\n error,\n isPolling,\n elapsedMs,\n attempts,\n start,\n stop,\n reset,\n };\n}\n","/**\n * useTokenList — React hook for loading token lists.\n *\n * Manages TokenListManager lifecycle and provides reactive\n * token data scoped to a specific chain.\n */\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport { TokenListManager } from \"@naculus/connect-core\";\nimport type { TokenListEntry, TokenListSource, TokenListManagerConfig } from \"@naculus/connect-core\";\n\nexport interface UseTokenListOptions {\n /** Auto-load on mount (default: true) */\n autoLoad?: boolean;\n /** Custom sources (overrides defaults) */\n sources?: TokenListSource[];\n}\n\nexport interface UseTokenListReturn {\n /** Loaded tokens for the specified chain */\n tokens: TokenListEntry[];\n /** Whether the initial load is in progress */\n isLoading: boolean;\n /** Whether tokens have been loaded at least once */\n isLoaded: boolean;\n /** Last error, if any */\n error: Error | null;\n /** Force a full refresh from all sources */\n refetch: () => Promise<void>;\n}\n\n/**\n * React hook for accessing token lists for a specific chain.\n *\n * @example\n * const { tokens, isLoading } = useTokenList(\"eip155:1\");\n * // tokens → [WETH, USDC, USDT, DAI, ...]\n */\nexport function useTokenList(\n chainId?: string,\n options?: UseTokenListOptions,\n): UseTokenListReturn {\n const managerRef = useRef<TokenListManager | null>(null);\n const [tokens, setTokens] = useState<TokenListEntry[]>([]);\n const [isLoading, setIsLoading] = useState(options?.autoLoad !== false);\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Initialize manager once\n if (!managerRef.current) {\n const config: Partial<TokenListManagerConfig> = {};\n if (options?.sources) {\n config.sources = options.sources;\n }\n managerRef.current = new TokenListManager(config);\n }\n\n const load = useCallback(async () => {\n const manager = managerRef.current;\n if (!manager) return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await manager.load();\n const numericChainId = chainId ? parseChainId(chainId) : undefined;\n const loaded = manager.getTokens(\n numericChainId !== undefined ? { chainId: numericChainId } : undefined,\n );\n setTokens(loaded);\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [chainId]);\n\n const refetch = useCallback(async () => {\n const manager = managerRef.current;\n if (!manager) return;\n\n setIsLoading(true);\n setError(null);\n\n try {\n await manager.refresh();\n const numericChainId = chainId ? parseChainId(chainId) : undefined;\n const loaded = manager.getTokens(\n numericChainId !== undefined ? { chainId: numericChainId } : undefined,\n );\n setTokens(loaded);\n setIsLoaded(true);\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setIsLoading(false);\n }\n }, [chainId]);\n\n useEffect(() => {\n if (options?.autoLoad !== false) {\n load();\n }\n }, [load, options?.autoLoad]);\n\n return { tokens, isLoading, isLoaded, error, refetch };\n}\n\n/**\n * Parse a CAIP-2 chain ID like \"eip155:1\" into a numeric chain ID (1).\n * Returns undefined for non-numeric chains.\n */\nfunction parseChainId(chainId: string): number | undefined {\n const parts = chainId.split(\":\");\n const numeric = parseInt(parts[parts.length - 1], 10);\n return isNaN(numeric) ? undefined : numeric;\n}\n","/**\n * useTokenSearch — React hook for searching tokens.\n *\n * Debounced search over loaded token lists.\n * Returns structured results (exact + fuzzy matches).\n */\n\nimport { useState, useEffect, useRef, useMemo } from \"react\";\nimport { TokenListManager } from \"@naculus/connect-core\";\nimport type { TokenSearchResult, TokenListSource, TokenListManagerConfig } from \"@naculus/connect-core\";\nimport { getDefaultSources } from \"./defaults\";\n\nconst DEBOUNCE_MS = 300;\n\nexport interface UseTokenSearchReturn {\n /** Structured search results */\n results: TokenSearchResult;\n /** Whether a search is currently running */\n isSearching: boolean;\n}\n\n// Shared manager instance across hooks\nlet sharedManager: TokenListManager | null = null;\n\nfunction getManager(): TokenListManager {\n if (!sharedManager) {\n sharedManager = new TokenListManager({\n sources: getDefaultSources(),\n });\n // Start loading in background\n sharedManager.load().catch(() => {});\n }\n return sharedManager;\n}\n\n/**\n * React hook for searching tokens by symbol, name, or address.\n *\n * Debounced 300ms to avoid excessive re-renders during typing.\n *\n * @example\n * const { results, isSearching } = useTokenSearch(\"USDC\");\n * // results.exact → [USDC on ETH]\n * // results.fuzzy → [USDC.e on AVAX]\n */\nexport function useTokenSearch(\n query: string,\n chainId?: string,\n): UseTokenSearchReturn {\n const [results, setResults] = useState<TokenSearchResult>({\n exact: [],\n fuzzy: [],\n hasMore: false,\n });\n const [isSearching, setIsSearching] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const trimmedQuery = query.trim();\n\n useEffect(() => {\n if (!trimmedQuery) {\n setResults({ exact: [], fuzzy: [], hasMore: false });\n setIsSearching(false);\n return;\n }\n\n // Debounce\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n setIsSearching(true);\n\n debounceRef.current = setTimeout(() => {\n const manager = getManager();\n const numericChainId = chainId ? parseChainId(chainId) : undefined;\n const searchResults = manager.search(trimmedQuery, {\n chainId: numericChainId,\n limit: 20,\n });\n setResults(searchResults);\n setIsSearching(false);\n }, DEBOUNCE_MS);\n\n return () => {\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n };\n }, [trimmedQuery, chainId]);\n\n return { results, isSearching };\n}\n\nfunction parseChainId(chainId: string): number | undefined {\n const parts = chainId.split(\":\");\n const numeric = parseInt(parts[parts.length - 1], 10);\n return isNaN(numeric) ? undefined : numeric;\n}\n","/**\n * Default token list sources for React hooks.\n */\n\nimport type { TokenListSource } from \"@naculus/connect-core\";\nimport {\n DEFAULT_SOURCES,\n ETHEREUM_MAINNET_TOKENS,\n POLYGON_TOKENS,\n OPTIMISM_TOKENS,\n ARBITRUM_TOKENS,\n BASE_TOKENS,\n} from \"@naculus/connect-core\";\n\n/**\n * Get default sources for useTokenList / useTokenSearch hooks.\n * Includes built-in tokens and remote source URLs.\n */\nexport function getDefaultSources(): TokenListSource[] {\n return [\n {\n name: \"built-in\",\n tokens: [\n ...ETHEREUM_MAINNET_TOKENS,\n ...POLYGON_TOKENS,\n ...OPTIMISM_TOKENS,\n ...ARBITRUM_TOKENS,\n ...BASE_TOKENS,\n ],\n enabled: true,\n },\n {\n name: \"uniswap-default\",\n url: \"https://tokens.uniswap.org\",\n enabled: true,\n refreshInterval: 24 * 60 * 60 * 1000,\n },\n ];\n}\n","/**\n * TokenSelector — chain-aware, searchable token selection component.\n *\n * Features:\n * - Loads token list for the given chain\n * - Search by symbol, name, or address\n * - Displays token logo, symbol, name, and decimals\n * - Calls onSelect when a token is chosen\n */\n\nimport React, { useCallback } from \"react\";\nimport type { TokenListEntry } from \"@naculus/connect-core\";\nimport { useTokenList } from \"./useTokenList\";\nimport { useTokenSearch } from \"./useTokenSearch\";\n\nexport interface TokenSelectorProps {\n /** Chain ID in CAIP-2 format (e.g. \"eip155:1\") */\n chainId: string;\n /** Called when a token is selected */\n onSelect: (token: TokenListEntry) => void;\n /** Called to close/dismiss the selector */\n onClose: () => void;\n /** Optional configuration */\n options?: {\n /** Show popular/recommended tokens (default: true) */\n showRecommendations?: boolean;\n /** Custom filter for tokens */\n filter?: (token: TokenListEntry) => boolean;\n };\n}\n\n/**\n * TokenSelector — a dropdown/modal component for selecting tokens.\n *\n * @example\n * <TokenSelector\n * chainId=\"eip155:1\"\n * onSelect={(token) => setSelectedToken(token)}\n * onClose={() => setOpen(false)}\n * />\n */\nexport function TokenSelector({\n chainId,\n onSelect,\n onClose,\n options,\n}: TokenSelectorProps) {\n const [searchQuery, setSearchQuery] = React.useState(\"\");\n\n const {\n tokens: allTokens,\n isLoading,\n error,\n } = useTokenList(chainId);\n\n const { results, isSearching } = useTokenSearch(\n searchQuery,\n searchQuery ? chainId : undefined,\n );\n\n const showRecommendations = options?.showRecommendations ?? true;\n\n // Display tokens: when searching, show results; otherwise show the full list\n const displayTokens = React.useMemo(() => {\n if (searchQuery.trim()) {\n const combined = [...results.exact, ...results.fuzzy].map((m) => m.token);\n return options?.filter\n ? combined.filter(options.filter)\n : combined;\n }\n\n const tokens = allTokens;\n return options?.filter\n ? tokens.filter(options.filter)\n : tokens;\n }, [searchQuery, results, allTokens, options?.filter]);\n\n // Popular tokens for recommendation section\n const popularTokens = React.useMemo(() => {\n if (!showRecommendations || searchQuery.trim()) return [];\n return allTokens.slice(0, 6); // Top 6\n }, [allTokens, showRecommendations, searchQuery]);\n\n const handleSelect = useCallback(\n (token: TokenListEntry) => {\n onSelect(token);\n onClose();\n },\n [onSelect, onClose],\n );\n\n return (\n <div\n style={{\n background: \"hsl(var(--background))\",\n borderRadius: \"12px\",\n padding: \"16px\",\n color: \"hsl(var(--foreground))\",\n minWidth: \"320px\",\n maxWidth: \"400px\",\n fontFamily: \"system-ui, sans-serif\",\n }}\n >\n {/* Header */}\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"12px\",\n }}\n >\n <h3 style={{ margin: 0, fontSize: \"16px\", fontWeight: 600 }}>\n Select Token\n </h3>\n <button\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n color: \"hsl(var(--muted-foreground))\",\n cursor: \"pointer\",\n fontSize: \"18px\",\n padding: \"4px 8px\",\n }}\n >\n ✕\n </button>\n </div>\n\n {/* Search Input */}\n <input\n type=\"text\"\n placeholder=\"Search token name or paste address\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{\n width: \"100%\",\n padding: \"10px 12px\",\n borderRadius: \"8px\",\n border: \"1px solid #333\",\n background: \"hsl(var(--card))\",\n color: \"hsl(var(--foreground))\",\n fontSize: \"14px\",\n outline: \"none\",\n boxSizing: \"border-box\",\n marginBottom: \"12px\",\n }}\n autoFocus\n />\n\n {/* Loading / Error States */}\n {isLoading && !isSearching && (\n <div style={{ textAlign: \"center\", padding: \"20px\", color: \"hsl(var(--muted-foreground))\" }}>\n Loading tokens...\n </div>\n )}\n {error && (\n <div\n style={{\n textAlign: \"center\",\n padding: \"12px\",\n color: \"hsl(var(--destructive))\",\n fontSize: \"13px\",\n }}\n >\n Error: {error.message}\n </div>\n )}\n\n {/* Popular / Recommended Section */}\n {showRecommendations && popularTokens.length > 0 && !searchQuery.trim() && (\n <div style={{ marginBottom: \"12px\" }}>\n <div\n style={{\n fontSize: \"11px\",\n color: \"hsl(var(--muted-foreground))\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.5px\",\n marginBottom: \"8px\",\n }}\n >\n Popular\n </div>\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\" }}>\n {popularTokens.map((token) => (\n <button\n key={`${token.chainId}:${token.address}`}\n onClick={() => handleSelect(token)}\n style={{\n background: \"hsl(var(--card))\",\n border: \"1px solid #333\",\n borderRadius: \"20px\",\n padding: \"6px 14px\",\n color: \"hsl(var(--foreground))\",\n cursor: \"pointer\",\n fontSize: \"13px\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n }}\n >\n {token.logoURI ? (\n <img\n src={token.logoURI}\n alt=\"\"\n style={{ width: \"16px\", height: \"16px\", borderRadius: \"50%\" }}\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n ) : null}\n {token.symbol}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Search Result Count */}\n {searchQuery.trim() && !isLoading && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"hsl(var(--muted-foreground))\",\n marginBottom: \"8px\",\n }}\n >\n {displayTokens.length > 0 ? (\n <>\n {results.exact.length} exact, {results.fuzzy.length} fuzzy\n {results.hasMore ? \" (more available)\" : \"\"}\n </>\n ) : (\n \"No results found\"\n )}\n </div>\n )}\n\n {/* Token List */}\n <div\n style={{\n maxHeight: \"320px\",\n overflowY: \"auto\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"2px\",\n }}\n >\n {displayTokens.map((token) => (\n <button\n key={`${token.chainId}:${token.address}`}\n onClick={() => handleSelect(token)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n padding: \"10px 8px\",\n background: \"transparent\",\n border: \"none\",\n borderRadius: \"8px\",\n color: \"hsl(var(--foreground))\",\n cursor: \"pointer\",\n textAlign: \"left\",\n width: \"100%\",\n fontSize: \"14px\",\n }}\n onMouseEnter={(e) => {\n (e.target as HTMLElement).style.background = \"hsl(var(--card))\";\n }}\n onMouseLeave={(e) => {\n (e.target as HTMLElement).style.background = \"transparent\";\n }}\n >\n {/* Logo */}\n <div\n style={{\n width: \"32px\",\n height: \"32px\",\n borderRadius: \"50%\",\n background: \"hsl(var(--border))\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"12px\",\n fontWeight: 600,\n flexShrink: 0,\n overflow: \"hidden\",\n }}\n >\n {token.logoURI ? (\n <img\n src={token.logoURI}\n alt={token.symbol}\n style={{ width: \"100%\", height: \"100%\" }}\n onError={(e) => {\n const img = e.target as HTMLImageElement;\n img.style.display = \"none\";\n (img.parentElement as HTMLElement).textContent =\n token.symbol.slice(0, 2);\n }}\n />\n ) : (\n token.symbol.slice(0, 2)\n )}\n </div>\n\n {/* Token info */}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontWeight: 600,\n fontSize: \"14px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {token.symbol}\n </div>\n <div\n style={{\n fontSize: \"12px\",\n color: \"hsl(var(--muted-foreground))\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {token.name}\n </div>\n </div>\n\n {/* Decimals & Chain Info */}\n <div\n style={{\n fontSize: \"11px\",\n color: \"#666\",\n textAlign: \"right\",\n flexShrink: 0,\n }}\n >\n <div>{token.decimals} decimals</div>\n <div>Chain {token.chainId}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n );\n}\n","/**\n * useNotification — React hook for push notification state.\n *\n * Provides notifications, settings, and control methods for the\n * in-app notification center.\n *\n * @example\n * ```tsx\n * import { useNotification } from \"@naculus/connect-appkit-react\";\n *\n * function NotificationCenter() {\n * const { notifications, unreadCount, clear, markAsRead } = useNotification();\n * return (\n * <div>\n * <span>Unread: {unreadCount}</span>\n * <ul>\n * {notifications.map(n => (\n * <li key={n.id} onClick={() => markAsRead(n.id)}>\n * {n.title} — {n.body}\n * </li>\n * ))}\n * </ul>\n * <button onClick={clear}>Clear all</button>\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from \"react\";\nimport {\n InAppChannel,\n type NotificationItem,\n type NotificationSettings,\n type NotificationFrequency,\n type TxStatus,\n} from \"@naculus/connect-core\";\nimport { createStorageAdapter } from \"@naculus/connect-core\";\n\n// ─── Default settings ─────────────────────────────────────────────────\n\nconst DEFAULT_SETTINGS: NotificationSettings = {\n telegram: false,\n webpush: false,\n inapp: true,\n frequency: \"final-only\" as NotificationFrequency,\n mutedChains: [],\n mutedTypes: [],\n};\n\nconst STORAGE_KEY_SETTINGS = \"naculus_notif_react_settings\";\n\n// ─── Hook ──────────────────────────────────────────────────────────────\n\n/**\n * Hook for consuming in-app notifications in React components.\n *\n * Uses InAppChannel internally to manage the notification queue.\n * All persistent state is stored via localStorage.\n */\nexport function useNotification(options?: {\n /** External InAppChannel instance (for sharing between hooks). If omitted, creates one. */\n channel?: InAppChannel;\n /** Custom storage for settings (defaults to localStorage) */\n storage?: {\n getItem: <T>(key: string) => Promise<T | null>;\n setItem: <T>(key: string, value: T) => Promise<void>;\n removeItem: (key: string) => Promise<void>;\n };\n}) {\n // ── Channel ──────────────────────────────────────────────────────\n\n const channelRef = useRef<InAppChannel | null>(null);\n\n if (!channelRef.current) {\n channelRef.current = options?.channel ?? new InAppChannel();\n }\n\n const channel = channelRef.current;\n\n // ── State ────────────────────────────────────────────────────────\n\n const [notifications, setNotifications] = useState<NotificationItem[]>(() =>\n channel.getHistory(),\n );\n\n const [settings, setSettingsState] = useState<NotificationSettings>(() => {\n // Try to load from storage, fall back to default\n return DEFAULT_SETTINGS;\n });\n\n // ── Load persisted settings on mount ──────────────────────────────\n\n useEffect(() => {\n const storage = options?.storage ?? createReactStorage();\n storage.getItem<NotificationSettings>(STORAGE_KEY_SETTINGS).then((saved) => {\n if (saved) {\n setSettingsState(saved);\n }\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // ── Sync notifications with channel ──────────────────────────────\n\n useEffect(() => {\n // Set up callback to reactively update state when new notifications arrive\n channel.onNotification = (item) => {\n setNotifications((prev) => [...prev, item]);\n };\n\n // Restore persisted history\n channel.restore().then(() => {\n setNotifications(channel.getHistory());\n });\n\n return () => {\n // Cleanup: deregister callback on unmount\n channel.onNotification = undefined;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // ── Computed ─────────────────────────────────────────────────────\n\n const unreadCount = useMemo(() => {\n return notifications.filter((n) => !n.read).length;\n }, [notifications]);\n\n // ── Actions ──────────────────────────────────────────────────────\n\n const clear = useCallback(() => {\n channel.clear();\n setNotifications([]);\n }, [channel]);\n\n const clearOne = useCallback((id: string) => {\n const updated = channel.getHistory().filter((n) => n.id !== id);\n // Mutate channel history in place (we recreate from the in-memory history)\n channel.clear();\n // Re-add the ones we want to keep\n Promise.all(\n updated.map((item) =>\n channel.send({\n id: item.id,\n userId: \"\",\n txHash: item.txHash,\n chainId: \"\",\n chainName: item.chainName,\n status: item.status,\n title: item.title,\n body: item.body,\n valueFormatted: item.valueFormatted,\n explorerUrl: item.explorerUrl,\n timestamp: item.timestamp,\n }),\n ),\n ).then(() => {\n // Force re-sync\n setNotifications(channel.getHistory());\n });\n }, [channel]);\n\n const markAsRead = useCallback(\n (id: string) => {\n channel.markAsRead(id);\n setNotifications((prev) =>\n prev.map((n) => (n.id === id ? { ...n, read: true } : n)),\n );\n },\n [channel],\n );\n\n const markAllAsRead = useCallback(() => {\n channel.markAllAsRead();\n setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));\n }, [channel]);\n\n // ── Add single notification ──────────────────────────────────────\n\n const addNotification = useCallback(\n (item: Omit<NotificationItem, \"id\" | \"timestamp\">) => {\n const full: NotificationItem = {\n ...item,\n id: `notif_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n timestamp: Date.now(),\n };\n channel.send({\n id: full.id,\n userId: \"\",\n txHash: full.txHash,\n chainId: \"\",\n chainName: full.chainName,\n status: full.status,\n title: full.title,\n body: full.body,\n valueFormatted: full.valueFormatted,\n explorerUrl: full.explorerUrl,\n timestamp: full.timestamp,\n });\n // The onNotification callback will update state\n },\n [channel],\n );\n\n // ── Settings ──────────────────────────────────────────────────────\n\n const updateSettings = useCallback(\n (update: Partial<NotificationSettings>) => {\n setSettingsState((prev) => {\n const next = { ...prev, ...update };\n const storage = options?.storage ?? createReactStorage();\n storage.setItem(STORAGE_KEY_SETTINGS, next).catch(() => {});\n return next;\n });\n },\n [options?.storage],\n );\n\n const setChannels = useCallback(\n (channels: string[]) => {\n const update: Partial<NotificationSettings> = {};\n if (channels.includes(\"telegram\")) update.telegram = true;\n if (channels.includes(\"webpush\")) update.webpush = true;\n if (channels.includes(\"inapp\")) update.inapp = true;\n updateSettings(update);\n },\n [updateSettings],\n );\n\n const muteChain = useCallback(\n (chainId: string) => {\n updateSettings({\n mutedChains: [...new Set([...settings.mutedChains, chainId])],\n });\n },\n [settings.mutedChains, updateSettings],\n );\n\n const unmuteChain = useCallback(\n (chainId: string) => {\n updateSettings({\n mutedChains: settings.mutedChains.filter((c) => c !== chainId),\n });\n },\n [settings.mutedChains, updateSettings],\n );\n\n // ── Return ───────────────────────────────────────────────────────\n\n return {\n /** All in-app notifications (newest last) */\n notifications,\n /** Number of unread notifications */\n unreadCount,\n /** Add a single notification manually */\n addNotification,\n /** Clear all in-app notifications */\n clear,\n /** Clear a single notification */\n clearOne,\n /** Mark a notification as read */\n markAsRead,\n /** Mark all as read */\n markAllAsRead,\n /** Current notification settings */\n settings,\n /** Update notification settings */\n updateSettings,\n /** Set active channels by id */\n setChannels,\n /** Mute a chain */\n muteChain,\n /** Unmute a chain */\n unmuteChain,\n };\n}\n\n// ─── Storage helper ───────────────────────────────────────────────────\n\nfunction createReactStorage() {\n const storage = createStorageAdapter(\"local\", \"naculus_notif_\");\n\n return {\n getItem: async <T>(key: string): Promise<T | null> => {\n try {\n return await storage.get<T>(key);\n } catch (e) {\n console.warn(\"useNotification: failed to read from storage:\", e);\n return null;\n }\n },\n setItem: async <T>(key: string, value: T): Promise<void> => {\n try {\n await storage.set(key, value);\n } catch (e) {\n console.warn(\"useNotification: failed to write to storage:\", e);\n }\n },\n removeItem: async (key: string): Promise<void> => {\n try {\n await storage.remove(key);\n } catch (e) {\n console.warn(\"useNotification: failed to remove from storage:\", e);\n }\n },\n };\n}\n","/**\n * useSimulateTransfer — React hook for simulating ERC-20 token transfers.\n *\n * Wraps SimulationManager.simulateERC20Transfer in a React hook with\n * reactive state for loading, result, and error.\n *\n * @example\n * ```tsx\n * import { useSimulateTransfer } from \"@naculus/connect-appkit-react\";\n *\n * function SendForm({ token, to, amount }) {\n * const { result, simulate, loading } = useSimulateTransfer({\n * rpcUrl: \"https://eth.llamarpc.com\",\n * });\n *\n * return (\n * <div>\n * <button onClick={() => simulate(token, to, amount)} disabled={loading}>\n * Simulate Transfer\n * </button>\n * {result && <p>Result: {result.status}</p>}\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useCallback, useRef } from \"react\";\nimport { SimulationManager } from \"@naculus/wallet-engine\";\nimport type { SimulationResult } from \"@naculus/wallet-engine\";\n\n// ── Types ──────────────────────────────────────────────────────────\n\nexport interface UseSimulateTransferOptions {\n /** RPC URL for eth_call simulation */\n rpcUrl?: string;\n /** Default chain ID */\n chainId?: number;\n}\n\nexport interface UseSimulateTransferReturn {\n /** Current simulation result */\n result: SimulationResult | null;\n /** Whether a simulation is in progress */\n loading: boolean;\n /** Last error (null if no error) */\n error: Error | null;\n /**\n * Simulate an ERC-20 transfer.\n *\n * @param tokenAddress - ERC-20 token contract address\n * @param from - Sender address\n * @param to - Recipient address\n * @param amount - Human-readable amount (e.g. \"1.50\")\n * @param options - Optional chainId, rpcUrl, decimals override\n */\n simulate: (\n tokenAddress: `0x${string}`,\n from: `0x${string}`,\n to: `0x${string}`,\n amount: string,\n options?: {\n chainId?: number;\n rpcUrl?: string;\n decimals?: number;\n },\n ) => Promise<SimulationResult>;\n /** Reset result and error state */\n reset: () => void;\n}\n\n// ── Hook ───────────────────────────────────────────────────────────\n\n/**\n * Hook for simulating an ERC-20 token transfer.\n *\n * Creates a SimulationManager internally and provides a `simulate`\n * function that builds transfer calldata automatically.\n *\n * @param options - Configuration for the underlying SimulationManager\n */\nexport function useSimulateTransfer(\n options?: UseSimulateTransferOptions,\n): UseSimulateTransferReturn {\n const rpcUrl = options?.rpcUrl;\n const chainId = options?.chainId;\n\n // ── SimulationManager ref (lazy init) ──────────────────────────\n\n const managerRef = useRef<SimulationManager | null>(null);\n\n function getManager(): SimulationManager {\n if (!managerRef.current) {\n managerRef.current = new SimulationManager({\n enabled: true,\n rpcUrl,\n autoSimulate: false,\n });\n }\n return managerRef.current;\n }\n\n // ── State ──────────────────────────────────────────────────────\n\n const [result, setResult] = useState<SimulationResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // ── Simulate ───────────────────────────────────────────────────\n\n const simulate = useCallback(\n async (\n tokenAddress: `0x${string}`,\n from: `0x${string}`,\n to: `0x${string}`,\n amount: string,\n simOptions?: {\n chainId?: number;\n rpcUrl?: string;\n decimals?: number;\n },\n ): Promise<SimulationResult> => {\n setLoading(true);\n setError(null);\n\n try {\n const manager = getManager();\n const actualChainId = simOptions?.chainId ?? chainId ?? 1;\n const actualRpcUrl = simOptions?.rpcUrl ?? rpcUrl;\n\n const simResult = await manager.simulateERC20Transfer(\n tokenAddress,\n from,\n to,\n amount,\n actualChainId,\n simOptions?.decimals,\n );\n\n setResult(simResult);\n return simResult;\n } catch (err) {\n const errorObj =\n err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n } finally {\n setLoading(false);\n }\n },\n [rpcUrl, chainId],\n );\n\n // ── Reset ──────────────────────────────────────────────────────\n\n const reset = useCallback(() => {\n setResult(null);\n setError(null);\n setLoading(false);\n }, []);\n\n // ── Return ─────────────────────────────────────────────────────\n\n return { result, loading, error, simulate, reset };\n}\n","/**\n * useRouteQuote — React hook for cross-chain route quoting.\n *\n * Provides reactive state for discovering routes and getting quotes\n * from the RouteEngine. Returns loading, error, and result states.\n *\n * @example\n * ```tsx\n * import { useRouteQuote } from \"@naculus/connect-appkit-react\";\n *\n * function QuotePanel() {\n * const { quotes, loading, error, refresh } = useRouteQuote({\n * fromChain: \"eip155:1\",\n * toChain: \"eip155:137\",\n * fromToken: \"USDC\",\n * amount: \"1000000\",\n * });\n *\n * if (loading) return <div>Loading quotes...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * {quotes.map(q => (\n * <div key={q.routeId}>\n * {q.provider} — {q.netReceiveFormatted} {q.toTokenSymbol}\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\n// ── Local type definitions (hook domain types, not core exports) ──────\n\nexport interface Quote {\n routeId: string;\n provider: string;\n netReceiveFormatted: string;\n toTokenSymbol: string;\n}\n\nexport interface QuoteOptions {\n sortBy?: \"cost\" | \"time\" | \"balance\";\n maxSlippage?: number;\n}\n\nexport interface UseRouteQuoteInput {\n fromChain: string;\n toChain: string;\n fromToken: string;\n toToken?: string;\n amount: string;\n options?: QuoteOptions;\n}\n\nexport interface UseRouteQuoteReturn {\n /** Current list of quotes (sorted by options.sortBy) */\n quotes: Quote[];\n /** Whether a quote request is in flight */\n loading: boolean;\n /** Error that occurred during the last request */\n error: Error | null;\n /** Manually trigger a refresh (re-fetches quotes) */\n refresh: () => Promise<void>;\n /** Clear the current quotes and error state */\n clear: () => void;\n}\n\n/**\n * Hook for fetching cross-chain route quotes.\n *\n * Automatically re-fetches when input parameters change.\n * Debounces rapid changes to avoid excessive API calls.\n *\n * @param input - Quote request parameters\n * @param getQuoteFn - Function that performs the actual quote fetch\n */\nexport function useRouteQuote(\n input: UseRouteQuoteInput,\n getQuoteFn?: (from: string, to: string, token: string, amount: string, options?: QuoteOptions) => Promise<Quote[]>,\n): UseRouteQuoteReturn {\n const { fromChain, toChain, fromToken, toToken, amount, options } = input;\n const [quotes, setQuotes] = useState<Quote[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const mountedRef = useRef(true);\n\n const fetchQuotes = useCallback(async () => {\n if (!fromChain || !toChain || !fromToken || !amount || BigInt(amount) <= 0n) {\n setQuotes([]);\n return;\n }\n\n if (!getQuoteFn) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await getQuoteFn(\n fromChain,\n toChain,\n fromToken,\n amount,\n options,\n );\n\n if (mountedRef.current) {\n setQuotes(result);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setQuotes([]);\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [fromChain, toChain, fromToken, amount, options, getQuoteFn]);\n\n // Debounced auto-fetch on input change\n useEffect(() => {\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current);\n }\n\n // Don't fetch if parameters are incomplete\n if (!fromChain || !toChain || !fromToken || !amount) {\n setQuotes([]);\n return;\n }\n\n debounceTimer.current = setTimeout(() => {\n fetchQuotes();\n }, 300); // 300ms debounce\n\n return () => {\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current);\n }\n };\n }, [fetchQuotes, fromChain, toChain, fromToken, amount]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const refresh = useCallback(async () => {\n await fetchQuotes();\n }, [fetchQuotes]);\n\n const clear = useCallback(() => {\n setQuotes([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { quotes, loading, error, refresh, clear };\n}\n","/**\n * useExecuteRoute — React hook for executing cross-chain routes.\n *\n * Manages the execution lifecycle of a cross-chain transfer.\n * Tracks execution status, bridge reference, and completion state.\n *\n * @example\n * ```tsx\n * import { useExecuteRoute } from \"@naculus/connect-appkit-react\";\n *\n * function RouteExecutionPanel({ quote }) {\n * const { execute, executing, result, error } = useExecuteRoute();\n *\n * return (\n * <div>\n * <button onClick={() => execute(quote, \"0xRecipient\")} disabled={executing}>\n * {executing ? \"Executing...\" : \"Execute Route\"}\n * </button>\n * {result && <div>Tx: {result.fromTxHash}</div>}\n * {error && <div>Error: {error.message}</div>}\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useCallback, useRef } from \"react\";\n// ── Local type definitions (hook domain types, not core exports) ──────\n\nexport interface Quote {\n routeId: string;\n provider: string;\n totalCost?: bigint;\n estimatedTimeMs?: number;\n}\n\nexport interface ExecuteRouteResult {\n fromTxHash: string;\n toTxHash?: string;\n}\n\nexport interface ExecuteOptions {\n timeoutMs?: number;\n gasLimit?: bigint;\n}\n\nexport interface UseExecuteRouteReturn {\n /** Execute a route (call this with the selected quote) */\n execute: (quote: Quote, recipient: string, options?: ExecuteOptions) => Promise<void>;\n /** Whether execution is in progress */\n executing: boolean;\n /** The execution result (populated after successful execution) */\n result: ExecuteRouteResult | null;\n /** Error that occurred during execution */\n error: ExecuteError | null;\n /** Reset execution state back to initial */\n reset: () => void;\n}\n\nexport interface ExecuteError {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\n/**\n * Hook for executing a cross-chain route.\n *\n * Manages the full lifecycle from calling executeRoute to\n * tracking the result. For auto-approve flows, handles the\n * approve → cross-chain sequence.\n *\n * @param executeRouteFn - Function that performs the actual route execution\n */\nexport function useExecuteRoute(\n executeRouteFn?: (quote: Quote, recipient: string, options?: ExecuteOptions) => Promise<ExecuteRouteResult>,\n): UseExecuteRouteReturn {\n const [executing, setExecuting] = useState(false);\n const [result, setResult] = useState<ExecuteRouteResult | null>(null);\n const [error, setError] = useState<ExecuteError | null>(null);\n const mountedRef = useRef(true);\n\n const execute = useCallback(async (\n quote: Quote,\n recipient: string,\n options?: ExecuteOptions,\n ) => {\n if (!executeRouteFn) {\n setError({\n code: \"no_executor\",\n message: \"No executeRoute function provided\",\n });\n return;\n }\n\n setExecuting(true);\n setError(null);\n setResult(null);\n\n try {\n const execResult = await executeRouteFn(quote, recipient, options);\n\n if (mountedRef.current) {\n setResult(execResult);\n }\n } catch (err) {\n if (mountedRef.current) {\n const executionError = err as Error;\n setError({\n code: (executionError as any).code ?? \"execution_failed\",\n message: executionError.message,\n details: (executionError as any).details,\n });\n }\n } finally {\n if (mountedRef.current) {\n setExecuting(false);\n }\n }\n }, [executeRouteFn]);\n\n const reset = useCallback(() => {\n setResult(null);\n setError(null);\n setExecuting(false);\n }, []);\n\n return { execute, executing, result, error, reset };\n}\n","/**\n * useCompareCosts — React hook for comparing operation costs across chains.\n *\n * Provides reactive state for comparing gas costs, fees, and estimated\n * times for a given operation across multiple chains.\n *\n * @example\n * ```tsx\n * import { useCompareCosts } from \"@naculus/connect-appkit-react\";\n *\n * function CostComparisonPanel() {\n * const { comparisons, loading, error, refresh } = useCompareCosts({\n * operation: \"send_erc20\",\n * chains: [\"eip155:1\", \"eip155:137\", \"eip155:10\"],\n * });\n *\n * if (loading) return <div>Loading...</div>;\n *\n * return (\n * <div>\n * {comparisons.map(c => (\n * <div key={c.chain}>\n * {c.chainName}: ${c.totalCost} (gas: ${c.gasCost})\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\n// ── Local type definitions (hook domain types, not core exports) ──────\n\nexport interface CostComparison {\n chain: string;\n chainName: string;\n totalCost: string;\n gasCost: string;\n estimatedTimeMs: number;\n}\n\nexport type CostComparisonOperation = \"send_erc20\" | \"swap\" | \"bridge\" | (string & {});\n\nexport interface CostComparisonOptions {\n amount?: string;\n token?: string;\n [key: string]: unknown;\n}\n\n\nexport interface UseCompareCostsInput {\n operation: CostComparisonOperation;\n chains: string[];\n options?: CostComparisonOptions;\n}\n\nexport interface UseCompareCostsReturn {\n /** Sorted cost comparisons (cheapest first) */\n comparisons: CostComparison[];\n /** Whether a comparison request is in flight */\n loading: boolean;\n /** Error that occurred during the last request */\n error: Error | null;\n /** Manually trigger a refresh */\n refresh: () => Promise<void>;\n}\n\n/**\n * Hook for comparing operation costs across multiple chains.\n *\n * Automatically re-fetches when input parameters change.\n * Helpful for chain selection UIs (\"show me the cheapest chain\").\n *\n * @param input - Comparison parameters\n * @param compareCostsFn - Function that performs the actual comparison\n */\nexport function useCompareCosts(\n input: UseCompareCostsInput,\n compareCostsFn?: (\n operation: string,\n chains: string[],\n options?: CostComparisonOptions,\n ) => Promise<CostComparison[]>,\n): UseCompareCostsReturn {\n const { operation, chains, options } = input;\n const [comparisons, setComparisons] = useState<CostComparison[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const fetchComparisons = useCallback(async () => {\n if (!chains || chains.length === 0) {\n setComparisons([]);\n return;\n }\n\n if (!compareCostsFn) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const result = await compareCostsFn(operation, chains, options);\n\n if (mountedRef.current) {\n setComparisons(result);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setComparisons([]);\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [operation, chains, options, compareCostsFn]);\n\n useEffect(() => {\n fetchComparisons();\n }, [fetchComparisons]);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const refresh = useCallback(async () => {\n await fetchComparisons();\n }, [fetchComparisons]);\n\n return { comparisons, loading, error, refresh };\n}\n","'use client';\n\n/**\n * This file was automatically generated by the Stencil React Output Target.\n * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.\n */\n\n/* eslint-disable */\n\nimport type { EventName, StencilReactComponent } from '@stencil/react-output-target/runtime';\nimport { createComponent } from '@stencil/react-output-target/runtime';\nimport React from 'react';\n\nimport { type AppkitAccordionCustomEvent, type AppkitAlertDialogCustomEvent, type AppkitCheckboxCustomEvent, type AppkitCollapsibleCustomEvent, type AppkitConnectButtonCustomEvent, type AppkitDialogCustomEvent, type AppkitDropdownMenuCustomEvent, type AppkitInputCustomEvent, type AppkitPopoverCustomEvent, type AppkitSelectCustomEvent, type AppkitSwitchCustomEvent, type AppkitTabsCustomEvent, type AppkitToggleGroupCustomEvent } from \"@naculus/connect-appkit-wc\";\nimport type { Components } from \"@naculus/connect-appkit-wc/dist/components\";\nimport { AppkitAccordion as AppkitAccordionElement, defineCustomElement as defineAppkitAccordion } from \"@naculus/connect-appkit-wc/dist/components/appkit-accordion.js\";\nimport { AppkitAccountButton as AppkitAccountButtonElement, defineCustomElement as defineAppkitAccountButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-account-button.js\";\nimport { AppkitAlertDialog as AppkitAlertDialogElement, defineCustomElement as defineAppkitAlertDialog } from \"@naculus/connect-appkit-wc/dist/components/appkit-alert-dialog.js\";\nimport { AppkitAvatar as AppkitAvatarElement, defineCustomElement as defineAppkitAvatar } from \"@naculus/connect-appkit-wc/dist/components/appkit-avatar.js\";\nimport { AppkitBadge as AppkitBadgeElement, defineCustomElement as defineAppkitBadge } from \"@naculus/connect-appkit-wc/dist/components/appkit-badge.js\";\nimport { AppkitButton as AppkitButtonElement, defineCustomElement as defineAppkitButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-button.js\";\nimport { AppkitCardContent as AppkitCardContentElement, defineCustomElement as defineAppkitCardContent } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-content.js\";\nimport { AppkitCardDescription as AppkitCardDescriptionElement, defineCustomElement as defineAppkitCardDescription } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-description.js\";\nimport { AppkitCardFooter as AppkitCardFooterElement, defineCustomElement as defineAppkitCardFooter } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-footer.js\";\nimport { AppkitCardHeader as AppkitCardHeaderElement, defineCustomElement as defineAppkitCardHeader } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-header.js\";\nimport { AppkitCardTitle as AppkitCardTitleElement, defineCustomElement as defineAppkitCardTitle } from \"@naculus/connect-appkit-wc/dist/components/appkit-card-title.js\";\nimport { AppkitCard as AppkitCardElement, defineCustomElement as defineAppkitCard } from \"@naculus/connect-appkit-wc/dist/components/appkit-card.js\";\nimport { AppkitCheckbox as AppkitCheckboxElement, defineCustomElement as defineAppkitCheckbox } from \"@naculus/connect-appkit-wc/dist/components/appkit-checkbox.js\";\nimport { AppkitCollapsible as AppkitCollapsibleElement, defineCustomElement as defineAppkitCollapsible } from \"@naculus/connect-appkit-wc/dist/components/appkit-collapsible.js\";\nimport { AppkitConnectButton as AppkitConnectButtonElement, defineCustomElement as defineAppkitConnectButton } from \"@naculus/connect-appkit-wc/dist/components/appkit-connect-button.js\";\nimport { AppkitDialog as AppkitDialogElement, defineCustomElement as defineAppkitDialog } from \"@naculus/connect-appkit-wc/dist/components/appkit-dialog.js\";\nimport { AppkitDropdownMenu as AppkitDropdownMenuElement, defineCustomElement as defineAppkitDropdownMenu } from \"@naculus/connect-appkit-wc/dist/components/appkit-dropdown-menu.js\";\nimport { AppkitInput as AppkitInputElement, defineCustomElement as defineAppkitInput } from \"@naculus/connect-appkit-wc/dist/components/appkit-input.js\";\nimport { AppkitPopover as AppkitPopoverElement, defineCustomElement as defineAppkitPopover } from \"@naculus/connect-appkit-wc/dist/components/appkit-popover.js\";\nimport { AppkitProgress as AppkitProgressElement, defineCustomElement as defineAppkitProgress } from \"@naculus/connect-appkit-wc/dist/components/appkit-progress.js\";\nimport { AppkitScrollArea as AppkitScrollAreaElement, defineCustomElement as defineAppkitScrollArea } from \"@naculus/connect-appkit-wc/dist/components/appkit-scroll-area.js\";\nimport { AppkitSelect as AppkitSelectElement, defineCustomElement as defineAppkitSelect } from \"@naculus/connect-appkit-wc/dist/components/appkit-select.js\";\nimport { AppkitSeparator as AppkitSeparatorElement, defineCustomElement as defineAppkitSeparator } from \"@naculus/connect-appkit-wc/dist/components/appkit-separator.js\";\nimport { AppkitSkeleton as AppkitSkeletonElement, defineCustomElement as defineAppkitSkeleton } from \"@naculus/connect-appkit-wc/dist/components/appkit-skeleton.js\";\nimport { AppkitSwitch as AppkitSwitchElement, defineCustomElement as defineAppkitSwitch } from \"@naculus/connect-appkit-wc/dist/components/appkit-switch.js\";\nimport { AppkitTabs as AppkitTabsElement, defineCustomElement as defineAppkitTabs } from \"@naculus/connect-appkit-wc/dist/components/appkit-tabs.js\";\nimport { AppkitToggleGroup as AppkitToggleGroupElement, defineCustomElement as defineAppkitToggleGroup } from \"@naculus/connect-appkit-wc/dist/components/appkit-toggle-group.js\";\nimport { AppkitTooltip as AppkitTooltipElement, defineCustomElement as defineAppkitTooltip } from \"@naculus/connect-appkit-wc/dist/components/appkit-tooltip.js\";\n\nexport type AppkitAccordionEvents = { onAppkitToggle: EventName<AppkitAccordionCustomEvent<boolean>> };\n\nexport const AppkitAccordion: StencilReactComponent<AppkitAccordionElement, AppkitAccordionEvents, Components.AppkitAccordion> = /*@__PURE__*/ createComponent<AppkitAccordionElement, AppkitAccordionEvents, Components.AppkitAccordion>({\n tagName: 'appkit-accordion',\n elementClass: AppkitAccordionElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitToggle: 'appkitToggle' } as AppkitAccordionEvents,\n defineCustomElement: defineAppkitAccordion\n});\n\nexport type AppkitAccountButtonEvents = NonNullable<unknown>;\n\nexport const AppkitAccountButton: StencilReactComponent<AppkitAccountButtonElement, AppkitAccountButtonEvents, Components.AppkitAccountButton> = /*@__PURE__*/ createComponent<AppkitAccountButtonElement, AppkitAccountButtonEvents, Components.AppkitAccountButton>({\n tagName: 'appkit-account-button',\n elementClass: AppkitAccountButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitAccountButtonEvents,\n defineCustomElement: defineAppkitAccountButton\n});\n\nexport type AppkitAlertDialogEvents = {\n onAppkitClose: EventName<AppkitAlertDialogCustomEvent<void>>,\n onAppkitOpenChange: EventName<AppkitAlertDialogCustomEvent<boolean>>\n};\n\nexport const AppkitAlertDialog: StencilReactComponent<AppkitAlertDialogElement, AppkitAlertDialogEvents, Components.AppkitAlertDialog> = /*@__PURE__*/ createComponent<AppkitAlertDialogElement, AppkitAlertDialogEvents, Components.AppkitAlertDialog>({\n tagName: 'appkit-alert-dialog',\n elementClass: AppkitAlertDialogElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitClose: 'appkitClose',\n onAppkitOpenChange: 'appkitOpenChange'\n } as AppkitAlertDialogEvents,\n defineCustomElement: defineAppkitAlertDialog\n});\n\nexport type AppkitAvatarEvents = NonNullable<unknown>;\n\nexport const AppkitAvatar: StencilReactComponent<AppkitAvatarElement, AppkitAvatarEvents, Components.AppkitAvatar> = /*@__PURE__*/ createComponent<AppkitAvatarElement, AppkitAvatarEvents, Components.AppkitAvatar>({\n tagName: 'appkit-avatar',\n elementClass: AppkitAvatarElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitAvatarEvents,\n defineCustomElement: defineAppkitAvatar\n});\n\nexport type AppkitBadgeEvents = NonNullable<unknown>;\n\nexport const AppkitBadge: StencilReactComponent<AppkitBadgeElement, AppkitBadgeEvents, Components.AppkitBadge> = /*@__PURE__*/ createComponent<AppkitBadgeElement, AppkitBadgeEvents, Components.AppkitBadge>({\n tagName: 'appkit-badge',\n elementClass: AppkitBadgeElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitBadgeEvents,\n defineCustomElement: defineAppkitBadge\n});\n\nexport type AppkitButtonEvents = NonNullable<unknown>;\n\nexport const AppkitButton: StencilReactComponent<AppkitButtonElement, AppkitButtonEvents, Components.AppkitButton> = /*@__PURE__*/ createComponent<AppkitButtonElement, AppkitButtonEvents, Components.AppkitButton>({\n tagName: 'appkit-button',\n elementClass: AppkitButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitButtonEvents,\n defineCustomElement: defineAppkitButton\n});\n\nexport type AppkitCardEvents = NonNullable<unknown>;\n\nexport const AppkitCard: StencilReactComponent<AppkitCardElement, AppkitCardEvents, Components.AppkitCard> = /*@__PURE__*/ createComponent<AppkitCardElement, AppkitCardEvents, Components.AppkitCard>({\n tagName: 'appkit-card',\n elementClass: AppkitCardElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardEvents,\n defineCustomElement: defineAppkitCard\n});\n\nexport type AppkitCardContentEvents = NonNullable<unknown>;\n\nexport const AppkitCardContent: StencilReactComponent<AppkitCardContentElement, AppkitCardContentEvents, Components.AppkitCardContent> = /*@__PURE__*/ createComponent<AppkitCardContentElement, AppkitCardContentEvents, Components.AppkitCardContent>({\n tagName: 'appkit-card-content',\n elementClass: AppkitCardContentElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardContentEvents,\n defineCustomElement: defineAppkitCardContent\n});\n\nexport type AppkitCardDescriptionEvents = NonNullable<unknown>;\n\nexport const AppkitCardDescription: StencilReactComponent<AppkitCardDescriptionElement, AppkitCardDescriptionEvents, Components.AppkitCardDescription> = /*@__PURE__*/ createComponent<AppkitCardDescriptionElement, AppkitCardDescriptionEvents, Components.AppkitCardDescription>({\n tagName: 'appkit-card-description',\n elementClass: AppkitCardDescriptionElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardDescriptionEvents,\n defineCustomElement: defineAppkitCardDescription\n});\n\nexport type AppkitCardFooterEvents = NonNullable<unknown>;\n\nexport const AppkitCardFooter: StencilReactComponent<AppkitCardFooterElement, AppkitCardFooterEvents, Components.AppkitCardFooter> = /*@__PURE__*/ createComponent<AppkitCardFooterElement, AppkitCardFooterEvents, Components.AppkitCardFooter>({\n tagName: 'appkit-card-footer',\n elementClass: AppkitCardFooterElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardFooterEvents,\n defineCustomElement: defineAppkitCardFooter\n});\n\nexport type AppkitCardHeaderEvents = NonNullable<unknown>;\n\nexport const AppkitCardHeader: StencilReactComponent<AppkitCardHeaderElement, AppkitCardHeaderEvents, Components.AppkitCardHeader> = /*@__PURE__*/ createComponent<AppkitCardHeaderElement, AppkitCardHeaderEvents, Components.AppkitCardHeader>({\n tagName: 'appkit-card-header',\n elementClass: AppkitCardHeaderElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardHeaderEvents,\n defineCustomElement: defineAppkitCardHeader\n});\n\nexport type AppkitCardTitleEvents = NonNullable<unknown>;\n\nexport const AppkitCardTitle: StencilReactComponent<AppkitCardTitleElement, AppkitCardTitleEvents, Components.AppkitCardTitle> = /*@__PURE__*/ createComponent<AppkitCardTitleElement, AppkitCardTitleEvents, Components.AppkitCardTitle>({\n tagName: 'appkit-card-title',\n elementClass: AppkitCardTitleElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitCardTitleEvents,\n defineCustomElement: defineAppkitCardTitle\n});\n\nexport type AppkitCheckboxEvents = { onAppkitChange: EventName<AppkitCheckboxCustomEvent<boolean>> };\n\nexport const AppkitCheckbox: StencilReactComponent<AppkitCheckboxElement, AppkitCheckboxEvents, Components.AppkitCheckbox> = /*@__PURE__*/ createComponent<AppkitCheckboxElement, AppkitCheckboxEvents, Components.AppkitCheckbox>({\n tagName: 'appkit-checkbox',\n elementClass: AppkitCheckboxElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitCheckboxEvents,\n defineCustomElement: defineAppkitCheckbox\n});\n\nexport type AppkitCollapsibleEvents = { onAppkitToggle: EventName<AppkitCollapsibleCustomEvent<boolean>> };\n\nexport const AppkitCollapsible: StencilReactComponent<AppkitCollapsibleElement, AppkitCollapsibleEvents, Components.AppkitCollapsible> = /*@__PURE__*/ createComponent<AppkitCollapsibleElement, AppkitCollapsibleEvents, Components.AppkitCollapsible>({\n tagName: 'appkit-collapsible',\n elementClass: AppkitCollapsibleElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitToggle: 'appkitToggle' } as AppkitCollapsibleEvents,\n defineCustomElement: defineAppkitCollapsible\n});\n\nexport type AppkitConnectButtonEvents = {\n onAppkitConnect: EventName<AppkitConnectButtonCustomEvent<{ kind: string; walletId?: string }>>,\n onAppkitDisconnect: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitStartPairing: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitRetry: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitMobileDeepLink: EventName<AppkitConnectButtonCustomEvent<void>>,\n onAppkitCopyAddress: EventName<AppkitConnectButtonCustomEvent<string>>\n};\n\nexport const AppkitConnectButton: StencilReactComponent<AppkitConnectButtonElement, AppkitConnectButtonEvents, Components.AppkitConnectButton> = /*@__PURE__*/ createComponent<AppkitConnectButtonElement, AppkitConnectButtonEvents, Components.AppkitConnectButton>({\n tagName: 'appkit-connect-button',\n elementClass: AppkitConnectButtonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitConnect: 'appkitConnect',\n onAppkitDisconnect: 'appkitDisconnect',\n onAppkitStartPairing: 'appkitStartPairing',\n onAppkitRetry: 'appkitRetry',\n onAppkitMobileDeepLink: 'appkitMobileDeepLink',\n onAppkitCopyAddress: 'appkitCopyAddress'\n } as AppkitConnectButtonEvents,\n defineCustomElement: defineAppkitConnectButton\n});\n\nexport type AppkitDialogEvents = {\n onAppkitClose: EventName<AppkitDialogCustomEvent<void>>,\n onAppkitOpenChange: EventName<AppkitDialogCustomEvent<boolean>>\n};\n\nexport const AppkitDialog: StencilReactComponent<AppkitDialogElement, AppkitDialogEvents, Components.AppkitDialog> = /*@__PURE__*/ createComponent<AppkitDialogElement, AppkitDialogEvents, Components.AppkitDialog>({\n tagName: 'appkit-dialog',\n elementClass: AppkitDialogElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {\n onAppkitClose: 'appkitClose',\n onAppkitOpenChange: 'appkitOpenChange'\n } as AppkitDialogEvents,\n defineCustomElement: defineAppkitDialog\n});\n\nexport type AppkitDropdownMenuEvents = { onAppkitSelect: EventName<AppkitDropdownMenuCustomEvent<string>> };\n\nexport const AppkitDropdownMenu: StencilReactComponent<AppkitDropdownMenuElement, AppkitDropdownMenuEvents, Components.AppkitDropdownMenu> = /*@__PURE__*/ createComponent<AppkitDropdownMenuElement, AppkitDropdownMenuEvents, Components.AppkitDropdownMenu>({\n tagName: 'appkit-dropdown-menu',\n elementClass: AppkitDropdownMenuElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitSelect: 'appkitSelect' } as AppkitDropdownMenuEvents,\n defineCustomElement: defineAppkitDropdownMenu\n});\n\nexport type AppkitInputEvents = { onAppkitChange: EventName<AppkitInputCustomEvent<string>> };\n\nexport const AppkitInput: StencilReactComponent<AppkitInputElement, AppkitInputEvents, Components.AppkitInput> = /*@__PURE__*/ createComponent<AppkitInputElement, AppkitInputEvents, Components.AppkitInput>({\n tagName: 'appkit-input',\n elementClass: AppkitInputElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitInputEvents,\n defineCustomElement: defineAppkitInput\n});\n\nexport type AppkitPopoverEvents = { onAppkitOpenChange: EventName<AppkitPopoverCustomEvent<boolean>> };\n\nexport const AppkitPopover: StencilReactComponent<AppkitPopoverElement, AppkitPopoverEvents, Components.AppkitPopover> = /*@__PURE__*/ createComponent<AppkitPopoverElement, AppkitPopoverEvents, Components.AppkitPopover>({\n tagName: 'appkit-popover',\n elementClass: AppkitPopoverElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitOpenChange: 'appkitOpenChange' } as AppkitPopoverEvents,\n defineCustomElement: defineAppkitPopover\n});\n\nexport type AppkitProgressEvents = NonNullable<unknown>;\n\nexport const AppkitProgress: StencilReactComponent<AppkitProgressElement, AppkitProgressEvents, Components.AppkitProgress> = /*@__PURE__*/ createComponent<AppkitProgressElement, AppkitProgressEvents, Components.AppkitProgress>({\n tagName: 'appkit-progress',\n elementClass: AppkitProgressElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitProgressEvents,\n defineCustomElement: defineAppkitProgress\n});\n\nexport type AppkitScrollAreaEvents = NonNullable<unknown>;\n\nexport const AppkitScrollArea: StencilReactComponent<AppkitScrollAreaElement, AppkitScrollAreaEvents, Components.AppkitScrollArea> = /*@__PURE__*/ createComponent<AppkitScrollAreaElement, AppkitScrollAreaEvents, Components.AppkitScrollArea>({\n tagName: 'appkit-scroll-area',\n elementClass: AppkitScrollAreaElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitScrollAreaEvents,\n defineCustomElement: defineAppkitScrollArea\n});\n\nexport type AppkitSelectEvents = { onAppkitChange: EventName<AppkitSelectCustomEvent<string>> };\n\nexport const AppkitSelect: StencilReactComponent<AppkitSelectElement, AppkitSelectEvents, Components.AppkitSelect> = /*@__PURE__*/ createComponent<AppkitSelectElement, AppkitSelectEvents, Components.AppkitSelect>({\n tagName: 'appkit-select',\n elementClass: AppkitSelectElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitSelectEvents,\n defineCustomElement: defineAppkitSelect\n});\n\nexport type AppkitSeparatorEvents = NonNullable<unknown>;\n\nexport const AppkitSeparator: StencilReactComponent<AppkitSeparatorElement, AppkitSeparatorEvents, Components.AppkitSeparator> = /*@__PURE__*/ createComponent<AppkitSeparatorElement, AppkitSeparatorEvents, Components.AppkitSeparator>({\n tagName: 'appkit-separator',\n elementClass: AppkitSeparatorElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitSeparatorEvents,\n defineCustomElement: defineAppkitSeparator\n});\n\nexport type AppkitSkeletonEvents = NonNullable<unknown>;\n\nexport const AppkitSkeleton: StencilReactComponent<AppkitSkeletonElement, AppkitSkeletonEvents, Components.AppkitSkeleton> = /*@__PURE__*/ createComponent<AppkitSkeletonElement, AppkitSkeletonEvents, Components.AppkitSkeleton>({\n tagName: 'appkit-skeleton',\n elementClass: AppkitSkeletonElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitSkeletonEvents,\n defineCustomElement: defineAppkitSkeleton\n});\n\nexport type AppkitSwitchEvents = { onAppkitChange: EventName<AppkitSwitchCustomEvent<boolean>> };\n\nexport const AppkitSwitch: StencilReactComponent<AppkitSwitchElement, AppkitSwitchEvents, Components.AppkitSwitch> = /*@__PURE__*/ createComponent<AppkitSwitchElement, AppkitSwitchEvents, Components.AppkitSwitch>({\n tagName: 'appkit-switch',\n elementClass: AppkitSwitchElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitSwitchEvents,\n defineCustomElement: defineAppkitSwitch\n});\n\nexport type AppkitTabsEvents = { onAppkitTabChange: EventName<AppkitTabsCustomEvent<string>> };\n\nexport const AppkitTabs: StencilReactComponent<AppkitTabsElement, AppkitTabsEvents, Components.AppkitTabs> = /*@__PURE__*/ createComponent<AppkitTabsElement, AppkitTabsEvents, Components.AppkitTabs>({\n tagName: 'appkit-tabs',\n elementClass: AppkitTabsElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitTabChange: 'appkitTabChange' } as AppkitTabsEvents,\n defineCustomElement: defineAppkitTabs\n});\n\nexport type AppkitToggleGroupEvents = { onAppkitChange: EventName<AppkitToggleGroupCustomEvent<string[]>> };\n\nexport const AppkitToggleGroup: StencilReactComponent<AppkitToggleGroupElement, AppkitToggleGroupEvents, Components.AppkitToggleGroup> = /*@__PURE__*/ createComponent<AppkitToggleGroupElement, AppkitToggleGroupEvents, Components.AppkitToggleGroup>({\n tagName: 'appkit-toggle-group',\n elementClass: AppkitToggleGroupElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: { onAppkitChange: 'appkitChange' } as AppkitToggleGroupEvents,\n defineCustomElement: defineAppkitToggleGroup\n});\n\nexport type AppkitTooltipEvents = NonNullable<unknown>;\n\nexport const AppkitTooltip: StencilReactComponent<AppkitTooltipElement, AppkitTooltipEvents, Components.AppkitTooltip> = /*@__PURE__*/ createComponent<AppkitTooltipElement, AppkitTooltipEvents, Components.AppkitTooltip>({\n tagName: 'appkit-tooltip',\n elementClass: AppkitTooltipElement,\n // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.\n react: React,\n events: {} as AppkitTooltipEvents,\n defineCustomElement: defineAppkitTooltip\n});\n"],"mappings":"AAEA,OAAgB,iBAAAA,GAAe,cAAAC,GAAY,cAAAC,GAAY,aAAAC,GAAW,eAAAC,EAAa,WAAAC,EAAS,UAAAC,OAAc,QCFtG,OAAiC,gCAAAC,OAAoC,mCACrE,OAAS,oBAAAC,MAAwB,kCACjC,OAAS,UAAAC,GAAQ,eAAAC,MAAmB,wBA0DpC,IAAIC,EAAoC,KAEjC,SAASC,GAAaC,EAAkC,CAC7D,GAAIF,EAAgB,OAAOA,EAE3B,IAAMG,EAAYP,GAA6B,CAC7C,UAAWM,EAAO,UAClB,SAAUA,EAAO,QACnB,CAAC,EAEGE,EAAqD,KACrDC,EAAqC,KAErCH,EAAO,iBACPG,EAAe,OAAO,6BAA6B,EAAE,KAAMC,GAAQ,CAEjEF,EADaE,EAAI,sBAAsB,EAEnCN,GAAgBA,EAAe,sBAAsBI,CAAkB,CAC/E,CAAC,EAAE,MAAOG,GAAQ,CAChBT,GAAO,KAAK,eAAgB,2CAA4CS,CAAG,EAC3EH,EAAqB,IACvB,CAAC,GAGH,IAAII,EAAmD,KACnDC,EAAqC,KAErCP,EAAO,iBACPO,EAAe,OAAO,6BAA6B,EAAE,KAAMH,GAAQ,CAEjEE,EADaF,EAAI,wBAAwB,EAErCN,GAAgBA,EAAe,sBAAsBQ,CAAkB,CAC/E,CAAC,EAAE,MAAOD,GAAQ,CAChBT,GAAO,KAAK,eAAgB,oCAAqCS,CAAG,EACpEC,EAAqB,IACvB,CAAC,GAGH,IAAIE,EAA8C,KAC9CC,EAAmC,KAEvC,OAAIT,EAAO,eACPS,EAAa,OAAO,2BAA2B,EAAE,KAAML,GAAa,CAGlE,IAAMM,EAAON,EAAI,gBACbJ,EAAO,oBAAsB,cAAeU,GAC7CA,EAAa,UAAU,CAAE,aAAcV,EAAO,kBAAmB,CAAC,EAErEQ,EAAmBE,EACf,OAAO,OAAW,KAAe,mBAAoBA,GACtDA,EAAa,eAAe,EAE3BZ,GAAgBA,EAAe,oBAAoBU,CAAgB,CAC3E,CAAC,EAAE,MAAOH,GAAQ,CAChBT,GAAO,KAAK,eAAgB,kCAAmCS,CAAG,EAClEG,EAAmB,IACrB,CAAC,GAIC,OAAO,OAAW,KACpBb,EAAiB,eAAe,EAGlCG,EAAiB,CACf,UAAAG,EACA,IAAI,mBAAoB,CAAE,OAAOC,CAAoB,EACrD,IAAI,mBAAoB,CAAE,OAAOI,CAAoB,EACrD,IAAI,iBAAkB,CAAE,OAAOE,CAAkB,EACjD,QAAS,IAAMP,EAAU,QAAQ,EACjC,gBAAiB,MAAOU,GACfhB,EAAiB,QAAQgB,CAAQ,EAE1C,gBAAiB,SAAY,CAE3B,GADIR,GAAc,MAAMA,EACpB,CAACD,EACH,MAAM,IAAI,MAAM,kEAAkE,EAEpF,OAAOA,EAAmB,QAAQ,CACpC,EACA,gBAAiB,SAAY,CAE3B,GADIK,GAAc,MAAMA,EACpB,CAACD,EACH,MAAM,IAAI,MAAM,qEAAqE,EAEvF,OAAOA,EAAmB,QAAQ,CACpC,EACA,aAAc,IAAML,EAAU,aAAa,EAC3C,gBAAiB,IAAMA,EAAU,gBAAgB,EACjD,YAAa,MAAOW,EAASC,IAAU,CACrC,GAAID,EAAQ,IAAI,WAAW,UAAU,EACnC,OAAOjB,EAAiB,YAAYiB,EAAgBC,CAAK,EAE3D,GAAID,EAAQ,aAAe,YAAcN,EACvC,OAAOA,EAAmB,YAAYM,EAAgBC,CAAK,EAE7D,GAAID,EAAQ,aAAe,SAAU,CAEnC,GADIH,GAAY,MAAMA,EAClBD,EACF,OAAQA,EAAyB,YAAYI,EAAgBC,CAAK,EAEpE,MAAM,IAAIhB,EAAY,qBAAsB,yGAAyG,CACvJ,CACA,OAAOI,EAAU,YAAYW,EAASC,CAAK,CAC7C,EACA,gBAAiB,MAAOD,EAASC,IAAU,CACzC,GAAID,EAAQ,IAAI,WAAW,UAAU,EACnC,OAAOjB,EAAiB,gBAAgBiB,EAAgBC,CAAK,EAE/D,GAAID,EAAQ,aAAe,YAAcN,EACvC,OAAOA,EAAmB,gBAAgBM,EAAgBC,CAAK,EAEjE,GAAID,EAAQ,aAAe,SAAU,CAEnC,GADIH,GAAY,MAAMA,EAClBD,EACF,OAAQA,EAAyB,gBAAgBI,EAAgBC,CAAK,EAExE,MAAM,IAAIhB,EAAY,qBAAsB,yGAAyG,CACvJ,CACA,OAAOI,EAAU,gBAAgBW,EAASC,CAAK,CACjD,EACA,UAAW,MAAOD,EAASE,EAAOC,IAAY,CAC5C,GAAIH,EAAQ,IAAI,WAAW,UAAU,EACnC,OAAOjB,EAAiB,UAAWiB,EAAgBE,EAAOC,CAAO,EAEnE,GAAIH,EAAQ,aAAe,YAAcN,EACvC,OAAOA,EAAmB,UAAUM,EAAgBE,EAAOC,CAAO,EAEpE,GAAIH,EAAQ,aAAe,SAAU,CAEnC,GADIH,GAAY,MAAMA,EAClBD,EACF,OAAQA,EAAyB,UAAUI,EAAgBE,EAAOC,CAAO,EAE3E,MAAM,IAAIlB,EAAY,qBAAsB,yGAAyG,CACvJ,CACA,GAAIe,EAAQ,aAAe,YAAcV,GAAsBA,EAAmB,UAChF,OAAOA,EAAmB,UAAUU,EAAgBE,EAAOC,CAAO,EAEpE,GAAI,CAACd,EAAU,UACb,MAAM,IAAIJ,EAAY,qBAAsB,2CAA2C,EAEzF,OAAOI,EAAU,UAAUW,EAASE,EAAOC,CAAO,CACpD,EACA,eAAgB,MAAOH,EAASI,IAAe,CAC7C,GAAIJ,EAAQ,IAAI,WAAW,UAAU,GAAKjB,EAAiB,eACzD,OAAOA,EAAiB,eAAeiB,EAAgBI,CAAU,EAEnE,GAAIJ,EAAQ,aAAe,YAAcN,GAAoB,eAC3D,OAAOA,EAAmB,eAAeM,EAAgBI,CAAU,EAErE,GAAI,CAACf,EAAU,eACb,MAAM,IAAIJ,EAAY,qBAAsB,gDAAgD,EAE9F,OAAOI,EAAU,eAAeW,EAASI,CAAU,CACrD,EACA,UAAW,MAAOJ,GACZA,EAAQ,aAAe,UAClBjB,EAAiB,UAAUiB,CAAO,EAEvCA,EAAQ,aAAe,WACrBV,EACKA,EAAmB,UAAUU,CAAO,EAEtCA,EAELA,EAAQ,aAAe,SAGlBA,EAEFX,EAAU,UAAUW,CAAO,EAEpC,WAAY,MAAOA,GAAY,CAC7B,GAAIA,EAAQ,aAAe,SAAU,CAEnC,GADIH,GAAY,MAAMA,EAClBD,EACF,OAAOA,EAAiB,WAAWI,CAAO,EAE5C,MAAM,IAAIf,EAAY,qBAAsB,yGAAyG,CACvJ,CACA,OAAOI,EAAU,WAAWW,CAAO,CACrC,EACA,iBAAkB,IAAM,CACtB,IAAMK,EAAmC,CAAChB,CAAS,EACnD,OAAIC,GAAoBe,EAAW,KAAKf,CAAkB,EACtDI,GAAoBW,EAAW,KAAKX,CAAkB,EACtDE,GAAkBS,EAAW,KAAKT,CAAgB,EAC/CS,CACT,EACA,sBAAwBP,GAAkC,CAAER,EAAqBQ,CAAM,EACvF,sBAAwBA,GAAgC,CAAEJ,EAAqBI,CAAM,EACrF,oBAAsBA,GAA6B,CAAEF,EAAmBE,CAAM,CAChF,EAEOZ,CACT,CAEO,SAASoB,GAA+B,CAC7C,OAAOpB,CACT,CAEO,SAASqB,IAAoB,CAClCrB,EAAiB,IACnB,CDlQA,OAAS,oBAAAsB,OAAwB,kCACjC,OACE,8BAAAC,GACA,eAAAC,GACA,UAAAC,EAEA,wBAAAC,GAEA,0BAAAC,OACK,wBEdP,OAAS,UAAAC,GAAQ,aAAAC,GAAW,oBAAAC,OAAwB,wBAMpD,IAAMC,GAAiC,CACrC,CACE,GAAI,EACJ,UAAW,SACX,KAAM,SACN,OAAQ,+CACR,YAAa,8BACb,MAAO,KACT,EACA,CACE,GAAI,MACJ,UAAW,SACX,KAAM,SACN,OAAQ,oCACR,YAAa,iCACb,MAAO,OACT,EACA,CACE,GAAI,OACJ,UAAW,SACX,KAAM,kBACN,OAAQ,wCACR,YAAa,6BACb,MAAO,KACT,EACA,CACE,GAAI,IACJ,UAAW,SACX,KAAM,kBACN,OAAQ,6BACR,YAAa,uCACb,MAAO,KACT,CACF,EAMA,SAASC,GAAcC,EAAqC,CAC1D,IAAMC,EAAON,GAAOK,CAAO,EAI3B,GAHI,CAACC,GAGD,CAACA,EAAK,YAAa,OAAO,KAE9B,IAAMC,EAAUD,EAAK,QAErB,MAAO,CACL,GAAID,EACJ,UAAW,SACX,KAAMC,EAAK,KACX,OAAQL,GAAUM,EAASL,GAAiBK,CAAO,GAAK,EAAE,EAC1D,YAAaD,EAAK,YAClB,MAAOA,EAAK,eAAe,MAC7B,CACF,CAEA,SAASE,IAAoC,CAC3C,GAAI,CAACR,GAAQ,MAAO,CAAC,EAErB,IAAMS,EAAgC,CAAC,EAGjCC,EAAW,OAAO,KAAKV,EAAM,EAChC,IAAI,MAAM,EACV,KAAK,CAACW,EAAGC,IAAMD,EAAIC,CAAC,EAEvB,QAAWC,KAAMH,EAAU,CACzB,IAAMI,EAAQV,GAAcS,CAAE,EAC1BC,GACFL,EAAe,KAAKK,CAAK,CAE7B,CAGA,QAAWC,KAAWZ,GACfH,GAAOe,EAAQ,EAAE,GACpBN,EAAe,KAAKM,CAAO,EAI/B,OAAON,CACT,CAEO,IAAMO,GAAoCR,GAAmB,EAI7D,SAASS,GAAaC,EAAuBb,EAA0C,CAC5F,OAAOa,EAAO,KAAMJ,GAAU,CAC5B,IAAMK,EAAiBd,EAAQ,WAAW,SAAS,EAC/C,SACA,KAEJ,GAAI,CAACc,EAAgB,MAAO,GAE5B,IAAMC,EAAWf,EAAQ,SAAS,GAAG,EACjC,SAASA,EAAQ,MAAM,GAAG,EAAE,CAAC,EAAG,EAAE,EAClC,SAASA,EAAS,EAAE,EAExB,OAAOS,EAAM,YAAcK,GAAkBL,EAAM,KAAOM,CAC5D,CAAC,CACH,CAEO,SAASC,IAAkC,CAChD,MAAO,CAAC,GAAGL,EAAkB,CAC/B,CFsZS,cAAAM,OAAA,oBAnfT,SAASC,GAAeC,EAAqBC,EAAYC,EAAgB,YAAyB,CAChG,OAAO,QAAQ,KAAK,CAClBF,EACA,IAAI,QAAW,CAACG,EAAGC,IACjB,WAAW,IAAMA,EAAO,IAAI,MAAM,GAAGF,CAAK,oBAAoBD,CAAE,IAAI,CAAC,EAAGA,CAAE,CAC5E,CACF,CAAC,CACH,CAUA,eAAeI,GAAaC,EAAsBC,EAAmC,CACnF,IAAIC,EACJ,QAASC,EAAU,EAAGA,GAAWF,EAAQ,WAAYE,IACnD,GAAI,CACF,OAAO,MAAMH,EAAG,CAClB,OAASI,EAAO,CAEd,GADAF,EAAYE,EACRD,EAAUF,EAAQ,WAAY,CAChC,IAAMI,EAAQJ,EAAQ,UAAa,GAAKE,EACxCG,EAAO,KAAK,iBAAkB,iBAAiBH,EAAU,CAAC,IAAIF,EAAQ,UAAU,UAAUI,CAAK,IAAI,EACnG,MAAM,IAAI,QAASE,GAAY,WAAWA,EAASF,CAAK,CAAC,CAC3D,CACF,CAEF,MAAMH,CACR,CAiBA,IAAMM,GAA0B,CAC9B,OAAQ,eACR,QAAS,KACT,SAAU,CAAC,EACX,QAAS,KACT,MAAO,IACT,EAEA,SAASC,GAAYC,EAAkBC,EAA+B,CACpE,OAAQA,EAAO,KAAM,CACnB,IAAK,aACH,MAAO,CAAE,GAAGD,EAAO,OAAQC,EAAO,OAAQ,EAC5C,IAAK,cACH,MAAO,CAAE,GAAGD,EAAO,QAASC,EAAO,OAAQ,EAC7C,IAAK,eACH,MAAO,CAAE,GAAGD,EAAO,SAAUC,EAAO,OAAQ,EAC9C,IAAK,YACH,MAAO,CAAE,GAAGD,EAAO,QAASC,EAAO,OAAQ,EAC7C,IAAK,YACH,MAAO,CAAE,GAAGD,EAAO,MAAOC,EAAO,OAAQ,EAC3C,IAAK,QACH,OAAOH,GACT,QACE,OAAOE,CACX,CACF,CAEO,IAAME,GAAcC,GAAuC,IAAI,EAQ/D,SAASC,GAAoB,CAClC,SAAAC,EACA,OAAAC,EACA,YAAAC,EAAc,EAChB,EAA6B,CAC3B,GAAM,CAACP,EAAOQ,CAAQ,EAAIC,GAAWV,GAAaD,EAAY,EAExDY,EAASC,EAAQ,IAAML,EAAO,QAAUM,GAAiB,EAAG,CAACN,EAAO,MAAM,CAAC,EAE3EO,EAAoBP,EAAO,mBAAqB,IAChDQ,EAAaR,EAAO,YAAc,EAElCS,EAAUJ,EACd,IAAM,IAAIK,GAA2BV,EAAO,YAAc,sBAAsB,EAChF,CAACA,EAAO,UAAU,CACpB,EAEMW,EAASN,EAAQ,IACdO,GAAa,CAClB,UAAWZ,EAAO,UAClB,SAAUA,EAAO,SACjB,eAAgBA,EAAO,eACvB,eAAgBA,EAAO,eACvB,aAAcA,EAAO,aACrB,mBAAoBA,EAAO,kBAC7B,CAAC,EACA,CAACA,EAAO,UAAWA,EAAO,SAAUA,EAAO,eAAgBA,EAAO,eAAgBA,EAAO,aAAcA,EAAO,kBAAkB,CAAC,EAI9Ha,EAAoBC,GAA8B,IAAI,EAEtDC,EAAiBV,EAAQ,IAAM,CAEnC,IAAMW,EAAKC,GAAuB,EAClCD,EAAG,SAASL,EAAO,UAAU,GAAIA,EAAO,SAAS,EAGjD,IAAMO,EAAyC,CAAC,EAC1CC,EAAwF,CAAC,EAE/F,QAAWC,KAAShB,EAAQ,CAC1B,IAAMiB,EAAU,GAAGD,EAAM,SAAS,IAAIA,EAAM,EAAE,GAC1CA,EAAM,SACRF,EAAeG,CAAO,EAAID,EAAM,QAE9BA,EAAM,QACRD,EAAkBE,CAAO,EAAI,CAC3B,KAAMD,EAAM,KACZ,OAAQA,EAAM,MACd,SAAU,EACZ,EAEJ,CAEA,IAAME,EAAKC,GAAqBP,EAAI,CAClC,uBAAwB,GACxB,eAAAE,EACA,kBAAAC,EACA,cAAenB,EAAO,aACxB,CAAC,EAED,OAAAa,EAAkB,QAAUS,EACrBA,CACT,EAAG,CAACX,EAAQP,CAAM,CAAC,EAGnBoB,GAAU,IAAM,CACd,IAAMC,EAAeC,GAA6B,CAChD,GAAM,CAAE,cAAAC,CAAc,EAAID,EAAQ,OAClCxB,EAAS,CAAE,KAAM,cAAe,QAASyB,CAAc,CAAC,EAExD,IAAMC,EAAqB,CAAC,EAC5B,OAAO,OAAOD,EAAc,UAAU,EAAE,QAASE,IAAY,CAC3DD,EAAS,KAAK,GAAGC,GAAG,QAAQ,CAC9B,CAAC,EACD3B,EAAS,CAAE,KAAM,eAAgB,QAAS0B,CAAS,CAAC,EACpD1B,EAAS,CAAE,KAAM,YAAa,QAASwB,EAAQ,OAAO,aAAc,CAAC,EACrExB,EAAS,CAAE,KAAM,aAAc,QAAS,WAAY,CAAC,CACvD,EAEM4B,EAAiB,IAAM,CAC3B5B,EAAS,CAAE,KAAM,OAAQ,CAAC,CAC5B,EAEM6B,EAAkBL,GAAoC,CAC1DxB,EAAS,CAAE,KAAM,YAAa,QAASwB,EAAQ,UAAW,CAAC,CAC7D,EAEA,OAAAX,EAAe,GAAG,mBAAoBU,CAAW,EACjDV,EAAe,GAAG,sBAAuBe,CAAc,EACvDf,EAAe,GAAG,eAAgBgB,CAAc,EAEzC,IAAM,CACXhB,EAAe,IAAI,mBAAoBU,CAAW,EAClDV,EAAe,IAAI,sBAAuBe,CAAc,EACxDf,EAAe,IAAI,eAAgBgB,CAAc,CACnD,CACF,EAAG,CAAChB,CAAc,CAAC,EAEnBS,GAAU,IAAM,CACd,IAAMQ,EAAU,IAAM,CACpBvB,EAAQ,MAAM,EACdP,EAAS,CAAE,KAAM,OAAQ,CAAC,CAC5B,EACAS,EAAO,UAAU,gBAAgBqB,CAAO,CAC1C,EAAG,CAACrB,EAAQF,CAAO,CAAC,EAEpB,IAAMwB,EAAyBC,EAAaC,GAAkC,CAG5E,GAFAjC,EAAS,CAAE,KAAM,cAAe,QAASiC,CAAQ,CAAC,EAE9CA,EAAS,CACX,IAAMP,EAAqB,CAAC,EAC5B,OAAO,OAAOO,EAAQ,UAAU,EAAE,QAASN,GAAO,CAChDD,EAAS,KAAK,GAAGC,EAAG,QAAQ,CAC9B,CAAC,EACD3B,EAAS,CAAE,KAAM,eAAgB,QAAS0B,CAAS,CAAC,EAEpD,IAAMQ,EAAWD,EAAQ,WAAW,QAAW,SAAS,CAAC,EACnDE,EAAWF,EAAQ,WAAW,QAAW,SAAS,CAAC,EACnDG,EAAYH,EAAQ,WAAW,MAAS,SAAS,CAAC,EACxDjC,EAAS,CAAE,KAAM,YAAa,QAASkC,GAAYC,GAAYC,GAAa,IAAK,CAAC,CACpF,MACEpC,EAAS,CAAE,KAAM,eAAgB,QAAS,CAAC,CAAE,CAAC,EAC9CA,EAAS,CAAE,KAAM,YAAa,QAAS,IAAK,CAAC,CAEjD,EAAG,CAAC,CAAC,EAMCqC,EAAUL,EAAY,MAAOC,GAA6D,CAC9F,GAAI,CAACnC,EAAO,MAAQ,CAACmC,EAAS,MAAO,GAErCjC,EAAS,CAAE,KAAM,aAAc,QAAS,gBAAiB,CAAC,EAE1D,GAAI,CACF,IAAMsC,EAAWL,EAAQ,WAAW,QAAW,WAAW,CAAC,EACrDM,EAAWN,EAAQ,WAAW,QAAW,WAAW,CAAC,EACrDO,EAAaF,GAAYC,EAC/B,GAAI,CAACC,EAAY,MAAM,IAAIC,GAAY,aAAc,6BAA6B,EAElF,IAAMC,EAAUJ,EACZL,EAAQ,WAAW,OAAU,SAAS,CAAC,GAAK,WAC5CA,EAAQ,WAAW,OAAU,SAAS,CAAC,GAAK,WAE1CU,EAAUH,EAAW,SAAS,GAAG,EAAIA,EAAW,MAAM,GAAG,EAAE,IAAI,EAAKA,EAEpEI,GAAU,MAAM9C,EAAO,KAAK,cAAc,CAAE,QAAA6C,EAAS,QAAAD,CAAQ,CAAC,EAC9DG,GAAa,MAAMpC,EAAO,YAAYwB,EAAS,CACnD,QAAAW,GACA,QAAAD,EACA,QAAAD,CACF,CAAC,EAED,OAAI5C,EAAO,KAAK,oBACd,MAAMA,EAAO,KAAK,mBAAmB,CAAE,QAAA8C,GAAS,UAAAC,EAAU,CAAC,EAGtD,EACT,OAASC,EAAW,CAGlB,OAFA1D,EAAO,MAAM,iBAAkB,8BAA+B0D,CAAS,EAEnEhD,EAAO,KAAK,WAAa,IAC3B,MAAMS,EAAQ,MAAM,EACpBP,EAAS,CAAE,KAAM,OAAQ,CAAC,EAC1BA,EAAS,CACP,KAAM,YACN,QAAS8C,aAAqB,MAAQA,EAAY,IAAI,MAAM,8BAA8B,CAC5F,CAAC,EACM,IAGF,EACT,CACF,EAAG,CAAChD,EAAO,KAAMW,EAAQF,CAAO,CAAC,EAE3BwC,EAAUf,EAAY,SAA2B,CACrDhC,EAAS,CAAE,KAAM,aAAc,QAAS,YAAa,CAAC,EACtDA,EAAS,CAAE,KAAM,YAAa,QAAS,IAAK,CAAC,EAE7C,GAAI,CACF,IAAMiC,EAAU,MAAM1D,GACpBkC,EAAO,QAAQ,EACfJ,EACA,gBACF,EACA,MAAME,EAAQ,KAAK0B,CAAO,EAC1BF,EAAuBE,CAAO,EAG9B,GAAI,CACF,IAAMb,EAAKT,EAAkB,QAC7B,GAAIS,GAAMa,EAAQ,WAAY,CAE5B,IAAMS,EADWT,EAAQ,WAAW,QAAW,SAAS,CAAC,GAC7B,WAE5Bb,EAAG,QAAQa,EAAQ,WAAYS,CAAO,CACxC,CACF,OAASM,EAAS,CAChB5D,EAAO,KAAK,iBAAkB,6BAA8B4D,CAAO,CACrE,CAEA,GAAI,CAAC,MAAMX,EAAQJ,CAAO,EAAG,OAC7BjC,EAAS,CAAE,KAAM,aAAc,QAAS,WAAY,CAAC,CACvD,OAASd,EAAO,CACd,IAAM0D,EAAU1D,aAAiB,MAAQA,EAAM,QAAU,oBACzDc,EAAS,CAAE,KAAM,YAAa,QAASd,aAAiB,MAAQA,EAAQ,IAAI,MAAM0D,CAAO,CAAE,CAAC,EAC5F5C,EAAS,CAAE,KAAM,aAAc,QAAS,cAAe,CAAC,CAC1D,CACF,EAAG,CAACS,EAAQF,EAASwB,EAAwB1B,EAAmBgC,CAAO,CAAC,EAElEY,EAAkBjB,EAAY,SAA2B,CAC7DhC,EAAS,CAAE,KAAM,aAAc,QAAS,YAAa,CAAC,EACtDA,EAAS,CAAE,KAAM,YAAa,QAAS,IAAK,CAAC,EAE7C,GAAI,CACF,IAAMiC,EAAU,MAAMxB,EAAO,gBAAgB,EAG7C,GAFA,MAAMF,EAAQ,KAAK0B,CAAO,EAC1BF,EAAuBE,CAAO,EAC1B,CAAC,MAAMI,EAAQJ,CAAO,EAAG,OAC7BjC,EAAS,CAAE,KAAM,aAAc,QAAS,WAAY,CAAC,CACvD,OAASd,EAAO,CACd,IAAM0D,EAAU1D,aAAiB,MAAQA,EAAM,QAAU,oCACzDc,EAAS,CAAE,KAAM,YAAa,QAASd,aAAiB,MAAQA,EAAQ,IAAI,MAAM0D,CAAO,CAAE,CAAC,EAC5F5C,EAAS,CAAE,KAAM,aAAc,QAAS,cAAe,CAAC,CAC1D,CACF,EAAG,CAACS,EAAQF,EAASwB,EAAwBM,CAAO,CAAC,EAE/Ca,EAAkBlB,EAAY,SAA2B,CAC7DhC,EAAS,CAAE,KAAM,aAAc,QAAS,YAAa,CAAC,EACtDA,EAAS,CAAE,KAAM,YAAa,QAAS,IAAK,CAAC,EAE7C,GAAI,CACF,IAAMiC,EAAU,MAAMxB,EAAO,gBAAgB,EAG7C,GAFA,MAAMF,EAAQ,KAAK0B,CAAO,EAC1BF,EAAuBE,CAAO,EAC1B,CAAC,MAAMI,EAAQJ,CAAO,EAAG,OAC7BjC,EAAS,CAAE,KAAM,aAAc,QAAS,WAAY,CAAC,CACvD,OAASd,EAAO,CACd,IAAM0D,EAAU1D,aAAiB,MAAQA,EAAM,QAAU,6BACzDc,EAAS,CAAE,KAAM,YAAa,QAASd,aAAiB,MAAQA,EAAQ,IAAI,MAAM0D,CAAO,CAAE,CAAC,EAC5F5C,EAAS,CAAE,KAAM,aAAc,QAAS,cAAe,CAAC,CAC1D,CACF,EAAG,CAACS,EAAQF,EAASwB,EAAwBM,CAAO,CAAC,EAE/Cc,EAAanB,EAAY,SAAY,CACzC,GAAI,CAACxC,EAAM,QAAS,CAClBQ,EAAS,CAAE,KAAM,OAAQ,CAAC,EAC1B,MACF,CAEA,GAAI,CACF,MAAMS,EAAO,WAAWjB,EAAM,OAAO,CACvC,OAASN,EAAO,CACdE,EAAO,MAAM,iBAAkB,oBAAqBF,CAAK,CAC3D,CAGA,GAAI,CACF,IAAMkC,EAAKT,EAAkB,QACzBS,GACF,MAAMA,EAAG,WAAW,CAExB,OAAS4B,EAAS,CAChB5D,EAAO,KAAK,iBAAkB,mCAAoC4D,CAAO,CAC3E,CAEA,MAAMzC,EAAQ,MAAM,EACpBP,EAAS,CAAE,KAAM,OAAQ,CAAC,CAC5B,EAAG,CAACS,EAAQjB,EAAM,QAASe,CAAO,CAAC,EAE7B6C,EAAkBpB,EAAY,MAAOqB,GAAqC,CAC9ErD,EAAS,CAAE,KAAM,aAAc,QAAS,YAAa,CAAC,EACtDA,EAAS,CAAE,KAAM,YAAa,QAAS,IAAK,CAAC,EAE7C,GAAI,CACF,IAAMiC,EAAU,MAAM1D,GACpBkC,EAAO,gBAAgB4C,CAAQ,EAC/BhD,EACA,yBACF,EACA,MAAME,EAAQ,KAAK0B,CAAO,EAC1BF,EAAuBE,CAAO,EAG9B,GAAI,CACF,IAAMb,EAAKT,EAAkB,QAC7B,GAAIS,EAAI,CAEN,IAAMsB,EADWT,EAAQ,WAAW,QAAW,SAAS,CAAC,GAC7B,WAC5Bb,EAAG,QAAQ,UAAWsB,CAAO,CAC/B,CACF,OAASM,EAAS,CAChB5D,EAAO,KAAK,iBAAkB,6BAA8B4D,CAAO,CACrE,CAEA,GAAI,CAAC,MAAMX,EAAQJ,CAAO,EAAG,OAC7BjC,EAAS,CAAE,KAAM,aAAc,QAAS,WAAY,CAAC,CACvD,OAASd,EAAO,CACd,IAAM0D,EAAU1D,aAAiB,MAAQA,EAAM,QAAU,oBACzDc,EAAS,CAAE,KAAM,YAAa,QAASd,aAAiB,MAAQA,EAAQ,IAAI,MAAM0D,CAAO,CAAE,CAAC,EAC5F5C,EAAS,CAAE,KAAM,aAAc,QAAS,cAAe,CAAC,CAC1D,CACF,EAAG,CAACS,EAAQF,EAASwB,EAAwB1B,EAAmBgC,CAAO,CAAC,EAElEiB,EAAetB,EAAY,SACxBvB,EAAO,aAAa,EAC1B,CAACA,CAAM,CAAC,EAEL8C,EAAkBvB,EAAY,SAAY,CAC9C,IAAMC,EAAU,MAAMxB,EAAO,gBAAgB,EAG7C,OAFA,MAAMF,EAAQ,KAAK0B,CAAO,EAC1BF,EAAuBE,CAAO,EACzB,MAAMI,EAAQJ,CAAO,GAC1BjC,EAAS,CAAE,KAAM,aAAc,QAAS,WAAY,CAAC,EAC9CiC,CACT,EAAG,CAACxB,EAAQF,EAASwB,EAAwBM,CAAO,CAAC,EAE/CmB,EAAYxB,EAAY,SAAY,CACxC,IAAMyB,EAAe,MAAMlD,EAAQ,KAAK,EACxC,GAAI,CAACkD,EAAc,CACjBzD,EAAS,CAAE,KAAM,aAAc,QAAS,cAAe,CAAC,EACxD,MACF,CAEAA,EAAS,CAAE,KAAM,aAAc,QAAS,cAAe,CAAC,EAExD,GAAI,CACF,IAAMiC,EAAU,MAAMpD,GACpB,IAAM4B,EAAO,UAAUgD,CAAY,EACnC,CAAE,WAAAnD,EAAY,UAAW,IAAM,MAAO,WAAY,CACpD,EACAyB,EAAuBE,CAAO,EAG9B,GAAI,CACF,IAAMb,EAAKT,EAAkB,QACzBS,GACF,MAAMA,EAAG,uBAAuB,CAEpC,OAAS4B,EAAS,CAChB5D,EAAO,KAAK,iBAAkB,gCAAiC4D,CAAO,CACxE,CAEAhD,EAAS,CAAE,KAAM,aAAc,QAAS,WAAY,CAAC,CACvD,OAASd,EAAO,CACdE,EAAO,MAAM,iBAAkB,mBAAoBF,CAAK,EACxD,MAAMqB,EAAQ,MAAM,EACpBP,EAAS,CAAE,KAAM,aAAc,QAAS,cAAe,CAAC,EACxDA,EAAS,CAAE,KAAM,cAAe,QAAS,IAAK,CAAC,CACjD,CACF,EAAG,CAACS,EAAQF,EAASwB,EAAwBzB,CAAU,CAAC,EAElDoD,EAAc1B,EAAY,MAAOU,GAAoB,CACzD,IAAMtB,EAAKT,EAAkB,QAC7B,GAAIS,EAAI,CAEN,MAAMA,EAAG,YAAYsB,CAAO,EAC5B1C,EAAS,CAAE,KAAM,YAAa,QAAS0C,CAAQ,CAAC,EAChD,MACF,CAGA,GAAI,CAAClD,EAAM,QACT,MAAM,IAAI,MAAM,mBAAmB,EAGrC,GAAI,CACEA,EAAM,QAAQ,aAAe,WAAaA,EAAM,QAAQ,IAAI,WAAW,UAAU,EACnF,MAAMmE,GAAiB,YAAYnE,EAAM,QAASkD,CAAO,EAChDlD,EAAM,QAAQ,aAAe,UAAYiB,EAAO,gBACzD,MAAMA,EAAO,gBAAgB,cAAcjB,EAAM,QAASkD,CAAO,EAEjE,MAAMjC,EAAO,UAAU,YAAYjB,EAAM,QAASkD,CAAO,EAE3D1C,EAAS,CAAE,KAAM,YAAa,QAAS0C,CAAQ,CAAC,CAClD,OAASxD,EAAO,CACd,MAAM,IAAIuD,GAAY,oBAAqB,yBAA0BvD,CAAK,CAC5E,CACF,EAAG,CAACuB,EAAQjB,EAAM,OAAO,CAAC,EAE1B8B,GAAU,IAAM,CACVvB,GACFyD,EAAU,CAEd,EAAG,CAACzD,EAAayD,CAAS,CAAC,EAE3B,IAAMI,EAAa5B,EAAY,IAAM,CACnChC,EAAS,CAAE,KAAM,YAAa,QAAS,IAAK,CAAC,CAC/C,EAAG,CAAC,CAAC,EAED6D,EAAQ1D,EACV,KAAO,CACL,GAAGX,EACH,QAAAuD,EACA,gBAAAE,EACA,gBAAAC,EACA,WAAAC,EACA,UAAAK,EACA,YAAAE,EACA,aAAAJ,EACA,gBAAAC,EACA,gBAAAH,EACA,WAAAQ,EACA,YAAapE,EAAM,SAAW,YAC9B,OAAAU,EACA,eAAAW,CACF,GACA,CAACrB,EAAOuD,EAASE,EAAiBC,EAChCC,EAAYK,EAAWE,EACvBJ,EAAcC,EAAiBH,EAAiBQ,EAAY1D,EAAQW,CAAc,CACtF,EAEA,OAAOvC,GAACoB,GAAY,SAAZ,CAAqB,MAAOmE,EAAQ,SAAAhE,EAAS,CACvD,CAEO,SAASiE,GAA4B,CAC1C,IAAMC,EAAUC,GAAWtE,EAAW,EACtC,GAAI,CAACqE,EACH,MAAM,IAAI,MAAM,mDAAmD,EAErE,OAAOA,CACT,CG/gBO,SAASE,IAAY,CAC1B,GAAM,CACJ,OAAAC,EACA,QAAAC,EACA,SAAAC,EACA,QAAAC,EACA,MAAAC,EACA,QAAAC,EACA,WAAAC,EACA,UAAAC,EACA,YAAAC,CACF,EAAIC,EAAQ,EAENC,EAAcV,IAAW,YACzBW,EAAeX,IAAW,aAC1BY,EAAiBZ,IAAW,eAE5Ba,EAAiBX,EAAS,CAAC,GAAK,KAGtC,MAAO,CACL,OAAAF,EACA,QAAAC,EACA,SAAAC,EACA,QAAAC,EACA,MAAAC,EACA,YAAAM,EACA,aAAAC,EACA,eAAAC,EACA,eAXqBZ,IAAW,eAYhC,eAAAa,EACA,QAAAR,EACA,WAAAC,EACA,UAAAC,EACA,YAAAC,CACF,CACF,CCtCA,OAAS,eAAAM,GAAa,YAAAC,OAAgB,QAEtC,OAAS,eAAAC,OAAmB,wBAErB,SAASC,IAAa,CAC3B,GAAM,CAAE,QAAAC,EAAS,OAAAC,CAAO,EAAIC,EAAQ,EAC9B,CAACC,EAAWC,CAAY,EAAIC,GAAS,EAAK,EAC1C,CAACC,EAAOC,CAAQ,EAAIF,GAAuB,IAAI,EAgBrD,MAAO,CACL,QAfoBG,GAAY,SAAY,CAC5CJ,EAAa,EAAI,EACjBG,EAAS,IAAI,EAEb,GAAI,CACF,MAAMP,EAAQ,CAChB,OAASS,EAAK,CACZ,IAAMC,EAAeD,aAAe,MAAQA,EAAI,QAAU,oBAC1DF,EAASE,aAAeX,GAAcW,EAAM,IAAI,MAAMC,CAAY,CAAC,CACrE,QAAE,CACAN,EAAa,EAAK,CACpB,CACF,EAAG,CAACJ,CAAO,CAAC,EAIV,aAAcG,GAAaF,IAAW,aACtC,MAAAK,CACF,CACF,CC5BA,OAAS,eAAAK,GAAa,UAAAC,GAAQ,YAAAC,OAAgB,QAGvC,SAASC,IAAgB,CAC9B,GAAM,CAAE,WAAAC,EAAY,OAAAC,CAAO,EAAIC,EAAQ,EACjC,CAACC,EAAWC,CAAY,EAAIC,GAAS,EAAK,EAC1C,CAACC,EAAOC,CAAQ,EAAIF,GAAuB,IAAI,EAC/CG,EAAaC,GAAO,EAAI,EAkB9B,MAAO,CACL,WAjBuBC,GAAY,SAAY,CAC/C,GAAIT,IAAW,eAEf,CAAAG,EAAa,EAAI,EACjBG,EAAS,IAAI,EAEb,GAAI,CACF,MAAMP,EAAW,CACnB,OAASW,EAAK,CACZ,GAAI,CAACH,EAAW,QAAS,OACzBD,EAASI,aAAe,MAAQA,EAAM,IAAI,MAAM,mBAAmB,CAAC,CACtE,QAAE,CACIH,EAAW,SAASJ,EAAa,EAAK,CAC5C,EACF,EAAG,CAACJ,EAAYC,CAAM,CAAC,EAIrB,gBAAiBE,EACjB,MAAAG,EACA,QAAS,IAAM,CAAEE,EAAW,QAAU,EAAO,CAC/C,CACF,CC/BA,OAAS,WAAAI,OAAe,QAGjB,SAASC,GAAa,CAC3B,GAAM,CAAE,SAAAC,EAAU,QAAAC,EAAS,YAAAC,CAAY,EAAIC,EAAQ,EAE7CC,EAAcC,GAAQ,IACtB,CAACH,GAAeF,EAAS,SAAW,EAC/B,KAGFA,EAAS,IAAKM,GAAY,CAK/B,IAAMC,EAAW,iCAAiC,KAAKD,CAAO,EACxDE,EAAa,sBAAsB,KAAKF,CAAO,EAGrD,MAAO,CACL,QAAAA,EACA,MAJYC,GAAYC,CAK1B,CACF,CAAC,EACA,CAACR,EAAUE,CAAW,CAAC,EAEpBO,EAAaL,GAAa,KAAMM,GAAMA,EAAE,KAAK,GAAG,SAAW,KAEjE,MAAO,CACL,SAAUN,EACV,WAAAK,EACA,eAAgBT,EAAS,CAAC,GAAK,KAC/B,YAAAE,EACA,MAAOF,EAAS,MAClB,CACF,CCpCA,OAAS,WAAAW,OAAe,QAKjB,SAASC,GAAW,CACzB,GAAM,CAAE,QAAAC,EAAS,QAAAC,EAAS,YAAAC,EAAa,OAAAC,CAAO,EAAIC,EAAQ,EAEpDC,EAAeC,GAAQ,IACtBN,EACEO,GAAaJ,EAAQH,CAAO,GAAK,KADnB,KAEpB,CAACA,EAASG,CAAM,CAAC,EAEdK,EAAYF,GAA0B,IAAM,CAChD,GAAI,CAACN,GAAW,CAACC,EAAS,OAAO,KAEjC,IAAMQ,EAAYT,EAAQ,WAAW,SAAS,EAC1C,SACA,KAEJ,GAAI,CAACS,EAAW,OAAO,KAEvB,IAAMC,EAAWV,EAAQ,SAAS,GAAG,EACjC,SAASA,EAAQ,MAAM,GAAG,EAAE,CAAC,EAAG,EAAE,EAClC,SAASA,EAAS,EAAE,EAElBW,EAAQR,EAAO,KAAMS,GAAMA,EAAE,YAAcH,GAAaG,EAAE,KAAOF,CAAQ,EAE/E,MAAO,CACL,UAAAD,EACA,QAAAT,EACA,KAAMW,GAAO,MAAQ,SAASD,CAAQ,GACtC,SAAU,EACZ,CACF,EAAG,CAACV,EAASC,EAASE,CAAM,CAAC,EAEvBU,EAAkBP,GAAuB,IAItCH,EACN,CAACA,CAAM,CAAC,EAEX,MAAO,CACL,QAAAH,EACA,aAAAK,EACA,UAAAG,EACA,gBAAAK,EACA,OAAQA,EACR,MAAOb,GAAS,WAAW,SAAS,EACpC,YAAAE,CACF,CACF,CCpDA,OAAS,YAAAY,GAAU,eAAAC,OAAmB,QAGtC,OAAS,eAAAC,OAAmB,wBAErB,SAASC,IAAiB,CAC/B,GAAM,CAAE,QAAAC,EAAS,QAAAC,CAAQ,EAAIC,EAAQ,EAC/B,CAACC,EAAWC,CAAY,EAAIC,GAAS,EAAK,EAC1C,CAACC,EAAOC,CAAQ,EAAIF,GAAuB,IAAI,EAmDrD,MAAO,CACL,YAlDkBG,GAClB,MAAOC,GAAqC,CAE1C,GAAI,CAACT,EAAS,CACZ,IAAMU,EAAM,IAAIZ,GAAY,qBAAsB,mBAAmB,EACrE,MAAAS,EAASG,CAAG,EACNA,CACR,CAEA,IAAMC,EAASC,EAAU,EACzB,GAAI,CAACD,EAAQ,CACX,IAAMD,EAAM,IAAIZ,GAAY,qBAAsB,wBAAwB,EAC1E,MAAAS,EAASG,CAAG,EACNA,CACR,CAEA,IAAMG,EAAU,OAAO,OAAOb,EAAQ,UAAU,EAC7C,QAASc,GAAOA,EAAG,QAAQ,EAC3B,KAAMC,GAAQA,EAAI,SAAS,IAAI,CAAC,GAAK,OAAO,OAAOf,EAAQ,UAAU,EAAE,CAAC,GAAG,SAAS,CAAC,EAExF,GAAI,CAACa,EAAS,CACZ,IAAMH,EAAM,IAAIZ,GAAY,qBAAsB,kBAAkB,EACpE,MAAAS,EAASG,CAAG,EACNA,CACR,CAEAN,EAAa,EAAI,EACjBG,EAAS,IAAI,EAEb,GAAI,CAOF,OANgB,MAAMI,EAAO,YAAYX,EAAS,CAChD,QAAAS,EACA,QAAAI,EACA,QAASZ,GAAW,MACtB,CAAC,CAGH,OAASS,EAAK,CACZ,IAAMM,EAAeN,aAAe,MAAQA,EAAI,QAAU,iBACpDJ,EAAQI,aAAe,MAAQA,EAAM,IAAI,MAAMM,CAAY,EACjE,MAAAT,EAASD,CAAK,EACRA,CACR,QAAE,CACAF,EAAa,EAAK,CACpB,CACF,EACA,CAACJ,EAASC,CAAO,CACnB,EAIE,UAAWE,EACX,MAAAG,CACF,CACF,CChEA,OAAS,YAAAW,GAAU,eAAAC,OAAmB,QAGtC,OAAS,eAAAC,OAAmB,wBAKrB,SAASC,GAAqB,CACnC,GAAM,CAAE,QAAAC,EAAS,QAAAC,CAAQ,EAAIC,EAAQ,EAC/B,CAACC,EAAQC,CAAS,EAAIC,GAAgC,MAAM,EAC5D,CAACC,EAAOC,CAAQ,EAAIF,GAAuB,IAAI,EAE/CG,EAAkBC,GACtB,MAAOC,GAAiD,CACtD,GAAI,CAACV,EAAS,CACZI,EAAU,QAAQ,EAClB,IAAMO,EAAM,IAAIb,GAAY,qBAAsB,mBAAmB,EACrE,MAAAS,EAASI,CAAG,EACNA,CACR,CAEA,IAAMC,EAASC,EAAU,EACzB,GAAI,CAACD,EAAQ,CACXR,EAAU,QAAQ,EAClB,IAAMO,EAAM,IAAIb,GAAY,qBAAsB,wBAAwB,EAC1E,MAAAS,EAASI,CAAG,EACNA,CACR,CAEA,IAAMG,EAAa,OAAO,OAAOd,EAAQ,UAAU,EAChD,QAASe,GAAOA,EAAG,QAAQ,EAC3B,KAAMC,GAAQA,EAAI,SAAS,IAAI,CAAC,EAEnC,GAAI,CAACF,EAAY,CACfV,EAAU,QAAQ,EAClB,IAAMO,EAAM,IAAIb,GAAY,qBAAsB,sBAAsB,EACxE,MAAAS,EAASI,CAAG,EACNA,CACR,CAEAP,EAAU,mBAAmB,EAC7BG,EAAS,IAAI,EAEb,GAAI,CACF,IAAMU,EAAa,CACjB,GAAGP,EACH,KAAMA,EAAY,MAAQI,EAAW,MAAM,GAAG,EAAE,IAAI,CACtD,EAEMI,EAAU,MAAMN,EAAO,gBAAgBZ,EAAS,CACpD,YAAaiB,EACb,QAAShB,GAAW,MACtB,CAAC,EAED,OAAAG,EAAU,WAAW,EACdc,CACT,OAASP,EAAK,CACZP,EAAU,QAAQ,EAClB,IAAMe,EAAeR,aAAe,MAAQA,EAAI,QAAU,qBAC1D,MAAAJ,EAASI,aAAe,MAAQA,EAAM,IAAI,MAAMQ,CAAY,CAAC,EACvDR,CACR,CACF,EACA,CAACX,EAASC,CAAO,CACnB,EAEMmB,EAAQX,GAAY,IAAM,CAC9BL,EAAU,MAAM,EAChBG,EAAS,IAAI,CACf,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,gBAAAC,EACA,OAAAL,EACA,MAAAG,EACA,MAAAc,EACA,UAAWjB,IAAW,mBACxB,CACF,CC/EA,OAAS,YAAAkB,GAAU,eAAAC,OAAmB,QAGtC,OAAS,eAAAC,MAAmB,wBAKrB,SAASC,IAAe,CAC7B,GAAM,CAAE,QAAAC,EAAS,QAAAC,CAAQ,EAAIC,EAAQ,EAC/B,CAACC,EAAQC,CAAS,EAAIC,GAA0B,MAAM,EACtD,CAACC,EAAOC,CAAQ,EAAIF,GAAuB,IAAI,EAC/C,CAACG,EAAWC,CAAY,EAAIJ,GAAwB,IAAI,EACxD,CAACK,EAAaC,CAAc,EAAIN,GAA6B,IAAI,EAEjEO,EAAYC,GAChB,MAAOC,EAAoBC,IAAoD,CAC7E,GAAI,CAACf,EAAS,CACZI,EAAU,QAAQ,EAClB,IAAMY,EAAM,IAAIlB,EAAY,qBAAsB,mBAAmB,EACrE,MAAAS,EAASS,CAAG,EACNA,CACR,CAEA,IAAMC,EAASC,EAAU,EACzB,GAAI,CAACD,EAAQ,CACXb,EAAU,QAAQ,EAClB,IAAMY,EAAM,IAAIlB,EAAY,qBAAsB,wBAAwB,EAC1E,MAAAS,EAASS,CAAG,EACNA,CACR,CAEA,GAAIF,EAAM,SAAW,EAAG,CACtBV,EAAU,QAAQ,EAClB,IAAMY,EAAM,IAAIlB,EAAY,gBAAiB,+BAA+B,EAC5E,MAAAS,EAASS,CAAG,EACNA,CACR,CAEAZ,EAAU,mBAAmB,EAC7BG,EAAS,IAAI,EACbE,EAAa,IAAI,EAEjB,GAAI,CACF,IAAMU,EAAS,MAAMF,EAAO,UAC1BjB,EACAc,EACAC,GAAS,SAAWd,GAAW,MACjC,EACA,OAAAG,EAAU,WAAW,EACrBK,EAAaU,CAAM,EACZA,CACT,OAASH,EAAK,CACZZ,EAAU,QAAQ,EAClB,IAAMgB,EAAeJ,aAAe,MAAQA,EAAI,QAAU,mBAC1D,MAAAT,EAASS,aAAe,MAAQA,EAAM,IAAI,MAAMI,CAAY,CAAC,EACvDJ,CACR,CACF,EACA,CAAChB,EAASC,CAAO,CACnB,EAEMoB,EAAiBR,GACrB,MAAOS,GAAwC,CAC7C,GAAI,CAACtB,EACH,MAAM,IAAIF,EAAY,qBAAsB,mBAAmB,EAGjE,IAAMmB,EAASC,EAAU,EACzB,GAAI,CAACD,EACH,MAAM,IAAInB,EAAY,qBAAsB,wBAAwB,EAGtE,IAAMyB,EAAaD,GAAQd,EAC3B,GAAI,CAACe,EACH,MAAM,IAAIzB,EAAY,gBAAiB,0BAA0B,EAGnE,IAAMqB,EAAS,MAAMF,EAAO,eAAejB,EAASuB,CAAU,EAC9D,OAAAZ,EAAeQ,CAAM,EACdA,CACT,EACA,CAACnB,EAASQ,CAAS,CACrB,EAEMgB,EAAQX,GAAY,IAAM,CAC9BT,EAAU,MAAM,EAChBG,EAAS,IAAI,EACbE,EAAa,IAAI,EACjBE,EAAe,IAAI,CACrB,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,UAAAC,EACA,eAAAS,EACA,OAAAlB,EACA,MAAAG,EACA,UAAAE,EACA,YAAAE,EACA,MAAAc,EACA,UAAWrB,IAAW,mBACxB,CACF,CCtGA,OAAS,YAAAsB,EAAU,aAAAC,GAAW,eAAAC,GAAa,WAAAC,GAAS,UAAAC,OAAc,QAGlE,OAAS,sBAAAC,GAAoB,QAAAC,GAAM,eAAAC,OAAoD,OACvF,OAAS,0BAAAC,OAA8B,wBAwBhC,SAASC,GAAWC,EAA+C,CACxE,GAAM,CAAE,WAAAC,EAAY,YAAAC,CAAY,EAAIC,EAAW,EACzC,CAAE,QAAAC,EAAS,OAAAC,CAAO,EAAIC,EAAQ,EAC9B,CAACC,EAASC,CAAU,EAAIC,EAAwB,IAAI,EACpD,CAACC,EAAWC,CAAY,EAAIF,EAAS,EAAK,EAC1C,CAACG,EAAOC,CAAQ,EAAIJ,EAAuB,IAAI,EAC/C,CAACK,EAAUC,CAAW,EAAIN,EAAwB,IAAI,EACtDO,EAAkBhB,GAAS,gBAC3BiB,EAAcC,GAA8C,IAAI,EAEhEC,EAAeC,GAAQ,IAAM,CACjC,GAAI,CAAChB,GAAW,CAACC,EAAO,OAAQ,OAAO,KAEvC,IAAMgB,EAAYjB,EAAQ,WAAW,SAAS,EAAI,SAAW,KAC7D,GAAI,CAACiB,EAAW,OAAO,KAEvB,IAAMC,EAAYlB,EAAQ,MAAM,GAAG,EAAE,CAAC,EAChCmB,EAAW,OAAOD,CAAS,EACjC,MAAI,CAAC,OAAO,SAASC,CAAQ,GAAKA,GAAY,EAAU,KACjDlB,EAAO,KAAMmB,GAAMA,EAAE,YAAcH,GAAaG,EAAE,KAAOD,CAAQ,GAAK,IAC/E,EAAG,CAACnB,EAASC,CAAM,CAAC,EAEdoB,EAAcL,GAAQ,IACnBD,GAAc,OAAS,MAC7B,CAACA,CAAY,CAAC,EAEX,CAACO,EAAQC,CAAS,EAAIlB,EAA8B,IAAI,EAE9DmB,GAAU,IAAM,CACd,GAAI,CAACT,GAAc,OAAQ,CACzBQ,EAAU,IAAI,EACd,MACF,CAEA,IAAME,EAAelC,GAAmB,CACtC,UAAWC,GAAKuB,EAAa,MAAM,EACnC,MAAO,CACL,GAAIA,EAAa,GACjB,KAAMA,EAAa,KACnB,eAAgB,CACd,KAAMA,EAAa,OAAS,MAC5B,OAAQA,EAAa,OAAS,MAC9B,SAAU,EACZ,EACA,QAAS,CACP,QAAS,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,EACvC,OAAQ,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,CACxC,CACF,CACF,CAAC,EAED,OAAAQ,EAAUE,CAAY,EAGf,IAAM,CAGb,CACF,EAAG,CAACV,CAAY,CAAC,EAEjB,IAAMW,EAAeC,GAAY,SAAY,CAC3C,GAAI,CAAC9B,GAAc,CAACyB,EAAQ,CAC1BlB,EAAW,IAAI,EACf,MACF,CAEAG,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,GAAI,CAEF,IAAMmB,EADU/B,EAAW,SAAS,GAAG,EAAIA,EAAW,MAAM,GAAG,EAAE,IAAI,EAAKA,EAEpE,CAACgC,EAAeC,CAAK,EAAI,MAAM,QAAQ,IAAI,CAC/CR,EAAO,WAAW,CAAE,QAASM,CAAS,CAAC,EACvC5B,EAAUN,GAAuBM,EAASe,GAAc,MAAM,EAAE,MAAM,IAAM,IAAI,EAAI,QAAQ,QAAQ,IAAI,CAC1G,CAAC,EACDX,EAAWyB,EAAc,SAAS,CAAC,EACnClB,EAAYmB,CAAK,CACnB,OAASC,EAAK,CACZtB,EAASsB,aAAe,MAAQA,EAAM,IAAI,MAAM,yBAAyB,CAAC,EAC1E3B,EAAW,IAAI,EACfO,EAAY,IAAI,CAClB,QAAE,CACAJ,EAAa,EAAK,CACpB,CACF,EAAG,CAACV,EAAYyB,EAAQtB,EAASe,GAAc,MAAM,CAAC,EAGtDS,GAAU,IAAM,CACV1B,GAAeD,GACjB6B,EAAa,CAEjB,EAAG,CAAC5B,EAAaD,EAAY6B,CAAY,CAAC,EAG1CF,GAAU,KACJZ,GAAmBA,EAAkB,GAAKd,GAAeD,IAC3DgB,EAAY,QAAU,YAAYa,EAAcd,CAAe,GAG1D,IAAM,CACPC,EAAY,UACd,cAAcA,EAAY,OAAO,EACjCA,EAAY,QAAU,KAE1B,GACC,CAACD,EAAiBd,EAAaD,EAAY6B,CAAY,CAAC,EAE3D,IAAMM,EAAYhB,GAAQ,IAAM,CAC9B,GAAIb,IAAY,KAAM,OAAO,KAC7B,GAAI,CACF,OAAOV,GAAY,OAAOU,CAAO,CAAC,CACpC,MAAQ,CACN,OAAO,IACT,CACF,EAAG,CAACA,CAAO,CAAC,EAEN8B,EAAWjB,GAAQ,IAAM,CAC7B,GAAIN,IAAa,MAAQsB,IAAc,KAAM,OAAO,KACpD,IAAME,EAAiB,WAAWF,CAAS,EAC3C,GAAI,MAAME,CAAc,EAAG,OAAO,KAClC,IAAMC,EAAWD,EAAiBxB,EAClC,OAAO,IAAI,KAAK,aAAa,QAAS,CACpC,MAAO,WACP,SAAU,MACV,sBAAuB,EACvB,sBAAuB,CACzB,CAAC,EAAE,OAAOyB,CAAQ,CACpB,EAAG,CAACzB,EAAUsB,CAAS,CAAC,EAExB,MAAO,CACL,QAAA7B,EACA,UAAA6B,EACA,OAAQX,EACR,SAAAX,EACA,SAAAuB,EACA,UAAA3B,EACA,MAAAE,EACA,QAASkB,EACT,MAAOX,CACT,CACF,CCzKA,OAAS,YAAAqB,GAAU,aAAAC,GAAW,eAAAC,GAAa,WAAAC,GAAS,UAAAC,OAAc,QAGlE,OACE,sBAAAC,GACA,QAAAC,GACA,eAAAC,OAGK,OA+BA,SAASC,GAAgBC,EAAiC,CAC/D,GAAM,CAAE,WAAAC,EAAY,YAAAC,CAAY,EAAIC,EAAW,EACzC,CAAE,QAAAC,EAAS,OAAAC,CAAO,EAAIC,EAAQ,EAC9B,CAACC,EAAeC,CAAgB,EAAIC,GAA+B,CAAC,CAAC,EACrE,CAACC,EAAWC,CAAY,EAAIF,GAAS,EAAK,EAC1C,CAACG,EAAOC,CAAQ,EAAIJ,GAAuB,IAAI,EAC/C,CAAE,OAAAK,EAAQ,gBAAAC,CAAgB,EAAIf,EAC9BgB,EAAcC,GAA8C,IAAI,EAEhEC,EAAYC,GAChB,IAAML,EAAO,IAAIM,GAAKA,EAAE,QAAQ,YAAY,EAAI,IAAMA,EAAE,SAAW,IAAMA,EAAE,MAAM,EAAE,KAAK,GAAG,EAC3F,CAACN,CAAM,CACT,EAEMO,EAAeF,GAAQ,IAAM,CACjC,GAAI,CAACf,GAAW,CAACC,EAAO,OAAQ,OAAO,KACvC,IAAMiB,EAAYlB,EAAQ,WAAW,SAAS,EAAI,SAAW,KAC7D,GAAI,CAACkB,EAAW,OAAO,KACvB,IAAMC,EAAW,SAASnB,EAAQ,MAAM,GAAG,EAAE,CAAC,EAAG,EAAE,EACnD,OAAOC,EAAO,KAAMmB,GAAMA,EAAE,YAAcF,GAAaE,EAAE,KAAOD,CAAQ,GAAK,IAC/E,EAAG,CAACnB,EAASC,CAAM,CAAC,EAEd,CAACoB,EAAQC,CAAS,EAAIjB,GAA8B,IAAI,EAE9DkB,GAAU,IAAM,CACd,GAAI,CAACN,GAAc,OAAQ,CACzBK,EAAU,IAAI,EACd,MACF,CAEA,IAAME,EAAehC,GAAmB,CACtC,UAAWC,GAAKwB,EAAa,MAAM,EACnC,MAAO,CACL,GAAIA,EAAa,GACjB,KAAMA,EAAa,KACnB,eAAgB,CACd,KAAMA,EAAa,OAAS,MAC5B,OAAQA,EAAa,OAAS,MAC9B,SAAU,EACZ,EACA,QAAS,CACP,QAAS,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,EACvC,OAAQ,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,CACxC,CACF,CACF,CAAC,EAEDK,EAAUE,CAAY,CACxB,EAAG,CAACP,CAAY,CAAC,EAGjB,IAAMQ,EAAW,CACf,CACE,KAAM,YACN,KAAM,WACN,gBAAiB,OACjB,OAAQ,CAAC,CAAE,KAAM,QAAS,KAAM,SAAU,CAAC,EAC3C,QAAS,CAAC,CAAE,KAAM,UAAW,KAAM,SAAU,CAAC,CAChD,CACF,EAEMC,EAAqBC,GAAY,SAAY,CACjD,GAAI,CAAC9B,GAAc,CAACwB,GAAUX,EAAO,SAAW,EAAG,CACjDN,EAAiB,CAAC,CAAC,EACnB,MACF,CAEAG,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMmB,EAAU/B,EAAW,SAAS,GAAG,EAClCA,EAAW,MAAM,GAAG,EAAE,IAAI,EAC1BA,EAiCCgC,GA9BU,MAAM,QAAQ,WAC5BnB,EAAO,IAAI,MAAOoB,GAAU,CAC1B,GAAI,CACF,IAAMC,EAAU,MAAMV,EAAO,aAAa,CACxC,QAASS,EAAM,QACf,IAAKL,EACL,aAAc,YACd,KAAM,CAACG,CAAO,CAChB,CAAC,EACD,MAAO,CACL,QAASE,EAAM,QACf,OAAQA,EAAM,OACd,SAAUA,EAAM,SAChB,KAAMA,EAAM,KACZ,QAASC,EAAQ,SAAS,EAC1B,UAAWrC,GAAYqC,EAASD,EAAM,QAAQ,CAChD,CACF,MAAQ,CACN,MAAO,CACL,QAASA,EAAM,QACf,OAAQA,EAAM,OACd,SAAUA,EAAM,SAChB,KAAMA,EAAM,KACZ,QAAS,KACT,UAAW,IACb,CACF,CACF,CAAC,CACH,GAE+C,IAAKE,GAC9CA,EAAE,SAAW,YACRA,EAAE,MAGJ,CACL,QAAS,GACT,OAAQ,IACR,SAAU,EACV,QAAS,KACT,UAAW,IACb,CACD,EAED5B,EAAiByB,CAAQ,CAC3B,OAASI,EAAK,CACZxB,EAASwB,aAAe,MAAQA,EAAM,IAAI,MAAM,gCAAgC,CAAC,CACnF,QAAE,CACA1B,EAAa,EAAK,CACpB,CACF,EAAG,CAACV,EAAYwB,EAAQP,CAAS,CAAC,EAGlCS,GAAU,IAAM,CACVzB,GAAeD,GAAca,EAAO,OAAS,GAC/CgB,EAAmB,CAEvB,EAAG,CAAC5B,EAAaD,EAAYiB,EAAWY,CAAkB,CAAC,EAG3DH,GAAU,KACJZ,GAAmBA,EAAkB,GAAKb,GAAeD,GAAca,EAAO,OAAS,IACzFE,EAAY,QAAU,YAAYc,EAAoBf,CAAe,GAEhE,IAAM,CACPC,EAAY,UACd,cAAcA,EAAY,OAAO,EACjCA,EAAY,QAAU,KAE1B,GACC,CAACD,EAAiBb,EAAaD,EAAYiB,EAAWY,CAAkB,CAAC,EAG5E,IAAMQ,EAAkBP,GACrBQ,GACQhC,EAAc,KAClBiC,GAAOA,EAAG,QAAQ,YAAY,IAAMD,EAAa,YAAY,CAChE,EAEF,CAAChC,CAAa,CAChB,EAEA,MAAO,CAEL,cAAAA,EACA,UAAAG,EACA,MAAAE,EAEA,QAASkB,EAET,gBAAAQ,EACA,MAAOjB,CACT,CACF,CCjNA,OAAS,YAAAoB,GAAU,eAAAC,GAAa,UAAAC,OAAc,QCA9C,OAAS,WAAAC,OAAe,QACxB,OAAS,sBAAAC,GAAoB,QAAAC,GAAM,sBAAAC,OAAgE,OAK5F,SAASC,GAId,CACA,GAAM,CAAE,WAAAC,EAAY,YAAAC,CAAY,EAAIC,EAAW,EACzC,CAAE,aAAAC,EAAc,OAAAC,CAAO,EAAIC,EAAS,EAEpCC,EAAeC,GAA6B,IAC3CJ,GAAc,OAEZK,GAAmB,CACxB,UAAWC,GAAKN,EAAa,MAAM,EACnC,MAAO,CACL,GAAIA,EAAa,GACjB,KAAMA,EAAa,KACnB,eAAgB,CACd,KAAMA,EAAa,OAAS,MAC5B,OAAQA,EAAa,OAAS,MAC9B,SAAU,EACZ,EACA,QAAS,CACP,QAAS,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,EACvC,OAAQ,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,CACxC,CACF,CACF,CAAC,EAjBiC,KAkBjC,CAACA,CAAY,CAAC,EAEXO,EAAeH,GAA6B,IAAM,CACtD,GAAI,CAACN,GAAe,CAACD,GAAc,CAACG,GAAc,OAAQ,OAAO,KAEjE,IAAMQ,EAAUX,EAAW,SAAS,GAAG,EAAIA,EAAW,MAAM,GAAG,EAAE,IAAI,EAAKA,EAE1E,OAAOY,GAAmB,CACxB,UAAWH,GAAKN,EAAa,MAAM,EACnC,MAAO,CACL,GAAIA,EAAa,GACjB,KAAMA,EAAa,KACnB,eAAgB,CACd,KAAMA,EAAa,OAAS,MAC5B,OAAQA,EAAa,OAAS,MAC9B,SAAU,EACZ,EACA,QAAS,CACP,QAAS,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,EACvC,OAAQ,CAAE,KAAM,CAACA,EAAa,MAAM,CAAE,CACxC,CACF,EACA,QAASQ,CACX,CAAC,CACH,EAAG,CAACV,EAAaD,EAAYG,CAAY,CAAC,EAE1C,MAAO,CACL,aAAAG,EACA,aAAAI,EACA,OAAAN,CACF,CACF,CD1DA,OAAS,eAAAS,GAAa,iBAAAC,GAAe,cAAAC,OAAkB,wBAGvD,OAAS,sBAAAC,OAA0B,OAInC,SAASC,GAAcC,EAAuB,CAC5C,OAAQA,EAAK,SAAS,GAAG,EAAIA,EAAK,MAAM,GAAG,EAAE,IAAI,EAAKA,CACxD,CAEA,SAASC,GAAuBC,EAAaC,EAAqB,CAChE,OAAOL,GAAmB,CACxB,IAAKF,GACL,aAAc,WACd,KAAM,CAACM,EAAIC,CAAM,CACnB,CAAC,CACH,CAiBO,SAASC,GACdC,EACwB,CACxB,GAAM,CAAE,aAAAC,EAAc,aAAAC,CAAa,EAAIC,EAAc,EAC/C,CAAE,WAAAC,EAAY,YAAAC,CAAY,EAAIC,EAAW,EACzC,CAAE,QAAAC,CAAQ,EAAIC,EAAQ,EACtB,CAAE,gBAAAC,EAAiB,UAAAC,EAAW,MAAOC,EAAa,MAAAC,CAAM,EAAIC,EAAmB,EAC/E,CAACC,EAAYC,CAAa,EAAIC,GAAuB,IAAI,EAEzDC,EAAcC,GAA2BlB,EAAQ,MAAM,QAAQ,EAC/DmB,EAAQL,GAAcH,EA8E5B,MAAO,CACL,aA7EmBS,GACnB,MAAOvB,EAAaC,IAA2C,CAI7D,GAHAiB,EAAc,IAAI,EAClBH,EAAM,EAEF,CAACP,GAAe,CAACD,EAAY,CAC/B,IAAMiB,EAAM,IAAI/B,GAAY,qBAAsB,sBAAsB,EACxE,MAAAyB,EAAcM,CAAG,EACXA,CACR,CAEA,GAAI,CAACpB,EAAc,CACjB,IAAMoB,EAAM,IAAI/B,GAAY,qBAAsB,4BAA4B,EAC9E,MAAAyB,EAAcM,CAAG,EACXA,CACR,CAEA,IAAMC,EAAU5B,GAAcU,CAAU,EAGpCmB,EAAWN,EAAY,QACvBM,IAAa,SACfA,EAAW,MAAMtB,EAAa,aAAa,CACzC,QAASD,EAAQ,MAAM,QACvB,IAAKT,GACL,aAAc,UAChB,CAAC,EACD0B,EAAY,QAAUM,GAGxB,IAAMC,EAAYhC,GAAWM,EAAQyB,CAAQ,EACvCE,EAAO7B,GAAuBC,EAAI2B,CAAS,EAEjD,GAAI,CAEF,GAAIjB,GACamB,EAAU,EAOvB,OALe,MAAMjB,EAAgB,CACnC,GAAIT,EAAQ,MAAM,QAClB,KAAAyB,EACA,MAAO,GACT,CAAC,EAML,GAAIvB,EAAc,CAChB,GAAM,CAAE,QAAAyB,CAAQ,EAAI,MAAM1B,EAAa,iBAAiB,CACtD,QAASD,EAAQ,MAAM,QACvB,IAAKT,GACL,aAAc,WACd,KAAM,CAACM,EAAI2B,CAAS,EACpB,QAASF,CACX,CAAC,EAED,OADe,MAAMpB,EAAa,cAAcyB,CAAO,CAEzD,CAQA,OALe,MAAMlB,EAAgB,CACnC,GAAIT,EAAQ,MAAM,QAClB,KAAAyB,EACA,MAAO,GACT,CAAC,CAEH,OAASJ,EAAK,CACZ,IAAMF,EAAQE,aAAe,MAAQA,EAAM,IAAI,MAAM,iBAAiB,EACtE,MAAAN,EAAcI,CAAK,EACbA,CACR,CACF,EACA,CAACnB,EAAQ,MAAOC,EAAcC,EAAcE,EAAYC,EAAaE,EAASE,EAAiBG,CAAK,CACtG,EAIE,UAAAF,EACA,MAAAS,CACF,CACF,CErIA,OAAS,YAAAS,GAAU,eAAAC,GAAa,UAAAC,OAAc,QAM9C,OAAS,eAAAC,GAAa,iBAAAC,GAAe,cAAAC,OAAkB,wBAGvD,OAAS,sBAAAC,OAA0B,OAInC,SAASC,GAAcC,EAAuB,CAC5C,OAAQA,EAAK,SAAS,GAAG,EAAIA,EAAK,MAAM,GAAG,EAAE,IAAI,EAAKA,CACxD,CAEA,SAASC,GAAsBC,EAAkBC,EAAqB,CACpE,OAAOL,GAAmB,CACxB,IAAKF,GACL,aAAc,UACd,KAAM,CAACM,EAASC,CAAM,CACxB,CAAC,CACH,CAIA,IAAMC,GAAc,IAAM,KAAO,GA4B1B,SAASC,GACdC,EACuB,CACvB,GAAM,CAAE,aAAAC,EAAc,aAAAC,CAAa,EAAIC,EAAc,EAC/C,CAAE,WAAAC,EAAY,YAAAC,CAAY,EAAIC,EAAW,EACzC,CAAE,QAAAC,CAAQ,EAAIC,EAAQ,EACtB,CAAE,gBAAAC,EAAiB,UAAAC,EAAW,MAAOC,EAAa,MAAAC,CAAM,EAAIC,EAAmB,EAC/E,CAACC,EAAYC,CAAa,EAAIC,GAAuB,IAAI,EACzD,CAACC,EAAcC,CAAe,EAAIF,GAAwB,IAAI,EAC9D,CAACG,EAAqBC,CAAsB,EAAIJ,GAAS,EAAK,EAE9DK,EAAcC,GAA2BtB,EAAQ,MAAM,QAAQ,EAC/DuB,EAAQT,GAAcH,EAEtBa,EACCpB,EACEX,GAAcW,CAAU,EADP,KAIpBqB,EAAiBC,GAAY,SAAY,CAC7C,GAAI,GAACzB,GAAgB,CAACuB,GAEtB,CAAAJ,EAAuB,EAAI,EAC3B,GAAI,CACF,IAAMO,EAAM,MAAM1B,EAAa,aAAa,CAC1C,QAASD,EAAQ,MAAM,QACvB,IAAKV,GACL,aAAc,YACd,KAAM,CAACkC,EAAcxB,EAAQ,OAAO,CACtC,CAAC,EACDkB,EAAgBS,CAAa,CAC/B,MAAQ,CACNT,EAAgB,IAAI,CACtB,QAAE,CACAE,EAAuB,EAAK,CAC9B,EACF,EAAG,CAACnB,EAAcuB,EAAcxB,EAAQ,MAAM,QAASA,EAAQ,OAAO,CAAC,EAEjE4B,GAAa,IAAM,CACvB,GAAIX,IAAiB,KAAM,OAAO,KAClC,IAAMY,EAAWR,EAAY,SAAWrB,EAAQ,MAAM,UAAY,GAE5D8B,EADMb,EAAa,SAAS,EACf,SAASY,EAAW,EAAG,GAAG,EACvCE,EAASD,EAAO,OAASD,EAC3BG,EAAUF,EAAO,MAAM,EAAGC,CAAM,EAAE,QAAQ,MAAO,EAAE,GAAK,IACxDE,EAAWH,EAAO,MAAMC,CAAM,EAAE,QAAQ,MAAO,EAAE,EACrD,OAAOE,EAAW,GAAGD,CAAO,IAAIC,CAAQ,GAAKD,CAC/C,GAAG,EAEGE,EAAYR,GAChB,MAAOS,GAA8C,CAInD,GAHApB,EAAc,IAAI,EAClBH,EAAM,EAEF,CAACP,GAAe,CAACD,EAAY,CAC/B,IAAMgC,EAAM,IAAI/C,GAAY,qBAAsB,sBAAsB,EACxE,MAAA0B,EAAcqB,CAAG,EACXA,CACR,CAEA,GAAI,CAACnC,EAAc,CACjB,IAAMmC,EAAM,IAAI/C,GAAY,qBAAsB,kBAAkB,EACpE,MAAA0B,EAAcqB,CAAG,EACXA,CACR,CAEA,IAAMC,EAAO1C,GAAsBK,EAAQ,QAASmC,CAAS,EAE7D,GAAI,CACF,GAAI5B,GACa+B,EAAU,EACb,CACV,IAAMC,EAAS,MAAM9B,EAAgB,CACnC,GAAIT,EAAQ,MAAM,QAClB,KAAAqC,EACA,MAAO,GACT,CAAC,EACD,OAAAZ,EAAe,EACRc,CACT,CAGF,GAAIrC,EAAc,CAChB,GAAM,CAAE,QAAAsC,CAAQ,EAAI,MAAMvC,EAAa,iBAAiB,CACtD,QAASD,EAAQ,MAAM,QACvB,IAAKV,GACL,aAAc,UACd,KAAM,CAACU,EAAQ,QAASmC,CAAS,EACjC,QAASX,CACX,CAAC,EACKe,EAAS,MAAMrC,EAAa,cAAcsC,CAAO,EACvD,OAAAf,EAAe,EACRc,CACT,CAEA,IAAMA,EAAS,MAAM9B,EAAgB,CACnC,GAAIT,EAAQ,MAAM,QAClB,KAAAqC,EACA,MAAO,GACT,CAAC,EACD,OAAAZ,EAAe,EACRc,CACT,OAASH,EAAK,CACZ,IAAMb,EAAQa,aAAe,MAAQA,EAAM,IAAI,MAAM,gBAAgB,EACrE,MAAArB,EAAcQ,CAAK,EACbA,CACR,CACF,EACA,CAACvB,EAASC,EAAcC,EAAcE,EAAYC,EAAaE,EAASiB,EAAcf,EAAiBG,EAAOa,CAAc,CAC9H,EAEMgB,EAAgBf,GACpB,MAAO7B,GAA2C,CAChD,GAAI,CAACI,EAAc,MAAM,IAAIZ,GAAY,qBAAsB,kBAAkB,EAEjF,IAAIwC,EAAWR,EAAY,QACvBQ,IAAa,SACfA,EAAW,MAAM5B,EAAa,aAAa,CACzC,QAASD,EAAQ,MAAM,QACvB,IAAKV,GACL,aAAc,UAChB,CAAC,EACD+B,EAAY,QAAUQ,GAGxB,IAAMM,EAAY5C,GAAWM,EAAQgC,CAAQ,EAC7C,OAAOK,EAAUC,CAAS,CAC5B,EACA,CAACnC,EAAQ,MAAM,QAASC,EAAciC,CAAS,CACjD,EAEMQ,EAAmBhB,GAAY,SAC5BQ,EAAUpC,EAAW,EAC3B,CAACoC,CAAS,CAAC,EAERS,EAAiBjB,GACrB,MAAOkB,GAAuC,CAI5C,GAHI3B,IAAiB,MACnB,MAAMQ,EAAe,EAEnBR,IAAiB,KAAM,MAAO,GAElC,IAAIY,EAAWR,EAAY,SAAWrB,EAAQ,MAAM,SAChD6B,IAAa,SACfA,EAAW,IAGb,IAAMgB,EAActD,GAAWqD,EAAUf,CAAQ,EACjD,OAAOZ,GAAgB4B,CACzB,EACA,CAAC5B,EAAcQ,EAAgBzB,EAAQ,MAAM,QAAQ,CACvD,EAEA,MAAO,CACL,QAASyC,EACT,WAAYC,EACZ,UAAAd,EACA,aAAAX,EACA,aAAc0B,EACd,YAAajC,EACb,oBAAAS,EACA,MAAAI,EACA,iBAAkBE,CACpB,CACF,CC3NA,OAAS,YAAAqB,GAAU,eAAAC,GAAa,aAAAC,GAAW,UAAAC,GAAQ,WAAAC,OAAe,QAElE,OAAS,iBAAAC,OAAqB,wBAuBvB,SAASC,GACdC,EACyB,CACzB,GAAM,CAAE,aAAAC,CAAa,EAAIC,EAAc,EACjC,CAACC,EAAcC,CAAe,EAAIC,GAAwB,IAAI,EAC9D,CAACC,EAAYC,CAAa,EAAIF,GAAS,EAAK,EAC5C,CAACG,EAAOC,CAAQ,EAAIJ,GAAuB,IAAI,EAC/CK,EAAcC,GAA8C,IAAI,EAEhEC,EAAiBC,GAAY,SAAY,CAC7C,GAAKZ,EAEL,CAAAM,EAAc,EAAI,EAClBE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMK,EAAM,MAAMb,EAAa,aAAa,CAC1C,QAASD,EAAQ,MAAM,QACvB,IAAKF,GACL,aAAc,YACd,KAAM,CAACE,EAAQ,MAAOA,EAAQ,OAAO,CACvC,CAAC,EACDI,EAAgBU,CAAa,CAC/B,OAASC,EAAK,CACZN,EAASM,aAAe,MAAQA,EAAM,IAAI,MAAM,2BAA2B,CAAC,EAC5EX,EAAgB,IAAI,CACtB,QAAE,CACAG,EAAc,EAAK,CACrB,EACF,EAAG,CAACN,EAAcD,EAAQ,MAAM,QAASA,EAAQ,MAAOA,EAAQ,OAAO,CAAC,EAGxE,OAAAgB,GAAU,IAAM,CACdJ,EAAe,EAAE,MAAOK,GAAM,QAAQ,KAAK,2CAA4CA,CAAC,CAAC,CAC3F,EAAG,CAACL,CAAc,CAAC,EAGnBI,GAAU,KACJhB,EAAQ,iBAAmBA,EAAQ,gBAAkB,IACvDU,EAAY,QAAU,YAAYE,EAAgBZ,EAAQ,eAAe,GAEpE,IAAM,CACPU,EAAY,UACd,cAAcA,EAAY,OAAO,EACjCA,EAAY,QAAU,KAE1B,GACC,CAACV,EAAQ,gBAAiBY,CAAc,CAAC,EAarC,CACL,UAZgBM,GAAQ,IAAM,CAC9B,GAAIf,IAAiB,KAAM,OAAO,KAClC,IAAMgB,EAAWnB,EAAQ,MAAM,UAAY,GAErCoB,EADMjB,EAAa,SAAS,EACf,SAASgB,EAAW,EAAG,GAAG,EACvCE,EAASD,EAAO,OAASD,EAC3BG,EAAUF,EAAO,MAAM,EAAGC,CAAM,EAAE,QAAQ,MAAO,EAAE,GAAK,IACxDE,EAAWH,EAAO,MAAMC,CAAM,EAAE,QAAQ,MAAO,EAAE,EACrD,OAAOE,EAAW,GAAGD,CAAO,IAAIC,CAAQ,GAAKD,CAC/C,EAAG,CAACnB,EAAcH,EAAQ,MAAM,QAAQ,CAAC,EAIvC,aAAAG,EACA,WAAAG,EACA,MAAAE,EACA,QAASI,CACX,CACF,CC5FA,OAAS,eAAAY,GAAa,UAAAC,GAAQ,YAAAC,OAAgB,QAI9C,OAAS,eAAAC,OAAmB,wBA4BrB,SAASC,IAA6C,CAC3D,GAAM,CAAE,gBAAiBC,CAAwB,EAAIC,EAAQ,EACvD,CAACC,EAAQC,CAAS,EAAIC,GAA4B,IAAI,EACtDC,EAAgBC,GAAsB,IAAI,EAC1C,CAACC,EAAeC,CAAgB,EAAIJ,GAAS,EAAK,EAClD,CAACK,EAAQC,CAAS,EAAIN,GAAS,EAAK,EACpC,CAACO,EAAOC,CAAQ,EAAIR,GAAuB,IAAI,EAE/CS,EAAa,IAAMD,EAAS,IAAI,EAGhCE,EAAgBC,GAAY,IAAM,CACtC,IAAMC,EAASX,EAAc,QAC7B,OAAAA,EAAc,QAAU,KACjBW,CACT,EAAG,CAAC,CAAC,EAECC,EAAuB,IAAM,CACjC,IAAMC,EAASC,EAAU,EACzB,GAAI,CAACD,GAAQ,kBACX,MAAM,IAAIpB,GAAY,qBAAsB,8BAA8B,EAE5E,OAAOoB,EAAO,iBAChB,EAEME,EAAwB,SAAY,CACxCV,EAAU,EAAI,EACdE,EAAS,IAAI,EACb,GAAI,CACF,IAAMS,EAAYJ,EAAqB,EACjCK,EAAS,MAAMD,EAAU,KAAK,EAC9BE,EAAIF,EAAU,UAAU,EAC1BC,GAAUC,IACZpB,EAAUoB,CAAC,EACXlB,EAAc,QAAUkB,EAAE,UAAY,KACtCf,EAAiB,CAACe,EAAE,QAAQ,GAE9B,MAAMvB,EAAwB,EAC9B,IAAMwB,EAAKH,EAAU,UAAU,EAC3BG,IACFrB,EAAUqB,CAAE,EACRA,EAAG,UAAY,CAACF,IAClBjB,EAAc,QAAUmB,EAAG,SAC3BhB,EAAiB,EAAI,GAG3B,OAASiB,EAAK,CACZb,EAASa,aAAe,MAAQA,EAAM,IAAI,MAAM,mCAAmC,CAAC,CACtF,QAAE,CACAf,EAAU,EAAK,CACjB,CACF,EAEMgB,EAAuB,SAAwC,CACnEhB,EAAU,EAAI,EACdE,EAAS,IAAI,EACb,GAAI,CAEF,IAAMW,EAAI,MADQN,EAAqB,EACb,eAAe,EACzC,OAAAd,EAAUoB,CAAC,EACXlB,EAAc,QAAUkB,EAAE,SAC1Bf,EAAiB,EAAI,EACde,CACT,OAASE,EAAK,CACZ,OAAAb,EAASa,aAAe,MAAQA,EAAM,IAAI,MAAM,2BAA2B,CAAC,EACrE,IACT,QAAE,CACAf,EAAU,EAAK,CACjB,CACF,EAEMiB,EAA2B,MAAOC,GAAiD,CACvFlB,EAAU,EAAI,EACdE,EAAS,IAAI,EACb,GAAI,CAEF,IAAMW,EAAI,MADQN,EAAqB,EACb,mBAAmBW,CAAQ,EACrD,OAAAzB,EAAUoB,CAAC,EACXlB,EAAc,QAAU,KACxBG,EAAiB,EAAK,EACfe,CACT,OAASE,EAAK,CACZ,OAAAb,EAASa,aAAe,MAAQA,EAAM,IAAI,MAAM,yBAAyB,CAAC,EACnE,IACT,QAAE,CACAf,EAAU,EAAK,CACjB,CACF,EAEMmB,EAA6B,MAAOC,GAAkD,CAC1FpB,EAAU,EAAI,EACdE,EAAS,IAAI,EACb,GAAI,CAEF,IAAMW,EAAI,MADQN,EAAqB,EACb,qBAAqBa,CAAE,EACjD,OAAA3B,EAAUoB,CAAC,EACXlB,EAAc,QAAU,KACxBG,EAAiB,EAAK,EACfe,CACT,OAASE,EAAK,CACZ,OAAAb,EAASa,aAAe,MAAQA,EAAM,IAAI,MAAM,yBAAyB,CAAC,EACnE,IACT,QAAE,CACAf,EAAU,EAAK,CACjB,CACF,EAEMqB,EAAa,IAAM,CACvB,GAAI,CACgBd,EAAqB,EAC7B,KAAK,EACfd,EAAU,IAAI,EACdE,EAAc,QAAU,KACxBG,EAAiB,EAAK,CACxB,OAASiB,EAAK,CACZb,EAASa,aAAe,MAAQA,EAAM,IAAI,MAAM,uBAAuB,CAAC,CAC1E,CACF,EAEMO,EAAsB,IAAM,CAChC3B,EAAc,QAAU,KACxBG,EAAiB,EAAK,CACxB,EAEA,MAAO,CACL,gBAAiBY,EACjB,eAAgBM,EAChB,mBAAoBC,EACpB,qBAAsBE,EACtB,KAAME,EACN,OAAA7B,EACA,UAAWA,IAAW,KACtB,QAASA,GAAQ,SAAW,KAC5B,WAAYG,EAAc,QAC1B,cAAAS,EACA,cAAAP,EACA,cAAeyB,EACf,OAAAvB,EACA,MAAAE,EACA,WAAAE,EACA,sBAAuB,IAAM,CAC3B,GAAI,CACF,OAAOI,EAAqB,EAAE,0BAA0B,GAAK,CAC/D,MAAQ,CACN,MAAO,EACT,CACF,GAAG,CACL,CACF,CC3KA,OAAS,WAAAgB,OAAe,QCAxB,IAAMC,GAAK,CAET,yBAA0B,4BAC1B,wBAAyB,wLACzB,wBAAyB,2BACzB,uBAAwB,wJAGxB,gBAAiB,mBACjB,yBAA0B,sDAC1B,uBAAwB,qEACxB,uBAAwB,8EAGxB,iBAAkB,iBAClB,oBAAqB,aACrB,oBAAqB,gBACrB,sBAAuB,eACvB,gBAAiB,UACjB,0BAA2B,mBAC3B,eAAgB,QAChB,2BAA4B,oBAC5B,iBAAkB,4BAGlB,oBAAqB,gBACrB,kBAAmB,gBACnB,uBAAwB,2BACxB,0BAA2B,yEAC3B,uBAAwB,4BACxB,gBAAiB,gBACjB,wBAAyB,sCAC3B,EAEMC,GAAsC,CAC1C,yBAA0B,mDAC1B,wBAAyB,4RACzB,wBAAyB,uCACzB,uBAAwB,8PAExB,gBAAiB,2BACjB,yBAA0B,wHAC1B,uBAAwB,mFACxB,uBAAwB,qGAExB,iBAAkB,2BAClB,oBAAqB,2BACrB,oBAAqB,wBACrB,sBAAuB,2BACvB,gBAAiB,2BACjB,0BAA2B,uCAC3B,eAAgB,eAChB,2BAA4B,2BAC5B,iBAAkB,4CAElB,oBAAqB,2BACrB,kBAAmB,2BACnB,uBAAwB,iCACxB,0BAA2B,+JAC3B,uBAAwB,6CACxB,gBAAiB,2BACjB,wBAAyB,4FAC3B,EAEMC,GAAU,CAAE,GAAAF,GAAI,GAAAC,EAAG,EAErBE,GAAwB,KAErB,SAASC,GAAUC,EAAsB,CAC9CF,GAAgBE,CAClB,CAEO,SAASC,IAAoB,CAClC,OAAOH,EACT,CAEO,SAASI,EAAEC,EAA8B,CAC9C,OAAON,GAAQC,EAAa,EAAEK,CAAG,GAAKN,GAAQ,GAAGM,CAAG,GAAKA,CAC3D,CDzEA,IAAMC,GAAe,6CACfC,GAAiB,IAAI,IAAI,CAC7BD,GACA,6CACA,6CACA,4CACF,CAAC,EAED,SAASE,GAAcC,EAAuB,CAC5C,IAAMC,EAAQD,EAAK,YAAY,EAC/B,OAAIF,GAAe,IAAIG,CAAK,EAAU,GAC/BA,EAAM,SAAS,MAAM,GAAKA,EAAM,QAAU,EACnD,CAEA,SAASC,GAAcF,EAAuB,CAC5C,OAAOA,IAASH,EAClB,CAEA,SAASM,GAAcH,EAAuB,CAC5C,MAAO,sBAAsB,KAAKA,CAAI,CACxC,CAUO,SAASI,GAAoBC,EAA0C,CAC5E,OAAKA,EAGAF,GAAcE,CAAO,EAGtBH,GAAcG,CAAO,EAChB,CAAE,QAAS,GAAO,MAAO,UAAW,QAASC,EAAE,sBAAsB,CAAE,EAE5EP,GAAcM,CAAO,EAChB,CAAE,QAAS,GAAO,MAAO,UAAW,QAASC,EAAE,sBAAsB,CAAE,EAEzE,CAAE,QAAS,GAAM,MAAO,OAAQ,QAAS,IAAK,EAR5C,CAAE,QAAS,GAAO,MAAO,UAAW,QAASA,EAAE,wBAAwB,CAAE,EAHzE,CAAE,QAAS,GAAO,MAAO,UAAW,QAASA,EAAE,eAAe,CAAE,CAY3E,CAUO,SAASC,GAAuB,CAAE,QAAAF,CAAQ,EAAgE,CAE/G,MAAO,CAAE,WADUG,GAAQ,IAAMJ,GAAoBC,CAAO,EAAG,CAACA,CAAO,CAAC,CACpD,CACtB,CEvEA,OAAS,YAAAI,GAAU,eAAAC,OAAmB,QAGtC,OAAS,eAAAC,OAAmB,wBAC5B,OACE,qBAAAC,GACA,iBAAAC,GACA,UAAAC,GACA,qBAAAC,OAEK,gBAoBP,SAASC,IAA2B,CAClC,OAAI,OAAO,OAAW,IAAoB,OAAO,SAAS,KACnD,WACT,CAEA,SAASC,IAAwB,CAC/B,OAAI,OAAO,OAAW,IAAoB,OAAO,SAAS,OACnD,kBACT,CAEO,SAASC,IAAuC,CACrD,GAAM,CAAE,QAAAC,EAAS,QAASC,CAAe,EAAIC,EAAQ,EAC/C,CAACC,EAAaC,CAAc,EAAIC,GAAS,EAAK,EAC9C,CAACC,EAAQC,CAAS,EAAIF,GAA4B,IAAI,EACtD,CAACG,EAAOC,CAAQ,EAAIJ,GAAuB,IAAI,EAE/CK,EAAaC,GAAY,IAAMF,EAAS,IAAI,EAAG,CAAC,CAAC,EA6FvD,MAAO,CAAE,OA3FME,GACb,MAAOC,GAAyD,CAC9D,GAAI,CAACZ,EACH,MAAM,IAAIR,GAAY,qBAAsB,mBAAmB,EAGjE,IAAMqB,EAASC,EAAU,EACzB,GAAI,CAACD,EACH,MAAM,IAAIrB,GAAY,qBAAsB,wBAAwB,EAGtE,IAAMuB,EAAc,OAAO,QAAQf,EAAQ,UAAU,EAAE,QACrD,CAAC,CAACgB,EAAIC,CAAI,IACRA,EAAK,SAAS,IAAKC,IAAiB,CAAE,GAAAF,EAAI,IAAAE,CAAI,EAAE,CACpD,EAEA,GAAIH,EAAY,SAAW,EACzB,MAAM,IAAIvB,GAAY,qBAAsB,kBAAkB,EAGhE,GAAM,CAAE,IAAK2B,CAAQ,EAAIJ,EAAY,CAAC,EAChCK,EAAUR,GAAS,SAAWX,GAAkB,WAChDoB,EAAST,GAAS,QAAUf,GAAiB,EAC7CyB,EAAMV,GAAS,KAAOd,GAAc,EACpCyB,EAAQ7B,GAAc,EACtB8B,EAAW7B,GAAO,EAElB8B,EAAUhC,GAAkB,CAChC,OAAA4B,EACA,QAAAF,EACA,IAAAG,EACA,QAAS,EACT,QAAAF,EACA,MAAAG,EACA,SAAAC,EACA,UAAWZ,GAAS,UACpB,eAAgBA,GAAS,cACrB,IAAI,KAAK,KAAK,IAAI,EAAIA,EAAQ,cAAgB,GAAI,EAAE,YAAY,EAChE,OACJ,UAAWA,GAAS,UACpB,UAAWA,GAAS,SACtB,CAAC,EAEDR,EAAe,EAAI,EACnBK,EAAS,IAAI,EAEb,GAAI,CACF,IAAMiB,EAAa,MAAMb,EAAO,YAAYb,EAAS,CACnD,QAAAyB,EACA,QAAAN,EACA,QAASC,GAAW,MACtB,CAAC,EAEKO,EAAiBf,GAAS,cAC5B,IAAI,KAAK,KAAK,IAAI,EAAIA,EAAQ,cAAgB,GAAI,EAAE,YAAY,EAChE,KAEEgB,EAAyB,CAC7B,QAAS,CACP,IAAKH,EACL,OAAAJ,EACA,QAAAF,EACA,UAAWP,GAAS,WAAa,KACjC,IAAAU,EACA,QAAS,EACT,QAAAF,EACA,MAAAG,EACA,SAAAC,EACA,WAAY5B,GAAkBwB,CAAO,EACrC,eAAAO,EACA,UAAW,KACX,UAAWf,GAAS,WAAa,CAAC,EAClC,UAAWA,GAAS,WAAa,IACnC,EACA,UAAAc,CACF,EAEA,OAAAnB,EAAUqB,CAAU,EACbA,CACT,OAASC,EAAK,CACZ,IAAMC,EACJD,aAAe,MAAQA,EAAM,IAAI,MAAM,qBAAqB,EAC9D,MAAApB,EAASqB,CAAU,EACbA,CACR,QAAE,CACA1B,EAAe,EAAK,CACtB,CACF,EACA,CAACJ,EAASC,CAAc,CAC1B,EAEiB,YAAAE,EAAa,OAAAG,EAAQ,MAAAE,EAAO,WAAAE,CAAW,CAC1D,CC1IA,OAAS,eAAAqB,OAAmB,wBAE5B,OAAS,eAAAC,OAAmB,QAM5B,SAASC,IAAoC,CAC3C,GAAM,CAAE,QAAAC,CAAQ,EAAIC,EAAQ,EAC5B,OAAOH,GAAY,IAAM,CACvB,GAAI,CAACE,EACH,MAAM,IAAIE,GAAY,qBAAsB,mBAAmB,EAEjE,IAAMC,EAAeH,EAAQ,WAAW,OACxC,GAAI,CAACG,GAAgBA,EAAa,SAAS,SAAW,EACpD,MAAM,IAAID,GACR,qBACA,2CACF,CAEJ,EAAG,CAACF,CAAO,CAAC,CACd,CAEO,SAASI,IAAqD,CACnE,IAAMC,EAAQN,GAAsB,EAC9BO,EAAOC,GAAe,EAU5B,MAAO,CACL,OATaT,GACb,MAAOU,IACLH,EAAM,EACCC,EAAK,OAAOE,CAAO,GAE5B,CAACH,EAAOC,EAAK,MAAM,CACrB,EAIE,YAAaA,EAAK,YAClB,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,WAAYA,EAAK,UACnB,CACF,CC7CA,OAAS,YAAAG,GAAU,eAAAC,GAAa,aAAAC,GAAW,UAAAC,OAAc,QAGzD,OAAS,uBAAAC,GAAqB,UAAAC,OAAc,wBAiC5C,IAAMC,GAAgB,YAItB,SAASC,GAAWC,EAAqC,CACvD,OAAO,IAAIJ,GAAoBI,CAAM,CACvC,CAEA,SAASC,GAAUC,EAAwBC,EAAoB,CAC7D,OAAKD,EAAW,QAAQ,eACjB,IAAI,KAAKA,EAAW,QAAQ,cAAc,EAAE,QAAQ,GAAKC,EAAI,QAAQ,EAD7B,EAEjD,CAEA,SAASC,GAAiBF,EAAwBC,EAAoB,CACpE,OAAKD,EAAW,QAAQ,UACjB,IAAI,KAAKA,EAAW,QAAQ,SAAS,EAAE,QAAQ,GAAKC,EAAI,QAAQ,EAD7B,EAE5C,CAIO,SAASE,GACdC,EAC0B,CAC1B,GAAM,CAAE,cAAAC,EAAgB,WAAY,YAAAC,EAAc,EAAK,EAAIF,GAAW,CAAC,EAEjE,CAACJ,EAAYO,CAAa,EAAIC,GAA4B,IAAI,EAC9D,CAACC,EAAaC,CAAc,EAAIF,GAASF,CAAW,EACpD,CAACK,EAAaC,CAAc,EAAIJ,GAAS,EAAK,EAC9C,CAACK,EAAOC,CAAQ,EAAIN,GAAuB,IAAI,EAG/CO,EAAcC,GAAe,EAC7BC,EAAaC,GAAOrB,GAAWQ,CAAa,CAAC,EAE7Cc,EAAaC,GAAY,IAAMN,EAAS,IAAI,EAAG,CAAC,CAAC,EAIvDO,GAAU,IAAM,CACd,GAAI,CAACf,EAAa,CAChBI,EAAe,EAAK,EACpB,MACF,CAEA,IAAIY,EAAY,GAEhB,OAAC,SAAY,CACX,GAAI,CACF,IAAMC,EAAUN,EAAW,QACrBO,EAAQ,MAAMD,EAAQ,IAAgB3B,EAAa,EAEzD,GAAI0B,EAAW,OAEXE,GAAS,CAACzB,GAAUyB,EAAO,IAAI,IAAM,GAAKtB,GAAiBsB,EAAO,IAAI,IAAM,GAC9E7B,GAAO,KAAK,2BAA4B,sCAAsC,EAC9EY,EAAciB,CAAK,EACnBV,EAAS,IAAI,GACJU,IAET7B,GAAO,KAAK,2BAA4B,uCAAuC,EAC/E,MAAM4B,EAAQ,OAAO3B,EAAa,EAEtC,OAAS6B,EAAK,CACZ9B,GAAO,KAAK,2BAA4B,+BAAgC8B,CAAG,CAC7E,QAAE,CACKH,GAAWZ,EAAe,EAAK,CACtC,CACF,GAAG,EAEI,IAAM,CACXY,EAAY,EACd,CACF,EAAG,CAAChB,CAAW,CAAC,EAIhB,IAAMoB,EAASN,GACb,MAAOO,GAA6D,CAClEf,EAAe,EAAI,EACnBE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMc,EAAS,MAAMb,EAAY,OAAOY,CAAW,EAInD,aADgBV,EAAW,QACb,IAAIrB,GAAegC,CAAM,EAEvCrB,EAAcqB,CAAM,EACpBhB,EAAe,EAAK,EACbgB,CACT,OAASH,EAAK,CACZ,IAAMI,EAAUJ,aAAe,MAAQA,EAAM,IAAI,MAAM,qBAAqB,EAC5E,MAAAX,EAASe,CAAO,EAChBjB,EAAe,EAAK,EACdiB,CACR,CACF,EACA,CAACd,CAAW,CACd,EAIMe,EAAUV,GAAY,SAAY,CACtC,GAAI,CAEF,MADgBH,EAAW,QACb,OAAOrB,EAAa,CACpC,OAAS6B,EAAK,CACZ9B,GAAO,KAAK,2BAA4B,6BAA8B8B,CAAG,CAC3E,CACAlB,EAAc,IAAI,EAClBO,EAAS,IAAI,CACf,EAAG,CAAC,CAAC,EAIL,MAAO,CACL,WAAYd,IAAe,KAC3B,YAAAS,EACA,WAAAT,EACA,YAAAW,EACA,MAAAE,EACA,OAAAa,EACA,QAAAI,EACA,WAAAX,CACF,CACF,CC3JA,OAAS,YAAAY,GAAU,eAAAC,OAAmB,QAGtC,OAAS,eAAAC,OAAmB,wBAC5B,OACE,qBAAAC,GACA,iBAAAC,GACA,UAAAC,GACA,qBAAAC,OAGK,gBAkCP,IAAMC,GAAyB,MAE/B,SAASC,IAA2B,CAClC,OAAI,OAAO,OAAW,IAAoB,OAAO,SAAS,KACnD,WACT,CAEA,SAASC,IAAwB,CAC/B,OAAI,OAAO,OAAW,IAAoB,OAAO,SAAS,OACnD,kBACT,CAIO,SAASC,IAAmC,CACjD,GAAM,CAAE,QAAAC,EAAS,QAASC,CAAe,EAAIC,EAAQ,EAC/C,CAACC,EAAaC,CAAc,EAAIC,GAAS,EAAK,EAC9C,CAACC,EAAOC,CAAQ,EAAIF,GAAuB,IAAI,EAE/CG,EAAaC,GAAY,IAAMF,EAAS,IAAI,EAAG,CAAC,CAAC,EA0FvD,MAAO,CAAE,OAxFME,GACb,MAAOC,GAAuD,CAC5D,GAAI,CAACV,EACH,MAAM,IAAIT,GAAY,qBAAsB,mBAAmB,EAGjE,IAAMoB,EAASC,EAAU,EACzB,GAAI,CAACD,EACH,MAAM,IAAIpB,GAAY,qBAAsB,wBAAwB,EAItE,IAAMsB,EAAc,OAAO,QAAQb,EAAQ,UAAU,EAAE,QACrD,CAAC,CAACc,EAAIC,CAAI,IACRA,EAAK,SAAS,IAAKC,IAAiB,CAAE,GAAAF,EAAI,IAAAE,CAAI,EAAE,CACpD,EAEA,GAAIH,EAAY,SAAW,EACzB,MAAM,IAAItB,GAAY,qBAAsB,kBAAkB,EAGhE,GAAM,CAAE,IAAK0B,CAAQ,EAAIJ,EAAY,CAAC,EAChCK,EAAUR,GAAS,SAAWT,GAAkB,WAChDkB,EAAST,GAAS,QAAUb,GAAiB,EAC7CuB,EAAMV,GAAS,KAAOZ,GAAc,EACpCuB,EAAQ5B,GAAc,EACtB6B,EAAW5B,GAAO,EAClB6B,EAAgBb,GAAS,eAAiBd,GAC1C4B,EAAiB,IAAI,KAAK,KAAK,IAAI,EAAID,EAAgB,GAAI,EAAE,YAAY,EAGzEE,EAAUjC,GAAkB,CAChC,OAAA2B,EACA,QAAAF,EACA,IAAAG,EACA,QAAS,EACT,QAAAF,EACA,MAAAG,EACA,SAAAC,EACA,eAAAE,EACA,UAAWd,GAAS,UACpB,UAAWA,GAAS,UACpB,UAAWA,GAAS,SACtB,CAAC,EAEDN,EAAe,EAAI,EACnBG,EAAS,IAAI,EAEb,GAAI,CACF,IAAMmB,EAAa,MAAMf,EAAO,YAAYX,EAAS,CACnD,QAAAyB,EACA,QAAAR,EACA,QAASC,GAAW,MACtB,CAAC,EAEKS,EAAyB,CAC7B,QAAS,CACP,IAAKF,EACL,OAAAN,EACA,QAAAF,EACA,UAAWP,GAAS,WAAa,KACjC,IAAAU,EACA,QAAS,EACT,QAAAF,EACA,MAAAG,EACA,SAAAC,EACA,WAAY3B,GAAkBuB,CAAO,EACrC,eAAAM,EACA,UAAW,KACX,UAAWd,GAAS,WAAa,CAAC,EAClC,UAAWA,GAAS,WAAa,IACnC,EACA,UAAAgB,CACF,EAEA,OAAAtB,EAAe,EAAK,EACbuB,CACT,OAASC,EAAK,CACZ,IAAMC,EACJD,aAAe,MAAQA,EAAM,IAAI,MAAM,qBAAqB,EAC9D,MAAArB,EAASsB,CAAU,EACnBzB,EAAe,EAAK,EACdyB,CACR,CACF,EACA,CAAC7B,EAASC,CAAc,CAC1B,EAEiB,YAAAE,EAAa,MAAAG,EAAO,WAAAE,CAAW,CAClD,CCrJA,OAAS,YAAAsB,GAAU,eAAAC,GAAa,aAAAC,GAAW,UAAAC,OAAc,QAGzD,OAA8B,UAAAC,OAAc,wBAK5C,OAAS,uBAAAC,GAAqB,wCAAAC,OAAgE,gBAmD9F,SAASC,GAAoBC,EAAiC,CAC5D,MAAO,CACL,GAAI,QAAQ,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,CAAC,GAC7E,QAASA,EAAO,QAAQ,QACxB,QAASA,EAAO,QAAQ,QACxB,OAAQA,EAAO,QAAQ,OACvB,QAASA,EAAO,QAChB,UAAWA,EAAO,UAClB,SAAUA,EAAO,QAAQ,UAAY,IAAI,KAAK,EAAE,YAAY,EAC5D,UAAWA,EAAO,QAAQ,eAC1B,YAAa,IACf,CACF,CAIO,SAASC,GACdC,EACsB,CACtB,GAAM,CACJ,cAAAC,EAAgB,WAChB,YAAAC,EAAc,GACd,qBAAAC,EAAuB,KACzB,EAAIH,GAAW,CAAC,EAEV,CAACI,EAASC,CAAU,EAAIC,GAA6B,IAAI,EACzD,CAACC,EAAaC,CAAc,EAAIF,GAASJ,CAAW,EACpD,CAACO,EAAaC,CAAc,EAAIJ,GAAS,EAAK,EAC9C,CAACK,EAAOC,CAAQ,EAAIN,GAAuB,IAAI,EAE/C,CAAE,QAASO,EAAa,QAASC,CAAe,EAAIC,EAAQ,EAC5DC,EAAQC,GAAa,EACrBC,EAAaC,GACjBC,GAAqC,GAAGnB,CAAa,cAAc,CACrE,EAEMoB,EAAaC,GAAY,IAAMV,EAAS,IAAI,EAAG,CAAC,CAAC,EAIvDW,GAAU,IAAM,CACd,GAAI,CAACrB,EAAa,CAChBM,EAAe,EAAK,EACpB,MACF,CAEA,IAAIgB,EAAY,GAEhB,OAAC,SAAY,CACX,GAAI,CAEF,IAAMC,EAAQ,MADEP,EAAW,QACC,IAAI,EAEhC,GAAIM,EAAW,OAEXC,GACFC,GAAO,KAAK,uBAAwB,iCAAiC,EACrErB,EAAWoB,CAAK,EAChBb,EAAS,IAAI,GAGbP,EAAW,IAAI,CAEnB,OAASsB,EAAK,CACZD,GAAO,KAAK,uBAAwB,kCAAmCC,CAAG,EAC1EtB,EAAW,IAAI,CACjB,QAAE,CACKmB,GAAWhB,EAAe,EAAK,CACtC,CACF,GAAG,EAEI,IAAM,CACXgB,EAAY,EACd,CACF,EAAG,CAACtB,CAAW,CAAC,EAIhBqB,GAAU,IAAM,CACd,GAAI,CAACnB,GAAS,UAAW,OAEzB,IAAMwB,EAAkB,IAAI,KAAKxB,EAAQ,SAAS,EAAE,QAAQ,EAAI,KAAK,IAAI,EACzE,GAAIwB,GAAmB,EAAG,CAExBvB,EAAW,IAAI,EACf,MACF,CAGA,IAAMwB,EAAQ,WAAW,IAAM,CAC7BxB,EAAYyB,GACNA,GAAQA,EAAK,KAAO1B,EAAQ,GACvB,KAEF0B,CACR,CACH,EAAGF,CAAe,EAElB,MAAO,IAAM,aAAaC,CAAK,CACjC,EAAG,CAACzB,GAAS,GAAIA,GAAS,SAAS,CAAC,EAIpC,IAAM2B,EAAST,GACb,MAAOU,GAA4D,CACjEtB,EAAe,EAAI,EACnBE,EAAS,IAAI,EAEb,GAAI,CAEF,IAAMqB,EAAwC,CAC5C,cAAe9B,EACf,QAASW,GAAkB,OAC3B,GAAGkB,CACL,EAEMlC,EAAS,MAAMkB,EAAM,OAAOiB,CAAgB,EAG5CC,EAAcrC,GAAoBC,CAAM,EAI9C,aADgBoB,EAAW,QACb,IAAIgB,CAAW,EAE7B7B,EAAW6B,CAAW,EACtBxB,EAAe,EAAK,EACbwB,CACT,OAASP,EAAK,CACZ,IAAMQ,EAAUR,aAAe,MAAQA,EAAM,IAAI,MAAM,qBAAqB,EAC5E,MAAAf,EAASuB,CAAO,EAChBzB,EAAe,EAAK,EACdyB,CACR,CACF,EACA,CAACnB,EAAOF,EAAgBX,CAAoB,CAC9C,EAIMiC,EAAUd,GAAY,SAAY,CACtC,GAAI,CAEF,MADgBJ,EAAW,QACb,OAAO,CACvB,OAASS,EAAK,CACZD,GAAO,KAAK,uBAAwB,2BAA4BC,CAAG,CACrE,CACAtB,EAAW,IAAI,EACfO,EAAS,IAAI,CACf,EAAG,CAAC,CAAC,EAICyB,EAAUf,GAAY,SAAkC,CAC5D,GAAI,CAAClB,EACH,MAAM,IAAI,MAAM,8BAA8B,EAGhDM,EAAe,EAAI,EACnBE,EAAS,IAAI,EAEb,GAAI,CAEF,IAAMd,EAAS,MAAMkB,EAAM,OAAO,CAChC,OAAQZ,EAAQ,OAChB,UAAWA,EAAQ,QAAQ,WAAa,OACxC,IAAKA,EAAQ,QAAQ,IACrB,QAASA,EAAQ,QACjB,cAAeD,EACf,UAAWC,EAAQ,QAAQ,UAAU,OAAS,EAAIA,EAAQ,QAAQ,UAAY,OAC9E,UAAWA,EAAQ,QAAQ,WAAa,MAC1C,CAAC,EAEKkC,EAAgC,CACpC,GAAGzC,GAAoBC,CAAM,EAC7B,GAAIM,EAAQ,GACZ,YAAa,IAAI,KAAK,EAAE,YAAY,CACtC,EAIA,aADgBc,EAAW,QACb,IAAIoB,CAAgB,EAElCjC,EAAWiC,CAAgB,EAC3B5B,EAAe,EAAK,EACb4B,CACT,OAASX,EAAK,CACZ,IAAMQ,EAAUR,aAAe,MAAQA,EAAM,IAAI,MAAM,wBAAwB,EAC/E,MAAAf,EAASuB,CAAO,EAChBzB,EAAe,EAAK,EACdyB,CACR,CACF,EAAG,CAAC/B,EAASY,EAAOb,CAAoB,CAAC,EAInCoC,EAAkBnC,IAAY,MAAQ,CAACoC,GAAoBpC,CAAO,EAClEqC,EAAUD,GAAoBpC,CAAO,EACrCwB,EAAkBxB,GAAS,UAC7B,KAAK,IAAI,EAAG,IAAI,KAAKA,EAAQ,SAAS,EAAE,QAAQ,EAAI,KAAK,IAAI,CAAC,EAC9D,KAEJ,MAAO,CACL,QAASmC,EAAkBnC,EAAU,KACrC,gBAAAmC,EACA,YAAAhC,EACA,YAAAE,EACA,UAAWgC,EACX,gBAAAb,EAEA,OAAAG,EACA,QAAAK,EACA,QAAAC,EAEA,MAAA1B,EACA,WAAAU,CACF,CACF,CC/RA,OAAS,YAAAqB,EAAU,eAAAC,EAAa,aAAAC,GAAW,UAAAC,OAAc,QAGzD,OAAS,eAAAC,GAAa,qBAAAC,GAAmB,wBAAAC,OAA4B,wBAUrE,IAAIC,GAAoD,KAExD,SAASC,GAAqBC,EAAqD,CACjF,OAAKF,KACHA,GAA0B,IAAIF,GAC5BI,EAEA,OAAO,OAAW,IAAc,OAAY,IAAIH,EAClD,GAEKC,EACT,CA6BO,SAASG,IAAuC,CACrD,GAAM,CAAE,QAAAC,CAAQ,EAAIC,EAAQ,EACtB,CAACC,EAAUC,CAAW,EAAIC,EAA2B,CAAC,CAAC,EACvD,CAACC,EAASC,CAAU,EAAIF,EAAS,EAAK,EACtC,CAACG,EAAOC,CAAQ,EAAIJ,EAAuB,IAAI,EAC/CK,EAAaC,GAAO,EAAI,EAExBC,EAAaC,EAAY,IAAMJ,EAAS,IAAI,EAAG,CAAC,CAAC,EAEjDK,EAAUhB,GAAqB,EAC/BiB,EAAmBD,EAAQ,mBAAmB,EAE9CE,EAAUH,EAAY,SAAY,CACtC,GAAI,CAACZ,EAAS,CACZG,EAAY,CAAC,CAAC,EACd,MACF,CAEAG,EAAW,EAAI,EACfE,EAAS,IAAI,EACb,GAAI,CACF,IAAMQ,EAAO,MAAMH,EAAQ,aAAa,EACpCJ,EAAW,SACbN,EAAYa,CAAI,CAEpB,OAASC,EAAK,CACRR,EAAW,SACbD,EAASS,aAAe,MAAQA,EAAM,IAAI,MAAM,6BAA6B,CAAC,CAElF,QAAE,CACIR,EAAW,SACbH,EAAW,EAAK,CAEpB,CACF,EAAG,CAACN,EAASa,CAAO,CAAC,EAGrBK,GAAU,KACRT,EAAW,QAAU,GACrBM,EAAQ,EACD,IAAM,CACXN,EAAW,QAAU,EACvB,GACC,CAACM,CAAO,CAAC,EAEZ,IAAMI,EAAiBjB,EAAS,OAAQkB,GAAMA,EAAE,SAAW,QAAQ,EAEnE,MAAO,CACL,SAAAlB,EACA,eAAAiB,EACA,QAAAd,EACA,MAAAE,EACA,QAAAQ,EACA,WAAAJ,EACA,iBAAAG,CACF,CACF,CAmCO,SAASO,IAAiD,CAC/D,GAAM,CAAE,QAAArB,CAAQ,EAAIC,EAAQ,EACtB,CAACqB,EAAaC,CAAc,EAAInB,EAAgC,IAAI,EACpE,CAACoB,EAAYC,CAAa,EAAIrB,EAAS,EAAK,EAC5C,CAACG,EAAOC,CAAQ,EAAIJ,EAAuB,IAAI,EAE/CO,EAAaC,EAAY,IAAMJ,EAAS,IAAI,EAAG,CAAC,CAAC,EAEjDK,EAAUhB,GAAqB,EA6BrC,MAAO,CACL,iBA5BuBe,EACvB,MACEc,EACAC,IAC4B,CAC5B,GAAI,CAAC3B,EACH,MAAM,IAAIP,GAAY,qBAAsB,0BAA0B,EAGxEgC,EAAc,EAAI,EAClBjB,EAAS,IAAI,EACb,GAAI,CACF,IAAMoB,EAAiBD,GAAiB,OAClCE,EAAO,MAAMhB,EAAQ,iBAAiBa,EAAOE,CAAc,EACjE,OAAAL,EAAeM,CAAI,EACZA,CACT,OAASZ,EAAK,CACZ,IAAMa,EAAWb,aAAe,MAAQA,EAAM,IAAI,MAAM,8BAA8B,EACtF,MAAAT,EAASsB,CAAQ,EACXA,CACR,QAAE,CACAL,EAAc,EAAK,CACrB,CACF,EACA,CAACzB,EAASa,CAAO,CACnB,EAIE,YAAAS,EACA,WAAAE,EACA,MAAAjB,EACA,WAAAI,CACF,CACF,CAwBO,SAASoB,IAA2C,CACzD,GAAM,CAACC,EAAYC,CAAa,EAAI7B,EAAS,EAAK,EAC5C,CAACG,EAAOC,CAAQ,EAAIJ,EAAuB,IAAI,EAE/CO,EAAaC,EAAY,IAAMJ,EAAS,IAAI,EAAG,CAAC,CAAC,EAEjDK,EAAUhB,GAAqB,EAmBrC,MAAO,CACL,cAlBoBe,EACpB,MAAOsB,GAAqC,CAC1CD,EAAc,EAAI,EAClBzB,EAAS,IAAI,EACb,GAAI,CACF,MAAMK,EAAQ,cAAcqB,CAAS,CACvC,OAASjB,EAAK,CACZ,IAAMa,EAAWb,aAAe,MAAQA,EAAM,IAAI,MAAM,8BAA8B,EACtF,MAAAT,EAASsB,CAAQ,EACXA,CACR,QAAE,CACAG,EAAc,EAAK,CACrB,CACF,EACA,CAACpB,CAAO,CACV,EAIE,WAAAmB,EACA,MAAAzB,EACA,WAAAI,CACF,CACF,CA6CO,SAASwB,IAA+C,CAC7D,GAAM,CAACC,EAAQC,CAAS,EAAIjC,EAAS,EAAK,EACpC,CAACG,EAAOC,CAAQ,EAAIJ,EAAuB,IAAI,EAE/CO,EAAaC,EAAY,IAAMJ,EAAS,IAAI,EAAG,CAAC,CAAC,EAEjDK,EAAUhB,GAAqB,EAE/ByC,EAAkB1B,EACtB,MAAOsB,EAAmBK,IAAuD,CAC/EF,EAAU,EAAI,EACd7B,EAAS,IAAI,EACb,GAAI,CACF,OAAO,MAAMK,EAAQ,mBAAmBqB,EAAWK,CAAW,CAChE,OAAStB,EAAK,CACZ,IAAMa,EAAWb,aAAe,MAAQA,EAAM,IAAI,MAAM,iCAAiC,EACzF,MAAAT,EAASsB,CAAQ,EACXA,CACR,QAAE,CACAO,EAAU,EAAK,CACjB,CACF,EACA,CAACxB,CAAO,CACV,EAEM2B,EAAa5B,EACjB,MACEsB,EACAO,IAOG,CACHJ,EAAU,EAAI,EACd7B,EAAS,IAAI,EACb,GAAI,CACF,OAAO,MAAMK,EAAQ,kBAAkBqB,EAAWO,CAAE,CACtD,OAASxB,EAAK,CACZ,IAAMa,EAAWb,aAAe,MAAQA,EAAM,IAAI,MAAM,+BAA+B,EACvF,MAAAT,EAASsB,CAAQ,EACXA,CACR,QAAE,CACAO,EAAU,EAAK,CACjB,CACF,EACA,CAACxB,CAAO,CACV,EAEA,MAAO,CACL,gBAAAyB,EACA,WAAAE,EACA,OAAAJ,EACA,MAAA7B,EACA,WAAAI,CACF,CACF,CAKO,SAAS+B,IAA+B,CAC7C9C,GAA0B,IAC5B,CCnWA,OAAS,YAAA+C,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QACzD,OAAS,gBAAAC,OAAoB,wBA4B7B,IAAIC,GAAsC,KAE1C,SAASC,GAAYC,EAA2C,CAC9D,OAAIA,EACK,IAAIH,GAAaG,CAAM,GAE3BF,KACHA,GAAiB,IAAID,IAEhBC,GACT,CAgBO,SAASG,GACdC,EACAC,EACsB,CACtB,GAAM,CAACC,EAAMC,CAAO,EAAIZ,GAA+B,IAAI,EACrD,CAACa,EAAWC,CAAY,EAAId,GAAS,EAAK,EAC1C,CAACe,EAAOC,CAAQ,EAAIhB,GAAuB,IAAI,EAC/CiB,EAAOP,GAAS,MAAQ,GACxBQ,EAAcf,GAA4B,IAAI,EAC9CgB,EAAgBhB,GAAe,EAAE,EACjCiB,EAAajB,GAAO,EAAI,EAG9BF,GAAU,KACRmB,EAAW,QAAU,GACd,IAAM,CACXA,EAAW,QAAU,EACvB,GACC,CAAC,CAAC,EAEL,IAAMC,EAAWH,EAAY,SAAWZ,GAAYI,GAAS,cAAc,EAC3EQ,EAAY,QAAUG,EAEtB,IAAMC,EAAUpB,GAAY,IAAM,CAChC,IAAMqB,EAAYd,EAAK,KAAK,EAE5B,GAAI,CAACc,GAAaN,EAAM,CACtBL,EAAQ,IAAI,EACZE,EAAa,EAAK,EAClBE,EAAS,IAAI,EACb,MACF,CAGIG,EAAc,UAAYI,GAAaZ,IAI3CQ,EAAc,QAAUI,EACxBT,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEbK,EACG,YAAYE,CAAS,EACrB,KAAMC,GAAW,CACZJ,EAAW,UACbR,EAAQY,CAAM,EACdV,EAAa,EAAK,EAEtB,CAAC,EACA,MAAOW,GAAiB,CACvB,GAAIL,EAAW,QAAS,CACtB,IAAMM,EACJD,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,EACpDT,EAASU,CAAe,EACxBd,EAAQ,IAAI,EACZE,EAAa,EAAK,CACpB,CACF,CAAC,EACL,EAAG,CAACL,EAAMQ,CAAI,CAAC,EAGfhB,GAAU,IAAM,CACdqB,EAAQ,CACV,EAAG,CAACA,CAAO,CAAC,EAEZ,IAAMK,EAAUzB,GAAY,IAAM,CAChCiB,EAAc,QAAU,GACxBG,EAAQ,CACV,EAAG,CAACA,CAAO,CAAC,EAEZ,MAAO,CAAE,KAAAX,EAAM,UAAAE,EAAW,MAAAE,EAAO,QAAAY,CAAQ,CAC3C,CC/HA,OAAS,YAAAC,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QACzD,OAAS,gBAAAC,OAAoB,wBA8B7B,IAAIC,GAAsC,KAE1C,SAASC,GAAYC,EAA2C,CAC9D,OAAIA,EACK,IAAIH,GAAaG,CAAM,GAE3BF,KACHA,GAAiB,IAAID,IAEhBC,GACT,CAgBO,SAASG,GACdC,EACAC,EACwB,CACxB,GAAM,CAACC,EAAMC,CAAO,EAAIZ,GAA4B,IAAI,EAClD,CAACa,EAAWC,CAAY,EAAId,GAAS,EAAK,EAC1C,CAACe,EAAOC,CAAQ,EAAIhB,GAAuB,IAAI,EAC/CiB,EAAUP,GAAS,QACnBQ,EAAOR,GAAS,MAAQ,GACxBS,EAAchB,GAA4B,IAAI,EAC9CiB,EAAgBjB,GAAe,EAAE,EACjCkB,EAAalB,GAAO,EAAI,EAG9BF,GAAU,KACRoB,EAAW,QAAU,GACd,IAAM,CACXA,EAAW,QAAU,EACvB,GACC,CAAC,CAAC,EAEL,IAAMC,EAAWH,EAAY,SAAWb,GAAYI,GAAS,cAAc,EAC3ES,EAAY,QAAUG,EAEtB,IAAMC,EAASrB,GAAY,IAAM,CAC/B,IAAMsB,EAAYf,EAAQ,KAAK,EAE/B,GAAI,CAACe,GAAaN,EAAM,CACtBN,EAAQ,IAAI,EACZE,EAAa,EAAK,EAClBE,EAAS,IAAI,EACb,MACF,CAGII,EAAc,UAAYI,GAAab,IAI3CS,EAAc,QAAUI,EACxBV,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEbM,EACG,cAAcE,EAAWP,CAAO,EAChC,KAAMQ,GAAW,CACZJ,EAAW,UACbT,EAAQa,CAAM,EACdX,EAAa,EAAK,EAEtB,CAAC,EACA,MAAOY,GAAiB,CACvB,GAAIL,EAAW,QAAS,CACtB,IAAMM,EACJD,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,EACpDV,EAASW,CAAe,EACxBf,EAAQ,IAAI,EACZE,EAAa,EAAK,CACpB,CACF,CAAC,EACL,EAAG,CAACL,EAASQ,EAASC,CAAI,CAAC,EAG3BjB,GAAU,IAAM,CACdsB,EAAO,CACT,EAAG,CAACA,CAAM,CAAC,EAEX,IAAMK,EAAU1B,GAAY,IAAM,CAChCkB,EAAc,QAAU,GACxBG,EAAO,CACT,EAAG,CAACA,CAAM,CAAC,EAEX,MAAO,CAAE,KAAAZ,EAAM,UAAAE,EAAW,MAAAE,EAAO,QAAAa,CAAQ,CAC3C,CCxHA,OAAS,wBAAAC,GAAsB,eAAAC,OAAmB,QAiBlD,SAASC,GACPC,EACAC,EACY,CACZ,GAAI,CAACD,EAAI,MAAO,IAAM,CAAC,EAEvB,IAAME,EAAU,IAAMD,EAAS,EAC/B,OAAAD,EAAG,GAAG,mBAAoBE,CAAO,EACjCF,EAAG,GAAG,sBAAuBE,CAAO,EACpCF,EAAG,GAAG,eAAgBE,CAAO,EAEtB,IAAM,CACXF,EAAG,IAAI,mBAAoBE,CAAO,EAClCF,EAAG,IAAI,sBAAuBE,CAAO,EACrCF,EAAG,IAAI,eAAgBE,CAAO,CAChC,CACF,CAEA,SAASC,GACPH,EACkB,CAClB,GAAI,CAACA,EACH,MAAO,CACL,QAAS,KACT,cAAe,CAAC,EAChB,cAAe,KACf,YAAa,GACb,YAAa,IACf,EAGF,IAAMI,EAASJ,EAAG,gBAAgB,EAClC,OAAKI,EAUE,CACL,QAASA,EAAO,cAChB,cAAe,MAAM,KAAKA,EAAO,cAAc,OAAO,CAAC,EACvD,cAAeA,EAAO,cACtB,YAAa,GACb,YAAaA,EAAO,cAAc,UACpC,EAfS,CACL,QAAS,KACT,cAAe,CAAC,EAChB,cAAe,KACf,YAAa,GACb,YAAa,IACf,CAUJ,CAEO,SAASC,GACdC,EACkB,CAClB,IAAMC,EAAOC,EAAQ,EACfR,EAAKM,GAAkBC,EAAK,gBAAkB,KAE9CE,EAAYC,GACfT,GAAyBF,GAA0BC,EAAIC,CAAQ,EAChE,CAACD,CAAE,CACL,EAEMW,EAAcD,GAClB,IAAMP,GAAmBH,CAAE,EAC3B,CAACA,CAAE,CACL,EAEA,OAAOY,GAAqBH,EAAWE,CAAW,CACpD,CCvFA,OAAS,YAAAE,GAAU,eAAAC,OAAmB,QAEtC,OAAS,eAAAC,OAAmB,wBAerB,SAASC,IAAuC,CACrD,GAAM,CAAE,YAAaC,EAAqB,QAAAC,CAAQ,EAAIC,EAAQ,EACxD,CAACC,EAAaC,CAAc,EAAIC,GAAS,EAAK,EAC9C,CAACC,EAAOC,CAAQ,EAAIF,GAAuB,IAAI,EAE/CG,EAAoBC,GACxB,MAAOC,GAA0B,CAC/BN,EAAe,EAAI,EACnBG,EAAS,IAAI,EAEb,GAAI,CACF,MAAMP,EAAoBU,CAAa,CACzC,OAASC,EAAK,CACZ,IAAMC,EACJD,aAAeb,GACXa,EACA,IAAIb,GACF,oBACAa,aAAe,MACXA,EAAI,QACJ,mCACN,EACN,MAAAJ,EAASK,CAAW,EACdA,CACR,QAAE,CACAR,EAAe,EAAK,CACtB,CACF,EACA,CAACJ,CAAmB,CACtB,EAEMa,EAAaJ,GAAY,IAAM,CACnCF,EAAS,IAAI,CACf,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,YAAaC,EACb,YAAAL,EACA,eAAgBF,EAChB,MAAAK,EACA,WAAAO,CACF,CACF,CCjEA,OAAS,eAAAC,GAAa,WAAAC,OAAe,QCQ9B,IAAMC,GAA8C,CACzD,mBAAoB,sBACpB,cAAe,sBACf,iBAAkB,8BAClB,gBAAiB,kBACjB,eAAgB,6BAChB,mBAAoB,mBACpB,kBAAmB,sBACnB,mBAAoB,qBACpB,mBAAoB,qBACpB,UAAW,oBACb,EAKaC,GAAoD,CAC/D,mBACE,qGACF,cAAe,+FACf,iBACE,kHACF,gBACE,iEACF,eACE,+DACF,mBACE,6FACF,kBACE,qFACF,mBACE,iEACF,mBAAoB,qDACpB,UACE,0HACJ,EAKaC,GAAsB,uBAKtBC,GACX,2HAKK,SAASC,GACdC,EACuD,CACvD,GAAI,CAACA,EACH,MAAO,CAAE,MAAOH,GAAqB,YAAaC,EAA0B,EAI9E,IAAMG,EAAmBD,EACzB,GAAIC,EAAiB,OAAS,eAAiBA,EAAiB,KAAM,CACpE,IAAMC,EAAOD,EAAiB,KACxBE,EAAQR,GAAoBO,CAAI,GAAKL,GACrCO,EACJR,GAA0BM,CAAI,GAAKD,EAAiB,SAAWH,GACjE,MAAO,CAAE,MAAAK,EAAO,YAAAC,EAAa,KAAAF,CAAK,CACpC,CAGA,GAAIF,aAAiB,MAAO,CAC1B,IAAMK,EAAUL,EAAM,QAEtB,MAAI,iBAAiB,KAAKK,CAAO,GAAK,WAAW,KAAKA,CAAO,EACpD,CACL,MAAO,mBACP,YAAa,4BACb,KAAM,eACR,EAEE,WAAW,KAAKA,CAAO,GAAK,eAAe,KAAKA,CAAO,EAClD,CACL,MAAO,oBACP,YAAa,+CACb,KAAM,kBACR,EAEE,WAAW,KAAKA,CAAO,GAAK,SAAS,KAAKA,CAAO,EAC5C,CACL,MAAO,gBACP,YAAaA,EACb,KAAM,mBACR,EAEE,sBAAsB,KAAKA,CAAO,EAC7B,CACL,MAAO,qBACP,YAAa,4DACb,KAAM,WACR,EAGK,CACL,MAAOR,GACP,YAAaQ,GAAWP,EAC1B,CACF,CAGA,OAAI,OAAOE,GAAU,SACZ,CACL,MAAOH,GACP,YAAaG,GAASF,EACxB,EAGK,CAAE,MAAOD,GAAqB,YAAaC,EAA0B,CAC9E,CAKO,SAASQ,GAAiBN,EAAyB,CACxD,IAAMO,EAAQP,EACd,OAAIO,EAAM,OAAS,eAAiB,CAACA,EAAM,KAAa,GACd,CACxC,mBACA,kBACA,iBACA,WACF,EACsB,SAASA,EAAM,IAAuB,CAC9D,CDxFO,SAASC,IAAiD,CAC/D,GAAM,CAAE,MAAAC,EAAO,WAAYC,CAAmB,EAAIC,EAAQ,EAEpDC,EAA0CC,GAC9C,IAAOJ,EAAQK,GAAqBL,CAAK,EAAI,KAC7C,CAACA,CAAK,CACR,EAEMM,EAAcF,GAClB,IAAOJ,EAAQO,GAAiBP,CAAK,EAAI,GACzC,CAACA,CAAK,CACR,EAEMQ,EAAaC,GAAY,IAAM,CACnCR,EAAmB,CACrB,EAAG,CAACA,CAAkB,CAAC,EAEjBS,EAAcD,GACjBE,GAAoCN,GAAqBM,CAAG,EAC7D,CAAC,CACH,EAEMC,EAAYH,GACXI,GACI,SAAY,CACjB,GAAI,CACF,OAAO,MAAMA,EAAG,CAClB,OAASF,EAAK,CAEZ,IAAMG,EAAWT,GAAqBM,CAAG,EACnCI,EAAW,IAAI,MAAMD,EAAS,WAAW,EAC/C,MAAAC,EAAS,MAAQD,EAAS,MAC1BC,EAAS,KAAOD,EAAS,KACnBC,CACR,CACF,EAEF,CAAC,CACH,EAEA,MAAO,CACL,MAAAf,EACA,cAAAG,EACA,WAAAK,EACA,YAAAF,EACA,YAAAI,EACA,UAAAE,CACF,CACF,CErGA,OAAS,YAAAI,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QAwDzD,OAAS,iBAAAC,GAAe,cAAAC,OAAkB,QAEnC,IAAMC,GAAmBF,GAAoC,IAAI,EAEjE,SAASG,IAA6C,CAC3D,OAAOF,GAAWC,EAAgB,CACpC,CAkBO,SAASE,GACdC,EACAC,EACAC,EACoB,CACpB,IAAMC,EAAaL,GAAqB,EAClCM,EAAmBF,GAAWC,EAE9B,CAACE,EAAOC,CAAQ,EAAIf,GAA+B,IAAI,EACvD,CAACgB,EAAWC,CAAY,EAAIjB,GAAS,EAAK,EAC1C,CAACkB,EAAYC,CAAa,EAAInB,GAAS,EAAK,EAC5C,CAACoB,EAAOC,CAAQ,EAAIrB,GAAuB,IAAI,EAC/CsB,EAAcnB,GAA2B,MAAS,EAElDoB,EAAUrB,GAAY,SAAY,CACtC,GAAI,GAACW,GAAoB,CAACJ,GAC1B,CAAAQ,EAAa,EAAI,EACjBI,EAAS,IAAI,EACb,GAAI,CACF,MAAMR,EAAiB,UAAUJ,EAAMC,CAAO,EAC9C,IAAMc,EAAUX,EAAiB,YAAYJ,EAAMC,CAAO,EACtDc,GAAST,EAASS,CAAO,CAC/B,OAASC,EAAK,CACZJ,EAASI,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,CAAC,CAC9D,QAAE,CACAR,EAAa,EAAK,CACpB,EACF,EAAG,CAACJ,EAAkBJ,EAAMC,CAAO,CAAC,EAE9BgB,EAAexB,GAAY,IAAM,CACjC,CAACW,GAAoB,CAACJ,IAC1BI,EAAiB,aAAaJ,EAAMC,CAAO,EAC3CS,EAAc,EAAK,EACrB,EAAG,CAACN,EAAkBJ,EAAMC,CAAO,CAAC,EAEpCT,GAAU,IAAM,CACd,GAAI,CAACY,GAAoB,CAACJ,GAAQ,CAACC,EAAS,CAC1CK,EAAS,IAAI,EACbI,EAAc,EAAK,EACnB,MACF,CAGIG,EAAY,SAAWA,EAAY,UAAYb,GACjDI,EAAiB,aAAaS,EAAY,OAAO,EAEnDA,EAAY,QAAUb,EAEtB,IAAIkB,EAAY,GAChBR,EAAc,EAAI,EAClBF,EAAa,EAAI,EACjBI,EAAS,IAAI,EAGb,IAAMG,EAAUX,EAAiB,YAAYJ,EAAMC,CAAO,EACtDc,IACFT,EAASS,CAAO,EAChBP,EAAa,EAAK,GAIpBJ,EAAiB,QAAQJ,EAAMC,EAAS,CAAC,CAAC,EAAE,KAAMkB,GAAY,CACvDD,IACHZ,EAASa,CAAO,EAChBX,EAAa,EAAK,EAEtB,CAAC,EAAE,MAAOQ,GAAQ,CACXE,IACHN,EAASI,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,CAAC,EAC5DR,EAAa,EAAK,EAEtB,CAAC,EAGD,IAAMY,EAAkBC,GAA2B,CAC5CH,GAAWZ,EAAS,CAAE,GAAGe,CAAQ,CAAC,CACzC,EACA,OAAAjB,EAAiB,GAAG,eAAgBgB,CAAc,EAE3C,IAAM,CACXF,EAAY,GACZR,EAAc,EAAK,EACnBN,EAAiB,IAAI,eAAgBgB,CAAc,CACrD,CACF,EAAG,CAAChB,EAAkBJ,EAAMC,CAAO,CAAC,EAEpC,IAAMqB,EAA4BjB,GAAO,QAAU,OAEnD,MAAO,CACL,MAAAA,EACA,OAAAiB,EACA,UAAAf,EACA,WAAAE,EACA,MAAAE,EACA,QAAAG,EACA,aAAAG,CACF,CACF,CCjLA,OAAS,YAAAM,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QAsBlD,SAASC,GACdC,EACAC,EACAC,EACoB,CACpB,IAAMC,EAAaC,GAAqB,EAClCC,EAAmBH,GAAWC,EAE9B,CAACG,EAASC,CAAU,EAAIC,GAA0B,CAAC,CAAC,EACpD,CAACC,EAAWC,CAAY,EAAIF,GAAS,EAAK,EAC1C,CAACG,EAAOC,CAAQ,EAAIJ,GAAuB,IAAI,EAC/CK,EAAiBC,GAAO,CAAC,EAEzBC,EAAUC,GAAY,SAAY,CACtC,GAAKX,EACL,CAAAK,EAAa,EAAI,EACjBE,EAAS,IAAI,EACbC,EAAe,UACf,GAAI,CACF,IAAMI,EAAU,MAAMZ,EAAiB,aAAaL,EAASC,CAAO,EACpEM,EAAWU,CAAO,CACpB,OAASC,EAAK,CACZN,EAASM,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,CAAC,CAC9D,QAAE,CACAR,EAAa,EAAK,CACpB,EACF,EAAG,CAACL,EAAkBL,EAASC,CAAO,CAAC,EAEvCkB,GAAU,IAAM,CACdJ,EAAQ,EAAE,MAAM,IAAM,CAAC,CAAC,CAC1B,EAAG,CAACA,CAAO,CAAC,EAGZI,GAAU,IAAM,CACd,GAAI,CAACd,EAAkB,OAEvB,IAAMe,EAAiB,IAAM,CAE3BL,EAAQ,EAAE,MAAM,IAAM,CAAC,CAAC,CAC1B,EACA,OAAAV,EAAiB,GAAG,eAAgBe,CAAc,EAE3C,IAAM,CACXf,EAAiB,IAAI,eAAgBe,CAAqB,CAC5D,CACF,EAAG,CAACf,EAAkBU,CAAO,CAAC,EAE9B,IAAMM,EAAU,CACd,QAASf,EAAQ,OAAOgB,GAAKA,EAAE,SAAW,SAAS,EAAE,OACrD,UAAWhB,EAAQ,OAAOgB,GAAKA,EAAE,SAAW,WAAW,EAAE,OACzD,OAAQhB,EAAQ,OAAOgB,GAAKA,EAAE,SAAW,QAAQ,EAAE,MACrD,EAEA,MAAO,CACL,QAAAhB,EACA,UAAAG,EACA,MAAAE,EACA,QAAAI,EACA,QAAAM,CACF,CACF,CCxEA,OAAS,YAAAE,GAAU,eAAAC,GAAa,aAAAC,GAAW,UAAAC,OAAc,QAgGlD,SAASC,GACdC,EACAC,EACgC,CAChC,GAAM,CAAE,QAAAC,CAAQ,EAAIC,EAAQ,EACtB,CAAE,WAAAC,EAAY,YAAAC,CAAY,EAAIC,EAAW,EACzC,CAAE,aAAAC,CAAa,EAAIC,EAAS,EAC5B,CAAE,aAAAC,CAAa,EAAIC,EAAc,EAEjC,CAACC,EAAQC,CAAS,EAAIC,GAAuC,MAAS,EACtE,CAACC,EAAcC,CAAe,EAAIF,GAAS,EAAK,EAChD,CAACG,EAAOC,CAAQ,EAAIJ,GAAuB,IAAI,EAG/CK,EAAcC,GAAkD,MAAS,EAIzEC,EAAWC,GAAY,SAAuC,CAClE,GAAI,CAACrB,EAAI,CACP,IAAMsB,EAA+B,CACnC,OAAQ,cACR,eAAgB,CAAC,EACjB,gBAAiB,CAAC,EAClB,eAAgB,CAAE,MAAO,UAAwB,MAAO,EAAG,SAAU,CAAC,CAAE,EACxE,SAAU,WACV,QAAS,6BACT,gBAAiB,EACnB,EACA,OAAAV,EAAUU,CAAU,EACbA,CACT,CAEAP,EAAgB,EAAI,EACpBE,EAAS,IAAI,EAEb,GAAI,CAEF,IAAMM,EAAgBtB,GAAWM,GAAc,IAAM,EAG/CiB,EAASjB,GAAc,OAG7B,GAAIE,EACF,GAAI,CACF,IAAMgB,EAAOrB,GAAY,SAAS,GAAG,EAChCA,EAAW,MAAM,GAAG,EAAE,IAAI,EAC3BA,EAEEsB,EAAkB,CACtB,GAAI1B,EAAG,GACP,KAAOA,EAAG,MAAQ,KAClB,MAAOA,EAAG,MAAQ,OAAOA,EAAG,KAAK,EAAI,EACvC,EAEIyB,IACFC,EAAW,KAAOD,GAGpB,MAAMhB,EAAa,KAAKiB,CAAU,EAGlC,IAAMC,EAA8B,CAClC,OAAQ,UACR,eAAgB,CAAC,EACjB,gBAAiB,CAAC,EAClB,eAAgB,CAAE,MAAO,UAAW,MAAO,EAAG,SAAU,CAAC,CAAE,EAC3D,QAAS3B,EAAG,IACR,CAAE,SAAU,OAAOA,EAAG,GAAG,EAAG,gBAAiB,GAAI,EACjD,OACJ,SAAU,WACV,QAAS,6DACT,gBAAiB,EACnB,EACA,OAAAY,EAAUe,CAAS,EACZA,CACT,OAASC,EAAc,CAErB,IAAIC,EACEC,EAASF,GAAS,SAAW,OAAOA,CAAO,EAC3CG,EAAUH,GAAS,MAAQA,GAAS,OAAO,KAGjD,GAAIG,GAAW,OAAOA,GAAY,SAAU,CAC1C,IAAMC,EAAQD,EAAQ,WAAW,IAAI,EAAIA,EAAQ,MAAM,CAAC,EAAIA,EAC5D,GAAIC,EAAM,WAAW,UAAU,GAAKA,EAAM,OAAS,IAAK,CAEtD,IAAMC,EAAS,SAASD,EAAM,MAAM,GAAI,GAAG,EAAG,EAAE,EAChD,GAAIC,EAAS,EAAG,CACd,IAAMC,EAASF,EAAM,MAAM,IAAK,IAAMC,EAAS,CAAC,EAC1CE,EAAQ,IAAI,WAAWF,CAAM,EACnC,QAASG,EAAI,EAAGA,EAAIH,EAAQG,IAC1BD,EAAMC,CAAC,EAAI,SAASF,EAAO,MAAME,EAAI,EAAGA,EAAI,EAAI,CAAC,EAAG,EAAE,EAExDP,EAAe,IAAI,YAAY,EAAE,OAAOM,CAAK,CAC/C,CACF,MAAWH,EAAM,WAAW,UAAU,IACpCH,EAAe,0BAEnB,CAEKA,IACHA,EAAeC,EAAO,SAAS,QAAQ,EACnCA,EACA,wBAGN,IAAMH,EAA8B,CAClC,OAAQ,WACR,aAAAE,EACA,eAAgB,CAAC,EACjB,gBAAiB,CAAC,EAClB,eAAgB,CACd,MAAO,UACP,MAAO,EACP,SAAU,CACR,CACE,SAAU,oBACV,SAAU,OACV,QAASA,EACL,6BAA6BA,CAAY,GACzC,0BACN,CACF,CACF,EACA,SAAU,WACV,QAASA,EACL,yBAAyBA,CAAY,GACrC,uBACJ,gBAAiB,EACnB,EACA,OAAAjB,EAAUe,CAAS,EACZA,CACT,CAIF,GAAIH,EACF,GAAI,CAsBF,IAAMa,EAAY,MArBD,MAAM,MAAMb,EAAQ,CACnC,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CACnB,QAAS,MACT,GAAI,KAAK,IAAI,EACb,OAAQ,WACR,OAAQ,CACN,CACE,GAAIxB,EAAG,GACP,KAAMI,GAAY,SAAS,GAAG,EAC1BA,EAAW,MAAM,GAAG,EAAE,IAAI,EAC1BA,EACJ,KAAMJ,EAAG,MAAQ,KACjB,MAAOA,EAAG,OAAS,KACrB,EACA,QACF,CACF,CAAC,CACH,CAAC,GAEgC,KAAK,EAEtC,GAAIqC,EAAK,MAAO,CACd,IAAMV,EAA8B,CAClC,OAAQ,WACR,eAAgB,CAAC,EACjB,gBAAiB,CAAC,EAClB,eAAgB,CACd,MAAO,UACP,MAAO,EACP,SAAU,CACR,CACE,SAAU,oBACV,SAAU,OACV,QAAS,6BAA6BU,EAAK,MAAM,OAAO,EAC1D,CACF,CACF,EACA,SAAU,WACV,QAAS,uBACT,gBAAiB,EACnB,EACA,OAAAzB,EAAUe,CAAS,EACZA,CACT,CAEA,IAAMA,EAA8B,CAClC,OAAQ,UACR,eAAgB,CAAC,EACjB,gBAAiB,CAAC,EAClB,eAAgB,CAAE,MAAO,UAAW,MAAO,EAAG,SAAU,CAAC,CAAE,EAC3D,SAAU,WACV,QAAS,mCACT,gBAAiB,EACnB,EACA,OAAAf,EAAUe,CAAS,EACZA,CACT,OAASW,EAAe,CAEtB,IAAMX,EAA8B,CAClC,OAAQ,cACR,eAAgB,CAAC,EACjB,gBAAiB,CAAC,EAClB,eAAgB,CACd,MAAO,UACP,MAAO,EACP,SAAU,CACR,CACE,SAAU,oBACV,SAAU,SACV,QAAS,kBAAkBW,GAAU,SAAW,SAAS,EAC3D,CACF,CACF,EACA,SAAU,WACV,QAAS,8CACT,gBAAiB,EACnB,EACA,OAAA1B,EAAUe,CAAS,EACZA,CACT,CAIF,IAAMA,EAA8B,CAClC,OAAQ,cACR,eAAgB,CAAC,EACjB,gBAAiB,CAAC,EAClB,eAAgB,CACd,MAAO,UACP,MAAO,EACP,SAAU,CACR,CACE,SAAU,oBACV,SAAU,MACV,QAAS,sDACX,CACF,CACF,EACA,SAAU,WACV,QAAS,qCACT,gBAAiB,EACnB,EACA,OAAAf,EAAUe,CAAS,EACZA,CACT,OAASY,EAAK,CACZ,IAAMvB,EAAQuB,aAAe,MAAQA,EAAM,IAAI,MAAM,mBAAmB,EACxE,MAAAtB,EAASD,CAAK,EACRA,CACR,QAAE,CACAD,EAAgB,EAAK,CACvB,CACF,EAAG,CAACf,EAAIC,EAASM,EAAcE,EAAcL,CAAU,CAAC,EAIxDoC,GAAU,IAAM,CACd,GAAKxC,EAGL,OAAIkB,EAAY,SACd,aAAaA,EAAY,OAAO,EAIlCA,EAAY,QAAU,WAAW,IAAM,CACrCE,EAAS,EAAE,MAAM,IAAM,CAEvB,CAAC,CACH,EAAG,GAAG,EAEC,IAAM,CACPF,EAAY,SACd,aAAaA,EAAY,OAAO,CAEpC,CACF,EAAG,CAAClB,EAAIoB,CAAQ,CAAC,EAIjB,IAAMqB,EAAQpB,GAAY,IAAM,CAC9BT,EAAU,MAAS,EACnBK,EAAS,IAAI,EACbF,EAAgB,EAAK,CACvB,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,OAAAJ,EACA,aAAAG,EACA,MAAAE,EACA,SAAAI,EACA,MAAAqB,CACF,CACF,CCtYA,OAAS,WAAAC,OAAe,QAiBxB,IAAMC,GAA0B,aAIhC,SAASC,GAAWC,EAAsB,CAExC,OADcA,EAAK,WAAW,IAAI,EAAIA,EAAK,MAAM,CAAC,EAAIA,GACzC,SAAS,GAAI,GAAG,CAC/B,CAKA,SAASC,GAAOC,EAAeC,EAAgB,GAAY,CAEzD,OADcD,EAAM,WAAW,IAAI,EAAIA,EAAM,MAAM,CAAC,EAAIA,GAC3C,SAASC,EAAQ,EAAG,GAAG,CACtC,CAMA,SAASC,GAAWC,EAAgBC,EAA0B,CAE5D,GAAM,CAACC,EAAQ,IAAKC,EAAW,EAAE,EAAIH,EAAO,MAAM,GAAG,EAC/CI,EAASD,EAAS,OAAOF,EAAU,GAAG,EAAE,MAAM,EAAGA,CAAQ,EAC/D,OAAO,OAAOC,EAAQE,GAAU,GAAG,CACrC,CAcA,SAASC,GACPC,EACAN,EACe,CACf,MAAO,GAAGP,EAAuB,GAAGC,GAAWY,CAAE,CAAC,GAAGV,GAAOI,EAAO,SAAS,EAAE,CAAC,CAAC,EAClF,CA6BO,SAASO,GACdC,EACkC,CAClC,GAAM,CAAE,WAAAC,EAAY,YAAAC,CAAY,EAAIC,EAAW,EACzC,CAAE,aAAAC,CAAa,EAAIC,EAAS,EAC5BC,EAAUN,EAAQ,MAAM,SAAWI,GAAc,IAAM,EAGvDG,EAAiCC,GAAQ,IAAM,CACnD,GAAI,GAACN,GAAe,CAACD,GAErB,GAAI,CACF,IAAMR,EAAWO,EAAQ,MAAM,UAAY,GACrCS,EAAYlB,GAAWS,EAAQ,OAAQP,CAAQ,EAC/CiB,EAAOb,GAAsBG,EAAQ,GAAIS,CAAS,EAExD,MAAO,CACL,GAAIT,EAAQ,MAAM,QAClB,KAAAU,EACA,MAAO,GACT,CACF,MAAQ,CAEN,MACF,CACF,EAAG,CACDV,EAAQ,MAAM,QACdA,EAAQ,MAAM,SACdA,EAAQ,GACRA,EAAQ,OACRC,EACAC,CACF,CAAC,EAGKS,EAAMC,GAAyBL,EAAID,CAAO,EAGhD,MAAO,CACL,OAAQK,EAAI,OACZ,aAAcA,EAAI,aAClB,MAAOA,EAAI,MACX,WAAYA,EAAI,SAChB,MAAOA,EAAI,KACb,CACF,CClJA,OAAS,YAAAE,GAAU,eAAAC,GAAa,UAAAC,OAAc,QAqBvC,SAASC,GAAUC,EAA0C,CAClE,IAAMC,EAAaC,GAAqB,EAClCC,EAAmBH,GAAWC,EAE9B,CAACG,EAAQC,CAAS,EAAIC,GAA+B,IAAI,EACzD,CAACC,EAAiBC,CAAkB,EAAIF,GAA+B,IAAI,EAC3E,CAACG,EAAcC,CAAe,EAAIJ,GAA+B,IAAI,EACrEK,EAAYC,GAAqC,IAAI,EAGrDC,EAAsBD,GAAgD,IAAI,EAC1EE,EAAmBF,GAAgD,IAAI,EAGzET,IACGU,EAAoB,UACvBA,EAAoB,QAAWE,GAAyB,CACtDP,EAAmBO,CAAK,GACpB,CAACJ,EAAU,SAAWI,EAAM,WAAaJ,EAAU,QAAQ,aAC7DN,EAAUU,CAAK,EACfJ,EAAU,QAAUI,EAExB,EACAZ,EAAiB,GAAG,YAAaU,EAAoB,OAAO,GAGzDC,EAAiB,UACpBA,EAAiB,QAAWC,GAAyB,CACnDL,EAAgBK,CAAK,GACjB,CAACJ,EAAU,SAAWI,EAAM,WAAaJ,EAAU,QAAQ,aAC7DN,EAAUU,CAAK,EACfJ,EAAU,QAAUI,EAExB,EACAZ,EAAiB,GAAG,SAAUW,EAAiB,OAAO,IAI1D,IAAME,EAAQC,GAAY,IAAM,CAC9BZ,EAAU,IAAI,EACdG,EAAmB,IAAI,EACvBE,EAAgB,IAAI,EACpBC,EAAU,QAAU,IACtB,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,OAAAP,EACA,gBAAAG,EACA,aAAAE,EACA,MAAAO,CACF,CACF,CCzDA,OAAS,YAAAE,GAAU,eAAAC,GAAa,aAAAC,GAAW,UAAAC,OAAc,QA8ClD,SAASC,GAAgBC,EAAyD,CACvF,GAAM,CAAE,WAAAC,CAAW,EAAIC,EAAW,EAC5B,CAACC,EAASC,CAAU,EAAIC,GAAyB,IAAI,EACrD,CAACC,EAAYC,CAAa,EAAIF,GAAS,EAAK,EAC5C,CAACG,EAAaC,CAAc,EAAIJ,GAAkC,IAAI,EACtE,CAACK,EAAWC,CAAY,EAAIN,GAAS,EAAK,EAC1C,CAACO,EAAOC,CAAQ,EAAIR,GAAuB,IAAI,EAC/CS,EAAaC,GAAmE,IAAI,EAG1FC,GAAU,IAAM,CACd,GAAI,CAAChB,GAAS,OAAQ,CACpBc,EAAW,QAAU,KACrB,MACF,CAEA,IAAIG,EAAY,GAEhB,cAAO,uBAAuB,EAAE,KAAK,CAAC,CAAE,oBAAAC,CAAoB,IAAM,CAC5DD,IACJH,EAAW,QAAU,IAAII,EAAoB,CAC3C,OAAQlB,EAAQ,OAChB,QAASA,EAAQ,SAAW,WAC5B,cAAe,CACb,IAAKA,EAAQ,YAAc,EAC7B,CACF,CAAC,EACH,CAAC,EAAE,MAAOmB,GAAQ,CACZF,GACJJ,EAASM,aAAe,MAAQA,EAAM,IAAI,MAAM,2CAA2C,CAAC,CAC9F,CAAC,EAEM,IAAM,CAAEF,EAAY,EAAM,CACnC,EAAG,CAACjB,GAAS,OAAQA,GAAS,WAAYA,GAAS,OAAO,CAAC,EAG3D,IAAMoB,EAAYC,GAAY,IAAiC,CAC7D,IAAMC,EAAQrB,EACd,MAAI,CAACqB,GAAS,CAACR,EAAW,QAAgB,KAInC,CACL,MAHcQ,EAAM,SAAS,GAAG,EAAIA,EAAM,MAAM,GAAG,EAAE,IAAI,EAAgBA,EAIzE,YAAatB,GAAS,aAAe,SACrC,WAAY,6CACZ,QAASA,GAAS,SAAW,WAC7B,KAAMA,GAAS,IACjB,CACF,EAAG,CAACC,EAAYD,GAAS,YAAaA,GAAS,QAASA,GAAS,IAAI,CAAC,EAGhEuB,EAAeF,GAAY,SAA8C,CAC7E,IAAMG,EAASJ,EAAU,EACzB,GAAI,CAACI,GAAU,CAACV,EAAW,QACzB,OAAAD,EAAS,IAAI,MAAM,8BAA8B,CAAC,EAC3C,KAGTF,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMY,EAAO,MAAMX,EAAW,QAAQ,cAAcU,CAAM,EAC1D,OAAApB,EAAWqB,EAAK,OAAO,EACvBlB,EAAckB,EAAK,UAAU,EAC7BhB,EAAegB,CAAI,EACZA,CACT,OAASN,EAAK,CACZ,IAAMO,EAAIP,aAAe,MAAQA,EAAM,IAAI,MAAM,gCAAgC,EACjF,OAAAN,EAASa,CAAC,EACH,IACT,QAAE,CACAf,EAAa,EAAK,CACpB,CACF,EAAG,CAACS,CAAS,CAAC,EAGRO,EAAeN,GAAY,SAAqC,CACpE,IAAMG,EAASJ,EAAU,EACzB,GAAI,CAACI,GAAU,CAACV,EAAW,QACzB,OAAAD,EAAS,IAAI,MAAM,8BAA8B,CAAC,EAC3C,KAGTF,EAAa,EAAI,EACjBE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMe,EAAe,MAAMd,EAAW,QAAQ,cAAcU,CAAM,EAGlE,GAAII,EAAc,CAChB,IAAMH,EAAO,MAAMX,EAAW,QAAQ,cAAcU,CAAM,EAC1DpB,EAAWqB,EAAK,OAAO,EACvBlB,EAAc,EAAI,EAClBE,EAAegB,CAAI,CACrB,CAEA,OAAOG,CACT,OAAST,EAAK,CACZ,IAAMO,EAAIP,aAAe,MAAQA,EAAM,IAAI,MAAM,gCAAgC,EACjF,OAAAN,EAASa,CAAC,EACH,IACT,QAAE,CACAf,EAAa,EAAK,CACpB,CACF,EAAG,CAACS,CAAS,CAAC,EAGRS,EAAaR,GAAY,SAAqC,CAClE,IAAMG,EAASJ,EAAU,EACzB,GAAI,CAACI,GAAU,CAACV,EAAW,QAAS,OAAO,KAE3C,GAAI,CAEF,OADa,MAAMA,EAAW,QAAQ,kBAAkBU,CAAM,CAEhE,MAAQ,CACN,OAAO,IACT,CACF,EAAG,CAACJ,CAAS,CAAC,EAEd,MAAO,CACL,QAAAjB,EACA,WAAAG,EACA,YAAAE,EACA,UAAAE,EACA,MAAAE,EACA,aAAAW,EACA,aAAAI,EACA,WAAAE,CACF,CACF,CC5KA,OAAS,YAAAC,GAAU,eAAAC,GAAa,UAAAC,OAAc,QAgDvC,SAASC,GACdC,EAC4B,CAC5B,GAAM,CAACC,EAAYC,CAAa,EAAIN,GAAqB,IAAI,EACvD,CAACO,EAASC,CAAU,EAAIR,GAAsC,IAAI,EAClE,CAACS,EAAWC,CAAY,EAAIV,GAAS,EAAK,EAC1C,CAACW,EAAcC,CAAe,EAAIZ,GAAS,EAAK,EAChD,CAACa,EAAOC,CAAQ,EAAId,GAAuB,IAAI,EAC/Ce,EAAWb,GAA+B,IAAI,EAE9Cc,EAAaf,GACjB,MACEgB,EACAC,IAC0C,CAC1C,GAAI,CAACd,GAAS,WACZ,OAAAU,EAAS,IAAI,MAAM,4BAA4B,CAAC,EACzC,KAGT,GAAI,CAACG,EAAM,OACT,OAAAH,EAAS,IAAI,MAAM,+BAA+B,CAAC,EAC5C,KAITC,EAAS,SAAS,MAAM,EACxBA,EAAS,QAAU,IAAI,gBAEvBL,EAAa,EAAI,EACjBE,EAAgB,EAAI,EACpBE,EAAS,IAAI,EACbR,EAAc,IAAI,EAClBE,EAAW,IAAI,EAEf,GAAI,CACF,GAAM,CAAE,oBAAAW,EAAqB,cAAAC,EAAe,kBAAAC,EAAmB,kBAAAC,EAAmB,mBAAAC,CAAmB,EACnG,KAAM,QAAO,uBAAuB,EAGhCC,EAAWJ,EAAcH,CAAK,EAG9BQ,EAAarB,GAAS,YAC1B,6CAEEsB,EAAc,CAChB,aAAc,QACd,qBAAsB,QACtB,mBAAoB,MACtB,EAEAd,EAAgB,EAAK,EAErB,GAAI,CASFc,EARY,KAAM,QAAO,uBAAuB,EAAE,KAChD,CAAC,CAAE,yBAAAC,CAAyB,IAC1BA,EACE,CAAE,SAAAH,EAAU,OAAQ,4CAAwD,EAC5EC,EACArB,EAAQ,UACV,CACJ,CAEF,MAAQ,CAER,CAGA,IAAIwB,EAAe,aACfC,EAAuB,YAE3B,GAAIzB,EAAQ,OACV,GAAI,CACF,IAAM0B,EAAU,MAAM,MAAM1B,EAAQ,OAAQ,CAC1C,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CACnB,QAAS,MACT,GAAI,EACJ,OAAQ,uBACR,OAAQ,CAAC,SAAU,EAAK,CAC1B,CAAC,EACD,OAAQW,EAAS,QAAQ,MAC3B,CAAC,EAAE,KAAKgB,GAAKA,EAAE,KAAK,CAAC,EAAE,KAAKC,GACtBA,EAAE,QAAQ,cAAsB,OAAOA,EAAE,OAAO,aAAa,EAC1D,IACR,EAEKC,EAAc,MAAM,MAAM7B,EAAQ,OAAQ,CAC9C,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CACnB,QAAS,MACT,GAAI,EACJ,OAAQ,2BACR,OAAQ,CAAC,CACX,CAAC,EACD,OAAQW,EAAS,QAAQ,MAC3B,CAAC,EAAE,KAAKgB,GAAKA,EAAE,KAAK,CAAC,EAAE,KAAKC,GACtBA,EAAE,OAAe,OAAOA,EAAE,MAAM,EAC7B,IACR,EAEGF,GAAWG,IACbL,EAAeE,EAAU,GAAKG,EAC9BJ,EAAuBI,EAE3B,MAAQ,CAER,CAIEf,GAAM,cAAc,eAAcQ,EAAY,aAAeR,EAAK,aAAa,cAC/EA,GAAM,cAAc,uBAAsBQ,EAAY,qBAAuBR,EAAK,aAAa,sBAC/FA,GAAM,cAAc,qBAAoBQ,EAAY,mBAAqBR,EAAK,aAAa,oBAC3FA,GAAM,cAAc,eAAcU,EAAeV,EAAK,aAAa,cACnEA,GAAM,cAAc,uBAAsBW,EAAuBX,EAAK,aAAa,sBAGvF,IAAMgB,EAASX,EAAmB,CAChC,OAAQ,6CACR,MAAO,GACP,SAAAC,EACA,iBAAkB,KAAKE,EAAY,qBAAqB,SAAS,EAAE,EAAE,SAAS,GAAI,GAAG,CAAC,GAAGA,EAAY,aAAa,SAAS,EAAE,EAAE,SAAS,GAAI,GAAG,CAAC,GAChJ,mBAAoBA,EAAY,mBAChC,aAAAE,EACA,qBAAAC,CACF,CAAC,EAGKM,EAAW,MAAMb,EACrBY,EACA9B,EAAQ,WACRqB,CACF,EAEA,OAAAnB,EAAc6B,EAAS,UAAU,EAGjCC,GAAaD,EAAS,WAAY/B,EAAQ,WAAaqB,CAAU,EAC9D,KAAMY,GAAS,CACVA,GAAM7B,EAAW6B,CAAI,CAC3B,CAAC,EACA,MAAM,IAAM,CAEb,CAAC,EAEIF,CACT,OAASG,EAAK,CACZ,IAAMzB,EAAQyB,aAAe,MAAQA,EAAM,IAAI,MAAM,8BAA8B,EACnF,OAAAxB,EAASD,CAAK,EACP,IACT,QAAE,CACAH,EAAa,EAAK,EAClBE,EAAgB,EAAK,CACvB,CACF,EACA,CAACR,CAAO,CACV,EAEMmC,EAAQtC,GAAY,IAAM,CAC9BK,EAAc,IAAI,EAClBE,EAAW,IAAI,EACfE,EAAa,EAAK,EAClBE,EAAgB,EAAK,EACrBE,EAAS,IAAI,CACf,EAAG,CAAC,CAAC,EAEL,MAAO,CACL,WAAAE,EACA,WAAAX,EACA,QAAAE,EACA,UAAAE,EACA,aAAAE,EACA,MAAAE,EACA,MAAA0B,CACF,CACF,CAKA,eAAeH,GACb/B,EACAmC,EACAf,EACAgB,EAAa,GACbC,EAAa,IACyB,CACtC,QAAS,EAAI,EAAG,EAAID,EAAY,IAAK,CACnC,GAAI,CAYF,IAAME,EAAO,MAXI,MAAM,MAAMH,EAAY,CACvC,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CACnB,QAAS,MACT,GAAI,EACJ,OAAQ,8BACR,OAAQ,CAACnC,CAAU,CACrB,CAAC,CACH,CAAC,GAE2B,KAAK,EAejC,GAAIsC,EAAK,OACP,MAAO,CACL,WAAYA,EAAK,OAAO,WACxB,WAAYA,EAAK,OAAO,WACxB,OAAQA,EAAK,OAAO,OACpB,MAAO,OAAOA,EAAK,OAAO,KAAK,EAC/B,UAAWA,EAAK,OAAO,UACvB,cAAe,OAAOA,EAAK,OAAO,aAAa,EAC/C,cAAe,OAAOA,EAAK,OAAO,aAAa,EAC/C,QAASA,EAAK,OAAO,QACrB,gBAAiBA,EAAK,OAAO,gBAC7B,KAAMA,EAAK,OAAO,IACpB,CAEJ,MAAQ,CAER,CAEI,EAAIF,EAAa,GACnB,MAAM,IAAI,QAAQG,GAAW,WAAWA,EAASF,CAAU,CAAC,CAEhE,CAEA,OAAO,IACT,CCpSA,OAAS,YAAAG,EAAU,aAAAC,GAAW,UAAAC,GAAQ,eAAAC,OAAmB,QAmDlD,SAASC,GACdC,EACuB,CACvB,IAAMC,EAAaD,GAAS,WACtBE,EAAeF,GAAS,cAAgB,IACxCG,EAAaH,GAAS,YAAc,GAEpC,CAACI,EAAQC,CAAS,EAAIV,EAAuB,MAAM,EACnD,CAACW,EAASC,CAAU,EAAIZ,EAAsC,IAAI,EAClE,CAACa,EAAYC,CAAa,EAAId,EAAqBK,GAAS,YAAc,IAAI,EAC9E,CAACU,EAAOC,CAAQ,EAAIhB,EAAuB,IAAI,EAC/C,CAACiB,EAAWC,CAAY,EAAIlB,EAAS,EAAK,EAC1C,CAACmB,EAAUC,CAAW,EAAIpB,EAAS,CAAC,EAEpCqB,EAAenB,GAAe,CAAC,EAC/B,CAACoB,EAAWC,CAAY,EAAIvB,EAAS,CAAC,EACtCwB,EAActB,GAA8C,IAAI,EAChEuB,EAAevB,GAA6C,IAAI,EAGhEwB,EAAcvB,GAAY,IAAM,CAChCqB,EAAY,UACd,cAAcA,EAAY,OAAO,EACjCA,EAAY,QAAU,MAEpBC,EAAa,UACf,aAAaA,EAAa,OAAO,EACjCA,EAAa,QAAU,KAE3B,EAAG,CAAC,CAAC,EAGCE,EAAOxB,GAAY,MAAOyB,GAAc,CAC5C,GAAKtB,EAEL,GAAI,CACF,IAAMuB,EAAW,MAAM,MAAMvB,EAAY,CACvC,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,UAAU,CACnB,QAAS,MACT,GAAI,EACJ,OAAQ,8BACR,OAAQ,CAACsB,CAAI,CACf,CAAC,CACH,CAAC,EAED,GAAI,CAACC,EAAS,GAAI,OAElB,IAAMC,EAAO,MAAMD,EAAS,KAAK,EAejC,GAAIC,EAAK,OAAQ,CACf,IAAMC,EAAoC,CACxC,WAAYD,EAAK,OAAO,WACxB,WAAYA,EAAK,OAAO,WACxB,OAAQA,EAAK,OAAO,OACpB,MAAO,OAAOA,EAAK,OAAO,KAAK,EAC/B,UAAWA,EAAK,OAAO,UACvB,cAAe,OAAOA,EAAK,OAAO,aAAa,EAC/C,cAAe,OAAOA,EAAK,OAAO,aAAa,EAC/C,QAASA,EAAK,OAAO,QACrB,gBAAiBA,EAAK,OAAO,gBAC7B,KAAMA,EAAK,OAAO,IACpB,EAEAlB,EAAWmB,CAAW,EACtBrB,EAAUoB,EAAK,OAAO,QAAU,YAAc,QAAQ,EACtDZ,EAAa,EAAK,EAClBQ,EAAY,EAEZ,MACF,CAGAN,EAAYY,GAAQA,EAAO,CAAC,EAC5BtB,EAAU,SAAS,EAEfS,EAAWX,EACbiB,EAAa,QAAU,WAAW,IAAME,EAAKC,CAAI,EAAGrB,CAAY,GAEhEG,EAAU,WAAW,EACrBQ,EAAa,EAAK,EAClBQ,EAAY,EACZV,EAAS,IAAI,MAAM,kDAAkD,CAAC,EAE1E,MAAQ,CAENI,EAAYY,GAAQA,EAAO,CAAC,EACxBb,EAAWX,IACbiB,EAAa,QAAU,WAAW,IAAME,EAAKC,CAAI,EAAGrB,CAAY,EAEpE,CACF,EAAG,CAACD,EAAYC,EAAcC,EAAYW,EAAUO,CAAW,CAAC,EAG1DO,EAAQ9B,GAAayB,GAAc,CACvCF,EAAY,EACZZ,EAAcc,CAAI,EAClBlB,EAAU,SAAS,EACnBE,EAAW,IAAI,EACfI,EAAS,IAAI,EACbI,EAAY,CAAC,EACbF,EAAa,EAAI,EACjBG,EAAa,QAAU,KAAK,IAAI,EAGhCG,EAAY,QAAU,YAAY,IAAM,CACtCD,EAAa,KAAK,IAAI,EAAIF,EAAa,OAAO,CAChD,EAAG,GAAI,EAGPM,EAAKC,CAAI,CACX,EAAG,CAACF,EAAaC,CAAI,CAAC,EAGhBO,EAAO/B,GAAY,IAAM,CAC7BuB,EAAY,EACZR,EAAa,EAAK,CACpB,EAAG,CAACQ,CAAW,CAAC,EAGVS,EAAQhC,GAAY,IAAM,CAC9BuB,EAAY,EACZZ,EAAc,IAAI,EAClBJ,EAAU,MAAM,EAChBE,EAAW,IAAI,EACfI,EAAS,IAAI,EACbE,EAAa,EAAK,EAClBE,EAAY,CAAC,EACbG,EAAa,CAAC,CAChB,EAAG,CAACG,CAAW,CAAC,EAGhB,OAAAzB,GAAU,IAAM,CACVI,GAAS,YAAcA,GAAS,YAAc,IAChD4B,EAAM5B,EAAQ,UAAU,CAI5B,EAAG,CAAC,CAAC,EAGLJ,GAAU,IACD,IAAM,CACXyB,EAAY,CACd,EACC,CAACA,CAAW,CAAC,EAET,CACL,OAAAjB,EACA,QAAAE,EACA,WAAAE,EACA,MAAAE,EACA,UAAAE,EACA,UAAAK,EACA,SAAAH,EACA,MAAAc,EACA,KAAAC,EACA,MAAAC,CACF,CACF,CC7OA,OAAS,YAAAC,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QACzD,OAAS,oBAAAC,OAAwB,wBA8B1B,SAASC,GACdC,EACAC,EACoB,CACpB,IAAMC,EAAaL,GAAgC,IAAI,EACjD,CAACM,EAAQC,CAAS,EAAIV,GAA2B,CAAC,CAAC,EACnD,CAACW,EAAWC,CAAY,EAAIZ,GAASO,GAAS,WAAa,EAAK,EAChE,CAACM,EAAUC,CAAW,EAAId,GAAS,EAAK,EACxC,CAACe,EAAOC,CAAQ,EAAIhB,GAAuB,IAAI,EAGrD,GAAI,CAACQ,EAAW,QAAS,CACvB,IAAMS,EAA0C,CAAC,EAC7CV,GAAS,UACXU,EAAO,QAAUV,EAAQ,SAE3BC,EAAW,QAAU,IAAIJ,GAAiBa,CAAM,CAClD,CAEA,IAAMC,EAAOhB,GAAY,SAAY,CACnC,IAAMiB,EAAUX,EAAW,QAC3B,GAAKW,EAEL,CAAAP,EAAa,EAAI,EACjBI,EAAS,IAAI,EAEb,GAAI,CACF,MAAMG,EAAQ,KAAK,EACnB,IAAMC,EAAiBd,EAAUe,GAAaf,CAAO,EAAI,OACnDgB,EAASH,EAAQ,UACrBC,IAAmB,OAAY,CAAE,QAASA,CAAe,EAAI,MAC/D,EACAV,EAAUY,CAAM,EAChBR,EAAY,EAAI,CAClB,OAASS,EAAK,CACZP,EAASO,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,CAAC,CAC9D,QAAE,CACAX,EAAa,EAAK,CACpB,EACF,EAAG,CAACN,CAAO,CAAC,EAENkB,EAAUtB,GAAY,SAAY,CACtC,IAAMiB,EAAUX,EAAW,QAC3B,GAAKW,EAEL,CAAAP,EAAa,EAAI,EACjBI,EAAS,IAAI,EAEb,GAAI,CACF,MAAMG,EAAQ,QAAQ,EACtB,IAAMC,EAAiBd,EAAUe,GAAaf,CAAO,EAAI,OACnDgB,EAASH,EAAQ,UACrBC,IAAmB,OAAY,CAAE,QAASA,CAAe,EAAI,MAC/D,EACAV,EAAUY,CAAM,EAChBR,EAAY,EAAI,CAClB,OAASS,EAAK,CACZP,EAASO,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,CAAC,CAC9D,QAAE,CACAX,EAAa,EAAK,CACpB,EACF,EAAG,CAACN,CAAO,CAAC,EAEZ,OAAAL,GAAU,IAAM,CACVM,GAAS,WAAa,IACxBW,EAAK,CAET,EAAG,CAACA,EAAMX,GAAS,QAAQ,CAAC,EAErB,CAAE,OAAAE,EAAQ,UAAAE,EAAW,SAAAE,EAAU,MAAAE,EAAO,QAAAS,CAAQ,CACvD,CAMA,SAASH,GAAaf,EAAqC,CACzD,IAAMmB,EAAQnB,EAAQ,MAAM,GAAG,EACzBoB,EAAU,SAASD,EAAMA,EAAM,OAAS,CAAC,EAAG,EAAE,EACpD,OAAO,MAAMC,CAAO,EAAI,OAAYA,CACtC,CC/GA,OAAS,YAAAC,GAAU,aAAAC,GAAW,UAAAC,OAAuB,QACrD,OAAS,oBAAAC,OAAwB,wBCHjC,OAEE,2BAAAC,GACA,kBAAAC,GACA,mBAAAC,GACA,mBAAAC,GACA,eAAAC,OACK,wBAMA,SAASC,IAAuC,CACrD,MAAO,CACL,CACE,KAAM,WACN,OAAQ,CACN,GAAGL,GACH,GAAGC,GACH,GAAGC,GACH,GAAGC,GACH,GAAGC,EACL,EACA,QAAS,EACX,EACA,CACE,KAAM,kBACN,IAAK,6BACL,QAAS,GACT,gBAAiB,KAAU,GAAK,GAClC,CACF,CACF,CD1BA,IAAME,GAAc,IAUhBC,GAAyC,KAE7C,SAASC,IAA+B,CACtC,OAAKD,KACHA,GAAgB,IAAIE,GAAiB,CACnC,QAASC,GAAkB,CAC7B,CAAC,EAEDH,GAAc,KAAK,EAAE,MAAM,IAAM,CAAC,CAAC,GAE9BA,EACT,CAYO,SAASI,GACdC,EACAC,EACsB,CACtB,GAAM,CAACC,EAASC,CAAU,EAAIC,GAA4B,CACxD,MAAO,CAAC,EACR,MAAO,CAAC,EACR,QAAS,EACX,CAAC,EACK,CAACC,EAAaC,CAAc,EAAIF,GAAS,EAAK,EAC9CG,EAAcC,GAA6C,IAAI,EAE/DC,EAAeT,EAAM,KAAK,EAEhC,OAAAU,GAAU,IAAM,CACd,GAAI,CAACD,EAAc,CACjBN,EAAW,CAAE,MAAO,CAAC,EAAG,MAAO,CAAC,EAAG,QAAS,EAAM,CAAC,EACnDG,EAAe,EAAK,EACpB,MACF,CAGA,OAAIC,EAAY,SACd,aAAaA,EAAY,OAAO,EAGlCD,EAAe,EAAI,EAEnBC,EAAY,QAAU,WAAW,IAAM,CACrC,IAAMI,EAAUf,GAAW,EACrBgB,EAAiBX,EAAUY,GAAaZ,CAAO,EAAI,OACnDa,EAAgBH,EAAQ,OAAOF,EAAc,CACjD,QAASG,EACT,MAAO,EACT,CAAC,EACDT,EAAWW,CAAa,EACxBR,EAAe,EAAK,CACtB,EAAGZ,EAAW,EAEP,IAAM,CACPa,EAAY,SACd,aAAaA,EAAY,OAAO,CAEpC,CACF,EAAG,CAACE,EAAcR,CAAO,CAAC,EAEnB,CAAE,QAAAC,EAAS,YAAAG,CAAY,CAChC,CAEA,SAASQ,GAAaZ,EAAqC,CACzD,IAAMc,EAAQd,EAAQ,MAAM,GAAG,EACzBe,EAAU,SAASD,EAAMA,EAAM,OAAS,CAAC,EAAG,EAAE,EACpD,OAAO,MAAMC,CAAO,EAAI,OAAYA,CACtC,CExFA,OAAOC,IAAS,eAAAC,OAAmB,QA8F7B,OA6HM,YAAAC,GArHJ,OAAAC,EARF,QAAAC,MAAA,oBA/DC,SAASC,GAAc,CAC5B,QAAAC,EACA,SAAAC,EACA,QAAAC,EACA,QAAAC,CACF,EAAuB,CACrB,GAAM,CAACC,EAAaC,CAAc,EAAIC,GAAM,SAAS,EAAE,EAEjD,CACJ,OAAQC,EACR,UAAAC,EACA,MAAAC,CACF,EAAIC,GAAaV,CAAO,EAElB,CAAE,QAAAW,EAAS,YAAAC,CAAY,EAAIC,GAC/BT,EACAA,EAAcJ,EAAU,MAC1B,EAEMc,EAAsBX,GAAS,qBAAuB,GAGtDY,EAAgBT,GAAM,QAAQ,IAAM,CACxC,GAAIF,EAAY,KAAK,EAAG,CACtB,IAAMY,EAAW,CAAC,GAAGL,EAAQ,MAAO,GAAGA,EAAQ,KAAK,EAAE,IAAKM,GAAMA,EAAE,KAAK,EACxE,OAAOd,GAAS,OACZa,EAAS,OAAOb,EAAQ,MAAM,EAC9Ba,CACN,CAEA,IAAME,EAASX,EACf,OAAOJ,GAAS,OACZe,EAAO,OAAOf,EAAQ,MAAM,EAC5Be,CACN,EAAG,CAACd,EAAaO,EAASJ,EAAWJ,GAAS,MAAM,CAAC,EAG/CgB,EAAgBb,GAAM,QAAQ,IAC9B,CAACQ,GAAuBV,EAAY,KAAK,EAAU,CAAC,EACjDG,EAAU,MAAM,EAAG,CAAC,EAC1B,CAACA,EAAWO,EAAqBV,CAAW,CAAC,EAE1CgB,EAAeC,GAClBC,GAA0B,CACzBrB,EAASqB,CAAK,EACdpB,EAAQ,CACV,EACA,CAACD,EAAUC,CAAO,CACpB,EAEA,OACEJ,EAAC,OACC,MAAO,CACL,WAAY,yBACZ,aAAc,OACd,QAAS,OACT,MAAO,yBACP,SAAU,QACV,SAAU,QACV,WAAY,uBACd,EAGA,UAAAA,EAAC,OACC,MAAO,CACL,QAAS,OACT,eAAgB,gBAChB,WAAY,SACZ,aAAc,MAChB,EAEA,UAAAD,EAAC,MAAG,MAAO,CAAE,OAAQ,EAAG,SAAU,OAAQ,WAAY,GAAI,EAAG,wBAE7D,EACAA,EAAC,UACC,QAASK,EACT,MAAO,CACL,WAAY,OACZ,OAAQ,OACR,MAAO,+BACP,OAAQ,UACR,SAAU,OACV,QAAS,SACX,EACD,kBAED,GACF,EAGAL,EAAC,SACC,KAAK,OACL,YAAY,qCACZ,MAAOO,EACP,SAAWmB,GAAMlB,EAAekB,EAAE,OAAO,KAAK,EAC9C,MAAO,CACL,MAAO,OACP,QAAS,YACT,aAAc,MACd,OAAQ,iBACR,WAAY,mBACZ,MAAO,yBACP,SAAU,OACV,QAAS,OACT,UAAW,aACX,aAAc,MAChB,EACA,UAAS,GACX,EAGCf,GAAa,CAACI,GACbf,EAAC,OAAI,MAAO,CAAE,UAAW,SAAU,QAAS,OAAQ,MAAO,8BAA+B,EAAG,6BAE7F,EAEDY,GACCX,EAAC,OACC,MAAO,CACL,UAAW,SACX,QAAS,OACT,MAAO,0BACP,SAAU,MACZ,EACD,oBACSW,EAAM,SAChB,EAIDK,GAAuBK,EAAc,OAAS,GAAK,CAACf,EAAY,KAAK,GACpEN,EAAC,OAAI,MAAO,CAAE,aAAc,MAAO,EACjC,UAAAD,EAAC,OACC,MAAO,CACL,SAAU,OACV,MAAO,+BACP,cAAe,YACf,cAAe,QACf,aAAc,KAChB,EACD,mBAED,EACAA,EAAC,OAAI,MAAO,CAAE,QAAS,OAAQ,IAAK,MAAO,SAAU,MAAO,EACzD,SAAAsB,EAAc,IAAKG,GAClBxB,EAAC,UAEC,QAAS,IAAMsB,EAAaE,CAAK,EACjC,MAAO,CACL,WAAY,mBACZ,OAAQ,iBACR,aAAc,OACd,QAAS,WACT,MAAO,yBACP,OAAQ,UACR,SAAU,OACV,QAAS,OACT,WAAY,SACZ,IAAK,KACP,EAEC,UAAAA,EAAM,QACLzB,EAAC,OACC,IAAKyB,EAAM,QACX,IAAI,GACJ,MAAO,CAAE,MAAO,OAAQ,OAAQ,OAAQ,aAAc,KAAM,EAC5D,QAAUC,GAAM,CACbA,EAAE,OAA4B,MAAM,QAAU,MACjD,EACF,EACE,KACHD,EAAM,SAzBF,GAAGA,EAAM,OAAO,IAAIA,EAAM,OAAO,EA0BxC,CACD,EACH,GACF,EAIDlB,EAAY,KAAK,GAAK,CAACI,GACtBX,EAAC,OACC,MAAO,CACL,SAAU,OACV,MAAO,+BACP,aAAc,KAChB,EAEC,SAAAkB,EAAc,OAAS,EACtBjB,EAAAF,GAAA,CACG,UAAAe,EAAQ,MAAM,OAAO,WAASA,EAAQ,MAAM,OAAO,SACnDA,EAAQ,QAAU,oBAAsB,IAC3C,EAEA,mBAEJ,EAIFd,EAAC,OACC,MAAO,CACL,UAAW,QACX,UAAW,OACX,QAAS,OACT,cAAe,SACf,IAAK,KACP,EAEC,SAAAkB,EAAc,IAAKO,GAClBxB,EAAC,UAEC,QAAS,IAAMsB,EAAaE,CAAK,EACjC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,OACL,QAAS,WACT,WAAY,cACZ,OAAQ,OACR,aAAc,MACd,MAAO,yBACP,OAAQ,UACR,UAAW,OACX,MAAO,OACP,SAAU,MACZ,EACA,aAAeC,GAAM,CAClBA,EAAE,OAAuB,MAAM,WAAa,kBAC/C,EACA,aAAeA,GAAM,CAClBA,EAAE,OAAuB,MAAM,WAAa,aAC/C,EAGA,UAAA1B,EAAC,OACC,MAAO,CACL,MAAO,OACP,OAAQ,OACR,aAAc,MACd,WAAY,qBACZ,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,SAAU,OACV,WAAY,IACZ,WAAY,EACZ,SAAU,QACZ,EAEC,SAAAyB,EAAM,QACLzB,EAAC,OACC,IAAKyB,EAAM,QACX,IAAKA,EAAM,OACX,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,EACvC,QAAUC,GAAM,CACd,IAAMC,EAAMD,EAAE,OACdC,EAAI,MAAM,QAAU,OACnBA,EAAI,cAA8B,YACjCF,EAAM,OAAO,MAAM,EAAG,CAAC,CAC3B,EACF,EAEAA,EAAM,OAAO,MAAM,EAAG,CAAC,EAE3B,EAGAxB,EAAC,OAAI,MAAO,CAAE,KAAM,EAAG,SAAU,CAAE,EACjC,UAAAD,EAAC,OACC,MAAO,CACL,WAAY,IACZ,SAAU,OACV,SAAU,SACV,aAAc,WACd,WAAY,QACd,EAEC,SAAAyB,EAAM,OACT,EACAzB,EAAC,OACC,MAAO,CACL,SAAU,OACV,MAAO,+BACP,SAAU,SACV,aAAc,WACd,WAAY,QACd,EAEC,SAAAyB,EAAM,KACT,GACF,EAGAxB,EAAC,OACC,MAAO,CACL,SAAU,OACV,MAAO,OACP,UAAW,QACX,WAAY,CACd,EAEA,UAAAA,EAAC,OAAK,UAAAwB,EAAM,SAAS,aAAS,EAC9BxB,EAAC,OAAI,mBAAOwB,EAAM,SAAQ,GAC5B,IA7FK,GAAGA,EAAM,OAAO,IAAIA,EAAM,OAAO,EA8FxC,CACD,EACH,GACF,CAEJ,CCjUA,OAAS,YAAAG,GAAU,eAAAC,EAAa,WAAAC,GAAS,aAAAC,GAAW,UAAAC,OAAc,QAClE,OACE,gBAAAC,OAKK,wBACP,OAAS,wBAAAC,OAA4B,wBAIrC,IAAMC,GAAyC,CAC7C,SAAU,GACV,QAAS,GACT,MAAO,GACP,UAAW,aACX,YAAa,CAAC,EACd,WAAY,CAAC,CACf,EAEMC,GAAuB,+BAUtB,SAASC,GAAgBC,EAS7B,CAGD,IAAMC,EAAaP,GAA4B,IAAI,EAE9CO,EAAW,UACdA,EAAW,QAAUD,GAAS,SAAW,IAAIL,IAG/C,IAAMO,EAAUD,EAAW,QAIrB,CAACE,EAAeC,CAAgB,EAAId,GAA6B,IACrEY,EAAQ,WAAW,CACrB,EAEM,CAACG,EAAUC,CAAgB,EAAIhB,GAA+B,IAE3DO,EACR,EAIDJ,GAAU,IAAM,EACEO,GAAS,SAAWO,GAAmB,GAC/C,QAA8BT,EAAoB,EAAE,KAAMU,GAAU,CACtEA,GACFF,EAAiBE,CAAK,CAE1B,CAAC,CAEH,EAAG,CAAC,CAAC,EAILf,GAAU,KAERS,EAAQ,eAAkBO,GAAS,CACjCL,EAAkBM,GAAS,CAAC,GAAGA,EAAMD,CAAI,CAAC,CAC5C,EAGAP,EAAQ,QAAQ,EAAE,KAAK,IAAM,CAC3BE,EAAiBF,EAAQ,WAAW,CAAC,CACvC,CAAC,EAEM,IAAM,CAEXA,EAAQ,eAAiB,MAC3B,GAEC,CAAC,CAAC,EAIL,IAAMS,EAAcnB,GAAQ,IACnBW,EAAc,OAAQS,GAAM,CAACA,EAAE,IAAI,EAAE,OAC3C,CAACT,CAAa,CAAC,EAIZU,EAAQtB,EAAY,IAAM,CAC9BW,EAAQ,MAAM,EACdE,EAAiB,CAAC,CAAC,CACrB,EAAG,CAACF,CAAO,CAAC,EAENY,EAAWvB,EAAawB,GAAe,CAC3C,IAAMC,EAAUd,EAAQ,WAAW,EAAE,OAAQU,GAAMA,EAAE,KAAOG,CAAE,EAE9Db,EAAQ,MAAM,EAEd,QAAQ,IACNc,EAAQ,IAAKP,GACXP,EAAQ,KAAK,CACX,GAAIO,EAAK,GACT,OAAQ,GACR,OAAQA,EAAK,OACb,QAAS,GACT,UAAWA,EAAK,UAChB,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,KAAMA,EAAK,KACX,eAAgBA,EAAK,eACrB,YAAaA,EAAK,YAClB,UAAWA,EAAK,SAClB,CAAC,CACH,CACF,EAAE,KAAK,IAAM,CAEXL,EAAiBF,EAAQ,WAAW,CAAC,CACvC,CAAC,CACH,EAAG,CAACA,CAAO,CAAC,EAENe,EAAa1B,EAChBwB,GAAe,CACdb,EAAQ,WAAWa,CAAE,EACrBX,EAAkBM,GAChBA,EAAK,IAAKE,GAAOA,EAAE,KAAOG,EAAK,CAAE,GAAGH,EAAG,KAAM,EAAK,EAAIA,CAAE,CAC1D,CACF,EACA,CAACV,CAAO,CACV,EAEMgB,EAAgB3B,EAAY,IAAM,CACtCW,EAAQ,cAAc,EACtBE,EAAkBM,GAASA,EAAK,IAAKE,IAAO,CAAE,GAAGA,EAAG,KAAM,EAAK,EAAE,CAAC,CACpE,EAAG,CAACV,CAAO,CAAC,EAINiB,EAAkB5B,EACrBkB,GAAqD,CACpD,IAAMW,EAAyB,CAC7B,GAAGX,EACH,GAAI,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,CAAC,GACjE,UAAW,KAAK,IAAI,CACtB,EACAP,EAAQ,KAAK,CACX,GAAIkB,EAAK,GACT,OAAQ,GACR,OAAQA,EAAK,OACb,QAAS,GACT,UAAWA,EAAK,UAChB,OAAQA,EAAK,OACb,MAAOA,EAAK,MACZ,KAAMA,EAAK,KACX,eAAgBA,EAAK,eACrB,YAAaA,EAAK,YAClB,UAAWA,EAAK,SAClB,CAAC,CAEH,EACA,CAAClB,CAAO,CACV,EAIMmB,EAAiB9B,EACpB+B,GAA0C,CACzChB,EAAkBI,GAAS,CACzB,IAAMa,EAAO,CAAE,GAAGb,EAAM,GAAGY,CAAO,EAElC,OADgBtB,GAAS,SAAWO,GAAmB,GAC/C,QAAQT,GAAsByB,CAAI,EAAE,MAAM,IAAM,CAAC,CAAC,EACnDA,CACT,CAAC,CACH,EACA,CAACvB,GAAS,OAAO,CACnB,EAEMwB,EAAcjC,EACjBkC,GAAuB,CACtB,IAAMH,EAAwC,CAAC,EAC3CG,EAAS,SAAS,UAAU,IAAGH,EAAO,SAAW,IACjDG,EAAS,SAAS,SAAS,IAAGH,EAAO,QAAU,IAC/CG,EAAS,SAAS,OAAO,IAAGH,EAAO,MAAQ,IAC/CD,EAAeC,CAAM,CACvB,EACA,CAACD,CAAc,CACjB,EAEMK,EAAYnC,EACfoC,GAAoB,CACnBN,EAAe,CACb,YAAa,CAAC,GAAG,IAAI,IAAI,CAAC,GAAGhB,EAAS,YAAasB,CAAO,CAAC,CAAC,CAC9D,CAAC,CACH,EACA,CAACtB,EAAS,YAAagB,CAAc,CACvC,EAEMO,EAAcrC,EACjBoC,GAAoB,CACnBN,EAAe,CACb,YAAahB,EAAS,YAAY,OAAQwB,GAAMA,IAAMF,CAAO,CAC/D,CAAC,CACH,EACA,CAACtB,EAAS,YAAagB,CAAc,CACvC,EAIA,MAAO,CAEL,cAAAlB,EAEA,YAAAQ,EAEA,gBAAAQ,EAEA,MAAAN,EAEA,SAAAC,EAEA,WAAAG,EAEA,cAAAC,EAEA,SAAAb,EAEA,eAAAgB,EAEA,YAAAG,EAEA,UAAAE,EAEA,YAAAE,CACF,CACF,CAIA,SAASrB,IAAqB,CAC5B,IAAMuB,EAAUlC,GAAqB,QAAS,gBAAgB,EAE9D,MAAO,CACL,QAAS,MAAUmC,GAAmC,CACpD,GAAI,CACF,OAAO,MAAMD,EAAQ,IAAOC,CAAG,CACjC,OAASC,EAAG,CACV,eAAQ,KAAK,gDAAiDA,CAAC,EACxD,IACT,CACF,EACA,QAAS,MAAUD,EAAaE,IAA4B,CAC1D,GAAI,CACF,MAAMH,EAAQ,IAAIC,EAAKE,CAAK,CAC9B,OAASD,EAAG,CACV,QAAQ,KAAK,+CAAgDA,CAAC,CAChE,CACF,EACA,WAAY,MAAOD,GAA+B,CAChD,GAAI,CACF,MAAMD,EAAQ,OAAOC,CAAG,CAC1B,OAASC,EAAG,CACV,QAAQ,KAAK,kDAAmDA,CAAC,CACnE,CACF,CACF,CACF,CCxRA,OAAS,YAAAE,GAAU,eAAAC,GAAa,UAAAC,OAAc,QAC9C,OAAS,qBAAAC,OAAyB,yBAqD3B,SAASC,GACdC,EAC2B,CAC3B,IAAMC,EAASD,GAAS,OAClBE,EAAUF,GAAS,QAInBG,EAAaN,GAAiC,IAAI,EAExD,SAASO,GAAgC,CACvC,OAAKD,EAAW,UACdA,EAAW,QAAU,IAAIL,GAAkB,CACzC,QAAS,GACT,OAAAG,EACA,aAAc,EAChB,CAAC,GAEIE,EAAW,OACpB,CAIA,GAAM,CAACE,EAAQC,CAAS,EAAIX,GAAkC,IAAI,EAC5D,CAACY,EAASC,CAAU,EAAIb,GAAS,EAAK,EACtC,CAACc,EAAOC,CAAQ,EAAIf,GAAuB,IAAI,EAI/CgB,EAAWf,GACf,MACEgB,EACAC,EACAC,EACAC,EACAC,IAK8B,CAC9BR,EAAW,EAAI,EACfE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMO,EAAUb,EAAW,EACrBc,EAAgBF,GAAY,SAAWd,GAAW,EAClDiB,EAAeH,GAAY,QAAUf,EAErCmB,EAAY,MAAMH,EAAQ,sBAC9BL,EACAC,EACAC,EACAC,EACAG,EACAF,GAAY,QACd,EAEA,OAAAV,EAAUc,CAAS,EACZA,CACT,OAASC,EAAK,CACZ,IAAMC,EACJD,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,EACpD,MAAAX,EAASY,CAAQ,EACXA,CACR,QAAE,CACAd,EAAW,EAAK,CAClB,CACF,EACA,CAACP,EAAQC,CAAO,CAClB,EAIMqB,EAAQ3B,GAAY,IAAM,CAC9BU,EAAU,IAAI,EACdI,EAAS,IAAI,EACbF,EAAW,EAAK,CAClB,EAAG,CAAC,CAAC,EAIL,MAAO,CAAE,OAAAH,EAAQ,QAAAE,EAAS,MAAAE,EAAO,SAAAE,EAAU,MAAAY,CAAM,CACnD,CClIA,OAAS,YAAAC,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QA8ClD,SAASC,GACdC,EACAC,EACqB,CACrB,GAAM,CAAE,UAAAC,EAAW,QAAAC,EAAS,UAAAC,EAAW,QAAAC,EAAS,OAAAC,EAAQ,QAAAC,CAAQ,EAAIP,EAC9D,CAACQ,EAAQC,CAAS,EAAId,GAAkB,CAAC,CAAC,EAC1C,CAACe,EAASC,CAAU,EAAIhB,GAAS,EAAK,EACtC,CAACiB,EAAOC,CAAQ,EAAIlB,GAAuB,IAAI,EAC/CmB,EAAgBhB,GAA6C,IAAI,EACjEiB,EAAajB,GAAO,EAAI,EAExBkB,EAAcnB,GAAY,SAAY,CAC1C,GAAI,CAACK,GAAa,CAACC,GAAW,CAACC,GAAa,CAACE,GAAU,OAAOA,CAAM,GAAK,GAAI,CAC3EG,EAAU,CAAC,CAAC,EACZ,MACF,CAEA,GAAKR,EAEL,CAAAU,EAAW,EAAI,EACfE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMI,EAAS,MAAMhB,EACnBC,EACAC,EACAC,EACAE,EACAC,CACF,EAEIQ,EAAW,SACbN,EAAUQ,CAAM,CAEpB,OAASC,EAAK,CACRH,EAAW,UACbF,EAASK,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,CAAC,EAC5DT,EAAU,CAAC,CAAC,EAEhB,QAAE,CACIM,EAAW,SACbJ,EAAW,EAAK,CAEpB,EACF,EAAG,CAACT,EAAWC,EAASC,EAAWE,EAAQC,EAASN,CAAU,CAAC,EAG/DL,GAAU,IAAM,CAMd,GALIkB,EAAc,SAChB,aAAaA,EAAc,OAAO,EAIhC,CAACZ,GAAa,CAACC,GAAW,CAACC,GAAa,CAACE,EAAQ,CACnDG,EAAU,CAAC,CAAC,EACZ,MACF,CAEA,OAAAK,EAAc,QAAU,WAAW,IAAM,CACvCE,EAAY,CACd,EAAG,GAAG,EAEC,IAAM,CACPF,EAAc,SAChB,aAAaA,EAAc,OAAO,CAEtC,CACF,EAAG,CAACE,EAAad,EAAWC,EAASC,EAAWE,CAAM,CAAC,EAEvDV,GAAU,KACRmB,EAAW,QAAU,GACd,IAAM,CACXA,EAAW,QAAU,EACvB,GACC,CAAC,CAAC,EAEL,IAAMI,EAAUtB,GAAY,SAAY,CACtC,MAAMmB,EAAY,CACpB,EAAG,CAACA,CAAW,CAAC,EAEVI,EAAQvB,GAAY,IAAM,CAC9BY,EAAU,CAAC,CAAC,EACZI,EAAS,IAAI,EACbF,EAAW,EAAK,CAClB,EAAG,CAAC,CAAC,EAEL,MAAO,CAAE,OAAAH,EAAQ,QAAAE,EAAS,MAAAE,EAAO,QAAAO,EAAS,MAAAC,CAAM,CAClD,CC7IA,OAAS,YAAAC,GAAU,eAAAC,GAAa,UAAAC,OAAc,QAgDvC,SAASC,GACdC,EACuB,CACvB,GAAM,CAACC,EAAWC,CAAY,EAAIN,GAAS,EAAK,EAC1C,CAACO,EAAQC,CAAS,EAAIR,GAAoC,IAAI,EAC9D,CAACS,EAAOC,CAAQ,EAAIV,GAA8B,IAAI,EACtDW,EAAaT,GAAO,EAAI,EAExBU,EAAUX,GAAY,MAC1BY,EACAC,EACAC,IACG,CACH,GAAI,CAACX,EAAgB,CACnBM,EAAS,CACP,KAAM,cACN,QAAS,mCACX,CAAC,EACD,MACF,CAEAJ,EAAa,EAAI,EACjBI,EAAS,IAAI,EACbF,EAAU,IAAI,EAEd,GAAI,CACF,IAAMQ,EAAa,MAAMZ,EAAeS,EAAOC,EAAWC,CAAO,EAE7DJ,EAAW,SACbH,EAAUQ,CAAU,CAExB,OAASC,EAAK,CACZ,GAAIN,EAAW,QAAS,CACtB,IAAMO,EAAiBD,EACvBP,EAAS,CACP,KAAOQ,EAAuB,MAAQ,mBACtC,QAASA,EAAe,QACxB,QAAUA,EAAuB,OACnC,CAAC,CACH,CACF,QAAE,CACIP,EAAW,SACbL,EAAa,EAAK,CAEtB,CACF,EAAG,CAACF,CAAc,CAAC,EAEbe,EAAQlB,GAAY,IAAM,CAC9BO,EAAU,IAAI,EACdE,EAAS,IAAI,EACbJ,EAAa,EAAK,CACpB,EAAG,CAAC,CAAC,EAEL,MAAO,CAAE,QAAAM,EAAS,UAAAP,EAAW,OAAAE,EAAQ,MAAAE,EAAO,MAAAU,CAAM,CACpD,CCjGA,OAAS,YAAAC,GAAU,aAAAC,GAAW,eAAAC,GAAa,UAAAC,OAAc,QA8ClD,SAASC,GACdC,EACAC,EAKuB,CACvB,GAAM,CAAE,UAAAC,EAAW,OAAAC,EAAQ,QAAAC,CAAQ,EAAIJ,EACjC,CAACK,EAAaC,CAAc,EAAIX,GAA2B,CAAC,CAAC,EAC7D,CAACY,EAASC,CAAU,EAAIb,GAAS,EAAK,EACtC,CAACc,EAAOC,CAAQ,EAAIf,GAAuB,IAAI,EAC/CgB,EAAab,GAAO,EAAI,EAExBc,EAAmBf,GAAY,SAAY,CAC/C,GAAI,CAACM,GAAUA,EAAO,SAAW,EAAG,CAClCG,EAAe,CAAC,CAAC,EACjB,MACF,CAEA,GAAKL,EAEL,CAAAO,EAAW,EAAI,EACfE,EAAS,IAAI,EAEb,GAAI,CACF,IAAMG,EAAS,MAAMZ,EAAeC,EAAWC,EAAQC,CAAO,EAE1DO,EAAW,SACbL,EAAeO,CAAM,CAEzB,OAASC,EAAK,CACRH,EAAW,UACbD,EAASI,aAAe,MAAQA,EAAM,IAAI,MAAM,OAAOA,CAAG,CAAC,CAAC,EAC5DR,EAAe,CAAC,CAAC,EAErB,QAAE,CACIK,EAAW,SACbH,EAAW,EAAK,CAEpB,EACF,EAAG,CAACN,EAAWC,EAAQC,EAASH,CAAc,CAAC,EAE/CL,GAAU,IAAM,CACdgB,EAAiB,CACnB,EAAG,CAACA,CAAgB,CAAC,EAErBhB,GAAU,KACRe,EAAW,QAAU,GACd,IAAM,CACXA,EAAW,QAAU,EACvB,GACC,CAAC,CAAC,EAEL,IAAMI,EAAUlB,GAAY,SAAY,CACtC,MAAMe,EAAiB,CACzB,EAAG,CAACA,CAAgB,CAAC,EAErB,MAAO,CAAE,YAAAP,EAAa,QAAAE,EAAS,MAAAE,EAAO,QAAAM,CAAQ,CAChD,CC9HA,OAAS,mBAAAC,MAAuB,uCAChC,OAAOC,MAAW,QAIlB,OAAS,mBAAmBC,GAAwB,uBAAuBC,OAA6B,iEACxG,OAAS,uBAAuBC,GAA4B,uBAAuBC,OAAiC,sEACpH,OAAS,qBAAqBC,GAA0B,uBAAuBC,OAA+B,oEAC9G,OAAS,gBAAgBC,GAAqB,uBAAuBC,OAA0B,8DAC/F,OAAS,eAAeC,GAAoB,uBAAuBC,OAAyB,6DAC5F,OAAS,gBAAgBC,GAAqB,uBAAuBC,OAA0B,8DAC/F,OAAS,qBAAqBC,GAA0B,uBAAuBC,OAA+B,oEAC9G,OAAS,yBAAyBC,GAA8B,uBAAuBC,OAAmC,wEAC1H,OAAS,oBAAoBC,GAAyB,uBAAuBC,OAA8B,mEAC3G,OAAS,oBAAoBC,GAAyB,uBAAuBC,OAA8B,mEAC3G,OAAS,mBAAmBC,GAAwB,uBAAuBC,OAA6B,kEACxG,OAAS,cAAcC,GAAmB,uBAAuBC,OAAwB,4DACzF,OAAS,kBAAkBC,GAAuB,uBAAuBC,OAA4B,gEACrG,OAAS,qBAAqBC,GAA0B,uBAAuBC,OAA+B,mEAC9G,OAAS,uBAAuBC,GAA4B,uBAAuBC,OAAiC,sEACpH,OAAS,gBAAgBC,GAAqB,uBAAuBC,OAA0B,8DAC/F,OAAS,sBAAsBC,GAA2B,uBAAuBC,OAAgC,qEACjH,OAAS,eAAeC,GAAoB,uBAAuBC,OAAyB,6DAC5F,OAAS,iBAAiBC,GAAsB,uBAAuBC,OAA2B,+DAClG,OAAS,kBAAkBC,GAAuB,uBAAuBC,OAA4B,gEACrG,OAAS,oBAAoBC,GAAyB,uBAAuBC,OAA8B,mEAC3G,OAAS,gBAAgBC,GAAqB,uBAAuBC,OAA0B,8DAC/F,OAAS,mBAAmBC,GAAwB,uBAAuBC,OAA6B,iEACxG,OAAS,kBAAkBC,GAAuB,uBAAuBC,OAA4B,gEACrG,OAAS,gBAAgBC,GAAqB,uBAAuBC,OAA0B,8DAC/F,OAAS,cAAcC,GAAmB,uBAAuBC,OAAwB,4DACzF,OAAS,qBAAqBC,GAA0B,uBAAuBC,OAA+B,oEAC9G,OAAS,iBAAiBC,GAAsB,uBAAuBC,OAA2B,+DAI3F,IAAMC,GAAkI1D,EAA2F,CACtO,QAAS,mBACT,aAAcE,GAEd,MAAOD,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqBE,EACzB,CAAC,EAIYwD,GAAkJ3D,EAAuG,CAClQ,QAAS,wBACT,aAAcI,GAEd,MAAOH,EACP,OAAQ,CAAC,EACT,oBAAqBI,EACzB,CAAC,EAOYuD,GAA0I5D,EAAiG,CACpP,QAAS,sBACT,aAAcM,GAEd,MAAOL,EACP,OAAQ,CACJ,cAAe,cACf,mBAAoB,kBACxB,EACA,oBAAqBM,EACzB,CAAC,EAIYsD,GAAsH7D,EAAkF,CACjN,QAAS,gBACT,aAAcQ,GAEd,MAAOP,EACP,OAAQ,CAAC,EACT,oBAAqBQ,EACzB,CAAC,EAIYqD,GAAkH9D,EAA+E,CAC1M,QAAS,eACT,aAAcU,GAEd,MAAOT,EACP,OAAQ,CAAC,EACT,oBAAqBU,EACzB,CAAC,EAIYoD,GAAsH/D,EAAkF,CACjN,QAAS,gBACT,aAAcY,GAEd,MAAOX,EACP,OAAQ,CAAC,EACT,oBAAqBY,EACzB,CAAC,EAIYmD,GAA8GhE,EAA4E,CACnM,QAAS,cACT,aAAcwB,GAEd,MAAOvB,EACP,OAAQ,CAAC,EACT,oBAAqBwB,EACzB,CAAC,EAIYwC,GAA0IjE,EAAiG,CACpP,QAAS,sBACT,aAAcc,GAEd,MAAOb,EACP,OAAQ,CAAC,EACT,oBAAqBc,EACzB,CAAC,EAIYmD,GAA0JlE,EAA6G,CAChR,QAAS,0BACT,aAAcgB,GAEd,MAAOf,EACP,OAAQ,CAAC,EACT,oBAAqBgB,EACzB,CAAC,EAIYkD,GAAsInE,EAA8F,CAC7O,QAAS,qBACT,aAAckB,GAEd,MAAOjB,EACP,OAAQ,CAAC,EACT,oBAAqBkB,EACzB,CAAC,EAIYiD,GAAsIpE,EAA8F,CAC7O,QAAS,qBACT,aAAcoB,GAEd,MAAOnB,EACP,OAAQ,CAAC,EACT,oBAAqBoB,EACzB,CAAC,EAIYgD,GAAkIrE,EAA2F,CACtO,QAAS,oBACT,aAAcsB,GAEd,MAAOrB,EACP,OAAQ,CAAC,EACT,oBAAqBsB,EACzB,CAAC,EAIY+C,GAA8HtE,EAAwF,CAC/N,QAAS,kBACT,aAAc0B,GAEd,MAAOzB,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqB0B,EACzB,CAAC,EAIY4C,GAA0IvE,EAAiG,CACpP,QAAS,qBACT,aAAc4B,GAEd,MAAO3B,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqB4B,EACzB,CAAC,EAWY2C,GAAkJxE,EAAuG,CAClQ,QAAS,wBACT,aAAc8B,GAEd,MAAO7B,EACP,OAAQ,CACJ,gBAAiB,gBACjB,mBAAoB,mBACpB,qBAAsB,qBACtB,cAAe,cACf,uBAAwB,uBACxB,oBAAqB,mBACzB,EACA,oBAAqB8B,EACzB,CAAC,EAOY0C,GAAsHzE,EAAkF,CACjN,QAAS,gBACT,aAAcgC,GAEd,MAAO/B,EACP,OAAQ,CACJ,cAAe,cACf,mBAAoB,kBACxB,EACA,oBAAqBgC,EACzB,CAAC,EAIYyC,GAA8I1E,EAAoG,CAC3P,QAAS,uBACT,aAAckC,GAEd,MAAOjC,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqBkC,EACzB,CAAC,EAIYwC,GAAkH3E,EAA+E,CAC1M,QAAS,eACT,aAAcoC,GAEd,MAAOnC,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqBoC,EACzB,CAAC,EAIYuC,GAA0H5E,EAAqF,CACxN,QAAS,iBACT,aAAcsC,GAEd,MAAOrC,EACP,OAAQ,CAAE,mBAAoB,kBAAmB,EACjD,oBAAqBsC,EACzB,CAAC,EAIYsC,GAA8H7E,EAAwF,CAC/N,QAAS,kBACT,aAAcwC,GAEd,MAAOvC,EACP,OAAQ,CAAC,EACT,oBAAqBwC,EACzB,CAAC,EAIYqC,GAAsI9E,EAA8F,CAC7O,QAAS,qBACT,aAAc0C,GAEd,MAAOzC,EACP,OAAQ,CAAC,EACT,oBAAqB0C,EACzB,CAAC,EAIYoC,GAAsH/E,EAAkF,CACjN,QAAS,gBACT,aAAc4C,GAEd,MAAO3C,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqB4C,EACzB,CAAC,EAIYmC,GAAkIhF,EAA2F,CACtO,QAAS,mBACT,aAAc8C,GAEd,MAAO7C,EACP,OAAQ,CAAC,EACT,oBAAqB8C,EACzB,CAAC,EAIYkC,GAA8HjF,EAAwF,CAC/N,QAAS,kBACT,aAAcgD,GAEd,MAAO/C,EACP,OAAQ,CAAC,EACT,oBAAqBgD,EACzB,CAAC,EAIYiC,GAAsHlF,EAAkF,CACjN,QAAS,gBACT,aAAckD,GAEd,MAAOjD,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqBkD,EACzB,CAAC,EAIYgC,GAA8GnF,EAA4E,CACnM,QAAS,cACT,aAAcoD,GAEd,MAAOnD,EACP,OAAQ,CAAE,kBAAmB,iBAAkB,EAC/C,oBAAqBoD,EACzB,CAAC,EAIY+B,GAA0IpF,EAAiG,CACpP,QAAS,sBACT,aAAcsD,GAEd,MAAOrD,EACP,OAAQ,CAAE,eAAgB,cAAe,EACzC,oBAAqBsD,EACzB,CAAC,EAIY8B,GAA0HrF,EAAqF,CACxN,QAAS,iBACT,aAAcwD,GAEd,MAAOvD,EACP,OAAQ,CAAC,EACT,oBAAqBwD,EACzB,CAAC","names":["createContext","useContext","useReducer","useEffect","useCallback","useMemo","useRef","createWalletConnectConnector","eip6963Connector","logger","WalletError","clientInstance","createClient","config","connector","_embeddedConnector","embeddedInit","mod","err","_passkeysConnector","passkeysInit","_solanaConnector","solanaInit","conn","walletId","session","input","calls","chainId","bundleHash","connectors","getClient","clearClient","eip6963Connector","LocalStorageSessionStorage","WalletError","logger","createSessionManager","createConnectorManager","CHAINS","getRpcUrl","DEFAULT_RPC_URLS","STATIC_TESTNETS","toWalletChain","chainId","info","caip2Id","buildDefaultChains","registryChains","chainIds","a","b","id","chain","testnet","DEFAULT_EVM_CHAINS","getChainById","chains","chainNamespace","chainNum","getDefaultChains","jsx","withTimeout","promise","ms","label","_","reject","withRetry","fn","options","lastError","attempt","error","delay","logger","resolve","initialState","web3Reducer","state","action","Web3Context","createContext","Web3ConnectProvider","children","config","autoConnect","dispatch","useReducer","chains","useMemo","getDefaultChains","connectionTimeout","maxRetries","storage","LocalStorageSessionStorage","client","createClient","sessionManagerRef","useRef","sessionManager","cm","createConnectorManager","defaultRpcUrls","defaultCurrencies","chain","caip2Id","sm","createSessionManager","useEffect","onConnected","payload","walletSession","accounts","ns","onDisconnected","onChainChanged","handler","updateStateFromSession","useCallback","session","evmChain","solChain","xrplChain","runSiwx","firstEvm","firstSol","rawAddress","WalletError","chainId","address","message","signature","siwxError","connect","smError","connectEmbedded","connectPasskeys","disconnect","connectInjected","walletId","startPairing","completePairing","reconnect","savedSession","switchChain","eip6963Connector","clearError","value","useWeb3","context","useContext","useWallet","status","session","accounts","chainId","error","connect","disconnect","reconnect","switchChain","useWeb3","isConnected","isConnecting","isReconnecting","currentAccount","useCallback","useState","WalletError","useConnect","connect","status","useWeb3","isLoading","setIsLoading","useState","error","setError","useCallback","err","errorMessage","useCallback","useRef","useState","useDisconnect","disconnect","status","useWeb3","isLoading","setIsLoading","useState","error","setError","mountedRef","useRef","useCallback","err","useMemo","useAccount","accounts","session","isConnected","useWeb3","accountData","useMemo","address","isCaip10","isPlainHex","evmAccount","a","useMemo","useChain","chainId","session","switchChain","chains","useWeb3","currentChain","useMemo","getChainById","chainInfo","namespace","chainNum","chain","c","availableChains","useState","useCallback","WalletError","useSignMessage","session","chainId","useWeb3","isLoading","setIsLoading","useState","error","setError","useCallback","message","err","client","getClient","address","ns","acc","errorMessage","useState","useCallback","WalletError","useSendTransaction","session","chainId","useWeb3","status","setStatus","useState","error","setError","sendTransaction","useCallback","transaction","err","client","getClient","evmAccount","ns","acc","txWithFrom","result","errorMessage","reset","useState","useCallback","WalletError","useSendCalls","session","chainId","useWeb3","status","setStatus","useState","error","setError","batchHash","setBatchHash","callsStatus","setCallsStatus","sendCalls","useCallback","calls","options","err","client","getClient","result","errorMessage","getCallsStatus","hash","bundleHash","reset","useState","useEffect","useCallback","useMemo","useRef","createPublicClient","http","formatEther","getNativeTokenPriceUsd","useBalance","options","evmAccount","isConnected","useAccount","chainId","chains","useWeb3","balance","setBalance","useState","isLoading","setIsLoading","error","setError","usdPrice","setUsdPrice","refreshInterval","intervalRef","useRef","currentChain","useMemo","namespace","chainPart","chainNum","c","tokenSymbol","client","setClient","useEffect","publicClient","fetchBalance","useCallback","address_","balanceResult","price","err","formatted","usdValue","numericBalance","totalUsd","useState","useEffect","useCallback","useMemo","useRef","createPublicClient","http","formatUnits","useTokenBalance","options","evmAccount","isConnected","useAccount","chainId","chains","useWeb3","tokenBalances","setTokenBalances","useState","isLoading","setIsLoading","error","setError","tokens","refreshInterval","intervalRef","useRef","tokensKey","useMemo","t","currentChain","namespace","chainNum","c","client","setClient","useEffect","publicClient","erc20Abi","fetchTokenBalances","useCallback","address","balances","token","balance","r","err","getTokenBalance","tokenAddress","tb","useState","useCallback","useRef","useMemo","createPublicClient","http","createWalletClient","useViemClient","evmAccount","isConnected","useAccount","currentChain","chains","useChain","publicClient","useMemo","createPublicClient","http","walletClient","address","createWalletClient","WalletError","ERC20_MIN_ABI","parseUnits","encodeFunctionData","toBareAddress","addr","encodeTransferCalldata","to","amount","useERC20Transfer","options","publicClient","walletClient","useViemClient","evmAccount","isConnected","useAccount","session","useWeb3","sendTransaction","isSending","sendTxError","reset","useSendTransaction","localError","setLocalError","useState","decimalsRef","useRef","error","useCallback","err","address","decimals","rawAmount","data","getClient","request","useState","useCallback","useRef","WalletError","ERC20_MIN_ABI","parseUnits","encodeFunctionData","toBareAddress","addr","encodeApproveCalldata","spender","amount","MAX_UINT256","useERC20Approve","options","publicClient","walletClient","useViemClient","evmAccount","isConnected","useAccount","session","useWeb3","sendTransaction","isSending","sendTxError","reset","useSendTransaction","localError","setLocalError","useState","allowanceRaw","setAllowanceRaw","isFetchingAllowance","setIsFetchingAllowance","decimalsRef","useRef","error","ownerAddress","fetchAllowance","useCallback","raw","allowance","decimals","padded","dotPos","intPart","fracPart","doApprove","rawAmount","err","data","getClient","txHash","request","approveAmount","approveMaxAmount","checkAllowance","required","requiredRaw","useState","useCallback","useEffect","useRef","useMemo","ERC20_MIN_ABI","useERC20Allowance","options","publicClient","useViemClient","allowanceRaw","setAllowanceRaw","useState","isFetching","setIsFetching","error","setError","intervalRef","useRef","fetchAllowance","useCallback","raw","err","useEffect","e","useMemo","decimals","padded","dotPos","intPart","fracPart","useCallback","useRef","useState","WalletError","useEmbeddedWallet","providerConnectEmbedded","useWeb3","wallet","setWallet","useState","seedPhraseRef","useRef","backupPending","setBackupPending","isBusy","setIsBusy","error","setError","clearError","getSeedPhrase","useCallback","phrase","getEmbeddedConnector","client","getClient","handleConnectEmbedded","connector","loaded","w","w2","err","handleGenerateWallet","handleImportFromMnemonic","mnemonic","handleImportFromPrivateKey","pk","handleWipe","handleConfirmBackup","useMemo","en","zh","locales","currentLocale","setLocale","locale","getLocale","t","key","ZERO_ADDRESS","DEAD_ADDRESSES","isBurnAddress","addr","lower","isZeroAddress","isValidFormat","validateDestination","address","t","useValidateDestination","useMemo","useState","useCallback","WalletError","createSiwxMessage","generateNonce","nowISO","getBlockchainName","getDefaultDomain","getDefaultUri","useSignInWithX","session","currentChainId","useWeb3","isSigningIn","setIsSigningIn","useState","result","setResult","error","setError","clearError","useCallback","options","client","getClient","allAccounts","ns","info","acc","address","chainId","domain","uri","nonce","issuedAt","message","signature","expirationTime","siwxResult","err","wrappedErr","WalletError","useCallback","useEip155SessionGuard","session","useWeb3","WalletError","evmNamespace","useSignInWithEthereum","guard","siwx","useSignInWithX","options","useState","useCallback","useEffect","useRef","LocalStorageAdapter","logger","SIWX_AUTH_KEY","getStorage","prefix","isExpired","siwxResult","now","isNotBeforeValid","useSiwxAuthSession","options","storagePrefix","autoRestore","setSiwxResult","useState","isRestoring","setIsRestoring","isSigningIn","setIsSigningIn","error","setError","signInWithX","useSignInWithX","storageRef","useRef","clearError","useCallback","useEffect","cancelled","storage","saved","err","signIn","signOptions","result","wrapped","signOut","useState","useCallback","WalletError","createSiwxMessage","generateNonce","nowISO","getBlockchainName","DEFAULT_EXPIRY_SECONDS","getDefaultDomain","getDefaultUri","useSIWxLogin","session","currentChainId","useWeb3","isSigningIn","setIsSigningIn","useState","error","setError","clearError","useCallback","options","client","getClient","allAccounts","ns","info","acc","address","chainId","domain","uri","nonce","issuedAt","expirySeconds","expirationTime","message","signature","siwxResult","err","wrappedErr","useState","useCallback","useEffect","useRef","logger","checkSessionExpired","createLocalStorageSiwxSessionStorage","siwxResultToSession","result","useSIWxSession","options","storagePrefix","autoRestore","defaultExpirySeconds","session","setSession","useState","isRestoring","setIsRestoring","isSigningIn","setIsSigningIn","error","setError","web3Session","currentChainId","useWeb3","login","useSIWxLogin","storageRef","useRef","createLocalStorageSiwxSessionStorage","clearError","useCallback","useEffect","cancelled","saved","logger","err","timeUntilExpiry","timer","prev","signIn","signOptions","effectiveOptions","siwxSession","wrapped","signOut","refresh","refreshedSession","isAuthenticated","checkSessionExpired","expired","useState","useCallback","useEffect","useRef","WalletError","SessionKeyManager","MemoryStorageAdapter","globalSessionKeyManager","getSessionKeyManager","config","useSessionKeys","session","useWeb3","sessions","setSessions","useState","loading","setLoading","error","setError","mountedRef","useRef","clearError","useCallback","manager","storageAvailable","refresh","keys","err","useEffect","activeSessions","s","useCreateSessionKey","lastCreated","setLastCreated","isCreating","setIsCreating","scope","signerAddress","resolvedSigner","info","errorObj","useRevokeSession","isRevoking","setIsRevoking","sessionId","useSendWithSession","isBusy","setIsBusy","signWithSession","messageHash","checkScope","tx","resetSessionKeyManager","useState","useEffect","useCallback","useRef","NameResolver","sharedResolver","getResolver","config","useResolveName","name","options","data","setData","isLoading","setIsLoading","error","setError","skip","resolverRef","activeNameRef","mountedRef","resolver","resolve","cleanName","result","err","resolutionError","refetch","useState","useEffect","useCallback","useRef","NameResolver","sharedResolver","getResolver","config","useLookupAddress","address","options","data","setData","isLoading","setIsLoading","error","setError","chainId","skip","resolverRef","activeAddrRef","mountedRef","resolver","lookup","cleanAddr","result","err","resolutionError","refetch","useSyncExternalStore","useCallback","subscribeToSessionManager","sm","callback","handler","getSessionSnapshot","bundle","useSession","sessionManager","web3","useWeb3","subscribe","useCallback","getSnapshot","useSyncExternalStore","useState","useCallback","WalletError","useSwitchChain","providerSwitchChain","chainId","useWeb3","isSwitching","setIsSwitching","useState","error","setError","handleSwitchChain","useCallback","targetChainId","err","walletError","clearError","useCallback","useMemo","WALLET_ERROR_TITLES","WALLET_ERROR_DESCRIPTIONS","UNKNOWN_ERROR_TITLE","UNKNOWN_ERROR_DESCRIPTION","getUserFriendlyError","error","maybeWalletError","code","title","description","message","isRetryableError","maybe","useWeb3ErrorHandler","error","providerClearError","useWeb3","friendlyError","useMemo","getUserFriendlyError","isRetryable","isRetryableError","clearError","useCallback","formatError","err","wrapAsync","fn","friendly","enhanced","useState","useEffect","useCallback","useRef","createContext","useContext","TxMonitorContext","useTxMonitorProvider","useTxMonitor","hash","chainId","monitor","ctxMonitor","effectiveMonitor","entry","setEntry","isLoading","setIsLoading","isWatching","setIsWatching","error","setError","prevHashRef","refresh","current","err","stopWatching","cancelled","initial","onStatusChange","updated","status","useState","useEffect","useCallback","useRef","useTxHistory","address","chainId","monitor","ctxMonitor","useTxMonitorProvider","effectiveMonitor","entries","setEntries","useState","isLoading","setIsLoading","error","setError","refreshCounter","useRef","refresh","useCallback","results","err","useEffect","onStatusChange","summary","e","useState","useCallback","useEffect","useRef","useTransactionSimulation","tx","chainId","session","useWeb3","evmAccount","isConnected","useAccount","currentChain","useChain","publicClient","useViemClient","result","setResult","useState","isSimulating","setIsSimulating","error","setError","debounceRef","useRef","simulate","useCallback","noTxResult","targetChainId","rpcUrl","from","callParams","simResult","callErr","revertReason","errMsg","errData","clean","length","msgHex","bytes","i","json","fetchErr","err","useEffect","reset","useMemo","ERC20_TRANSFER_SELECTOR","padAddress","addr","padHex","value","bytes","parseUnits","amount","decimals","whole","fraction","padded","buildTransferCalldata","to","useERC20TransferSimulation","options","evmAccount","isConnected","useAccount","currentChain","useChain","chainId","tx","useMemo","rawAmount","data","sim","useTransactionSimulation","useState","useCallback","useRef","useLastTx","monitor","ctxMonitor","useTxMonitorProvider","effectiveMonitor","lastTx","setLastTx","useState","lastConfirmedTx","setLastConfirmedTx","lastFailedTx","setLastFailedTx","lastTxRef","useRef","confirmedHandlerRef","failedHandlerRef","entry","clear","useCallback","useState","useCallback","useEffect","useRef","useSmartAccount","options","evmAccount","useAccount","address","setAddress","useState","isDeployed","setIsDeployed","accountInfo","setAccountInfo","isLoading","setIsLoading","error","setError","managerRef","useRef","useEffect","cancelled","SmartAccountManager","err","getConfig","useCallback","owner","createWallet","config","info","e","deployWallet","deployResult","getAddress","useState","useCallback","useRef","useSendUserOperation","options","userOpHash","setUserOpHash","receipt","setReceipt","isPending","setIsPending","isEstimating","setIsEstimating","error","setError","abortRef","sendUserOp","calls","opts","SmartAccountManager","buildCallData","signUserOperation","sendUserOperation","buildUserOperation","callData","entryPoint","gasEstimate","estimateUserOperationGas","maxFeePerGas","maxPriorityFeePerGas","baseFee","r","j","priorityFee","userOp","response","UserOpPoller","rcpt","err","reset","bundlerUrl","maxRetries","intervalMs","json","resolve","useState","useEffect","useRef","useCallback","useUserOpStatus","options","bundlerUrl","pollInterval","maxRetries","status","setStatus","receipt","setReceipt","userOpHash","setUserOpHash","error","setError","isPolling","setIsPolling","attempts","setAttempts","startTimeRef","elapsedMs","setElapsedMs","intervalRef","pollTimerRef","clearTimers","poll","hash","response","json","receiptData","prev","start","stop","reset","useState","useEffect","useCallback","useRef","TokenListManager","useTokenList","chainId","options","managerRef","tokens","setTokens","isLoading","setIsLoading","isLoaded","setIsLoaded","error","setError","config","load","manager","numericChainId","parseChainId","loaded","err","refetch","parts","numeric","useState","useEffect","useRef","TokenListManager","ETHEREUM_MAINNET_TOKENS","POLYGON_TOKENS","OPTIMISM_TOKENS","ARBITRUM_TOKENS","BASE_TOKENS","getDefaultSources","DEBOUNCE_MS","sharedManager","getManager","TokenListManager","getDefaultSources","useTokenSearch","query","chainId","results","setResults","useState","isSearching","setIsSearching","debounceRef","useRef","trimmedQuery","useEffect","manager","numericChainId","parseChainId","searchResults","parts","numeric","React","useCallback","Fragment","jsx","jsxs","TokenSelector","chainId","onSelect","onClose","options","searchQuery","setSearchQuery","React","allTokens","isLoading","error","useTokenList","results","isSearching","useTokenSearch","showRecommendations","displayTokens","combined","m","tokens","popularTokens","handleSelect","useCallback","token","e","img","useState","useCallback","useMemo","useEffect","useRef","InAppChannel","createStorageAdapter","DEFAULT_SETTINGS","STORAGE_KEY_SETTINGS","useNotification","options","channelRef","channel","notifications","setNotifications","settings","setSettingsState","createReactStorage","saved","item","prev","unreadCount","n","clear","clearOne","id","updated","markAsRead","markAllAsRead","addNotification","full","updateSettings","update","next","setChannels","channels","muteChain","chainId","unmuteChain","c","storage","key","e","value","useState","useCallback","useRef","SimulationManager","useSimulateTransfer","options","rpcUrl","chainId","managerRef","getManager","result","setResult","loading","setLoading","error","setError","simulate","tokenAddress","from","to","amount","simOptions","manager","actualChainId","actualRpcUrl","simResult","err","errorObj","reset","useState","useEffect","useCallback","useRef","useRouteQuote","input","getQuoteFn","fromChain","toChain","fromToken","toToken","amount","options","quotes","setQuotes","loading","setLoading","error","setError","debounceTimer","mountedRef","fetchQuotes","result","err","refresh","clear","useState","useCallback","useRef","useExecuteRoute","executeRouteFn","executing","setExecuting","result","setResult","error","setError","mountedRef","execute","quote","recipient","options","execResult","err","executionError","reset","useState","useEffect","useCallback","useRef","useCompareCosts","input","compareCostsFn","operation","chains","options","comparisons","setComparisons","loading","setLoading","error","setError","mountedRef","fetchComparisons","result","err","refresh","createComponent","React","AppkitAccordionElement","defineAppkitAccordion","AppkitAccountButtonElement","defineAppkitAccountButton","AppkitAlertDialogElement","defineAppkitAlertDialog","AppkitAvatarElement","defineAppkitAvatar","AppkitBadgeElement","defineAppkitBadge","AppkitButtonElement","defineAppkitButton","AppkitCardContentElement","defineAppkitCardContent","AppkitCardDescriptionElement","defineAppkitCardDescription","AppkitCardFooterElement","defineAppkitCardFooter","AppkitCardHeaderElement","defineAppkitCardHeader","AppkitCardTitleElement","defineAppkitCardTitle","AppkitCardElement","defineAppkitCard","AppkitCheckboxElement","defineAppkitCheckbox","AppkitCollapsibleElement","defineAppkitCollapsible","AppkitConnectButtonElement","defineAppkitConnectButton","AppkitDialogElement","defineAppkitDialog","AppkitDropdownMenuElement","defineAppkitDropdownMenu","AppkitInputElement","defineAppkitInput","AppkitPopoverElement","defineAppkitPopover","AppkitProgressElement","defineAppkitProgress","AppkitScrollAreaElement","defineAppkitScrollArea","AppkitSelectElement","defineAppkitSelect","AppkitSeparatorElement","defineAppkitSeparator","AppkitSkeletonElement","defineAppkitSkeleton","AppkitSwitchElement","defineAppkitSwitch","AppkitTabsElement","defineAppkitTabs","AppkitToggleGroupElement","defineAppkitToggleGroup","AppkitTooltipElement","defineAppkitTooltip","AppkitAccordion","AppkitAccountButton","AppkitAlertDialog","AppkitAvatar","AppkitBadge","AppkitButton","AppkitCard","AppkitCardContent","AppkitCardDescription","AppkitCardFooter","AppkitCardHeader","AppkitCardTitle","AppkitCheckbox","AppkitCollapsible","AppkitConnectButton","AppkitDialog","AppkitDropdownMenu","AppkitInput","AppkitPopover","AppkitProgress","AppkitScrollArea","AppkitSelect","AppkitSeparator","AppkitSkeleton","AppkitSwitch","AppkitTabs","AppkitToggleGroup","AppkitTooltip"]}
|