@anywalletkit/protocol-swap2-core 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@anywalletkit/protocol-swap2-core",
3
- "version": "0.3.2",
4
- "description": "",
3
+ "version": "0.4.0",
4
+ "description": "The swap2 engine for Any Wallet Kit: one interface for swaps and bridges, quote binding, approvals, review gate, fee caps and status resume; providers plug in as separate packages.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://docs.anywallet.tech",
7
7
  "bugs": {
@@ -13,6 +13,9 @@
13
13
  "directory": "packages/protocol-swap2-core"
14
14
  },
15
15
  "type": "module",
16
+ "engines": {
17
+ "node": ">=20"
18
+ },
16
19
  "sideEffects": false,
17
20
  "main": "./dist/index.cjs",
18
21
  "module": "./dist/index.js",
@@ -48,6 +51,11 @@
48
51
  "import": "./dist/remote.js",
49
52
  "require": "./dist/remote.cjs"
50
53
  },
54
+ "./server": {
55
+ "types": "./dist/server.d.ts",
56
+ "import": "./dist/server.js",
57
+ "require": "./dist/server.cjs"
58
+ },
51
59
  "./util": {
52
60
  "types": "./dist/util.d.ts",
53
61
  "import": "./dist/util.js",
@@ -76,17 +84,17 @@
76
84
  ],
77
85
  "dependencies": {
78
86
  "viem": "^2.45.0",
79
- "@anywalletkit/swap2-assets": "0.1.4",
80
- "@anywalletkit/tx-preview-evm": "0.1.3"
87
+ "@anywalletkit/swap2-assets": "0.1.5",
88
+ "@anywalletkit/tx-preview-evm": "0.1.4"
81
89
  },
82
90
  "peerDependencies": {
83
- "@anywalletkit/core": "0.3.2"
91
+ "@anywalletkit/core": "0.4.0"
84
92
  },
85
93
  "devDependencies": {
86
94
  "@types/node": "^22",
87
95
  "vitest": "^5.0.3",
88
- "@anywalletkit/core": "0.3.2",
89
- "@anywalletkit/conformance": "0.3.2"
96
+ "@anywalletkit/core": "0.4.0",
97
+ "@anywalletkit/conformance": "0.4.0"
90
98
  },
91
99
  "keywords": [],
92
100
  "publishConfig": {
@@ -97,6 +105,6 @@
97
105
  "build": "tsup",
98
106
  "typecheck": "tsc --noEmit",
99
107
  "test": "vitest run",
100
- "lint": "echo ok"
108
+ "lint": "eslint src"
101
109
  }
