{"version":3,"file":"etherscan.mjs","names":["createChain"],"sources":["../../src/providers/etherscan.ts"],"sourcesContent":["/**\n * Etherscan V2 provider.\n *\n * Uses Etherscan's unified multichain endpoint for Ethereum, Base, Arbitrum, Optimism, Polygon,\n * BSC, Avalanche, Gnosis, Linea, and Berachain.\n *\n * Auth: Etherscan API key. Env: ETHERSCAN_API_KEY\n */\n\nimport type {\n  ProviderCapabilities,\n  ProviderConfig,\n  ChainKey,\n  Balance,\n  Transaction,\n  TxHistoryOptions,\n  ContractInfo,\n  TokenBalance,\n  TokenBalanceOptions,\n  TokenTransfer,\n  TokenTransferOptions,\n  GasData,\n  BlockInfo,\n  TxStatus,\n} from \"../core/types.js\";\nimport { Provider } from \"../core/provider.js\";\nimport { buildQuery, normalizeBaseUrl } from \"../core/client.js\";\nimport {\n  AuthError,\n  ExplorerError,\n  NotFoundError,\n  PlanRestrictedError,\n  RateLimitError,\n  UnsupportedChainError,\n} from \"../core/errors.js\";\nimport { create as createChain } from \"@agntn/chains\";\nimport { clampMaxResults, formatWei, multiplyIntegerStrings } from \"../core/types.js\";\n\nconst DEFAULT_BASE = \"https://api.etherscan.io/v2/api\";\nconst SUPPORTED_CHAINS = new Set<ChainKey>([\n  \"ethereum\",\n  \"base\",\n  \"arbitrum\",\n  \"optimism\",\n  \"polygon\",\n  \"bsc\",\n  \"avalanche\",\n  \"gnosis\",\n  \"linea\",\n  \"berachain\",\n]);\n\ninterface EtherscanResponse<T> {\n  readonly status?: string;\n  readonly message?: string;\n  readonly result?: T;\n  readonly error?: { readonly code: number; readonly message: string };\n}\n\ninterface EtherscanTx {\n  readonly blockNumber: string;\n  readonly timeStamp: string;\n  readonly hash: string;\n  readonly from: string;\n  readonly to: string;\n  readonly value: string;\n  readonly gas: string;\n  readonly gasUsed: string;\n  readonly gasPrice: string;\n  readonly isError: string;\n  readonly txreceipt_status: string;\n  readonly input: string;\n  readonly functionName?: string;\n  readonly methodId?: string;\n  readonly contractAddress: string;\n  readonly confirmations: string;\n}\n\ninterface EtherscanTokenTx {\n  readonly blockNumber: string;\n  readonly timeStamp: string;\n  readonly hash: string;\n  readonly from: string;\n  readonly to: string;\n  readonly value: string;\n  readonly contractAddress: string;\n  readonly tokenName: string;\n  readonly tokenSymbol: string;\n  readonly tokenDecimal: string;\n}\n\ninterface EtherscanTokenBalance {\n  readonly TokenAddress: string;\n  readonly TokenName: string;\n  readonly TokenSymbol: string;\n  readonly TokenDivisor: string;\n  readonly TokenQuantity: string;\n}\n\ninterface EtherscanGasResult {\n  readonly LastBlock: string;\n  readonly SafeGasPrice: string;\n  readonly ProposeGasPrice: string;\n  readonly FastGasPrice: string;\n  readonly suggestBaseFee: string;\n  readonly gasUsedRatio: string;\n}\n\ninterface EtherscanBlockResult {\n  readonly number: string;\n  readonly hash: string;\n  readonly parentHash: string;\n  readonly timestamp: string;\n  readonly miner: string;\n  readonly gasLimit: string;\n  readonly gasUsed: string;\n  readonly baseFeePerGas?: string;\n  readonly transactions: readonly string[];\n}\n\nfunction getChainId(chain: ChainKey): string {\n  if (!SUPPORTED_CHAINS.has(chain)) {\n    throw new UnsupportedChainError(chain, \"etherscan\");\n  }\n  const { chainId } = createChain(chain);\n  if (!chainId) {\n    throw new UnsupportedChainError(chain, \"etherscan\");\n  }\n  return BigInt(chainId).toString();\n}\n\nfunction mapTx(raw: Readonly<EtherscanTx>): Transaction {\n  const status: TxStatus =\n    raw.isError === \"1\" || raw.txreceipt_status === \"0\" ? \"failed\" : \"success\";\n  return {\n    hash: raw.hash,\n    blockNumber: Number(raw.blockNumber),\n    timestamp: new Date(Number(raw.timeStamp) * 1000).toISOString(),\n    from: raw.from,\n    to: raw.to || null,\n    value: raw.value,\n    valueFormatted: formatWei(raw.value),\n    gasUsed: raw.gasUsed,\n    gasPrice: raw.gasPrice,\n    fee: multiplyIntegerStrings(raw.gasUsed, raw.gasPrice),\n    status,\n    methodId: raw.methodId,\n    functionName: raw.functionName,\n    isContractInteraction: raw.input !== \"0x\" && raw.input.length > 2,\n    tokenTransfers: [],\n    raw: raw as unknown as Record<string, unknown>,\n  };\n}\n\nfunction isEmptyEtherscanResult(action: string, message: string): boolean {\n  if (action === \"txlist\" || action === \"tokentx\") return /no transactions found/i.test(message);\n  return action === \"addresstokenbalance\" && /no (token|record)/i.test(message);\n}\n\nfunction isPlanRestriction(message: string): boolean {\n  return /free api access is not supported|api pro endpoint/i.test(message);\n}\n\nfunction etherscanFailure(action: string, message: string): never | [] {\n  if (isEmptyEtherscanResult(action, message)) return [];\n  if (/rate limit/i.test(message)) throw new RateLimitError(\"etherscan\");\n  if (isPlanRestriction(message)) throw new PlanRestrictedError(\"etherscan\", message);\n  if (/invalid api key|missing\\/invalid api key/i.test(message)) {\n    throw new AuthError(\"etherscan\", \"Invalid API key\");\n  }\n  throw new ExplorerError(`Etherscan API error: ${message}`, \"etherscan\");\n}\n\nfunction unwrapEtherscanResponse<T>(response: Readonly<EtherscanResponse<T>>, action: string): T {\n  if (response.error) {\n    if (isPlanRestriction(response.error.message)) {\n      throw new PlanRestrictedError(\"etherscan\", response.error.message);\n    }\n    throw new ExplorerError(`Etherscan API error: ${response.error.message}`, \"etherscan\");\n  }\n  if (response.status === \"0\") {\n    const detail = typeof response.result === \"string\" ? response.result : response.message;\n    return etherscanFailure(action, detail || \"Unknown Etherscan API error\") as T;\n  }\n  if (!(\"result\" in response)) {\n    throw new ExplorerError(\"Etherscan API response did not include a result\", \"etherscan\");\n  }\n  return response.result as T;\n}\n\nfunction historyParams(\n  address: string,\n  options: Readonly<TxHistoryOptions> | undefined,\n  limit: number,\n): Readonly<Record<string, string | number | undefined>> {\n  return {\n    address,\n    startblock: options?.startBlock ?? 0,\n    endblock: options?.endBlock ?? 99999999,\n    page: options?.page ?? 1,\n    offset: limit,\n    sort: options?.sort ?? \"desc\",\n  };\n}\n\nfunction rpcQuantity(value: string | null | undefined): string | undefined {\n  return value ? BigInt(value).toString() : undefined;\n}\n\nfunction rpcStatus(receipt: Readonly<Record<string, string | null>> | null): TxStatus {\n  if (!receipt) return \"pending\";\n  return receipt.status === \"0x1\" ? \"success\" : \"failed\";\n}\n\nfunction rpcFee(gasUsed: string | undefined, gasPrice: string | undefined): string | undefined {\n  return gasUsed && gasPrice ? multiplyIntegerStrings(gasUsed, gasPrice) : undefined;\n}\n\nfunction rpcInput(input: string | null | undefined): {\n  readonly isContractInteraction: boolean;\n  readonly methodId?: string;\n} {\n  return {\n    methodId: input ? input.slice(0, 10) : undefined,\n    isContractInteraction: (input?.length ?? 0) > 2,\n  };\n}\n\nfunction mapRpcTransaction(\n  tx: Readonly<Record<string, string | null>>,\n  receipt: Readonly<Record<string, string | null>> | null,\n): Transaction {\n  const gasUsed = rpcQuantity(receipt?.gasUsed);\n  const gasPrice = rpcQuantity(tx.gasPrice);\n  const value = rpcQuantity(tx.value) ?? \"0\";\n  return {\n    hash: tx.hash ?? \"\",\n    blockNumber: Number(tx.blockNumber ?? \"0x0\"),\n    from: tx.from ?? \"\",\n    to: tx.to ?? null,\n    value,\n    valueFormatted: formatWei(value),\n    gasUsed,\n    gasPrice,\n    fee: rpcFee(gasUsed, gasPrice),\n    status: rpcStatus(receipt),\n    ...rpcInput(tx.input),\n    tokenTransfers: [],\n    raw: { ...tx, receipt } as Record<string, unknown>,\n  };\n}\n\nfunction optionalString(value: string | undefined): string | undefined {\n  return value || undefined;\n}\n\nfunction contractSource(\n  contract: Readonly<Record<string, string>> | undefined,\n): Pick<ContractInfo, \"abi\" | \"compilerVersion\" | \"isVerified\" | \"name\" | \"sourceCode\"> {\n  const abi = contract?.ABI;\n  const isVerified = abi !== undefined && abi !== \"Contract source code not verified\" && abi !== \"\";\n  return {\n    isVerified,\n    name: optionalString(contract?.ContractName),\n    compilerVersion: optionalString(contract?.CompilerVersion),\n    abi: isVerified ? abi : undefined,\n    sourceCode: isVerified ? contract?.SourceCode : undefined,\n  };\n}\n\nfunction mapContract(\n  address: string,\n  contract: Readonly<Record<string, string>> | undefined,\n): ContractInfo {\n  return {\n    address,\n    ...contractSource(contract),\n    isProxy: contract?.Proxy === \"1\",\n    implementationAddress: optionalString(contract?.Implementation),\n  };\n}\n\nfunction mapTokenTransfer(raw: Readonly<EtherscanTokenTx>): TokenTransfer {\n  const decimals = Number(raw.tokenDecimal);\n  return {\n    contract: raw.contractAddress,\n    symbol: raw.tokenSymbol,\n    name: raw.tokenName,\n    decimals,\n    value: raw.value,\n    valueFormatted: formatWei(raw.value, decimals),\n    from: raw.from,\n    to: raw.to,\n    txHash: raw.hash,\n    blockNumber: Number(raw.blockNumber),\n    timestamp: new Date(Number(raw.timeStamp) * 1000).toISOString(),\n  };\n}\n\nexport class Etherscan extends Provider {\n  static readonly key = \"etherscan\";\n\n  private readonly apiKey: string;\n  private readonly apiUrl: string;\n  private readonly defaultChain: ChainKey;\n\n  constructor(config: Readonly<ProviderConfig>) {\n    super(config);\n    const key = config.apiKey ?? process.env.ETHERSCAN_API_KEY ?? \"\";\n    if (!key) {\n      throw new AuthError(\"etherscan\", \"Set ETHERSCAN_API_KEY or pass apiKey in config\");\n    }\n    this.apiKey = key;\n    this.apiUrl = normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE);\n    this.defaultChain = config.defaultChain ?? \"ethereum\";\n    getChainId(this.defaultChain);\n  }\n  get capabilities(): ProviderCapabilities {\n    return {\n      balances: true,\n      txHistory: true,\n      txDetail: true,\n      utxos: false,\n      contractInfo: true,\n      tokenBalances: true,\n      tokenTransfers: true,\n      gasData: true,\n      blockInfo: true,\n    };\n  }\n\n  private async api<T>(\n    chain: ChainKey,\n    module: string,\n    action: string,\n    params: Readonly<Record<string, string | number | undefined>> = {},\n  ): Promise<T> {\n    const query = buildQuery({\n      chainid: getChainId(chain),\n      module,\n      action,\n      apikey: this.apiKey,\n      ...params,\n    });\n    const response = await this.getJSON<EtherscanResponse<T>>(`${this.apiUrl}${query}`);\n    return unwrapEtherscanResponse(response, action);\n  }\n\n  async getBalance(address: string, chain?: ChainKey): Promise<Balance> {\n    const c = chain ?? this.defaultChain;\n    const result = await this.api<string>(c, \"account\", \"balance\", {\n      address,\n      tag: \"latest\",\n    });\n\n    return this.snapshotBalance({\n      address,\n      chain: c,\n      balance: result,\n      balanceFormatted: formatWei(result),\n      symbol: createChain(c).symbol,\n    });\n  }\n\n  async getTxHistory(\n    address: string,\n    chain?: ChainKey,\n    options?: Readonly<TxHistoryOptions>,\n  ): Promise<Transaction[]> {\n    const c = chain ?? this.defaultChain;\n    const limit = clampMaxResults(options?.limit);\n    const result = await this.api<EtherscanTx[]>(\n      c,\n      \"account\",\n      \"txlist\",\n      historyParams(address, options, limit),\n    );\n\n    if (!Array.isArray(result)) return [];\n    return result.map(mapTx);\n  }\n\n  override async getTxDetail(hash: string, chain?: ChainKey): Promise<Transaction> {\n    const c = chain ?? this.defaultChain;\n    const tx = await this.api<Record<string, string | null> | null>(\n      c,\n      \"proxy\",\n      \"eth_getTransactionByHash\",\n      { txhash: hash },\n    );\n\n    if (!tx?.hash) {\n      throw new NotFoundError(`Transaction ${hash}`, \"etherscan\");\n    }\n\n    const receipt = await this.api<Record<string, string | null> | null>(\n      c,\n      \"proxy\",\n      \"eth_getTransactionReceipt\",\n      { txhash: hash },\n    );\n\n    return mapRpcTransaction(tx, receipt);\n  }\n\n  override async getContractInfo(address: string, chain?: ChainKey): Promise<ContractInfo> {\n    const c = chain ?? this.defaultChain;\n\n    const source = await this.api<Array<Record<string, string>>>(c, \"contract\", \"getsourcecode\", {\n      address,\n    });\n    return mapContract(address, source[0]);\n  }\n\n  override async getTokenBalances(\n    address: string,\n    chain?: ChainKey,\n    options?: Readonly<TokenBalanceOptions>,\n  ): Promise<TokenBalance[]> {\n    const c = chain ?? this.defaultChain;\n    const result = await this.api<EtherscanTokenBalance[]>(c, \"account\", \"addresstokenbalance\", {\n      address,\n    });\n\n    let tokens = result.map((token) => {\n      const decimals = Number(token.TokenDivisor);\n      return {\n        contract: token.TokenAddress,\n        symbol: token.TokenSymbol,\n        name: token.TokenName,\n        decimals,\n        balance: token.TokenQuantity,\n        balanceFormatted: formatWei(token.TokenQuantity, decimals),\n      };\n    });\n\n    if (options?.nonZeroOnly) {\n      tokens = tokens.filter((t) => t.balance !== \"0\");\n    }\n\n    return tokens;\n  }\n\n  override async getTokenTransfers(\n    address: string,\n    chain?: ChainKey,\n    options?: Readonly<TokenTransferOptions>,\n  ): Promise<TokenTransfer[]> {\n    const c = chain ?? this.defaultChain;\n    const limit = clampMaxResults(options?.limit);\n    const result = await this.api<EtherscanTokenTx[]>(c, \"account\", \"tokentx\", {\n      ...historyParams(address, options, limit),\n      contractaddress: options?.token,\n    });\n\n    return Array.isArray(result) ? result.map(mapTokenTransfer) : [];\n  }\n\n  override async getGasData(chain?: ChainKey): Promise<GasData> {\n    const c = chain ?? this.defaultChain;\n    const result = await this.api<EtherscanGasResult>(c, \"gastracker\", \"gasoracle\");\n\n    return {\n      chain: c,\n      unit: \"gwei\",\n      safeGasPrice: result.SafeGasPrice,\n      proposedGasPrice: result.ProposeGasPrice,\n      fastGasPrice: result.FastGasPrice,\n      baseFee: result.suggestBaseFee,\n    };\n  }\n\n  override async getBlockInfo(blockNumber: number, chain?: ChainKey): Promise<BlockInfo> {\n    const c = chain ?? this.defaultChain;\n    const result = await this.api<EtherscanBlockResult | null>(c, \"proxy\", \"eth_getBlockByNumber\", {\n      tag: `0x${blockNumber.toString(16)}`,\n      boolean: \"false\",\n    });\n    if (!result) {\n      throw new NotFoundError(`Block ${blockNumber}`, \"etherscan\");\n    }\n\n    return {\n      number: Number(result.number),\n      hash: result.hash,\n      parentHash: result.parentHash,\n      timestamp: new Date(Number(result.timestamp) * 1000).toISOString(),\n      miner: result.miner,\n      gasUsed: BigInt(result.gasUsed).toString(),\n      gasLimit: BigInt(result.gasLimit).toString(),\n      txCount: result.transactions.length,\n      baseFee: result.baseFeePerGas ? BigInt(result.baseFeePerGas).toString() : undefined,\n    };\n  }\n}\n"],"mappings":";;;;AAsCA,MAAM,eAAe;AACrB,MAAM,mCAAmB,IAAI,IAAc;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAsED,SAAS,WAAW,OAAyB;CAC3C,IAAI,CAAC,iBAAiB,IAAI,KAAK,GAC7B,MAAM,IAAI,sBAAsB,OAAO,WAAW;CAEpD,MAAM,EAAE,YAAYA,OAAY,KAAK;CACrC,IAAI,CAAC,SACH,MAAM,IAAI,sBAAsB,OAAO,WAAW;CAEpD,OAAO,OAAO,OAAO,CAAC,CAAC,SAAS;AAClC;AAEA,SAAS,MAAM,KAAyC;CACtD,MAAM,SACJ,IAAI,YAAY,OAAO,IAAI,qBAAqB,MAAM,WAAW;CACnE,OAAO;EACL,MAAM,IAAI;EACV,aAAa,OAAO,IAAI,WAAW;EACnC,4BAAW,IAAI,KAAK,OAAO,IAAI,SAAS,IAAI,GAAI,EAAA,CAAE,YAAY;EAC9D,MAAM,IAAI;EACV,IAAI,IAAI,MAAM;EACd,OAAO,IAAI;EACX,gBAAgB,UAAU,IAAI,KAAK;EACnC,SAAS,IAAI;EACb,UAAU,IAAI;EACd,KAAK,uBAAuB,IAAI,SAAS,IAAI,QAAQ;EACrD;EACA,UAAU,IAAI;EACd,cAAc,IAAI;EAClB,uBAAuB,IAAI,UAAU,QAAQ,IAAI,MAAM,SAAS;EAChE,gBAAgB,CAAC;EACZ;CACP;AACF;AAEA,SAAS,uBAAuB,QAAgB,SAA0B;CACxE,IAAI,WAAW,YAAY,WAAW,WAAW,OAAO,yBAAyB,KAAK,OAAO;CAC7F,OAAO,WAAW,yBAAyB,qBAAqB,KAAK,OAAO;AAC9E;AAEA,SAAS,kBAAkB,SAA0B;CACnD,OAAO,qDAAqD,KAAK,OAAO;AAC1E;AAEA,SAAS,iBAAiB,QAAgB,SAA6B;CACrE,IAAI,uBAAuB,QAAQ,OAAO,GAAG,OAAO,CAAC;CACrD,IAAI,cAAc,KAAK,OAAO,GAAG,MAAM,IAAI,eAAe,WAAW;CACrE,IAAI,kBAAkB,OAAO,GAAG,MAAM,IAAI,oBAAoB,aAAa,OAAO;CAClF,IAAI,4CAA4C,KAAK,OAAO,GAC1D,MAAM,IAAI,UAAU,aAAa,iBAAiB;CAEpD,MAAM,IAAI,cAAc,wBAAwB,WAAW,WAAW;AACxE;AAEA,SAAS,wBAA2B,UAA0C,QAAmB;CAC/F,IAAI,SAAS,OAAO;EAClB,IAAI,kBAAkB,SAAS,MAAM,OAAO,GAC1C,MAAM,IAAI,oBAAoB,aAAa,SAAS,MAAM,OAAO;EAEnE,MAAM,IAAI,cAAc,wBAAwB,SAAS,MAAM,WAAW,WAAW;CACvF;CACA,IAAI,SAAS,WAAW,KAEtB,OAAO,iBAAiB,SADT,OAAO,SAAS,WAAW,WAAW,SAAS,SAAS,SAAS,YACtC,6BAA6B;CAEzE,IAAI,EAAE,YAAY,WAChB,MAAM,IAAI,cAAc,mDAAmD,WAAW;CAExF,OAAO,SAAS;AAClB;AAEA,SAAS,cACP,SACA,SACA,OACuD;CACvD,OAAO;EACL;EACA,YAAY,SAAS,cAAc;EACnC,UAAU,SAAS,YAAY;EAC/B,MAAM,SAAS,QAAQ;EACvB,QAAQ;EACR,MAAM,SAAS,QAAQ;CACzB;AACF;AAEA,SAAS,YAAY,OAAsD;CACzE,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,SAAS,IAAI,KAAA;AAC5C;AAEA,SAAS,UAAU,SAAmE;CACpF,IAAI,CAAC,SAAS,OAAO;CACrB,OAAO,QAAQ,WAAW,QAAQ,YAAY;AAChD;AAEA,SAAS,OAAO,SAA6B,UAAkD;CAC7F,OAAO,WAAW,WAAW,uBAAuB,SAAS,QAAQ,IAAI,KAAA;AAC3E;AAEA,SAAS,SAAS,OAGhB;CACA,OAAO;EACL,UAAU,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,KAAA;EACvC,wBAAwB,OAAO,UAAU,KAAK;CAChD;AACF;AAEA,SAAS,kBACP,IACA,SACa;CACb,MAAM,UAAU,YAAY,SAAS,OAAO;CAC5C,MAAM,WAAW,YAAY,GAAG,QAAQ;CACxC,MAAM,QAAQ,YAAY,GAAG,KAAK,KAAK;CACvC,OAAO;EACL,MAAM,GAAG,QAAQ;EACjB,aAAa,OAAO,GAAG,eAAe,KAAK;EAC3C,MAAM,GAAG,QAAQ;EACjB,IAAI,GAAG,MAAM;EACb;EACA,gBAAgB,UAAU,KAAK;EAC/B;EACA;EACA,KAAK,OAAO,SAAS,QAAQ;EAC7B,QAAQ,UAAU,OAAO;EACzB,GAAG,SAAS,GAAG,KAAK;EACpB,gBAAgB,CAAC;EACjB,KAAK;GAAE,GAAG;GAAI;EAAQ;CACxB;AACF;AAEA,SAAS,eAAe,OAA+C;CACrE,OAAO,SAAS,KAAA;AAClB;AAEA,SAAS,eACP,UACsF;CACtF,MAAM,MAAM,UAAU;CACtB,MAAM,aAAa,QAAQ,KAAA,KAAa,QAAQ,uCAAuC,QAAQ;CAC/F,OAAO;EACL;EACA,MAAM,eAAe,UAAU,YAAY;EAC3C,iBAAiB,eAAe,UAAU,eAAe;EACzD,KAAK,aAAa,MAAM,KAAA;EACxB,YAAY,aAAa,UAAU,aAAa,KAAA;CAClD;AACF;AAEA,SAAS,YACP,SACA,UACc;CACd,OAAO;EACL;EACA,GAAG,eAAe,QAAQ;EAC1B,SAAS,UAAU,UAAU;EAC7B,uBAAuB,eAAe,UAAU,cAAc;CAChE;AACF;AAEA,SAAS,iBAAiB,KAAgD;CACxE,MAAM,WAAW,OAAO,IAAI,YAAY;CACxC,OAAO;EACL,UAAU,IAAI;EACd,QAAQ,IAAI;EACZ,MAAM,IAAI;EACV;EACA,OAAO,IAAI;EACX,gBAAgB,UAAU,IAAI,OAAO,QAAQ;EAC7C,MAAM,IAAI;EACV,IAAI,IAAI;EACR,QAAQ,IAAI;EACZ,aAAa,OAAO,IAAI,WAAW;EACnC,4BAAW,IAAI,KAAK,OAAO,IAAI,SAAS,IAAI,GAAI,EAAA,CAAE,YAAY;CAChE;AACF;AAEA,IAAa,YAAb,cAA+B,SAAS;CACtC,OAAgB,MAAM;CAEtB;CACA;CACA;CAEA,YAAY,QAAkC;EAC5C,MAAM,MAAM;EACZ,MAAM,MAAM,OAAO,UAAU,QAAQ,IAAI,qBAAqB;EAC9D,IAAI,CAAC,KACH,MAAM,IAAI,UAAU,aAAa,gDAAgD;EAEnF,KAAK,SAAS;EACd,KAAK,SAAS,iBAAiB,OAAO,WAAW,YAAY;EAC7D,KAAK,eAAe,OAAO,gBAAgB;EAC3C,WAAW,KAAK,YAAY;CAC9B;CACA,IAAI,eAAqC;EACvC,OAAO;GACL,UAAU;GACV,WAAW;GACX,UAAU;GACV,OAAO;GACP,cAAc;GACd,eAAe;GACf,gBAAgB;GAChB,SAAS;GACT,WAAW;EACb;CACF;CAEA,MAAc,IACZ,OACA,QACA,QACA,SAAgE,CAAC,GACrD;EACZ,MAAM,QAAQ,WAAW;GACvB,SAAS,WAAW,KAAK;GACzB;GACA;GACA,QAAQ,KAAK;GACb,GAAG;EACL,CAAC;EAED,OAAO,wBAAwB,MADR,KAAK,QAA8B,GAAG,KAAK,SAAS,OAAO,GACzC,MAAM;CACjD;CAEA,MAAM,WAAW,SAAiB,OAAoC;EACpE,MAAM,IAAI,SAAS,KAAK;EACxB,MAAM,SAAS,MAAM,KAAK,IAAY,GAAG,WAAW,WAAW;GAC7D;GACA,KAAK;EACP,CAAC;EAED,OAAO,KAAK,gBAAgB;GAC1B;GACA,OAAO;GACP,SAAS;GACT,kBAAkB,UAAU,MAAM;GAClC,QAAQA,OAAY,CAAC,CAAC,CAAC;EACzB,CAAC;CACH;CAEA,MAAM,aACJ,SACA,OACA,SACwB;EACxB,MAAM,IAAI,SAAS,KAAK;EACxB,MAAM,QAAQ,gBAAgB,SAAS,KAAK;EAC5C,MAAM,SAAS,MAAM,KAAK,IACxB,GACA,WACA,UACA,cAAc,SAAS,SAAS,KAAK,CACvC;EAEA,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;EACpC,OAAO,OAAO,IAAI,KAAK;CACzB;CAEA,MAAe,YAAY,MAAc,OAAwC;EAC/E,MAAM,IAAI,SAAS,KAAK;EACxB,MAAM,KAAK,MAAM,KAAK,IACpB,GACA,SACA,4BACA,EAAE,QAAQ,KAAK,CACjB;EAEA,IAAI,CAAC,IAAI,MACP,MAAM,IAAI,cAAc,eAAe,QAAQ,WAAW;EAU5D,OAAO,kBAAkB,IAAI,MAPP,KAAK,IACzB,GACA,SACA,6BACA,EAAE,QAAQ,KAAK,CACjB,CAEoC;CACtC;CAEA,MAAe,gBAAgB,SAAiB,OAAyC;EACvF,MAAM,IAAI,SAAS,KAAK;EAKxB,OAAO,YAAY,UAAS,MAHP,KAAK,IAAmC,GAAG,YAAY,iBAAiB,EAC3F,QACF,CAAC,EAAA,CACkC,EAAE;CACvC;CAEA,MAAe,iBACb,SACA,OACA,SACyB;EACzB,MAAM,IAAI,SAAS,KAAK;EAKxB,IAAI,UAAS,MAJQ,KAAK,IAA6B,GAAG,WAAW,uBAAuB,EAC1F,QACF,CAAC,EAAA,CAEmB,KAAK,UAAU;GACjC,MAAM,WAAW,OAAO,MAAM,YAAY;GAC1C,OAAO;IACL,UAAU,MAAM;IAChB,QAAQ,MAAM;IACd,MAAM,MAAM;IACZ;IACA,SAAS,MAAM;IACf,kBAAkB,UAAU,MAAM,eAAe,QAAQ;GAC3D;EACF,CAAC;EAED,IAAI,SAAS,aACX,SAAS,OAAO,QAAQ,MAAM,EAAE,YAAY,GAAG;EAGjD,OAAO;CACT;CAEA,MAAe,kBACb,SACA,OACA,SAC0B;EAC1B,MAAM,IAAI,SAAS,KAAK;EACxB,MAAM,QAAQ,gBAAgB,SAAS,KAAK;EAC5C,MAAM,SAAS,MAAM,KAAK,IAAwB,GAAG,WAAW,WAAW;GACzE,GAAG,cAAc,SAAS,SAAS,KAAK;GACxC,iBAAiB,SAAS;EAC5B,CAAC;EAED,OAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,IAAI,gBAAgB,IAAI,CAAC;CACjE;CAEA,MAAe,WAAW,OAAoC;EAC5D,MAAM,IAAI,SAAS,KAAK;EACxB,MAAM,SAAS,MAAM,KAAK,IAAwB,GAAG,cAAc,WAAW;EAE9E,OAAO;GACL,OAAO;GACP,MAAM;GACN,cAAc,OAAO;GACrB,kBAAkB,OAAO;GACzB,cAAc,OAAO;GACrB,SAAS,OAAO;EAClB;CACF;CAEA,MAAe,aAAa,aAAqB,OAAsC;EACrF,MAAM,IAAI,SAAS,KAAK;EACxB,MAAM,SAAS,MAAM,KAAK,IAAiC,GAAG,SAAS,wBAAwB;GAC7F,KAAK,KAAK,YAAY,SAAS,EAAE;GACjC,SAAS;EACX,CAAC;EACD,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,SAAS,eAAe,WAAW;EAG7D,OAAO;GACL,QAAQ,OAAO,OAAO,MAAM;GAC5B,MAAM,OAAO;GACb,YAAY,OAAO;GACnB,4BAAW,IAAI,KAAK,OAAO,OAAO,SAAS,IAAI,GAAI,EAAA,CAAE,YAAY;GACjE,OAAO,OAAO;GACd,SAAS,OAAO,OAAO,OAAO,CAAC,CAAC,SAAS;GACzC,UAAU,OAAO,OAAO,QAAQ,CAAC,CAAC,SAAS;GAC3C,SAAS,OAAO,aAAa;GAC7B,SAAS,OAAO,gBAAgB,OAAO,OAAO,aAAa,CAAC,CAAC,SAAS,IAAI,KAAA;EAC5E;CACF;AACF"}