102
110
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/swap2/base.ts"],"sourcesContent":["/**\n * `Swap2Protocol` adapter over the cross-chain engine.\n *\n * The engine speaks in symbols + CAIP-2 chain ids and a deposit-address /\n * calldata execution model; core's `Swap2Protocol` speaks in provider token ids\n * bound to an account whose chain is the source. This base bridges the two:\n * it maps `Swap2Options` → the engine's `QuoteParams`, delegates quoting to a\n * provider (or the router, in the aggregator), and executes the source leg\n * through the bound account. Subclasses only supply \"which provider(s)\".\n */\nimport {Swap2Protocol} from \"@anywalletkit/core\";\nimport {encodeFunctionData, getAddress} from \"viem\";\nimport {decodeCall} from \"@anywalletkit/tx-preview-evm\";\nimport type {\n Swap2Options,\n Swap2Quote,\n Swap2Result,\n Swap2StatusOptions,\n Swap2StatusResult,\n Swap2Status,\n Swap2Fee,\n Swap2ProtocolConfig,\n Swap2SupportedChain,\n Swap2SupportedToken,\n Swap2SupportedTokensOptions,\n BridgeOptions,\n BridgeResult,\n SwapOptions,\n SwapResult,\n} from \"@anywalletkit/core\";\nimport {\n CC_SOURCE_CHAINS,\n ccAsset,\n ccAssetByToken,\n type CcChain,\n} from \"@anywalletkit/swap2-assets\";\nimport type {CrossChainProvider, IntentStatus, QuoteParams, Quote, UnsignedTx} from \"../types.js\";\nimport {\n Swap2ConfigurationError,\n Swap2ExecutionError,\n Swap2FeeLimitError,\n Swap2InFlightError,\n Swap2InsufficientGasError,\n Swap2MaybeSentError,\n Swap2QuoteError,\n Swap2StatusError,\n Swap2UnsupportedOperationError,\n Swap2ValidationError,\n} from \"../errors.js\";\n\nconst ZERO = \"0x0000000000000000000000000000000000000000\";\n\nconst ERC20_TRANSFER_ABI = [\n {\n type: \"function\",\n name: \"transfer\",\n stateMutability: \"nonpayable\",\n inputs: [\n {name: \"to\", type: \"address\"},\n {name: \"amount\", type: \"uint256\"},\n ],\n outputs: [{type: \"bool\"}],\n },\n] as const;\nconst ERC20_APPROVE_ABI = [\n {type: \"function\", name: \"approve\", stateMutability: \"nonpayable\", inputs: [{name: \"spender\", type: \"address\"}, {name: \"amount\", type: \"uint256\"}], outputs: [{type: \"bool\"}]},\n] as const;\nconst approveData = (spender: string, amount: bigint) =>\n encodeFunctionData({abi: ERC20_APPROVE_ABI, functionName: \"approve\", args: [spender as `0x${string}`, amount]});\n\n/** swap2() calls running per account object, keyed by their options: a double tap must not run two swaps. */\nconst IN_FLIGHT = new WeakMap<object, Set<string>>();\nconst inFlightKey = (fromChain: string, o: Swap2Options) =>\n JSON.stringify([fromChain, o.fromToken, o.toToken, o.toChain, o.recipient, o.refundAddress, o.fromTokenAmount, o.toTokenAmount, o.minAmountOut, o.slippage],\n (_k, v) => (typeof v === \"bigint\" ? v.toString() : v));\n\n/**\n * Did a failed broadcast possibly reach the node? An account that knows says\n * so on the error (`maybeSent` + the locally computed `hash`, see\n * @anywalletkit/wallet-evm); otherwise a lost transport response (socket\n * closed, timeout) is treated as possibly sent. A node's own JSON-RPC\n * rejection, a refusal before signing, etc. are clean failures.\n */\nfunction maybeSent(error: unknown): {hash?: string} | null {\n for (let e = error as {maybeSent?: unknown; hash?: unknown; cause?: unknown} | undefined, i = 0; e && typeof e === \"object\" && i < 5; e = e.cause as typeof e, i++) {\n if (e.maybeSent === true) return typeof e.hash === \"string\" && e.hash ? {hash: e.hash} : {};\n }\n const text = error instanceof Error ? error.message : String(error);\n return /socket hang up|ECONNRESET|ETIMEDOUT|EPIPE|timed? ?out|request aborted|connection (?:closed|reset)/i.test(text) ? {} : null;\n}\n\n/** Our config adds the account's source chain (CAIP-2) the base type omits. */\n/**\n * Where an execution is, for progress UIs. A source leg can spend a minute\n * before anything is signed (two awaited ERC-20 approvals for USDT), so\n * \"signing\" alone reads as hung. \"requoting\": the mined approvals outlived\n * the quote's TTL and the engine is fetching a fresh quote for the same\n * spender and amount (the allowance is kept, not revoked). Diagnostics only:\n * a throwing observer can never change the outcome.\n */\n/**\n * Most native coin a route may charge on top of the input (bridge messaging\n * fees), base units per chain. Above this the quote is refused even though it\n * declared the fee — a provider bug or a hostile backend must not turn a\n * token swap into a native drain.\n */\n/**\n * Base-unit precision of a chain's native coin — what `value`, `eth_getBalance`\n * and a declared `nativeFee` are counted in. Every EVM chain the engine knows\n * accounts for gas in 18-decimal units, Arc included: Arc's gas token is USDC,\n * but its native accounting is 18-decimal (\"the native USDC gas token uses 18\n * decimals of precision, while the USDC ERC-20 interface uses 6\" —\n * docs.arc.network, gas-and-fees / contract-addresses, 2026-10-14). Arc is\n * pinned here so the 6-decimal ERC-20 view can never leak into a ceiling:\n * 10 USDC of fee headroom is 10 × 10^18 base units, not 10 × 10^6. A chain\n * whose native accounting is genuinely not 18-decimal gets its own row and\n * every cap below, declared in whole coins, scales with it.\n */\nexport const NATIVE_DECIMALS: Readonly<Record<string, number>> = Object.freeze({\n \"eip155:5042\": 18, // Arc — USDC gas token, 18-decimal native accounting (ERC-20 view at 0x3600… is 6)\n});\nconst DEFAULT_NATIVE_DECIMALS = 18;\n/** Decimals of `chain`'s native coin in base units (18 unless the chain says otherwise). */\nexport function nativeDecimals(chain: string): number {\n return NATIVE_DECIMALS[chain] ?? DEFAULT_NATIVE_DECIMALS;\n}\n/** `whole` native coins (an integer, or a decimal string such as \"0.005\") in `chain`'s base units. */\nexport function nativeUnits(chain: string, whole: number | string): bigint {\n const text = String(whole);\n if (!/^\\d+(\\.\\d+)?$/.test(text)) throw new Error(`swap2: malformed native amount '${text}'`);\n const [int, frac = \"\"] = text.split(\".\") as [string, string?];\n const decimals = nativeDecimals(chain);\n if (frac.length > decimals) throw new Error(`swap2: '${text}' has more than ${decimals} fractional digits for ${chain}`);\n return BigInt(int + frac.padEnd(decimals, \"0\"));\n}\nconst NATIVE_FEE_CAP: Readonly<Record<string, bigint>> = Object.freeze({\n \"eip155:1\": 5_000_000_000_000_000n, // 0.005 ETH\n \"eip155:137\": 20_000_000_000_000_000_000n, // 20 POL\n \"eip155:56\": 5_000_000_000_000_000n, // 0.005 BNB\n \"eip155:43114\": 100_000_000_000_000_000n, // 0.1 AVAX\n \"eip155:999\": 100_000_000_000_000_000n, // 0.1 HYPE\n // Non-ETH natives, ~$10-12 each at 2026-10-13 prices (0.005 ETH ≈ $12.6).\n \"eip155:100\": 10_000_000_000_000_000_000n, // 10 xDAI\n \"eip155:143\": 400_000_000_000_000_000_000n, // 400 MON\n \"eip155:146\": 200_000_000_000_000_000_000n, // 200 S\n \"eip155:9745\": 150_000_000_000_000_000_000n, // 150 XPL\n \"eip155:42220\": 100_000_000_000_000_000_000n, // 100 CELO\n \"eip155:80094\": 50_000_000_000_000_000_000n, // 50 BERA\n \"eip155:1329\": 200_000_000_000_000_000_000n, // 200 SEI\n \"eip155:98866\": 500_000_000_000_000_000_000n, // 500 PLUME\n \"eip155:196\": 100_000_000_000_000_000n, // 0.1 OKB\n // 2026-10-14 batch, ~$10 each at 2026-10-14 prices; declared in whole coins so the chain's native decimals apply.\n \"eip155:5000\": nativeUnits(\"eip155:5000\", 20), // 20 MNT (≈ $0.53 each)\n \"eip155:14\": nativeUnits(\"eip155:14\", 1500), // 1500 FLR (≈ $0.0067 each)\n \"eip155:5042\": nativeUnits(\"eip155:5042\", 10), // 10 USDC — Arc's gas token, in its 18-decimal native units\n // Katana and Morph are ETH-denominated: the 0.005 ETH default applies.\n});\nconst DEFAULT_NATIVE_FEE_CAP = 5_000_000_000_000_000n; // 0.005 of an ETH-denominated L2\n\nfunction declaredNativeFee(q: {txRequest?: {nativeFee?: string}}, chain: string): bigint {\n const raw = q.txRequest?.nativeFee;\n if (raw === undefined) return 0n;\n if (!/^\\d+$/.test(raw)) throw new Error(\"swap2: quote declares a malformed native fee\");\n const fee = BigInt(raw);\n const cap = NATIVE_FEE_CAP[chain] ?? DEFAULT_NATIVE_FEE_CAP;\n if (fee > cap) throw new Error(`swap2: quoted native fee ${fee} exceeds the cap ${cap} for ${chain}`);\n return fee;\n}\n\nexport type Swap2ExecutionPhase = \"approving\" | \"requoting\" | \"preflight\" | \"signing\" | \"broadcast\";\nexport interface Swap2ExecutionPhaseDetail {\n /** approving: which approval of how many (USDT on Ethereum needs two). */\n index?: number;\n total?: number;\n /** broadcast: the source transaction hash. */\n hash?: string;\n}\n\n/** EIP-712 domain with `chainId` as a number whatever notation the provider used. */\nexport function normalizeTypedDomain(domain: unknown): unknown {\n if (!domain || typeof domain !== \"object\") return domain;\n const raw = (domain as {chainId?: unknown}).chainId;\n let chainId: number | undefined;\n if (typeof raw === \"number\") chainId = raw;\n else if (typeof raw === \"bigint\") chainId = Number(raw);\n else if (typeof raw === \"string\" && /^\\d+$/.test(raw)) chainId = Number(raw);\n else if (typeof raw === \"string\" && /^0x[0-9a-fA-F]+$/.test(raw)) chainId = Number(BigInt(raw));\n return chainId === undefined || !Number.isSafeInteger(chainId) ? domain : {...(domain as object), chainId};\n}\n\nexport interface Swap2EngineConfig extends Swap2ProtocolConfig {\n /** CAIP-2 of the chain the bound account lives on (the swap2 source). */\n fromChain: string;\n /** Progress observer, see {@link Swap2ExecutionPhase}. */\n onExecutionPhase?: (phase: Swap2ExecutionPhase, detail?: Swap2ExecutionPhaseDetail) => void;\n /** Explicit escape hatch for adapters that can prove chain binding elsewhere. */\n skipAccountChainCheck?: boolean;\n /** Optional account chain identity when the account does not expose a provider. */\n accountChain?: string;\n /**\n * Decodes a base64 BoC into a TON `Cell` for deposits that carry a cell body\n * (e.g. Omniston escrow payloads). The package deliberately does not depend on\n * `@ton/core`; the caller supplies e.g. `(b) => Cell.fromBase64(b)`. Without\n * it, cell-body deposits fail closed — a TON account treats a string body\n * as a TEXT COMMENT, which would strand the swap.\n */\n decodeTonBody?: (bocBase64: string) => unknown;\n /**\n * Provider-SERIALIZED legs (a swap aggregator's fully built Solana\n * transaction): how much native coin, in base units, the account may lose\n * on top of the swap input — rent for a destination token account, wrapped\n * SOL juggling, priority fees. Default 20 000 000 lamports (0.02 SOL).\n */\n serializedNativeAllowance?: bigint | number | string;\n /**\n * Review gate: called once the live quote is built and every payload/value\n * check has passed, BEFORE any approval or signature. It receives a copy of\n * exactly what will be signed; throwing (the user cancelled) aborts with\n * nothing sent. A quote that expires while the gate is open is refused\n * before the first approval.\n */\n reviewExecution?: (plan: Swap2ExecutionPlan) => Promise<void> | void;\n}\n\n/** What `swap2()` is about to sign, handed to {@link Swap2EngineConfig.reviewExecution}. */\nexport interface Swap2ExecutionPlan {\n provider: string;\n fromChain: string;\n destChain: string;\n destToken: string;\n recipient: string;\n refundAddress: string;\n sourceAmount: bigint;\n destAmount: bigint;\n minDestAmount: bigint;\n feeUsd: number;\n etaSeconds: number;\n validUntilMs: number;\n /** ERC-20 approvals sent first, in order (USDT on Ethereum resets to 0 first). */\n approvals: {token: string; spender: string; amount: bigint; chainId?: number}[];\n /** The source leg exactly as the account will receive it. */\n source:\n | {kind: \"call\"; to: string; data?: string; value: bigint; chainId?: number; gasLimit?: bigint; memo?: string; memoEncoding?: \"utf8\" | \"hex\"; cellBody?: boolean}\n | {kind: \"token-transfer\"; token: string; recipient: string; amount: bigint; memo?: string; memoEncoding?: \"utf8\" | \"hex\"}\n | {kind: \"serialized\"; serializedTx: string}\n | {kind: \"typed-order\"; typedData: string};\n}\n\n/**\n * What a provider-serialized transaction is allowed to do with the bound\n * account's balances; derived from the validated quote and handed to the\n * account's `sendSerializedTransaction` hook, which must prove it (simulate\n * with post-state balances) before signing. Amounts are base-unit strings.\n */\nexport interface SerializedExecutionExpectation {\n /** Most native coin the account may lose, fee excluded: swap input (native source) + allowance. */\n maxValueOut: string;\n /** Same-chain swaps: the token the account must receive and the quoted minimum (zero address = native). */\n tokenIn?: {token: string; minAmount: string};\n /** Token sources: the token the account may send and the exact swap input. */\n source?: {token: string; maxAmount: string};\n}\n\nconst DEFAULT_SERIALIZED_NATIVE_ALLOWANCE = 20_000_000n;\n\n/**\n * A bound wallet account, accepted opaquely: the write surface we need is\n * reached through {@link Swap2Signer}. Passing `undefined` builds a quote-only\n * protocol (no `swap2()` execution).\n */\nexport type Swap2Account = unknown;\n\n/** Minimal write surface we need off the bound account to send the leg. */\ninterface Swap2Signer {\n getAddress(): Promise<string> | string;\n sendTransaction(tx: {\n to?: string;\n data?: string;\n value?: bigint;\n chainId?: number;\n gasLimit?: bigint;\n /** TON message body: a text comment (string) or a decoded Cell. */\n body?: string | unknown;\n /** Tron: swap memo the account must place in `raw_data.data`. */\n memo?: string;\n /** Tron: 'hex' = `memo` is a binary payload in 0x-hex (default 'utf8'). */\n memoEncoding?: \"utf8\" | \"hex\";\n }): Promise<{hash?: string}>;\n /** The account's token-transfer surface, used by TON/Solana/Tron accounts. */\n transfer?: (options: {\n token: string;\n recipient: string;\n amount: bigint;\n /** Tron TRC-20: memo in `raw_data.data` next to the TriggerSmartContract. */\n memo?: string;\n /** Tron: 'hex' = `memo` is a binary payload in 0x-hex (default 'utf8'). */\n memoEncoding?: \"utf8\" | \"hex\";\n }) => Promise<{hash?: string}>;\n signTypedData?: (args: {domain: unknown; types: unknown; primaryType?: string; message: unknown}) => Promise<string>;\n /**\n * Execute a provider-built transaction the account cannot rebuild (a swap\n * aggregator's serialized Solana tx). The account owns the proof: it must\n * refuse anything beyond `expect` before signing.\n */\n sendSerializedTransaction?: (serializedTx: string, expect: SerializedExecutionExpectation) => Promise<{hash?: string}>;\n /**\n * Wait until a transaction this account sent is INCLUDED (and succeeded).\n * Used between an ERC-20 approval and the deposit that spends it: a signer\n * that returns on broadcast leaves the deposit's gas estimate looking at a\n * block where the allowance is still zero (or, for USDT's approve(0) →\n * approve(n) dance, still non-zero) — \"execution reverted\" before any\n * funds move. Accounts without it keep the fire-and-forget behaviour.\n */\n waitForTransaction?: (hash: string) => Promise<void>;\n /**\n * Current ERC-20 allowance of this account for `spender`. With it the\n * engine sends only the approvals the chain needs: none when the exact\n * allowance is already live, a single approve(n) for mainnet USDT when the\n * current allowance is 0 (its reset rule only bites non-zero → non-zero).\n * Without it (or when the read fails) the engine assumes the worst and\n * resets USDT every time.\n */\n getAllowance?: (token: string, spender: string) => Promise<bigint | number | string>;\n /** EVM gas pre-check before approvals: native balance and a fee upper bound per tx. */\n getBalance?: () => Promise<bigint | number | string>;\n quoteSendTransaction?: (tx: {to: string; data?: string; value?: bigint; chainId?: number; gasLimit?: bigint}) => Promise<{fee: bigint}>;\n /** CAIP-2 id of a @anywalletkit/core account. */\n chain?: string;\n getChainId?: () => Promise<number | bigint> | number | bigint;\n getNetwork?: () => Promise<{chainId?: number | bigint} | string> | {chainId?: number | bigint} | string;\n chainId?: number | bigint;\n _provider?: {getNetwork?: () => Promise<{chainId?: number | bigint}>};\n provider?: {getNetwork?: () => Promise<{chainId?: number | bigint}>};\n}\n\n/**\n * An exact allowance the first execution pass mined before its quote\n * expired, handed to the re-quote pass (SDK-128). The pass that adopts it\n * owns its cleanup; until then the first pass revokes on any failure.\n */\ninterface CarriedAllowance {\n token: string;\n spender: string;\n amount: bigint;\n revoke: () => Promise<void>;\n adopted: boolean;\n}\n\n/** Swap2 status ids are `awk1.<provider>.<intent>[.<sourceTxHash>]` (URI-encoded segments). */\nexport const SWAP2_ID_PREFIX = \"awk1\";\n\n/** Versioned provider/intent/source-hash id for durable status tracking. */\nfunction encodeId(provider: string, intentId: string, sourceTxHash?: string): string {\n // encodeURIComponent leaves \".\" unescaped, which would shift decodeId's\n // split — escape it explicitly so segments are dot-safe.\n const enc = (v: string) => encodeURIComponent(v).replace(/\\./g, \"%2E\");\n return `${SWAP2_ID_PREFIX}.${[provider, intentId, sourceTxHash].filter((v): v is string => v != null).map(enc).join(\".\")}`;\n}\nfunction decodeId(id: string): {provider: string; intentId: string; sourceTxHash?: string} {\n try {\n if (!id.startsWith(`${SWAP2_ID_PREFIX}.`)) throw new Error(\"unsupported id version\");\n const parts = id.slice(SWAP2_ID_PREFIX.length + 1).split(\".\");\n if (parts.length < 2 || parts.length > 3 || !parts[0] || !parts[1]) throw new Error(\"invalid id shape\");\n const provider = decodeURIComponent(parts[0]);\n const intentId = decodeURIComponent(parts[1]);\n const sourceTxHash = parts[2] ? decodeURIComponent(parts[2]) : undefined;\n if (!/^[A-Za-z0-9_-]+$/.test(provider) || !intentId || (parts[2] !== undefined && !sourceTxHash)) {\n throw new Error(\"invalid id contents\");\n }\n return {provider, intentId, ...(sourceTxHash ? {sourceTxHash} : {})};\n } catch {\n throw new Swap2ValidationError(\"swap2: malformed swap2 status id\");\n }\n}\n\nasync function readAccountChain(signer: Swap2Signer, configured?: string): Promise<string | number | bigint | undefined> {\n if (configured) return configured;\n // @anywalletkit/core accounts carry their CAIP-2 id directly.\n if (typeof signer.chain === \"string\" && signer.chain && !signer.chain.endsWith(\":unknown\")) return signer.chain;\n if (typeof signer.getChainId === \"function\") return await signer.getChainId();\n if (typeof signer.getNetwork === \"function\") {\n const network = await signer.getNetwork();\n return typeof network === \"string\" ? network : network?.chainId;\n }\n if (signer.chainId != null) return signer.chainId;\n for (const provider of [signer._provider, signer.provider]) {\n if (provider?.getNetwork) {\n const network = await provider.getNetwork();\n if (network?.chainId != null) return network.chainId;\n }\n }\n return undefined;\n}\n\n/** CAIP-2 → the coarse VM family Swap2SupportedChain.type expects. */\nfunction chainType(caip2: string): string {\n const ns = caip2.split(\":\")[0] ?? \"\";\n if (ns === \"eip155\") return \"evm\";\n if (ns === \"solana\") return \"svm\";\n if (ns === \"tron\") return \"tvm\";\n if ([\"bitcoin\", \"litecoin\", \"doge\", \"bch\", \"zcash\"].includes(ns)) return \"utxo\";\n return ns;\n}\n\n/**\n * The wallet packages name non-EVM chains by genesis hash (CAIP-2 proper:\n * `account.chain` of a Solana account is `solana:5eykt…`), while the swap2\n * catalog and every provider use the short ids. The engine takes either.\n */\nexport const SWAP2_CHAIN_ALIASES: Readonly<Record<string, string>> = Object.freeze({\n \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\": \"solana:mainnet\",\n \"tron:0x2b6653dc\": \"tron:728126428\",\n \"bip122:000000000019d6689c085ae165831e93\": \"bitcoin:mainnet\",\n});\n/** The swap2 id for `chain` (itself when it has no alias). */\nexport const swap2ChainId = (chain: string): string => SWAP2_CHAIN_ALIASES[chain] ?? chain;\n\n/** Normalize a `toChain` (number chainId | CAIP-2 | numeric string) to CAIP-2. */\nfunction toCaip2(chain: string | number | undefined, fallback: string): string {\n if (chain == null || chain === \"\") return fallback;\n if (typeof chain === \"number\") {\n if (!Number.isSafeInteger(chain) || chain <= 0) throw new Swap2ValidationError(\"swap2: chain id must be a positive safe integer\");\n return `eip155:${chain}`;\n }\n if (/^\\d+$/.test(chain)) {\n const id = Number(chain);\n if (!Number.isSafeInteger(id) || id <= 0) throw new Swap2ValidationError(\"swap2: chain id must be a positive safe integer\");\n return `eip155:${id}`;\n }\n if (!/^[a-z0-9]{3,8}:[-_A-Za-z0-9]{1,32}$/.test(chain)) {\n throw new Swap2ValidationError(\"swap2: chain must be a valid CAIP-2 identifier\");\n }\n return swap2ChainId(chain);\n}\n\n/** Resolve a token ref (symbol OR on-chain address) to the engine's symbol. */\nfunction toSymbol(caip2: string, ref: string): string {\n const byToken = ref.startsWith(\"0x\") || ref.length > 20 ? ccAssetByToken(caip2, ref) : undefined;\n if (byToken) return byToken.symbol;\n if (ccAsset(caip2, ref)) return ref; // already a symbol we know\n return ref;\n}\n\n/** Resolve a dest token ref to the engine's dest address (zero = native). */\nfunction toDestAddress(caip2: string, ref: string): string {\n if (ref.startsWith(\"0x\")) return ref;\n const asset = ccAssetByToken(caip2, ref) ?? ccAsset(caip2, ref);\n if (!asset) {\n throw new Error(`swap2: unknown destination token '${ref}' on ${caip2}`);\n }\n return asset.contract ?? ZERO;\n}\n\nfunction snapshotOptions(options: Swap2Options): Swap2Options {\n return Object.freeze({...options});\n}\n\nfunction snapshotConfig(config?: Swap2ProtocolConfig): Swap2ProtocolConfig | undefined {\n return config ? Object.freeze({...config}) : undefined;\n}\n\nfunction snapshotQuote<T extends Quote>(quote: T): T {\n return Object.freeze({\n ...quote,\n ...(quote.txRequest ? {txRequest: Object.freeze({...quote.txRequest})} : {}),\n ...(quote.providerData ? {providerData: Object.freeze({...quote.providerData})} : {}),\n ...(quote.fees ? {fees: Object.freeze(quote.fees.map((fee) => Object.freeze({...fee})))} : {}),\n }) as T;\n}\n\nfunction exactPositiveAmount(value: number | bigint, name: string): bigint {\n if (typeof value === \"number\") {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Swap2ValidationError(`swap2: ${name} must be a positive safe integer or bigint`);\n }\n return BigInt(value);\n }\n if (value <= 0n) throw new Swap2ValidationError(`swap2: ${name} must be a positive safe integer or bigint`);\n return value;\n}\n\n/**\n * floor(x × scale) that forgives binary representation error: a caller's\n * 0.0029 is 29 bps, though 0.0029 × 10 000 is 28.999…96 in floating point\n * (573 of the 10 001 whole-bps decimals land one short with a plain floor).\n */\nfunction floorScaled(x: number, scale: number): number {\n const v = x * scale;\n const nearest = Math.round(v);\n return Math.abs(v - nearest) < 1e-6 ? nearest : Math.floor(v);\n}\n\nfunction callerConstraints(options: Swap2Options): {minAmountOut?: bigint; slippageBps?: number} {\n let minAmountOut: bigint | undefined;\n if (options.minAmountOut !== undefined) {\n try {\n minAmountOut = BigInt(options.minAmountOut);\n } catch {\n throw new Error(\"swap2: minAmountOut must be a positive integer\");\n }\n if (minAmountOut <= 0n) throw new Error(\"swap2: minAmountOut must be a positive integer\");\n }\n let slippageBps: number | undefined;\n if (options.slippage !== undefined) {\n if (!Number.isFinite(options.slippage) || options.slippage < 0 || options.slippage >= 1) {\n throw new Error(\"swap2: slippage must be a finite decimal in [0, 1)\");\n }\n // Providers accept whole bps. Round down so their on-chain/API tolerance\n // can never be wider than the caller requested; the exact decimal is also\n // checked against the returned quote below.\n slippageBps = floorScaled(options.slippage, 10_000);\n }\n return {\n ...(minAmountOut !== undefined ? {minAmountOut} : {}),\n ...(slippageBps !== undefined ? {slippageBps} : {}),\n };\n}\n\nfunction assertQuoteConstraints(q: Quote, options: Swap2Options): void {\n const {minAmountOut} = callerConstraints(options);\n const nominal = BigInt(q.destAmount);\n const guaranteed = BigInt(q.minDestAmount);\n if (minAmountOut !== undefined && guaranteed < minAmountOut) {\n throw new Error(`swap2: quoted minimum ${guaranteed} is below caller minAmountOut ${minAmountOut}`);\n }\n if (options.slippage !== undefined) {\n const scale = 1_000_000_000n;\n const permitted = BigInt(floorScaled(options.slippage, Number(scale)));\n // Floor, like the providers compute their minimum (see validQuote).\n const required = (nominal * (scale - permitted)) / scale;\n if (guaranteed < required) {\n throw new Error(`swap2: quote exceeds caller slippage (${options.slippage})`);\n }\n }\n}\n\nfunction requireExecutionFloor(options: Swap2Options): void {\n if (options.minAmountOut === undefined) {\n throw new Error(\"swap2: swap2() requires caller-supplied minAmountOut\");\n }\n callerConstraints(options);\n}\n\nfunction mapStatus(s: IntentStatus): Swap2StatusResult {\n const status: Swap2Status =\n s.state === \"completed\"\n ? \"completed\"\n : s.state === \"action-required\"\n ? \"action-required\"\n : s.state === \"refund-pending\"\n ? \"refund-pending\"\n : s.state === \"partial\"\n ? \"partial\"\n : s.state === \"failed\"\n ? \"failed\"\n : s.state === \"refunded\"\n ? \"refunded\"\n : s.state === \"cancelled\"\n ? \"cancelled\"\n : s.state === \"expired\"\n ? \"expired\"\n : \"pending\";\n return s.destTxHash\n ? {status, transactions: [{hash: s.destTxHash, type: \"destination\"}]}\n : {status};\n}\n\n/**\n * Abstract swap2 protocol backed by the engine. Concrete subclasses bind\n * either a single provider (contribution-shaped) or the router (aggregator).\n */\nexport abstract class BaseSwap2Protocol extends Swap2Protocol {\n protected readonly fromChain: string;\n\n constructor(account: Swap2Account | undefined, config: Swap2EngineConfig) {\n const fromChain = toCaip2(config.fromChain, \"\");\n if (!fromChain) throw new Swap2ValidationError(\"swap2: fromChain is required\");\n const configSnapshot = Object.freeze({...config, fromChain});\n super(account as never, configSnapshot);\n this.fromChain = fromChain;\n }\n\n /** Quote the route (single provider, or best across the router). */\n protected abstract resolveQuote(params: QuoteParams): Promise<Quote | null>;\n\n /** Why the last resolveQuote came back empty (venue names + reasons), or \"\".\n * Rides inside the no-route error so execution failures are diagnosable\n * from the surface that shows them. */\n protected noRouteDetail(): string {\n return \"\";\n }\n /** Look up a provider by name to resume/track an in-flight swap2. */\n protected abstract providerFor(name: string): CrossChainProvider | undefined;\n /** Whether this protocol can route a chain at all (for support discovery). */\n protected abstract chainSupported(caip2: string): boolean;\n\n /** Report an execution phase; an observer that throws is ignored. */\n protected emitPhase(phase: Swap2ExecutionPhase, detail?: Swap2ExecutionPhaseDetail): void {\n const observer = (this._config as Swap2EngineConfig).onExecutionPhase;\n if (!observer) return;\n try {\n observer(phase, detail);\n } catch {\n /* diagnostics only */\n }\n }\n /** Runtime availability used by the public discovery methods. */\n protected protocolEnabled(): boolean { return true; }\n /** Pair-level capability used when discovery specifies both endpoints. */\n protected pairSupported(fromChain: string, toChain: string): boolean {\n return this.chainSupported(fromChain) && this.chainSupported(toChain);\n }\n\n /** Swap2Options → the engine's QuoteParams (exact-in only). */\n protected toParams(options: Swap2Options, dry: boolean): QuoteParams {\n if (options.fromTokenAmount == null) {\n throw new Swap2UnsupportedOperationError(\"swap2: exact-out swap2 is not supported by the engine\");\n }\n const destChain = toCaip2(options.toChain, this.fromChain);\n const constraints = callerConstraints(options);\n const amountIn = exactPositiveAmount(options.fromTokenAmount, \"fromTokenAmount\");\n const params: QuoteParams = {\n sourceChain: this.fromChain,\n sourceToken: toSymbol(this.fromChain, options.fromToken),\n destChain,\n destToken: toDestAddress(destChain, options.toToken),\n amountIn: amountIn.toString(),\n destAddress: options.recipient ?? \"\",\n dry,\n ...(constraints.minAmountOut !== undefined ? {minAmountOut: constraints.minAmountOut.toString()} : {}),\n ...(constraints.slippageBps !== undefined ? {slippageBps: constraints.slippageBps} : {}),\n };\n return options.refundAddress ? {...params, refundAddress: options.refundAddress} : params;\n }\n\n private async assertAccountChain(signer: Swap2Signer): Promise<void> {\n const config = this._config as Swap2EngineConfig;\n if (config.skipAccountChainCheck) return;\n const actual = await readAccountChain(signer, config.accountChain);\n if (actual == null) {\n throw new Error(`swap2: account chain identity is unavailable for ${this.fromChain}; set accountChain or explicitly opt out with skipAccountChainCheck`);\n }\n const expected = this.fromChain;\n const expectedId = expected.startsWith(\"eip155:\") ? expected.slice(\"eip155:\".length) : expected;\n const actualText = swap2ChainId(typeof actual === \"string\" ? actual : String(actual));\n const actualId = actualText.startsWith(\"eip155:\") ? actualText.slice(\"eip155:\".length) : actualText;\n if (actualId !== expectedId) {\n throw new Error(`swap2: account is bound to ${actualText}, but fromChain is ${expected}`);\n }\n }\n\n protected assertFeeConfig(config?: Swap2ProtocolConfig): void {\n const configured = {...(this._config as Swap2ProtocolConfig), ...(config ?? {})};\n for (const [name, value] of [[\"maxNetworkFeeBps\", configured.maxNetworkFeeBps], [\"maxProtocolFeeBps\", configured.maxProtocolFeeBps]] as const) {\n if (value === undefined) continue;\n const bps = typeof value === \"bigint\" ? value : Number.isSafeInteger(value) ? BigInt(value) : -1n;\n if (bps < 0n || bps > 10_000n) throw new Swap2ConfigurationError(`swap2: ${name} must be an integer between 0 and 10000`);\n }\n }\n\n protected assertFeeCaps(\n fees: readonly Swap2Fee[] | undefined,\n sourceAmount: bigint,\n sourceToken: string,\n config?: Swap2ProtocolConfig,\n ): void {\n this.assertFeeConfig(config);\n const configured = {...(this._config as Swap2ProtocolConfig), ...(config ?? {})};\n const caps = [\n [\"network\", configured.maxNetworkFeeBps],\n [\"protocol\", configured.maxProtocolFeeBps],\n ] as const;\n if (!caps.some(([, cap]) => cap !== undefined)) return;\n if (!fees) throw new Swap2FeeLimitError(\"swap2: fee caps require an itemized provider fee breakdown\");\n const normalizedSource = sourceToken.toLowerCase();\n for (const [type, cap] of caps) {\n if (cap === undefined) continue;\n const matching = fees.filter((fee) => fee.type === type);\n if (matching.some((fee) => fee.token.toLowerCase() !== normalizedSource)) {\n throw new Swap2FeeLimitError(`swap2: cannot apply ${type} fee cap across different fee tokens`);\n }\n const total = matching.reduce((sum, fee) => sum + fee.amount, 0n);\n const bps = typeof cap === \"bigint\" ? cap : BigInt(cap);\n if (total * 10_000n > sourceAmount * bps) {\n throw new Swap2FeeLimitError(`swap2: ${type} fee exceeds configured cap`);\n }\n }\n }\n\n protected assertQuoteFeeCaps(q: Quote, options: Swap2Options, config?: Swap2ProtocolConfig): void {\n const source = ccAsset(this.fromChain, toSymbol(this.fromChain, options.fromToken));\n if (!source) throw new Error(`swap2: unknown source token '${options.fromToken}' on ${this.fromChain}`);\n const token = source.contract ?? source.assetId;\n const fees = q.fees?.map((fee) => ({...fee, amount: BigInt(fee.amount)} as Swap2Fee));\n this.assertFeeCaps(fees, BigInt(q.sourceAmount), token, config);\n }\n\n protected toQuote(q: Quote, options: Swap2Options): Swap2Quote {\n // Never fabricate a zero-valued fee. Providers that expose base-unit fee\n // amounts map them precisely; otherwise the net guaranteed output remains\n // authoritative and the itemized list is honestly empty.\n const fees: Swap2Fee[] = (q.fees ?? []).map((fee) => ({\n type: fee.type,\n amount: BigInt(fee.amount),\n token: fee.token,\n included: fee.included,\n ...(fee.description ? {description: fee.description} : {}),\n }));\n return {\n fromTokenAmount: BigInt(q.sourceAmount),\n toTokenAmount: BigInt(q.destAmount),\n toTokenAmountMin: BigInt(q.minDestAmount),\n fees,\n ...(q.etaSeconds ? {estimatedDuration: q.etaSeconds} : {}),\n ...(q.validUntilMs ? {expiry: Math.floor(q.validUntilMs / 1000)} : {}),\n };\n }\n\n /** A frozen, validated copy of caller options (what every engine path works from). */\n protected snapshotOf(options: Swap2Options): Swap2Options {\n return snapshotOptions(options);\n }\n\n /** A dry route the auction already validated → the public quote, or null when the caller's floor / fee caps refuse it. */\n protected routeQuote(q: Quote, options: Swap2Options): Swap2Quote | null {\n try {\n assertQuoteConstraints(q, options);\n this.assertQuoteFeeCaps(q, options);\n return this.toQuote(q, options);\n } catch {\n return null;\n }\n }\n\n /**\n * Ask for a quote and check it against the request (amounts, slippage floor, fee ceilings in the\n * protocol config). Works on a read-only account.\n *\n * @throws {@link Swap2QuoteError} when no route answers, with the provider's own reason when it\n * gave one.\n */\n override async quoteSwap2(options: Swap2Options): Promise<Swap2Quote> {\n const snapshot = snapshotOptions(options);\n const q = await this.resolveQuote(this.toParams(snapshot, true));\n if (!q) {\n const detail = this.noRouteDetail();\n throw new Swap2QuoteError(`swap2: no route available for the requested pair${detail ? ` :: ${detail}` : \"\"}`);\n }\n assertQuoteConstraints(q, snapshot);\n this.assertQuoteFeeCaps(q, snapshot);\n return this.toQuote(q, snapshot);\n }\n\n /**\n * Re-quote, check the quote, show it to `reviewExecution` when configured, send any approvals,\n * then sign and broadcast the source leg. An identical call already in flight on the same account\n * is refused.\n *\n * @throws {@link Swap2ExecutionError} for a read-only account, {@link Swap2InFlightError} for a\n * double tap, {@link Swap2MaybeSentError} when the broadcast outcome is unknown (do not retry;\n * track `hash`).\n */\n override async swap2(options: Swap2Options, config?: Swap2ProtocolConfig): Promise<Swap2Result> {\n // Account first: a read-only or missing account is refused before any option is\n // validated or any network call is made (SDK protocol conformance).\n const signerCandidate = this._account as Partial<Swap2Signer> | undefined;\n if (!signerCandidate || typeof signerCandidate.sendTransaction !== \"function\") {\n throw new Swap2ExecutionError(\"swap2: swap2() requires a signing account (read-only accounts can only quote)\");\n }\n const snapshot = snapshotOptions(options);\n requireExecutionFloor(snapshot);\n // A double tap re-quotes and would run a second complete swap: refuse it\n // while the identical call is still in flight on this account.\n const key = inFlightKey(this.fromChain, snapshot);\n const running = IN_FLIGHT.get(signerCandidate) ?? new Set<string>();\n if (running.has(key)) throw new Swap2InFlightError(\"swap2: an identical swap is already in progress on this account — wait for its result\");\n running.add(key);\n IN_FLIGHT.set(signerCandidate, running);\n try {\n return await this.executeSwap2(signerCandidate as Swap2Signer, snapshot, config);\n } finally {\n running.delete(key);\n }\n }\n\n private async executeSwap2(signer: Swap2Signer, snapshot: Swap2Options, config?: Swap2ProtocolConfig, carried?: CarriedAllowance): Promise<Swap2Result> {\n const configSnapshot = snapshotConfig(config);\n this.assertFeeConfig(configSnapshot);\n await this.assertAccountChain(signer);\n // Refunds land on the SOURCE chain, so the only safe default is the bound\n // account's own address — never the recipient, which may be a dest-chain\n // address (a TON-source swap with an EVM recipient would otherwise hand the\n // provider an EVM string as the TON refund/trader wallet).\n const selfAddress = await signer.getAddress();\n const recipient = snapshot.recipient ?? selfAddress;\n const refundAddress = snapshot.refundAddress ?? selfAddress;\n const executionOptions = snapshotOptions({...snapshot, recipient, refundAddress});\n const params = this.toParams(executionOptions, false);\n const resolved = await this.resolveQuote(params);\n if (!resolved) {\n const detail = this.noRouteDetail();\n throw new Swap2QuoteError(`swap2: no route available for the requested pair${detail ? ` :: ${detail}` : \"\"}`);\n }\n const q = snapshotQuote(resolved);\n assertQuoteConstraints(q, executionOptions);\n this.assertQuoteFeeCaps(q, executionOptions, configSnapshot);\n\n const provider = this.providerFor(q.provider);\n if (!provider) throw new Error(`swap2: provider '${q.provider}' is not registered`);\n let providerEnabled = false;\n try { providerEnabled = provider.enabled(); } catch { /* fail closed below */ }\n if (!providerEnabled) throw new Error(`swap2: provider '${q.provider}' is disabled`);\n let unsigned: UnsignedTx = Object.freeze({...await provider.buildDeposit(q)});\n\n const serialized = unsigned.serializedTx !== undefined;\n if (serialized) {\n if (!unsigned.serializedTx) throw new Error(\"swap2: provider returned an empty serialized transaction\");\n if (unsigned.data !== undefined || unsigned.bodyBoc !== undefined || unsigned.typedData !== undefined || unsigned.memo !== undefined || unsigned.approvalAddress !== undefined) {\n throw new Error(\"swap2: provider returned ambiguous execution payloads\");\n }\n if (typeof signer.sendSerializedTransaction !== \"function\") {\n throw new Swap2ExecutionError(`swap2: ${this.fromChain} serialized execution requires account.sendSerializedTransaction`);\n }\n }\n if (unsigned.chain && unsigned.chain !== this.fromChain) {\n throw new Error(`swap2: provider transaction chain ${unsigned.chain} does not match ${this.fromChain}`);\n }\n if (unsigned.stateInitBoc !== undefined) {\n throw new Error(\"swap2: deposit requires a stateInit the generic account cannot attach\");\n }\n // A remote build response is not a new authority. For ordinary calldata and\n // deposit-address providers the validated quote already commits every\n // execution field; require buildDeposit to reproduce it exactly.\n if (q.txRequest) {\n const tx = q.txRequest;\n const sameAddress = (a: string | undefined, b: string | undefined) =>\n a === b || (!!a && !!b && a.startsWith(\"0x\") && b.startsWith(\"0x\") && a.toLowerCase() === b.toLowerCase());\n if (\n !sameAddress(unsigned.to, tx.to ?? \"\") ||\n unsigned.data !== tx.data ||\n unsigned.value !== (tx.value ?? \"0\") ||\n unsigned.chainId !== tx.chainId ||\n unsigned.gasLimit !== tx.gasLimit ||\n !sameAddress(unsigned.approvalAddress, tx.approvalAddress) ||\n unsigned.serializedTx !== tx.serializedTx\n ) {\n throw new Error(\"swap2: provider build does not match the validated quote transaction\");\n }\n } else if (!unsigned.bodyBoc && !unsigned.typedData) {\n if (!q.depositAddress || unsigned.to !== q.depositAddress || (unsigned.memo ?? null) !== q.depositMemo) {\n throw new Error(\"swap2: provider build does not match the validated quote deposit\");\n }\n }\n const executionModels = [unsigned.data !== undefined, unsigned.bodyBoc !== undefined, unsigned.typedData !== undefined]\n .filter(Boolean).length;\n if (executionModels > 1 || (unsigned.memo !== undefined && (unsigned.bodyBoc !== undefined || unsigned.typedData !== undefined))) {\n throw new Error(\"swap2: provider returned ambiguous execution payloads\");\n }\n if (unsigned.approvalAddress && !unsigned.data && !unsigned.typedData) {\n throw new Error(\"swap2: approval is only valid for calldata or typed-order execution\");\n }\n // Memo'd deposits: TON carries it as the message body, Tron in\n // raw_data.data (both TRX and TRC-20 — bifrost reads that field for\n // either contract type). Every other chain would silently drop it.\n const tronSource = this.fromChain.startsWith(\"tron:\");\n // NEAR: a NEP-141 `ft_transfer` carries `memo`; a native transfer cannot\n // (the account refuses a memo it would otherwise drop).\n const nearSource = this.fromChain.startsWith(\"near:\");\n if (unsigned.memo && !this.fromChain.startsWith(\"ton:\") && !tronSource && !nearSource) {\n throw new Error(`swap2: deposit memo execution is not implemented for ${this.fromChain}`);\n }\n if (unsigned.data !== undefined && !this.fromChain.startsWith(\"eip155:\")) {\n throw new Error(`swap2: calldata execution is not implemented for ${this.fromChain}`);\n }\n // Cell-body deposits (Omniston escrow): the body MUST be decoded to a Cell —\n // a TON account renders a string body as a text comment, stranding the\n // swap. Fail closed unless the caller supplied `decodeTonBody`.\n let cellBody: unknown;\n if (unsigned.bodyBoc !== undefined) {\n if (!unsigned.bodyBoc) throw new Error(\"swap2: cell-body deposit has an empty body\");\n if (!this.fromChain.startsWith(\"ton:\")) {\n throw new Error(`swap2: cell-body execution is not implemented for ${this.fromChain}`);\n }\n const decode = (this._config as Swap2EngineConfig).decodeTonBody;\n if (!decode) {\n throw new Error(\"swap2: cell-body deposit needs config.decodeTonBody (e.g. Cell.fromBase64)\");\n }\n cellBody = decode(unsigned.bodyBoc);\n if (cellBody == null) {\n throw new Error(\"swap2: config.decodeTonBody returned no Cell\");\n }\n }\n if (unsigned.chainId !== undefined && this.fromChain.startsWith(\"eip155:\") && String(unsigned.chainId) !== this.fromChain.slice(\"eip155:\".length)) {\n throw new Error(`swap2: provider transaction chain ${unsigned.chainId} does not match ${this.fromChain}`);\n }\n\n // TOKEN-asset sources on deposit-address routes need token-transfer\n // semantics: a bare {to, value} would move the NATIVE coin with the\n // token's base-unit amount (audit C1 — e.g. USDT source via a 1Click\n // deposit address would have sent ETH wei). EVM sources are rewritten\n // into an ERC-20 transfer(depositAddress, amount); supported non-EVM\n // sources use the account's transfer() token surface below.\n let tokenId: string | undefined;\n if (!unsigned.data && !unsigned.bodyBoc && !unsigned.typedData && !serialized) {\n const src = ccAsset(this.fromChain, toSymbol(this.fromChain, executionOptions.fromToken));\n if (src?.contract) {\n if (this.fromChain.startsWith(\"eip155:\")) {\n unsigned = {\n ...unsigned,\n to: src.contract,\n data: encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [unsigned.to as `0x${string}`, BigInt(q.sourceAmount)],\n }),\n value: \"0\",\n };\n } else if (\n this.fromChain.startsWith(\"solana:\") ||\n this.fromChain.startsWith(\"ton:\") ||\n this.fromChain.startsWith(\"tron:\") ||\n nearSource\n ) {\n // Solana SPL / TON jetton / Tron TRC-20 / NEAR NEP-141 source. These\n // accounts expose token movement through `transfer()`; their\n // `sendTransaction({to,value})` surface is a NATIVE transfer and does\n // not recognize custom token metadata.\n tokenId = src.contract;\n } else {\n throw new Error(\n `swap2: token deposit-address execution is not implemented for ${this.fromChain} — only cell-body/calldata providers can move non-native assets here`,\n );\n }\n }\n }\n\n // A TON jetton transfer carries the memo as its forward-payload comment: the\n // account's `transfer({memo})` surface places it there (TEP-74), exactly as\n // Tron puts it in raw_data.data and NEAR in the ft_transfer memo.\n const tonSource = this.fromChain.startsWith(\"ton:\");\n if (tokenId && (cellBody !== undefined || (unsigned.memo !== undefined && !tronSource && !nearSource && !tonSource))) {\n throw new Error(\"swap2: token deposit with memo/cell payload is not implemented\");\n }\n\n // Bind the value presented to the signer to the already validated quote.\n // Native deposits and the amount handed to transfer() must carry the exact\n // input amount; EVM token execution must never attach native value.\n const source = ccAsset(this.fromChain, toSymbol(this.fromChain, executionOptions.fromToken));\n if (!source) throw new Error(`swap2: unknown source token '${executionOptions.fromToken}' on ${this.fromChain}`);\n const executionValue = BigInt(unsigned.value);\n if (serialized) {\n // The native coin leaves through the serialized tx itself; `value` only\n // declares what the account may let it take: the input for a native\n // source, nothing for a token source.\n if (executionValue !== (source.contract ? 0n : BigInt(q.sourceAmount))) {\n throw new Error(\"swap2: provider execution amount does not match the validated quote\");\n }\n } else if (source.contract && this.fromChain.startsWith(\"eip155:\")) {\n // Only a fee the sealed quote declared, and only up to the chain's cap.\n const declared = declaredNativeFee(q, this.fromChain);\n if (executionValue !== declared) {\n throw new Error(declared === 0n\n ? \"swap2: token execution attempted to attach native value\"\n : `swap2: token execution value ${executionValue} does not match the quoted native fee ${declared}`);\n }\n } else if (!unsigned.typedData && !unsigned.bodyBoc && executionValue !== BigInt(q.sourceAmount) + declaredNativeFee(q, this.fromChain)) {\n throw new Error(\"swap2: provider execution amount does not match the validated quote\");\n }\n\n // The engine binds the build to the quote; also bind what the quote's own\n // calldata hands out. A plain ERC-20 transfer / approval / Permit2 /\n // operator approval may only name this account, the quoted deposit\n // address or the declared spender/target. Aggregator calldata (a LI.FI\n // diamond, a THORChain router) is not decoded here — the provider's\n // target allowlist and the review screen cover it.\n if (unsigned.data !== undefined && this.fromChain.startsWith(\"eip155:\")) {\n const call = decodeCall({to: unsigned.to, data: unsigned.data, value: executionValue});\n const named = call.transfer?.to ?? call.approval?.spender;\n const allowed = [selfAddress, q.depositAddress, unsigned.approvalAddress, unsigned.to].filter((a): a is string => !!a).map((a) => a.toLowerCase());\n if (named && !allowed.includes(named.toLowerCase())) {\n throw new Swap2ValidationError(`swap2: quote calldata (${call.method}) names ${getAddress(named)}, which is not this account, the deposit address or the declared spender — refused`);\n }\n }\n\n // ERC-20 calldata/typed-order routes need an exact allowance. Decide the\n // approvals now (the reviewer sees exactly what will be sent) but send\n // them only after every local payload/value check, so a malformed build\n // cannot leave an allowance behind before failing validation.\n const needsApproval = !!unsigned.approvalAddress && !!source.contract;\n const approvalAmount = needsApproval ? BigInt(executionOptions.fromTokenAmount!) : 0n;\n const sameHex = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();\n let approvalAmounts: bigint[] = [];\n let revokeApproval: (() => Promise<void>) | undefined;\n if (carried && !needsApproval) {\n // The fresh quote no longer spends through an allowance: the one the\n // first pass mined would outlive this swap with nobody to revoke it.\n carried.adopted = true;\n await carried.revoke().catch(() => {});\n throw new Swap2QuoteError(\"swap2: the fresh quote no longer spends through an allowance — aborted, the allowance was revoked\");\n }\n if (needsApproval && carried) {\n // Re-quote pass: the allowance must fit the fresh quote exactly;\n // otherwise it is revoked and the swap aborts (the caller may retry).\n if (!sameHex(carried.token, source.contract!) || !sameHex(carried.spender, unsigned.approvalAddress!) || carried.amount !== approvalAmount) {\n carried.adopted = true;\n await carried.revoke().catch(() => {});\n throw new Swap2QuoteError(`swap2: the fresh quote moved the spender to ${unsigned.approvalAddress} — aborted, the allowance for ${carried.spender} was revoked`);\n }\n carried.adopted = true;\n revokeApproval = carried.revoke;\n } else if (needsApproval) {\n // Mainnet USDT refuses non-zero → non-zero; every other token\n // overwrites. The live allowance decides what is actually needed: the\n // reset only when USDT holds a non-zero value, nothing at all when the\n // exact amount is already in place (an allowance this engine did not\n // create is left alone on failure). A failed read assumes the worst.\n const usdtMainnet = this.fromChain === \"eip155:1\" && source.symbol.toUpperCase() === \"USDT\";\n let current: bigint | undefined;\n if (typeof signer.getAllowance === \"function\") {\n try {\n current = BigInt(await signer.getAllowance(source.contract!, unsigned.approvalAddress!));\n } catch {\n current = undefined;\n }\n }\n approvalAmounts = current === approvalAmount ? [] : [...(usdtMainnet && current !== 0n ? [0n] : []), approvalAmount];\n }\n\n // The re-quote pass is not reviewed again: everything the reviewer\n // committed to — source amount, spender, recipient, the caller's floor —\n // is unchanged by construction, and the engine re-validates the rest.\n const review = (this._config as Swap2EngineConfig).reviewExecution;\n if (review && !carried) {\n const chainId = unsigned.chainId !== undefined ? {chainId: unsigned.chainId} : {};\n const approvals: Swap2ExecutionPlan[\"approvals\"] = approvalAmounts.map((amount) =>\n ({token: source.contract!, spender: unsigned.approvalAddress!, amount, ...chainId}));\n const plan: Swap2ExecutionPlan = {\n provider: q.provider,\n fromChain: this.fromChain,\n destChain: params.destChain,\n destToken: params.destToken,\n recipient,\n refundAddress,\n sourceAmount: BigInt(q.sourceAmount),\n destAmount: BigInt(q.destAmount),\n minDestAmount: BigInt(q.minDestAmount),\n feeUsd: q.feeUsd,\n etaSeconds: q.etaSeconds,\n validUntilMs: q.validUntilMs,\n approvals,\n source: serialized\n ? {kind: \"serialized\", serializedTx: unsigned.serializedTx!}\n : unsigned.typedData\n ? {kind: \"typed-order\", typedData: unsigned.typedData}\n : tokenId\n ? {kind: \"token-transfer\", token: tokenId, recipient: unsigned.to, amount: BigInt(q.sourceAmount), ...(unsigned.memo ? {memo: unsigned.memo, ...(unsigned.memoEncoding ? {memoEncoding: unsigned.memoEncoding} : {})} : {})}\n : {\n kind: \"call\",\n to: unsigned.to,\n ...(unsigned.data ? {data: unsigned.data} : {}),\n value: BigInt(unsigned.value),\n ...(unsigned.chainId !== undefined ? {chainId: unsigned.chainId} : {}),\n ...(unsigned.gasLimit ? {gasLimit: BigInt(unsigned.gasLimit)} : {}),\n ...(unsigned.memo ? {memo: unsigned.memo, ...(unsigned.memoEncoding ? {memoEncoding: unsigned.memoEncoding} : {})} : {}),\n ...(cellBody !== undefined ? {cellBody: true} : {}),\n },\n };\n // A frozen deep copy: nothing the reviewer does reaches the payload sent below.\n await review(deepFreeze(structuredCloneSafe(plan)));\n if (q.validUntilMs > 0 && q.validUntilMs <= Date.now()) {\n throw new Swap2QuoteError(\"swap2: quote expired during review — nothing was signed\");\n }\n }\n\n await this.assertNativeGas(signer, unsigned, approvalAmounts, source.contract ?? undefined, !!unsigned.typedData || serialized || !!tokenId);\n\n if (approvalAmounts.length) {\n const approve = async (amount: bigint) => {\n const sent = await signer.sendTransaction({\n to: source.contract!,\n data: approveData(unsigned.approvalAddress!, amount),\n value: 0n,\n ...(unsigned.chainId !== undefined ? {chainId: unsigned.chainId} : {}),\n });\n // The next step (a second approve, or the deposit's gas estimate)\n // reads on-chain allowance: it must see this approval mined.\n if (sent.hash && typeof signer.waitForTransaction === \"function\") await signer.waitForTransaction(sent.hash);\n return sent;\n };\n // Install cleanup BEFORE broadcasting approval. An RPC can lose the\n // response after the transaction was accepted; treating that exception\n // as \"nothing happened\" would leave a live allowance with no callback.\n revokeApproval = async () => { await approve(0n); };\n try {\n for (const [i, amount] of approvalAmounts.entries()) {\n this.emitPhase(\"approving\", {index: i + 1, total: approvalAmounts.length});\n await approve(amount);\n }\n } catch (error) {\n await revokeApproval().catch(() => {});\n throw error;\n }\n }\n\n // The quote/build step can be separated from the actual send by an ERC-20\n // approval. Recheck rotating/halt-sensitive provider state only now.\n if (q.validUntilMs > 0 && q.validUntilMs <= Date.now()) {\n // The mined approvals outlived the quote (mainnet USDT: 50–108 s of\n // approvals against a 55 s LI.FI / 45 s Omniston TTL, SDK-128). The\n // allowance is exact and ours: quote once more and spend it, instead of\n // revoking it (a third tx) and making the caller pay for the approvals\n // again. The second pass is bound to the same spender and amount, held\n // to the caller's floor like the first, and never re-quotes itself.\n if (!carried && approvalAmounts.length && revokeApproval) {\n this.emitPhase(\"requoting\");\n const handoff: CarriedAllowance = {token: source.contract!, spender: unsigned.approvalAddress!, amount: approvalAmount, revoke: revokeApproval, adopted: false};\n try {\n return await this.executeSwap2(signer, snapshot, config, handoff);\n } catch (error) {\n if (!handoff.adopted) await revokeApproval().catch(() => {});\n throw error;\n }\n }\n await revokeApproval?.().catch(() => {});\n throw new Swap2QuoteError(\"swap2: quote expired before source broadcast\");\n }\n try {\n let providerStillEnabled = false;\n try { providerStillEnabled = provider.enabled(); } catch { /* fail closed below */ }\n if (!providerStillEnabled) throw new Error(`swap2: provider '${q.provider}' was disabled before source broadcast`);\n if (provider.preflightDeposit) this.emitPhase(\"preflight\");\n await provider.preflightDeposit?.(q, unsigned);\n } catch (error) {\n await revokeApproval?.().catch(() => {});\n throw error;\n }\n\n // GASLESS typed-order execution (Omniston EVM-source): sign the EIP-712\n // payload and register it with the provider — there is no source tx.\n if (unsigned.typedData) {\n try {\n if (!signer.signTypedData) {\n throw new Error(\"swap2: typed-order execution needs an account with signTypedData\");\n }\n if (!provider.registerSignedOrder) {\n throw new Error(`swap2: provider '${q.provider}' cannot register signed orders`);\n }\n const td = JSON.parse(unsigned.typedData) as {\n domain: unknown;\n types: Record<string, unknown>;\n primaryType?: string;\n message: unknown;\n };\n if (!td || typeof td !== \"object\" || !td.domain || !td.types || typeof td.types !== \"object\" || !td.message) {\n throw new Error(\"swap2: provider returned malformed typed data\");\n }\n // ethers and the account infer the domain type and reject an explicit\n // EIP712Domain entry as an ambiguous primary type.\n const {EIP712Domain: _domain, ...types} = td.types;\n // Providers may send the domain chainId as a hex string (\"0x89\");\n // signers that build the EIP712Domain type from value types (viem)\n // would then drop chainId from the domain and produce a signature the\n // verifying contract rejects (Omniston order, 2026-10-16). Sign with a number.\n const signature = await signer.signTypedData({\n domain: normalizeTypedDomain(td.domain),\n types,\n ...(td.primaryType ? {primaryType: td.primaryType} : {}),\n message: td.message,\n });\n await provider.registerSignedOrder(q.intentId, signature);\n return {\n id: encodeId(q.provider, q.intentId),\n fees: this.toQuote(q, executionOptions).fees,\n fromTokenAmount: BigInt(q.sourceAmount),\n toTokenAmount: BigInt(q.destAmount),\n toTokenAmountMin: BigInt(q.minDestAmount),\n };\n } catch (error) {\n // Any failed validation/sign/registration must not leave a reusable\n // exact allowance behind. If the RPC response was lost after\n // registration, revocation safely prevents execution.\n await revokeApproval?.().catch(() => {});\n throw error;\n }\n }\n\n // Execute the source leg through the bound account. Non-EVM token deposits\n // MUST use the account's transfer({token,recipient,amount}); passing token metadata\n // to sendTransaction would be ignored and send native SOL/TON/TRX instead.\n let sent: {hash?: string};\n this.emitPhase(\"signing\");\n try {\n if (serialized) {\n const allowanceRaw = (this._config as Swap2EngineConfig).serializedNativeAllowance;\n const allowance = allowanceRaw === undefined ? DEFAULT_SERIALIZED_NATIVE_ALLOWANCE : BigInt(allowanceRaw);\n if (allowance < 0n) throw new Swap2ConfigurationError(\"swap2: serializedNativeAllowance must be non-negative\");\n const expect: SerializedExecutionExpectation = {\n maxValueOut: ((source.contract ? 0n : BigInt(q.sourceAmount)) + allowance).toString(),\n // Only a same-chain swap lands in this account; a bridge delivers elsewhere.\n ...(params.destChain === this.fromChain ? {tokenIn: {token: params.destToken, minAmount: q.minDestAmount}} : {}),\n ...(source.contract ? {source: {token: source.contract, maxAmount: q.sourceAmount}} : {}),\n };\n sent = await signer.sendSerializedTransaction!(unsigned.serializedTx!, expect);\n } else if (tokenId) {\n if (typeof signer.transfer !== \"function\") {\n throw new Swap2ExecutionError(\n `swap2: ${this.fromChain} token execution requires account.transfer({token, recipient, amount})`,\n );\n }\n sent = await signer.transfer({\n token: tokenId,\n recipient: unsigned.to,\n amount: BigInt(q.sourceAmount),\n ...((tronSource || nearSource || tonSource) && unsigned.memo ? {memo: unsigned.memo, ...(tronSource && unsigned.memoEncoding ? {memoEncoding: unsigned.memoEncoding} : {})} : {}),\n });\n } else {\n sent = await signer.sendTransaction({\n to: unsigned.to,\n ...(unsigned.data ? {data: unsigned.data} : {}),\n value: BigInt(unsigned.value),\n ...(unsigned.chainId !== undefined ? {chainId: unsigned.chainId} : {}),\n ...(unsigned.gasLimit ? {gasLimit: BigInt(unsigned.gasLimit)} : {}),\n ...(cellBody !== undefined\n ? {body: cellBody}\n : unsigned.memo\n ? (tronSource ? {memo: unsigned.memo, ...(unsigned.memoEncoding ? {memoEncoding: unsigned.memoEncoding} : {})} : nearSource ? {memo: unsigned.memo} : {body: unsigned.memo})\n : {}),\n });\n }\n if (!sent.hash) throw new Swap2ExecutionError(\"swap2: account did not return a source transaction hash\");\n this.emitPhase(\"broadcast\", {hash: sent.hash});\n } catch (error) {\n // The deposit may be in the mempool: revoking would race it, and a\n // \"clean\" error invites a retry that sends a second deposit.\n const unknown = maybeSent(error);\n if (unknown) {\n throw new Swap2MaybeSentError(\n `swap2: the source transaction may have been broadcast (${error instanceof Error ? error.message.slice(0, 160) : String(error).slice(0, 160)}) — do not retry; ${unknown.hash ? `poll the status of ${unknown.hash}` : \"check the account's recent transactions\"}`,\n unknown.hash,\n unknown.hash ? encodeId(q.provider, q.intentId, unknown.hash) : undefined,\n {cause: error},\n );\n }\n await revokeApproval?.().catch(() => {});\n throw error;\n }\n\n if (provider.notifyDeposit) {\n await provider.notifyDeposit(q.intentId, sent.hash).catch(() => {});\n }\n\n const fees = this.toQuote(q, executionOptions).fees;\n return {\n id: encodeId(q.provider, q.intentId, sent.hash),\n fees,\n fromTokenAmount: BigInt(q.sourceAmount),\n toTokenAmount: BigInt(q.destAmount),\n toTokenAmountMin: BigInt(q.minDestAmount),\n ...(sent.hash ? {hash: sent.hash, transactions: [{hash: sent.hash, type: \"source\"}]} : {}),\n };\n }\n\n /**\n * EVM: refuse before the first approval when the native balance cannot pay\n * every approval, the main call and its value. Fees are the account's own\n * upper bound (`quoteSendTransaction`: gas × max fee). The main call's gas\n * comes from the quote's gas limit; without one it is estimated, which a\n * not-yet-approved call cannot do — then only approvals + value count.\n * Accounts without `getBalance`/`quoteSendTransaction` (and non-EVM chains,\n * whose accounts check their own fee at send) are not checked here.\n */\n private async assertNativeGas(signer: Swap2Signer, unsigned: UnsignedTx, approvalAmounts: bigint[], token: string | undefined, noMainCall: boolean): Promise<void> {\n if (!this.fromChain.startsWith(\"eip155:\") || typeof signer.getBalance !== \"function\" || typeof signer.quoteSendTransaction !== \"function\") return;\n const chainId = unsigned.chainId !== undefined ? {chainId: unsigned.chainId} : {};\n const fees = await Promise.all(approvalAmounts.map(async (amount) =>\n (await signer.quoteSendTransaction!({to: token!, data: approveData(unsigned.approvalAddress!, amount), value: 0n, ...chainId})).fee));\n const value = noMainCall ? 0n : BigInt(unsigned.value);\n if (!noMainCall) {\n const main = {to: unsigned.to, ...(unsigned.data ? {data: unsigned.data} : {}), value, ...chainId, ...(unsigned.gasLimit ? {gasLimit: BigInt(unsigned.gasLimit)} : {})};\n fees.push(await signer.quoteSendTransaction(main).then((r) => r.fee, (error) => {\n if (approvalAmounts.length) return 0n; // estimation needs the allowance the approval creates\n throw error;\n }));\n }\n const need = fees.reduce((a, b) => a + b, 0n) + value;\n const balance = BigInt(await signer.getBalance());\n if (balance < need) {\n throw new Swap2InsufficientGasError(`swap2: native balance ${balance} cannot pay this swap's gas: need ${need} (${fees.length} transaction${fees.length === 1 ? \"\" : \"s\"}${value ? ` + value ${value}` : \"\"}) — nothing was signed`);\n }\n }\n\n /** Status of a swap by the id `swap2()` returned, asked from the provider that executed it. */\n override async getSwap2Status(id: string, _options?: Swap2StatusOptions): Promise<Swap2StatusResult> {\n const {provider: name, intentId, sourceTxHash} = decodeId(id);\n const provider = this.providerFor(name);\n if (!provider) throw new Error(`swap2: no swap2 found for id '${id}'`);\n return mapStatus(await provider.trackIntent(sourceTxHash == null ? {intentId} : {intentId, sourceTxHash}));\n }\n\n /**\n * Two-phase routes (CCTP-style burn-and-mint): once `getSwap2Status` reports\n * \"action-required\", the delivery needs a second transaction on the\n * DESTINATION chain, signed there and paid in that chain's gas. `account` is\n * the destination-chain account (the bound source account is not reused:\n * the chains differ). The provider builds the claim from the attestation; it\n * is refused when not ready, when it names another chain than the account,\n * or when it is anything but plain EVM calldata. Returns the claim hash and\n * the status id to keep polling with.\n */\n async claimSwap2(id: string, account: Swap2Account): Promise<{hash: string; chain: string; id: string}> {\n const {provider: name, intentId, sourceTxHash} = decodeId(id);\n const provider = this.providerFor(name);\n if (!provider) throw new Error(`swap2: no swap2 found for id '${id}'`);\n if (typeof provider.buildClaim !== \"function\") {\n throw new Swap2UnsupportedOperationError(`swap2: provider '${name}' has no claim step`);\n }\n const signerCandidate = account as Partial<Swap2Signer> | undefined;\n if (!signerCandidate || typeof signerCandidate.sendTransaction !== \"function\") {\n throw new Swap2ExecutionError(\"swap2: claimSwap2() requires a signing account on the destination chain\");\n }\n const signer = signerCandidate as Swap2Signer;\n let providerEnabled = false;\n try { providerEnabled = provider.enabled(); } catch { /* fail closed below */ }\n if (!providerEnabled) throw new Error(`swap2: provider '${name}' is disabled`);\n const unsigned = await provider.buildClaim(sourceTxHash == null ? {intentId} : {intentId, sourceTxHash});\n if (!unsigned) throw new Swap2StatusError(\"swap2: the claim is not ready yet (attestation pending) — poll the status and retry\");\n if (!unsigned.chain || !unsigned.chain.startsWith(\"eip155:\")) {\n throw new Swap2UnsupportedOperationError(`swap2: claim execution is only implemented for EVM destinations (got '${unsigned.chain || \"?\"}')`);\n }\n if (!unsigned.to || !unsigned.data || !/^0x(?:[0-9a-fA-F]{2})+$/.test(unsigned.data)) {\n throw new Error(\"swap2: provider returned a malformed claim transaction\");\n }\n if (unsigned.serializedTx !== undefined || unsigned.bodyBoc !== undefined || unsigned.typedData !== undefined || unsigned.memo !== undefined || unsigned.approvalAddress !== undefined) {\n throw new Error(\"swap2: claim must be plain calldata\");\n }\n if (unsigned.value !== undefined && unsigned.value !== \"0\") throw new Error(\"swap2: a claim must not carry native value\");\n const expectedId = unsigned.chain.slice(\"eip155:\".length);\n if (unsigned.chainId !== undefined && String(unsigned.chainId) !== expectedId) {\n throw new Error(`swap2: claim chainId ${unsigned.chainId} does not match ${unsigned.chain}`);\n }\n const actual = await readAccountChain(signer);\n if (actual == null) throw new Error(`swap2: destination account chain identity is unavailable for ${unsigned.chain}`);\n const actualText = typeof actual === \"string\" ? actual : String(actual);\n const actualId = actualText.startsWith(\"eip155:\") ? actualText.slice(\"eip155:\".length) : actualText;\n if (actualId !== expectedId) throw new Error(`swap2: claim is on ${unsigned.chain}, but the account is bound to ${actualText}`);\n this.emitPhase(\"signing\");\n const sent = await signer.sendTransaction({\n to: unsigned.to,\n data: unsigned.data,\n value: 0n,\n chainId: Number(expectedId),\n ...(unsigned.gasLimit ? {gasLimit: BigInt(unsigned.gasLimit)} : {}),\n });\n if (!sent.hash) throw new Swap2ExecutionError(\"swap2: account did not return a claim transaction hash\");\n this.emitPhase(\"broadcast\", {hash: sent.hash});\n return {hash: sent.hash, chain: unsigned.chain, id};\n }\n\n /** The inherited bridge() has no floor field: quote first, then bind execution\n * to that quote's minimum so the inherited convenience API stays safe. */\n override async bridge(options: BridgeOptions): Promise<BridgeResult> {\n const amount = exactPositiveAmount(options.amount, \"amount\");\n const swap2Options: Swap2Options = {\n fromToken: options.token,\n toToken: options.token,\n toChain: options.targetChain,\n recipient: options.recipient,\n fromTokenAmount: amount,\n };\n const quote = await this.quoteSwap2(swap2Options);\n const result = await this.swap2({...swap2Options, minAmountOut: quote.toTokenAmountMin});\n const fee = result.fees.filter((f) => f.type === \"network\").reduce((sum, f) => sum + f.amount, 0n);\n const bridgeFee = result.fees.filter((f) => f.type === \"protocol\").reduce((sum, f) => sum + f.amount, 0n);\n return {hash: result.id, fee, bridgeFee};\n }\n\n /** Same protection for legacy exact-in swap() calls whose min is optional. */\n override async swap(options: SwapOptions): Promise<SwapResult> {\n if (options.tokenInAmount === undefined) {\n throw new Swap2UnsupportedOperationError(\"swap2: exact-out swap is not supported by the engine\");\n }\n const amount = exactPositiveAmount(options.tokenInAmount, \"tokenInAmount\");\n const swap2Options: Swap2Options = {\n fromToken: options.tokenIn,\n toToken: options.tokenOut,\n fromTokenAmount: amount,\n // `to` is optional on the legacy API: omit the key rather than passing\n // undefined, so swap2() falls back to the bound account's own address.\n ...(options.to !== undefined ? {recipient: options.to} : {}),\n ...(options.minAmountOut !== undefined ? {minAmountOut: options.minAmountOut} : {}),\n };\n const floor = options.minAmountOut ?? (await this.quoteSwap2(swap2Options)).toTokenAmountMin;\n const result = await this.swap2({...swap2Options, minAmountOut: floor});\n const fee = result.fees.reduce((sum, item) => sum + item.amount, 0n);\n return {hash: result.id, fee, tokenInAmount: result.fromTokenAmount, tokenOutAmount: result.toTokenAmount};\n }\n\n /** Source chains this protocol can swap from. */\n override async getSupportedChains(): Promise<Swap2SupportedChain[]> {\n if (!this.protocolEnabled()) return [];\n return CC_SOURCE_CHAINS.filter((c: CcChain) => this.chainSupported(c.caip2)).map((c) => ({\n id: c.caip2,\n name: c.label,\n type: chainType(c.caip2),\n nativeToken: c.assets[0]?.symbol ?? \"\",\n }));\n }\n\n /** Tokens of the asset catalog on the supported chains, optionally narrowed. */\n override async getSupportedTokens(options?: Swap2SupportedTokensOptions): Promise<Swap2SupportedToken[]> {\n const wantFrom = options?.fromChain != null ? toCaip2(options.fromChain, \"\") : undefined;\n const wantTo = options?.toChain != null ? toCaip2(options.toChain, \"\") : undefined;\n if (!this.protocolEnabled() || (wantFrom && wantTo && !this.pairSupported(wantFrom, wantTo))) return [];\n const out: Swap2SupportedToken[] = [];\n for (const c of CC_SOURCE_CHAINS) {\n if (!this.chainSupported(c.caip2)) continue;\n if ((wantFrom || wantTo) && c.caip2 !== wantFrom && c.caip2 !== wantTo) continue;\n for (const a of c.assets) {\n out.push({\n token: a.assetId,\n chain: c.caip2,\n symbol: a.symbol,\n decimals: a.decimals,\n ...(a.contract ? {address: a.contract} : {}),\n });\n }\n }\n return out;\n }\n}\n\nfunction structuredCloneSafe<T>(value: T): T {\n if (value === null || typeof value !== \"object\") return value;\n if (Array.isArray(value)) return value.map((v) => structuredCloneSafe(v)) as T;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) out[k] = structuredCloneSafe(v);\n return out as T;\n}\n\nfunction deepFreeze<T>(value: T): T {\n if (value && typeof value === \"object\") {\n for (const v of Object.values(value as Record<string, unknown>)) deepFreeze(v);\n Object.freeze(value);\n }\n return value;\n}\n"],"mappings":";;;;;;;;;;;;;;AAUA,SAAQ,qBAAoB;AAC5B,SAAQ,oBAAoB,kBAAiB;AAC7C,SAAQ,kBAAiB;AAkBzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAeP,IAAM,OAAO;AAEb,IAAM,qBAAqB;AAAA,EACzB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAC,MAAM,MAAM,MAAM,UAAS;AAAA,MAC5B,EAAC,MAAM,UAAU,MAAM,UAAS;AAAA,IAClC;AAAA,IACA,SAAS,CAAC,EAAC,MAAM,OAAM,CAAC;AAAA,EAC1B;AACF;AACA,IAAM,oBAAoB;AAAA,EACxB,EAAC,MAAM,YAAY,MAAM,WAAW,iBAAiB,cAAc,QAAQ,CAAC,EAAC,MAAM,WAAW,MAAM,UAAS,GAAG,EAAC,MAAM,UAAU,MAAM,UAAS,CAAC,GAAG,SAAS,CAAC,EAAC,MAAM,OAAM,CAAC,EAAC;AAC/K;AACA,IAAM,cAAc,CAAC,SAAiB,WACpC,mBAAmB,EAAC,KAAK,mBAAmB,cAAc,WAAW,MAAM,CAAC,SAA0B,MAAM,EAAC,CAAC;AAGhH,IAAM,YAAY,oBAAI,QAA6B;AACnD,IAAM,cAAc,CAAC,WAAmB,MACtC,KAAK;AAAA,EAAU,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ;AAAA,EACxJ,CAAC,IAAI,MAAO,OAAO,MAAM,WAAW,EAAE,SAAS,IAAI;AAAE;AASzD,SAAS,UAAU,OAAwC;AACzD,WAAS,IAAI,OAA6E,IAAI,GAAG,KAAK,OAAO,MAAM,YAAY,IAAI,GAAG,IAAI,EAAE,OAAmB,KAAK;AAClK,QAAI,EAAE,cAAc,KAAM,QAAO,OAAO,EAAE,SAAS,YAAY,EAAE,OAAO,EAAC,MAAM,EAAE,KAAI,IAAI,CAAC;AAAA,EAC5F;AACA,QAAM,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAClE,SAAO,qGAAqG,KAAK,IAAI,IAAI,CAAC,IAAI;AAChI;AA6BO,IAAM,kBAAoD,OAAO,OAAO;AAAA,EAC7E,eAAe;AAAA;AACjB,CAAC;AACD,IAAM,0BAA0B;AAEzB,SAAS,eAAe,OAAuB;AACpD,SAAO,gBAAgB,KAAK,KAAK;AACnC;AAEO,SAAS,YAAY,OAAe,OAAgC;AACzE,QAAM,OAAO,OAAO,KAAK;AACzB,MAAI,CAAC,gBAAgB,KAAK,IAAI,EAAG,OAAM,IAAI,MAAM,mCAAmC,IAAI,GAAG;AAC3F,QAAM,CAAC,KAAK,OAAO,EAAE,IAAI,KAAK,MAAM,GAAG;AACvC,QAAM,WAAW,eAAe,KAAK;AACrC,MAAI,KAAK,SAAS,SAAU,OAAM,IAAI,MAAM,WAAW,IAAI,mBAAmB,QAAQ,0BAA0B,KAAK,EAAE;AACvH,SAAO,OAAO,MAAM,KAAK,OAAO,UAAU,GAAG,CAAC;AAChD;AACA,IAAM,iBAAmD,OAAO,OAAO;AAAA,EACrE,YAAY;AAAA;AAAA,EACZ,cAAc;AAAA;AAAA,EACd,aAAa;AAAA;AAAA,EACb,gBAAgB;AAAA;AAAA,EAChB,cAAc;AAAA;AAAA;AAAA,EAEd,cAAc;AAAA;AAAA,EACd,cAAc;AAAA;AAAA,EACd,cAAc;AAAA;AAAA,EACd,eAAe;AAAA;AAAA,EACf,gBAAgB;AAAA;AAAA,EAChB,gBAAgB;AAAA;AAAA,EAChB,eAAe;AAAA;AAAA,EACf,gBAAgB;AAAA;AAAA,EAChB,cAAc;AAAA;AAAA;AAAA,EAEd,eAAe,YAAY,eAAe,EAAE;AAAA;AAAA,EAC5C,aAAa,YAAY,aAAa,IAAI;AAAA;AAAA,EAC1C,eAAe,YAAY,eAAe,EAAE;AAAA;AAAA;AAE9C,CAAC;AACD,IAAM,yBAAyB;AAE/B,SAAS,kBAAkB,GAAuC,OAAuB;AACvF,QAAM,MAAM,EAAE,WAAW;AACzB,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI,CAAC,QAAQ,KAAK,GAAG,EAAG,OAAM,IAAI,MAAM,8CAA8C;AACtF,QAAM,MAAM,OAAO,GAAG;AACtB,QAAM,MAAM,eAAe,KAAK,KAAK;AACrC,MAAI,MAAM,IAAK,OAAM,IAAI,MAAM,4BAA4B,GAAG,oBAAoB,GAAG,QAAQ,KAAK,EAAE;AACpG,SAAO;AACT;AAYO,SAAS,qBAAqB,QAA0B;AAC7D,MAAI,CAAC,UAAU,OAAO,WAAW,SAAU,QAAO;AAClD,QAAM,MAAO,OAA+B;AAC5C,MAAI;AACJ,MAAI,OAAO,QAAQ,SAAU,WAAU;AAAA,WAC9B,OAAO,QAAQ,SAAU,WAAU,OAAO,GAAG;AAAA,WAC7C,OAAO,QAAQ,YAAY,QAAQ,KAAK,GAAG,EAAG,WAAU,OAAO,GAAG;AAAA,WAClE,OAAO,QAAQ,YAAY,mBAAmB,KAAK,GAAG,EAAG,WAAU,OAAO,OAAO,GAAG,CAAC;AAC9F,SAAO,YAAY,UAAa,CAAC,OAAO,cAAc,OAAO,IAAI,SAAS,EAAC,GAAI,QAAmB,QAAO;AAC3G;AA2EA,IAAM,sCAAsC;AAsFrC,IAAM,kBAAkB;AAG/B,SAAS,SAAS,UAAkB,UAAkB,cAA+B;AAGnF,QAAM,MAAM,CAAC,MAAc,mBAAmB,CAAC,EAAE,QAAQ,OAAO,KAAK;AACrE,SAAO,GAAG,eAAe,IAAI,CAAC,UAAU,UAAU,YAAY,EAAE,OAAO,CAAC,MAAmB,KAAK,IAAI,EAAE,IAAI,GAAG,EAAE,KAAK,GAAG,CAAC;AAC1H;AACA,SAAS,SAAS,IAAyE;AACzF,MAAI;AACF,QAAI,CAAC,GAAG,WAAW,GAAG,eAAe,GAAG,EAAG,OAAM,IAAI,MAAM,wBAAwB;AACnF,UAAM,QAAQ,GAAG,MAAM,gBAAgB,SAAS,CAAC,EAAE,MAAM,GAAG;AAC5D,QAAI,MAAM,SAAS,KAAK,MAAM,SAAS,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAG,OAAM,IAAI,MAAM,kBAAkB;AACtG,UAAM,WAAW,mBAAmB,MAAM,CAAC,CAAC;AAC5C,UAAM,WAAW,mBAAmB,MAAM,CAAC,CAAC;AAC5C,UAAM,eAAe,MAAM,CAAC,IAAI,mBAAmB,MAAM,CAAC,CAAC,IAAI;AAC/D,QAAI,CAAC,mBAAmB,KAAK,QAAQ,KAAK,CAAC,YAAa,MAAM,CAAC,MAAM,UAAa,CAAC,cAAe;AAChG,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AACA,WAAO,EAAC,UAAU,UAAU,GAAI,eAAe,EAAC,aAAY,IAAI,CAAC,EAAE;AAAA,EACrE,QAAQ;AACN,UAAM,IAAI,qBAAqB,kCAAkC;AAAA,EACnE;AACF;AAEA,eAAe,iBAAiB,QAAqB,YAAoE;AACvH,MAAI,WAAY,QAAO;AAEvB,MAAI,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,CAAC,OAAO,MAAM,SAAS,UAAU,EAAG,QAAO,OAAO;AAC1G,MAAI,OAAO,OAAO,eAAe,WAAY,QAAO,MAAM,OAAO,WAAW;AAC5E,MAAI,OAAO,OAAO,eAAe,YAAY;AAC3C,UAAM,UAAU,MAAM,OAAO,WAAW;AACxC,WAAO,OAAO,YAAY,WAAW,UAAU,SAAS;AAAA,EAC1D;AACA,MAAI,OAAO,WAAW,KAAM,QAAO,OAAO;AAC1C,aAAW,YAAY,CAAC,OAAO,WAAW,OAAO,QAAQ,GAAG;AAC1D,QAAI,UAAU,YAAY;AACxB,YAAM,UAAU,MAAM,SAAS,WAAW;AAC1C,UAAI,SAAS,WAAW,KAAM,QAAO,QAAQ;AAAA,IAC/C;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,UAAU,OAAuB;AACxC,QAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK;AAClC,MAAI,OAAO,SAAU,QAAO;AAC5B,MAAI,OAAO,SAAU,QAAO;AAC5B,MAAI,OAAO,OAAQ,QAAO;AAC1B,MAAI,CAAC,WAAW,YAAY,QAAQ,OAAO,OAAO,EAAE,SAAS,EAAE,EAAG,QAAO;AACzE,SAAO;AACT;AAOO,IAAM,sBAAwD,OAAO,OAAO;AAAA,EACjF,2CAA2C;AAAA,EAC3C,mBAAmB;AAAA,EACnB,2CAA2C;AAC7C,CAAC;AAEM,IAAM,eAAe,CAAC,UAA0B,oBAAoB,KAAK,KAAK;AAGrF,SAAS,QAAQ,OAAoC,UAA0B;AAC7E,MAAI,SAAS,QAAQ,UAAU,GAAI,QAAO;AAC1C,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,EAAG,OAAM,IAAI,qBAAqB,iDAAiD;AAChI,WAAO,UAAU,KAAK;AAAA,EACxB;AACA,MAAI,QAAQ,KAAK,KAAK,GAAG;AACvB,UAAM,KAAK,OAAO,KAAK;AACvB,QAAI,CAAC,OAAO,cAAc,EAAE,KAAK,MAAM,EAAG,OAAM,IAAI,qBAAqB,iDAAiD;AAC1H,WAAO,UAAU,EAAE;AAAA,EACrB;AACA,MAAI,CAAC,sCAAsC,KAAK,KAAK,GAAG;AACtD,UAAM,IAAI,qBAAqB,gDAAgD;AAAA,EACjF;AACA,SAAO,aAAa,KAAK;AAC3B;AAGA,SAAS,SAAS,OAAe,KAAqB;AACpD,QAAM,UAAU,IAAI,WAAW,IAAI,KAAK,IAAI,SAAS,KAAK,eAAe,OAAO,GAAG,IAAI;AACvF,MAAI,QAAS,QAAO,QAAQ;AAC5B,MAAI,QAAQ,OAAO,GAAG,EAAG,QAAO;AAChC,SAAO;AACT;AAGA,SAAS,cAAc,OAAe,KAAqB;AACzD,MAAI,IAAI,WAAW,IAAI,EAAG,QAAO;AACjC,QAAM,QAAQ,eAAe,OAAO,GAAG,KAAK,QAAQ,OAAO,GAAG;AAC9D,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,qCAAqC,GAAG,QAAQ,KAAK,EAAE;AAAA,EACzE;AACA,SAAO,MAAM,YAAY;AAC3B;AAEA,SAAS,gBAAgB,SAAqC;AAC5D,SAAO,OAAO,OAAO,EAAC,GAAG,QAAO,CAAC;AACnC;AAEA,SAAS,eAAe,QAA+D;AACrF,SAAO,SAAS,OAAO,OAAO,EAAC,GAAG,OAAM,CAAC,IAAI;AAC/C;AAEA,SAAS,cAA+B,OAAa;AACnD,SAAO,OAAO,OAAO;AAAA,IACnB,GAAG;AAAA,IACH,GAAI,MAAM,YAAY,EAAC,WAAW,OAAO,OAAO,EAAC,GAAG,MAAM,UAAS,CAAC,EAAC,IAAI,CAAC;AAAA,IAC1E,GAAI,MAAM,eAAe,EAAC,cAAc,OAAO,OAAO,EAAC,GAAG,MAAM,aAAY,CAAC,EAAC,IAAI,CAAC;AAAA,IACnF,GAAI,MAAM,OAAO,EAAC,MAAM,OAAO,OAAO,MAAM,KAAK,IAAI,CAAC,QAAQ,OAAO,OAAO,EAAC,GAAG,IAAG,CAAC,CAAC,CAAC,EAAC,IAAI,CAAC;AAAA,EAC9F,CAAC;AACH;AAEA,SAAS,oBAAoB,OAAwB,MAAsB;AACzE,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,GAAG;AAC9C,YAAM,IAAI,qBAAqB,UAAU,IAAI,4CAA4C;AAAA,IAC3F;AACA,WAAO,OAAO,KAAK;AAAA,EACrB;AACA,MAAI,SAAS,GAAI,OAAM,IAAI,qBAAqB,UAAU,IAAI,4CAA4C;AAC1G,SAAO;AACT;AAOA,SAAS,YAAY,GAAW,OAAuB;AACrD,QAAM,IAAI,IAAI;AACd,QAAM,UAAU,KAAK,MAAM,CAAC;AAC5B,SAAO,KAAK,IAAI,IAAI,OAAO,IAAI,OAAO,UAAU,KAAK,MAAM,CAAC;AAC9D;AAEA,SAAS,kBAAkB,SAAsE;AAC/F,MAAI;AACJ,MAAI,QAAQ,iBAAiB,QAAW;AACtC,QAAI;AACF,qBAAe,OAAO,QAAQ,YAAY;AAAA,IAC5C,QAAQ;AACN,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,QAAI,gBAAgB,GAAI,OAAM,IAAI,MAAM,gDAAgD;AAAA,EAC1F;AACA,MAAI;AACJ,MAAI,QAAQ,aAAa,QAAW;AAClC,QAAI,CAAC,OAAO,SAAS,QAAQ,QAAQ,KAAK,QAAQ,WAAW,KAAK,QAAQ,YAAY,GAAG;AACvF,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AAIA,kBAAc,YAAY,QAAQ,UAAU,GAAM;AAAA,EACpD;AACA,SAAO;AAAA,IACL,GAAI,iBAAiB,SAAY,EAAC,aAAY,IAAI,CAAC;AAAA,IACnD,GAAI,gBAAgB,SAAY,EAAC,YAAW,IAAI,CAAC;AAAA,EACnD;AACF;AAEA,SAAS,uBAAuB,GAAU,SAA6B;AACrE,QAAM,EAAC,aAAY,IAAI,kBAAkB,OAAO;AAChD,QAAM,UAAU,OAAO,EAAE,UAAU;AACnC,QAAM,aAAa,OAAO,EAAE,aAAa;AACzC,MAAI,iBAAiB,UAAa,aAAa,cAAc;AAC3D,UAAM,IAAI,MAAM,yBAAyB,UAAU,iCAAiC,YAAY,EAAE;AAAA,EACpG;AACA,MAAI,QAAQ,aAAa,QAAW;AAClC,UAAM,QAAQ;AACd,UAAM,YAAY,OAAO,YAAY,QAAQ,UAAU,OAAO,KAAK,CAAC,CAAC;AAErE,UAAM,WAAY,WAAW,QAAQ,aAAc;AACnD,QAAI,aAAa,UAAU;AACzB,YAAM,IAAI,MAAM,yCAAyC,QAAQ,QAAQ,GAAG;AAAA,IAC9E;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,SAA6B;AAC1D,MAAI,QAAQ,iBAAiB,QAAW;AACtC,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,oBAAkB,OAAO;AAC3B;AAEA,SAAS,UAAU,GAAoC;AACrD,QAAM,SACJ,EAAE,UAAU,cACR,cACA,EAAE,UAAU,oBACV,oBACA,EAAE,UAAU,mBACV,mBACA,EAAE,UAAU,YACV,YACA,EAAE,UAAU,WACV,WACA,EAAE,UAAU,aACV,aACA,EAAE,UAAU,cACV,cACA,EAAE,UAAU,YACV,YACA;AACpB,SAAO,EAAE,aACL,EAAC,QAAQ,cAAc,CAAC,EAAC,MAAM,EAAE,YAAY,MAAM,cAAa,CAAC,EAAC,IAClE,EAAC,OAAM;AACb;AAMO,IAAe,oBAAf,cAAyC,cAAc;AAAA,EACzC;AAAA,EAEnB,YAAY,SAAmC,QAA2B;AACxE,UAAM,YAAY,QAAQ,OAAO,WAAW,EAAE;AAC9C,QAAI,CAAC,UAAW,OAAM,IAAI,qBAAqB,8BAA8B;AAC7E,UAAM,iBAAiB,OAAO,OAAO,EAAC,GAAG,QAAQ,UAAS,CAAC;AAC3D,UAAM,SAAkB,cAAc;AACtC,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAQU,gBAAwB;AAChC,WAAO;AAAA,EACT;AAAA;AAAA,EAOU,UAAU,OAA4B,QAA0C;AACxF,UAAM,WAAY,KAAK,QAA8B;AACrD,QAAI,CAAC,SAAU;AACf,QAAI;AACF,eAAS,OAAO,MAAM;AAAA,IACxB,QAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA,EAEU,kBAA2B;AAAE,WAAO;AAAA,EAAM;AAAA;AAAA,EAE1C,cAAc,WAAmB,SAA0B;AACnE,WAAO,KAAK,eAAe,SAAS,KAAK,KAAK,eAAe,OAAO;AAAA,EACtE;AAAA;AAAA,EAGU,SAAS,SAAuB,KAA2B;AACnE,QAAI,QAAQ,mBAAmB,MAAM;AACnC,YAAM,IAAI,+BAA+B,uDAAuD;AAAA,IAClG;AACA,UAAM,YAAY,QAAQ,QAAQ,SAAS,KAAK,SAAS;AACzD,UAAM,cAAc,kBAAkB,OAAO;AAC7C,UAAM,WAAW,oBAAoB,QAAQ,iBAAiB,iBAAiB;AAC/E,UAAM,SAAsB;AAAA,MAC1B,aAAa,KAAK;AAAA,MAClB,aAAa,SAAS,KAAK,WAAW,QAAQ,SAAS;AAAA,MACvD;AAAA,MACA,WAAW,cAAc,WAAW,QAAQ,OAAO;AAAA,MACnD,UAAU,SAAS,SAAS;AAAA,MAC5B,aAAa,QAAQ,aAAa;AAAA,MAClC;AAAA,MACA,GAAI,YAAY,iBAAiB,SAAY,EAAC,cAAc,YAAY,aAAa,SAAS,EAAC,IAAI,CAAC;AAAA,MACpG,GAAI,YAAY,gBAAgB,SAAY,EAAC,aAAa,YAAY,YAAW,IAAI,CAAC;AAAA,IACxF;AACA,WAAO,QAAQ,gBAAgB,EAAC,GAAG,QAAQ,eAAe,QAAQ,cAAa,IAAI;AAAA,EACrF;AAAA,EAEA,MAAc,mBAAmB,QAAoC;AACnE,UAAM,SAAS,KAAK;AACpB,QAAI,OAAO,sBAAuB;AAClC,UAAM,SAAS,MAAM,iBAAiB,QAAQ,OAAO,YAAY;AACjE,QAAI,UAAU,MAAM;AAClB,YAAM,IAAI,MAAM,oDAAoD,KAAK,SAAS,qEAAqE;AAAA,IACzJ;AACA,UAAM,WAAW,KAAK;AACtB,UAAM,aAAa,SAAS,WAAW,SAAS,IAAI,SAAS,MAAM,UAAU,MAAM,IAAI;AACvF,UAAM,aAAa,aAAa,OAAO,WAAW,WAAW,SAAS,OAAO,MAAM,CAAC;AACpF,UAAM,WAAW,WAAW,WAAW,SAAS,IAAI,WAAW,MAAM,UAAU,MAAM,IAAI;AACzF,QAAI,aAAa,YAAY;AAC3B,YAAM,IAAI,MAAM,8BAA8B,UAAU,sBAAsB,QAAQ,EAAE;AAAA,IAC1F;AAAA,EACF;AAAA,EAEU,gBAAgB,QAAoC;AAC5D,UAAM,aAAa,EAAC,GAAI,KAAK,SAAiC,GAAI,UAAU,CAAC,EAAE;AAC/E,eAAW,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,oBAAoB,WAAW,gBAAgB,GAAG,CAAC,qBAAqB,WAAW,iBAAiB,CAAC,GAAY;AAC7I,UAAI,UAAU,OAAW;AACzB,YAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,OAAO,cAAc,KAAK,IAAI,OAAO,KAAK,IAAI,CAAC;AAC/F,UAAI,MAAM,MAAM,MAAM,OAAS,OAAM,IAAI,wBAAwB,UAAU,IAAI,yCAAyC;AAAA,IAC1H;AAAA,EACF;AAAA,EAEU,cACR,MACA,cACA,aACA,QACM;AACN,SAAK,gBAAgB,MAAM;AAC3B,UAAM,aAAa,EAAC,GAAI,KAAK,SAAiC,GAAI,UAAU,CAAC,EAAE;AAC/E,UAAM,OAAO;AAAA,MACX,CAAC,WAAW,WAAW,gBAAgB;AAAA,MACvC,CAAC,YAAY,WAAW,iBAAiB;AAAA,IAC3C;AACA,QAAI,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,GAAG,MAAM,QAAQ,MAAS,EAAG;AAChD,QAAI,CAAC,KAAM,OAAM,IAAI,mBAAmB,4DAA4D;AACpG,UAAM,mBAAmB,YAAY,YAAY;AACjD,eAAW,CAAC,MAAM,GAAG,KAAK,MAAM;AAC9B,UAAI,QAAQ,OAAW;AACvB,YAAM,WAAW,KAAK,OAAO,CAAC,QAAQ,IAAI,SAAS,IAAI;AACvD,UAAI,SAAS,KAAK,CAAC,QAAQ,IAAI,MAAM,YAAY,MAAM,gBAAgB,GAAG;AACxE,cAAM,IAAI,mBAAmB,uBAAuB,IAAI,sCAAsC;AAAA,MAChG;AACA,YAAM,QAAQ,SAAS,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,QAAQ,EAAE;AAChE,YAAM,MAAM,OAAO,QAAQ,WAAW,MAAM,OAAO,GAAG;AACtD,UAAI,QAAQ,SAAU,eAAe,KAAK;AACxC,cAAM,IAAI,mBAAmB,UAAU,IAAI,6BAA6B;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAAA,EAEU,mBAAmB,GAAU,SAAuB,QAAoC;AAChG,UAAM,SAAS,QAAQ,KAAK,WAAW,SAAS,KAAK,WAAW,QAAQ,SAAS,CAAC;AAClF,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,gCAAgC,QAAQ,SAAS,QAAQ,KAAK,SAAS,EAAE;AACtG,UAAM,QAAQ,OAAO,YAAY,OAAO;AACxC,UAAM,OAAO,EAAE,MAAM,IAAI,CAAC,SAAS,EAAC,GAAG,KAAK,QAAQ,OAAO,IAAI,MAAM,EAAC,EAAc;AACpF,SAAK,cAAc,MAAM,OAAO,EAAE,YAAY,GAAG,OAAO,MAAM;AAAA,EAChE;AAAA,EAEU,QAAQ,GAAU,SAAmC;AAI7D,UAAM,QAAoB,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS;AAAA,MACpD,MAAM,IAAI;AAAA,MACV,QAAQ,OAAO,IAAI,MAAM;AAAA,MACzB,OAAO,IAAI;AAAA,MACX,UAAU,IAAI;AAAA,MACd,GAAI,IAAI,cAAc,EAAC,aAAa,IAAI,YAAW,IAAI,CAAC;AAAA,IAC1D,EAAE;AACF,WAAO;AAAA,MACL,iBAAiB,OAAO,EAAE,YAAY;AAAA,MACtC,eAAe,OAAO,EAAE,UAAU;AAAA,MAClC,kBAAkB,OAAO,EAAE,aAAa;AAAA,MACxC;AAAA,MACA,GAAI,EAAE,aAAa,EAAC,mBAAmB,EAAE,WAAU,IAAI,CAAC;AAAA,MACxD,GAAI,EAAE,eAAe,EAAC,QAAQ,KAAK,MAAM,EAAE,eAAe,GAAI,EAAC,IAAI,CAAC;AAAA,IACtE;AAAA,EACF;AAAA;AAAA,EAGU,WAAW,SAAqC;AACxD,WAAO,gBAAgB,OAAO;AAAA,EAChC;AAAA;AAAA,EAGU,WAAW,GAAU,SAA0C;AACvE,QAAI;AACF,6BAAuB,GAAG,OAAO;AACjC,WAAK,mBAAmB,GAAG,OAAO;AAClC,aAAO,KAAK,QAAQ,GAAG,OAAO;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAe,WAAW,SAA4C;AACpE,UAAM,WAAW,gBAAgB,OAAO;AACxC,UAAM,IAAI,MAAM,KAAK,aAAa,KAAK,SAAS,UAAU,IAAI,CAAC;AAC/D,QAAI,CAAC,GAAG;AACN,YAAM,SAAS,KAAK,cAAc;AAClC,YAAM,IAAI,gBAAgB,mDAAmD,SAAS,OAAO,MAAM,KAAK,EAAE,EAAE;AAAA,IAC9G;AACA,2BAAuB,GAAG,QAAQ;AAClC,SAAK,mBAAmB,GAAG,QAAQ;AACnC,WAAO,KAAK,QAAQ,GAAG,QAAQ;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAe,MAAM,SAAuB,QAAoD;AAG9F,UAAM,kBAAkB,KAAK;AAC7B,QAAI,CAAC,mBAAmB,OAAO,gBAAgB,oBAAoB,YAAY;AAC7E,YAAM,IAAI,oBAAoB,+EAA+E;AAAA,IAC/G;AACA,UAAM,WAAW,gBAAgB,OAAO;AACxC,0BAAsB,QAAQ;AAG9B,UAAM,MAAM,YAAY,KAAK,WAAW,QAAQ;AAChD,UAAM,UAAU,UAAU,IAAI,eAAe,KAAK,oBAAI,IAAY;AAClE,QAAI,QAAQ,IAAI,GAAG,EAAG,OAAM,IAAI,mBAAmB,4FAAuF;AAC1I,YAAQ,IAAI,GAAG;AACf,cAAU,IAAI,iBAAiB,OAAO;AACtC,QAAI;AACF,aAAO,MAAM,KAAK,aAAa,iBAAgC,UAAU,MAAM;AAAA,IACjF,UAAE;AACA,cAAQ,OAAO,GAAG;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,aAAa,QAAqB,UAAwB,QAA8B,SAAkD;AACtJ,UAAM,iBAAiB,eAAe,MAAM;AAC5C,SAAK,gBAAgB,cAAc;AACnC,UAAM,KAAK,mBAAmB,MAAM;AAKpC,UAAM,cAAc,MAAM,OAAO,WAAW;AAC5C,UAAM,YAAY,SAAS,aAAa;AACxC,UAAM,gBAAgB,SAAS,iBAAiB;AAChD,UAAM,mBAAmB,gBAAgB,EAAC,GAAG,UAAU,WAAW,cAAa,CAAC;AAChF,UAAM,SAAS,KAAK,SAAS,kBAAkB,KAAK;AACpD,UAAM,WAAW,MAAM,KAAK,aAAa,MAAM;AAC/C,QAAI,CAAC,UAAU;AACb,YAAM,SAAS,KAAK,cAAc;AAClC,YAAM,IAAI,gBAAgB,mDAAmD,SAAS,OAAO,MAAM,KAAK,EAAE,EAAE;AAAA,IAC9G;AACA,UAAM,IAAI,cAAc,QAAQ;AAChC,2BAAuB,GAAG,gBAAgB;AAC1C,SAAK,mBAAmB,GAAG,kBAAkB,cAAc;AAE3D,UAAM,WAAW,KAAK,YAAY,EAAE,QAAQ;AAC5C,QAAI,CAAC,SAAU,OAAM,IAAI,MAAM,oBAAoB,EAAE,QAAQ,qBAAqB;AAClF,QAAI,kBAAkB;AACtB,QAAI;AAAE,wBAAkB,SAAS,QAAQ;AAAA,IAAG,QAAQ;AAAA,IAA0B;AAC9E,QAAI,CAAC,gBAAiB,OAAM,IAAI,MAAM,oBAAoB,EAAE,QAAQ,eAAe;AACnF,QAAI,WAAuB,OAAO,OAAO,EAAC,GAAG,MAAM,SAAS,aAAa,CAAC,EAAC,CAAC;AAE5E,UAAM,aAAa,SAAS,iBAAiB;AAC7C,QAAI,YAAY;AACd,UAAI,CAAC,SAAS,aAAc,OAAM,IAAI,MAAM,0DAA0D;AACtG,UAAI,SAAS,SAAS,UAAa,SAAS,YAAY,UAAa,SAAS,cAAc,UAAa,SAAS,SAAS,UAAa,SAAS,oBAAoB,QAAW;AAC9K,cAAM,IAAI,MAAM,uDAAuD;AAAA,MACzE;AACA,UAAI,OAAO,OAAO,8BAA8B,YAAY;AAC1D,cAAM,IAAI,oBAAoB,UAAU,KAAK,SAAS,kEAAkE;AAAA,MAC1H;AAAA,IACF;AACA,QAAI,SAAS,SAAS,SAAS,UAAU,KAAK,WAAW;AACvD,YAAM,IAAI,MAAM,qCAAqC,SAAS,KAAK,mBAAmB,KAAK,SAAS,EAAE;AAAA,IACxG;AACA,QAAI,SAAS,iBAAiB,QAAW;AACvC,YAAM,IAAI,MAAM,uEAAuE;AAAA,IACzF;AAIA,QAAI,EAAE,WAAW;AACf,YAAM,KAAK,EAAE;AACb,YAAM,cAAc,CAAC,GAAuB,MAC1C,MAAM,KAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,KAAK,EAAE,YAAY,MAAM,EAAE,YAAY;AAC1G,UACE,CAAC,YAAY,SAAS,IAAI,GAAG,MAAM,EAAE,KACrC,SAAS,SAAS,GAAG,QACrB,SAAS,WAAW,GAAG,SAAS,QAChC,SAAS,YAAY,GAAG,WACxB,SAAS,aAAa,GAAG,YACzB,CAAC,YAAY,SAAS,iBAAiB,GAAG,eAAe,KACzD,SAAS,iBAAiB,GAAG,cAC7B;AACA,cAAM,IAAI,MAAM,sEAAsE;AAAA,MACxF;AAAA,IACF,WAAW,CAAC,SAAS,WAAW,CAAC,SAAS,WAAW;AACnD,UAAI,CAAC,EAAE,kBAAkB,SAAS,OAAO,EAAE,mBAAmB,SAAS,QAAQ,UAAU,EAAE,aAAa;AACtG,cAAM,IAAI,MAAM,kEAAkE;AAAA,MACpF;AAAA,IACF;AACA,UAAM,kBAAkB,CAAC,SAAS,SAAS,QAAW,SAAS,YAAY,QAAW,SAAS,cAAc,MAAS,EACnH,OAAO,OAAO,EAAE;AACnB,QAAI,kBAAkB,KAAM,SAAS,SAAS,WAAc,SAAS,YAAY,UAAa,SAAS,cAAc,SAAa;AAChI,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AACA,QAAI,SAAS,mBAAmB,CAAC,SAAS,QAAQ,CAAC,SAAS,WAAW;AACrE,YAAM,IAAI,MAAM,qEAAqE;AAAA,IACvF;AAIA,UAAM,aAAa,KAAK,UAAU,WAAW,OAAO;AAGpD,UAAM,aAAa,KAAK,UAAU,WAAW,OAAO;AACpD,QAAI,SAAS,QAAQ,CAAC,KAAK,UAAU,WAAW,MAAM,KAAK,CAAC,cAAc,CAAC,YAAY;AACrF,YAAM,IAAI,MAAM,wDAAwD,KAAK,SAAS,EAAE;AAAA,IAC1F;AACA,QAAI,SAAS,SAAS,UAAa,CAAC,KAAK,UAAU,WAAW,SAAS,GAAG;AACxE,YAAM,IAAI,MAAM,oDAAoD,KAAK,SAAS,EAAE;AAAA,IACtF;AAIA,QAAI;AACJ,QAAI,SAAS,YAAY,QAAW;AAClC,UAAI,CAAC,SAAS,QAAS,OAAM,IAAI,MAAM,4CAA4C;AACnF,UAAI,CAAC,KAAK,UAAU,WAAW,MAAM,GAAG;AACtC,cAAM,IAAI,MAAM,qDAAqD,KAAK,SAAS,EAAE;AAAA,MACvF;AACA,YAAM,SAAU,KAAK,QAA8B;AACnD,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,4EAA4E;AAAA,MAC9F;AACA,iBAAW,OAAO,SAAS,OAAO;AAClC,UAAI,YAAY,MAAM;AACpB,cAAM,IAAI,MAAM,8CAA8C;AAAA,MAChE;AAAA,IACF;AACA,QAAI,SAAS,YAAY,UAAa,KAAK,UAAU,WAAW,SAAS,KAAK,OAAO,SAAS,OAAO,MAAM,KAAK,UAAU,MAAM,UAAU,MAAM,GAAG;AACjJ,YAAM,IAAI,MAAM,qCAAqC,SAAS,OAAO,mBAAmB,KAAK,SAAS,EAAE;AAAA,IAC1G;AAQA,QAAI;AACJ,QAAI,CAAC,SAAS,QAAQ,CAAC,SAAS,WAAW,CAAC,SAAS,aAAa,CAAC,YAAY;AAC7E,YAAM,MAAM,QAAQ,KAAK,WAAW,SAAS,KAAK,WAAW,iBAAiB,SAAS,CAAC;AACxF,UAAI,KAAK,UAAU;AACjB,YAAI,KAAK,UAAU,WAAW,SAAS,GAAG;AACxC,qBAAW;AAAA,YACT,GAAG;AAAA,YACH,IAAI,IAAI;AAAA,YACR,MAAM,mBAAmB;AAAA,cACvB,KAAK;AAAA,cACL,cAAc;AAAA,cACd,MAAM,CAAC,SAAS,IAAqB,OAAO,EAAE,YAAY,CAAC;AAAA,YAC7D,CAAC;AAAA,YACD,OAAO;AAAA,UACT;AAAA,QACF,WACE,KAAK,UAAU,WAAW,SAAS,KACnC,KAAK,UAAU,WAAW,MAAM,KAChC,KAAK,UAAU,WAAW,OAAO,KACjC,YACA;AAKA,oBAAU,IAAI;AAAA,QAChB,OAAO;AACL,gBAAM,IAAI;AAAA,YACR,iEAAiE,KAAK,SAAS;AAAA,UACjF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAKA,UAAM,YAAY,KAAK,UAAU,WAAW,MAAM;AAClD,QAAI,YAAY,aAAa,UAAc,SAAS,SAAS,UAAa,CAAC,cAAc,CAAC,cAAc,CAAC,YAAa;AACpH,YAAM,IAAI,MAAM,gEAAgE;AAAA,IAClF;AAKA,UAAM,SAAS,QAAQ,KAAK,WAAW,SAAS,KAAK,WAAW,iBAAiB,SAAS,CAAC;AAC3F,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,gCAAgC,iBAAiB,SAAS,QAAQ,KAAK,SAAS,EAAE;AAC/G,UAAM,iBAAiB,OAAO,SAAS,KAAK;AAC5C,QAAI,YAAY;AAId,UAAI,oBAAoB,OAAO,WAAW,KAAK,OAAO,EAAE,YAAY,IAAI;AACtE,cAAM,IAAI,MAAM,qEAAqE;AAAA,MACvF;AAAA,IACF,WAAW,OAAO,YAAY,KAAK,UAAU,WAAW,SAAS,GAAG;AAElE,YAAM,WAAW,kBAAkB,GAAG,KAAK,SAAS;AACpD,UAAI,mBAAmB,UAAU;AAC/B,cAAM,IAAI,MAAM,aAAa,KACzB,4DACA,gCAAgC,cAAc,yCAAyC,QAAQ,EAAE;AAAA,MACvG;AAAA,IACF,WAAW,CAAC,SAAS,aAAa,CAAC,SAAS,WAAW,mBAAmB,OAAO,EAAE,YAAY,IAAI,kBAAkB,GAAG,KAAK,SAAS,GAAG;AACvI,YAAM,IAAI,MAAM,qEAAqE;AAAA,IACvF;AAQA,QAAI,SAAS,SAAS,UAAa,KAAK,UAAU,WAAW,SAAS,GAAG;AACvE,YAAM,OAAO,WAAW,EAAC,IAAI,SAAS,IAAI,MAAM,SAAS,MAAM,OAAO,eAAc,CAAC;AACrF,YAAM,QAAQ,KAAK,UAAU,MAAM,KAAK,UAAU;AAClD,YAAM,UAAU,CAAC,aAAa,EAAE,gBAAgB,SAAS,iBAAiB,SAAS,EAAE,EAAE,OAAO,CAAC,MAAmB,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AACjJ,UAAI,SAAS,CAAC,QAAQ,SAAS,MAAM,YAAY,CAAC,GAAG;AACnD,cAAM,IAAI,qBAAqB,0BAA0B,KAAK,MAAM,WAAW,WAAW,KAAK,CAAC,yFAAoF;AAAA,MACtL;AAAA,IACF;AAMA,UAAM,gBAAgB,CAAC,CAAC,SAAS,mBAAmB,CAAC,CAAC,OAAO;AAC7D,UAAM,iBAAiB,gBAAgB,OAAO,iBAAiB,eAAgB,IAAI;AACnF,UAAM,UAAU,CAAC,GAAW,MAAc,EAAE,YAAY,MAAM,EAAE,YAAY;AAC5E,QAAI,kBAA4B,CAAC;AACjC,QAAI;AACJ,QAAI,WAAW,CAAC,eAAe;AAG7B,cAAQ,UAAU;AAClB,YAAM,QAAQ,OAAO,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACrC,YAAM,IAAI,gBAAgB,wGAAmG;AAAA,IAC/H;AACA,QAAI,iBAAiB,SAAS;AAG5B,UAAI,CAAC,QAAQ,QAAQ,OAAO,OAAO,QAAS,KAAK,CAAC,QAAQ,QAAQ,SAAS,SAAS,eAAgB,KAAK,QAAQ,WAAW,gBAAgB;AAC1I,gBAAQ,UAAU;AAClB,cAAM,QAAQ,OAAO,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AACrC,cAAM,IAAI,gBAAgB,+CAA+C,SAAS,eAAe,sCAAiC,QAAQ,OAAO,cAAc;AAAA,MACjK;AACA,cAAQ,UAAU;AAClB,uBAAiB,QAAQ;AAAA,IAC3B,WAAW,eAAe;AAMxB,YAAM,cAAc,KAAK,cAAc,cAAc,OAAO,OAAO,YAAY,MAAM;AACrF,UAAI;AACJ,UAAI,OAAO,OAAO,iBAAiB,YAAY;AAC7C,YAAI;AACF,oBAAU,OAAO,MAAM,OAAO,aAAa,OAAO,UAAW,SAAS,eAAgB,CAAC;AAAA,QACzF,QAAQ;AACN,oBAAU;AAAA,QACZ;AAAA,MACF;AACA,wBAAkB,YAAY,iBAAiB,CAAC,IAAI,CAAC,GAAI,eAAe,YAAY,KAAK,CAAC,EAAE,IAAI,CAAC,GAAI,cAAc;AAAA,IACrH;AAKA,UAAM,SAAU,KAAK,QAA8B;AACnD,QAAI,UAAU,CAAC,SAAS;AACtB,YAAM,UAAU,SAAS,YAAY,SAAY,EAAC,SAAS,SAAS,QAAO,IAAI,CAAC;AAChF,YAAM,YAA6C,gBAAgB,IAAI,CAAC,YACrE,EAAC,OAAO,OAAO,UAAW,SAAS,SAAS,iBAAkB,QAAQ,GAAG,QAAO,EAAE;AACrF,YAAM,OAA2B;AAAA,QAC/B,UAAU,EAAE;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,WAAW,OAAO;AAAA,QAClB,WAAW,OAAO;AAAA,QAClB;AAAA,QACA;AAAA,QACA,cAAc,OAAO,EAAE,YAAY;AAAA,QACnC,YAAY,OAAO,EAAE,UAAU;AAAA,QAC/B,eAAe,OAAO,EAAE,aAAa;AAAA,QACrC,QAAQ,EAAE;AAAA,QACV,YAAY,EAAE;AAAA,QACd,cAAc,EAAE;AAAA,QAChB;AAAA,QACA,QAAQ,aACJ,EAAC,MAAM,cAAc,cAAc,SAAS,aAAa,IACzD,SAAS,YACP,EAAC,MAAM,eAAe,WAAW,SAAS,UAAS,IACnD,UACE,EAAC,MAAM,kBAAkB,OAAO,SAAS,WAAW,SAAS,IAAI,QAAQ,OAAO,EAAE,YAAY,GAAG,GAAI,SAAS,OAAO,EAAC,MAAM,SAAS,MAAM,GAAI,SAAS,eAAe,EAAC,cAAc,SAAS,aAAY,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IACzN;AAAA,UACE,MAAM;AAAA,UACN,IAAI,SAAS;AAAA,UACb,GAAI,SAAS,OAAO,EAAC,MAAM,SAAS,KAAI,IAAI,CAAC;AAAA,UAC7C,OAAO,OAAO,SAAS,KAAK;AAAA,UAC5B,GAAI,SAAS,YAAY,SAAY,EAAC,SAAS,SAAS,QAAO,IAAI,CAAC;AAAA,UACpE,GAAI,SAAS,WAAW,EAAC,UAAU,OAAO,SAAS,QAAQ,EAAC,IAAI,CAAC;AAAA,UACjE,GAAI,SAAS,OAAO,EAAC,MAAM,SAAS,MAAM,GAAI,SAAS,eAAe,EAAC,cAAc,SAAS,aAAY,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,UACtH,GAAI,aAAa,SAAY,EAAC,UAAU,KAAI,IAAI,CAAC;AAAA,QACnD;AAAA,MACV;AAEA,YAAM,OAAO,WAAW,oBAAoB,IAAI,CAAC,CAAC;AAClD,UAAI,EAAE,eAAe,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG;AACtD,cAAM,IAAI,gBAAgB,8DAAyD;AAAA,MACrF;AAAA,IACF;AAEA,UAAM,KAAK,gBAAgB,QAAQ,UAAU,iBAAiB,OAAO,YAAY,QAAW,CAAC,CAAC,SAAS,aAAa,cAAc,CAAC,CAAC,OAAO;AAE3I,QAAI,gBAAgB,QAAQ;AAC1B,YAAM,UAAU,OAAO,WAAmB;AACxC,cAAMA,QAAO,MAAM,OAAO,gBAAgB;AAAA,UACxC,IAAI,OAAO;AAAA,UACX,MAAM,YAAY,SAAS,iBAAkB,MAAM;AAAA,UACnD,OAAO;AAAA,UACP,GAAI,SAAS,YAAY,SAAY,EAAC,SAAS,SAAS,QAAO,IAAI,CAAC;AAAA,QACtE,CAAC;AAGD,YAAIA,MAAK,QAAQ,OAAO,OAAO,uBAAuB,WAAY,OAAM,OAAO,mBAAmBA,MAAK,IAAI;AAC3G,eAAOA;AAAA,MACT;AAIA,uBAAiB,YAAY;AAAE,cAAM,QAAQ,EAAE;AAAA,MAAG;AAClD,UAAI;AACF,mBAAW,CAAC,GAAG,MAAM,KAAK,gBAAgB,QAAQ,GAAG;AACnD,eAAK,UAAU,aAAa,EAAC,OAAO,IAAI,GAAG,OAAO,gBAAgB,OAAM,CAAC;AACzE,gBAAM,QAAQ,MAAM;AAAA,QACtB;AAAA,MACF,SAAS,OAAO;AACd,cAAM,eAAe,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AACrC,cAAM;AAAA,MACR;AAAA,IACF;AAIA,QAAI,EAAE,eAAe,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG;AAOtD,UAAI,CAAC,WAAW,gBAAgB,UAAU,gBAAgB;AACxD,aAAK,UAAU,WAAW;AAC1B,cAAM,UAA4B,EAAC,OAAO,OAAO,UAAW,SAAS,SAAS,iBAAkB,QAAQ,gBAAgB,QAAQ,gBAAgB,SAAS,MAAK;AAC9J,YAAI;AACF,iBAAO,MAAM,KAAK,aAAa,QAAQ,UAAU,QAAQ,OAAO;AAAA,QAClE,SAAS,OAAO;AACd,cAAI,CAAC,QAAQ,QAAS,OAAM,eAAe,EAAE,MAAM,MAAM;AAAA,UAAC,CAAC;AAC3D,gBAAM;AAAA,QACR;AAAA,MACF;AACA,YAAM,iBAAiB,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACvC,YAAM,IAAI,gBAAgB,8CAA8C;AAAA,IAC1E;AACA,QAAI;AACF,UAAI,uBAAuB;AAC3B,UAAI;AAAE,+BAAuB,SAAS,QAAQ;AAAA,MAAG,QAAQ;AAAA,MAA0B;AACnF,UAAI,CAAC,qBAAsB,OAAM,IAAI,MAAM,oBAAoB,EAAE,QAAQ,wCAAwC;AACjH,UAAI,SAAS,iBAAkB,MAAK,UAAU,WAAW;AACzD,YAAM,SAAS,mBAAmB,GAAG,QAAQ;AAAA,IAC/C,SAAS,OAAO;AACd,YAAM,iBAAiB,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACvC,YAAM;AAAA,IACR;AAIA,QAAI,SAAS,WAAW;AACtB,UAAI;AACF,YAAI,CAAC,OAAO,eAAe;AACzB,gBAAM,IAAI,MAAM,kEAAkE;AAAA,QACpF;AACA,YAAI,CAAC,SAAS,qBAAqB;AACjC,gBAAM,IAAI,MAAM,oBAAoB,EAAE,QAAQ,iCAAiC;AAAA,QACjF;AACA,cAAM,KAAK,KAAK,MAAM,SAAS,SAAS;AAMxC,YAAI,CAAC,MAAM,OAAO,OAAO,YAAY,CAAC,GAAG,UAAU,CAAC,GAAG,SAAS,OAAO,GAAG,UAAU,YAAY,CAAC,GAAG,SAAS;AAC3G,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACjE;AAGA,cAAM,EAAC,cAAc,SAAS,GAAG,MAAK,IAAI,GAAG;AAK7C,cAAM,YAAY,MAAM,OAAO,cAAc;AAAA,UAC3C,QAAQ,qBAAqB,GAAG,MAAM;AAAA,UACtC;AAAA,UACA,GAAI,GAAG,cAAc,EAAC,aAAa,GAAG,YAAW,IAAI,CAAC;AAAA,UACtD,SAAS,GAAG;AAAA,QACd,CAAC;AACD,cAAM,SAAS,oBAAoB,EAAE,UAAU,SAAS;AACxD,eAAO;AAAA,UACL,IAAI,SAAS,EAAE,UAAU,EAAE,QAAQ;AAAA,UACnC,MAAM,KAAK,QAAQ,GAAG,gBAAgB,EAAE;AAAA,UACxC,iBAAiB,OAAO,EAAE,YAAY;AAAA,UACtC,eAAe,OAAO,EAAE,UAAU;AAAA,UAClC,kBAAkB,OAAO,EAAE,aAAa;AAAA,QAC1C;AAAA,MACF,SAAS,OAAO;AAId,cAAM,iBAAiB,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AACvC,cAAM;AAAA,MACR;AAAA,IACF;AAKA,QAAI;AACJ,SAAK,UAAU,SAAS;AACxB,QAAI;AACF,UAAI,YAAY;AACd,cAAM,eAAgB,KAAK,QAA8B;AACzD,cAAM,YAAY,iBAAiB,SAAY,sCAAsC,OAAO,YAAY;AACxG,YAAI,YAAY,GAAI,OAAM,IAAI,wBAAwB,uDAAuD;AAC7G,cAAM,SAAyC;AAAA,UAC7C,eAAe,OAAO,WAAW,KAAK,OAAO,EAAE,YAAY,KAAK,WAAW,SAAS;AAAA;AAAA,UAEpF,GAAI,OAAO,cAAc,KAAK,YAAY,EAAC,SAAS,EAAC,OAAO,OAAO,WAAW,WAAW,EAAE,cAAa,EAAC,IAAI,CAAC;AAAA,UAC9G,GAAI,OAAO,WAAW,EAAC,QAAQ,EAAC,OAAO,OAAO,UAAU,WAAW,EAAE,aAAY,EAAC,IAAI,CAAC;AAAA,QACzF;AACA,eAAO,MAAM,OAAO,0BAA2B,SAAS,cAAe,MAAM;AAAA,MAC/E,WAAW,SAAS;AAClB,YAAI,OAAO,OAAO,aAAa,YAAY;AACzC,gBAAM,IAAI;AAAA,YACR,UAAU,KAAK,SAAS;AAAA,UAC1B;AAAA,QACF;AACA,eAAO,MAAM,OAAO,SAAS;AAAA,UAC3B,OAAO;AAAA,UACP,WAAW,SAAS;AAAA,UACpB,QAAQ,OAAO,EAAE,YAAY;AAAA,UAC7B,IAAK,cAAc,cAAc,cAAc,SAAS,OAAO,EAAC,MAAM,SAAS,MAAM,GAAI,cAAc,SAAS,eAAe,EAAC,cAAc,SAAS,aAAY,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,QACjL,CAAC;AAAA,MACH,OAAO;AACL,eAAO,MAAM,OAAO,gBAAgB;AAAA,UAClC,IAAI,SAAS;AAAA,UACb,GAAI,SAAS,OAAO,EAAC,MAAM,SAAS,KAAI,IAAI,CAAC;AAAA,UAC7C,OAAO,OAAO,SAAS,KAAK;AAAA,UAC5B,GAAI,SAAS,YAAY,SAAY,EAAC,SAAS,SAAS,QAAO,IAAI,CAAC;AAAA,UACpE,GAAI,SAAS,WAAW,EAAC,UAAU,OAAO,SAAS,QAAQ,EAAC,IAAI,CAAC;AAAA,UACjE,GAAI,aAAa,SACb,EAAC,MAAM,SAAQ,IACf,SAAS,OACN,aAAa,EAAC,MAAM,SAAS,MAAM,GAAI,SAAS,eAAe,EAAC,cAAc,SAAS,aAAY,IAAI,CAAC,EAAE,IAAI,aAAa,EAAC,MAAM,SAAS,KAAI,IAAI,EAAC,MAAM,SAAS,KAAI,IACxK,CAAC;AAAA,QACT,CAAC;AAAA,MACH;AACA,UAAI,CAAC,KAAK,KAAM,OAAM,IAAI,oBAAoB,yDAAyD;AACvG,WAAK,UAAU,aAAa,EAAC,MAAM,KAAK,KAAI,CAAC;AAAA,IAC/C,SAAS,OAAO;AAGd,YAAM,UAAU,UAAU,KAAK;AAC/B,UAAI,SAAS;AACX,cAAM,IAAI;AAAA,UACR,0DAA0D,iBAAiB,QAAQ,MAAM,QAAQ,MAAM,GAAG,GAAG,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,0BAAqB,QAAQ,OAAO,sBAAsB,QAAQ,IAAI,KAAK,yCAAyC;AAAA,UAChQ,QAAQ;AAAA,UACR,QAAQ,OAAO,SAAS,EAAE,UAAU,EAAE,UAAU,QAAQ,IAAI,IAAI;AAAA,UAChE,EAAC,OAAO,MAAK;AAAA,QACf;AAAA,MACF;AACA,YAAM,iBAAiB,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACvC,YAAM;AAAA,IACR;AAEA,QAAI,SAAS,eAAe;AAC1B,YAAM,SAAS,cAAc,EAAE,UAAU,KAAK,IAAI,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACpE;AAEA,UAAM,OAAO,KAAK,QAAQ,GAAG,gBAAgB,EAAE;AAC/C,WAAO;AAAA,MACL,IAAI,SAAS,EAAE,UAAU,EAAE,UAAU,KAAK,IAAI;AAAA,MAC9C;AAAA,MACA,iBAAiB,OAAO,EAAE,YAAY;AAAA,MACtC,eAAe,OAAO,EAAE,UAAU;AAAA,MAClC,kBAAkB,OAAO,EAAE,aAAa;AAAA,MACxC,GAAI,KAAK,OAAO,EAAC,MAAM,KAAK,MAAM,cAAc,CAAC,EAAC,MAAM,KAAK,MAAM,MAAM,SAAQ,CAAC,EAAC,IAAI,CAAC;AAAA,IAC1F;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,gBAAgB,QAAqB,UAAsB,iBAA2B,OAA2B,YAAoC;AACjK,QAAI,CAAC,KAAK,UAAU,WAAW,SAAS,KAAK,OAAO,OAAO,eAAe,cAAc,OAAO,OAAO,yBAAyB,WAAY;AAC3I,UAAM,UAAU,SAAS,YAAY,SAAY,EAAC,SAAS,SAAS,QAAO,IAAI,CAAC;AAChF,UAAM,OAAO,MAAM,QAAQ,IAAI,gBAAgB,IAAI,OAAO,YACvD,MAAM,OAAO,qBAAsB,EAAC,IAAI,OAAQ,MAAM,YAAY,SAAS,iBAAkB,MAAM,GAAG,OAAO,IAAI,GAAG,QAAO,CAAC,GAAG,GAAG,CAAC;AACtI,UAAM,QAAQ,aAAa,KAAK,OAAO,SAAS,KAAK;AACrD,QAAI,CAAC,YAAY;AACf,YAAM,OAAO,EAAC,IAAI,SAAS,IAAI,GAAI,SAAS,OAAO,EAAC,MAAM,SAAS,KAAI,IAAI,CAAC,GAAI,OAAO,GAAG,SAAS,GAAI,SAAS,WAAW,EAAC,UAAU,OAAO,SAAS,QAAQ,EAAC,IAAI,CAAC,EAAE;AACtK,WAAK,KAAK,MAAM,OAAO,qBAAqB,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU;AAC9E,YAAI,gBAAgB,OAAQ,QAAO;AACnC,cAAM;AAAA,MACR,CAAC,CAAC;AAAA,IACJ;AACA,UAAM,OAAO,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,IAAI;AAChD,UAAM,UAAU,OAAO,MAAM,OAAO,WAAW,CAAC;AAChD,QAAI,UAAU,MAAM;AAClB,YAAM,IAAI,0BAA0B,yBAAyB,OAAO,qCAAqC,IAAI,KAAK,KAAK,MAAM,eAAe,KAAK,WAAW,IAAI,KAAK,GAAG,GAAG,QAAQ,YAAY,KAAK,KAAK,EAAE,6BAAwB;AAAA,IACrO;AAAA,EACF;AAAA;AAAA,EAGA,MAAe,eAAe,IAAY,UAA2D;AACnG,UAAM,EAAC,UAAU,MAAM,UAAU,aAAY,IAAI,SAAS,EAAE;AAC5D,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,QAAI,CAAC,SAAU,OAAM,IAAI,MAAM,iCAAiC,EAAE,GAAG;AACrE,WAAO,UAAU,MAAM,SAAS,YAAY,gBAAgB,OAAO,EAAC,SAAQ,IAAI,EAAC,UAAU,aAAY,CAAC,CAAC;AAAA,EAC3G;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WAAW,IAAY,SAA2E;AACtG,UAAM,EAAC,UAAU,MAAM,UAAU,aAAY,IAAI,SAAS,EAAE;AAC5D,UAAM,WAAW,KAAK,YAAY,IAAI;AACtC,QAAI,CAAC,SAAU,OAAM,IAAI,MAAM,iCAAiC,EAAE,GAAG;AACrE,QAAI,OAAO,SAAS,eAAe,YAAY;AAC7C,YAAM,IAAI,+BAA+B,oBAAoB,IAAI,qBAAqB;AAAA,IACxF;AACA,UAAM,kBAAkB;AACxB,QAAI,CAAC,mBAAmB,OAAO,gBAAgB,oBAAoB,YAAY;AAC7E,YAAM,IAAI,oBAAoB,yEAAyE;AAAA,IACzG;AACA,UAAM,SAAS;AACf,QAAI,kBAAkB;AACtB,QAAI;AAAE,wBAAkB,SAAS,QAAQ;AAAA,IAAG,QAAQ;AAAA,IAA0B;AAC9E,QAAI,CAAC,gBAAiB,OAAM,IAAI,MAAM,oBAAoB,IAAI,eAAe;AAC7E,UAAM,WAAW,MAAM,SAAS,WAAW,gBAAgB,OAAO,EAAC,SAAQ,IAAI,EAAC,UAAU,aAAY,CAAC;AACvG,QAAI,CAAC,SAAU,OAAM,IAAI,iBAAiB,0FAAqF;AAC/H,QAAI,CAAC,SAAS,SAAS,CAAC,SAAS,MAAM,WAAW,SAAS,GAAG;AAC5D,YAAM,IAAI,+BAA+B,yEAAyE,SAAS,SAAS,GAAG,IAAI;AAAA,IAC7I;AACA,QAAI,CAAC,SAAS,MAAM,CAAC,SAAS,QAAQ,CAAC,0BAA0B,KAAK,SAAS,IAAI,GAAG;AACpF,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AACA,QAAI,SAAS,iBAAiB,UAAa,SAAS,YAAY,UAAa,SAAS,cAAc,UAAa,SAAS,SAAS,UAAa,SAAS,oBAAoB,QAAW;AACtL,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AACA,QAAI,SAAS,UAAU,UAAa,SAAS,UAAU,IAAK,OAAM,IAAI,MAAM,4CAA4C;AACxH,UAAM,aAAa,SAAS,MAAM,MAAM,UAAU,MAAM;AACxD,QAAI,SAAS,YAAY,UAAa,OAAO,SAAS,OAAO,MAAM,YAAY;AAC7E,YAAM,IAAI,MAAM,wBAAwB,SAAS,OAAO,mBAAmB,SAAS,KAAK,EAAE;AAAA,IAC7F;AACA,UAAM,SAAS,MAAM,iBAAiB,MAAM;AAC5C,QAAI,UAAU,KAAM,OAAM,IAAI,MAAM,gEAAgE,SAAS,KAAK,EAAE;AACpH,UAAM,aAAa,OAAO,WAAW,WAAW,SAAS,OAAO,MAAM;AACtE,UAAM,WAAW,WAAW,WAAW,SAAS,IAAI,WAAW,MAAM,UAAU,MAAM,IAAI;AACzF,QAAI,aAAa,WAAY,OAAM,IAAI,MAAM,sBAAsB,SAAS,KAAK,iCAAiC,UAAU,EAAE;AAC9H,SAAK,UAAU,SAAS;AACxB,UAAM,OAAO,MAAM,OAAO,gBAAgB;AAAA,MACxC,IAAI,SAAS;AAAA,MACb,MAAM,SAAS;AAAA,MACf,OAAO;AAAA,MACP,SAAS,OAAO,UAAU;AAAA,MAC1B,GAAI,SAAS,WAAW,EAAC,UAAU,OAAO,SAAS,QAAQ,EAAC,IAAI,CAAC;AAAA,IACnE,CAAC;AACD,QAAI,CAAC,KAAK,KAAM,OAAM,IAAI,oBAAoB,wDAAwD;AACtG,SAAK,UAAU,aAAa,EAAC,MAAM,KAAK,KAAI,CAAC;AAC7C,WAAO,EAAC,MAAM,KAAK,MAAM,OAAO,SAAS,OAAO,GAAE;AAAA,EACpD;AAAA;AAAA;AAAA,EAIA,MAAe,OAAO,SAA+C;AACnE,UAAM,SAAS,oBAAoB,QAAQ,QAAQ,QAAQ;AAC3D,UAAM,eAA6B;AAAA,MACjC,WAAW,QAAQ;AAAA,MACnB,SAAS,QAAQ;AAAA,MACjB,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ;AAAA,MACnB,iBAAiB;AAAA,IACnB;AACA,UAAM,QAAQ,MAAM,KAAK,WAAW,YAAY;AAChD,UAAM,SAAS,MAAM,KAAK,MAAM,EAAC,GAAG,cAAc,cAAc,MAAM,iBAAgB,CAAC;AACvF,UAAM,MAAM,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,QAAQ,EAAE;AACjG,UAAM,YAAY,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,QAAQ,EAAE;AACxG,WAAO,EAAC,MAAM,OAAO,IAAI,KAAK,UAAS;AAAA,EACzC;AAAA;AAAA,EAGA,MAAe,KAAK,SAA2C;AAC7D,QAAI,QAAQ,kBAAkB,QAAW;AACvC,YAAM,IAAI,+BAA+B,sDAAsD;AAAA,IACjG;AACA,UAAM,SAAS,oBAAoB,QAAQ,eAAe,eAAe;AACzE,UAAM,eAA6B;AAAA,MACjC,WAAW,QAAQ;AAAA,MACnB,SAAS,QAAQ;AAAA,MACjB,iBAAiB;AAAA;AAAA;AAAA,MAGjB,GAAI,QAAQ,OAAO,SAAY,EAAC,WAAW,QAAQ,GAAE,IAAI,CAAC;AAAA,MAC1D,GAAI,QAAQ,iBAAiB,SAAY,EAAC,cAAc,QAAQ,aAAY,IAAI,CAAC;AAAA,IACnF;AACA,UAAM,QAAQ,QAAQ,iBAAiB,MAAM,KAAK,WAAW,YAAY,GAAG;AAC5E,UAAM,SAAS,MAAM,KAAK,MAAM,EAAC,GAAG,cAAc,cAAc,MAAK,CAAC;AACtE,UAAM,MAAM,OAAO,KAAK,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,QAAQ,EAAE;AACnE,WAAO,EAAC,MAAM,OAAO,IAAI,KAAK,eAAe,OAAO,iBAAiB,gBAAgB,OAAO,cAAa;AAAA,EAC3G;AAAA;AAAA,EAGA,MAAe,qBAAqD;AAClE,QAAI,CAAC,KAAK,gBAAgB,EAAG,QAAO,CAAC;AACrC,WAAO,iBAAiB,OAAO,CAAC,MAAe,KAAK,eAAe,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO;AAAA,MACvF,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,MAAM,UAAU,EAAE,KAAK;AAAA,MACvB,aAAa,EAAE,OAAO,CAAC,GAAG,UAAU;AAAA,IACtC,EAAE;AAAA,EACJ;AAAA;AAAA,EAGA,MAAe,mBAAmB,SAAuE;AACvG,UAAM,WAAW,SAAS,aAAa,OAAO,QAAQ,QAAQ,WAAW,EAAE,IAAI;AAC/E,UAAM,SAAS,SAAS,WAAW,OAAO,QAAQ,QAAQ,SAAS,EAAE,IAAI;AACzE,QAAI,CAAC,KAAK,gBAAgB,KAAM,YAAY,UAAU,CAAC,KAAK,cAAc,UAAU,MAAM,EAAI,QAAO,CAAC;AACtG,UAAM,MAA6B,CAAC;AACpC,eAAW,KAAK,kBAAkB;AAChC,UAAI,CAAC,KAAK,eAAe,EAAE,KAAK,EAAG;AACnC,WAAK,YAAY,WAAW,EAAE,UAAU,YAAY,EAAE,UAAU,OAAQ;AACxE,iBAAW,KAAK,EAAE,QAAQ;AACxB,YAAI,KAAK;AAAA,UACP,OAAO,EAAE;AAAA,UACT,OAAO,EAAE;AAAA,UACT,QAAQ,EAAE;AAAA,UACV,UAAU,EAAE;AAAA,UACZ,GAAI,EAAE,WAAW,EAAC,SAAS,EAAE,SAAQ,IAAI,CAAC;AAAA,QAC5C,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,oBAAuB,OAAa;AAC3C,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,CAAC,MAAM,oBAAoB,CAAC,CAAC;AACxE,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAgC,EAAG,KAAI,CAAC,IAAI,oBAAoB,CAAC;AACrG,SAAO;AACT;AAEA,SAAS,WAAc,OAAa;AAClC,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,eAAW,KAAK,OAAO,OAAO,KAAgC,EAAG,YAAW,CAAC;AAC7E,WAAO,OAAO,KAAK;AAAA,EACrB;AACA,SAAO;AACT;","names":["sent"]}