@elizaos/plugin-wallet 2.0.0-beta.1 → 2.0.3-beta.6
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/README.md +70 -45
- package/auto-enable.ts +1 -1
- package/dist/actions/failure-codes.d.ts +12 -0
- package/dist/actions/index.d.ts +1 -0
- package/dist/analytics/birdeye/actions/wallet-search-address.d.ts +7 -0
- package/dist/analytics/birdeye/birdeye-task.d.ts +27 -0
- package/dist/analytics/birdeye/birdeye.d.ts +140 -0
- package/dist/analytics/birdeye/constants.d.ts +68 -0
- package/dist/analytics/birdeye/providers/agent-portfolio-provider.d.ts +8 -0
- package/dist/analytics/birdeye/providers/market.d.ts +18 -0
- package/dist/analytics/birdeye/providers/portfolio-factory.d.ts +10 -0
- package/dist/analytics/birdeye/providers/trending.d.ts +19 -0
- package/dist/analytics/birdeye/providers/wallet.d.ts +5 -0
- package/dist/analytics/birdeye/search-category.d.ts +52 -0
- package/dist/analytics/birdeye/service.d.ts +94 -0
- package/dist/analytics/birdeye/types/api/common.d.ts +199 -0
- package/dist/analytics/birdeye/types/api/defi.d.ts +187 -0
- package/dist/analytics/birdeye/types/api/pair.d.ts +182 -0
- package/dist/analytics/birdeye/types/api/search.d.ts +64 -0
- package/dist/analytics/birdeye/types/api/token.d.ts +580 -0
- package/dist/analytics/birdeye/types/api/trader.d.ts +70 -0
- package/dist/analytics/birdeye/types/api/wallet.d.ts +161 -0
- package/dist/analytics/birdeye/types/shared.d.ts +83 -0
- package/dist/analytics/birdeye/utils.d.ts +74 -0
- package/dist/analytics/dexscreener/errors.d.ts +2 -0
- package/dist/analytics/dexscreener/index.d.ts +3 -0
- package/dist/analytics/dexscreener/search-category.d.ts +3 -0
- package/dist/analytics/dexscreener/service.d.ts +34 -0
- package/dist/analytics/dexscreener/types.d.ts +131 -0
- package/dist/analytics/lpinfo/index.d.ts +31 -0
- package/dist/analytics/lpinfo/kamino/index.d.ts +7 -0
- package/dist/analytics/lpinfo/kamino/providers/kaminoLiquidityProvider.d.ts +6 -0
- package/dist/analytics/lpinfo/kamino/providers/kaminoPoolProvider.d.ts +6 -0
- package/dist/analytics/lpinfo/kamino/providers/kaminoProvider.d.ts +6 -0
- package/dist/analytics/lpinfo/kamino/services/kaminoLiquidityService.d.ts +203 -0
- package/dist/analytics/lpinfo/kamino/services/kaminoService.d.ts +171 -0
- package/dist/analytics/lpinfo/steer/index.d.ts +7 -0
- package/dist/analytics/lpinfo/steer/providers/steerLiquidityProvider.d.ts +6 -0
- package/dist/analytics/lpinfo/steer/services/steerLiquidityService.d.ts +208 -0
- package/dist/analytics/lpinfo/steer/steer-display-types.d.ts +97 -0
- package/dist/analytics/news/index.d.ts +32 -0
- package/dist/analytics/news/interfaces/types.d.ts +177 -0
- package/dist/analytics/news/providers/defiNewsProvider.d.ts +106 -0
- package/dist/analytics/news/services/newsDataService.d.ts +72 -0
- package/dist/analytics/news/utils/formatters.d.ts +54 -0
- package/dist/analytics/token-info/action.d.ts +6 -0
- package/dist/analytics/token-info/index.d.ts +3 -0
- package/dist/analytics/token-info/params.d.ts +10 -0
- package/dist/analytics/token-info/providers.d.ts +4 -0
- package/dist/analytics/token-info/service.d.ts +19 -0
- package/dist/analytics/token-info/types.d.ts +45 -0
- package/dist/api/wallet-routes.d.ts +100 -0
- package/dist/audit/audit-log.d.ts +29 -0
- package/dist/browser-shim/build-shim.d.ts +31 -0
- package/dist/browser-shim/index.d.ts +1 -0
- package/dist/chains/evm/actions/helpers.d.ts +31 -0
- package/dist/chains/evm/actions/swap.d.ts +53 -0
- package/dist/chains/evm/actions/transfer.d.ts +10 -0
- package/dist/chains/evm/bridge-router.d.ts +44 -0
- package/dist/chains/evm/build.d.ts +2 -0
- package/dist/chains/evm/chain-handler.d.ts +37 -0
- package/dist/chains/evm/constants.d.ts +16 -0
- package/dist/chains/evm/dex/aerodrome/index.d.ts +6 -0
- package/dist/chains/evm/dex/aerodrome/services/AerodromeLpService.d.ts +27 -0
- package/dist/chains/evm/dex/aerodrome/types.d.ts +435 -0
- package/dist/chains/evm/dex/pancakeswp/index.d.ts +6 -0
- package/dist/chains/evm/dex/pancakeswp/services/PancakeSwapV3LpService.d.ts +28 -0
- package/dist/chains/evm/dex/pancakeswp/types.d.ts +19 -0
- package/dist/chains/evm/dex/uniswap/index.d.ts +6 -0
- package/dist/chains/evm/dex/uniswap/services/UniswapV3LpService.d.ts +28 -0
- package/dist/chains/evm/dex/uniswap/types.d.ts +458 -0
- package/dist/chains/evm/generated/specs/spec-helpers.d.ts +35 -0
- package/dist/chains/evm/generated/specs/specs.d.ts +99 -0
- package/dist/chains/evm/gov-router.d.ts +6 -0
- package/dist/chains/evm/index.browser.d.ts +3 -0
- package/dist/chains/evm/index.d.ts +6 -0
- package/dist/chains/evm/prompts.d.ts +24 -0
- package/dist/chains/evm/providers/get-balance.d.ts +2 -0
- package/dist/chains/evm/providers/wallet.d.ts +35 -0
- package/dist/chains/evm/routes/sign.d.ts +13 -0
- package/dist/chains/evm/rpc-providers.d.ts +26 -0
- package/dist/chains/evm/service.d.ts +26 -0
- package/dist/chains/evm/templates/index.d.ts +1 -0
- package/dist/chains/evm/types/index.d.ts +296 -0
- package/dist/chains/evm/vitest.config.d.ts +2 -0
- package/dist/chains/registry.d.ts +3 -0
- package/dist/chains/solana/actions/confirmation.d.ts +9 -0
- package/dist/chains/solana/bn.d.ts +6 -0
- package/dist/chains/solana/build.d.ts +2 -0
- package/dist/chains/solana/constants.d.ts +2 -0
- package/dist/chains/solana/dex/meteora/e2e/scenarios.d.ts +10 -0
- package/dist/chains/solana/dex/meteora/e2e/test-utils.d.ts +28 -0
- package/dist/chains/solana/dex/meteora/index.d.ts +3 -0
- package/dist/chains/solana/dex/meteora/providers/positionProvider.d.ts +9 -0
- package/dist/chains/solana/dex/meteora/services/MeteoraLpService.d.ts +37 -0
- package/dist/chains/solana/dex/meteora/utils/dlmm.d.ts +6 -0
- package/dist/chains/solana/dex/meteora/utils/loadWallet.d.ts +14 -0
- package/dist/chains/solana/dex/meteora/utils/sendTransaction.d.ts +2 -0
- package/dist/chains/solana/dex/orca/index.d.ts +6 -0
- package/dist/chains/solana/dex/orca/providers/positionProvider.d.ts +10 -0
- package/dist/chains/solana/dex/orca/services/srv_orca.d.ts +10 -0
- package/dist/chains/solana/dex/orca/types.d.ts +61 -0
- package/dist/chains/solana/dex/orca/utils/loadWallet.d.ts +1 -0
- package/dist/chains/solana/dex/orca/utils/sendTransaction.d.ts +2 -0
- package/dist/chains/solana/dex/raydium/index.d.ts +6 -0
- package/dist/chains/solana/dex/raydium/providers/positionProvider.d.ts +10 -0
- package/dist/chains/solana/dex/raydium/services/srv_raydium.d.ts +104 -0
- package/dist/chains/solana/dex/raydium/types.d.ts +42 -0
- package/dist/chains/solana/environment.d.ts +15 -0
- package/dist/chains/solana/generated/specs/spec-helpers.d.ts +35 -0
- package/dist/chains/solana/generated/specs/specs.d.ts +73 -0
- package/dist/chains/solana/index.browser.d.ts +3 -0
- package/dist/chains/solana/index.d.ts +7 -0
- package/dist/chains/solana/keypairUtils.d.ts +7 -0
- package/dist/chains/solana/prompts.d.ts +12 -0
- package/dist/chains/solana/providers/wallet.d.ts +2 -0
- package/dist/chains/solana/routes/index.d.ts +2 -0
- package/dist/chains/solana/routes/sign.d.ts +16 -0
- package/dist/chains/solana/service.d.ts +237 -0
- package/dist/chains/solana/types.d.ts +377 -0
- package/dist/chains/solana/vitest.config.d.ts +2 -0
- package/dist/chains/wallet-action.d.ts +3 -0
- package/dist/contracts.d.ts +58 -0
- package/dist/core-augmentation.d.ts +9 -0
- package/dist/index.d.mts +27 -34727
- package/dist/index.d.ts +27 -0
- package/dist/index.mjs +28246 -21186
- package/dist/index.mjs.map +153 -0
- package/dist/lib/server-wallet-trade.d.ts +22 -0
- package/dist/lib/server-wallet-trade.js +333 -0
- package/dist/lib/server-wallet-trade.js.map +11 -0
- package/dist/lib/wallet-export-guard.d.ts +45 -0
- package/dist/lp/actions/liquidity.d.ts +2 -0
- package/dist/lp/e2e/real-token-tests.d.ts +6 -0
- package/dist/lp/e2e/scenarios.d.ts +9 -0
- package/dist/lp/e2e/test-utils.d.ts +28 -0
- package/dist/lp/lp-manager-entry.d.ts +18 -0
- package/dist/lp/services/ConcentratedLiquidityService.d.ts +32 -0
- package/dist/lp/services/DexInteractionService.d.ts +34 -0
- package/dist/lp/services/LpManagementService.d.ts +116 -0
- package/dist/lp/services/UserLpProfileService.d.ts +18 -0
- package/dist/lp/services/VaultService.d.ts +21 -0
- package/dist/lp/services/YieldOptimizationService.d.ts +59 -0
- package/dist/lp/services/__tests__/MockLpService.d.ts +17 -0
- package/dist/lp/types.d.ts +439 -0
- package/dist/lp/utils/solanaClient.d.ts +26 -0
- package/dist/plugin.d.ts +7 -0
- package/dist/policy/policy.d.ts +14 -0
- package/dist/providers/canonical-provider.d.ts +19 -0
- package/dist/providers/wallet-provider.d.ts +5 -0
- package/dist/register-routes.d.ts +1 -0
- package/dist/routes/plugin.d.ts +14 -0
- package/dist/routes/wallet-market-overview-route.d.ts +7 -0
- package/dist/sdk/abi.d.ts +396 -0
- package/dist/sdk/bridge/abis.d.ts +63 -0
- package/dist/sdk/bridge/client.d.ts +48 -0
- package/dist/sdk/bridge/index.d.ts +14 -0
- package/dist/sdk/bridge/solana.d.ts +131 -0
- package/dist/sdk/bridge/types.d.ts +92 -0
- package/dist/sdk/convenience.d.ts +104 -0
- package/dist/sdk/escrow/MutualStakeEscrow.d.ts +75 -0
- package/dist/sdk/escrow/types.d.ts +58 -0
- package/dist/sdk/escrow/verifiers.d.ts +25 -0
- package/dist/sdk/identity/erc8004.d.ts +304 -0
- package/dist/sdk/identity/reputation.d.ts +317 -0
- package/dist/sdk/identity/uaid.d.ts +192 -0
- package/dist/sdk/identity/validation.d.ts +282 -0
- package/dist/sdk/index.d.ts +133 -0
- package/dist/sdk/index.js +5284 -0
- package/dist/sdk/index.js.map +40 -0
- package/dist/sdk/policy/SpendingPolicy.d.ts +105 -0
- package/dist/sdk/policy/UptoBillingPolicy.d.ts +87 -0
- package/dist/sdk/router/PaymentRouter.d.ts +77 -0
- package/dist/sdk/router/index.d.ts +2 -0
- package/dist/sdk/swap/SwapModule.d.ts +47 -0
- package/dist/sdk/swap/abi.d.ts +50 -0
- package/dist/sdk/swap/index.d.ts +11 -0
- package/dist/sdk/swap/types.d.ts +101 -0
- package/dist/sdk/tokens/decimals.d.ts +64 -0
- package/dist/sdk/tokens/registry.d.ts +81 -0
- package/dist/sdk/tokens/solana.d.ts +107 -0
- package/dist/sdk/tokens/transfers.d.ts +94 -0
- package/dist/sdk/types.d.ts +129 -0
- package/dist/sdk/wallet-core.d.ts +29450 -0
- package/dist/sdk/x402/budget.d.ts +51 -0
- package/dist/sdk/x402/chains/abstract/index.d.ts +134 -0
- package/dist/sdk/x402/client.d.ts +66 -0
- package/dist/sdk/x402/index.d.ts +8 -0
- package/dist/sdk/x402/middleware.d.ts +37 -0
- package/dist/sdk/x402/multi-asset.d.ts +53 -0
- package/dist/sdk/x402/types.d.ts +109 -0
- package/dist/security/wallet-context-safety.d.ts +7 -0
- package/dist/security/wallet-financial-confirmation.d.ts +23 -0
- package/dist/services/wallet-backend-service.d.ts +39 -0
- package/dist/types/wallet-router.d.ts +130 -0
- package/dist/utils/intent-trajectory.d.ts +34 -0
- package/dist/wallet/backend.d.ts +41 -0
- package/dist/wallet/errors.d.ts +17 -0
- package/dist/wallet/index.d.ts +6 -0
- package/dist/wallet/local-eoa-backend.d.ts +37 -0
- package/dist/wallet/pending.d.ts +47 -0
- package/dist/wallet/select-backend.d.ts +11 -0
- package/dist/wallet/steward-backend.d.ts +22 -0
- package/dist/wallet-action.d.ts +1 -0
- package/dist/wallet-action.js +6292 -0
- package/dist/wallet-action.js.map +44 -0
- package/package.json +35 -21
- package/registry-entry.json +134 -0
- package/src/analytics/birdeye/actions/wallet-search-address.ts +85 -5
- package/src/analytics/birdeye/birdeye-task.ts +25 -9
- package/src/analytics/birdeye/birdeye.ts +6 -7
- package/src/analytics/birdeye/constants.ts +0 -1
- package/src/analytics/birdeye/providers/agent-portfolio-provider.ts +0 -1
- package/src/analytics/birdeye/providers/market.ts +51 -45
- package/src/analytics/birdeye/providers/portfolio-factory.ts +79 -38
- package/src/analytics/birdeye/providers/trending.ts +43 -46
- package/src/analytics/birdeye/providers/wallet.ts +0 -1
- package/src/analytics/birdeye/search-category.test.ts +1 -1
- package/src/analytics/birdeye/search-category.ts +77 -12
- package/src/analytics/birdeye/service.test.ts +146 -0
- package/src/analytics/birdeye/service.ts +220 -105
- package/src/analytics/birdeye/types/api/common.ts +0 -1
- package/src/analytics/birdeye/types/api/defi.ts +0 -1
- package/src/analytics/birdeye/types/api/pair.ts +0 -1
- package/src/analytics/birdeye/types/api/search.ts +0 -1
- package/src/analytics/birdeye/types/api/token.ts +0 -1
- package/src/analytics/birdeye/types/api/trader.ts +0 -1
- package/src/analytics/birdeye/types/api/wallet.ts +0 -1
- package/src/analytics/birdeye/types/shared.ts +0 -11
- package/src/analytics/birdeye/utils.test.ts +69 -0
- package/src/analytics/birdeye/utils.ts +11 -8
- package/src/analytics/dexscreener/search-category.ts +0 -1
- package/src/analytics/dexscreener/service.ts +7 -12
- package/src/analytics/dexscreener/types.ts +0 -1
- package/src/analytics/lpinfo/index.ts +5 -2
- package/src/analytics/lpinfo/kamino/README.md +2 -2
- package/src/analytics/lpinfo/kamino/index.ts +9 -2
- package/src/analytics/lpinfo/kamino/providers/kaminoLiquidityProvider.ts +6 -26
- package/src/analytics/lpinfo/kamino/providers/kaminoPoolProvider.ts +11 -12
- package/src/analytics/lpinfo/kamino/providers/kaminoProvider.ts +76 -32
- package/src/analytics/lpinfo/kamino/services/kaminoLiquidityService.ts +78 -38
- package/src/analytics/lpinfo/kamino/services/kaminoService.ts +71 -31
- package/src/analytics/lpinfo/steer/index.ts +7 -2
- package/src/analytics/lpinfo/steer/providers/steerLiquidityProvider.ts +25 -26
- package/src/analytics/lpinfo/steer/services/steerLiquidityService.ts +367 -149
- package/src/analytics/news/index.ts +7 -2
- package/src/analytics/news/interfaces/types.ts +0 -1
- package/src/analytics/news/providers/defiNewsProvider.ts +17 -44
- package/src/analytics/news/services/newsDataService.ts +1 -22
- package/src/analytics/news/utils/formatters.test.ts +60 -0
- package/src/analytics/news/utils/formatters.ts +0 -1
- package/src/analytics/token-info/action.ts +52 -212
- package/src/analytics/token-info/index.ts +1 -1
- package/src/analytics/token-info/params.test.ts +69 -0
- package/src/analytics/token-info/params.ts +13 -11
- package/src/analytics/token-info/providers.ts +46 -17
- package/src/analytics/token-info/service.ts +3 -3
- package/src/analytics/token-info/types.ts +2 -2
- package/src/api/wallet-routes.test.ts +56 -0
- package/src/api/wallet-routes.ts +1728 -0
- package/src/audit/audit-log.ts +57 -2
- package/src/browser-shim/build-shim.ts +1 -1
- package/src/browser-shim/shim.template.js +107 -117
- package/src/chains/{wallet-router.test.ts → __tests__/wallet-router.test.ts} +57 -10
- package/src/chains/evm/actions/helpers.ts +9 -7
- package/src/chains/evm/actions/swap.ts +176 -22
- package/src/chains/evm/actions/transfer.ts +29 -22
- package/src/chains/evm/biome.json +1 -1
- package/src/chains/evm/build.ts +6 -1
- package/src/chains/evm/constants.ts +19 -0
- package/src/chains/evm/contracts/artifacts/OZGovernor.json +25 -1682
- package/src/chains/evm/dex/aerodrome/index.ts +6 -1
- package/src/chains/evm/dex/aerodrome/services/AerodromeLpService.ts +41 -15
- package/src/chains/evm/dex/aerodrome/types.ts +1 -2
- package/src/chains/evm/dex/pancakeswp/index.ts +6 -1
- package/src/chains/evm/dex/pancakeswp/services/PancakeSwapV3LpService.ts +54 -17
- package/src/chains/evm/dex/pancakeswp/types.ts +1 -2
- package/src/chains/evm/dex/uniswap/index.ts +6 -1
- package/src/chains/evm/dex/uniswap/services/UniswapV3LpService.ts +20 -9
- package/src/chains/evm/dex/uniswap/types.ts +1 -2
- package/src/chains/evm/gov-router.ts +3 -1
- package/src/chains/evm/index.browser.ts +1 -1
- package/src/chains/evm/index.ts +5 -1
- package/src/chains/evm/prompts.ts +5 -0
- package/src/chains/evm/providers/get-balance.ts +1 -1
- package/src/chains/evm/providers/wallet.ts +80 -9
- package/src/chains/evm/routes/sign.ts +35 -26
- package/src/chains/evm/rpc-providers.ts +1 -1
- package/src/chains/evm/types/index.ts +22 -2
- package/src/chains/registry.ts +1 -1
- package/src/chains/wallet-action.ts +301 -91
- package/src/index.ts +9 -5
- package/src/lib/wallet-export-guard.test.ts +233 -0
- package/src/lib/wallet-export-guard.ts +1 -1
- package/src/lp/actions/liquidity.ts +53 -26
- package/src/lp/e2e/real-token-tests.ts +0 -1
- package/src/lp/e2e/scenarios.ts +1 -2
- package/src/lp/e2e/test-utils.ts +20 -7
- package/src/lp/lp-manager-entry.ts +2 -5
- package/src/lp/services/ConcentratedLiquidityService.ts +3 -10
- package/src/lp/services/DexInteractionService.ts +1 -2
- package/src/lp/services/LpManagementService.test.ts +0 -1
- package/src/lp/services/LpManagementService.ts +75 -35
- package/src/lp/services/UserLpProfileService.ts +2 -3
- package/src/lp/services/VaultService.ts +10 -4
- package/src/lp/services/YieldOptimizationService.ts +29 -13
- package/src/lp/services/__tests__/MockLpService.ts +1 -2
- package/src/lp/types.ts +9 -13
- package/src/lp/utils/solanaClient.ts +4 -2
- package/src/plugin.routes.test.ts +24 -0
- package/src/plugin.ts +30 -13
- package/src/providers/canonical-provider.ts +1 -1
- package/src/providers/{unified-wallet-provider.ts → wallet-provider.ts} +3 -3
- package/src/routes/__fixtures__/coingecko-markets.recorded.json +97 -0
- package/src/routes/wallet-market-overview-route.ts +1 -1
- package/src/routes/wallet-market-overview.contract.test.ts +139 -0
- package/src/routes/wallet-market-overview.real.test.ts +83 -0
- package/src/sdk/escrow/MutualStakeEscrow.ts +1 -2
- package/src/sdk/identity/erc8004.ts +1 -1
- package/src/sdk/identity/validation.ts +3 -4
- package/src/sdk/index.ts +2 -2
- package/src/sdk/policy/SpendingPolicy.ts +1 -1
- package/src/sdk/router/PaymentRouter.ts +8 -11
- package/src/sdk/swap/SwapModule.ts +1 -1
- package/src/sdk/tokens/registry.ts +1 -1
- package/src/sdk/x402/middleware.ts +2 -8
- package/src/security/__tests__/wallet-context-safety.test.ts +79 -0
- package/src/security/__tests__/wallet-financial-confirmation.test.ts +88 -0
- package/src/security/wallet-context-safety.ts +128 -0
- package/src/security/wallet-financial-confirmation.ts +150 -0
- package/src/services/wallet-backend-service.ts +15 -1
- package/src/utils/intent-trajectory.ts +2 -2
- package/src/wallet/steward-backend.ts +4 -4
- package/dist/LpManagementService-BWrQ5-cO.mjs +0 -353
- package/dist/MockLpService-D_Apn4Fd.mjs +0 -99
- package/dist/aerodrome-CfnESC32.mjs +0 -890
- package/dist/chunk-hT5z_Zn9.mjs +0 -35
- package/dist/lib/server-wallet-trade.d.mts +0 -34
- package/dist/lib/server-wallet-trade.mjs +0 -306
- package/dist/meteora-BPX39hZo.mjs +0 -22640
- package/dist/orca-Bybp1HXO.mjs +0 -249
- package/dist/pancakeswp-CkEXlXti.mjs +0 -604
- package/dist/plugin-ZO_MTyd0.mjs +0 -529
- package/dist/raydium-rfaM9yEf.mjs +0 -539
- package/dist/sdk/index.d.mts +0 -32492
- package/dist/sdk/index.mjs +0 -6415
- package/dist/types-D5252NZk.mjs +0 -487
- package/dist/uniswap-CReXgXVN.mjs +0 -573
- package/dist/wallet-action.d.mts +0 -6
- package/dist/wallet-action.mjs +0 -820
- package/src/analytics/birdeye/tasks/birdeye.ts +0 -232
- package/src/analytics/lpinfo/index.d.ts +0 -7
- package/src/chains/evm/contracts/artifacts/TimelockController.json +0 -1007
- package/src/chains/evm/contracts/artifacts/VoteToken.json +0 -895
- package/src/lp/tasks/LpAutoRebalanceTask.ts +0 -117
- package/src/lp/tasks/__tests__/LpAutoRebalanceTask.test.ts +0 -370
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/sdk/index.ts", "../src/sdk/abi.ts", "../src/sdk/wallet-core.ts", "../src/sdk/x402/budget.ts", "../src/sdk/x402/chains/abstract/index.ts", "../src/sdk/tokens/registry.ts", "../src/sdk/x402/types.ts", "../src/sdk/x402/multi-asset.ts", "../src/sdk/x402/client.ts", "../src/sdk/x402/middleware.ts", "../src/sdk/bridge/abis.ts", "../src/sdk/bridge/client.ts", "../src/sdk/bridge/types.ts", "../src/sdk/bridge/solana.ts", "../src/sdk/identity/erc8004.ts", "../src/sdk/identity/reputation.ts", "../src/sdk/identity/uaid.ts", "../src/sdk/identity/validation.ts", "../src/sdk/swap/abi.ts", "../src/sdk/swap/SwapModule.ts", "../src/sdk/swap/types.ts", "../src/sdk/convenience.ts", "../src/sdk/escrow/types.ts", "../src/sdk/escrow/verifiers.ts", "../src/sdk/escrow/MutualStakeEscrow.ts", "../src/sdk/policy/SpendingPolicy.ts", "../src/sdk/policy/UptoBillingPolicy.ts", "../src/sdk/router/PaymentRouter.ts", "../src/sdk/tokens/decimals.ts", "../src/sdk/tokens/solana.ts", "../src/sdk/tokens/transfers.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { JsonValue } from \"@elizaos/core\";\nimport {\n type Address,\n type Chain,\n createPublicClient,\n getContract,\n type Hash,\n type Hex,\n http,\n type WalletClient,\n} from \"viem\";\nimport { arbitrum, base, baseSepolia, mainnet, polygon } from \"viem/chains\";\nimport { AgentAccountFactoryV2Abi, AgentAccountV2Abi } from \"./abi.js\";\nimport type {\n ActivityEntry,\n BatchTransfer,\n BudgetForecast,\n ExecuteResult,\n PendingTx,\n QueuedEvent,\n WalletHealth,\n} from \"./types.js\";\nimport {\n NATIVE_TOKEN,\n requireWalletAccount,\n type AgentWallet as Wallet,\n} from \"./wallet-core.js\";\n\nexport { AgentAccountFactoryV2Abi, AgentAccountV2Abi } from \"./abi.js\";\nexport type {\n ActivityEntry,\n AgentWalletConfig,\n BatchTransfer,\n BudgetForecast,\n BudgetStatus,\n ExecuteResult,\n PendingTx,\n QueuedEvent,\n SpendPolicy,\n WalletHealth,\n} from \"./types.js\";\nexport {\n agentTransferToken,\n checkBudget,\n createWallet,\n NATIVE_TOKEN,\n requireWalletAccount,\n setSpendPolicy,\n} from \"./wallet-core.js\";\nexport type {\n X402ClientConfig,\n X402PaymentPayload,\n X402PaymentRequired,\n X402PaymentRequirements,\n X402ResourceInfo,\n X402ServiceBudget,\n X402SettlementResponse,\n X402TransactionLog,\n} from \"./x402/index.js\";\n// [MAX-ADDED] x402 protocol support\nexport {\n createX402Client,\n createX402Fetch,\n DEFAULT_SUPPORTED_NETWORKS,\n USDC_ADDRESSES,\n wrapWithX402,\n X402BudgetExceededError,\n X402BudgetTracker,\n X402Client,\n X402PaymentError,\n} from \"./x402/index.js\";\n\nconst CHAINS: Record<string, Chain> = {\n base,\n \"base-sepolia\": baseSepolia,\n ethereum: mainnet,\n arbitrum,\n polygon,\n};\n\n/**\n * Execute a transaction as the agent. If within limits, executes immediately.\n * If over limits, queues for owner approval and returns the pending tx ID.\n */\nexport async function agentExecute(\n wallet: Wallet,\n params: { to: Address; value?: bigint; data?: Hex },\n): Promise<ExecuteResult> {\n const value = params.value ?? 0n;\n const data = params.data ?? \"0x\";\n\n const hash = await wallet.contract.write.agentExecute(\n [params.to, value, data],\n {\n value,\n account: requireWalletAccount(wallet.walletClient),\n chain: wallet.chain,\n },\n );\n\n // Check the tx receipt for TransactionQueued vs TransactionExecuted events\n const receipt = await wallet.publicClient.waitForTransactionReceipt({ hash });\n\n // Event topic hash for AgentAccountV2 queue detection\n const QUEUED_TOPIC =\n \"0x338e4b9b04df0b67a953d7ea6a7037128b8c6948e3d8c09a9d51a5f5be6c2284\";\n\n const walletAddr = wallet.address.toLowerCase();\n const queuedLog = receipt.logs.find(\n (log) =>\n log.address.toLowerCase() === walletAddr &&\n log.topics[0] === QUEUED_TOPIC,\n );\n\n const wasExecuted = !queuedLog;\n\n return {\n executed: wasExecuted,\n txHash: hash,\n };\n}\n\n/**\n * Get a pending transaction by ID.\n */\nexport async function getPendingApprovals(\n wallet: Wallet,\n fromId: bigint = 0n,\n toId?: bigint,\n): Promise<PendingTx[]> {\n const maxId = toId ?? (await wallet.contract.read.pendingNonce());\n const results: PendingTx[] = [];\n\n for (let i = fromId; i < maxId; i++) {\n const [to, value, token, amount, createdAt, executed, cancelled] =\n await wallet.contract.read.getPending([i]);\n\n if (!executed && !cancelled && createdAt > 0n) {\n results.push({\n txId: i,\n to,\n value,\n data: \"0x\", // data not returned by getPending view\n token,\n amount,\n createdAt: Number(createdAt),\n executed,\n cancelled,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Approve a pending transaction. Only callable by the NFT owner.\n */\nexport async function approveTransaction(\n wallet: Wallet,\n txId: bigint,\n): Promise<Hash> {\n return wallet.contract.write.approvePending([txId], {\n account: requireWalletAccount(wallet.walletClient),\n chain: wallet.chain,\n });\n}\n\n/**\n * Cancel a pending transaction. Only callable by the NFT owner.\n */\nexport async function cancelTransaction(\n wallet: Wallet,\n txId: bigint,\n): Promise<Hash> {\n return wallet.contract.write.cancelPending([txId], {\n account: requireWalletAccount(wallet.walletClient),\n chain: wallet.chain,\n });\n}\n\n/**\n * Add or remove an operator (agent hot wallet).\n */\nexport async function setOperator(\n wallet: Wallet,\n operator: Address,\n authorized: boolean,\n): Promise<Hash> {\n return wallet.contract.write.setOperator([operator, authorized], {\n account: requireWalletAccount(wallet.walletClient),\n chain: wallet.chain,\n });\n}\n\n// ─── Factory: Deploy New Wallets ───\n\n/**\n * Deploy a new AgentAccountV2 wallet via the factory (CREATE2).\n * Returns the deterministic wallet address.\n */\nexport async function deployWallet(config: {\n factoryAddress: Address;\n tokenContract: Address;\n tokenId: bigint;\n chain: keyof typeof CHAINS;\n rpcUrl?: string;\n walletClient: WalletClient;\n}): Promise<{ walletAddress: Address; txHash: Hash }> {\n const chain = CHAINS[config.chain];\n if (!chain) throw new Error(`Unsupported chain: ${config.chain}`);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(config.rpcUrl),\n });\n\n const factory = getContract({\n address: config.factoryAddress,\n abi: AgentAccountFactoryV2Abi,\n client: { public: publicClient, wallet: config.walletClient },\n });\n\n // Get deterministic address first\n const walletAddress = (await factory.read.getAddress([\n config.tokenContract,\n config.tokenId,\n ])) as Address;\n\n // Deploy\n const txHash = await factory.write.createAccount(\n [config.tokenContract, config.tokenId],\n { account: requireWalletAccount(config.walletClient), chain },\n );\n\n return { walletAddress, txHash };\n}\n\n/**\n * Compute the deterministic wallet address without deploying.\n */\nexport async function getWalletAddress(config: {\n factoryAddress: Address;\n tokenContract: Address;\n tokenId: bigint;\n chain: string;\n rpcUrl?: string;\n}): Promise<Address> {\n const chain = CHAINS[config.chain];\n if (!chain) throw new Error(`Unsupported chain: ${config.chain}`);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(config.rpcUrl),\n });\n\n const factory = getContract({\n address: config.factoryAddress,\n abi: AgentAccountFactoryV2Abi,\n client: publicClient,\n });\n\n return factory.read.getAddress([\n config.tokenContract,\n config.tokenId,\n ]) as Promise<Address>;\n}\n\n// ─── [MAX-ADDED] Value-Add Features for Agent Customers ───\n\n/**\n * [MAX-ADDED] Budget forecast with period-aware remaining capacity.\n * Why: Agents need to know not just \"how much is left\" but \"when does budget reset\"\n * so they can plan spending across time windows and avoid unnecessary queuing.\n */\nexport async function getBudgetForecast(\n wallet: Wallet,\n token: Address = NATIVE_TOKEN,\n now?: number,\n): Promise<BudgetForecast> {\n const [perTxLimit, remainingInPeriod] =\n await wallet.contract.read.remainingBudget([token]);\n const [_policyPerTx, periodLimit, periodLength, periodSpent, periodStart] =\n await wallet.contract.read.spendPolicies([token]);\n\n const currentTime = now ?? Math.floor(Date.now() / 1000);\n const periodEnd = Number(periodStart) + Number(periodLength);\n const secondsUntilReset = Math.max(0, periodEnd - currentTime);\n const utilizationPercent =\n periodLimit > 0n ? Number((periodSpent * 100n) / periodLimit) : 0;\n\n return {\n token,\n perTxLimit,\n remainingInPeriod,\n periodLimit,\n periodLength: Number(periodLength),\n periodSpent,\n periodStart: Number(periodStart),\n secondsUntilReset,\n utilizationPercent,\n };\n}\n\n/**\n * [MAX-ADDED] Wallet health check — diagnostic snapshot for agent self-monitoring.\n * Why: Agents need a single-call way to verify their wallet is properly configured,\n * check operator status, and monitor queue depth before executing transactions.\n */\nexport async function getWalletHealth(\n wallet: Wallet,\n operatorsToCheck: Address[] = [],\n tokensToCheck: Address[] = [NATIVE_TOKEN],\n now?: number,\n): Promise<WalletHealth> {\n // Read wallet identity\n const [tokenContract, tokenId, operatorEpoch] = await Promise.all([\n wallet.contract.read.tokenContract(),\n wallet.contract.read.tokenId(),\n wallet.contract.read.operatorEpoch(),\n ]);\n\n // Check operator status\n const activeOperators = await Promise.all(\n operatorsToCheck.map(async (addr) => ({\n address: addr,\n active: (await wallet.contract.read.isOperatorActive([addr])) as boolean,\n })),\n );\n\n // Count pending queue depth\n const pendingNonce = (await wallet.contract.read.pendingNonce()) as bigint;\n let pendingQueueDepth = 0;\n for (let i = 0n; i < pendingNonce; i++) {\n const [, , , , createdAt, executed, cancelled] =\n await wallet.contract.read.getPending([i]);\n if (!executed && !cancelled && createdAt > 0n) pendingQueueDepth++;\n }\n\n // Budget forecasts for requested tokens\n const budgets = await Promise.all(\n tokensToCheck.map((t) => getBudgetForecast(wallet, t, now)),\n );\n\n return {\n address: wallet.address,\n tokenContract: tokenContract as Address,\n tokenId: tokenId as bigint,\n operatorEpoch: operatorEpoch as bigint,\n activeOperators,\n pendingQueueDepth,\n budgets,\n };\n}\n\n/**\n * [MAX-ADDED] Batch agent token transfers — multiple transfers in sequential calls.\n * Why: Agents often need to pay multiple recipients (tips, fees, splits). This helper\n * reduces boilerplate and returns all tx hashes. Each is a separate on-chain tx\n * (true batching would need a multicall contract, but this is the safe SDK-level helper).\n */\nexport async function batchAgentTransfer(\n wallet: Wallet,\n transfers: BatchTransfer[],\n): Promise<Hash[]> {\n const hashes: Hash[] = [];\n for (const t of transfers) {\n const hash = await wallet.contract.write.agentTransferToken(\n [t.token, t.to, t.amount],\n {\n account: requireWalletAccount(wallet.walletClient),\n chain: wallet.chain,\n },\n );\n hashes.push(hash);\n }\n return hashes;\n}\n\n/**\n * [MAX-ADDED] Activity history — query past wallet events for self-auditing.\n * Why: Agents need to verify what happened on-chain (transfers, operator changes,\n * policy updates) without relying on external indexers. This queries event logs directly.\n */\nexport async function getActivityHistory(\n wallet: Wallet,\n options: { fromBlock?: bigint; toBlock?: bigint | \"latest\" } = {},\n): Promise<ActivityEntry[]> {\n const fromBlock = options.fromBlock ?? 0n;\n const toBlock = options.toBlock ?? (\"latest\" as const);\n\n const eventConfigs = [\n { eventName: \"TransactionExecuted\" as const, type: \"execution\" as const },\n { eventName: \"TransactionQueued\" as const, type: \"queued\" as const },\n { eventName: \"TransactionApproved\" as const, type: \"approved\" as const },\n { eventName: \"TransactionCancelled\" as const, type: \"cancelled\" as const },\n {\n eventName: \"SpendPolicyUpdated\" as const,\n type: \"policy_update\" as const,\n },\n { eventName: \"OperatorUpdated\" as const, type: \"operator_update\" as const },\n ];\n\n const allEntries: ActivityEntry[] = [];\n\n for (const { eventName, type } of eventConfigs) {\n const logs = await wallet.publicClient.getContractEvents({\n address: wallet.address,\n abi: AgentAccountV2Abi,\n eventName,\n fromBlock,\n toBlock,\n });\n\n for (const log of logs) {\n const rawArgs =\n log && typeof log === \"object\" && \"args\" in log\n ? (log as { args?: Record<string, JsonValue> }).args\n : undefined;\n allEntries.push({\n type,\n blockNumber: log.blockNumber,\n transactionHash: log.transactionHash,\n args: rawArgs ?? {},\n });\n }\n }\n\n // Sort by block number ascending\n allEntries.sort((a, b) => Number(a.blockNumber - b.blockNumber));\n return allEntries;\n}\n\n// ─── Event Listeners ───\n\n/**\n * Watch for TransactionQueued events (over-limit transactions needing approval).\n * Returns an unwatch function.\n */\nexport function onTransactionQueued(\n wallet: Wallet,\n callback: (event: QueuedEvent) => void,\n): () => void {\n return wallet.publicClient.watchContractEvent({\n address: wallet.address,\n abi: AgentAccountV2Abi,\n eventName: \"TransactionQueued\",\n onLogs: (logs) => {\n for (const log of logs) {\n const args =\n log && typeof log === \"object\" && \"args\" in log\n ? (\n log as {\n args?: {\n txId?: bigint;\n to?: Address;\n value?: bigint;\n token?: Address;\n amount?: bigint;\n };\n }\n ).args\n : undefined;\n if (\n !args ||\n args.txId === undefined ||\n args.to === undefined ||\n args.value === undefined ||\n args.token === undefined ||\n args.amount === undefined ||\n !log.transactionHash\n ) {\n continue;\n }\n callback({\n txId: args.txId,\n to: args.to,\n value: args.value,\n token: args.token,\n amount: args.amount,\n blockNumber: log.blockNumber,\n transactionHash: log.transactionHash,\n });\n }\n },\n });\n}\n\n/**\n * Watch for TransactionExecuted events.\n */\nexport function onTransactionExecuted(\n wallet: Wallet,\n callback: (event: {\n target: Address;\n value: bigint;\n executor: Address;\n transactionHash: Hash;\n }) => void,\n): () => void {\n return wallet.publicClient.watchContractEvent({\n address: wallet.address,\n abi: AgentAccountV2Abi,\n eventName: \"TransactionExecuted\",\n onLogs: (logs) => {\n for (const log of logs) {\n const args =\n log && typeof log === \"object\" && \"args\" in log\n ? (\n log as {\n args?: {\n target?: Address;\n value?: bigint;\n executor?: Address;\n };\n }\n ).args\n : undefined;\n const transactionHash = log.transactionHash;\n if (\n !args ||\n args.target === undefined ||\n args.value === undefined ||\n args.executor === undefined ||\n !transactionHash\n ) {\n continue;\n }\n callback({\n target: args.target,\n value: args.value,\n executor: args.executor,\n transactionHash,\n });\n }\n },\n });\n}\n\nexport type {\n BridgeChain,\n BridgeOptions,\n BridgeResult,\n BurnResult,\n} from \"./bridge/index.js\";\n// ─── CCTP V2 Cross-Chain Bridge ─────────────────────────────────────────────\nexport {\n BRIDGE_CHAIN_IDS,\n BridgeError,\n BridgeModule,\n CCTP_DOMAIN_IDS,\n createBridge,\n ERC20BridgeAbi,\n FINALITY_THRESHOLD,\n MESSAGE_TRANSMITTER_V2,\n MessageTransmitterV2Abi,\n TOKEN_MESSENGER_V2,\n TokenMessengerV2Abi,\n USDC_CONTRACT,\n} from \"./bridge/index.js\";\nexport type {\n AgentIdentity,\n AgentModelMetadata,\n AgentRegistrationFile,\n AgentRegistrationRef,\n AgentServiceEndpoint,\n ERC8004ClientConfig,\n MetadataEntry,\n RegistrationResult,\n SupportedChain,\n SupportedTrustMechanism,\n} from \"./identity/erc8004.js\";\n// ─── ERC-8004: Trustless Agents — Identity Registry ─────────────────────────\nexport {\n buildDataURI,\n ERC8004Client,\n ERC8004IdentityRegistryAbi,\n formatAgentRegistry,\n KNOWN_REGISTRY_ADDRESSES,\n METADATA_KEYS,\n parseDataURI,\n REGISTRATION_FILE_TYPE,\n resolveAgentURI,\n validateRegistrationFile,\n} from \"./identity/erc8004.js\";\nexport type {\n AgentReputationSummary,\n FeedbackEntry,\n FeedbackFilters,\n GiveFeedbackParams,\n ReputationClientConfig,\n RespondToFeedbackParams,\n} from \"./identity/reputation.js\";\n// ─── ERC-8004: Reputation Registry ─────────────────────────────────────────\nexport {\n ReputationClient,\n ReputationRegistryAbi,\n} from \"./identity/reputation.js\";\nexport type {\n ParsedUAID,\n RegisterUAIDParams,\n UAIDProtocol,\n UAIDResolution,\n UAIDResolverConfig,\n UniversalAgentIdentity,\n} from \"./identity/uaid.js\";\n// ─── UAID: Cross-Chain Identity Resolution (HOL Registry Broker) ────────────\nexport { UAIDResolver } from \"./identity/uaid.js\";\nexport type {\n RequestValidationParams,\n RespondToValidationParams,\n ValidationClientConfig,\n ValidationStatus,\n ValidationSummary,\n} from \"./identity/validation.js\";\n// ─── ERC-8004: Validation Registry ─────────────────────────────────────────\nexport {\n ValidationClient,\n ValidationRegistryAbi,\n} from \"./identity/validation.js\";\nexport type {\n SwapModuleConfig,\n SwapOptions,\n SwapQuote,\n SwapResult,\n UniswapFeeTier,\n} from \"./swap/index.js\";\n// ─── SwapModule — Uniswap V3 token swap aggregator ──────────────────────────\nexport {\n applySlippage,\n attachSwap,\n BASE_TOKENS,\n calcDeadline,\n calcProtocolFee,\n DEFAULT_SLIPPAGE_BPS,\n ERC20Abi,\n PROTOCOL_FEE_BPS,\n PROTOCOL_FEE_COLLECTOR,\n SwapModule,\n UniswapV3QuoterV2Abi,\n UniswapV3RouterAbi,\n} from \"./swap/index.js\";\n\n// x402 already exported above from original index.ts\n\n// ─── Convenience: env-variable-driven wallet bootstrap ──────────────────────\nexport {\n setPolicyFromEnv,\n walletFromEnv,\n x402FromEnv,\n} from \"./convenience.js\";\n// ─── Mutual Stake Escrow ─────────────────────────────────────────────────────\nexport { MutualStakeEscrow } from \"./escrow/MutualStakeEscrow.js\";\nexport type {\n CreateEscrowParams,\n EscrowCreated,\n EscrowDetails,\n TxResult as EscrowTxResult,\n} from \"./escrow/types.js\";\nexport { TaskStatus } from \"./escrow/types.js\";\nexport {\n encodeHashVerifierData,\n encodeOptimisticVerifierData,\n resolveVerifierAddress,\n VERIFIER_ADDRESSES,\n} from \"./escrow/verifiers.js\";\nexport type {\n AuditEntry,\n DraftEntry,\n PaymentIntent,\n PolicyResult,\n PolicyStatus,\n SpendingPolicyConfig,\n} from \"./policy/SpendingPolicy.js\";\n// ─── SpendingPolicy — Programmable spending guardrails ───────────────────────\nexport { SpendingPolicy } from \"./policy/SpendingPolicy.js\";\nexport type {\n UptoAuthorizationRecord,\n UptoAuthorizationRequest,\n UptoAuthorizationStatus,\n UptoBillingSnapshot,\n UptoSettlementOptions,\n UptoSettlementRecord,\n WalletLedgerDelta,\n} from \"./policy/UptoBillingPolicy.js\";\n// ─── UptoBillingPolicy — x402 usage-based settlement accounting ─────────────\nexport { UptoBillingPolicy } from \"./policy/UptoBillingPolicy.js\";\n\n// ─── v6: Multi-Token Support ─────────────────────────────────────────────────\n\nexport type {\n PaymentContext,\n PaymentRail,\n RailConfig,\n RailStatus,\n RoutingDecision,\n} from \"./router/index.js\";\n// ─── Payment Router ───────────────────────────────────────────────────────────\nexport { PaymentRouter } from \"./router/index.js\";\nexport type { TokenInfo } from \"./tokens/decimals.js\";\n// Token decimal normalization\nexport {\n formatBalance,\n parseAmount,\n toHuman,\n toRaw,\n} from \"./tokens/decimals.js\";\nexport type { AddTokenParams, TokenEntry } from \"./tokens/registry.js\";\n// TokenRegistry — pre-populated multi-chain token address registry\nexport {\n ARBITRUM_REGISTRY,\n AVALANCHE_REGISTRY,\n BASE_REGISTRY,\n BASE_SEPOLIA_REGISTRY,\n ETHEREUM_REGISTRY,\n getGlobalRegistry,\n getNativeToken,\n LINEA_REGISTRY,\n OPTIMISM_REGISTRY,\n POLYGON_REGISTRY,\n SONIC_REGISTRY,\n TokenRegistry,\n UNICHAIN_REGISTRY,\n WORLDCHAIN_REGISTRY,\n} from \"./tokens/registry.js\";\nexport type {\n SolanaTokenInfo,\n SolanaTokenSymbol,\n SolanaTxResult,\n SolanaWalletConfig,\n SolBalanceResult,\n SplBalanceResult,\n} from \"./tokens/solana.js\";\n// Solana SPL token support (optional peer dependency: @solana/web3.js)\nexport {\n createSolanaWallet,\n SOLANA_TOKEN_DECIMALS,\n SOLANA_TOKENS,\n SolanaWallet,\n} from \"./tokens/solana.js\";\nexport type {\n NativeBalanceResult,\n TokenBalanceResult,\n TransferContext,\n TransferOptions,\n} from \"./tokens/transfers.js\";\n// Multi-token EVM transfers (direct EOA/hot-wallet operations)\nexport {\n encodeERC20Transfer,\n getBalances,\n getNativeBalance,\n getTokenBalance,\n sendNative,\n sendToken,\n} from \"./tokens/transfers.js\";\n// x402 multi-asset resolution (v6 additions)\nexport {\n buildSupportedAssets,\n isStablecoin,\n parseNetworkChainId,\n resolveAssetAddress,\n resolveAssetDecimals,\n} from \"./x402/multi-asset.js\";\n",
|
|
6
|
+
"export const AgentAccountV2Abi = [\n // ─── Owner Functions ───\n {\n name: \"setSpendPolicy\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"token\", type: \"address\" },\n { name: \"perTxLimit\", type: \"uint256\" },\n { name: \"periodLimit\", type: \"uint256\" },\n { name: \"periodLength\", type: \"uint256\" },\n ],\n outputs: [],\n },\n {\n name: \"setOperator\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"operator\", type: \"address\" },\n { name: \"authorized\", type: \"bool\" },\n ],\n outputs: [],\n },\n {\n name: \"execute\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n ],\n outputs: [{ name: \"\", type: \"bytes\" }],\n },\n {\n name: \"approvePending\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"txId\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"cancelPending\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"txId\", type: \"uint256\" }],\n outputs: [],\n },\n\n // ─── Agent Functions ───\n {\n name: \"agentExecute\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n ],\n outputs: [{ name: \"\", type: \"bytes\" }],\n },\n {\n name: \"agentTransferToken\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"token\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [],\n },\n\n // ─── View Functions ───\n {\n name: \"remainingBudget\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"token\", type: \"address\" }],\n outputs: [\n { name: \"perTx\", type: \"uint256\" },\n { name: \"inPeriod\", type: \"uint256\" },\n ],\n },\n {\n name: \"getPending\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"txId\", type: \"uint256\" }],\n outputs: [\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n { name: \"createdAt\", type: \"uint256\" },\n { name: \"executed\", type: \"bool\" },\n { name: \"cancelled\", type: \"bool\" },\n ],\n },\n {\n name: \"spendPolicies\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"token\", type: \"address\" }],\n outputs: [\n { name: \"perTxLimit\", type: \"uint256\" },\n { name: \"periodLimit\", type: \"uint256\" },\n { name: \"periodLength\", type: \"uint256\" },\n { name: \"periodSpent\", type: \"uint256\" },\n { name: \"periodStart\", type: \"uint256\" },\n ],\n },\n {\n name: \"operators\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"operator\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"pendingNonce\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"nonce\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n // [MAX-ADDED] ABI entries for wallet health check & activity history\n {\n name: \"tokenContract\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"tokenId\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"operatorEpoch\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"isOperatorActive\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"operator\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n\n // ─── Events ───\n {\n name: \"TransactionExecuted\",\n type: \"event\",\n inputs: [\n { name: \"target\", type: \"address\", indexed: true },\n { name: \"value\", type: \"uint256\", indexed: false },\n { name: \"data\", type: \"bytes\", indexed: false },\n { name: \"executor\", type: \"address\", indexed: true },\n ],\n },\n {\n name: \"SpendPolicyUpdated\",\n type: \"event\",\n inputs: [\n { name: \"token\", type: \"address\", indexed: true },\n { name: \"perTxLimit\", type: \"uint256\", indexed: false },\n { name: \"periodLimit\", type: \"uint256\", indexed: false },\n { name: \"periodLength\", type: \"uint256\", indexed: false },\n ],\n },\n {\n name: \"OperatorUpdated\",\n type: \"event\",\n inputs: [\n { name: \"operator\", type: \"address\", indexed: true },\n { name: \"authorized\", type: \"bool\", indexed: false },\n ],\n },\n {\n name: \"TransactionQueued\",\n type: \"event\",\n inputs: [\n { name: \"txId\", type: \"uint256\", indexed: true },\n { name: \"to\", type: \"address\", indexed: true },\n { name: \"value\", type: \"uint256\", indexed: false },\n { name: \"token\", type: \"address\", indexed: false },\n { name: \"amount\", type: \"uint256\", indexed: false },\n ],\n },\n {\n name: \"TransactionApproved\",\n type: \"event\",\n inputs: [{ name: \"txId\", type: \"uint256\", indexed: true }],\n },\n {\n name: \"TransactionCancelled\",\n type: \"event\",\n inputs: [{ name: \"txId\", type: \"uint256\", indexed: true }],\n },\n] as const;\n\nexport const AgentAccountFactoryV2Abi = [\n {\n name: \"createAccount\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"tokenContract\", type: \"address\" },\n { name: \"tokenId\", type: \"uint256\" },\n ],\n outputs: [{ name: \"wallet\", type: \"address\" }],\n },\n {\n name: \"getAddress\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"tokenContract\", type: \"address\" },\n { name: \"tokenId\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"wallets\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"tokenContract\", type: \"address\" },\n { name: \"tokenId\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"WalletCreated\",\n type: \"event\",\n inputs: [\n { name: \"wallet\", type: \"address\", indexed: true },\n { name: \"tokenContract\", type: \"address\", indexed: true },\n { name: \"tokenId\", type: \"uint256\", indexed: true },\n { name: \"deployer\", type: \"address\", indexed: false },\n ],\n },\n] as const;\n",
|
|
7
|
+
"import {\n type Address,\n type Chain,\n createPublicClient,\n getContract,\n type Hash,\n http,\n type WalletClient,\n zeroAddress,\n} from \"viem\";\nimport { arbitrum, base, baseSepolia, mainnet, polygon } from \"viem/chains\";\nimport { AgentAccountV2Abi } from \"./abi.js\";\nimport type { AgentWalletConfig, BudgetStatus, SpendPolicy } from \"./types.js\";\n\nconst CHAINS: Record<string, Chain> = {\n base,\n \"base-sepolia\": baseSepolia,\n ethereum: mainnet,\n arbitrum,\n polygon,\n};\n\n/** Asserts the viem wallet client has a selected account (required for writes). */\nexport function requireWalletAccount(client: WalletClient) {\n const { account } = client;\n if (!account) {\n throw new Error(\"WalletClient.account is required for this operation\");\n }\n return account;\n}\n\n/** Native ETH token address (zero address) */\nexport const NATIVE_TOKEN: Address = zeroAddress;\n\n/**\n * Create a wallet client connected to an existing AgentAccountV2.\n */\nexport function createWallet(\n config: AgentWalletConfig & { walletClient: WalletClient },\n) {\n const chain = CHAINS[config.chain];\n if (!chain) throw new Error(`Unsupported chain: ${config.chain}`);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(config.rpcUrl),\n });\n\n const contract = getContract({\n address: config.accountAddress,\n abi: AgentAccountV2Abi,\n client: { public: publicClient, wallet: config.walletClient },\n });\n\n return {\n address: config.accountAddress,\n contract,\n publicClient,\n walletClient: config.walletClient,\n chain,\n };\n}\n\nexport type AgentWallet = ReturnType<typeof createWallet>;\n\n/**\n * Set a spend policy for a token. Only callable by the NFT owner.\n * Use NATIVE_TOKEN (address(0)) for native ETH.\n */\nexport async function setSpendPolicy(\n wallet: AgentWallet,\n policy: SpendPolicy,\n): Promise<Hash> {\n const periodLength = policy.periodLength || 86400;\n\n const hash = await wallet.contract.write.setSpendPolicy(\n [policy.token, policy.perTxLimit, policy.periodLimit, BigInt(periodLength)],\n { account: requireWalletAccount(wallet.walletClient), chain: wallet.chain },\n );\n\n return hash;\n}\n\n/**\n * Check remaining autonomous budget for a token.\n */\nexport async function checkBudget(\n wallet: AgentWallet,\n token: Address = NATIVE_TOKEN,\n): Promise<BudgetStatus> {\n const [perTxLimit, remainingInPeriod] =\n await wallet.contract.read.remainingBudget([token]);\n\n return {\n token,\n perTxLimit,\n remainingInPeriod,\n };\n}\n\n/**\n * Transfer ERC20 tokens as the agent, respecting spend limits.\n */\nexport async function agentTransferToken(\n wallet: AgentWallet,\n params: { token: Address; to: Address; amount: bigint },\n): Promise<Hash> {\n return wallet.contract.write.agentTransferToken(\n [params.token, params.to, params.amount],\n {\n account: requireWalletAccount(wallet.walletClient),\n chain: wallet.chain,\n },\n );\n}\n",
|
|
8
|
+
"// [MAX-ADDED] x402 Budget Controls — per-service spending caps and transaction logging\n// viem types imported on-demand within class methods\nimport type {\n X402ClientConfig,\n X402ServiceBudget,\n X402TransactionLog,\n} from \"./types.js\";\n\n/**\n * [MAX-ADDED] In-memory budget tracker for x402 payments.\n * Enforces per-service caps, daily limits, and per-request maximums.\n * On-chain spend limits are ALSO enforced by the AgentWallet contract —\n * this is an additional client-side layer for granular service-level control.\n */\nexport class X402BudgetTracker {\n private serviceBudgets: Map<string, X402ServiceBudget> = new Map();\n private dailySpend: Map<string, bigint> = new Map(); // service -> today's total\n private globalDailySpend: bigint = 0n;\n private dailyResetTimestamp: number;\n private transactionLog: X402TransactionLog[] = [];\n\n private globalDailyLimit: bigint;\n private globalPerRequestMax: bigint;\n\n constructor(config: X402ClientConfig = {}) {\n this.globalDailyLimit =\n config.globalDailyLimit ?? BigInt(\"0xFFFFFFFFFFFFFFFFFFFFFFFF\"); // effectively unlimited\n this.globalPerRequestMax =\n config.globalPerRequestMax ?? BigInt(\"0xFFFFFFFFFFFFFFFFFFFFFFFF\");\n this.dailyResetTimestamp = this.startOfDay();\n\n if (config.serviceBudgets) {\n for (const budget of config.serviceBudgets) {\n this.serviceBudgets.set(budget.service, budget);\n }\n }\n }\n\n /**\n * Check if a payment is within budget limits.\n * Returns { allowed: true } or { allowed: false, reason: string }.\n */\n checkBudget(\n service: string,\n amount: bigint,\n ): { allowed: boolean; reason?: string } {\n this.maybeResetDaily();\n\n // Global per-request check\n if (amount > this.globalPerRequestMax) {\n return {\n allowed: false,\n reason: `Amount ${amount} exceeds global per-request max ${this.globalPerRequestMax}`,\n };\n }\n\n // Global daily check\n if (this.globalDailySpend + amount > this.globalDailyLimit) {\n return {\n allowed: false,\n reason: `Would exceed global daily limit ${this.globalDailyLimit}`,\n };\n }\n\n // Service-specific checks\n const budget = this.findServiceBudget(service);\n if (budget) {\n if (amount > budget.maxPerRequest) {\n return {\n allowed: false,\n reason: `Amount ${amount} exceeds service per-request max ${budget.maxPerRequest} for ${service}`,\n };\n }\n const serviceDailySpend = this.dailySpend.get(service) ?? 0n;\n if (serviceDailySpend + amount > budget.dailyLimit) {\n return {\n allowed: false,\n reason: `Would exceed daily limit ${budget.dailyLimit} for ${service}`,\n };\n }\n }\n\n return { allowed: true };\n }\n\n /**\n * Record a completed payment.\n */\n recordPayment(log: X402TransactionLog): void {\n this.maybeResetDaily();\n this.transactionLog.push(log);\n\n if (log.success) {\n const service = log.service;\n this.dailySpend.set(\n service,\n (this.dailySpend.get(service) ?? 0n) + log.amount,\n );\n this.globalDailySpend += log.amount;\n }\n }\n\n /**\n * Get transaction history, optionally filtered.\n */\n getTransactionLog(filter?: {\n service?: string;\n since?: number;\n }): X402TransactionLog[] {\n let logs = this.transactionLog;\n if (filter?.service) {\n logs = logs.filter((l) => l.service === filter.service);\n }\n if (filter?.since !== undefined) {\n const since = filter.since;\n logs = logs.filter((l) => l.timestamp >= since);\n }\n return logs;\n }\n\n /**\n * Get current daily spend summary.\n */\n getDailySpendSummary(): {\n global: bigint;\n byService: Record<string, bigint>;\n resetsAt: number;\n } {\n this.maybeResetDaily();\n const byService: Record<string, bigint> = {};\n for (const [service, amount] of this.dailySpend) {\n byService[service] = amount;\n }\n return {\n global: this.globalDailySpend,\n byService,\n resetsAt: this.dailyResetTimestamp + 86400,\n };\n }\n\n /**\n * Add or update a service budget at runtime.\n */\n setServiceBudget(budget: X402ServiceBudget): void {\n this.serviceBudgets.set(budget.service, budget);\n }\n\n // ─── Internals ───\n\n private findServiceBudget(service: string): X402ServiceBudget | undefined {\n // Exact match first, then wildcard\n return this.serviceBudgets.get(service) ?? this.serviceBudgets.get(\"*\");\n }\n\n private maybeResetDaily(): void {\n const now = this.startOfDay();\n if (now > this.dailyResetTimestamp) {\n this.dailySpend.clear();\n this.globalDailySpend = 0n;\n this.dailyResetTimestamp = now;\n }\n }\n\n private startOfDay(): number {\n const now = Math.floor(Date.now() / 1000);\n return now - (now % 86400);\n }\n}\n",
|
|
9
|
+
"/**\n * Abstract x402 Delegated Payment Facilitator Adapter\n *\n * Abstract's x402 implementation uses a delegated facilitator pattern:\n * 1. The agent wallet does NOT sign the payment tx directly\n * 2. A \"payment facilitator\" contract is designated per-merchant\n * 3. The agent's wallet delegates authorization via a signed EIP-712 permit\n * 4. The facilitator executes the actual chain transaction\n *\n * Chain IDs:\n * - Abstract Mainnet: 2741\n * - Abstract Testnet: 11124\n */\n\nimport type { Address, Hex, WalletClient } from \"viem\";\nimport { encodeAbiParameters, parseAbiParameters } from \"viem\";\n\n// ─── Abstract Chain Constants ────────────────────────────────────────────────\n\nexport const ABSTRACT_CHAIN_IDS = {\n mainnet: 2741,\n testnet: 11124,\n} as const;\n\n/** USDC on Abstract Mainnet (official Bridged USDC) */\nexport const ABSTRACT_USDC: Record<number, Address> = {\n 2741: \"0x84A71ccD554Cc1b02749b35d22F684CC8ec987e1\", // Abstract Mainnet USDC\n 11124: \"0x3eBdeaA0DB3FfDe96E7a0DBBAFEC961FC50F725f\", // Abstract Testnet USDC\n};\n\n/** Abstract's approved payment facilitator contracts */\nexport const ABSTRACT_APPROVED_FACILITATORS: Address[] = [\n \"0x5FbDB2315678afecb367f032d93F642f64180aa3\", // Abstract official facilitator (mainnet)\n];\n\n// ─── EIP-712 Types for Abstract Delegated Payment ───────────────────────────\n\nconst ABSTRACT_PERMIT_DOMAIN = {\n name: \"AbstractDelegatedPayment\",\n version: \"1\",\n chainId: ABSTRACT_CHAIN_IDS.mainnet,\n} as const;\n\nconst ABSTRACT_PERMIT_TYPES = {\n DelegatedPaymentPermit: [\n { name: \"facilitator\", type: \"address\" },\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n { name: \"payTo\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n { name: \"resource\", type: \"string\" },\n ],\n} as const;\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface AbstractDelegatedPaymentConfig {\n /** The facilitator contract address (must be on approved list or user-allowlisted) */\n facilitatorAddress: Address;\n /** Token to pay with (default: USDC on Abstract) */\n token?: Address;\n /** Permit deadline in seconds from now (default: 300 = 5 min) */\n deadlineSeconds?: number;\n /** User-allowlisted facilitator addresses (extends the approved list) */\n userAllowlist?: Address[];\n}\n\nexport interface DelegatedPaymentPermit {\n facilitator: Address;\n token: Address;\n amount: bigint;\n payTo: Address;\n nonce: bigint;\n deadline: bigint;\n resource: string;\n}\n\nexport interface AbstractPaymentResult {\n /** EIP-712 signature for the facilitator permit */\n permitSignature: Hex;\n /** Encoded permit data to submit to the facilitator contract */\n permitData: Hex;\n /** The permit fields for verification */\n permit: DelegatedPaymentPermit;\n /** Chain ID this payment is valid on */\n chainId: number;\n}\n\n// ─── AbstractDelegatedFacilitatorAdapter ─────────────────────────────────────\n\n/**\n * Adapter for Abstract's delegated payment facilitator x402 model.\n *\n * Instead of signing a direct payment transaction, the agent signs an EIP-712\n * permit authorizing a facilitator contract to execute the payment on its behalf.\n * This is Abstract's model — the agent's keys never touch the chain directly.\n *\n * @example\n * ```typescript\n * const adapter = new AbstractDelegatedFacilitatorAdapter(walletClient, {\n * facilitatorAddress: '0x5FbDB2315678afecb367f032d93F642f64180aa3',\n * });\n *\n * const result = await adapter.signPaymentPermit({\n * amount: 1_000_000n, // 1 USDC (6 decimals)\n * payTo: '0xmerchant...',\n * nonce: 0n,\n * resource: 'https://api.example.com/resource',\n * });\n * ```\n */\nexport class AbstractDelegatedFacilitatorAdapter {\n private walletClient: WalletClient;\n private config: Required<AbstractDelegatedPaymentConfig>;\n private chainId: number;\n\n constructor(\n walletClient: WalletClient,\n config: AbstractDelegatedPaymentConfig,\n chainId: number = ABSTRACT_CHAIN_IDS.mainnet,\n ) {\n this.walletClient = walletClient;\n this.chainId = chainId;\n\n // Validate facilitator\n const approved = [\n ...ABSTRACT_APPROVED_FACILITATORS,\n ...(config.userAllowlist ?? []),\n ];\n const isApproved = approved.some(\n (a) => a.toLowerCase() === config.facilitatorAddress.toLowerCase(),\n );\n if (!isApproved) {\n throw new Error(\n `Facilitator ${config.facilitatorAddress} is not on the Abstract approved list. ` +\n `Pass it in userAllowlist to explicitly allow it.`,\n );\n }\n\n this.config = {\n facilitatorAddress: config.facilitatorAddress,\n token:\n config.token ??\n ABSTRACT_USDC[chainId] ??\n ABSTRACT_USDC[ABSTRACT_CHAIN_IDS.mainnet],\n deadlineSeconds: config.deadlineSeconds ?? 300,\n userAllowlist: config.userAllowlist ?? [],\n };\n }\n\n /**\n * Sign an EIP-712 delegated payment permit for the Abstract facilitator.\n * This replaces direct tx signing — the permit is submitted to the facilitator contract.\n */\n async signPaymentPermit(params: {\n amount: bigint;\n payTo: Address;\n nonce: bigint;\n resource: string;\n }): Promise<AbstractPaymentResult> {\n const deadline = BigInt(\n Math.floor(Date.now() / 1000) + this.config.deadlineSeconds,\n );\n\n const permit: DelegatedPaymentPermit = {\n facilitator: this.config.facilitatorAddress,\n token: this.config.token,\n amount: params.amount,\n payTo: params.payTo,\n nonce: params.nonce,\n deadline,\n resource: params.resource,\n };\n\n const domain = {\n ...ABSTRACT_PERMIT_DOMAIN,\n chainId: this.chainId,\n };\n\n const account = this.walletClient.account;\n if (!account) throw new Error(\"WalletClient has no account attached\");\n\n const signature = await this.walletClient.signTypedData({\n account,\n domain,\n types: ABSTRACT_PERMIT_TYPES,\n primaryType: \"DelegatedPaymentPermit\",\n message: permit,\n });\n\n // Encode the permit for submission to the facilitator contract\n const permitData = encodeAbiParameters(\n parseAbiParameters(\n \"address facilitator, address token, uint256 amount, address payTo, uint256 nonce, uint256 deadline, string resource, bytes signature\",\n ),\n [\n permit.facilitator,\n permit.token,\n permit.amount,\n permit.payTo,\n permit.nonce,\n permit.deadline,\n permit.resource,\n signature,\n ],\n );\n\n return {\n permitSignature: signature,\n permitData,\n permit,\n chainId: this.chainId,\n };\n }\n\n /**\n * Build the x402 payment payload for Abstract's delegated facilitator model.\n * This payload replaces the standard txHash payload in the X-PAYMENT header.\n */\n async buildX402Payload(params: {\n amount: bigint;\n payTo: Address;\n nonce: bigint;\n resource: string;\n }): Promise<Record<string, unknown>> {\n const result = await this.signPaymentPermit(params);\n\n return {\n scheme: \"abstract-delegated\",\n chainId: result.chainId,\n facilitator: result.permit.facilitator,\n token: result.permit.token,\n amount: result.permit.amount.toString(),\n payTo: result.permit.payTo,\n nonce: result.permit.nonce.toString(),\n deadline: result.permit.deadline.toString(),\n resource: result.permit.resource,\n permitSignature: result.permitSignature,\n permitData: result.permitData,\n };\n }\n\n /** Check if a chain ID is an Abstract chain */\n static isAbstractChain(chainId: number): boolean {\n return Object.values(ABSTRACT_CHAIN_IDS).includes(chainId as 2741 | 11124);\n }\n\n /** Get the network string for x402 payment requirements (e.g. \"abstract:2741\") */\n static getNetworkString(chainId: number): string {\n return `abstract:${chainId}`;\n }\n}\n\n// ─── SUPPORTED_CHAINS Extension ──────────────────────────────────────────────\n\n/**\n * Abstract chain IDs to add to SUPPORTED_CHAINS in the main SDK.\n * These route through AbstractDelegatedFacilitatorAdapter for x402 payments.\n */\nexport const ABSTRACT_SUPPORTED_CHAINS = {\n \"abstract:2741\": {\n chainId: ABSTRACT_CHAIN_IDS.mainnet,\n name: \"Abstract Mainnet\",\n rpcUrl: \"https://api.mainnet.abs.xyz\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://explorer.mainnet.abs.xyz\",\n x402Model: \"delegated-facilitator\" as const,\n usdc: ABSTRACT_USDC[ABSTRACT_CHAIN_IDS.mainnet],\n },\n \"abstract-testnet:11124\": {\n chainId: ABSTRACT_CHAIN_IDS.testnet,\n name: \"Abstract Testnet\",\n rpcUrl: \"https://api.testnet.abs.xyz\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://explorer.testnet.abs.xyz\",\n x402Model: \"delegated-facilitator\" as const,\n usdc: ABSTRACT_USDC[ABSTRACT_CHAIN_IDS.testnet],\n },\n} as const;\n",
|
|
10
|
+
"/**\n * @module tokens/registry\n * TokenRegistry — multi-chain token address registry for AgentWallet v6.\n *\n * Ships pre-populated with top tokens for all 11 supported EVM chains.\n * All addresses sourced from:\n * - EVM: CoinGecko official token lists + chain explorers\n * - USDC: https://developers.circle.com/stablecoins/usdc-contract-addresses\n * - WBTC: https://wbtc.network/dashboard/order\n * - WETH: official wrapped ETH contracts per chain\n * - L2 native tokens: official L2 documentation\n *\n * Chain IDs follow the CHAIN_IDS map in src/types.ts.\n */\n\nimport type { Address } from \"viem\";\nimport { zeroAddress } from \"viem\";\nimport type { TokenInfo } from \"./decimals.js\";\n\nexport type { TokenInfo };\n\n/** Full token entry stored in the registry */\nexport interface TokenEntry extends TokenInfo {\n chainId: number;\n name: string;\n isNative?: boolean; // true for native gas tokens (ETH, MATIC, etc.)\n}\n\n/** Params for adding a custom token */\nexport interface AddTokenParams {\n symbol: string;\n address: Address;\n decimals: number;\n chainId: number;\n name?: string;\n isNative?: boolean;\n}\n\n// ─── Chain IDs ───────────────────────────────────────────────────────────────\n\nconst CHAIN = {\n ETHEREUM: 1,\n BASE: 8453,\n ARBITRUM: 42161,\n OPTIMISM: 10,\n POLYGON: 137,\n AVALANCHE: 43114,\n UNICHAIN: 130,\n LINEA: 59144,\n SONIC: 146,\n WORLDCHAIN: 480,\n BASE_SEPOLIA: 84532,\n} as const;\n\n// ─── Pre-verified token address tables ───────────────────────────────────────\n//\n// All addresses are verified against:\n// - Etherscan (chain 1), Basescan (8453), Arbiscan (42161), Optimistic Etherscan (10),\n// Polygonscan (137), Snowtrace (43114), Lineascan (59144)\n// - CoinGecko token detail pages\n// - Circle USDC registry\n//\n// NATIVE_ADDR = zeroAddress (0x0000...0000) — used for native gas tokens\n\nconst NATIVE_ADDR = zeroAddress;\n\n// ─── Native gas tokens ────────────────────────────────────────────────────────\n\nconst NATIVE_TOKENS: TokenEntry[] = [\n // ETH on ETH-compatible chains\n {\n chainId: CHAIN.ETHEREUM,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n {\n chainId: CHAIN.BASE,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n {\n chainId: CHAIN.ARBITRUM,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n {\n chainId: CHAIN.OPTIMISM,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n {\n chainId: CHAIN.UNICHAIN,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n {\n chainId: CHAIN.LINEA,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n {\n chainId: CHAIN.WORLDCHAIN,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n {\n chainId: CHAIN.BASE_SEPOLIA,\n address: NATIVE_ADDR,\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n isNative: true,\n },\n // MATIC on Polygon\n {\n chainId: CHAIN.POLYGON,\n address: NATIVE_ADDR,\n symbol: \"POL\",\n name: \"POL (ex-MATIC)\",\n decimals: 18,\n isNative: true,\n },\n // AVAX on Avalanche\n {\n chainId: CHAIN.AVALANCHE,\n address: NATIVE_ADDR,\n symbol: \"AVAX\",\n name: \"Avalanche\",\n decimals: 18,\n isNative: true,\n },\n // S (Sonic's native token)\n {\n chainId: CHAIN.SONIC,\n address: NATIVE_ADDR,\n symbol: \"S\",\n name: \"Sonic\",\n decimals: 18,\n isNative: true,\n },\n];\n\n// ─── EVM token table ──────────────────────────────────────────────────────────\n// Format: [chainId, address, symbol, name, decimals]\n// Sources documented inline where non-obvious.\n\ntype RawEntry = [number, Address, string, string, number];\n\nconst EVM_TOKENS: RawEntry[] = [\n // ─── Ethereum Mainnet (1) ────────────────────────────────────────────────\n // USDC — Circle official\n [\n CHAIN.ETHEREUM,\n \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n // USDT — Tether official\n [\n CHAIN.ETHEREUM,\n \"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\n \"USDT\",\n \"Tether USD\",\n 6,\n ],\n // DAI — MakerDAO\n [\n CHAIN.ETHEREUM,\n \"0x6B175474E89094C44Da98b954EedeAC495271d0F\",\n \"DAI\",\n \"Dai Stablecoin\",\n 18,\n ],\n // WETH — official WETH9\n [\n CHAIN.ETHEREUM,\n \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n // WBTC — BitGo wrapped BTC\n [\n CHAIN.ETHEREUM,\n \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\",\n \"WBTC\",\n \"Wrapped BTC\",\n 8,\n ],\n // LINK — Chainlink\n [\n CHAIN.ETHEREUM,\n \"0x514910771AF9Ca656af840dff83E8264EcF986CA\",\n \"LINK\",\n \"ChainLink Token\",\n 18,\n ],\n // UNI — Uniswap\n [\n CHAIN.ETHEREUM,\n \"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984\",\n \"UNI\",\n \"Uniswap\",\n 18,\n ],\n // AAVE\n [\n CHAIN.ETHEREUM,\n \"0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9\",\n \"AAVE\",\n \"Aave Token\",\n 18,\n ],\n // CRV — Curve DAO Token\n [\n CHAIN.ETHEREUM,\n \"0xD533a949740bb3306d119CC777fa900bA034cd52\",\n \"CRV\",\n \"Curve DAO Token\",\n 18,\n ],\n // MKR — MakerDAO\n [\n CHAIN.ETHEREUM,\n \"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2\",\n \"MKR\",\n \"Maker\",\n 18,\n ],\n // SNX — Synthetix\n [\n CHAIN.ETHEREUM,\n \"0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F\",\n \"SNX\",\n \"Synthetix Network Token\",\n 18,\n ],\n // COMP — Compound\n [\n CHAIN.ETHEREUM,\n \"0xc00e94Cb662C3520282E6f5717214004A7f26888\",\n \"COMP\",\n \"Compound\",\n 18,\n ],\n // LDO — Lido DAO\n [\n CHAIN.ETHEREUM,\n \"0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32\",\n \"LDO\",\n \"Lido DAO Token\",\n 18,\n ],\n // MATIC (ERC-20 on ETH, now POL)\n [\n CHAIN.ETHEREUM,\n \"0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0\",\n \"POL\",\n \"POL (ex-MATIC)\",\n 18,\n ],\n\n // ─── Base Mainnet (8453) ─────────────────────────────────────────────────\n [\n CHAIN.BASE,\n \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.BASE,\n \"0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2\",\n \"USDT\",\n \"Tether USD\",\n 6,\n ],\n [\n CHAIN.BASE,\n \"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb\",\n \"DAI\",\n \"Dai Stablecoin\",\n 18,\n ],\n [\n CHAIN.BASE,\n \"0x4200000000000000000000000000000000000006\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n // WBTC on Base — bridged via LayerZero\n [\n CHAIN.BASE,\n \"0x0555E30da8f98308EdB960aa94C0Db47230d2B9c\",\n \"WBTC\",\n \"Wrapped BTC\",\n 8,\n ],\n [\n CHAIN.BASE,\n \"0xE3B53AF74a4BF62Ae5511055290838050bf764Df\",\n \"LINK\",\n \"ChainLink Token\",\n 18,\n ],\n [\n CHAIN.BASE,\n \"0xc3De830EA07524a0761646a6a4e4be0e114a3C83\",\n \"AAVE\",\n \"Aave Token\",\n 18,\n ],\n // cbETH — Coinbase Staked ETH\n [\n CHAIN.BASE,\n \"0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22\",\n \"cbETH\",\n \"Coinbase Staked Ether\",\n 18,\n ],\n // USDbC — Bridged USDC (legacy on Base)\n [\n CHAIN.BASE,\n \"0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA\",\n \"USDbC\",\n \"USD Base Coin\",\n 6,\n ],\n\n // ─── Arbitrum One (42161) ────────────────────────────────────────────────\n [\n CHAIN.ARBITRUM,\n \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.ARBITRUM,\n \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n \"USDT\",\n \"Tether USD\",\n 6,\n ],\n [\n CHAIN.ARBITRUM,\n \"0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1\",\n \"DAI\",\n \"Dai Stablecoin\",\n 18,\n ],\n [\n CHAIN.ARBITRUM,\n \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n [\n CHAIN.ARBITRUM,\n \"0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f\",\n \"WBTC\",\n \"Wrapped BTC\",\n 8,\n ],\n [\n CHAIN.ARBITRUM,\n \"0xf97f4df75117a78c1A5a0DBb814Af92458539FB4\",\n \"LINK\",\n \"ChainLink Token\",\n 18,\n ],\n [\n CHAIN.ARBITRUM,\n \"0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0\",\n \"UNI\",\n \"Uniswap\",\n 18,\n ],\n [\n CHAIN.ARBITRUM,\n \"0xba5DdD1f9d7F570dc94a51479a000E3BCE967196\",\n \"AAVE\",\n \"Aave Token\",\n 18,\n ],\n // ARB — Arbitrum governance token (native to Arbitrum)\n [\n CHAIN.ARBITRUM,\n \"0x912CE59144191C1204E64559FE8253a0e49E6548\",\n \"ARB\",\n \"Arbitrum\",\n 18,\n ],\n [\n CHAIN.ARBITRUM,\n \"0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978\",\n \"CRV\",\n \"Curve DAO Token\",\n 18,\n ],\n [\n CHAIN.ARBITRUM,\n \"0x13Ad51ed4F1B7e9Dc168d8a00cB3f4dDD85EfA60\",\n \"LDO\",\n \"Lido DAO Token\",\n 18,\n ],\n [\n CHAIN.ARBITRUM,\n \"0x354A6dA3fcde098F8389cad84b0182725c6C91dE\",\n \"COMP\",\n \"Compound\",\n 18,\n ],\n\n // ─── Optimism (10) ───────────────────────────────────────────────────────\n [\n CHAIN.OPTIMISM,\n \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.OPTIMISM,\n \"0x94b008aA00579c1307B0EF2c499aD98a8ce58e58\",\n \"USDT\",\n \"Tether USD\",\n 6,\n ],\n [\n CHAIN.OPTIMISM,\n \"0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1\",\n \"DAI\",\n \"Dai Stablecoin\",\n 18,\n ],\n [\n CHAIN.OPTIMISM,\n \"0x4200000000000000000000000000000000000006\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n [\n CHAIN.OPTIMISM,\n \"0x68f180fcCe6836688e9084f035309E29Bf0A2095\",\n \"WBTC\",\n \"Wrapped BTC\",\n 8,\n ],\n [\n CHAIN.OPTIMISM,\n \"0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6\",\n \"LINK\",\n \"ChainLink Token\",\n 18,\n ],\n [\n CHAIN.OPTIMISM,\n \"0x6fd9d7AD17242c41f7131d257212c54A0e816691\",\n \"UNI\",\n \"Uniswap\",\n 18,\n ],\n [\n CHAIN.OPTIMISM,\n \"0x76FB31fb4af56892A25e32cFC43De717950c9278\",\n \"AAVE\",\n \"Aave Token\",\n 18,\n ],\n // OP — Optimism governance token (native to Optimism)\n [\n CHAIN.OPTIMISM,\n \"0x4200000000000000000000000000000000000042\",\n \"OP\",\n \"Optimism\",\n 18,\n ],\n [\n CHAIN.OPTIMISM,\n \"0x9560e827aF36c94D2Ac33a39bCE1Fe78631088Db\",\n \"VELO\",\n \"Velodrome Finance\",\n 18,\n ],\n [\n CHAIN.OPTIMISM,\n \"0xc5b001DC33727F8F26880B184090D3E252470D45\",\n \"SNX\",\n \"Synthetix\",\n 18,\n ],\n\n // ─── Polygon (137) ───────────────────────────────────────────────────────\n [\n CHAIN.POLYGON,\n \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.POLYGON,\n \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n \"USDT\",\n \"Tether USD\",\n 6,\n ],\n [\n CHAIN.POLYGON,\n \"0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063\",\n \"DAI\",\n \"Dai Stablecoin\",\n 18,\n ],\n [\n CHAIN.POLYGON,\n \"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n [\n CHAIN.POLYGON,\n \"0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6\",\n \"WBTC\",\n \"Wrapped BTC\",\n 8,\n ],\n [\n CHAIN.POLYGON,\n \"0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39\",\n \"LINK\",\n \"ChainLink Token\",\n 18,\n ],\n [\n CHAIN.POLYGON,\n \"0xb33EaAd8d922B1083446DC23f610c2567fB5180f\",\n \"UNI\",\n \"Uniswap\",\n 18,\n ],\n [\n CHAIN.POLYGON,\n \"0xD6DF932A45C0f255f85145f286eA0b292B21C90B\",\n \"AAVE\",\n \"Aave Token\",\n 18,\n ],\n // WMATIC — Wrapped POL (MATIC) on Polygon\n [\n CHAIN.POLYGON,\n \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\",\n \"WMATIC\",\n \"Wrapped POL (MATIC)\",\n 18,\n ],\n [\n CHAIN.POLYGON,\n \"0x172370d5Cd63279eFa6d502DAB29171933a610AF\",\n \"CRV\",\n \"Curve DAO Token\",\n 18,\n ],\n [\n CHAIN.POLYGON,\n \"0x50B728D8D964fd00C2d0AAD81718b71311feF68a\",\n \"SNX\",\n \"Synthetix\",\n 18,\n ],\n\n // ─── Avalanche C-Chain (43114) ───────────────────────────────────────────\n [\n CHAIN.AVALANCHE,\n \"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.AVALANCHE,\n \"0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7\",\n \"USDT\",\n \"Tether USD\",\n 6,\n ],\n [\n CHAIN.AVALANCHE,\n \"0xd586E7F844cEa2F87f50152665BCbc2C279D8d70\",\n \"DAI\",\n \"Dai Stablecoin\",\n 18,\n ],\n // WETH.e — Bridged Ether on Avalanche\n [\n CHAIN.AVALANCHE,\n \"0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB\",\n \"WETH.e\",\n \"Wrapped Ether\",\n 18,\n ],\n [\n CHAIN.AVALANCHE,\n \"0x50b7545627a5162F82A992c33b87aDc75187B218\",\n \"WBTC\",\n \"Wrapped BTC\",\n 8,\n ],\n [\n CHAIN.AVALANCHE,\n \"0x5947BB275c521040051D82396192181b413227A3\",\n \"LINK\",\n \"ChainLink Token\",\n 18,\n ],\n [\n CHAIN.AVALANCHE,\n \"0x8eBAf22B6F053dFFeaf46f4Dd9eFA95D89ba8580\",\n \"UNI\",\n \"Uniswap\",\n 18,\n ],\n // WAVAX — Wrapped AVAX\n [\n CHAIN.AVALANCHE,\n \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\",\n \"WAVAX\",\n \"Wrapped AVAX\",\n 18,\n ],\n [\n CHAIN.AVALANCHE,\n \"0x63a72806098Bd3D9520cC43356dD78afe5D386D9\",\n \"AAVE\",\n \"Aave Token\",\n 18,\n ],\n\n // ─── Unichain (130) ──────────────────────────────────────────────────────\n [\n CHAIN.UNICHAIN,\n \"0x078D782b760474a361dDA0AF3839290b0EF57AD6\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.UNICHAIN,\n \"0x4200000000000000000000000000000000000006\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n\n // ─── Linea (59144) ───────────────────────────────────────────────────────\n [\n CHAIN.LINEA,\n \"0x176211869cA2b568f2A7D4EE941E073a821EE1ff\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.LINEA,\n \"0xA219439258ca9da29E9Cc4cE5596924745e12B93\",\n \"USDT\",\n \"Tether USD\",\n 6,\n ],\n [\n CHAIN.LINEA,\n \"0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5\",\n \"DAI\",\n \"Dai Stablecoin\",\n 18,\n ],\n [\n CHAIN.LINEA,\n \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n [\n CHAIN.LINEA,\n \"0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4\",\n \"WBTC\",\n \"Wrapped BTC\",\n 8,\n ],\n\n // ─── Sonic (146) ─────────────────────────────────────────────────────────\n [\n CHAIN.SONIC,\n \"0x29219dd400f2Bf60E5a23d13Be72B486D4038894\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n // WS — Wrapped Sonic (native S wrapped)\n [\n CHAIN.SONIC,\n \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\",\n \"WS\",\n \"Wrapped Sonic\",\n 18,\n ],\n\n // ─── World Chain (480) ───────────────────────────────────────────────────\n [\n CHAIN.WORLDCHAIN,\n \"0x79A02482A880bCE3B13e09Da970dC34db4CD24d1\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.WORLDCHAIN,\n \"0x4200000000000000000000000000000000000006\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n // WLD — Worldcoin token\n [\n CHAIN.WORLDCHAIN,\n \"0x163f8C2467924be0ae7B5347228CABF260318753\",\n \"WLD\",\n \"Worldcoin\",\n 18,\n ],\n\n // ─── Base Sepolia Testnet (84532) ────────────────────────────────────────\n [\n CHAIN.BASE_SEPOLIA,\n \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n \"USDC\",\n \"USD Coin\",\n 6,\n ],\n [\n CHAIN.BASE_SEPOLIA,\n \"0x4200000000000000000000000000000000000006\",\n \"WETH\",\n \"Wrapped Ether\",\n 18,\n ],\n];\n\n// ─── TokenRegistry class ──────────────────────────────────────────────────────\n\nexport class TokenRegistry {\n private readonly tokens: Map<string, TokenEntry> = new Map();\n\n constructor(initialTokens?: TokenEntry[]) {\n // Load native gas tokens\n for (const t of NATIVE_TOKENS) {\n this._store(t);\n }\n // Load EVM tokens\n for (const [chainId, address, symbol, name, decimals] of EVM_TOKENS) {\n this._store({ chainId, address, symbol, name, decimals });\n }\n // Load any provided custom tokens\n if (initialTokens) {\n for (const t of initialTokens) {\n this._store(t);\n }\n }\n }\n\n private _key(symbol: string, chainId: number): string {\n return `${symbol.toUpperCase()}:${chainId}`;\n }\n\n private _store(entry: TokenEntry): void {\n const key = this._key(entry.symbol, entry.chainId);\n this.tokens.set(key, { ...entry });\n }\n\n /**\n * Add or overwrite a token in the registry.\n */\n addToken(params: AddTokenParams): void {\n const entry: TokenEntry = {\n symbol: params.symbol,\n address: params.address,\n decimals: params.decimals,\n chainId: params.chainId,\n name: params.name ?? params.symbol,\n isNative: params.isNative ?? false,\n };\n this._store(entry);\n }\n\n /**\n * Look up a token by symbol and chainId.\n * Returns undefined if not found.\n */\n getToken(symbol: string, chainId: number): TokenEntry | undefined {\n return this.tokens.get(this._key(symbol, chainId));\n }\n\n /**\n * List all tokens registered for a given chainId.\n */\n listTokens(chainId: number): TokenEntry[] {\n const result: TokenEntry[] = [];\n for (const entry of this.tokens.values()) {\n if (entry.chainId === chainId) result.push(entry);\n }\n return result;\n }\n\n /**\n * Find a token by its contract address on a given chain.\n */\n getTokenByAddress(address: Address, chainId: number): TokenEntry | undefined {\n const lower = address.toLowerCase();\n for (const entry of this.tokens.values()) {\n if (entry.chainId === chainId && entry.address.toLowerCase() === lower) {\n return entry;\n }\n }\n return undefined;\n }\n\n /**\n * Returns all registered tokens (all chains).\n */\n getAllTokens(): TokenEntry[] {\n return Array.from(this.tokens.values());\n }\n\n /**\n * Returns number of registered tokens.\n */\n size(): number {\n return this.tokens.size;\n }\n}\n\n// ─── Pre-built per-chain registries ──────────────────────────────────────────\n// These are lazy singletons — constructed once on first import.\n\nlet _globalRegistry: TokenRegistry | null = null;\n\n/** Global registry with all supported chains pre-populated. */\nexport function getGlobalRegistry(): TokenRegistry {\n if (!_globalRegistry) _globalRegistry = new TokenRegistry();\n return _globalRegistry;\n}\n\n/** Create a fresh registry pre-populated for a single chain.\n * @internal — reserved for per-chain filtering API\n */\nexport function createChainRegistry(_chainId: number): TokenRegistry {\n return new TokenRegistry(); // loads all tokens; filter via listTokens(chainId)\n}\n\n// Named per-chain exports — each returns the global registry (all tokens loaded,\n// filtered access via listTokens(chainId)). Use getGlobalRegistry() for multi-chain.\nexport const ETHEREUM_REGISTRY = new TokenRegistry();\nexport const BASE_REGISTRY = new TokenRegistry();\nexport const ARBITRUM_REGISTRY = new TokenRegistry();\nexport const OPTIMISM_REGISTRY = new TokenRegistry();\nexport const POLYGON_REGISTRY = new TokenRegistry();\nexport const AVALANCHE_REGISTRY = new TokenRegistry();\nexport const UNICHAIN_REGISTRY = new TokenRegistry();\nexport const LINEA_REGISTRY = new TokenRegistry();\nexport const SONIC_REGISTRY = new TokenRegistry();\nexport const WORLDCHAIN_REGISTRY = new TokenRegistry();\nexport const BASE_SEPOLIA_REGISTRY = new TokenRegistry();\n\n// Convenience: get native gas token for a chain\nexport function getNativeToken(chainId: number): TokenEntry | undefined {\n return (\n getGlobalRegistry().getToken(\"ETH\", chainId) ??\n getGlobalRegistry().getToken(\"POL\", chainId) ??\n getGlobalRegistry().getToken(\"AVAX\", chainId) ??\n getGlobalRegistry().getToken(\"S\", chainId)\n );\n}\n",
|
|
11
|
+
"/**\n * @module x402/types\n * x402 protocol type definitions and well-known asset constants.\n *\n * Implements the x402 HTTP payment protocol spec (coinbase/x402) for\n * multi-chain USDC payments. Covers 10 mainnet chains: Base, Ethereum,\n * Arbitrum, Polygon, Optimism, Avalanche, Unichain, Linea, Sonic, Worldchain.\n *\n * USDC addresses are sourced from Circle's official registry:\n * https://developers.circle.com/stablecoins/usdc-contract-addresses\n */\n// x402 protocol types — compatible with @x402/core spec\nimport type { Address, Hash } from \"viem\";\n\n// ─── x402 Protocol Types (from coinbase/x402 spec) ───\n\n/** Resource information included in x402 responses */\nexport interface X402ResourceInfo {\n url: string;\n description: string;\n mimeType: string;\n}\n\n/** Payment requirements returned in 402 response PAYMENT-REQUIRED header */\nexport interface X402PaymentRequirements {\n scheme: string; // e.g. \"exact\"\n network: string; // e.g. \"base:8453\"\n asset: string; // token contract address (e.g. USDC on Base)\n amount: string; // amount in smallest unit (e.g. \"1000000\" = 1 USDC)\n payTo: string; // recipient address\n maxTimeoutSeconds: number;\n extra: Record<string, unknown>;\n}\n\n/** Full 402 response payload (base64-decoded from PAYMENT-REQUIRED header) */\nexport interface X402PaymentRequired {\n x402Version: number;\n error?: string;\n resource: X402ResourceInfo;\n accepts: X402PaymentRequirements[];\n extensions?: Record<string, unknown>;\n}\n\n/** Payment payload sent back with PAYMENT-SIGNATURE header */\nexport interface X402PaymentPayload {\n x402Version: number;\n resource: X402ResourceInfo;\n accepted: X402PaymentRequirements;\n payload: Record<string, unknown>; // scheme-specific (e.g. tx hash, signature)\n extensions?: Record<string, unknown>;\n}\n\n/** Settlement response returned in PAYMENT-RESPONSE header */\nexport interface X402SettlementResponse {\n success: boolean;\n txHash?: string;\n network?: string;\n error?: string;\n}\n\n// ─── AgentWallet x402 Client Types ───\n\n/** Per-service spending cap configuration */\nexport interface X402ServiceBudget {\n /** Domain or URL pattern (e.g. \"api.example.com\" or \"*\") */\n service: string;\n /** Max spend per single request in token base units */\n maxPerRequest: bigint;\n /** Max total spend per day in token base units */\n dailyLimit: bigint;\n}\n\n/** Transaction log entry for x402 payments */\nexport interface X402TransactionLog {\n timestamp: number;\n service: string;\n url: string;\n amount: bigint;\n token: Address;\n recipient: Address;\n txHash: Hash;\n network: string;\n scheme: string;\n success: boolean;\n error?: string;\n}\n\n/** Configuration for the x402 client */\nexport interface X402ClientConfig {\n /** Service-level budget controls */\n serviceBudgets?: X402ServiceBudget[];\n /** Global daily spending limit (token base units, default: unlimited) */\n globalDailyLimit?: bigint;\n /** Global per-request max (token base units, default: unlimited) */\n globalPerRequestMax?: bigint;\n /** Supported networks (default: [\"base:8453\"]) */\n supportedNetworks?: string[];\n /** Supported assets by network (default: USDC on Base) */\n supportedAssets?: Record<string, Address[]>;\n /** Max retries after payment (default: 1) */\n maxRetries?: number;\n /** Custom facilitator URL (optional, for verify/settle) */\n facilitatorUrl?: string;\n /** Whether to auto-pay 402 responses (default: true) */\n autoPay?: boolean;\n /** Callback before payment — return false to reject */\n onBeforePayment?: (\n req: X402PaymentRequirements,\n url: string,\n ) => Promise<boolean> | boolean;\n /** Callback after payment */\n onPaymentComplete?: (log: X402TransactionLog) => void;\n}\n\n// ─── Well-known Assets ───\n\n/**\n * USDC contract addresses by network (chain-name:chainId format).\n * Sources:\n * - EVM chains: https://developers.circle.com/cctp/references/contract-addresses\n * - Linea: https://linea.build/ecosystem/usdc\n * - Unichain: https://docs.unichain.org/docs/technical-information/token-addresses\n * - Sonic: https://docs.soniclabs.com/build/useful-addresses\n * - Worldchain: https://docs.worldcoin.org/world-chain/addresses/usdc\n */\nexport const USDC_ADDRESSES: Record<string, Address> = {\n // Testnets\n \"base-sepolia:84532\": \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n // Mainnets\n \"base:8453\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"ethereum:1\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"arbitrum:42161\": \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n \"polygon:137\": \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n \"bsc:56\": \"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d\",\n \"optimism:10\": \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\",\n \"avalanche:43114\": \"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\",\n \"unichain:130\": \"0x078D782b760474a361dDA0AF3839290b0EF57AD6\",\n \"linea:59144\": \"0x176211869cA2b568f2A7D4EE941E073a821EE1ff\",\n \"sonic:146\": \"0x29219dd400f2Bf60E5a23d13Be72B486D4038894\",\n \"worldchain:480\": \"0x79A02482A880bCE3B13e09Da970dC34db4CD24d1\",\n} as const;\n\n/** Default supported networks (all mainnet chains) */\nexport const DEFAULT_SUPPORTED_NETWORKS = [\n \"base:8453\",\n \"ethereum:1\",\n \"arbitrum:42161\",\n \"polygon:137\",\n \"bsc:56\",\n \"optimism:10\",\n \"avalanche:43114\",\n \"unichain:130\",\n \"linea:59144\",\n \"sonic:146\",\n \"worldchain:480\",\n] as const;\n",
|
|
12
|
+
"/**\n * @module x402/multi-asset\n * Multi-asset support utilities for the x402 payment client.\n *\n * Resolves asset names/symbols → token addresses via the global TokenRegistry.\n * This extends x402 beyond USDC-only to support any token the 402 response requests.\n *\n * All address lookups use the TokenRegistry from src/tokens/registry.ts.\n * Fallback: USDC_ADDRESSES from x402/types.ts.\n */\n\nimport type { Address } from \"viem\";\nimport { getGlobalRegistry } from \"../tokens/registry.js\";\nimport { USDC_ADDRESSES } from \"./types.js\";\n\n/**\n * Network string format used in x402: \"chainName:chainId\" (e.g. \"base:8453\").\n * Returns the chainId portion as a number.\n */\nexport function parseNetworkChainId(network: string): number | null {\n const parts = network.split(\":\");\n if (parts.length < 2) return null;\n const id = parseInt(parts[parts.length - 1], 10);\n return Number.isNaN(id) ? null : id;\n}\n\n/**\n * Resolve an asset address in the context of a 402 response.\n * The asset field may be:\n * 1. A token symbol (\"USDC\", \"WETH\", etc.) → look up in registry by symbol\n * 2. A hex contract address → look up in registry by address (must be registered)\n *\n * Only returns an address if the asset is known in the TokenRegistry.\n * Unknown addresses are NOT accepted — they must be explicitly added or\n * whitelisted via supportedAssets config.\n *\n * @param asset - Asset identifier from the 402 response\n * @param network - Network string from the 402 response (e.g. \"base:8453\")\n * @returns Resolved contract address, or null if not found in registry\n */\nexport function resolveAssetAddress(\n asset: string,\n network: string,\n): Address | null {\n const chainId = parseNetworkChainId(network);\n if (chainId == null) return null;\n\n const registry = getGlobalRegistry();\n\n // If it looks like an EVM address, check registry by address\n if (/^0x[0-9a-fA-F]{40}$/.test(asset)) {\n const entry = registry.getTokenByAddress(asset as Address, chainId);\n if (entry) return entry.address;\n return null; // unknown address — reject for safety\n }\n\n // Try registry lookup by symbol (e.g. \"USDC\", \"WETH\")\n const entry = registry.getToken(asset.toUpperCase(), chainId);\n if (entry) return entry.address;\n\n return null;\n}\n\n/**\n * Get token decimals for a given asset+network pair.\n * Used to correctly format amounts in x402 payments.\n *\n * @param asset - Asset address (hex) or symbol\n * @param network - Network string (e.g. \"base:8453\")\n * @returns Decimals, defaults to 6 for USDC-like stable, 18 for everything else\n */\nexport function resolveAssetDecimals(asset: string, network: string): number {\n const chainId = parseNetworkChainId(network);\n if (chainId == null) return 6;\n\n const registry = getGlobalRegistry();\n\n // Try by address first\n if (/^0x[0-9a-fA-F]{40}$/.test(asset)) {\n const entry = registry.getTokenByAddress(asset as Address, chainId);\n if (entry) return entry.decimals;\n // Unknown token — default to 18\n return 18;\n }\n\n // Try by symbol\n const entry = registry.getToken(asset.toUpperCase(), chainId);\n if (entry) return entry.decimals;\n\n return 18;\n}\n\n/**\n * Build a set of accepted payment assets for an x402 client, using the\n * global registry to auto-populate known tokens per network.\n *\n * @param networks - List of network strings (e.g. [\"base:8453\", \"arbitrum:42161\"])\n * @param symbols - Token symbols to include (e.g. [\"USDC\", \"USDT\", \"WETH\"])\n * @returns Map from network string → array of token addresses\n */\nexport function buildSupportedAssets(\n networks: string[],\n symbols: string[] = [\"USDC\", \"USDT\", \"DAI\", \"WETH\"],\n): Record<string, Address[]> {\n const result: Record<string, Address[]> = {};\n const registry = getGlobalRegistry();\n\n for (const network of networks) {\n const chainId = parseNetworkChainId(network);\n if (chainId == null) continue;\n\n const addrs: Address[] = [];\n\n for (const symbol of symbols) {\n const entry = registry.getToken(symbol, chainId);\n if (entry && !entry.isNative) {\n addrs.push(entry.address);\n }\n }\n\n // Always include USDC from the existing USDC_ADDRESSES table as fallback\n const usdcFallback = USDC_ADDRESSES[network];\n if (\n usdcFallback &&\n !addrs.some((a) => a.toLowerCase() === usdcFallback.toLowerCase())\n ) {\n addrs.push(usdcFallback);\n }\n\n if (addrs.length > 0) {\n result[network] = addrs;\n }\n }\n\n return result;\n}\n\n/**\n * Check if a given asset address is a known stablecoin (6 decimals) on the network.\n */\nexport function isStablecoin(asset: string, network: string): boolean {\n const decimals = resolveAssetDecimals(asset, network);\n return decimals === 6;\n}\n",
|
|
13
|
+
"/**\n * @module x402/client\n * x402 Payment Client — automatic HTTP 402 payment handling for AgentWallet.\n *\n * Wraps the standard fetch API to transparently handle 402 Payment Required\n * responses using the x402 protocol. Supports multi-chain, multi-asset payments\n * (USDC, USDT, DAI, WETH, and any token in the TokenRegistry) across all 11\n * mainnet chains configured in x402/types.ts.\n *\n * Flow: fetch → 402 detected → parse payment requirements → resolve asset address\n * via TokenRegistry → budget check → execute ERC-20 transfer → retry with\n * X-PAYMENT header.\n */\n// x402 Client — automatic 402 payment handling for AgentWallet (v6: multi-asset)\nimport type { Address, Hash } from \"viem\";\nimport {\n type AgentWallet,\n agentTransferToken,\n checkBudget,\n} from \"../wallet-core.js\";\nimport { X402BudgetTracker } from \"./budget.js\";\nimport { resolveAssetAddress } from \"./multi-asset.js\";\nimport type {\n X402ClientConfig,\n X402PaymentPayload,\n X402PaymentRequired,\n X402PaymentRequirements,\n X402TransactionLog,\n} from \"./types.js\";\nimport { DEFAULT_SUPPORTED_NETWORKS } from \"./types.js\";\n\n/**\n * [MAX-ADDED] x402 Payment Client for AgentWallet.\n *\n * Handles the full x402 payment flow:\n * 1. Detects 402 Payment Required responses\n * 2. Parses payment instructions from PAYMENT-REQUIRED header\n * 3. Validates against budget controls\n * 4. Executes USDC payment via AgentWallet contract\n * 5. Retries original request with payment proof\n */\nexport class X402Client {\n private wallet: AgentWallet;\n private config: X402ClientConfig;\n private budget: X402BudgetTracker;\n private supportedNetworks: Set<string>;\n\n constructor(wallet: AgentWallet, config: X402ClientConfig = {}) {\n this.wallet = wallet;\n this.config = {\n autoPay: true,\n maxRetries: 1,\n supportedNetworks: [...DEFAULT_SUPPORTED_NETWORKS],\n ...config,\n };\n this.budget = new X402BudgetTracker(config);\n this.supportedNetworks = new Set(this.config.supportedNetworks);\n }\n\n /**\n * Make an x402-aware fetch request. Automatically handles 402 responses.\n */\n async fetch(url: string | URL, init?: RequestInit): Promise<Response> {\n const urlStr = url.toString();\n const response = await globalThis.fetch(url, init);\n\n if (response.status !== 402) {\n return response;\n }\n\n if (!this.config.autoPay) {\n return response;\n }\n\n // Parse the 402 response\n const paymentRequired = await this.parse402Response(response);\n if (!paymentRequired) {\n return response; // Couldn't parse — return original 402\n }\n\n // Find a compatible payment option\n const selected = this.selectPaymentOption(paymentRequired.accepts);\n if (!selected) {\n return response; // No compatible payment option\n }\n\n // Check budget\n const amount = BigInt(selected.amount);\n const service = new URL(urlStr).hostname;\n const budgetCheck = this.budget.checkBudget(service, amount);\n if (!budgetCheck.allowed) {\n throw new X402BudgetExceededError(\n budgetCheck.reason ?? \"Budget check failed\",\n urlStr,\n selected,\n );\n }\n\n // Callback check\n if (this.config.onBeforePayment) {\n const proceed = await this.config.onBeforePayment(selected, urlStr);\n if (!proceed) {\n return response;\n }\n }\n\n // Execute payment\n const paymentResult = await this.executePayment(selected);\n\n // Build payment payload\n const paymentPayload: X402PaymentPayload = {\n x402Version: paymentRequired.x402Version,\n resource: paymentRequired.resource,\n accepted: selected,\n payload: {\n txHash: paymentResult.txHash,\n network: selected.network,\n },\n };\n\n // Log the transaction\n const log: X402TransactionLog = {\n timestamp: Math.floor(Date.now() / 1000),\n service,\n url: urlStr,\n amount,\n token: selected.asset as Address,\n recipient: selected.payTo as Address,\n txHash: paymentResult.txHash,\n network: selected.network,\n scheme: selected.scheme,\n success: true,\n };\n this.budget.recordPayment(log);\n this.config.onPaymentComplete?.(log);\n\n // Retry request with payment proof\n const retryHeaders = new Headers(init?.headers);\n const payloadB64 = btoa(JSON.stringify(paymentPayload));\n retryHeaders.set(\"X-PAYMENT\", payloadB64);\n\n const retryResponse = await globalThis.fetch(url, {\n ...init,\n headers: retryHeaders,\n });\n\n return retryResponse;\n }\n\n /**\n * Parse a 402 response to extract payment requirements.\n */\n async parse402Response(\n response: Response,\n ): Promise<X402PaymentRequired | null> {\n // Try PAYMENT-REQUIRED header first (standard x402)\n const headerValue =\n response.headers.get(\"payment-required\") ??\n response.headers.get(\"x-payment-required\");\n\n if (headerValue) {\n try {\n const decoded = JSON.parse(atob(headerValue));\n return decoded as X402PaymentRequired;\n } catch {\n // Fall through to body parsing\n }\n }\n\n // Try JSON body as fallback\n try {\n const body = await response.clone().json();\n if (body.x402Version && body.accepts) {\n return body as X402PaymentRequired;\n }\n } catch {\n // Not parseable\n }\n\n return null;\n }\n\n /**\n * Select the best compatible payment option from offered requirements.\n * Prefers: Base network, stablecoins, exact scheme.\n *\n * v6 change: resolves assets via TokenRegistry in addition to USDC_ADDRESSES.\n * Now accepts any ERC-20 whose address is in the TokenRegistry for the network.\n */\n selectPaymentOption(\n accepts: X402PaymentRequirements[],\n ): X402PaymentRequirements | null {\n // Filter to supported networks and resolvable assets\n const compatible = accepts.filter((req) => {\n if (!this.supportedNetworks.has(req.network)) return false;\n\n // Config override: explicit supportedAssets list\n if (this.config.supportedAssets?.[req.network]) {\n return this.config.supportedAssets[req.network].some(\n (a) => a.toLowerCase() === req.asset.toLowerCase(),\n );\n }\n\n // v6: resolve via TokenRegistry — accept any known ERC-20 on this network\n const resolved = resolveAssetAddress(req.asset, req.network);\n return resolved != null;\n });\n\n if (compatible.length === 0) return null;\n\n // Prefer \"exact\" scheme, then lowest amount\n const exact = compatible.filter((r) => r.scheme === \"exact\");\n const candidates = exact.length > 0 ? exact : compatible;\n candidates.sort((a, b) => Number(BigInt(a.amount) - BigInt(b.amount)));\n\n return candidates[0];\n }\n\n /**\n * Execute the payment via AgentWallet's agentTransferToken.\n *\n * v6 change: resolves asset address via TokenRegistry before executing.\n * The 402 response may specify an asset by symbol (\"USDC\") or by address.\n */\n private async executePayment(\n req: X402PaymentRequirements,\n ): Promise<{ txHash: Hash }> {\n // Resolve the actual contract address for the requested asset\n const resolvedAddress = resolveAssetAddress(req.asset, req.network);\n if (!resolvedAddress) {\n throw new X402PaymentError(\n `Cannot resolve asset \"${req.asset}\" on network \"${req.network}\" to a contract address`,\n req,\n );\n }\n\n // First check on-chain budget\n const onChainBudget = await checkBudget(this.wallet, resolvedAddress);\n const amount = BigInt(req.amount);\n\n if (amount > onChainBudget.perTxLimit) {\n throw new X402PaymentError(\n `Amount ${amount} exceeds on-chain per-tx limit ${onChainBudget.perTxLimit}`,\n req,\n );\n }\n\n if (amount > onChainBudget.remainingInPeriod) {\n throw new X402PaymentError(\n `Amount ${amount} exceeds remaining period budget ${onChainBudget.remainingInPeriod}`,\n req,\n );\n }\n\n // Calculate and transfer protocol fee (0.77% = 77 bps)\n const X402_PROTOCOL_FEE_BPS = 77n;\n const FEE_COLLECTOR: Address = \"0xff86829393C6C26A4EC122bE0Cc3E466Ef876AdD\";\n const feeAmount = (amount * X402_PROTOCOL_FEE_BPS) / 10000n;\n\n if (feeAmount > 0n) {\n await agentTransferToken(this.wallet, {\n token: req.asset as Address,\n to: FEE_COLLECTOR,\n amount: feeAmount,\n });\n }\n\n // Execute the ERC20 transfer via AgentWallet (full amount to payee)\n const txHash = await agentTransferToken(this.wallet, {\n token: resolvedAddress,\n to: req.payTo as Address,\n amount,\n });\n\n return { txHash };\n }\n\n // ─── Budget Access ───\n\n /** Get the budget tracker for direct inspection */\n get budgetTracker(): X402BudgetTracker {\n return this.budget;\n }\n\n /** Get transaction log */\n getTransactionLog(filter?: {\n service?: string;\n since?: number;\n }): X402TransactionLog[] {\n return this.budget.getTransactionLog(filter);\n }\n\n /** Get daily spend summary */\n getDailySpendSummary() {\n return this.budget.getDailySpendSummary();\n }\n}\n\n// ─── Error Types ───\n\nexport class X402PaymentError extends Error {\n constructor(\n message: string,\n public readonly paymentRequirements: X402PaymentRequirements,\n ) {\n super(`x402 payment error: ${message}`);\n this.name = \"X402PaymentError\";\n }\n}\n\nexport class X402BudgetExceededError extends Error {\n constructor(\n public readonly reason: string,\n public readonly url: string,\n public readonly paymentRequirements: X402PaymentRequirements,\n ) {\n super(`x402 budget exceeded: ${reason}`);\n this.name = \"X402BudgetExceededError\";\n }\n}\n",
|
|
14
|
+
"// [MAX-ADDED] x402 Middleware — wraps fetch/axios to be x402-aware\n\nimport type { AgentWallet } from \"../wallet-core.js\";\nimport { X402Client } from \"./client.js\";\nimport type { X402ClientConfig } from \"./types.js\";\n\n/**\n * [MAX-ADDED] Create an x402-aware HTTP client.\n *\n * Usage:\n * const client = createX402Client(wallet, { globalDailyLimit: 10_000_000n });\n * const response = await client.fetch('https://api.example.com/data');\n * // If the endpoint returns 402, payment is handled automatically\n *\n * @param wallet - AgentWallet instance from createWallet()\n * @param config - Optional x402 client configuration\n * @returns X402Client with .fetch() method and budget controls\n */\nexport function createX402Client(\n wallet: AgentWallet,\n config?: X402ClientConfig,\n): X402Client {\n return new X402Client(wallet, config);\n}\n\n/**\n * [MAX-ADDED] Create an x402-aware fetch function (drop-in replacement).\n *\n * Usage:\n * const x402Fetch = createX402Fetch(wallet);\n * const response = await x402Fetch('https://api.example.com/data');\n *\n * @param wallet - AgentWallet instance from createWallet()\n * @param config - Optional x402 client configuration\n * @returns A fetch-compatible function that handles 402 payments\n */\nexport function createX402Fetch(\n wallet: AgentWallet,\n config?: X402ClientConfig,\n): typeof globalThis.fetch {\n const client = new X402Client(wallet, config);\n const impl = (input: string | URL | Request, init?: RequestInit) => {\n const url = input instanceof Request ? input.url : input.toString();\n return client.fetch(url, init);\n };\n return impl as typeof globalThis.fetch;\n}\n\n/**\n * [MAX-ADDED] Wrap an existing fetch-like function to be x402-aware.\n * Useful for wrapping custom HTTP clients or test mocks.\n *\n * @param fetchFn - The original fetch function to wrap\n * @param wallet - AgentWallet instance\n * @param config - Optional x402 client configuration\n */\nexport function wrapWithX402(\n fetchFn: typeof globalThis.fetch,\n wallet: AgentWallet,\n config?: X402ClientConfig,\n): typeof globalThis.fetch {\n const wrappedClient = new X402Client(wallet, config);\n\n const impl = async (\n input: string | URL | Request,\n init?: RequestInit,\n ): Promise<Response> => {\n const url = input instanceof Request ? input.url : input.toString();\n const response = await fetchFn(input, init);\n\n if (response.status !== 402) {\n return response;\n }\n\n // Parse and handle 402 via the client\n const paymentRequired = await wrappedClient.parse402Response(response);\n if (!paymentRequired) return response;\n\n const selected = wrappedClient.selectPaymentOption(paymentRequired.accepts);\n if (!selected) return response;\n\n // Use the client's fetch for retry (which calls globalThis.fetch)\n return wrappedClient.fetch(url, init);\n };\n return impl as typeof globalThis.fetch;\n}\n",
|
|
15
|
+
"// [MAX-ADDED] CCTP V2 Contract ABIs — Circle Cross-Chain Transfer Protocol V2\n// Sources: https://developers.circle.com/stablecoins/cctp-protocol-contract\n/**\n * CCTP V2 TokenMessengerV2 ABI (source chain)\n * Key function: depositForBurn — burns USDC and emits a MessageSent event\n */\nexport const TokenMessengerV2Abi = [\n {\n name: \"depositForBurn\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"amount\", type: \"uint256\" },\n { name: \"destinationDomain\", type: \"uint32\" },\n { name: \"mintRecipient\", type: \"bytes32\" },\n { name: \"burnToken\", type: \"address\" },\n { name: \"destinationCaller\", type: \"bytes32\" },\n { name: \"maxFee\", type: \"uint256\" },\n { name: \"minFinalityThreshold\", type: \"uint32\" },\n ],\n outputs: [{ name: \"nonce\", type: \"uint64\" }],\n },\n {\n name: \"depositForBurnWithHook\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"amount\", type: \"uint256\" },\n { name: \"destinationDomain\", type: \"uint32\" },\n { name: \"mintRecipient\", type: \"bytes32\" },\n { name: \"burnToken\", type: \"address\" },\n { name: \"destinationCaller\", type: \"bytes32\" },\n { name: \"maxFee\", type: \"uint256\" },\n { name: \"minFinalityThreshold\", type: \"uint32\" },\n { name: \"hookData\", type: \"bytes\" },\n ],\n outputs: [{ name: \"nonce\", type: \"uint64\" }],\n },\n {\n name: \"localMessageTransmitter\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"localDomain\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint32\" }],\n },\n];\n/**\n * CCTP V2 MessageTransmitterV2 ABI (destination chain)\n * Key function: receiveMessage — mints USDC using attested message\n */\nexport const MessageTransmitterV2Abi = [\n {\n name: \"receiveMessage\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"message\", type: \"bytes\" },\n { name: \"attestation\", type: \"bytes\" },\n ],\n outputs: [{ name: \"success\", type: \"bool\" }],\n },\n {\n name: \"usedNonces\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"\", type: \"bytes32\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"localDomain\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint32\" }],\n },\n];\n/**\n * Minimal ERC20 ABI — approve + allowance + balanceOf\n */\nexport const ERC20BridgeAbi = [\n {\n name: \"approve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"allowance\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n];\n/**\n * MessageTransmitter MessageSent event ABI — emitted during depositForBurn\n * Used to extract the CCTP message bytes and hash for attestation polling.\n */\nexport const MessageSentEventAbi = [\n {\n name: \"MessageSent\",\n type: \"event\",\n inputs: [{ name: \"message\", type: \"bytes\", indexed: false }],\n },\n];\n",
|
|
16
|
+
"/**\n * @module bridge/client\n * BridgeModule — CCTP V2 cross-chain USDC bridge for AgentWallet (EVM↔EVM).\n *\n * Implements a full EVM-to-EVM USDC bridge using Circle's CCTP V2 protocol.\n * Non-custodial: all signing is done locally via the agent's viem WalletClient.\n *\n * For EVM↔Solana bridging, see bridge/solana.ts.\n *\n * Supported chains: Ethereum, Avalanche, Optimism, Arbitrum, Base, Polygon,\n * Unichain, Linea, Sonic, Worldchain.\n *\n * Flow: approve USDC → depositForBurn → poll Circle IRIS → receiveMessage\n */\n// BridgeModule — CCTP V2 cross-chain USDC bridge for AgentWallet\n// Non-custodial: all signing is done locally via the agent's WalletClient.\nimport {\n type Chain,\n createPublicClient,\n getContract,\n type Hash,\n type Hex,\n http,\n keccak256,\n type PublicClient,\n pad,\n type TransactionReceipt,\n type WalletClient,\n} from \"viem\";\nimport {\n arbitrum,\n avalanche,\n base,\n linea,\n mainnet,\n optimism,\n polygon,\n} from \"viem/chains\";\nimport { requireWalletAccount } from \"../wallet-core.js\";\nimport {\n ERC20BridgeAbi,\n MessageTransmitterV2Abi,\n TokenMessengerV2Abi,\n} from \"./abis.js\";\nimport type {\n BridgeChain,\n BridgeOptions,\n BridgeResult,\n BurnResult,\n EVMBridgeChain,\n} from \"./types.js\";\nimport {\n ATTESTATION_POLL_INTERVAL_MS,\n BRIDGE_CHAIN_IDS,\n CCTP_DOMAIN_IDS,\n CIRCLE_ATTESTATION_API,\n FINALITY_THRESHOLD,\n MAX_ATTESTATION_POLLS,\n MESSAGE_TRANSMITTER_V2,\n TOKEN_MESSENGER_V2,\n USDC_CONTRACT,\n} from \"./types.js\";\n\n/**\n * Viem chain definitions for all supported EVM CCTP V2 chains.\n * Chains without built-in viem definitions use custom definitions.\n * Solana is NOT included — use bridge/solana.ts for EVM↔Solana bridging.\n */\nconst VIEM_CHAINS: Record<EVMBridgeChain, Chain> = {\n base,\n ethereum: mainnet,\n optimism,\n arbitrum,\n polygon,\n avalanche,\n linea,\n unichain: {\n id: 130,\n name: \"Unichain\",\n nativeCurrency: { name: \"ETH\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: { default: { http: [\"https://mainnet.unichain.org\"] } },\n },\n sonic: {\n id: 146,\n name: \"Sonic\",\n nativeCurrency: { name: \"S\", symbol: \"S\", decimals: 18 },\n rpcUrls: { default: { http: [\"https://rpc.soniclabs.com\"] } },\n },\n worldchain: {\n id: 480,\n name: \"World Chain\",\n nativeCurrency: { name: \"ETH\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: { http: [\"https://worldchain-mainnet.g.alchemy.com/public\"] },\n },\n },\n};\n\nexport class BridgeModule {\n private readonly walletClient: WalletClient;\n private readonly signerAccount: ReturnType<typeof requireWalletAccount>;\n private readonly publicClient: PublicClient;\n private readonly fromChain: EVMBridgeChain;\n\n constructor(\n walletClient: WalletClient,\n fromChain: EVMBridgeChain = \"base\",\n options: { rpcUrl?: string } = {},\n ) {\n this.signerAccount = requireWalletAccount(walletClient);\n this.walletClient = walletClient;\n this.fromChain = fromChain;\n this.publicClient = createPublicClient({\n chain: VIEM_CHAINS[fromChain],\n transport: http(options.rpcUrl),\n }) as PublicClient;\n }\n\n async bridge(\n amount: bigint,\n toChain: EVMBridgeChain,\n options: BridgeOptions = {},\n ): Promise<BridgeResult> {\n const startMs = Date.now();\n this.validateBridgeParams(amount, toChain);\n const account = this.signerAccount;\n const recipient = options.destinationAddress ?? account.address;\n const minFinalityThreshold =\n options.minFinalityThreshold ?? FINALITY_THRESHOLD.FAST;\n const maxFee = options.maxFee ?? 0n;\n const attestationApiUrl =\n options.attestationApiUrl ?? CIRCLE_ATTESTATION_API;\n\n await this.approveUsdc(amount);\n const burnResult = await this.depositForBurn(\n amount,\n toChain,\n recipient,\n minFinalityThreshold,\n maxFee,\n );\n const attestation = await this.pollForAttestation(\n burnResult.messageHash,\n this.fromChain,\n attestationApiUrl,\n );\n const mintTxHash = await this.receiveMessage(\n burnResult.messageBytes,\n attestation,\n toChain,\n options.destinationRpcUrl,\n );\n\n return {\n burnTxHash: burnResult.burnTxHash,\n mintTxHash,\n amount,\n fromChain: this.fromChain,\n toChain,\n recipient,\n nonce: burnResult.nonce,\n elapsedMs: Date.now() - startMs,\n };\n }\n\n async burn(\n amount: bigint,\n toChain: EVMBridgeChain,\n options: BridgeOptions = {},\n ): Promise<BurnResult> {\n this.validateBridgeParams(amount, toChain);\n const account = this.signerAccount;\n const recipient = options.destinationAddress ?? account.address;\n const minFinalityThreshold =\n options.minFinalityThreshold ?? FINALITY_THRESHOLD.FAST;\n const maxFee = options.maxFee ?? 0n;\n await this.approveUsdc(amount);\n return this.depositForBurn(\n amount,\n toChain,\n recipient,\n minFinalityThreshold,\n maxFee,\n );\n }\n\n async waitForAttestation(\n messageHash: Hex,\n apiUrl: string = CIRCLE_ATTESTATION_API,\n ): Promise<Hex> {\n return this.pollForAttestation(messageHash, this.fromChain, apiUrl);\n }\n\n async mint(\n messageBytes: Hex,\n attestation: Hex,\n toChain: EVMBridgeChain,\n destinationRpcUrl?: string,\n ): Promise<Hash> {\n return this.receiveMessage(\n messageBytes,\n attestation,\n toChain,\n destinationRpcUrl,\n );\n }\n\n async getUsdcBalance(): Promise<bigint> {\n const account = this.signerAccount;\n const usdc = getContract({\n address: USDC_CONTRACT[this.fromChain],\n abi: ERC20BridgeAbi,\n client: this.publicClient,\n });\n return usdc.read.balanceOf([account.address]) as Promise<bigint>;\n }\n\n async getUsdcAllowance(): Promise<bigint> {\n const account = this.signerAccount;\n const usdc = getContract({\n address: USDC_CONTRACT[this.fromChain],\n abi: ERC20BridgeAbi,\n client: this.publicClient,\n });\n return usdc.read.allowance([\n account.address,\n TOKEN_MESSENGER_V2[this.fromChain],\n ]) as Promise<bigint>;\n }\n\n private async approveUsdc(amount: bigint): Promise<void> {\n const account = this.signerAccount;\n const spender = TOKEN_MESSENGER_V2[this.fromChain];\n const usdcAddress = USDC_CONTRACT[this.fromChain];\n const usdc = getContract({\n address: usdcAddress,\n abi: ERC20BridgeAbi,\n client: this.publicClient,\n });\n const currentAllowance = (await usdc.read.allowance([\n account.address,\n spender,\n ])) as bigint;\n if (currentAllowance >= amount) return;\n\n const usdcWrite = getContract({\n address: usdcAddress,\n abi: ERC20BridgeAbi,\n client: { public: this.publicClient, wallet: this.walletClient },\n });\n const approveTxHash = await usdcWrite.write.approve([spender, amount], {\n account,\n chain: VIEM_CHAINS[this.fromChain],\n });\n const approveReceipt = await this.publicClient.waitForTransactionReceipt({\n hash: approveTxHash,\n });\n if (approveReceipt.status !== \"success\") {\n throw new BridgeError(\n \"INSUFFICIENT_ALLOWANCE\",\n `USDC approve failed (tx: ${approveTxHash}).`,\n );\n }\n }\n\n private async depositForBurn(\n amount: bigint,\n toChain: EVMBridgeChain,\n recipient: `0x${string}`,\n minFinalityThreshold: number,\n maxFee: bigint,\n ): Promise<BurnResult> {\n const account = this.signerAccount;\n const destinationDomain = CCTP_DOMAIN_IDS[toChain];\n const messengerAddress = TOKEN_MESSENGER_V2[this.fromChain];\n const usdcAddress = USDC_CONTRACT[this.fromChain];\n const mintRecipient = pad(recipient, { size: 32 });\n const destinationCaller = pad(\"0x0\" as Hex, { size: 32 });\n\n const messenger = getContract({\n address: messengerAddress,\n abi: TokenMessengerV2Abi,\n client: { public: this.publicClient, wallet: this.walletClient },\n });\n\n let burnTxHash: Hash;\n try {\n burnTxHash = await messenger.write.depositForBurn(\n [\n amount,\n destinationDomain,\n mintRecipient,\n usdcAddress,\n destinationCaller,\n maxFee,\n minFinalityThreshold,\n ],\n { account, chain: VIEM_CHAINS[this.fromChain] },\n );\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new BridgeError(\n \"BURN_FAILED\",\n `CCTP depositForBurn failed: ${msg}.`,\n );\n }\n\n const receipt = await this.publicClient.waitForTransactionReceipt({\n hash: burnTxHash,\n });\n if (receipt.status !== \"success\") {\n throw new BridgeError(\n \"BURN_FAILED\",\n `depositForBurn transaction reverted (tx: ${burnTxHash}).`,\n );\n }\n\n const { messageBytes, messageHash, nonce } =\n this.extractMessageSent(receipt);\n return {\n burnTxHash,\n nonce,\n messageHash,\n messageBytes,\n sourceDomain: CCTP_DOMAIN_IDS[this.fromChain],\n destinationDomain,\n };\n }\n\n private extractMessageSent(receipt: TransactionReceipt): {\n messageBytes: Hex;\n messageHash: Hex;\n nonce: bigint;\n } {\n const MESSAGE_SENT_TOPIC =\n \"0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036\";\n for (const log of receipt.logs) {\n if (log.topics[0]?.toLowerCase() === MESSAGE_SENT_TOPIC.toLowerCase()) {\n const rawData = log.data;\n if (rawData.length < 130) continue;\n const dataHex = rawData.slice(2);\n const lengthHex = dataHex.slice(64, 128);\n const messageLength = parseInt(lengthHex, 16);\n if (messageLength === 0) continue;\n const messageBytesHex = dataHex.slice(128, 128 + messageLength * 2);\n const messageBytes = `0x${messageBytesHex}` as Hex;\n const messageHash = keccak256(messageBytes);\n const nonceBytesHex = messageBytesHex.slice(24, 40);\n const nonce = BigInt(`0x${nonceBytesHex}`);\n return { messageBytes, messageHash, nonce };\n }\n }\n throw new BridgeError(\n \"BURN_FAILED\",\n \"Could not find MessageSent event in burn transaction receipt.\",\n );\n }\n\n private async pollForAttestation(\n messageHash: Hex,\n fromChain: EVMBridgeChain,\n apiUrl: string,\n ): Promise<Hex> {\n const sourceDomain = CCTP_DOMAIN_IDS[fromChain];\n const url = `${apiUrl}/v2/messages/${sourceDomain}/${messageHash}`;\n\n for (let attempt = 0; attempt < MAX_ATTESTATION_POLLS; attempt++) {\n let response: {\n status: string;\n attestation?: Hex | null;\n error?: string;\n };\n try {\n // @duplicate-component-audit-allow Circle attestation polling is not an LLM generation call.\n const res = await fetch(url, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n if (res.status === 404) {\n await this.sleep(ATTESTATION_POLL_INTERVAL_MS);\n continue;\n }\n const body = await res.text().catch(() => \"\");\n throw new BridgeError(\n \"ATTESTATION_ERROR\",\n `Circle API returned HTTP ${res.status}: ${body}.`,\n );\n }\n response = (await res.json()) as typeof response;\n } catch (err: unknown) {\n if (err instanceof BridgeError) throw err;\n const msg = err instanceof Error ? err.message : String(err);\n throw new BridgeError(\n \"ATTESTATION_ERROR\",\n `Failed to reach Circle IRIS API: ${msg}.`,\n );\n }\n\n if (response.status === \"complete\" && response.attestation)\n return response.attestation;\n if (response.status === \"error\") {\n throw new BridgeError(\n \"ATTESTATION_ERROR\",\n `Circle attestation failed: ${response.error ?? \"unknown error\"}.`,\n );\n }\n await this.sleep(ATTESTATION_POLL_INTERVAL_MS);\n }\n throw new BridgeError(\n \"ATTESTATION_TIMEOUT\",\n `Attestation not received after ${MAX_ATTESTATION_POLLS} attempts. Message hash: ${messageHash}.`,\n );\n }\n\n private async receiveMessage(\n messageBytes: Hex,\n attestation: Hex,\n toChain: EVMBridgeChain,\n destinationRpcUrl?: string,\n ): Promise<Hash> {\n const account = this.signerAccount;\n const transmitterAddress = MESSAGE_TRANSMITTER_V2[toChain];\n const destChain = VIEM_CHAINS[toChain];\n const destPublicClient = createPublicClient({\n chain: destChain,\n transport: http(destinationRpcUrl),\n }) as PublicClient;\n\n const transmitter = getContract({\n address: transmitterAddress,\n abi: MessageTransmitterV2Abi,\n client: { public: destPublicClient, wallet: this.walletClient },\n });\n\n let mintTxHash: Hash;\n try {\n mintTxHash = await transmitter.write.receiveMessage(\n [messageBytes, attestation],\n { account, chain: destChain },\n );\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new BridgeError(\n \"MINT_FAILED\",\n `CCTP receiveMessage failed on ${toChain}: ${msg}.`,\n );\n }\n\n const mintReceipt = await destPublicClient.waitForTransactionReceipt({\n hash: mintTxHash,\n });\n if (mintReceipt.status !== \"success\") {\n throw new BridgeError(\n \"MINT_FAILED\",\n `receiveMessage reverted on ${toChain} (tx: ${mintTxHash}).`,\n );\n }\n return mintTxHash;\n }\n\n private validateBridgeParams(amount: bigint, toChain: EVMBridgeChain): void {\n if (amount <= 0n) {\n throw new BridgeError(\n \"INVALID_AMOUNT\",\n `Bridge amount must be greater than 0. Received: ${amount}.`,\n );\n }\n if (!(toChain in CCTP_DOMAIN_IDS)) {\n throw new BridgeError(\n \"UNSUPPORTED_CHAIN\",\n `Chain '${toChain}' is not supported.`,\n );\n }\n if (toChain === this.fromChain) {\n throw new BridgeError(\n \"UNSUPPORTED_CHAIN\",\n `Source and destination chains must be different.`,\n );\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\nexport class BridgeError extends Error {\n readonly code: string;\n constructor(code: string, message: string) {\n super(`[BridgeModule:${code}] ${message}`);\n this.code = code;\n this.name = \"BridgeError\";\n }\n}\n\nexport function createBridge(\n walletClient: WalletClient,\n fromChain: EVMBridgeChain = \"base\",\n options: { rpcUrl?: string } = {},\n): BridgeModule {\n return new BridgeModule(walletClient, fromChain, options);\n}\n\nexport type {\n BridgeChain,\n BridgeOptions,\n BridgeResult,\n BurnResult,\n EVMBridgeChain,\n};\nexport {\n BRIDGE_CHAIN_IDS,\n CCTP_DOMAIN_IDS,\n FINALITY_THRESHOLD,\n MESSAGE_TRANSMITTER_V2,\n TOKEN_MESSENGER_V2,\n USDC_CONTRACT,\n};\n",
|
|
17
|
+
"/**\n * @module bridge/types\n * Type definitions and constants for the CCTP V2 cross-chain USDC bridge.\n *\n * Supports 10 EVM chains + Solana via Circle's Cross-Chain Transfer Protocol V2.\n * EVM chains: Ethereum, Avalanche, Optimism, Arbitrum, Base, Polygon,\n * Unichain, Linea, Sonic, Worldchain.\n * Non-EVM: Solana (via bridge/solana.ts — uses separate CCTP V2 programs).\n *\n * Contract addresses verified against:\n * - CCTP V2 EVM: https://developers.circle.com/cctp/references/contract-addresses\n * - Solana V2 programs: https://developers.circle.com/cctp/references/solana-programs\n * - USDC addresses: https://developers.circle.com/stablecoins/usdc-contract-addresses\n */\nimport type { Address, Hash, Hex } from \"viem\";\n\n/** Supported bridge destination chains */\nexport type BridgeChain =\n | \"ethereum\"\n | \"avalanche\"\n | \"optimism\"\n | \"arbitrum\"\n | \"base\"\n | \"polygon\"\n | \"unichain\"\n | \"linea\"\n | \"sonic\"\n | \"worldchain\"\n | \"solana\";\n\n/** EVM-only bridge chains (excludes non-EVM like Solana) */\nexport type EVMBridgeChain = Exclude<BridgeChain, \"solana\">;\n\n/**\n * CCTP V2 domain IDs — official Circle domain identifiers.\n * Source: https://developers.circle.com/cctp/references/contract-addresses\n * Solana domain: 5 — https://developers.circle.com/cctp/docs/solana\n */\nexport const CCTP_DOMAIN_IDS: Record<BridgeChain, number> = {\n ethereum: 0,\n avalanche: 1,\n optimism: 2,\n arbitrum: 3,\n base: 6,\n polygon: 7,\n unichain: 10,\n linea: 11,\n sonic: 13,\n worldchain: 14,\n solana: 5,\n};\n\n/**\n * EVM chain IDs for EVM-compatible bridge chains.\n * Solana is excluded — use solana.ts for Solana-specific operations.\n */\nexport const BRIDGE_CHAIN_IDS: Record<EVMBridgeChain, number> = {\n ethereum: 1,\n avalanche: 43114,\n optimism: 10,\n arbitrum: 42161,\n base: 8453,\n polygon: 137,\n unichain: 130,\n linea: 59144,\n sonic: 146,\n worldchain: 480,\n};\n\n/**\n * USDC contract addresses per chain (native Circle USDC, not bridged variants).\n * Solana USDC: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v (stored as string, not Address/Hex)\n */\nexport const USDC_CONTRACT: Record<EVMBridgeChain, Address> = {\n ethereum: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n avalanche: \"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E\",\n optimism: \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\",\n arbitrum: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n base: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n polygon: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n unichain: \"0x078D782b760474a361dDA0AF3839290b0EF57AD6\",\n linea: \"0x176211869cA2b568f2A7D4EE941E073a821EE1ff\",\n sonic: \"0x29219dd400f2Bf60E5a23d13Be72B486D4038894\",\n worldchain: \"0x79A02482A880bCE3B13e09Da970dC34db4CD24d1\",\n};\n\n/** Solana USDC mint address */\nexport const SOLANA_USDC_MINT =\n \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\" as const;\n\n/**\n * CCTP V2 TokenMessengerV2 — deterministic CREATE2 deployment, same address on all EVM chains.\n * Source: https://developers.circle.com/cctp/references/contract-addresses\n * Verified on-chain: BaseScan, Etherscan, Arbiscan (active transactions as of 2026-03-10)\n * Solana uses a different program — see bridge/solana.ts\n */\nconst CCTP_V2_TOKEN_MESSENGER: Address =\n \"0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d\";\n\nexport const TOKEN_MESSENGER_V2: Record<EVMBridgeChain, Address> = {\n ethereum: CCTP_V2_TOKEN_MESSENGER,\n avalanche: CCTP_V2_TOKEN_MESSENGER,\n optimism: CCTP_V2_TOKEN_MESSENGER,\n arbitrum: CCTP_V2_TOKEN_MESSENGER,\n base: CCTP_V2_TOKEN_MESSENGER,\n polygon: CCTP_V2_TOKEN_MESSENGER,\n unichain: CCTP_V2_TOKEN_MESSENGER,\n linea: CCTP_V2_TOKEN_MESSENGER,\n sonic: CCTP_V2_TOKEN_MESSENGER,\n worldchain: CCTP_V2_TOKEN_MESSENGER,\n};\n\n/**\n * CCTP V2 MessageTransmitterV2 — deterministic CREATE2 deployment, same address on all EVM chains.\n * Source: https://developers.circle.com/cctp/references/contract-addresses\n * Solana uses a different program — see bridge/solana.ts\n */\nconst CCTP_V2_MESSAGE_TRANSMITTER: Address =\n \"0x81D40F21F12A8F0E3252Bccb954D722d4c464B64\";\n\nexport const MESSAGE_TRANSMITTER_V2: Record<EVMBridgeChain, Address> = {\n ethereum: CCTP_V2_MESSAGE_TRANSMITTER,\n avalanche: CCTP_V2_MESSAGE_TRANSMITTER,\n optimism: CCTP_V2_MESSAGE_TRANSMITTER,\n arbitrum: CCTP_V2_MESSAGE_TRANSMITTER,\n base: CCTP_V2_MESSAGE_TRANSMITTER,\n polygon: CCTP_V2_MESSAGE_TRANSMITTER,\n unichain: CCTP_V2_MESSAGE_TRANSMITTER,\n linea: CCTP_V2_MESSAGE_TRANSMITTER,\n sonic: CCTP_V2_MESSAGE_TRANSMITTER,\n worldchain: CCTP_V2_MESSAGE_TRANSMITTER,\n};\n\n/**\n * CCTP V2 minFinalityThreshold values.\n * - FAST (0): ~12 seconds. Circle fast attestation.\n * - FINALIZED (1000): Full on-chain finality.\n */\nexport const FINALITY_THRESHOLD = {\n FAST: 0,\n FINALIZED: 1000,\n} as const;\n\n/** Circle IRIS attestation API base URL */\nexport const CIRCLE_ATTESTATION_API = \"https://iris-api.circle.com\";\n/** Max attestation polling attempts before timeout */\nexport const MAX_ATTESTATION_POLLS = 60;\n/** Polling interval for attestation (milliseconds) */\nexport const ATTESTATION_POLL_INTERVAL_MS = 5000;\n\n/** Options for a bridge operation */\nexport interface BridgeOptions {\n minFinalityThreshold?: number;\n maxFee?: bigint;\n destinationAddress?: Address;\n destinationRpcUrl?: string;\n attestationApiUrl?: string;\n}\n\n/** Result of a bridge.burn() operation */\nexport interface BurnResult {\n burnTxHash: Hash;\n nonce: bigint;\n messageHash: Hex;\n messageBytes: Hex;\n sourceDomain: number;\n destinationDomain: number;\n}\n\n/** Circle attestation status */\nexport type AttestationStatus = \"pending_confirmations\" | \"complete\" | \"error\";\n\n/** Circle IRIS API response for an attestation */\nexport interface AttestationResponse {\n status: AttestationStatus;\n attestation: Hex | null;\n error?: string;\n}\n\n/** Result of the full EVM↔EVM bridge() operation */\nexport interface BridgeResult {\n burnTxHash: Hash;\n mintTxHash: Hash;\n amount: bigint;\n fromChain: EVMBridgeChain;\n toChain: EVMBridgeChain;\n recipient: Address;\n nonce: bigint;\n elapsedMs: number;\n}\n\n/** Error codes for actionable bridge error messages */\nexport type BridgeErrorCode =\n | \"UNSUPPORTED_CHAIN\"\n | \"INSUFFICIENT_ALLOWANCE\"\n | \"INSUFFICIENT_BALANCE\"\n | \"BURN_FAILED\"\n | \"ATTESTATION_TIMEOUT\"\n | \"ATTESTATION_ERROR\"\n | \"MINT_FAILED\"\n | \"INVALID_AMOUNT\"\n | \"NO_WALLET_CLIENT\";\n",
|
|
18
|
+
"/**\n * SolanaBridgeModule — CCTP V2 cross-chain USDC bridge between EVM chains and Solana.\n *\n * Uses Circle's Cross-Chain Transfer Protocol (CCTP) V2 for trustless USDC transfers.\n * EVM side uses viem; Solana side uses @solana/web3.js as an optional peer dependency.\n *\n * Sources:\n * - Circle CCTP Solana docs: https://developers.circle.com/cctp/docs/solana\n * - Solana USDC mint: https://solana.com/ecosystem/usdc\n * - CCTP domain IDs: https://developers.circle.com/cctp/references/contract-addresses\n */\n\nimport {\n type Address,\n type Chain,\n createPublicClient,\n getContract,\n type Hash,\n type Hex,\n http,\n keccak256,\n type PublicClient,\n pad,\n type WalletClient,\n} from \"viem\";\nimport {\n arbitrum,\n avalanche,\n base,\n linea,\n mainnet,\n optimism,\n polygon,\n} from \"viem/chains\";\nimport {\n ERC20BridgeAbi,\n MessageTransmitterV2Abi,\n TokenMessengerV2Abi,\n} from \"./abis.js\";\nimport {\n ATTESTATION_POLL_INTERVAL_MS,\n CCTP_DOMAIN_IDS,\n CIRCLE_ATTESTATION_API,\n type EVMBridgeChain,\n FINALITY_THRESHOLD,\n MAX_ATTESTATION_POLLS,\n MESSAGE_TRANSMITTER_V2 as MESSAGE_TRANSMITTER_V2_MAP,\n TOKEN_MESSENGER_V2,\n USDC_CONTRACT,\n} from \"./types.js\";\n\n// ─── Solana Constants ───\n\n/** Solana CCTP domain ID */\nexport const SOLANA_CCTP_DOMAIN = 5;\n\n/** Native USDC mint on Solana Mainnet */\nexport const SOLANA_USDC_MINT =\n \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\" as const;\n\n/**\n * Solana CCTP V2 TokenMessengerMinterV2 program address.\n * This is the V2 program (not V1 CCTPiPYP...). The V2 program combines\n * TokenMessengerV2 + TokenMinterV2 into a single program.\n * Source: https://developers.circle.com/cctp/references/solana-programs\n * Verified: https://github.com/circlefin/solana-cctp-contracts (programs/v2)\n */\nexport const SOLANA_TOKEN_MESSENGER =\n \"CCTPV2vPZJS2u2BBsUoscuikbYjnpFmbFsvVuJdgUMQe\" as const;\n\n/**\n * Solana CCTP V2 MessageTransmitterV2 program address.\n * This is the V2 program (not V1 CCTPmbSD...).\n * Source: https://developers.circle.com/cctp/references/solana-programs\n * Verified: https://github.com/circlefin/solana-cctp-contracts (programs/v2)\n */\nexport const SOLANA_MESSAGE_TRANSMITTER =\n \"CCTPV2Sm4AdWt5296sk4P66VBZ7bEhcARwFaaS9YPbeC\" as const;\n\n/** Default Solana Mainnet RPC endpoint */\nexport const SOLANA_DEFAULT_RPC =\n \"https://api.mainnet-beta.solana.com\" as const;\n\n// ─── Viem chain definitions for EVM side ───\n\nconst VIEM_CHAINS: Record<EVMBridgeChain, Chain> = {\n base,\n ethereum: mainnet,\n optimism,\n arbitrum,\n polygon,\n avalanche,\n linea,\n unichain: {\n id: 130,\n name: \"Unichain\",\n nativeCurrency: { name: \"ETH\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: { default: { http: [\"https://mainnet.unichain.org\"] } },\n },\n sonic: {\n id: 146,\n name: \"Sonic\",\n nativeCurrency: { name: \"S\", symbol: \"S\", decimals: 18 },\n rpcUrls: { default: { http: [\"https://rpc.soniclabs.com\"] } },\n },\n worldchain: {\n id: 480,\n name: \"World Chain\",\n nativeCurrency: { name: \"ETH\", symbol: \"ETH\", decimals: 18 },\n rpcUrls: {\n default: { http: [\"https://worldchain-mainnet.g.alchemy.com/public\"] },\n },\n },\n};\n\n// ─── Helpers ───\n\n/**\n * Encode a Solana base58 public key as a 32-byte hex buffer for CCTP.\n * CCTP requires the mint recipient to be a 32-byte zero-padded value.\n * For Solana, this is the base58-decoded public key (already 32 bytes).\n */\nfunction solanaPubkeyToBytes32(base58Address: string): Hex {\n // Dynamic import for optional @solana/web3.js\n // We manually decode base58 here to avoid requiring the dependency at import time.\n const ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n const bytes = new Uint8Array(32);\n let intVal = 0n;\n for (const char of base58Address) {\n const digit = BigInt(ALPHABET.indexOf(char));\n if (digit < 0n)\n throw new Error(\n `SolanaBridge: Invalid base58 character '${char}' in address.`,\n );\n intVal = intVal * 58n + digit;\n }\n // Write to 32-byte big-endian buffer\n for (let i = 31; i >= 0; i--) {\n bytes[i] = Number(intVal & 0xffn);\n intVal >>= 8n;\n }\n if (intVal !== 0n)\n throw new Error(`SolanaBridge: Address value overflows 32 bytes.`);\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return `0x${hex}` as Hex;\n}\n\n/**\n * Decode a 32-byte hex buffer back to a Solana base58 public key.\n * Used when interpreting Solana→EVM message recipient fields.\n */\nexport function bytes32ToSolanaPubkey(bytes32: Hex): string {\n const ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n const hex = bytes32.startsWith(\"0x\") ? bytes32.slice(2) : bytes32;\n if (hex.length !== 64)\n throw new Error(\n `SolanaBridge: Expected 32-byte hex (64 chars), got ${hex.length}.`,\n );\n let intVal = BigInt(`0x${hex}`);\n let result = \"\";\n while (intVal > 0n) {\n const rem = Number(intVal % 58n);\n intVal /= 58n;\n result = ALPHABET[rem] + result;\n }\n return result || \"1\";\n}\n\n// ─── EVM→Solana Bridge ───\n\nexport interface EVMToSolanaOptions {\n /** Solana recipient address (base58). Defaults to the EVM signer's address re-encoded — usually wrong; always specify. */\n solanaRecipient: string;\n /** EVM source chain. Defaults to 'base'. */\n fromChain?: EVMBridgeChain;\n /** Optional EVM RPC URL override. */\n evmRpcUrl?: string;\n /** Finality threshold: FAST (0) or FINALIZED (1000). Default: FAST. */\n minFinalityThreshold?: number;\n /** Max bridge fee in USDC base units. Default: 0 (no fee). */\n maxFee?: bigint;\n /** Circle IRIS API URL override. */\n attestationApiUrl?: string;\n}\n\nexport interface EVMToSolanaResult {\n /** EVM burn transaction hash */\n burnTxHash: Hash;\n /** Circle message hash (used to poll for attestation) */\n messageHash: Hex;\n /** Raw CCTP message bytes (for manual receiveMessage on Solana) */\n messageBytes: Hex;\n /** Circle attestation signature (for receiveMessage on Solana) */\n attestation: Hex;\n /** The Solana CCTP domain (5) */\n destinationDomain: number;\n /** Amount bridged in USDC base units */\n amount: bigint;\n /** Elapsed time in milliseconds */\n elapsedMs: number;\n}\n\n/**\n * Bridge USDC from an EVM chain to Solana using CCTP V2.\n *\n * This function handles the EVM burn side and attestation polling.\n * The Solana receive side must be completed by calling `receiveMessageOnSolana()`\n * or by the Solana recipient manually submitting the message and attestation\n * to the Solana MessageTransmitter program.\n *\n * @param walletClient - Viem WalletClient with a signer attached (for EVM)\n * @param amount - Amount to bridge in USDC base units (6 decimals, e.g. 1_000_000n = 1 USDC)\n * @param options - Bridge options including solanaRecipient (required)\n * @returns Burn tx hash, attestation, and message bytes for Solana receive\n */\nexport async function bridgeEVMToSolana(\n walletClient: WalletClient,\n amount: bigint,\n options: EVMToSolanaOptions,\n): Promise<EVMToSolanaResult> {\n const startMs = Date.now();\n const fromChain = options.fromChain ?? \"base\";\n const minFinalityThreshold =\n options.minFinalityThreshold ?? FINALITY_THRESHOLD.FAST;\n const maxFee = options.maxFee ?? 0n;\n const attestationApiUrl = options.attestationApiUrl ?? CIRCLE_ATTESTATION_API;\n\n if (!walletClient.account) {\n throw new SolanaBridgeError(\n \"NO_WALLET_CLIENT\",\n \"WalletClient must have an account attached.\",\n );\n }\n if (amount <= 0n) {\n throw new SolanaBridgeError(\n \"INVALID_AMOUNT\",\n `Bridge amount must be > 0. Received: ${amount}.`,\n );\n }\n if (!options.solanaRecipient) {\n throw new SolanaBridgeError(\n \"INVALID_RECIPIENT\",\n \"solanaRecipient (base58 Solana address) is required.\",\n );\n }\n\n // Encode Solana address as 32-byte CCTP mint recipient\n const mintRecipient = solanaPubkeyToBytes32(options.solanaRecipient);\n\n // Zero destinationCaller = any relayer can submit on Solana\n const destinationCaller = pad(\"0x0\" as Hex, { size: 32 });\n\n const publicClient = createPublicClient({\n chain: VIEM_CHAINS[fromChain],\n transport: http(options.evmRpcUrl),\n }) as PublicClient;\n\n const account = walletClient.account;\n const usdcAddress = USDC_CONTRACT[fromChain];\n const messengerAddress = TOKEN_MESSENGER_V2[fromChain];\n\n // Approve USDC if needed\n const usdcRead = getContract({\n address: usdcAddress,\n abi: ERC20BridgeAbi,\n client: publicClient,\n });\n const currentAllowance = (await usdcRead.read.allowance([\n account.address,\n messengerAddress,\n ])) as bigint;\n if (currentAllowance < amount) {\n const usdcWrite = getContract({\n address: usdcAddress,\n abi: ERC20BridgeAbi,\n client: { public: publicClient, wallet: walletClient },\n });\n const approveTxHash = await usdcWrite.write.approve(\n [messengerAddress, amount],\n {\n account,\n chain: VIEM_CHAINS[fromChain],\n },\n );\n const approveReceipt = await publicClient.waitForTransactionReceipt({\n hash: approveTxHash,\n });\n if (approveReceipt.status !== \"success\") {\n throw new SolanaBridgeError(\n \"INSUFFICIENT_ALLOWANCE\",\n `USDC approve failed (tx: ${approveTxHash}).`,\n );\n }\n }\n\n // Burn USDC via CCTP V2 depositForBurn targeting Solana domain\n const messenger = getContract({\n address: messengerAddress,\n abi: TokenMessengerV2Abi,\n client: { public: publicClient, wallet: walletClient },\n });\n\n let burnTxHash: Hash;\n try {\n burnTxHash = await messenger.write.depositForBurn(\n [\n amount,\n SOLANA_CCTP_DOMAIN,\n mintRecipient,\n usdcAddress,\n destinationCaller,\n maxFee,\n minFinalityThreshold,\n ],\n { account, chain: VIEM_CHAINS[fromChain] },\n );\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SolanaBridgeError(\n \"BURN_FAILED\",\n `CCTP depositForBurn to Solana failed: ${msg}.`,\n );\n }\n\n const receipt = await publicClient.waitForTransactionReceipt({\n hash: burnTxHash,\n });\n if (receipt.status !== \"success\") {\n throw new SolanaBridgeError(\n \"BURN_FAILED\",\n `depositForBurn transaction reverted (tx: ${burnTxHash}).`,\n );\n }\n\n // Extract message bytes from MessageSent event\n const { messageBytes, messageHash } = extractMessageSent(receipt.logs);\n\n // Poll Circle IRIS for attestation\n const attestation = await pollForAttestation(\n messageHash,\n CCTP_DOMAIN_IDS[fromChain],\n attestationApiUrl,\n );\n\n return {\n burnTxHash,\n messageHash,\n messageBytes,\n attestation,\n destinationDomain: SOLANA_CCTP_DOMAIN,\n amount,\n elapsedMs: Date.now() - startMs,\n };\n}\n\n// ─── Solana→EVM Bridge ───\n\nexport interface SolanaToEVMOptions {\n /** EVM destination chain */\n toChain: EVMBridgeChain;\n /** Optional EVM destination RPC URL override */\n evmRpcUrl?: string;\n /** EVM recipient address. Defaults to the EVM walletClient's account address. */\n evmRecipient?: Address;\n /** Circle IRIS API URL override */\n attestationApiUrl?: string;\n /** Solana RPC URL override */\n solanaRpcUrl?: string;\n}\n\nexport interface SolanaToEVMBurnParams {\n /** Raw CCTP message bytes from Solana burn transaction */\n messageBytes: Hex;\n /** Circle message hash */\n messageHash: Hex;\n /** Source domain (should be SOLANA_CCTP_DOMAIN = 5) */\n sourceDomain: number;\n}\n\nexport interface SolanaToEVMResult {\n /** EVM mint transaction hash */\n mintTxHash: Hash;\n /** Amount received in USDC base units */\n amount: bigint;\n /** EVM destination chain */\n toChain: EVMBridgeChain;\n /** EVM recipient address */\n recipient: Address;\n /** Elapsed time in milliseconds */\n elapsedMs: number;\n}\n\n/**\n * Complete the Solana→EVM bridge by polling for Circle's attestation and minting on EVM.\n *\n * The caller is responsible for initiating the Solana burn via the Solana\n * CCTP MessageTransmitter and passing the resulting messageBytes + messageHash here.\n *\n * @param walletClient - Viem WalletClient (for EVM signing)\n * @param burnParams - Message bytes and hash from the Solana burn transaction\n * @param options - Destination chain and optional overrides\n */\nexport async function receiveFromSolanaOnEVM(\n walletClient: WalletClient,\n burnParams: SolanaToEVMBurnParams,\n options: SolanaToEVMOptions,\n): Promise<SolanaToEVMResult> {\n const startMs = Date.now();\n const { toChain, evmRpcUrl } = options;\n const attestationApiUrl = options.attestationApiUrl ?? CIRCLE_ATTESTATION_API;\n\n if (!walletClient.account) {\n throw new SolanaBridgeError(\n \"NO_WALLET_CLIENT\",\n \"WalletClient must have an account attached.\",\n );\n }\n\n const account = walletClient.account;\n const recipient = options.evmRecipient ?? account.address;\n\n // Poll Circle IRIS for attestation\n const attestation = await pollForAttestation(\n burnParams.messageHash,\n burnParams.sourceDomain,\n attestationApiUrl,\n );\n\n // Submit receiveMessage on EVM\n const transmitterAddress = MESSAGE_TRANSMITTER_V2_MAP[toChain];\n const destChain = VIEM_CHAINS[toChain];\n const destPublicClient = createPublicClient({\n chain: destChain,\n transport: http(evmRpcUrl),\n }) as PublicClient;\n\n const transmitter = getContract({\n address: transmitterAddress,\n abi: MessageTransmitterV2Abi,\n client: { public: destPublicClient, wallet: walletClient },\n });\n\n let mintTxHash: Hash;\n try {\n mintTxHash = await transmitter.write.receiveMessage(\n [burnParams.messageBytes, attestation],\n { account, chain: destChain },\n );\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SolanaBridgeError(\n \"MINT_FAILED\",\n `CCTP receiveMessage on ${toChain} failed: ${msg}.`,\n );\n }\n\n const mintReceipt = await destPublicClient.waitForTransactionReceipt({\n hash: mintTxHash,\n });\n if (mintReceipt.status !== \"success\") {\n throw new SolanaBridgeError(\n \"MINT_FAILED\",\n `receiveMessage reverted on ${toChain} (tx: ${mintTxHash}).`,\n );\n }\n\n // Parse amount from mint receipt logs (MintAndWithdraw event)\n // Fallback: return 0n if event not found (amount can be retrieved from the original Solana tx)\n const amount = parseMintAmount(mintReceipt.logs);\n\n return {\n mintTxHash,\n amount,\n toChain,\n recipient,\n elapsedMs: Date.now() - startMs,\n };\n}\n\n// ─── Shared helpers ───\n\n/**\n * Extract CCTP MessageSent event from EVM transaction logs.\n * Event topic: keccak256(\"MessageSent(bytes)\") = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036\n */\nfunction extractMessageSent(\n logs: readonly { topics: readonly Hex[]; data: Hex }[],\n): { messageBytes: Hex; messageHash: Hex } {\n const MESSAGE_SENT_TOPIC =\n \"0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036\";\n for (const log of logs) {\n if (log.topics[0]?.toLowerCase() === MESSAGE_SENT_TOPIC.toLowerCase()) {\n const dataHex = log.data.slice(2);\n if (dataHex.length < 128) continue;\n const lengthHex = dataHex.slice(64, 128);\n const messageLength = parseInt(lengthHex, 16);\n if (messageLength === 0) continue;\n const messageBytesHex = dataHex.slice(128, 128 + messageLength * 2);\n const messageBytes = `0x${messageBytesHex}` as Hex;\n const messageHash = keccak256(messageBytes);\n return { messageBytes, messageHash };\n }\n }\n throw new SolanaBridgeError(\n \"BURN_FAILED\",\n \"Could not find MessageSent event in burn transaction receipt.\",\n );\n}\n\n/** Parse USDC amount from MintAndWithdraw event logs (best-effort). */\nfunction parseMintAmount(\n logs: readonly { topics: readonly Hex[]; data: Hex }[],\n): bigint {\n // MintAndWithdraw(address,uint256,address) — topic0 = keccak256(\"MintAndWithdraw(address,uint256,address)\")\n const MINT_AND_WITHDRAW_TOPIC =\n \"0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e9\";\n for (const log of logs) {\n if (\n log.topics[0]?.toLowerCase() === MINT_AND_WITHDRAW_TOPIC.toLowerCase()\n ) {\n // amount is the second indexed param OR first data word\n if (log.data.length >= 66) {\n return BigInt(`0x${log.data.slice(2, 66)}`);\n }\n }\n }\n return 0n; // fallback: caller can determine amount from source transaction\n}\n\n/** Poll Circle IRIS attestation API. */\nasync function pollForAttestation(\n messageHash: Hex,\n sourceDomain: number,\n apiUrl: string,\n): Promise<Hex> {\n const url = `${apiUrl}/v2/messages/${sourceDomain}/${messageHash}`;\n for (let attempt = 0; attempt < MAX_ATTESTATION_POLLS; attempt++) {\n let response: { status: string; attestation?: Hex | null; error?: string };\n try {\n // @duplicate-component-audit-allow Circle attestation polling is not an LLM generation call.\n const res = await fetch(url, { headers: { Accept: \"application/json\" } });\n if (!res.ok) {\n if (res.status === 404) {\n await sleep(ATTESTATION_POLL_INTERVAL_MS);\n continue;\n }\n const body = await res.text().catch(() => \"\");\n throw new SolanaBridgeError(\n \"ATTESTATION_ERROR\",\n `Circle API returned HTTP ${res.status}: ${body}.`,\n );\n }\n response = (await res.json()) as typeof response;\n } catch (err: unknown) {\n if (err instanceof SolanaBridgeError) throw err;\n const msg = err instanceof Error ? err.message : String(err);\n throw new SolanaBridgeError(\n \"ATTESTATION_ERROR\",\n `Failed to reach Circle IRIS API: ${msg}.`,\n );\n }\n\n if (response.status === \"complete\" && response.attestation)\n return response.attestation;\n if (response.status === \"error\") {\n throw new SolanaBridgeError(\n \"ATTESTATION_ERROR\",\n `Circle attestation failed: ${response.error ?? \"unknown error\"}.`,\n );\n }\n await sleep(ATTESTATION_POLL_INTERVAL_MS);\n }\n throw new SolanaBridgeError(\n \"ATTESTATION_TIMEOUT\",\n `Attestation not received after ${MAX_ATTESTATION_POLLS} attempts. Message hash: ${messageHash}.`,\n );\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ─── Error Class ───\n\nexport type SolanaBridgeErrorCode =\n | \"NO_WALLET_CLIENT\"\n | \"INVALID_AMOUNT\"\n | \"INVALID_RECIPIENT\"\n | \"INSUFFICIENT_ALLOWANCE\"\n | \"BURN_FAILED\"\n | \"ATTESTATION_ERROR\"\n | \"ATTESTATION_TIMEOUT\"\n | \"MINT_FAILED\";\n\nexport class SolanaBridgeError extends Error {\n readonly code: SolanaBridgeErrorCode;\n constructor(code: SolanaBridgeErrorCode, message: string) {\n super(`[SolanaBridge:${code}] ${message}`);\n this.code = code;\n this.name = \"SolanaBridgeError\";\n }\n}\n",
|
|
19
|
+
"/**\n * ERC-8004: Trustless Agents — Identity Registry Integration\n *\n * Implements the Identity Registry component of ERC-8004, which provides every\n * AI agent with a portable, censorship-resistant on-chain identifier using ERC-721\n * with URIStorage extension.\n *\n * Spec: https://eips.ethereum.org/EIPS/eip-8004\n * Status: DRAFT (August 2025). No official mainnet singleton deployed yet.\n * Key Principle: Non-custodial. All signing happens locally via WalletClient.\n */\nimport {\n type Address,\n type Chain,\n createPublicClient,\n getContract,\n type Hash,\n type Hex,\n http,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\nimport {\n arbitrum,\n arbitrumSepolia,\n base,\n baseSepolia,\n mainnet,\n polygon,\n} from \"viem/chains\";\n\n// ─── ABI ─────────────────────────────────────────────────────────────────────\n\nexport const ERC8004IdentityRegistryAbi = [\n // register() — no args\n {\n name: \"register\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [{ name: \"agentId\", type: \"uint256\" }],\n },\n // register(string) — URI only\n {\n name: \"register\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"agentURI\", type: \"string\" }],\n outputs: [{ name: \"agentId\", type: \"uint256\" }],\n },\n // register(string,tuple[]) — URI + metadata\n {\n name: \"register\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentURI\", type: \"string\" },\n {\n name: \"metadata\",\n type: \"tuple[]\",\n components: [\n { name: \"metadataKey\", type: \"string\" },\n { name: \"metadataValue\", type: \"bytes\" },\n ],\n },\n ],\n outputs: [{ name: \"agentId\", type: \"uint256\" }],\n },\n {\n name: \"setAgentURI\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"newURI\", type: \"string\" },\n ],\n outputs: [],\n },\n {\n name: \"tokenURI\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"agentId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n {\n name: \"getMetadata\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"metadataKey\", type: \"string\" },\n ],\n outputs: [{ name: \"\", type: \"bytes\" }],\n },\n {\n name: \"setMetadata\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"metadataKey\", type: \"string\" },\n { name: \"metadataValue\", type: \"bytes\" },\n ],\n outputs: [],\n },\n {\n name: \"getAgentWallet\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"agentId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"setAgentWallet\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"newWallet\", type: \"address\" },\n { name: \"deadline\", type: \"uint256\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n outputs: [],\n },\n {\n name: \"unsetAgentWallet\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"agentId\", type: \"uint256\" }],\n outputs: [],\n },\n {\n name: \"ownerOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"tokenId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"Registered\",\n type: \"event\",\n inputs: [\n { name: \"agentId\", type: \"uint256\", indexed: true },\n { name: \"agentURI\", type: \"string\", indexed: false },\n { name: \"owner\", type: \"address\", indexed: true },\n ],\n },\n {\n name: \"URIUpdated\",\n type: \"event\",\n inputs: [\n { name: \"agentId\", type: \"uint256\", indexed: true },\n { name: \"newURI\", type: \"string\", indexed: false },\n { name: \"updatedBy\", type: \"address\", indexed: true },\n ],\n },\n {\n name: \"MetadataSet\",\n type: \"event\",\n inputs: [\n { name: \"agentId\", type: \"uint256\", indexed: true },\n { name: \"indexedMetadataKey\", type: \"string\", indexed: true },\n { name: \"metadataKey\", type: \"string\", indexed: false },\n { name: \"metadataValue\", type: \"bytes\", indexed: false },\n ],\n },\n] as const;\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface AgentServiceEndpoint {\n name: string;\n endpoint: string;\n version?: string;\n skills?: string[];\n domains?: string[];\n}\n\nexport type SupportedTrustMechanism =\n | \"reputation\"\n | \"crypto-economic\"\n | \"tee-attestation\"\n | \"zkml\"\n | string;\n\nexport interface AgentRegistrationRef {\n agentId: number;\n agentRegistry: string;\n}\n\nexport interface AgentRegistrationFile {\n type: string;\n name: string;\n description: string;\n image?: string;\n services?: AgentServiceEndpoint[];\n x402Support?: boolean;\n active?: boolean;\n registrations?: AgentRegistrationRef[];\n supportedTrust?: SupportedTrustMechanism[];\n [key: string]: unknown;\n}\n\nexport interface AgentModelMetadata {\n model?: string;\n provider?: string;\n version?: string;\n capabilities?: string[];\n framework?: string;\n}\n\nexport interface AgentIdentity {\n agentId: bigint;\n owner: Address;\n agentURI: string;\n agentWallet: Address;\n registrationFile: AgentRegistrationFile | null;\n modelMetadata: AgentModelMetadata | null;\n}\n\nexport interface MetadataEntry {\n metadataKey: string;\n metadataValue: Hex;\n}\n\nexport type SupportedChain =\n | \"base\"\n | \"base-sepolia\"\n | \"ethereum\"\n | \"arbitrum\"\n | \"polygon\"\n | \"arbitrum-sepolia\";\n\nexport interface ERC8004ClientConfig {\n registryAddress?: Address;\n chain: SupportedChain;\n rpcUrl?: string;\n}\n\nexport interface RegistrationResult {\n txHash: Hash;\n agentId: bigint | null;\n}\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nexport const METADATA_KEYS = {\n AGENT_WALLET: \"agentWallet\",\n MODEL: \"agentModel\",\n MODEL_PROVIDER: \"agentModelProvider\",\n VERSION: \"agentVersion\",\n CAPABILITIES: \"agentCapabilities\",\n FRAMEWORK: \"agentFramework\",\n} as const;\n\nexport const REGISTRATION_FILE_TYPE =\n \"https://eips.ethereum.org/EIPS/eip-8004#registration-v1\";\n\nexport const KNOWN_REGISTRY_ADDRESSES: Record<\n string,\n { identity: Address; reputation: Address; validation?: Address }\n> = {\n ethereum: {\n identity: \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\",\n reputation: \"0x8004BAa17C55a88189AE136b182e5fdA19dE9b63\",\n },\n base: {\n identity: \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\",\n reputation: \"0x8004BAa17C55a88189AE136b182e5fdA19dE9b63\",\n },\n arbitrum: {\n identity: \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\",\n reputation: \"0x8004BAa17C55a88189AE136b182e5fdA19dE9b63\",\n },\n polygon: {\n identity: \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\",\n reputation: \"0x8004BAa17C55a88189AE136b182e5fdA19dE9b63\",\n },\n \"base-sepolia\": {\n identity: \"0x8004A818BFB912233c491871b3d84c89A494BD9e\",\n reputation: \"0x8004B663056A597Dffe9eCcC1965A193B7388713\",\n },\n \"arbitrum-sepolia\": {\n identity: \"0x8004A818BFB912233c491871b3d84c89A494BD9e\",\n reputation: \"0x8004B663056A597Dffe9eCcC1965A193B7388713\",\n },\n};\n\nconst CHAINS: Record<string, Chain> = {\n base,\n \"base-sepolia\": baseSepolia,\n ethereum: mainnet,\n arbitrum,\n polygon,\n \"arbitrum-sepolia\": arbitrumSepolia,\n};\n\nconst REGISTERED_TOPIC =\n \"0xca52e62c367d81bb2e328eb795f7c7ba24afb478408a26c0e201d155c449bc4a\";\n\n// ─── Client ──────────────────────────────────────────────────────────────────\n\nexport class ERC8004Client {\n private readonly publicClient: PublicClient;\n private readonly config: ERC8004ClientConfig & { registryAddress: Address };\n private readonly chain: Chain;\n\n constructor(config: ERC8004ClientConfig) {\n // Auto-resolve registry address from KNOWN_REGISTRY_ADDRESSES if not explicitly provided\n const resolvedAddress =\n config.registryAddress ??\n KNOWN_REGISTRY_ADDRESSES[config.chain]?.identity;\n if (!resolvedAddress) {\n throw new Error(\n `ERC8004Client: No registry address provided and no known address for chain \"${config.chain}\"`,\n );\n }\n this.config = { ...config, registryAddress: resolvedAddress };\n const chain = CHAINS[config.chain];\n if (!chain)\n throw new Error(`ERC8004Client: Unsupported chain \"${config.chain}\"`);\n this.chain = chain;\n this.publicClient = createPublicClient({\n chain,\n transport: http(config.rpcUrl),\n });\n }\n\n private getReadContract() {\n return getContract({\n address: this.config.registryAddress,\n abi: ERC8004IdentityRegistryAbi,\n client: this.publicClient,\n });\n }\n\n private getWriteContract(walletClient: WalletClient) {\n return getContract({\n address: this.config.registryAddress,\n abi: ERC8004IdentityRegistryAbi,\n client: { public: this.publicClient, wallet: walletClient },\n });\n }\n\n async registerAgent(\n walletClient: WalletClient,\n metadata: Omit<AgentRegistrationFile, \"type\">,\n agentURI?: string,\n onChainMetadata?: Record<string, string>,\n ): Promise<RegistrationResult> {\n if (!walletClient.account)\n throw new Error(\"ERC8004Client: WalletClient has no account\");\n\n const registrationFile = {\n type: REGISTRATION_FILE_TYPE,\n ...metadata,\n } as AgentRegistrationFile;\n const resolvedURI = agentURI ?? buildDataURI(registrationFile);\n const contract = this.getWriteContract(walletClient);\n\n let txHash: Hash;\n if (onChainMetadata && Object.keys(onChainMetadata).length > 0) {\n const entries = encodeMetadataEntries(onChainMetadata);\n txHash = await contract.write.register([resolvedURI, entries], {\n account: walletClient.account,\n chain: this.chain,\n });\n } else {\n txHash = await contract.write.register([resolvedURI], {\n account: walletClient.account,\n chain: this.chain,\n });\n }\n\n let agentId: bigint | null = null;\n try {\n const receipt = await this.publicClient.waitForTransactionReceipt({\n hash: txHash,\n });\n const registeredEvent = receipt.logs.find(\n (log) =>\n log.address.toLowerCase() ===\n this.config.registryAddress.toLowerCase() &&\n log.topics[0] === REGISTERED_TOPIC,\n );\n if (registeredEvent?.topics[1]) {\n agentId = BigInt(registeredEvent.topics[1]);\n }\n } catch {\n // agentId remains null\n }\n\n return { txHash, agentId };\n }\n\n async lookupAgentIdentity(agentId: bigint): Promise<AgentIdentity> {\n const contract = this.getReadContract();\n const [owner, agentURI, agentWallet] = await Promise.all([\n contract.read.ownerOf([agentId]),\n contract.read.tokenURI([agentId]),\n contract.read.getAgentWallet([agentId]),\n ]);\n\n let registrationFile: AgentRegistrationFile | null = null;\n try {\n registrationFile = await resolveAgentURI(agentURI as string);\n } catch {\n /* unavailable */\n }\n\n const modelMetadata = await this.readModelMetadata(agentId);\n\n return {\n agentId,\n owner: owner as Address,\n agentURI: agentURI as string,\n agentWallet: agentWallet as Address,\n registrationFile,\n modelMetadata,\n };\n }\n\n async lookupAgentByOwner(\n ownerAddress: Address,\n fromBlock: bigint = 0n,\n ): Promise<AgentIdentity | null> {\n const logs = await this.publicClient.getLogs({\n address: this.config.registryAddress,\n event: {\n type: \"event\",\n name: \"Registered\",\n inputs: [\n { name: \"agentId\", type: \"uint256\", indexed: true },\n { name: \"agentURI\", type: \"string\", indexed: false },\n { name: \"owner\", type: \"address\", indexed: true },\n ],\n },\n args: { owner: ownerAddress },\n fromBlock,\n toBlock: \"latest\",\n });\n\n if (logs.length === 0) return null;\n const latestLog = logs[logs.length - 1];\n const agentId = BigInt(latestLog.args.agentId ?? 0);\n return this.lookupAgentIdentity(agentId);\n }\n\n async updateAgentURI(\n walletClient: WalletClient,\n agentId: bigint,\n newURI: string,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ERC8004Client: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.setAgentURI([agentId, newURI], {\n account: walletClient.account,\n chain: this.chain,\n });\n }\n\n async getOnChainMetadata(agentId: bigint, key: string): Promise<Hex | null> {\n const contract = this.getReadContract();\n const value = await contract.read.getMetadata([agentId, key]);\n return value === \"0x\" || value === null ? null : (value as Hex);\n }\n\n async setOnChainMetadata(\n walletClient: WalletClient,\n agentId: bigint,\n key: string,\n value: string,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ERC8004Client: WalletClient has no account\");\n if (key === METADATA_KEYS.AGENT_WALLET) {\n throw new Error(\n 'ERC8004Client: \"agentWallet\" is reserved — use setAgentWallet() instead',\n );\n }\n const contract = this.getWriteContract(walletClient);\n const hexValue = stringToHex(value);\n return contract.write.setMetadata([agentId, key, hexValue], {\n account: walletClient.account,\n chain: this.chain,\n });\n }\n\n async setModelMetadata(\n walletClient: WalletClient,\n agentId: bigint,\n model: AgentModelMetadata,\n ): Promise<Hash[]> {\n const hashes: Hash[] = [];\n const entries: [string, string][] = [];\n if (model.model) entries.push([METADATA_KEYS.MODEL, model.model]);\n if (model.provider)\n entries.push([METADATA_KEYS.MODEL_PROVIDER, model.provider]);\n if (model.version) entries.push([METADATA_KEYS.VERSION, model.version]);\n if (model.framework)\n entries.push([METADATA_KEYS.FRAMEWORK, model.framework]);\n if (model.capabilities?.length)\n entries.push([\n METADATA_KEYS.CAPABILITIES,\n JSON.stringify(model.capabilities),\n ]);\n\n for (const [key, val] of entries) {\n const hash = await this.setOnChainMetadata(\n walletClient,\n agentId,\n key,\n val,\n );\n hashes.push(hash);\n }\n return hashes;\n }\n\n async readModelMetadata(agentId: bigint): Promise<AgentModelMetadata | null> {\n const keys = [\n METADATA_KEYS.MODEL,\n METADATA_KEYS.MODEL_PROVIDER,\n METADATA_KEYS.VERSION,\n METADATA_KEYS.FRAMEWORK,\n METADATA_KEYS.CAPABILITIES,\n ];\n const values = await Promise.all(\n keys.map((k) => this.getOnChainMetadata(agentId, k)),\n );\n const [modelHex, providerHex, versionHex, frameworkHex, capabilitiesHex] =\n values;\n\n if (\n !modelHex &&\n !providerHex &&\n !versionHex &&\n !frameworkHex &&\n !capabilitiesHex\n )\n return null;\n\n const result: AgentModelMetadata = {};\n if (modelHex) result.model = hexToString(modelHex);\n if (providerHex) result.provider = hexToString(providerHex);\n if (versionHex) result.version = hexToString(versionHex);\n if (frameworkHex) result.framework = hexToString(frameworkHex);\n if (capabilitiesHex) {\n try {\n result.capabilities = JSON.parse(hexToString(capabilitiesHex));\n } catch {\n result.capabilities = [];\n }\n }\n return result;\n }\n\n async getAgentWallet(agentId: bigint): Promise<Address> {\n const contract = this.getReadContract();\n return contract.read.getAgentWallet([agentId]) as Promise<Address>;\n }\n\n async setAgentWallet(\n walletClient: WalletClient,\n agentId: bigint,\n newWallet: Address,\n deadline: bigint,\n signature: Hex,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ERC8004Client: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.setAgentWallet(\n [agentId, newWallet, deadline, signature],\n {\n account: walletClient.account,\n chain: this.chain,\n },\n );\n }\n\n async unsetAgentWallet(\n walletClient: WalletClient,\n agentId: bigint,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ERC8004Client: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.unsetAgentWallet([agentId], {\n account: walletClient.account,\n chain: this.chain,\n });\n }\n}\n\n// ─── Standalone helpers ───────────────────────────────────────────────────────\n\nexport function buildDataURI(registrationFile: AgentRegistrationFile): string {\n const payload = { ...registrationFile, type: REGISTRATION_FILE_TYPE };\n const json = JSON.stringify(payload);\n const b64 = btoa(unescape(encodeURIComponent(json)));\n return `data:application/json;base64,${b64}`;\n}\n\nexport function parseDataURI(uri: string): AgentRegistrationFile {\n if (uri.startsWith(\"data:application/json;base64,\")) {\n const b64 = uri.replace(\"data:application/json;base64,\", \"\");\n const json = decodeURIComponent(escape(atob(b64)));\n return JSON.parse(json);\n }\n if (uri.startsWith(\"{\")) return JSON.parse(uri);\n throw new Error(\n `parseDataURI: Cannot parse URI scheme: ${uri.substring(0, 50)}`,\n );\n}\n\nexport async function resolveAgentURI(\n uri: string,\n): Promise<AgentRegistrationFile> {\n if (uri.startsWith(\"data:\")) return parseDataURI(uri);\n if (uri.startsWith(\"https://\") || uri.startsWith(\"http://\")) {\n const response = await fetch(uri);\n if (!response.ok)\n throw new Error(`resolveAgentURI: HTTP ${response.status} for ${uri}`);\n return response.json();\n }\n throw new Error(`resolveAgentURI: Unsupported URI scheme: ${uri}`);\n}\n\nexport function validateRegistrationFile(\n file: AgentRegistrationFile,\n): string[] {\n const errors: string[] = [];\n if (file.type !== REGISTRATION_FILE_TYPE)\n errors.push(`type must be \"${REGISTRATION_FILE_TYPE}\"`);\n if (!file.name || typeof file.name !== \"string\" || file.name.trim() === \"\")\n errors.push(\"name is required\");\n if (!file.description || typeof file.description !== \"string\")\n errors.push(\"description is required\");\n if (file.services) {\n file.services.forEach((svc, i) => {\n if (!svc.name) errors.push(`services[${i}].name is required`);\n if (!svc.endpoint) errors.push(`services[${i}].endpoint is required`);\n });\n }\n if (file.registrations) {\n file.registrations.forEach((reg, i) => {\n if (reg.agentId === undefined)\n errors.push(`registrations[${i}].agentId is required`);\n if (!reg.agentRegistry)\n errors.push(`registrations[${i}].agentRegistry is required`);\n });\n }\n return errors;\n}\n\nexport function formatAgentRegistry(\n chainId: number,\n registryAddress: Address,\n): string {\n return `eip155:${chainId}:${registryAddress}`;\n}\n\n// ─── Internal utilities ───────────────────────────────────────────────────────\n\nfunction stringToHex(str: string): Hex {\n const bytes = new TextEncoder().encode(str);\n const hexStr = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return `0x${hexStr}` as Hex;\n}\n\nfunction hexToString(hex: Hex): string {\n const stripped = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n const pairs = stripped.match(/.{1,2}/g);\n const bytes = new Uint8Array(\n pairs?.map((byte) => Number.parseInt(byte, 16)) ?? [],\n );\n return new TextDecoder(\"utf-8\").decode(bytes);\n}\n\nfunction encodeMetadataEntries(\n entries: Record<string, string>,\n): MetadataEntry[] {\n return Object.entries(entries).map(([key, value]) => ({\n metadataKey: key,\n metadataValue: stringToHex(value),\n }));\n}\n",
|
|
20
|
+
"/**\n * ERC-8004: Trustless Agents — Reputation Registry Client\n *\n * On-chain reputation system for AI agents. Clients can leave scored feedback,\n * agents can respond, and anyone can query aggregated reputation summaries.\n *\n * Spec: https://eips.ethereum.org/EIPS/eip-8004\n */\nimport {\n type Address,\n type Chain,\n createPublicClient,\n getContract,\n type Hash,\n type Hex,\n http,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\nimport {\n arbitrum,\n arbitrumSepolia,\n base,\n baseSepolia,\n mainnet,\n polygon,\n} from \"viem/chains\";\nimport { KNOWN_REGISTRY_ADDRESSES, type SupportedChain } from \"./erc8004.js\";\n\n// ─── ABI ─────────────────────────────────────────────────────────────────────\n\nexport const ReputationRegistryAbi = [\n {\n name: \"giveFeedback\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"score\", type: \"int128\" },\n { name: \"category\", type: \"uint8\" },\n { name: \"comment\", type: \"string\" },\n { name: \"taskRef\", type: \"string\" },\n { name: \"verifierRef\", type: \"string\" },\n { name: \"clientRef\", type: \"string\" },\n { name: \"contentHash\", type: \"bytes32\" },\n ],\n outputs: [],\n },\n {\n name: \"readFeedback\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"client\", type: \"address\" },\n { name: \"index\", type: \"uint64\" },\n ],\n outputs: [\n { name: \"score\", type: \"int128\" },\n { name: \"category\", type: \"uint8\" },\n { name: \"comment\", type: \"string\" },\n { name: \"taskRef\", type: \"string\" },\n { name: \"revoked\", type: \"bool\" },\n ],\n },\n {\n name: \"readAllFeedback\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"clients\", type: \"address[]\" },\n { name: \"category\", type: \"string\" },\n { name: \"taskRef\", type: \"string\" },\n { name: \"includeRevoked\", type: \"bool\" },\n ],\n outputs: [\n { name: \"scores\", type: \"int128[]\" },\n { name: \"categories\", type: \"uint8[]\" },\n { name: \"comments\", type: \"string[]\" },\n { name: \"taskRefs\", type: \"string[]\" },\n { name: \"revoked\", type: \"bool[]\" },\n ],\n },\n {\n name: \"getSummary\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"clients\", type: \"address[]\" },\n { name: \"category\", type: \"string\" },\n { name: \"taskRef\", type: \"string\" },\n ],\n outputs: [\n { name: \"count\", type: \"uint64\" },\n { name: \"totalScore\", type: \"int128\" },\n { name: \"avgCategory\", type: \"uint8\" },\n ],\n },\n {\n name: \"getClients\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"agentId\", type: \"uint256\" }],\n outputs: [{ name: \"\", type: \"address[]\" }],\n },\n {\n name: \"getLastIndex\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"client\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint64\" }],\n },\n {\n name: \"appendResponse\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"client\", type: \"address\" },\n { name: \"index\", type: \"uint64\" },\n { name: \"response\", type: \"string\" },\n { name: \"contentHash\", type: \"bytes32\" },\n ],\n outputs: [],\n },\n {\n name: \"revokeFeedback\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"index\", type: \"uint64\" },\n ],\n outputs: [],\n },\n {\n name: \"getResponseCount\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"client\", type: \"address\" },\n { name: \"index\", type: \"uint64\" },\n { name: \"responders\", type: \"address[]\" },\n ],\n outputs: [{ name: \"\", type: \"uint64\" }],\n },\n {\n name: \"getIdentityRegistry\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n] as const;\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface ReputationClientConfig {\n reputationAddress?: Address;\n chain: SupportedChain;\n rpcUrl?: string;\n}\n\nexport interface GiveFeedbackParams {\n agentId: bigint;\n score: bigint;\n category: number;\n comment: string;\n taskRef: string;\n verifierRef: string;\n clientRef: string;\n contentHash: Hex;\n}\n\nexport interface FeedbackEntry {\n score: bigint;\n category: number;\n comment: string;\n taskRef: string;\n revoked: boolean;\n}\n\nexport interface AgentReputationSummary {\n count: bigint;\n totalScore: bigint;\n avgCategory: number;\n clients: Address[];\n}\n\nexport interface FeedbackFilters {\n clients?: Address[];\n category?: string;\n taskRef?: string;\n includeRevoked?: boolean;\n}\n\nexport interface RespondToFeedbackParams {\n agentId: bigint;\n client: Address;\n index: bigint;\n response: string;\n contentHash: Hex;\n}\n\n// ─── Chains ──────────────────────────────────────────────────────────────────\n\nconst CHAINS: Record<string, Chain> = {\n base,\n \"base-sepolia\": baseSepolia,\n ethereum: mainnet,\n arbitrum,\n polygon,\n \"arbitrum-sepolia\": arbitrumSepolia,\n};\n\n// ─── Client ──────────────────────────────────────────────────────────────────\n\nexport class ReputationClient {\n private readonly publicClient: PublicClient;\n private readonly reputationAddress: Address;\n private readonly chain: Chain;\n\n constructor(config: ReputationClientConfig) {\n const resolvedAddress =\n config.reputationAddress ??\n KNOWN_REGISTRY_ADDRESSES[config.chain]?.reputation;\n if (!resolvedAddress) {\n throw new Error(\n `ReputationClient: No reputation address provided and no known address for chain \"${config.chain}\"`,\n );\n }\n this.reputationAddress = resolvedAddress;\n\n const chain = CHAINS[config.chain];\n if (!chain)\n throw new Error(`ReputationClient: Unsupported chain \"${config.chain}\"`);\n this.chain = chain;\n this.publicClient = createPublicClient({\n chain,\n transport: http(config.rpcUrl),\n });\n }\n\n private getReadContract() {\n return getContract({\n address: this.reputationAddress,\n abi: ReputationRegistryAbi,\n client: this.publicClient,\n });\n }\n\n private getWriteContract(walletClient: WalletClient) {\n return getContract({\n address: this.reputationAddress,\n abi: ReputationRegistryAbi,\n client: { public: this.publicClient, wallet: walletClient },\n });\n }\n\n /**\n * Submit feedback for an agent.\n */\n async giveFeedback(\n walletClient: WalletClient,\n params: GiveFeedbackParams,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ReputationClient: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.giveFeedback(\n [\n params.agentId,\n params.score,\n params.category,\n params.comment,\n params.taskRef,\n params.verifierRef,\n params.clientRef,\n params.contentHash,\n ],\n { account: walletClient.account, chain: this.chain },\n );\n }\n\n /**\n * Read a specific feedback entry.\n */\n async readFeedback(\n agentId: bigint,\n client: Address,\n index: bigint,\n ): Promise<FeedbackEntry> {\n const contract = this.getReadContract();\n const [score, category, comment, taskRef, revoked] =\n (await contract.read.readFeedback([agentId, client, index])) as [\n bigint,\n number,\n string,\n string,\n boolean,\n ];\n\n return { score, category, comment, taskRef, revoked };\n }\n\n /**\n * Get agent reputation summary: aggregated score + list of clients.\n */\n async getAgentReputation(\n agentId: bigint,\n options?: { clients?: Address[]; category?: string; taskRef?: string },\n ): Promise<AgentReputationSummary> {\n const contract = this.getReadContract();\n\n const clients = (await contract.read.getClients([agentId])) as Address[];\n\n const filterClients = options?.clients ?? clients;\n const category = options?.category ?? \"\";\n const taskRef = options?.taskRef ?? \"\";\n\n const [count, totalScore, avgCategory] = (await contract.read.getSummary([\n agentId,\n filterClients,\n category,\n taskRef,\n ])) as [bigint, bigint, number];\n\n return { count, totalScore, avgCategory, clients };\n }\n\n /**\n * Read all feedback for an agent with optional filters.\n */\n async getAllFeedback(\n agentId: bigint,\n options?: FeedbackFilters,\n ): Promise<FeedbackEntry[]> {\n const contract = this.getReadContract();\n\n const clients = options?.clients ?? [];\n const category = options?.category ?? \"\";\n const taskRef = options?.taskRef ?? \"\";\n const includeRevoked = options?.includeRevoked ?? false;\n\n const [scores, categories, comments, taskRefs, revoked] =\n (await contract.read.readAllFeedback([\n agentId,\n clients,\n category,\n taskRef,\n includeRevoked,\n ])) as [bigint[], number[], string[], string[], boolean[]];\n\n return scores.map((score, i) => ({\n score,\n category: categories[i],\n comment: comments[i],\n taskRef: taskRefs[i],\n revoked: revoked[i],\n }));\n }\n\n /**\n * Append a response to existing feedback.\n */\n async respondToFeedback(\n walletClient: WalletClient,\n params: RespondToFeedbackParams,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ReputationClient: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.appendResponse(\n [\n params.agentId,\n params.client,\n params.index,\n params.response,\n params.contentHash,\n ],\n { account: walletClient.account, chain: this.chain },\n );\n }\n\n /**\n * Revoke own feedback for an agent.\n */\n async revokeFeedback(\n walletClient: WalletClient,\n agentId: bigint,\n index: bigint,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ReputationClient: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.revokeFeedback([agentId, index], {\n account: walletClient.account,\n chain: this.chain,\n });\n }\n\n /**\n * Get the linked identity registry address.\n */\n async getIdentityRegistry(): Promise<Address> {\n const contract = this.getReadContract();\n return contract.read.getIdentityRegistry() as Promise<Address>;\n }\n\n /**\n * Get the last feedback index for a client on an agent.\n */\n async getLastIndex(agentId: bigint, client: Address): Promise<bigint> {\n const contract = this.getReadContract();\n return contract.read.getLastIndex([agentId, client]) as Promise<bigint>;\n }\n\n /**\n * Get clients who have left feedback for an agent.\n */\n async getClients(agentId: bigint): Promise<Address[]> {\n const contract = this.getReadContract();\n return contract.read.getClients([agentId]) as Promise<Address[]>;\n }\n\n /**\n * Get the number of responses for a specific feedback entry.\n */\n async getResponseCount(\n agentId: bigint,\n client: Address,\n index: bigint,\n responders: Address[],\n ): Promise<bigint> {\n const contract = this.getReadContract();\n return contract.read.getResponseCount([\n agentId,\n client,\n index,\n responders,\n ]) as Promise<bigint>;\n }\n}\n",
|
|
21
|
+
"/**\n * uaid.ts — Universal Agent Identifier (UAID) Resolution Layer\n *\n * Provides cross-chain agent identity resolution via the HOL Registry Broker.\n * UAIDs are chain-agnostic identifiers that bridge ERC-8004 tokens on EVM chains\n * to agents on Solana, Hedera, off-chain frameworks, and any other protocol.\n *\n * This module is an optional extension — agents that only operate on EVM chains\n * can continue using ERC8004Client directly.\n *\n * Registry: https://hol.org\n * SDK: @hol-org/rb-client (peer dependency — install only if needed)\n *\n * @module identity/uaid\n */\n\nimport type { Address } from \"viem\";\nimport type {\n AgentIdentity,\n AgentRegistrationFile,\n SupportedChain,\n} from \"./erc8004.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Supported protocol types in the UAID ecosystem */\nexport type UAIDProtocol =\n | \"erc8004\"\n | \"a2a\"\n | \"openconvai\"\n | \"virtuals\"\n | \"x402\"\n | \"hedera\"\n | \"solana\"\n | string;\n\n/** A parsed UAID with its component parts */\nexport interface ParsedUAID {\n /** Raw UAID string */\n raw: string;\n /** Agent identifier portion */\n aid: string;\n /** Unique identifier portion */\n uid: string;\n /** Protocol used for resolution */\n protocol: UAIDProtocol;\n /** Native identifier on the protocol's own chain/system */\n nativeId?: string;\n}\n\n/** Result of resolving a UAID to a known identity */\nexport interface UAIDResolution {\n /** Whether resolution succeeded */\n resolved: boolean;\n /** The UAID that was resolved */\n uaid: string;\n /** Resolved agent identity (if ERC-8004 backed) */\n identity: UniversalAgentIdentity | null;\n /** Protocol the agent was resolved through */\n protocol: UAIDProtocol;\n /** Chain the identity lives on (if applicable) */\n chain?: string;\n /** Trust score from the registry (0-100) */\n trustScore?: number;\n /** Whether the agent is verified in the HOL registry */\n registryVerified: boolean;\n /** Error message if resolution failed */\n error?: string;\n}\n\n/**\n * Universal agent identity — superset of ERC-8004 AgentIdentity that works\n * across chains. For EVM agents, this mirrors AgentIdentity. For non-EVM\n * agents, it provides equivalent fields using native identifiers.\n */\nexport interface UniversalAgentIdentity {\n /** Identifier — ERC-8004 tokenId for EVM, native ID for others */\n agentId: string;\n /** Owner — EVM address, Hedera account, Solana pubkey, etc. */\n owner: string;\n /** Agent URI / metadata endpoint */\n agentURI: string;\n /** Payment address (chain-native format) */\n paymentAddress: string;\n /** Registration metadata (if available) */\n registrationFile: AgentRegistrationFile | null;\n /** Source protocol */\n protocol: UAIDProtocol;\n /** Source chain */\n chain: string;\n /** UAID for cross-chain reference */\n uaid: string;\n}\n\n/** Configuration for the UAID resolver */\nexport interface UAIDResolverConfig {\n /** HOL Registry Broker API key (optional for read-only resolution) */\n apiKey?: string;\n /** Custom broker base URL (defaults to production) */\n brokerUrl?: string;\n /** Request timeout in ms (default: 10000) */\n timeoutMs?: number;\n /** Cache resolved identities for this many ms (default: 300000 = 5 min) */\n cacheTtlMs?: number;\n}\n\n/** Parameters for registering an ERC-8004 identity as a UAID */\nexport interface RegisterUAIDParams {\n /** ERC-8004 agent ID (tokenId) */\n agentId: bigint;\n /** Chain the identity is registered on */\n chain: SupportedChain;\n /** Registry contract address (uses known defaults if omitted) */\n registryAddress?: Address;\n /** Agent name for the registry */\n name: string;\n /** Agent description */\n description: string;\n /** Optional: additional capabilities to advertise */\n capabilities?: string[];\n}\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\nconst DEFAULT_BROKER_URL = \"https://hol.org/registry/api/v1\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst DEFAULT_CACHE_TTL_MS = 300_000; // 5 minutes\n\n/** EVM chain IDs for UAID protocol mapping */\nconst EVM_CHAIN_IDS: Record<SupportedChain, number> = {\n ethereum: 1,\n base: 8453,\n \"base-sepolia\": 84532,\n arbitrum: 42161,\n \"arbitrum-sepolia\": 421614,\n polygon: 137,\n};\n\n// ─── Cache ───────────────────────────────────────────────────────────────────\n\ninterface CacheEntry {\n result: UAIDResolution;\n expiresAt: number;\n}\n\n// ─── Client ──────────────────────────────────────────────────────────────────\n\nexport class UAIDResolver {\n private readonly brokerUrl: string;\n private readonly apiKey?: string;\n private readonly timeoutMs: number;\n private readonly cacheTtlMs: number;\n private readonly cache = new Map<string, CacheEntry>();\n\n constructor(config: UAIDResolverConfig = {}) {\n this.brokerUrl = (config.brokerUrl ?? DEFAULT_BROKER_URL).replace(\n /\\/+$/,\n \"\",\n );\n this.apiKey = config.apiKey;\n this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.cacheTtlMs = config.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n }\n\n // ── Core resolution ──────────────────────────────────────────────────────\n\n /**\n * Resolve a UAID to an agent identity.\n *\n * Works across chains — the resolver contacts the HOL Registry Broker to\n * find the agent's identity regardless of whether it lives on EVM, Hedera,\n * Solana, or off-chain.\n *\n * @param uaid - Universal Agent Identifier string\n * @returns Resolution result with identity details\n *\n * @example\n * ```ts\n * const resolver = new UAIDResolver();\n * const result = await resolver.resolve('uaid:aid:0x8004...;uid=42;proto=erc8004');\n * if (result.resolved) {\n * console.log(result.identity?.paymentAddress);\n * }\n * ```\n */\n async resolve(uaid: string): Promise<UAIDResolution> {\n // Check cache\n const cached = this.cache.get(uaid);\n if (cached && cached.expiresAt > Date.now()) {\n return cached.result;\n }\n\n try {\n const response = await this.brokerRequest(\n \"GET\",\n `/agents/resolve?uaid=${encodeURIComponent(uaid)}`,\n );\n\n if (!response.ok) {\n const result: UAIDResolution = {\n resolved: false,\n uaid,\n identity: null,\n protocol: \"unknown\",\n registryVerified: false,\n error: `Registry returned ${response.status}`,\n };\n return result;\n }\n\n const data = await response.json();\n\n const identity: UniversalAgentIdentity = {\n agentId: String(data.agentId ?? data.nativeId ?? \"\"),\n owner: data.owner ?? data.controller ?? \"\",\n agentURI: data.agentURI ?? data.metadataUri ?? \"\",\n paymentAddress: data.paymentAddress ?? data.agentWallet ?? \"\",\n registrationFile: data.registrationFile ?? null,\n protocol: data.protocol ?? \"unknown\",\n chain: data.chain ?? \"\",\n uaid,\n };\n\n const result: UAIDResolution = {\n resolved: true,\n uaid,\n identity,\n protocol: data.protocol ?? \"unknown\",\n chain: data.chain,\n trustScore: data.trustScore,\n registryVerified: data.verified ?? false,\n };\n\n // Cache the result\n this.cache.set(uaid, { result, expiresAt: Date.now() + this.cacheTtlMs });\n return result;\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n resolved: false,\n uaid,\n identity: null,\n protocol: \"unknown\",\n registryVerified: false,\n error: `Resolution failed: ${message}`,\n };\n }\n }\n\n /**\n * Search the HOL registry for agents matching criteria.\n *\n * @param query - Search terms (name, capability, protocol)\n * @param options - Optional filters\n * @returns Array of matching UAIDResolution results\n */\n async search(\n query: string,\n options?: {\n protocol?: UAIDProtocol;\n limit?: number;\n minTrustScore?: number;\n },\n ): Promise<UAIDResolution[]> {\n try {\n const params = new URLSearchParams({ q: query });\n if (options?.protocol) params.set(\"protocol\", options.protocol);\n if (options?.limit) params.set(\"limit\", String(options.limit));\n if (options?.minTrustScore)\n params.set(\"minTrust\", String(options.minTrustScore));\n\n const response = await this.brokerRequest(\n \"GET\",\n `/agents/search?${params}`,\n );\n if (!response.ok) return [];\n\n const data = await response.json();\n const results: UAIDResolution[] = (data.agents ?? []).map(\n (agent: Record<string, unknown>) => ({\n resolved: true,\n uaid: agent.uaid as string,\n identity: {\n agentId: String(agent.agentId ?? agent.nativeId ?? \"\"),\n owner: (agent.owner ?? agent.controller ?? \"\") as string,\n agentURI: (agent.agentURI ?? agent.metadataUri ?? \"\") as string,\n paymentAddress: (agent.paymentAddress ??\n agent.agentWallet ??\n \"\") as string,\n registrationFile: (agent.registrationFile ??\n null) as AgentRegistrationFile | null,\n protocol: (agent.protocol ?? \"unknown\") as UAIDProtocol,\n chain: (agent.chain ?? \"\") as string,\n uaid: agent.uaid as string,\n },\n protocol: (agent.protocol ?? \"unknown\") as UAIDProtocol,\n chain: agent.chain as string | undefined,\n trustScore: agent.trustScore as number | undefined,\n registryVerified: (agent.verified ?? false) as boolean,\n }),\n );\n\n return results;\n } catch {\n return [];\n }\n }\n\n // ── ERC-8004 ↔ UAID bridge ────────────────────────────────────────────────\n\n /**\n * Convert an ERC-8004 AgentIdentity to a UniversalAgentIdentity.\n *\n * Useful when you already have an on-chain identity and want to work\n * with the universal format (e.g., for cross-chain discovery).\n */\n erc8004ToUniversal(\n identity: AgentIdentity,\n chain: SupportedChain,\n ): UniversalAgentIdentity {\n const chainId = EVM_CHAIN_IDS[chain];\n return {\n agentId: identity.agentId.toString(),\n owner: identity.owner,\n agentURI: identity.agentURI,\n paymentAddress: identity.agentWallet,\n registrationFile: identity.registrationFile,\n protocol: \"erc8004\",\n chain: `eip155:${chainId}`,\n uaid: `uaid:aid:eip155:${chainId}:${identity.owner};uid=${identity.agentId};proto=erc8004`,\n };\n }\n\n /**\n * Build a UAID string for an ERC-8004 agent.\n *\n * This creates the identifier — it does NOT register with the HOL registry.\n * Use registerERC8004Agent() to make the agent discoverable cross-chain.\n */\n buildERC8004UAID(\n agentId: bigint,\n chain: SupportedChain,\n ownerAddress: Address,\n ): string {\n const chainId = EVM_CHAIN_IDS[chain];\n return `uaid:aid:eip155:${chainId}:${ownerAddress};uid=${agentId};proto=erc8004`;\n }\n\n /**\n * Register an ERC-8004 agent in the HOL registry for cross-chain discovery.\n *\n * After registration, agents on Solana, Hedera, or any protocol can\n * discover and verify this agent's identity via its UAID.\n *\n * Requires an API key with write permissions.\n *\n * @param params - Registration parameters\n * @returns The assigned UAID\n */\n async registerERC8004Agent(params: RegisterUAIDParams): Promise<string> {\n if (!this.apiKey) {\n throw new Error(\n \"UAIDResolver: API key required for registration. Get one at https://hol.org\",\n );\n }\n\n const chainId = EVM_CHAIN_IDS[params.chain];\n const uaid = `uaid:aid:eip155:${chainId}:${params.registryAddress ?? \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\"};uid=${params.agentId};proto=erc8004`;\n\n const response = await this.brokerRequest(\"POST\", \"/agents/register\", {\n uaid,\n protocol: \"erc8004\",\n chain: `eip155:${chainId}`,\n agentId: params.agentId.toString(),\n name: params.name,\n description: params.description,\n capabilities: params.capabilities ?? [],\n registryAddress:\n params.registryAddress ?? \"0x8004A169FB4a3325136EB29fA0ceB6D2e539a432\",\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"\");\n throw new Error(\n `UAIDResolver: Registration failed (${response.status}): ${errorBody}`,\n );\n }\n\n const data = await response.json();\n return data.uaid ?? uaid;\n }\n\n // ── Verification ──────────────────────────────────────────────────────────\n\n /**\n * Verify an agent's identity via UAID — works across any chain.\n *\n * This is the cross-chain equivalent of ERC8004Client.lookupAgentIdentity().\n * For EVM agents, it verifies the UAID maps to a valid on-chain ERC-8004 token.\n * For non-EVM agents, it verifies through the registry's native trust mechanism.\n *\n * @param uaid - Universal Agent Identifier to verify\n * @returns Verification result\n */\n async verify(uaid: string): Promise<{\n verified: boolean;\n identity: UniversalAgentIdentity | null;\n trustScore: number;\n protocol: UAIDProtocol;\n error?: string;\n }> {\n const resolution = await this.resolve(uaid);\n\n if (!resolution.resolved || !resolution.identity) {\n return {\n verified: false,\n identity: null,\n trustScore: 0,\n protocol: resolution.protocol,\n error: resolution.error ?? \"Agent not found in registry\",\n };\n }\n\n return {\n verified: resolution.registryVerified,\n identity: resolution.identity,\n trustScore: resolution.trustScore ?? 0,\n protocol: resolution.protocol,\n };\n }\n\n // ── Utility ───────────────────────────────────────────────────────────────\n\n /**\n * Parse a UAID string into its components.\n *\n * Format: `uaid:aid:<identifier>;uid=<unique-id>;proto=<protocol>[;nativeId=<id>]`\n */\n static parseUAID(uaid: string): ParsedUAID | null {\n if (!uaid.startsWith(\"uaid:\")) return null;\n\n const parts = uaid.split(\";\");\n const aidPart = parts.find((p) => p.startsWith(\"uaid:aid:\"));\n const uidPart = parts.find((p) => p.startsWith(\"uid=\"));\n const protoPart = parts.find((p) => p.startsWith(\"proto=\"));\n const nativeIdPart = parts.find((p) => p.startsWith(\"nativeId=\"));\n\n if (!aidPart || !uidPart || !protoPart) return null;\n\n return {\n raw: uaid,\n aid: aidPart.replace(\"uaid:aid:\", \"\"),\n uid: uidPart.replace(\"uid=\", \"\"),\n protocol: protoPart.replace(\"proto=\", \"\") as UAIDProtocol,\n nativeId: nativeIdPart?.replace(\"nativeId=\", \"\"),\n };\n }\n\n /** Clear the resolution cache */\n clearCache(): void {\n this.cache.clear();\n }\n\n // ── Private ───────────────────────────────────────────────────────────────\n\n private async brokerRequest(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<Response> {\n const url = `${this.brokerUrl}${path}`;\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n \"User-Agent\": \"agentwallet-sdk/uaid-resolver\",\n };\n if (this.apiKey) {\n headers.Authorization = `Bearer ${this.apiKey}`;\n }\n if (body) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n return await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeout);\n }\n }\n}\n",
|
|
22
|
+
"/**\n * ERC-8004: Trustless Agents — Validation Registry Client\n *\n * On-chain validation system for AI agents. Validators can be requested to\n * validate an agent's capabilities, and their responses are recorded on-chain.\n *\n * Note: The ValidationRegistry is part of the ERC-8004 spec. Official registry\n * addresses are absent from erc-8004-contracts, so deployments must supply the\n * ValidationRegistry address alongside Identity and Reputation registries.\n *\n * Spec: https://eips.ethereum.org/EIPS/eip-8004\n */\nimport {\n type Address,\n type Chain,\n createPublicClient,\n getContract,\n type Hash,\n type Hex,\n http,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\nimport {\n arbitrum,\n arbitrumSepolia,\n base,\n baseSepolia,\n mainnet,\n polygon,\n} from \"viem/chains\";\nimport { KNOWN_REGISTRY_ADDRESSES, type SupportedChain } from \"./erc8004.js\";\n\n// ─── ABI ─────────────────────────────────────────────────────────────────────\n\nexport const ValidationRegistryAbi = [\n {\n name: \"validationRequest\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"validator\", type: \"address\" },\n { name: \"agentId\", type: \"uint256\" },\n { name: \"requestURI\", type: \"string\" },\n { name: \"requestHash\", type: \"bytes32\" },\n ],\n outputs: [],\n },\n {\n name: \"validationResponse\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"requestHash\", type: \"bytes32\" },\n { name: \"response\", type: \"uint8\" },\n { name: \"responseURI\", type: \"string\" },\n { name: \"responseHash\", type: \"bytes32\" },\n { name: \"tag\", type: \"string\" },\n ],\n outputs: [],\n },\n {\n name: \"getValidationStatus\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"requestHash\", type: \"bytes32\" }],\n outputs: [\n { name: \"validator\", type: \"address\" },\n { name: \"agentId\", type: \"uint256\" },\n { name: \"requestURI\", type: \"string\" },\n { name: \"response\", type: \"uint8\" },\n { name: \"responseURI\", type: \"string\" },\n { name: \"responseHash\", type: \"bytes32\" },\n { name: \"tag\", type: \"string\" },\n { name: \"responded\", type: \"bool\" },\n ],\n },\n {\n name: \"getAgentValidations\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"agentId\", type: \"uint256\" }],\n outputs: [{ name: \"requestHashes\", type: \"bytes32[]\" }],\n },\n {\n name: \"getValidatorRequests\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"validator\", type: \"address\" }],\n outputs: [{ name: \"requestHashes\", type: \"bytes32[]\" }],\n },\n {\n name: \"getSummary\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"agentId\", type: \"uint256\" },\n { name: \"validators\", type: \"address[]\" },\n { name: \"category\", type: \"string\" },\n ],\n outputs: [\n { name: \"totalRequests\", type: \"uint256\" },\n { name: \"totalResponses\", type: \"uint256\" },\n { name: \"passCount\", type: \"uint256\" },\n { name: \"failCount\", type: \"uint256\" },\n ],\n },\n {\n name: \"getIdentityRegistry\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\" }],\n },\n {\n name: \"getVersion\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n // Events\n {\n name: \"ValidationRequest\",\n type: \"event\",\n inputs: [\n { name: \"validator\", type: \"address\", indexed: true },\n { name: \"agentId\", type: \"uint256\", indexed: true },\n { name: \"requestURI\", type: \"string\", indexed: false },\n { name: \"requestHash\", type: \"bytes32\", indexed: false },\n ],\n },\n {\n name: \"ValidationResponse\",\n type: \"event\",\n inputs: [\n { name: \"validator\", type: \"address\", indexed: true },\n { name: \"agentId\", type: \"uint256\", indexed: true },\n { name: \"requestHash\", type: \"bytes32\", indexed: false },\n { name: \"response\", type: \"uint8\", indexed: false },\n { name: \"responseURI\", type: \"string\", indexed: false },\n { name: \"responseHash\", type: \"bytes32\", indexed: false },\n { name: \"tag\", type: \"string\", indexed: false },\n ],\n },\n] as const;\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface ValidationClientConfig {\n validationAddress?: Address;\n chain: SupportedChain;\n rpcUrl?: string;\n}\n\nexport interface RequestValidationParams {\n validator: Address;\n agentId: bigint;\n requestURI: string;\n requestHash: Hex;\n}\n\nexport interface RespondToValidationParams {\n requestHash: Hex;\n response: number;\n responseURI: string;\n responseHash: Hex;\n tag: string;\n}\n\nexport interface ValidationStatus {\n validator: Address;\n agentId: bigint;\n requestURI: string;\n response: number;\n responseURI: string;\n responseHash: Hex;\n tag: string;\n responded: boolean;\n}\n\nexport interface ValidationSummary {\n totalRequests: bigint;\n totalResponses: bigint;\n passCount: bigint;\n failCount: bigint;\n}\n\n// ─── Chains ──────────────────────────────────────────────────────────────────\n\nconst CHAINS: Record<string, Chain> = {\n base,\n \"base-sepolia\": baseSepolia,\n ethereum: mainnet,\n arbitrum,\n polygon,\n \"arbitrum-sepolia\": arbitrumSepolia,\n};\n\n// ─── Client ──────────────────────────────────────────────────────────────────\n\nexport class ValidationClient {\n private readonly publicClient: PublicClient;\n private readonly validationAddress: Address;\n private readonly chain: Chain;\n\n constructor(config: ValidationClientConfig) {\n const resolvedAddress =\n config.validationAddress ??\n KNOWN_REGISTRY_ADDRESSES[config.chain]?.validation;\n if (!resolvedAddress) {\n throw new Error(\n `ValidationClient: No validation address provided and no known address for chain \"${config.chain}\". The ValidationRegistry is under active development — provide the address explicitly once deployed.`,\n );\n }\n this.validationAddress = resolvedAddress;\n\n const chain = CHAINS[config.chain];\n if (!chain)\n throw new Error(`ValidationClient: Unsupported chain \"${config.chain}\"`);\n this.chain = chain;\n this.publicClient = createPublicClient({\n chain,\n transport: http(config.rpcUrl),\n });\n }\n\n private getReadContract() {\n return getContract({\n address: this.validationAddress,\n abi: ValidationRegistryAbi,\n client: this.publicClient,\n });\n }\n\n private getWriteContract(walletClient: WalletClient) {\n return getContract({\n address: this.validationAddress,\n abi: ValidationRegistryAbi,\n client: { public: this.publicClient, wallet: walletClient },\n });\n }\n\n /**\n * Submit a validation request. Must be called by the owner/operator of the agentId.\n */\n async requestValidation(\n walletClient: WalletClient,\n params: RequestValidationParams,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ValidationClient: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.validationRequest(\n [params.validator, params.agentId, params.requestURI, params.requestHash],\n { account: walletClient.account, chain: this.chain },\n );\n }\n\n /**\n * Respond to a validation request. Must be called by the requested validator.\n */\n async respondToValidation(\n walletClient: WalletClient,\n params: RespondToValidationParams,\n ): Promise<Hash> {\n if (!walletClient.account)\n throw new Error(\"ValidationClient: WalletClient has no account\");\n const contract = this.getWriteContract(walletClient);\n return contract.write.validationResponse(\n [\n params.requestHash,\n params.response,\n params.responseURI,\n params.responseHash,\n params.tag,\n ],\n { account: walletClient.account, chain: this.chain },\n );\n }\n\n /**\n * Check the status of a validation request by its hash.\n */\n async getValidationStatus(requestHash: Hex): Promise<ValidationStatus> {\n const contract = this.getReadContract();\n const [\n validator,\n agentId,\n requestURI,\n response,\n responseURI,\n responseHash,\n tag,\n responded,\n ] = (await contract.read.getValidationStatus([requestHash])) as [\n Address,\n bigint,\n string,\n number,\n string,\n Hex,\n string,\n boolean,\n ];\n\n return {\n validator,\n agentId,\n requestURI,\n response,\n responseURI,\n responseHash,\n tag,\n responded,\n };\n }\n\n /**\n * Get all validation request hashes for an agent.\n */\n async getAgentValidations(agentId: bigint): Promise<Hex[]> {\n const contract = this.getReadContract();\n return contract.read.getAgentValidations([agentId]) as Promise<Hex[]>;\n }\n\n /**\n * Get all validation request hashes assigned to a validator.\n */\n async getValidatorRequests(validatorAddress: Address): Promise<Hex[]> {\n const contract = this.getReadContract();\n return contract.read.getValidatorRequests([validatorAddress]) as Promise<\n Hex[]\n >;\n }\n\n /**\n * Get a summary of validations for an agent, optionally filtered by validators and category.\n */\n async getSummary(\n agentId: bigint,\n validators?: Address[],\n category?: string,\n ): Promise<ValidationSummary> {\n const contract = this.getReadContract();\n const [totalRequests, totalResponses, passCount, failCount] =\n (await contract.read.getSummary([\n agentId,\n validators ?? [],\n category ?? \"\",\n ])) as [bigint, bigint, bigint, bigint];\n\n return { totalRequests, totalResponses, passCount, failCount };\n }\n\n /**\n * Get the linked identity registry address.\n */\n async getIdentityRegistry(): Promise<Address> {\n const contract = this.getReadContract();\n return contract.read.getIdentityRegistry() as Promise<Address>;\n }\n\n /**\n * Get the registry contract version.\n */\n async getVersion(): Promise<string> {\n const contract = this.getReadContract();\n return contract.read.getVersion() as Promise<string>;\n }\n}\n",
|
|
23
|
+
"// [MAX-ADDED] ABIs for Uniswap V3 SwapRouter02 and QuoterV2 on Base Mainnet\n/** Uniswap V3 SwapRouter02 ABI — exactInputSingle */\nexport const UniswapV3RouterAbi = [\n {\n name: \"exactInputSingle\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [\n {\n name: \"params\",\n type: \"tuple\",\n components: [\n { name: \"tokenIn\", type: \"address\" },\n { name: \"tokenOut\", type: \"address\" },\n { name: \"fee\", type: \"uint24\" },\n { name: \"recipient\", type: \"address\" },\n { name: \"amountIn\", type: \"uint256\" },\n { name: \"amountOutMinimum\", type: \"uint256\" },\n { name: \"sqrtPriceLimitX96\", type: \"uint160\" },\n ],\n },\n ],\n outputs: [{ name: \"amountOut\", type: \"uint256\" }],\n },\n {\n name: \"exactInput\",\n type: \"function\",\n stateMutability: \"payable\",\n inputs: [\n {\n name: \"params\",\n type: \"tuple\",\n components: [\n { name: \"path\", type: \"bytes\" },\n { name: \"recipient\", type: \"address\" },\n { name: \"amountIn\", type: \"uint256\" },\n { name: \"amountOutMinimum\", type: \"uint256\" },\n ],\n },\n ],\n outputs: [{ name: \"amountOut\", type: \"uint256\" }],\n },\n];\n/** Uniswap V3 QuoterV2 ABI — quoteExactInputSingle */\nexport const UniswapV3QuoterV2Abi = [\n {\n name: \"quoteExactInputSingle\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n {\n name: \"params\",\n type: \"tuple\",\n components: [\n { name: \"tokenIn\", type: \"address\" },\n { name: \"tokenOut\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n { name: \"fee\", type: \"uint24\" },\n { name: \"sqrtPriceLimitX96\", type: \"uint160\" },\n ],\n },\n ],\n outputs: [\n { name: \"amountOut\", type: \"uint256\" },\n { name: \"sqrtPriceX96After\", type: \"uint160\" },\n { name: \"initializedTicksCrossed\", type: \"uint32\" },\n { name: \"gasEstimate\", type: \"uint256\" },\n ],\n },\n];\n/** Minimal ERC-20 ABI for allowance, approve, transferFrom */\nexport const ERC20Abi = [\n {\n name: \"allowance\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"approve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"decimals\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n];\n",
|
|
24
|
+
"/**\n * @module swap/SwapModule\n * SwapModule — multi-chain Uniswap V3 token swap aggregator with 0.875% protocol fee.\n *\n * Supports Base, Arbitrum, Optimism, and Polygon. Automatically selects the best\n * Uniswap V3 fee tier (0.01%, 0.05%, 0.3%, 1%) by quoting all tiers and choosing\n * the highest output. Applies slippage protection and an optional protocol fee.\n *\n * Usage: construct with `chain` param or use `attachSwap(wallet, { chain: 'arbitrum' })`.\n */\n// SwapModule — Uniswap V3 token swap aggregator with 0.875% protocol fee\nimport {\n type Address,\n encodeFunctionData,\n type Hash,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\nimport { ERC20Abi, UniswapV3QuoterV2Abi, UniswapV3RouterAbi } from \"./abi.js\";\nimport {\n DEFAULT_SLIPPAGE_BPS,\n PROTOCOL_FEE_BPS,\n PROTOCOL_FEE_COLLECTOR,\n type SwapChain,\n type SwapModuleConfig,\n type SwapOptions,\n type SwapQuote,\n type SwapResult,\n UNISWAP_V3_ADDRESSES,\n type UniswapFeeTier,\n} from \"./types.js\";\n\nconst FEE_TIERS: UniswapFeeTier[] = [100, 500, 3000, 10000];\n\n/** Calculate protocol fee: floor(amount * feeBps / 100_000) */\nexport function calcProtocolFee(amount: bigint, feeBps: number): bigint {\n return (amount * BigInt(feeBps)) / 100000n;\n}\n\n/** Apply slippage: floor(amount * (10_000 - slippageBps) / 10_000) */\nexport function applySlippage(amount: bigint, slippageBps: number): bigint {\n return (amount * BigInt(10000 - slippageBps)) / 10000n;\n}\n\n/** Encode deadline: block.timestamp + deadlineSecs */\nexport function calcDeadline(deadlineSecs: number): bigint {\n return BigInt(Math.floor(Date.now() / 1000) + deadlineSecs);\n}\n\nexport class SwapModule {\n private readonly publicClient: PublicClient;\n private readonly walletClient: WalletClient;\n private readonly accountAddress: Address;\n private readonly config: SwapModuleConfig;\n\n constructor(\n publicClient: PublicClient,\n walletClient: WalletClient,\n accountAddress: Address,\n config?: Partial<SwapModuleConfig> & { chain?: SwapChain },\n ) {\n this.publicClient = publicClient;\n this.walletClient = walletClient;\n this.accountAddress = accountAddress;\n const chain: SwapChain = config?.chain ?? \"base\";\n const chainAddresses = UNISWAP_V3_ADDRESSES[chain];\n this.config = {\n routerAddress: chainAddresses.ROUTER,\n quoterAddress: chainAddresses.QUOTER_V2,\n feeBps: PROTOCOL_FEE_BPS,\n feeWallet: PROTOCOL_FEE_COLLECTOR,\n chain,\n ...config,\n // Re-apply chain-derived addresses if chain was specified but addresses were not\n ...(config?.routerAddress\n ? {}\n : { routerAddress: chainAddresses.ROUTER }),\n ...(config?.quoterAddress\n ? {}\n : { quoterAddress: chainAddresses.QUOTER_V2 }),\n };\n }\n\n async getQuote(\n tokenIn: Address,\n tokenOut: Address,\n amountIn: bigint,\n options: Pick<SwapOptions, \"slippageBps\" | \"feeTiers\"> = {},\n ): Promise<SwapQuote> {\n const slippageBps = options.slippageBps ?? DEFAULT_SLIPPAGE_BPS;\n const tiersToTry = options.feeTiers ?? FEE_TIERS;\n const feeAmount = calcProtocolFee(amountIn, this.config.feeBps);\n const amountInNet = amountIn - feeAmount;\n if (amountInNet <= 0n) {\n throw new Error(\n `SwapModule: amountIn (${amountIn}) is too small — fee (${feeAmount}) exceeds input`,\n );\n }\n\n let bestQuote: {\n amountOut: bigint;\n gasEstimate: bigint;\n feeTier: UniswapFeeTier;\n } | null = null;\n for (const fee of tiersToTry) {\n try {\n const result = await this.publicClient.readContract({\n address: this.config.quoterAddress,\n abi: UniswapV3QuoterV2Abi,\n functionName: \"quoteExactInputSingle\",\n args: [\n {\n tokenIn,\n tokenOut,\n amount: amountInNet,\n fee,\n sqrtPriceLimitX96: 0n,\n },\n ],\n });\n const [amountOut, , , gasEstimate] = result as [\n bigint,\n bigint,\n number,\n bigint,\n ];\n if (!bestQuote || amountOut > bestQuote.amountOut) {\n bestQuote = {\n amountOut,\n gasEstimate,\n feeTier: fee as UniswapFeeTier,\n };\n }\n } catch {\n // Pool doesn't exist for this fee tier\n }\n }\n\n if (!bestQuote) {\n throw new Error(\n `SwapModule: No Uniswap V3 pool found for ${tokenIn} → ${tokenOut} on ${this.config.chain}.`,\n );\n }\n\n const amountOutMinimum = applySlippage(bestQuote.amountOut, slippageBps);\n const effectiveRate =\n amountInNet > 0n ? Number(bestQuote.amountOut) / Number(amountInNet) : 0;\n\n return {\n tokenIn,\n tokenOut,\n amountInRaw: amountIn,\n amountInNet,\n feeAmount,\n amountOut: bestQuote.amountOut,\n amountOutMinimum,\n poolFeeTier: bestQuote.feeTier,\n effectiveRate,\n gasEstimate: bestQuote.gasEstimate,\n };\n }\n\n async ensureApproval(\n token: Address,\n spender: Address,\n amount: bigint,\n ): Promise<Hash | undefined> {\n const currentAllowance = (await this.publicClient.readContract({\n address: token,\n abi: ERC20Abi,\n functionName: \"allowance\",\n args: [this.accountAddress, spender],\n })) as bigint;\n\n if (currentAllowance >= amount) return undefined;\n\n const MAX_UINT256 =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935n;\n const account = this.walletClient.account;\n if (!account) throw new Error(\"SwapModule: walletClient has no account\");\n\n const approveData = encodeFunctionData({\n abi: ERC20Abi,\n functionName: \"approve\",\n args: [spender, MAX_UINT256],\n });\n\n return this.walletClient.sendTransaction({\n account,\n to: token,\n data: approveData,\n chain: this.walletClient.chain ?? null,\n });\n }\n\n private async transferFee(\n token: Address,\n feeAmount: bigint,\n feeWallet: Address,\n ): Promise<Hash> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"SwapModule: walletClient has no account\");\n\n const transferData = encodeFunctionData({\n abi: ERC20Abi,\n functionName: \"transfer\",\n args: [feeWallet, feeAmount],\n });\n\n return this.walletClient.sendTransaction({\n account,\n to: token,\n data: transferData,\n chain: this.walletClient.chain ?? null,\n });\n }\n\n async swap(\n tokenIn: Address,\n tokenOut: Address,\n amountIn: bigint,\n options: SwapOptions = {},\n ): Promise<SwapResult> {\n const slippageBps = options.slippageBps ?? DEFAULT_SLIPPAGE_BPS;\n const deadlineSecs = options.deadlineSecs ?? 300;\n const feeWallet = options.feeWallet ?? this.config.feeWallet;\n\n const quote = await this.getQuote(tokenIn, tokenOut, amountIn, {\n slippageBps,\n feeTiers: options.feeTiers,\n });\n\n if (quote.gasEstimate > 2000000n) {\n console.warn(\n `SwapModule: High gas estimate (${quote.gasEstimate}). Pool may be illiquid.`,\n );\n }\n\n const approvalTxHash = await this.ensureApproval(\n tokenIn,\n this.config.routerAddress,\n amountIn,\n );\n const approvalRequired = approvalTxHash !== undefined;\n\n let feeTxHash: Hash | undefined;\n if (quote.feeAmount > 0n && feeWallet !== this.accountAddress) {\n feeTxHash = await this.transferFee(tokenIn, quote.feeAmount, feeWallet);\n }\n\n const account = this.walletClient.account;\n if (!account) throw new Error(\"SwapModule: walletClient has no account\");\n\n const _deadline = calcDeadline(deadlineSecs); // reserved for router versions that accept deadlines\n const swapData = encodeFunctionData({\n abi: UniswapV3RouterAbi,\n functionName: \"exactInputSingle\",\n args: [\n {\n tokenIn,\n tokenOut,\n fee: quote.poolFeeTier,\n recipient: this.accountAddress,\n amountIn: quote.amountInNet,\n amountOutMinimum: quote.amountOutMinimum,\n sqrtPriceLimitX96: 0n,\n },\n ],\n });\n\n const txHash = await this.walletClient.sendTransaction({\n account,\n to: this.config.routerAddress,\n data: swapData,\n chain: this.walletClient.chain ?? null,\n });\n\n return { txHash, feeTxHash, quote, approvalRequired, approvalTxHash };\n }\n\n getConfig(): SwapModuleConfig {\n return { ...this.config };\n }\n\n setFeeWallet(address: Address): void {\n this.config.feeWallet = address;\n }\n}\n\nexport function attachSwap(\n wallet: {\n address: Address;\n publicClient: PublicClient;\n walletClient: WalletClient;\n },\n config?: Partial<SwapModuleConfig> & { chain?: SwapChain },\n) {\n const swapModule = new SwapModule(\n wallet.publicClient,\n wallet.walletClient,\n wallet.address,\n config,\n );\n return {\n ...wallet,\n swapModule,\n swap: swapModule.swap.bind(swapModule),\n getQuote: swapModule.getQuote.bind(swapModule),\n };\n}\n",
|
|
25
|
+
"/**\n * @module swap/types\n * Type definitions and constants for the multi-chain Uniswap V3 SwapModule.\n *\n * Supported swap chains: Base, Arbitrum, Optimism, Polygon.\n * All router/quoter addresses verified against official Uniswap V3 deployment docs:\n * - Base: https://docs.uniswap.org/contracts/v3/reference/deployments/base-deployments\n * - Arbitrum: https://docs.uniswap.org/contracts/v3/reference/deployments/arbitrum-deployments\n * - Optimism: https://docs.uniswap.org/contracts/v3/reference/deployments/optimism-deployments\n * - Polygon: https://docs.uniswap.org/contracts/v3/reference/deployments/polygon-deployments\n *\n * Note: Base uses a unique SwapRouter02 address; Arbitrum, Optimism, and Polygon\n * share the same universal SwapRouter02 deployment address.\n */\nimport type { Address, Hash } from \"viem\";\n\n/** Uniswap V3 fee tier options */\nexport type UniswapFeeTier = 100 | 500 | 3000 | 10000;\n\n/** Chains supported for Uniswap V3 swap */\nexport type SwapChain = \"base\" | \"arbitrum\" | \"optimism\" | \"polygon\";\n\nexport interface SwapQuote {\n tokenIn: Address;\n tokenOut: Address;\n amountInRaw: bigint;\n amountInNet: bigint;\n feeAmount: bigint;\n amountOut: bigint;\n amountOutMinimum: bigint;\n poolFeeTier: UniswapFeeTier;\n effectiveRate: number;\n gasEstimate: bigint;\n}\n\nexport interface SwapOptions {\n slippageBps?: number;\n feeTiers?: UniswapFeeTier[];\n deadlineSecs?: number;\n feeWallet?: Address;\n}\n\nexport interface SwapResult {\n txHash: Hash;\n feeTxHash?: Hash;\n quote: SwapQuote;\n approvalRequired: boolean;\n approvalTxHash?: Hash;\n}\n\nexport interface SwapModuleConfig {\n routerAddress: Address;\n quoterAddress: Address;\n feeBps: number;\n feeWallet: Address;\n /** Chain this SwapModule is configured for */\n chain: SwapChain;\n}\n\n// ─── Token Addresses ───\n\n/** Well-known Base Mainnet token addresses */\nexport const BASE_TOKENS = {\n USDC: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\" as const,\n WETH: \"0x4200000000000000000000000000000000000006\" as const,\n cbETH: \"0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22\" as const,\n WNATIVE: \"0x4200000000000000000000000000000000000006\" as const,\n};\n\n/** Well-known Arbitrum token addresses */\nexport const ARBITRUM_TOKENS = {\n USDC: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\" as const,\n WETH: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\" as const,\n WNATIVE: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\" as const,\n};\n\n/** Well-known Optimism token addresses */\nexport const OPTIMISM_TOKENS = {\n USDC: \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\" as const,\n WETH: \"0x4200000000000000000000000000000000000006\" as const,\n OP: \"0x4200000000000000000000000000000000000042\" as const,\n WNATIVE: \"0x4200000000000000000000000000000000000006\" as const,\n};\n\n/** Well-known Polygon token addresses */\nexport const POLYGON_TOKENS = {\n USDC: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\" as const,\n WETH: \"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619\" as const,\n WMATIC: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\" as const,\n WNATIVE: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\" as const,\n};\n\n// ─── Uniswap V3 Contract Addresses ───\n\n/**\n * Uniswap V3 router and quoter addresses.\n *\n * Base has a different router (SwapRouter02 deployed at a unique address due to BASE chain launch).\n * Arbitrum, Optimism, and Polygon use the same universal SwapRouter02 address.\n *\n * Sources:\n * - Base: https://docs.uniswap.org/contracts/v3/reference/deployments/base-deployments\n * - Arbitrum: https://docs.uniswap.org/contracts/v3/reference/deployments/arbitrum-deployments\n * - Optimism: https://docs.uniswap.org/contracts/v3/reference/deployments/optimism-deployments\n * - Polygon: https://docs.uniswap.org/contracts/v3/reference/deployments/polygon-deployments\n */\nexport const UNISWAP_V3_ADDRESSES: Record<\n SwapChain,\n { ROUTER: Address; QUOTER_V2: Address }\n> = {\n base: {\n ROUTER: \"0x2626664c2603336E57B271c5C0b26F421741e481\",\n QUOTER_V2: \"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a\",\n },\n arbitrum: {\n ROUTER: \"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\",\n QUOTER_V2: \"0x61fFE014bA17989E743c5F6cB21bF9697530B21e\",\n },\n optimism: {\n ROUTER: \"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\",\n QUOTER_V2: \"0x61fFE014bA17989E743c5F6cB21bF9697530B21e\",\n },\n polygon: {\n ROUTER: \"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\",\n QUOTER_V2: \"0x61fFE014bA17989E743c5F6cB21bF9697530B21e\",\n },\n};\n\n/** Protocol fee in bps — 0.875% */\nexport const PROTOCOL_FEE_BPS = 875;\n/** Protocol fee collector address (all EVM chains) */\nexport const PROTOCOL_FEE_COLLECTOR =\n \"0xff86829393C6C26A4EC122bE0Cc3E466Ef876AdD\" as const;\n/** Default slippage in bps — 0.5% */\nexport const DEFAULT_SLIPPAGE_BPS = 50;\n",
|
|
26
|
+
"/**\n * @module convenience\n * Environment-variable-driven wallet bootstrap helpers.\n *\n * Provides three dead-simple factory functions that read all configuration\n * from process environment variables so that any agent can set up a fully\n * functional wallet in 3 lines without touching viem directly:\n *\n * ```typescript\n * import { walletFromEnv, setPolicyFromEnv, x402FromEnv } from 'agentwallet-sdk';\n *\n * const wallet = walletFromEnv();\n * await setPolicyFromEnv(wallet);\n * const client = x402FromEnv(wallet);\n * ```\n *\n * ### Environment variables\n *\n * | Variable | Required | Default | Description |\n * |-----------------------|----------|----------------|--------------------------------------------------|\n * | AGENT_PRIVATE_KEY | ✅ yes | — | EOA private key (0x-prefixed hex, 32 bytes) |\n * | AGENT_WALLET_ADDRESS | ✅ yes | — | AgentAccountV2 smart-wallet address |\n * | CHAIN_NAME | no | base | Chain name (base, mainnet, arbitrum, …) |\n * | CHAIN_ID | no | — | Alternative to CHAIN_NAME — numeric chain id |\n * | RPC_URL | no | chain default | Custom JSON-RPC endpoint |\n * | SPEND_LIMIT_PER_TX | no | — | Per-tx USDC limit (decimal, e.g. \"1.00\") |\n * | SPEND_LIMIT_DAILY | no | — | Daily USDC limit (decimal, e.g. \"10.00\") |\n * | SPEND_ALLOWLIST | no | — | Comma-separated recipient addresses |\n * | X402_SUPPORTED_NETWORKS | no | (all mainnet) | Comma-separated \"chain:chainId\" network strings |\n * | X402_GLOBAL_DAILY_LIMIT | no | — | Global daily x402 USDC limit (decimal) |\n * | X402_PER_REQUEST_MAX | no | — | Per-request max USDC spend (decimal) |\n */\n\nimport type { Address, Chain, Hex } from \"viem\";\nimport { createWalletClient, http, parseUnits } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport {\n arbitrum,\n base,\n baseSepolia,\n mainnet,\n optimism,\n polygon,\n} from \"viem/chains\";\nimport type { AgentWalletConfig } from \"./types.js\";\nimport { createWallet, NATIVE_TOKEN, setSpendPolicy } from \"./wallet-core.js\";\nimport { createX402Client } from \"./x402/middleware.js\";\nimport { DEFAULT_SUPPORTED_NETWORKS, USDC_ADDRESSES } from \"./x402/types.js\";\n\n// ─── Chain registry ────────────────────────────────────────────────────────\n\n/**\n * Well-known chains, keyed by name (lower-case) or numeric id.\n * Extend this map if you need additional L2s.\n */\nconst CHAIN_MAP: Record<string, Chain> = {\n base,\n \"base-sepolia\": baseSepolia,\n basesepolia: baseSepolia,\n mainnet,\n ethereum: mainnet,\n eth: mainnet,\n arbitrum,\n arb: arbitrum,\n optimism,\n op: optimism,\n polygon,\n matic: polygon,\n};\n\n/** Fallback RPC endpoints for chains that have no public default in viem. */\nconst DEFAULT_RPC: Record<string, string> = {\n base: \"https://mainnet.base.org\",\n \"base-sepolia\": \"https://sepolia.base.org\",\n mainnet: \"https://cloudflare-eth.com\",\n ethereum: \"https://cloudflare-eth.com\",\n arbitrum: \"https://arb1.arbitrum.io/rpc\",\n optimism: \"https://mainnet.optimism.io\",\n polygon: \"https://polygon-rpc.com\",\n};\n\n/**\n * Resolve a chain object from either a name string or a numeric chain id.\n * Tries CHAIN_MAP by name, then falls back to scanning by chainId.\n *\n * @param nameOrId - Chain name (\"base\", \"arbitrum\", …) or numeric id (8453, …).\n * @returns The viem Chain object, or `base` as the default.\n */\nfunction resolveChain(nameOrId: string | number): Chain {\n if (typeof nameOrId === \"number\") {\n const found = Object.values(CHAIN_MAP).find((c) => c.id === nameOrId);\n return found ?? base;\n }\n const key = nameOrId.toLowerCase().trim();\n return CHAIN_MAP[key] ?? base;\n}\n\n/** Maps a viem chain to the string key expected by `createWallet` (subset of networks). */\nfunction chainToCreateWalletKey(chain: Chain): AgentWalletConfig[\"chain\"] {\n switch (chain.id) {\n case 8453:\n return \"base\";\n case 84532:\n return \"base-sepolia\";\n case 1:\n return \"ethereum\";\n case 42161:\n return \"arbitrum\";\n case 137:\n return \"polygon\";\n default:\n throw new Error(\n `[walletFromEnv] Unsupported chain for AgentWallet (${chain.name}, id ${chain.id}). ` +\n `Use base, base-sepolia, ethereum, arbitrum, or polygon.`,\n );\n }\n}\n\n// ─── USDC scaling ──────────────────────────────────────────────────────────\n\nconst USDC_DECIMALS = 6;\n\n/**\n * Parse a human-readable USDC amount (e.g. \"1.50\") into base units (bigint).\n * Returns `undefined` if the string is falsy or not a valid number.\n *\n * @param value - Decimal string such as \"0.50\" or \"100\".\n */\nfunction parseUsdc(value: string | undefined): bigint | undefined {\n if (!value || value.trim() === \"\") return undefined;\n try {\n return parseUnits(value.trim(), USDC_DECIMALS);\n } catch {\n console.warn(`[walletFromEnv] Could not parse USDC amount: \"${value}\"`);\n return undefined;\n }\n}\n\n// ─── Public API ────────────────────────────────────────────────────────────\n\n/**\n * Create a fully configured AgentWallet from environment variables.\n *\n * Reads:\n * - **AGENT_PRIVATE_KEY** — EOA signing key (required; 0x-prefixed 32-byte hex)\n * - **AGENT_WALLET_ADDRESS** — AgentAccountV2 contract address (required)\n * - **CHAIN_NAME** or **CHAIN_ID** — target chain (optional; defaults to Base mainnet)\n * - **RPC_URL** — custom RPC endpoint (optional; uses chain default if omitted)\n *\n * @param options - Optional overrides for chain and rpcUrl.\n * @param options.chain - Chain name that takes precedence over the env var.\n * @param options.rpcUrl - RPC endpoint that takes precedence over the env var.\n * @returns A fully configured wallet object (same shape as `createWallet()`).\n *\n * @throws {Error} If AGENT_PRIVATE_KEY is missing or not a valid hex key.\n * @throws {Error} If AGENT_WALLET_ADDRESS is missing.\n *\n * @example\n * ```typescript\n * const wallet = walletFromEnv({ chain: 'base-sepolia' });\n * ```\n */\nexport function walletFromEnv(options?: {\n chain?: string;\n rpcUrl?: string;\n}): ReturnType<typeof createWallet> {\n // ── Private key ────────────────────────────────────────────────────────\n const rawKey = process.env.AGENT_PRIVATE_KEY;\n if (!rawKey || rawKey.trim() === \"\") {\n throw new Error(\n \"[walletFromEnv] AGENT_PRIVATE_KEY environment variable is required. \" +\n \"Set it to the 0x-prefixed 32-byte hex private key of your agent EOA.\",\n );\n }\n const privateKey = (rawKey.startsWith(\"0x\") ? rawKey : `0x${rawKey}`) as Hex;\n\n // ── Wallet (smart-contract) address ────────────────────────────────────\n const walletAddress = process.env.AGENT_WALLET_ADDRESS;\n if (!walletAddress || walletAddress.trim() === \"\") {\n throw new Error(\n \"[walletFromEnv] AGENT_WALLET_ADDRESS environment variable is required. \" +\n \"Set it to the address of your deployed AgentAccountV2 smart wallet.\",\n );\n }\n\n // ── Chain resolution ────────────────────────────────────────────────────\n const chainSource =\n options?.chain ??\n process.env.CHAIN_NAME ??\n (process.env.CHAIN_ID ? process.env.CHAIN_ID : undefined);\n\n const chain = chainSource\n ? resolveChain(\n /^\\d+$/.test(String(chainSource))\n ? parseInt(chainSource, 10)\n : String(chainSource),\n )\n : base;\n\n // ── RPC URL ─────────────────────────────────────────────────────────────\n const rpcUrl =\n options?.rpcUrl ??\n process.env.RPC_URL ??\n DEFAULT_RPC[chain.name.toLowerCase()] ??\n DEFAULT_RPC.base;\n\n // ── Build viem walletClient ──────────────────────────────────────────────\n const account = privateKeyToAccount(privateKey);\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // ── Delegate to core createWallet ────────────────────────────────────────\n return createWallet({\n accountAddress: walletAddress as Address,\n chain: chainToCreateWalletKey(chain),\n rpcUrl,\n walletClient,\n });\n}\n\n/**\n * Apply a spending policy to a wallet from environment variables.\n *\n * Reads:\n * - **SPEND_LIMIT_PER_TX** — maximum USDC per single transaction (e.g. \"1.00\")\n * - **SPEND_LIMIT_DAILY** — maximum USDC per 24-hour period (e.g. \"10.00\")\n * - **SPEND_ALLOWLIST** — comma-separated ERC-20 token addresses to restrict\n *\n * If neither limit is set, logs a warning and falls back to queue-for-approval\n * mode (perTxLimit = 0, periodLimit = 0) so all agent transactions must be\n * manually approved. This is the safest default.\n *\n * @param wallet - Wallet returned by `walletFromEnv()` (or `createWallet()`).\n * @returns Promise that resolves to the on-chain tx hash of the policy update.\n *\n * @example\n * ```typescript\n * await setPolicyFromEnv(wallet);\n * ```\n */\nexport async function setPolicyFromEnv(\n wallet: ReturnType<typeof createWallet>,\n): Promise<string> {\n const perTxLimit = parseUsdc(process.env.SPEND_LIMIT_PER_TX);\n const periodLimit = parseUsdc(process.env.SPEND_LIMIT_DAILY);\n\n // Determine which USDC token address to use for this chain\n const chainId = wallet.chain.id;\n const networkKey = Object.keys(USDC_ADDRESSES).find((k) => {\n const parts = k.split(\":\");\n return parts.length === 2 && parseInt(parts[1], 10) === chainId;\n });\n // Use USDC if found for this chain, otherwise fall back to native ETH (zero address)\n const token: Address = networkKey\n ? (USDC_ADDRESSES[networkKey] as Address)\n : NATIVE_TOKEN;\n\n // Warn and use safe defaults when no limits are configured\n if (perTxLimit === undefined && periodLimit === undefined) {\n console.warn(\n \"[setPolicyFromEnv] Neither SPEND_LIMIT_PER_TX nor SPEND_LIMIT_DAILY is set. \" +\n \"Defaulting to queue-for-approval mode (all agent transactions require owner sign-off). \" +\n \"Set these env vars to enable autonomous spending.\",\n );\n const hash = await setSpendPolicy(wallet, {\n token,\n perTxLimit: 0n,\n periodLimit: 0n,\n periodLength: 86400, // 24 h\n });\n console.info(\n `[setPolicyFromEnv] Queue-for-approval policy set. tx: ${hash}`,\n );\n return hash;\n }\n\n const resolvedPerTxLimit = perTxLimit ?? 0n;\n const resolvedPeriodLimit = periodLimit ?? 0n;\n\n const hash = await setSpendPolicy(wallet, {\n token,\n perTxLimit: resolvedPerTxLimit,\n periodLimit: resolvedPeriodLimit,\n periodLength: 86400, // 24 h\n });\n\n console.info(\n `[setPolicyFromEnv] Policy set — perTx: ${resolvedPerTxLimit} base units, ` +\n `daily: ${resolvedPeriodLimit} base units on ${wallet.chain.name}. tx: ${hash}`,\n );\n\n return hash;\n}\n\n/**\n * Create an x402 payment client from environment variables.\n *\n * Reads:\n * - **X402_SUPPORTED_NETWORKS** — comma-separated \"chain:chainId\" strings\n * (e.g. \"base:8453,arbitrum:42161\"); defaults to all supported mainnets\n * - **X402_GLOBAL_DAILY_LIMIT** — total daily USDC budget across all x402\n * services (decimal, e.g. \"5.00\")\n * - **X402_PER_REQUEST_MAX** — per-request USDC ceiling (decimal)\n *\n * Sensible defaults: supports all 10 mainnet x402 chains, unlimited daily spend\n * (rely on the agent's on-chain spend policy as the hard limit), 1 auto-retry.\n *\n * @param wallet - Wallet returned by `walletFromEnv()` (or `createWallet()`).\n * @returns A configured X402Client instance.\n *\n * @example\n * ```typescript\n * const client = x402FromEnv(wallet);\n * const data = await client.fetch('https://api.example.com/premium-endpoint');\n * ```\n */\nexport function x402FromEnv(\n wallet: ReturnType<typeof createWallet>,\n): ReturnType<typeof createX402Client> {\n // Supported networks — override with comma-separated list or use all defaults\n const networksEnv = process.env.X402_SUPPORTED_NETWORKS;\n const supportedNetworks: string[] = networksEnv\n ? networksEnv\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(Boolean)\n : [...DEFAULT_SUPPORTED_NETWORKS];\n\n // Global daily limit\n const globalDailyLimitUsdc = parseUsdc(process.env.X402_GLOBAL_DAILY_LIMIT);\n const globalPerRequestMaxUsdc = parseUsdc(process.env.X402_PER_REQUEST_MAX);\n\n return createX402Client(wallet, {\n supportedNetworks,\n ...(globalDailyLimitUsdc !== undefined && {\n globalDailyLimit: globalDailyLimitUsdc,\n }),\n ...(globalPerRequestMaxUsdc !== undefined && {\n globalPerRequestMax: globalPerRequestMaxUsdc,\n }),\n autoPay: true,\n maxRetries: 1,\n });\n}\n",
|
|
27
|
+
"import type { Address, Hash, Hex } from \"viem\";\n\n/** Mirrors the on-chain TaskStatus enum */\nexport enum TaskStatus {\n Created = 0,\n Funded = 1,\n Fulfilled = 2,\n Challenged = 3,\n Resolved = 4,\n Cancelled = 5,\n}\n\n/** Supported built-in verifier types */\nexport type VerifierType = \"optimistic\" | \"hash\";\n\n/** Parameters for creating a new mutual-stake escrow */\nexport interface CreateEscrowParams {\n /** Seller/service-provider address */\n seller: Address;\n /** Payment amount in token's smallest unit (e.g., 6 decimals for USDC) */\n paymentAmount: bigint;\n /** Buyer's anti-grief collateral */\n buyerStake: bigint;\n /** Seller's anti-fraud collateral */\n sellerStake: bigint;\n /** Verifier type or custom verifier contract address */\n verifier: VerifierType | Address;\n /** Verifier-specific configuration data (auto-generated for built-in verifiers) */\n verifierData?: Hex;\n /** Challenge window in seconds after fulfillment */\n challengeWindow: number;\n /** Unix timestamp deadline for the task */\n deadline: number;\n /** ERC-20 token address (defaults to USDC on Base) */\n token?: Address;\n}\n\n/** Result from creating an escrow */\nexport interface EscrowCreated {\n /** Address of the deployed StakeVault contract */\n address: Address;\n /** Transaction hash of the factory call */\n txHash: Hash;\n}\n\n/** Full escrow details from on-chain */\nexport interface EscrowDetails {\n buyer: Address;\n seller: Address;\n token: Address;\n paymentAmount: bigint;\n buyerStake: bigint;\n sellerStake: bigint;\n verifier: Address;\n deadline: bigint;\n challengeWindow: bigint;\n status: TaskStatus;\n fulfilledAt: bigint;\n}\n\n/** Transaction result */\nexport interface TxResult {\n txHash: Hash;\n}\n",
|
|
28
|
+
"import {\n type Address,\n encodeAbiParameters,\n type Hex,\n parseAbiParameters,\n} from \"viem\";\nimport type { VerifierType } from \"./types.js\";\n\n/**\n * Known verifier contract addresses on Base mainnet.\n * These are deployed once and shared by all StakeVault instances.\n */\nexport const VERIFIER_ADDRESSES: Record<\n string,\n Record<VerifierType, Address>\n> = {\n // Base mainnet (chain ID 8453)\n \"8453\": {\n optimistic: \"0x0000000000000000000000000000000000000000\", // Pre-deployment: set after deploying StakeVault verifier contracts to Base\n hash: \"0x0000000000000000000000000000000000000000\", // Pre-deployment: set after deploying StakeVault verifier contracts to Base\n },\n // Base Sepolia testnet (chain ID 84532)\n \"84532\": {\n optimistic: \"0x0000000000000000000000000000000000000000\", // Pre-deployment: set after deploying StakeVault verifier contracts to Base\n hash: \"0x0000000000000000000000000000000000000000\", // Pre-deployment: set after deploying StakeVault verifier contracts to Base\n },\n};\n\n/**\n * Resolve a verifier type to its deployed contract address for a given chain\n * @param verifier - Built-in verifier type or custom contract address\n * @param chainId - Chain ID to look up\n * @returns The verifier contract address\n */\nexport function resolveVerifierAddress(\n verifier: VerifierType | Address,\n chainId: number,\n): Address {\n if (verifier.startsWith(\"0x\") && verifier.length === 42) {\n return verifier as Address;\n }\n\n const chainAddresses = VERIFIER_ADDRESSES[chainId.toString()];\n if (!chainAddresses) {\n throw new Error(`No verifier addresses configured for chain ${chainId}`);\n }\n\n const address = chainAddresses[verifier as VerifierType];\n if (!address || address === \"0x0000000000000000000000000000000000000000\") {\n throw new Error(\n `Verifier \"${verifier}\" not deployed on chain ${chainId}. Deploy it first or pass a custom address.`,\n );\n }\n\n return address;\n}\n\n/**\n * Encode verifier configuration data for the HashVerifier\n * @param expectedHash - SHA256 hash of the expected output\n * @returns ABI-encoded bytes for the verifierData field\n */\nexport function encodeHashVerifierData(expectedHash: Hex): Hex {\n return encodeAbiParameters(parseAbiParameters(\"bytes32\"), [expectedHash]);\n}\n\n/**\n * Encode verifier configuration data for the OptimisticVerifier\n * @returns Empty bytes (optimistic verifier has no config)\n */\nexport function encodeOptimisticVerifierData(): Hex {\n return \"0x\";\n}\n",
|
|
29
|
+
"import type { Address, Hex, PublicClient, WalletClient } from \"viem\";\nimport type {\n CreateEscrowParams,\n EscrowCreated,\n EscrowDetails,\n TxResult,\n} from \"./types.js\";\nimport { TaskStatus } from \"./types.js\";\nimport {\n encodeOptimisticVerifierData,\n resolveVerifierAddress,\n} from \"./verifiers.js\";\n\n// ─── ABIs ────────────────────────────────────────────────────────────────────\n\nconst StakeVaultFactoryAbi = [\n {\n name: \"createEscrow\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"_buyer\", type: \"address\" },\n { name: \"_seller\", type: \"address\" },\n { name: \"_token\", type: \"address\" },\n { name: \"_paymentAmount\", type: \"uint256\" },\n { name: \"_buyerStake\", type: \"uint256\" },\n { name: \"_sellerStake\", type: \"uint256\" },\n { name: \"_verifier\", type: \"address\" },\n { name: \"_verifierData\", type: \"bytes\" },\n { name: \"_deadline\", type: \"uint256\" },\n { name: \"_challengeWindow\", type: \"uint256\" },\n ],\n outputs: [{ name: \"vault\", type: \"address\" }],\n },\n {\n name: \"VaultCreated\",\n type: \"event\",\n inputs: [\n { name: \"vault\", type: \"address\", indexed: true },\n { name: \"buyer\", type: \"address\", indexed: true },\n { name: \"seller\", type: \"address\", indexed: true },\n { name: \"token\", type: \"address\", indexed: false },\n { name: \"paymentAmount\", type: \"uint256\", indexed: false },\n { name: \"buyerStake\", type: \"uint256\", indexed: false },\n { name: \"sellerStake\", type: \"uint256\", indexed: false },\n { name: \"verifier\", type: \"address\", indexed: false },\n { name: \"deadline\", type: \"uint256\", indexed: false },\n ],\n },\n] as const;\n\nconst StakeVaultAbi = [\n {\n name: \"fund\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"accept\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"fulfill\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"proof\", type: \"bytes\" }],\n outputs: [],\n },\n {\n name: \"verify\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"challenge\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"evidence\", type: \"bytes\" }],\n outputs: [],\n },\n {\n name: \"resolve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"sellerWins\", type: \"bool\" }],\n outputs: [],\n },\n {\n name: \"cancel\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"reclaimExpired\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [],\n },\n {\n name: \"getEscrowDetails\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [\n { name: \"_buyer\", type: \"address\" },\n { name: \"_seller\", type: \"address\" },\n { name: \"_token\", type: \"address\" },\n { name: \"_paymentAmount\", type: \"uint256\" },\n { name: \"_buyerStake\", type: \"uint256\" },\n { name: \"_sellerStake\", type: \"uint256\" },\n { name: \"_verifier\", type: \"address\" },\n { name: \"_deadline\", type: \"uint256\" },\n { name: \"_challengeWindow\", type: \"uint256\" },\n { name: \"_status\", type: \"uint8\" },\n { name: \"_fulfilledAt\", type: \"uint256\" },\n ],\n },\n {\n name: \"status\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n] as const;\n\nfunction toTaskStatus(value: unknown): TaskStatus {\n const status = Number(value);\n if (!Number.isInteger(status) || !(status in TaskStatus)) {\n throw new Error(`Invalid escrow task status: ${String(value)}`);\n }\n return status as TaskStatus;\n}\n\nconst ERC20ApproveAbi = [\n {\n name: \"approve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n] as const;\n\n/** Base USDC address */\nconst BASE_USDC: Address = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\";\n\n/**\n * MutualStakeEscrow — SDK class for creating and managing mutual-stake escrow vaults\n *\n * Wraps the StakeVault and StakeVaultFactory contracts with a clean TypeScript API.\n * Both buyer and seller deposit collateral, ensuring aligned incentives.\n */\nexport class MutualStakeEscrow {\n private publicClient: PublicClient;\n private walletClient: WalletClient;\n private factoryAddress: Address;\n private chainId: number;\n\n constructor(params: {\n publicClient: PublicClient;\n walletClient: WalletClient;\n factoryAddress: Address;\n chainId: number;\n }) {\n this.publicClient = params.publicClient;\n this.walletClient = params.walletClient;\n this.factoryAddress = params.factoryAddress;\n this.chainId = params.chainId;\n }\n\n /**\n * Create a new escrow vault via the factory\n * @param params - Escrow creation parameters\n * @returns The deployed vault address and transaction hash\n */\n async create(params: CreateEscrowParams): Promise<EscrowCreated> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const token = params.token ?? BASE_USDC;\n const verifierAddress = resolveVerifierAddress(\n params.verifier,\n this.chainId,\n );\n const verifierData = params.verifierData ?? encodeOptimisticVerifierData();\n\n const txHash = await this.walletClient.writeContract({\n address: this.factoryAddress,\n abi: StakeVaultFactoryAbi,\n functionName: \"createEscrow\",\n args: [\n account.address,\n params.seller,\n token,\n params.paymentAmount,\n params.buyerStake,\n params.sellerStake,\n verifierAddress,\n verifierData,\n BigInt(params.deadline),\n BigInt(params.challengeWindow),\n ],\n account,\n chain: this.walletClient.chain,\n });\n\n await this.publicClient.waitForTransactionReceipt({ hash: txHash });\n\n // Read vault address from return data via simulation.\n const vaultAddress = (await this.publicClient.readContract({\n address: this.factoryAddress,\n abi: StakeVaultFactoryAbi,\n functionName: \"createEscrow\",\n args: [\n account.address,\n params.seller,\n token,\n params.paymentAmount,\n params.buyerStake,\n params.sellerStake,\n verifierAddress,\n verifierData,\n BigInt(params.deadline),\n BigInt(params.challengeWindow),\n ],\n })) as Address;\n\n return { address: vaultAddress, txHash };\n }\n\n /**\n * Fund an escrow as buyer (deposits payment + buyerStake)\n * @param vaultAddress - Address of the StakeVault\n * @param approveAmount - Total amount to approve (payment + buyerStake)\n */\n async fund(vaultAddress: Address, approveAmount: bigint): Promise<TxResult> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const details = await this.getDetails(vaultAddress);\n\n // Approve token transfer\n await this.walletClient.writeContract({\n address: details.token,\n abi: ERC20ApproveAbi,\n functionName: \"approve\",\n args: [vaultAddress, approveAmount],\n account,\n chain: this.walletClient.chain,\n });\n\n const txHash = await this.walletClient.writeContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"fund\",\n args: [],\n account,\n chain: this.walletClient.chain,\n });\n\n return { txHash };\n }\n\n /**\n * Accept an escrow as seller (deposits sellerStake)\n * @param vaultAddress - Address of the StakeVault\n */\n async accept(vaultAddress: Address): Promise<TxResult> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const details = await this.getDetails(vaultAddress);\n\n // Approve seller stake transfer\n await this.walletClient.writeContract({\n address: details.token,\n abi: ERC20ApproveAbi,\n functionName: \"approve\",\n args: [vaultAddress, details.sellerStake],\n account,\n chain: this.walletClient.chain,\n });\n\n const txHash = await this.walletClient.writeContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"accept\",\n args: [],\n account,\n chain: this.walletClient.chain,\n });\n\n return { txHash };\n }\n\n /**\n * Submit fulfillment proof as seller\n * @param vaultAddress - Address of the StakeVault\n * @param proof - Completion proof bytes\n */\n async fulfill(vaultAddress: Address, proof: Hex): Promise<TxResult> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const txHash = await this.walletClient.writeContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"fulfill\",\n args: [proof],\n account,\n chain: this.walletClient.chain,\n });\n\n return { txHash };\n }\n\n /**\n * Verify completion after challenge window (anyone can call)\n * @param vaultAddress - Address of the StakeVault\n */\n async verify(vaultAddress: Address): Promise<TxResult> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const txHash = await this.walletClient.writeContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"verify\",\n args: [],\n account,\n chain: this.walletClient.chain,\n });\n\n return { txHash };\n }\n\n /**\n * Challenge a fulfillment as buyer\n * @param vaultAddress - Address of the StakeVault\n * @param evidence - Challenge evidence bytes\n */\n async challenge(vaultAddress: Address, evidence: Hex): Promise<TxResult> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const txHash = await this.walletClient.writeContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"challenge\",\n args: [evidence],\n account,\n chain: this.walletClient.chain,\n });\n\n return { txHash };\n }\n\n /**\n * Cancel escrow before seller accepts (buyer only)\n * @param vaultAddress - Address of the StakeVault\n */\n async cancel(vaultAddress: Address): Promise<TxResult> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const txHash = await this.walletClient.writeContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"cancel\",\n args: [],\n account,\n chain: this.walletClient.chain,\n });\n\n return { txHash };\n }\n\n /**\n * Reclaim funds after deadline expiry\n * @param vaultAddress - Address of the StakeVault\n */\n async reclaimExpired(vaultAddress: Address): Promise<TxResult> {\n const account = this.walletClient.account;\n if (!account) throw new Error(\"Wallet client must have an account\");\n\n const txHash = await this.walletClient.writeContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"reclaimExpired\",\n args: [],\n account,\n chain: this.walletClient.chain,\n });\n\n return { txHash };\n }\n\n /**\n * Get full escrow details from on-chain\n * @param vaultAddress - Address of the StakeVault\n */\n async getDetails(vaultAddress: Address): Promise<EscrowDetails> {\n const result = await this.publicClient.readContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"getEscrowDetails\",\n args: [],\n });\n\n const [\n buyer,\n seller,\n token,\n paymentAmount,\n buyerStake,\n sellerStake,\n verifier,\n deadline,\n challengeWindow,\n statusNum,\n fulfilledAt,\n ] = result as [\n Address,\n Address,\n Address,\n bigint,\n bigint,\n bigint,\n Address,\n bigint,\n bigint,\n number,\n bigint,\n ];\n\n return {\n buyer,\n seller,\n token,\n paymentAmount,\n buyerStake,\n sellerStake,\n verifier,\n deadline,\n challengeWindow,\n status: statusNum as TaskStatus,\n fulfilledAt,\n };\n }\n\n /**\n * Get the current status of an escrow\n * @param vaultAddress - Address of the StakeVault\n */\n async getStatus(vaultAddress: Address): Promise<TaskStatus> {\n const result = await this.publicClient.readContract({\n address: vaultAddress,\n abi: StakeVaultAbi,\n functionName: \"status\",\n args: [],\n });\n\n return toTaskStatus(result);\n }\n}\n",
|
|
30
|
+
"/**\n * SpendingPolicy — Programmable spending guardrails for AI agents.\n *\n * Beats PolicyLayer.com to market with:\n * - MerchantAllowlist — allowlist-only merchant enforcement\n * - RollingSpendCap — time-windowed spend limits\n * - DraftThenApprove — human-in-the-loop for large transactions\n * - AuditTrail — immutable local log of every payment attempt\n * - FailClosed — policy errors always reject, never approve\n *\n * @module policy/SpendingPolicy\n */\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** A payment the agent wants to make. */\nexport interface PaymentIntent {\n /** Merchant contract address or domain (e.g. \"0xABC...\" or \"api.example.com\") */\n merchant: string;\n /** Amount in the smallest token unit (e.g. USDC micro-cents = 6 decimals). Use number for JS safety in tests; real on-chain code passes BigInt via adapter. */\n amount: number;\n /** ISO-8601 timestamp string. Defaults to now if omitted. */\n timestamp?: string;\n /** Optional human-readable label */\n description?: string;\n}\n\nexport type PolicyStatus = \"approved\" | \"rejected\" | \"draft\";\n\n/** Result returned by SpendingPolicy.check(). */\nexport interface PolicyResult {\n status: PolicyStatus;\n reason?: string;\n draftId?: string; // populated when status === 'draft'\n}\n\n/** A queued draft transaction awaiting approval. */\nexport interface DraftEntry {\n draftId: string;\n payment: PaymentIntent;\n queuedAt: string; // ISO-8601\n approved: boolean;\n rejected: boolean;\n}\n\n/** Immutable record written to the audit log. */\nexport interface AuditEntry {\n id: string;\n timestamp: string;\n merchant: string;\n amount: number;\n status: PolicyStatus;\n reason?: string;\n draftId?: string;\n}\n\n/** Configuration passed to SpendingPolicy constructor. */\nexport interface SpendingPolicyConfig {\n /**\n * MerchantAllowlist: list of allowed contract addresses or domains.\n * If provided and non-empty, only these merchants are allowed.\n * Pass an empty array [] to disable allowlist enforcement (allow all).\n */\n merchantAllowlist?: string[];\n\n /**\n * RollingSpendCap: maximum cumulative spend in a rolling time window.\n * Set to undefined to disable.\n */\n rollingCap?: {\n /** Max amount (same units as PaymentIntent.amount) */\n maxAmount: number;\n /** Window size in milliseconds (e.g. 86_400_000 for 24 h) */\n windowMs: number;\n };\n\n /**\n * DraftThenApprove: payments above this threshold are placed in draft status\n * for human (or another agent) approval rather than executed immediately.\n * Set to undefined to disable.\n */\n draftThreshold?: number;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nlet _idCounter = 0;\nfunction nextId(prefix: string): string {\n return `${prefix}-${Date.now()}-${++_idCounter}`;\n}\n\n// ─── SpendingPolicy ───────────────────────────────────────────────────────────\n\nexport class SpendingPolicy {\n private config: SpendingPolicyConfig;\n private allowlist: Set<string>;\n private spendWindow: Array<{ amount: number; ts: number }>; // rolling window entries\n private auditLog: AuditEntry[];\n private drafts: Map<string, DraftEntry>;\n\n constructor(config: SpendingPolicyConfig) {\n this.config = config;\n this.allowlist = new Set(\n (config.merchantAllowlist ?? []).map((m) => m.toLowerCase()),\n );\n this.spendWindow = [];\n this.auditLog = [];\n this.drafts = new Map();\n }\n\n // ─── Public Interface ───────────────────────────────────────────────────────\n\n /**\n * FailClosed: wraps the actual check logic so that ANY unhandled error\n * produces a rejection rather than inadvertently approving a payment.\n */\n async check(payment: PaymentIntent): Promise<PolicyResult> {\n try {\n return await this._check(payment);\n } catch (err: unknown) {\n const reason = `Policy engine error (fail-closed): ${err instanceof Error ? err.message : String(err)}`;\n const result: PolicyResult = { status: \"rejected\", reason };\n await this.log(payment, result).catch(() => {\n /* ignore log errors in fail-closed path */\n });\n return result;\n }\n }\n\n /**\n * Write a payment attempt to the immutable audit log.\n */\n async log(payment: PaymentIntent, result: PolicyResult): Promise<void> {\n const entry: AuditEntry = {\n id: nextId(\"audit\"),\n timestamp: payment.timestamp ?? new Date().toISOString(),\n merchant: payment.merchant,\n amount: payment.amount,\n status: result.status,\n reason: result.reason,\n draftId: result.draftId,\n };\n this.auditLog.push(entry);\n }\n\n /** Return a copy of the current merchant allowlist. */\n getMerchantAllowlist(): string[] {\n return Array.from(this.allowlist);\n }\n\n /** Add a merchant address/domain to the allowlist at runtime. */\n addMerchant(address: string): void {\n this.allowlist.add(address.toLowerCase());\n }\n\n /** Return the full, immutable audit log (copy). */\n getAuditLog(): AuditEntry[] {\n return [...this.auditLog];\n }\n\n // ─── Draft queue management ─────────────────────────────────────────────────\n\n /** Approve a queued draft by its draftId. Returns false if not found. */\n approveDraft(draftId: string): boolean {\n const draft = this.drafts.get(draftId);\n if (!draft) return false;\n draft.approved = true;\n return true;\n }\n\n /** Reject a queued draft by its draftId. Returns false if not found. */\n rejectDraft(draftId: string): boolean {\n const draft = this.drafts.get(draftId);\n if (!draft) return false;\n draft.rejected = true;\n return true;\n }\n\n /** Return all pending drafts awaiting approval or rejection. */\n getPendingDrafts(): DraftEntry[] {\n return Array.from(this.drafts.values()).filter(\n (d) => !d.approved && !d.rejected,\n );\n }\n\n /** Return all drafts. */\n getAllDrafts(): DraftEntry[] {\n return Array.from(this.drafts.values());\n }\n\n // ─── Private Logic ──────────────────────────────────────────────────────────\n\n private async _check(payment: PaymentIntent): Promise<PolicyResult> {\n // 1. MerchantAllowlist check (only enforced when allowlist is non-empty)\n if (this.allowlist.size > 0) {\n const merchant = payment.merchant.toLowerCase();\n if (!this.allowlist.has(merchant)) {\n const result: PolicyResult = {\n status: \"rejected\",\n reason: `Merchant \"${payment.merchant}\" is not on the allowlist.`,\n };\n await this.log(payment, result);\n return result;\n }\n }\n\n // 2. RollingSpendCap check\n if (this.config.rollingCap) {\n const { maxAmount, windowMs } = this.config.rollingCap;\n const now = Date.now();\n const windowStart = now - windowMs;\n\n // Purge entries outside the window\n this.spendWindow = this.spendWindow.filter((e) => e.ts >= windowStart);\n\n const spent = this.spendWindow.reduce((sum, e) => sum + e.amount, 0);\n if (spent + payment.amount > maxAmount) {\n const result: PolicyResult = {\n status: \"rejected\",\n reason: `Rolling spend cap exceeded: spent ${spent}, cap ${maxAmount}, attempted ${payment.amount}.`,\n };\n await this.log(payment, result);\n return result;\n }\n }\n\n // 3. DraftThenApprove check\n if (\n this.config.draftThreshold !== undefined &&\n payment.amount >= this.config.draftThreshold\n ) {\n const draftId = nextId(\"draft\");\n const draft: DraftEntry = {\n draftId,\n payment,\n queuedAt: payment.timestamp ?? new Date().toISOString(),\n approved: false,\n rejected: false,\n };\n this.drafts.set(draftId, draft);\n\n const result: PolicyResult = {\n status: \"draft\",\n reason: `Amount ${payment.amount} meets or exceeds draft threshold ${this.config.draftThreshold}. Awaiting approval.`,\n draftId,\n };\n await this.log(payment, result);\n return result;\n }\n\n // 4. Approved — record spend in rolling window\n if (this.config.rollingCap) {\n this.spendWindow.push({ amount: payment.amount, ts: Date.now() });\n }\n\n const result: PolicyResult = { status: \"approved\" };\n await this.log(payment, result);\n return result;\n }\n}\n",
|
|
31
|
+
"/**\n * UptoBillingPolicy\n *\n * Local accounting for x402 \"upto\" flows where a buyer authorizes a maximum\n * amount up front and the seller later settles only actual usage.\n *\n * The policy tracks three things:\n * - the max amount authorized\n * - the amount actually settled\n * - ledger deltas for reservation, settlement, and release of unused capacity\n */\n\nexport type UptoAuthorizationStatus =\n | \"authorized\"\n | \"partially_settled\"\n | \"settled\"\n | \"released\";\n\nexport interface UptoAuthorizationRequest {\n authorizationId?: string;\n service: string;\n resource?: string;\n network: string;\n asset: string;\n payTo: string;\n maxAmount: bigint;\n metadata?: Record<string, unknown>;\n authorizedAt?: string;\n}\n\nexport interface UptoSettlementOptions {\n settledAt?: string;\n finalize?: boolean;\n txHash?: string;\n reference?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UptoSettlementRecord {\n settlementId: string;\n authorizationId: string;\n amount: bigint;\n settledAt: string;\n txHash?: string;\n reference?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UptoAuthorizationRecord {\n authorizationId: string;\n service: string;\n resource?: string;\n network: string;\n asset: string;\n payTo: string;\n maxAmount: bigint;\n settledAmount: bigint;\n releasedAmount: bigint;\n remainingAmount: bigint;\n authorizedAt: string;\n finalizedAt?: string;\n status: UptoAuthorizationStatus;\n metadata?: Record<string, unknown>;\n}\n\nexport interface WalletLedgerDelta {\n deltaId: string;\n authorizationId: string;\n type: \"authorization\" | \"settlement\" | \"release\";\n timestamp: string;\n reservedDelta: bigint;\n settledDelta: bigint;\n netWalletDelta: bigint;\n txHash?: string;\n reference?: string;\n}\n\nexport interface UptoBillingSnapshot {\n authorization: UptoAuthorizationRecord;\n settlements: UptoSettlementRecord[];\n ledgerDeltas: WalletLedgerDelta[];\n}\n\nlet counter = 0;\nfunction nextId(prefix: string): string {\n counter += 1;\n return `${prefix}-${Date.now()}-${counter}`;\n}\n\nfunction nowIso(value?: string): string {\n return value ?? new Date().toISOString();\n}\n\nfunction cloneAuthorization(\n record: UptoAuthorizationRecord,\n): UptoAuthorizationRecord {\n return {\n ...record,\n metadata: record.metadata ? { ...record.metadata } : undefined,\n };\n}\n\nfunction cloneSettlement(record: UptoSettlementRecord): UptoSettlementRecord {\n return {\n ...record,\n metadata: record.metadata ? { ...record.metadata } : undefined,\n };\n}\n\nfunction cloneDelta(record: WalletLedgerDelta): WalletLedgerDelta {\n return { ...record };\n}\n\nexport class UptoBillingPolicy {\n private authorizations = new Map<string, UptoAuthorizationRecord>();\n private settlements = new Map<string, UptoSettlementRecord[]>();\n private ledger = new Map<string, WalletLedgerDelta[]>();\n\n authorize(request: UptoAuthorizationRequest): UptoAuthorizationRecord {\n if (request.maxAmount <= 0n) {\n throw new Error(\"maxAmount must be greater than zero\");\n }\n\n const authorizationId = request.authorizationId ?? nextId(\"upto-auth\");\n if (this.authorizations.has(authorizationId)) {\n throw new Error(`Authorization already exists: ${authorizationId}`);\n }\n\n const record: UptoAuthorizationRecord = {\n authorizationId,\n service: request.service,\n resource: request.resource,\n network: request.network,\n asset: request.asset,\n payTo: request.payTo,\n maxAmount: request.maxAmount,\n settledAmount: 0n,\n releasedAmount: 0n,\n remainingAmount: request.maxAmount,\n authorizedAt: nowIso(request.authorizedAt),\n status: \"authorized\",\n metadata: request.metadata ? { ...request.metadata } : undefined,\n };\n\n this.authorizations.set(authorizationId, record);\n this.settlements.set(authorizationId, []);\n this.ledger.set(authorizationId, [\n {\n deltaId: nextId(\"upto-ledger\"),\n authorizationId,\n type: \"authorization\",\n timestamp: record.authorizedAt,\n reservedDelta: record.maxAmount,\n settledDelta: 0n,\n netWalletDelta: 0n,\n },\n ]);\n\n return cloneAuthorization(record);\n }\n\n recordSettlement(\n authorizationId: string,\n amount: bigint,\n options: UptoSettlementOptions = {},\n ): UptoBillingSnapshot {\n const auth = this.requireAuthorization(authorizationId);\n\n if (auth.status === \"settled\" || auth.status === \"released\") {\n throw new Error(`Authorization is already finalized: ${authorizationId}`);\n }\n if (amount <= 0n) {\n throw new Error(\"Settlement amount must be greater than zero\");\n }\n if (amount > auth.remainingAmount) {\n throw new Error(\n `Settlement amount ${amount} exceeds remaining authorized amount ${auth.remainingAmount}`,\n );\n }\n\n const settledAt = nowIso(options.settledAt);\n const settlement: UptoSettlementRecord = {\n settlementId: nextId(\"upto-settlement\"),\n authorizationId,\n amount,\n settledAt,\n txHash: options.txHash,\n reference: options.reference,\n metadata: options.metadata ? { ...options.metadata } : undefined,\n };\n\n auth.settledAmount += amount;\n auth.remainingAmount -= amount;\n auth.status = auth.remainingAmount === 0n ? \"settled\" : \"partially_settled\";\n\n const settlementList = this.settlements.get(authorizationId);\n if (!settlementList) {\n throw new Error(\n `[UptoBillingPolicy] Missing settlements for authorization ${authorizationId}`,\n );\n }\n settlementList.push(settlement);\n\n const ledger = this.ledger.get(authorizationId);\n if (!ledger) {\n throw new Error(\n `[UptoBillingPolicy] Missing ledger for authorization ${authorizationId}`,\n );\n }\n ledger.push({\n deltaId: nextId(\"upto-ledger\"),\n authorizationId,\n type: \"settlement\",\n timestamp: settledAt,\n reservedDelta: -amount,\n settledDelta: amount,\n netWalletDelta: -amount,\n txHash: options.txHash,\n reference: options.reference,\n });\n\n if (options.finalize) {\n this.finalizeAuthorization(authorizationId, settledAt, options.reference);\n }\n\n return this.getSnapshot(authorizationId);\n }\n\n finalizeAuthorization(\n authorizationId: string,\n finalizedAt?: string,\n reference?: string,\n ): UptoAuthorizationRecord {\n const auth = this.requireAuthorization(authorizationId);\n const ledger = this.ledger.get(authorizationId);\n if (!ledger) {\n throw new Error(\n `[UptoBillingPolicy] Missing ledger for authorization ${authorizationId}`,\n );\n }\n const timestamp = nowIso(finalizedAt);\n\n if (auth.status === \"settled\" || auth.status === \"released\") {\n auth.finalizedAt = auth.finalizedAt ?? timestamp;\n return cloneAuthorization(auth);\n }\n\n const released = auth.remainingAmount;\n auth.releasedAmount += released;\n auth.remainingAmount = 0n;\n auth.finalizedAt = timestamp;\n auth.status = auth.settledAmount > 0n ? \"settled\" : \"released\";\n\n if (released > 0n) {\n ledger.push({\n deltaId: nextId(\"upto-ledger\"),\n authorizationId,\n type: \"release\",\n timestamp,\n reservedDelta: -released,\n settledDelta: 0n,\n netWalletDelta: 0n,\n reference,\n });\n }\n\n return cloneAuthorization(auth);\n }\n\n getAuthorization(authorizationId: string): UptoAuthorizationRecord | null {\n const auth = this.authorizations.get(authorizationId);\n return auth ? cloneAuthorization(auth) : null;\n }\n\n listAuthorizations(): UptoAuthorizationRecord[] {\n return Array.from(this.authorizations.values()).map(cloneAuthorization);\n }\n\n getSettlements(authorizationId: string): UptoSettlementRecord[] {\n return (this.settlements.get(authorizationId) ?? []).map(cloneSettlement);\n }\n\n getWalletLedgerDeltas(authorizationId: string): WalletLedgerDelta[] {\n return (this.ledger.get(authorizationId) ?? []).map(cloneDelta);\n }\n\n getSnapshot(authorizationId: string): UptoBillingSnapshot {\n return {\n authorization: cloneAuthorization(\n this.requireAuthorization(authorizationId),\n ),\n settlements: this.getSettlements(authorizationId),\n ledgerDeltas: this.getWalletLedgerDeltas(authorizationId),\n };\n }\n\n getNetWalletDelta(authorizationId: string): bigint {\n return this.getWalletLedgerDeltas(authorizationId).reduce(\n (sum, delta) => sum + delta.netWalletDelta,\n 0n,\n );\n }\n\n getReservedAmount(authorizationId: string): bigint {\n return this.getWalletLedgerDeltas(authorizationId).reduce(\n (sum, delta) => sum + delta.reservedDelta,\n 0n,\n );\n }\n\n private requireAuthorization(\n authorizationId: string,\n ): UptoAuthorizationRecord {\n const auth = this.authorizations.get(authorizationId);\n if (!auth) {\n throw new Error(`Unknown authorization: ${authorizationId}`);\n }\n return auth;\n }\n}\n",
|
|
32
|
+
"/**\n * PaymentRouter — Three-rail payment architecture.\n *\n * Routes payments across three rails:\n * 1. **x402** (crypto-native) — on-chain USDC payments via the x402 protocol. Optimal for\n * micropayments, autonomous agents, and scenarios requiring on-chain audit trails.\n * 2. **MPP** (Managed Payment Protocol / Stripe) — fiat-based payments with dispute resolution.\n * Optimal for larger amounts, supervised agents, and high-frequency session batching.\n * 3. **Google AP2** (Agent Payment Protocol) — reserved rail for Google's managed agent\n * payment flow. Settlement on Base when explicitly marked live by configuration.\n *\n * Routing criteria:\n * - Transaction amount (micropayments → x402, high-frequency → MPP)\n * - Session context (ongoing session → MPP for batching efficiency)\n * - Agent autonomy level (autonomous → x402, supervised → MPP)\n * - Chain/ecosystem preference (Google ecosystem → AP2, Solana → x402-solana)\n * - Rail availability\n *\n * @module router/PaymentRouter\n */\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type PaymentRail = \"x402\" | \"mpp\" | \"x402-solana\" | \"google-ap2\";\n\nexport type RailStatus = \"live\" | \"planned\" | \"disabled\";\n\nexport interface RailConfig {\n rail: PaymentRail;\n status: RailStatus;\n /** Maximum per-transaction amount in USDC micro-units (6 decimals) */\n maxAmount?: number;\n /** Minimum per-transaction amount in USDC micro-units */\n minAmount?: number;\n}\n\nexport interface PaymentContext {\n /** Amount in USDC micro-units (6 decimals). e.g. 1_000_000 = $1.00 */\n amount: number;\n /** Recipient address or merchant domain */\n recipient: string;\n /** Whether this payment is part of an active session with repeated transactions */\n isSessionContext?: boolean;\n /** Number of transactions in the current session (if applicable) */\n sessionTxCount?: number;\n /** Whether the agent is operating autonomously (no human in loop) */\n autonomous?: boolean;\n /** Preferred chain, if any */\n preferredChain?: \"base\" | \"solana\" | \"google-ap2\";\n}\n\nexport interface RoutingDecision {\n rail: PaymentRail;\n reason: string;\n /** Estimated cost overhead (basis points) */\n estimatedOverheadBps: number;\n /** Whether this rail is currently live */\n isLive: boolean;\n}\n\n// ─── Default Rail Configuration ───────────────────────────────────────────────\n\nconst DEFAULT_RAILS: RailConfig[] = [\n {\n rail: \"x402\",\n status: \"live\",\n minAmount: 1_000, // $0.001 minimum\n maxAmount: 100_000_000, // $100 max per tx (soft limit)\n },\n {\n rail: \"mpp\",\n status: \"live\",\n minAmount: 100_000, // $0.10 minimum (Stripe floor)\n maxAmount: 10_000_000_000, // $10,000 max\n },\n {\n rail: \"x402-solana\",\n status: \"planned\",\n },\n {\n rail: \"google-ap2\",\n status: \"planned\",\n minAmount: 1_000, // $0.001 minimum (aligned with x402)\n maxAmount: 50_000_000, // $50 max per tx (conservative until spec finalized)\n },\n];\n\n// ─── Router ───────────────────────────────────────────────────────────────────\n\nexport class PaymentRouter {\n private rails: RailConfig[];\n /** Amount threshold (micro-units) below which x402 is preferred. Default: $1.00 */\n private microPaymentThreshold: number;\n /** Session tx count above which MPP is preferred for batching. Default: 5 */\n private highFrequencyThreshold: number;\n\n constructor(options?: {\n rails?: RailConfig[];\n microPaymentThreshold?: number;\n highFrequencyThreshold?: number;\n }) {\n this.rails = options?.rails ?? DEFAULT_RAILS;\n this.microPaymentThreshold = options?.microPaymentThreshold ?? 1_000_000; // $1.00\n this.highFrequencyThreshold = options?.highFrequencyThreshold ?? 5;\n }\n\n /**\n * Select the optimal payment rail for a given context.\n */\n route(context: PaymentContext): RoutingDecision {\n const {\n amount,\n isSessionContext,\n sessionTxCount,\n autonomous,\n preferredChain,\n } = context;\n\n // Google AP2 only routes after configuration explicitly marks it live.\n const googleRail = this.getRail(\"google-ap2\");\n if (googleRail?.status === \"live\" && preferredChain === \"base\") {\n // Google AP2 routes through Base for on-chain settlement\n // When live, AP2 provides Google-managed identity + payment in a single flow\n return {\n rail: \"google-ap2\",\n reason: \"Google AP2 rail — managed identity + payment bundle\",\n estimatedOverheadBps: 100, // Estimated Google platform fee\n isLive: true,\n };\n }\n\n // If Solana is explicitly preferred and x402-solana is available\n if (preferredChain === \"solana\") {\n const solanaRail = this.getRail(\"x402-solana\");\n if (solanaRail?.status === \"live\") {\n return {\n rail: \"x402-solana\",\n reason: \"Preferred chain: Solana x402\",\n estimatedOverheadBps: 0,\n isLive: true,\n };\n }\n // Solana rail is unavailable, so fall through to other rails.\n }\n\n // Rule 1: High-frequency session context → MPP (batching efficiency)\n if (\n isSessionContext &&\n (sessionTxCount ?? 0) >= this.highFrequencyThreshold\n ) {\n const mppRail = this.getRail(\"mpp\");\n if (mppRail?.status === \"live\") {\n return {\n rail: \"mpp\",\n reason: `High-frequency session (${sessionTxCount} txns) — MPP batching is more efficient`,\n estimatedOverheadBps: 290, // Stripe's ~2.9%\n isLive: true,\n };\n }\n }\n\n // Rule 2: Micropayments + autonomous → x402 (lower overhead, no session needed)\n if (amount < this.microPaymentThreshold && autonomous !== false) {\n const x402Rail = this.getRail(\"x402\");\n if (x402Rail?.status === \"live\") {\n return {\n rail: \"x402\",\n reason: `Micropayment ($${(amount / 1_000_000).toFixed(2)}) + autonomous — x402 optimal`,\n estimatedOverheadBps: 0, // x402 has no protocol fee\n isLive: true,\n };\n }\n }\n\n // Rule 3: Larger amounts or supervised → MPP (better dispute resolution, fiat rails)\n const mppRail = this.getRail(\"mpp\");\n if (mppRail?.status === \"live\" && amount >= (mppRail.minAmount ?? 0)) {\n return {\n rail: \"mpp\",\n reason: `Amount $${(amount / 1_000_000).toFixed(2)} — MPP provides fiat rails and dispute resolution`,\n estimatedOverheadBps: 290,\n isLive: true,\n };\n }\n\n // Default: x402 on Base\n return {\n rail: \"x402\",\n reason: \"Default rail — Base x402\",\n estimatedOverheadBps: 0,\n isLive: this.getRail(\"x402\")?.status === \"live\",\n };\n }\n\n /**\n * Get all available (live) rails.\n */\n getLiveRails(): RailConfig[] {\n return this.rails.filter((r) => r.status === \"live\");\n }\n\n /**\n * Check if a specific rail is available.\n */\n isRailLive(rail: PaymentRail): boolean {\n return this.getRail(rail)?.status === \"live\";\n }\n\n private getRail(rail: PaymentRail): RailConfig | undefined {\n return this.rails.find((r) => r.rail === rail);\n }\n}\n",
|
|
33
|
+
"/**\n * @module tokens/decimals\n * Token decimal normalization utilities for multi-token agent wallets.\n *\n * Handles safe conversion between human-readable amounts (\"1.5\") and raw\n * on-chain bigint amounts (1500000n for USDC with 6 decimals). All arithmetic\n * is done in integer domain to avoid floating point precision errors.\n */\n\nimport type { Address } from \"viem\";\n\n/** Minimal token info required for formatting */\nexport interface TokenInfo {\n symbol: string;\n decimals: number;\n address: Address;\n name?: string;\n chainId?: number;\n}\n\n/**\n * Convert a human-readable amount string to raw bigint (on-chain units).\n *\n * @param amount - Human-readable amount, e.g. \"1.5\" or \"1000\"\n * @param decimals - Token decimal places (e.g. 6 for USDC, 18 for WETH)\n * @returns Raw on-chain amount as bigint\n *\n * @example\n * toRaw(\"1.5\", 6) // → 1500000n (1.5 USDC)\n * toRaw(\"1.0\", 18) // → 1000000000000000000n (1 WETH)\n * toRaw(\"0.001\", 8) // → 100000n (0.001 WBTC)\n */\nexport function toRaw(amount: string | bigint, decimals: number): bigint {\n if (typeof amount === \"bigint\") return amount;\n\n const str = amount.trim();\n if (!str || str === \"0\") return 0n;\n\n // Validate: only digits and one optional decimal point, optional leading minus\n if (!/^-?\\d+(\\.\\d+)?$/.test(str)) {\n throw new Error(`toRaw: invalid amount string \"${amount}\"`);\n }\n\n const negative = str.startsWith(\"-\");\n const abs = negative ? str.slice(1) : str;\n\n const dotIndex = abs.indexOf(\".\");\n if (dotIndex === -1) {\n // Integer amount\n const result = BigInt(abs) * 10n ** BigInt(decimals);\n return negative ? -result : result;\n }\n\n const intPart = abs.slice(0, dotIndex);\n let fracPart = abs.slice(dotIndex + 1);\n\n // Truncate or pad fractional part to `decimals` digits\n if (fracPart.length > decimals) {\n fracPart = fracPart.slice(0, decimals); // truncate (floor for positive amounts)\n } else {\n fracPart = fracPart.padEnd(decimals, \"0\");\n }\n\n const raw =\n BigInt(intPart || \"0\") * 10n ** BigInt(decimals) + BigInt(fracPart);\n\n return negative ? -raw : raw;\n}\n\n/**\n * Convert a raw bigint on-chain amount to a human-readable string.\n *\n * @param amount - Raw on-chain amount\n * @param decimals - Token decimal places\n * @returns Human-readable string, trimmed trailing zeros\n *\n * @example\n * toHuman(1500000n, 6) // → \"1.5\"\n * toHuman(1000000000000000000n, 18) // → \"1.0\"\n * toHuman(0n, 6) // → \"0.0\"\n */\nexport function toHuman(amount: bigint, decimals: number): string {\n if (decimals === 0) return amount.toString();\n\n const negative = amount < 0n;\n const abs = negative ? -amount : amount;\n\n const divisor = 10n ** BigInt(decimals);\n const intPart = abs / divisor;\n const fracRaw = abs % divisor;\n\n // Pad fractional part to `decimals` digits\n const fracStr = fracRaw.toString().padStart(decimals, \"0\");\n\n // Trim trailing zeros but keep at least one decimal digit\n const trimmed = fracStr.replace(/0+$/, \"\") || \"0\";\n\n const result = `${intPart}.${trimmed}`;\n return negative ? `-${result}` : result;\n}\n\n/**\n * Format a raw bigint amount with token symbol for display.\n *\n * @param amount - Raw on-chain amount\n * @param token - Token info (symbol + decimals required)\n * @param displayDecimals - Max decimal places to show (default: 4 for high-precision, 2 for stablecoins)\n * @returns Formatted string e.g. \"1.50 USDC\" or \"0.0023 WETH\"\n *\n * @example\n * formatBalance(1500000n, { symbol: 'USDC', decimals: 6, address: '0x...' })\n * // → \"1.50 USDC\"\n */\nexport function formatBalance(\n amount: bigint,\n token: Pick<TokenInfo, \"symbol\" | \"decimals\">,\n displayDecimals?: number,\n): string {\n const human = toHuman(amount, token.decimals);\n const maxDisplay = displayDecimals ?? (token.decimals <= 6 ? 2 : 4);\n\n // Parse the human string and reformat to maxDisplay decimal places\n const [intPart, fracPart = \"\"] = human.split(\".\");\n const padded = fracPart.padEnd(maxDisplay, \"0\").slice(0, maxDisplay);\n\n // If all fraction digits are zero, still show them for consistent formatting\n return `${intPart}.${padded} ${token.symbol}`;\n}\n\n/**\n * Parse amount that may be either a string (human-readable) or bigint (raw).\n * Returns raw bigint. Used in transfer functions to accept flexible input.\n *\n * @param amount - Either a human-readable string \"1.5\" or a raw bigint\n * @param decimals - Required only when amount is a string\n */\nexport function parseAmount(amount: string | bigint, decimals: number): bigint {\n if (typeof amount === \"bigint\") return amount;\n return toRaw(amount, decimals);\n}\n",
|
|
34
|
+
"/**\n * @module tokens/solana\n * Solana SPL token support for AgentWallet v6.\n *\n * Uses @solana/web3.js as an optional peer dependency.\n * All imports are done dynamically so EVM-only users pay zero overhead.\n *\n * Token addresses verified against:\n * - Solana SPL Token Registry: https://raw.githubusercontent.com/solana-labs/token-list/main/src/tokens/solana.tokenlist.json\n * - USDC on Solana: https://developers.circle.com/stablecoins/usdc-contract-addresses\n * - Raydium: https://docs.raydium.io/raydium/token-pairs-and-liquidity\n */\n\nimport type { TransactionInstruction } from \"@solana/web3.js\";\nimport bs58 from \"bs58\";\n\ntype SolanaWeb3Module = typeof import(\"@solana/web3.js\");\ntype SplTokenModule = typeof import(\"@solana/spl-token\");\ntype SolanaConnectionInstance = InstanceType<SolanaWeb3Module[\"Connection\"]>;\ntype SolanaKeypairInstance = InstanceType<SolanaWeb3Module[\"Keypair\"]>;\ntype SolanaPublicKeyInstance = InstanceType<SolanaWeb3Module[\"PublicKey\"]>;\n\ninterface ParsedSplTokenWalletAccountEntry {\n account: {\n data: {\n parsed: {\n info: {\n mint: string;\n tokenAmount: { amount: string; decimals: number };\n };\n };\n };\n };\n}\n\n// ─── Well-known Solana token mint addresses ───────────────────────────────────\n//\n// All addresses are base-58 encoded Solana public keys.\n// Sources: Solana token registry + Circle USDC docs\n\nexport const SOLANA_TOKENS = {\n // Native SOL (special: no mint address, use null or SystemProgram)\n SOL: null as null, // native, not a mint\n\n // USDC on Solana mainnet — Circle official\n USDC: \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n\n // USDT on Solana — Tether official\n USDT: \"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\",\n\n // Raydium\n RAY: \"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R\",\n\n // Serum (now Openbook predecessor token)\n SRM: \"SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt\",\n\n // Bonk memecoin\n BONK: \"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263\",\n\n // JitoSOL — Jito staked SOL\n JITOSOL: \"J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn\",\n\n // mSOL — Marinade staked SOL\n MSOL: \"mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So\",\n\n // Wrapped BTC on Solana (Portal/Wormhole)\n WBTC: \"3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh\",\n\n // Wrapped ETH on Solana (Portal/Wormhole)\n WETH: \"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs\",\n} as const;\n\nexport type SolanaTokenSymbol = keyof typeof SOLANA_TOKENS;\n\nexport interface SolanaTokenInfo {\n symbol: SolanaTokenSymbol;\n mint: string | null; // null for native SOL\n decimals: number;\n name: string;\n}\n\n/** Known decimals for Solana tokens */\nexport const SOLANA_TOKEN_DECIMALS: Record<SolanaTokenSymbol, number> = {\n SOL: 9,\n USDC: 6,\n USDT: 6,\n RAY: 6,\n SRM: 6,\n BONK: 5,\n JITOSOL: 9,\n MSOL: 9,\n WBTC: 8,\n WETH: 8,\n};\n\n// ─── Dynamic import helper ────────────────────────────────────────────────────\n\nasync function loadSolanaWeb3(): Promise<SolanaWeb3Module> {\n try {\n const mod = await import(\"@solana/web3.js\");\n return mod;\n } catch {\n throw new Error(\n \"SolanaWallet requires @solana/web3.js. Install it: npm install @solana/web3.js\",\n );\n }\n}\n\nasync function loadSplToken(): Promise<SplTokenModule> {\n try {\n const mod = await import(\"@solana/spl-token\");\n return mod;\n } catch {\n throw new Error(\n \"SolanaWallet SPL token operations require @solana/spl-token. Install it: npm install @solana/spl-token\",\n );\n }\n}\n\n// ─── SolanaWallet class ───────────────────────────────────────────────────────\n\nexport interface SolanaWalletConfig {\n /** Solana RPC endpoint (default: mainnet) */\n rpcUrl?: string;\n /** Base-58 encoded private key for the signer */\n privateKeyBase58?: string;\n /** Keypair bytes (Uint8Array of 64 bytes) */\n keypairBytes?: Uint8Array;\n}\n\nexport interface SolBalanceResult {\n rawBalance: bigint; // lamports\n sol: string; // human-readable SOL\n}\n\nexport interface SplBalanceResult {\n mint: string;\n rawBalance: bigint;\n humanBalance: string;\n decimals: number;\n}\n\nexport interface SolanaTxResult {\n signature: string;\n}\n\n/**\n * Solana wallet for native SOL and SPL token operations.\n * Uses @solana/web3.js (optional peer dependency, dynamically imported).\n */\nexport class SolanaWallet {\n private readonly rpcUrl: string;\n private readonly config: SolanaWalletConfig;\n\n // Lazily loaded modules and connection\n private _connection: SolanaConnectionInstance | null = null;\n private _keypair: SolanaKeypairInstance | null = null;\n\n constructor(config: SolanaWalletConfig = {}) {\n this.rpcUrl = config.rpcUrl ?? \"https://api.mainnet-beta.solana.com\";\n this.config = config;\n }\n\n private async getConnection() {\n if (this._connection) return this._connection;\n const { Connection } = await loadSolanaWeb3();\n this._connection = new Connection(this.rpcUrl, \"confirmed\");\n return this._connection;\n }\n\n private async getKeypair() {\n if (this._keypair) return this._keypair;\n const { Keypair } = await loadSolanaWeb3();\n\n if (this.config.keypairBytes) {\n this._keypair = Keypair.fromSecretKey(this.config.keypairBytes);\n } else if (this.config.privateKeyBase58) {\n const decoded = bs58.decode(this.config.privateKeyBase58);\n this._keypair = Keypair.fromSecretKey(decoded);\n } else {\n throw new Error(\n \"SolanaWallet: no private key provided. Set keypairBytes or privateKeyBase58 in config.\",\n );\n }\n\n return this._keypair;\n }\n\n /** Get signer's public key as base-58 string */\n async getPublicKey(): Promise<string> {\n const kp = await this.getKeypair();\n return kp.publicKey.toBase58();\n }\n\n /**\n * Get native SOL balance.\n * @param address - Optional base-58 public key to check (defaults to wallet's key)\n */\n async getSolBalance(address?: string): Promise<SolBalanceResult> {\n const { PublicKey } = await loadSolanaWeb3();\n const connection = await this.getConnection();\n\n let pubkey: SolanaPublicKeyInstance;\n if (address) {\n pubkey = new PublicKey(address);\n } else {\n const kp = await this.getKeypair();\n pubkey = kp.publicKey;\n }\n\n const lamports = await connection.getBalance(pubkey);\n const rawBalance = BigInt(lamports);\n const sol = (lamports / 1e9).toFixed(9).replace(/\\.?0+$/, \"\");\n\n return { rawBalance, sol };\n }\n\n /**\n * Get SPL token balance for a given mint.\n * @param mintAddress - SPL token mint address (base-58)\n * @param owner - Optional owner address (defaults to wallet's key)\n */\n async getSplTokenBalance(\n mintAddress: string,\n owner?: string,\n ): Promise<SplBalanceResult> {\n const { PublicKey } = await loadSolanaWeb3();\n const splToken = await loadSplToken();\n const connection = await this.getConnection();\n\n let ownerPubkey: SolanaPublicKeyInstance;\n if (owner) {\n ownerPubkey = new PublicKey(owner);\n } else {\n const kp = await this.getKeypair();\n ownerPubkey = kp.publicKey;\n }\n\n const mintPubkey = new PublicKey(mintAddress);\n\n // Get associated token account\n const ata = await splToken.getAssociatedTokenAddress(\n mintPubkey,\n ownerPubkey,\n );\n\n let rawBalance = 0n;\n let decimals = 9;\n\n try {\n const accountInfo = await splToken.getAccount(connection, ata);\n rawBalance = accountInfo.amount;\n\n // Get mint info for decimals\n const mintInfo = await splToken.getMint(connection, mintPubkey);\n decimals = mintInfo.decimals;\n } catch {\n // Token account doesn't exist — balance is 0\n }\n\n const humanBalance =\n (Number(rawBalance) / 10 ** decimals)\n .toFixed(decimals)\n .replace(/\\.?0+$/, \"\") || \"0\";\n\n return { mint: mintAddress, rawBalance, humanBalance, decimals };\n }\n\n /**\n * Send native SOL to a recipient.\n * @param to - Recipient base-58 public key\n * @param amount - Lamports (bigint) OR SOL amount as string (e.g. \"1.5\")\n */\n async sendSol(to: string, amount: string | bigint): Promise<SolanaTxResult> {\n const { PublicKey, SystemProgram, Transaction, sendAndConfirmTransaction } =\n await loadSolanaWeb3();\n const connection = await this.getConnection();\n const keypair = await this.getKeypair();\n\n let lamports: bigint;\n if (typeof amount === \"string\") {\n // Parse SOL string (9 decimals)\n const parts = amount.split(\".\");\n const intPart = BigInt(parts[0] || \"0\");\n const fracStr = (parts[1] ?? \"\").padEnd(9, \"0\").slice(0, 9);\n lamports = intPart * 1_000_000_000n + BigInt(fracStr);\n } else {\n lamports = amount;\n }\n\n const transaction = new Transaction().add(\n SystemProgram.transfer({\n fromPubkey: keypair.publicKey,\n toPubkey: new PublicKey(to),\n lamports: Number(lamports),\n }),\n );\n\n const signature = await sendAndConfirmTransaction(connection, transaction, [\n keypair,\n ]);\n return { signature };\n }\n\n /**\n * Send SPL tokens to a recipient.\n * Creates the recipient's associated token account if it doesn't exist.\n *\n * @param to - Recipient base-58 public key\n * @param amount - Raw token units (bigint) OR human-readable string\n * @param mintAddress - SPL token mint address (base-58)\n */\n async sendSplToken(\n to: string,\n amount: string | bigint,\n mintAddress: string,\n ): Promise<SolanaTxResult> {\n const { PublicKey } = await loadSolanaWeb3();\n const splToken = await loadSplToken();\n const connection = await this.getConnection();\n const keypair = await this.getKeypair();\n\n const mintPubkey = new PublicKey(mintAddress);\n const toPubkey = new PublicKey(to);\n\n // Get mint info for decimals\n const mintInfo = await splToken.getMint(connection, mintPubkey);\n const { decimals } = mintInfo;\n\n // Parse amount\n let rawAmount: bigint;\n if (typeof amount === \"string\") {\n const parts = amount.split(\".\");\n const intPart = BigInt(parts[0] || \"0\");\n const fracStr = (parts[1] ?? \"\").padEnd(decimals, \"0\").slice(0, decimals);\n rawAmount = intPart * 10n ** BigInt(decimals) + BigInt(fracStr);\n } else {\n rawAmount = amount;\n }\n\n // Get sender's associated token account\n const fromAta = await splToken.getAssociatedTokenAddress(\n mintPubkey,\n keypair.publicKey,\n );\n\n // Get or create recipient's associated token account\n const toAta = await splToken.getAssociatedTokenAddress(\n mintPubkey,\n toPubkey,\n );\n\n // Build instructions\n const instructions: TransactionInstruction[] = [];\n\n // Check if recipient ATA exists\n const toAtaInfo = await connection.getAccountInfo(toAta);\n if (!toAtaInfo) {\n instructions.push(\n splToken.createAssociatedTokenAccountInstruction(\n keypair.publicKey, // payer\n toAta,\n toPubkey,\n mintPubkey,\n ),\n );\n }\n\n // Transfer instruction\n instructions.push(\n splToken.createTransferInstruction(\n fromAta,\n toAta,\n keypair.publicKey,\n rawAmount,\n ),\n );\n\n const { Transaction, sendAndConfirmTransaction } = await loadSolanaWeb3();\n const transaction = new Transaction().add(...instructions);\n\n const signature = await sendAndConfirmTransaction(connection, transaction, [\n keypair,\n ]);\n return { signature };\n }\n\n /**\n * List all SPL token accounts for the wallet.\n */\n async listSplTokenAccounts(): Promise<\n Array<{ mint: string; amount: bigint; decimals: number }>\n > {\n const splToken = await loadSplToken();\n const connection = await this.getConnection();\n const keypair = await this.getKeypair();\n\n const tokenAccounts = await connection.getParsedTokenAccountsByOwner(\n keypair.publicKey,\n { programId: splToken.TOKEN_PROGRAM_ID },\n );\n\n return tokenAccounts.value.map((acc: ParsedSplTokenWalletAccountEntry) => {\n const info = acc.account.data.parsed.info;\n return {\n mint: info.mint,\n amount: BigInt(info.tokenAmount.amount),\n decimals: info.tokenAmount.decimals,\n };\n });\n }\n}\n\n/**\n * Create a SolanaWallet instance.\n */\nexport function createSolanaWallet(config: SolanaWalletConfig): SolanaWallet {\n return new SolanaWallet(config);\n}\n",
|
|
35
|
+
"/**\n * @module tokens/transfers\n * Multi-token transfer utilities for AgentWallet v6.\n *\n * Provides send/balance functions for any ERC-20 token or native gas token,\n * with flexible amount input (raw bigint or human-readable string).\n *\n * All transfer functions go through viem's wallet client — they do NOT\n * route through the AgentAccountV2 contract (use agentTransferToken for that).\n * These are direct EOA/smart-wallet operations for wallets that hold the key.\n */\n\nimport {\n type Address,\n type Chain,\n encodeFunctionData,\n type Hash,\n type PublicClient,\n parseAbi,\n type WalletClient,\n zeroAddress,\n} from \"viem\";\nimport { formatBalance, parseAmount, toHuman } from \"./decimals.js\";\nimport { getGlobalRegistry } from \"./registry.js\";\n\n// ─── ERC20 ABI (minimal) ─────────────────────────────────────────────────────\n\nconst ERC20_ABI = parseAbi([\n \"function transfer(address to, uint256 amount) returns (bool)\",\n \"function balanceOf(address account) view returns (uint256)\",\n \"function decimals() view returns (uint8)\",\n \"function symbol() view returns (string)\",\n \"function name() view returns (string)\",\n]);\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface TransferOptions {\n /** Gas price override */\n gasPrice?: bigint;\n /** Max fee per gas (EIP-1559) */\n maxFeePerGas?: bigint;\n /** Max priority fee per gas (EIP-1559) */\n maxPriorityFeePerGas?: bigint;\n /** Gas limit override */\n gas?: bigint;\n /** Chain ID for multi-chain operations */\n chainId?: number;\n}\n\nexport interface TokenBalanceResult {\n address: Address;\n symbol: string;\n name: string;\n decimals: number;\n rawBalance: bigint;\n humanBalance: string;\n formatted: string;\n}\n\nexport interface NativeBalanceResult {\n symbol: string;\n decimals: number;\n rawBalance: bigint;\n humanBalance: string;\n}\n\n// ─── Transfer context ─────────────────────────────────────────────────────────\n\nexport interface TransferContext {\n publicClient: PublicClient;\n walletClient: WalletClient;\n /** Caller's address (used as from address) */\n account: Address;\n /** Chain ID for registry lookups */\n chainId?: number;\n}\n\n// ─── Core transfer functions ──────────────────────────────────────────────────\n\n/**\n * Send any ERC-20 token.\n *\n * @param ctx - Public + wallet clients and account\n * @param to - Recipient address\n * @param amount - Amount as raw bigint OR human-readable string (requires tokenAddress decimals lookup)\n * @param tokenAddress - ERC-20 contract address\n * @param options - Optional gas overrides\n */\nexport async function sendToken(\n ctx: TransferContext,\n to: Address,\n amount: string | bigint,\n tokenAddress: Address,\n options: TransferOptions = {},\n): Promise<Hash> {\n let rawAmount: bigint;\n\n if (typeof amount === \"string\") {\n // Need decimals to parse string amount\n let decimals: number;\n\n // Try registry first\n if (ctx.chainId != null) {\n const entry = getGlobalRegistry().getTokenByAddress(\n tokenAddress,\n ctx.chainId,\n );\n decimals =\n entry?.decimals ??\n (await fetchTokenDecimals(ctx.publicClient, tokenAddress));\n } else {\n decimals = await fetchTokenDecimals(ctx.publicClient, tokenAddress);\n }\n\n rawAmount = parseAmount(amount, decimals);\n } else {\n rawAmount = amount;\n }\n\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"transfer\",\n args: [to, rawAmount],\n });\n\n return ctx.walletClient.sendTransaction({\n account: ctx.account,\n chain: requirePublicClientChain(ctx),\n to: tokenAddress,\n data,\n ...buildGasOptions(options),\n });\n}\n\n/**\n * Send native gas token (ETH, MATIC, AVAX, etc.).\n *\n * @param ctx - Transfer context\n * @param to - Recipient address\n * @param amount - Raw bigint OR human-readable string (18 decimals for ETH/MATIC/AVAX)\n * @param options - Optional gas overrides\n */\nexport async function sendNative(\n ctx: TransferContext,\n to: Address,\n amount: string | bigint,\n options: TransferOptions = {},\n): Promise<Hash> {\n const rawAmount = parseAmount(amount, 18);\n\n return ctx.walletClient.sendTransaction({\n account: ctx.account,\n chain: requirePublicClientChain(ctx),\n to,\n value: rawAmount,\n ...buildGasOptions(options),\n });\n}\n\n/**\n * Get the ERC-20 balance of the current account (or a specified address).\n *\n * @param ctx - Transfer context\n * @param tokenAddress - ERC-20 contract address\n * @param holder - Address to check (defaults to ctx.account)\n */\nexport async function getTokenBalance(\n ctx: TransferContext,\n tokenAddress: Address,\n holder?: Address,\n): Promise<TokenBalanceResult> {\n const target = holder ?? ctx.account;\n\n // Batch read: balanceOf + decimals + symbol + name\n const [rawBalance, decimals, symbol, name] = await Promise.all([\n ctx.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [target],\n }) as Promise<bigint>,\n ctx.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"decimals\",\n }) as Promise<number>,\n ctx.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"symbol\",\n }) as Promise<string>,\n ctx.publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"name\",\n }) as Promise<string>,\n ]);\n\n const humanBalance = toHuman(rawBalance, decimals);\n const formatted = formatBalance(rawBalance, { symbol, decimals });\n\n return {\n address: tokenAddress,\n symbol,\n name,\n decimals,\n rawBalance,\n humanBalance,\n formatted,\n };\n}\n\n/**\n * Get the native gas token balance of the current account (or a specified address).\n *\n * @param ctx - Transfer context\n * @param holder - Address to check (defaults to ctx.account)\n */\nexport async function getNativeBalance(\n ctx: TransferContext,\n holder?: Address,\n): Promise<NativeBalanceResult> {\n const target = holder ?? ctx.account;\n const rawBalance = await ctx.publicClient.getBalance({ address: target });\n\n // Determine native token symbol from registry if chainId is known\n let symbol = \"ETH\";\n if (ctx.chainId != null) {\n const native = getGlobalRegistry().getTokenByAddress(\n zeroAddress,\n ctx.chainId,\n );\n symbol = native?.symbol ?? \"ETH\";\n }\n\n const humanBalance = toHuman(rawBalance, 18);\n\n return { symbol, decimals: 18, rawBalance, humanBalance };\n}\n\n/**\n * Batch query balances for multiple ERC-20 tokens.\n *\n * @param ctx - Transfer context\n * @param tokenAddresses - List of ERC-20 addresses to query (or null/empty for all registry tokens)\n * @param holder - Address to check (defaults to ctx.account)\n */\nexport async function getBalances(\n ctx: TransferContext,\n tokenAddresses?: Address[],\n holder?: Address,\n): Promise<TokenBalanceResult[]> {\n const target = holder ?? ctx.account;\n\n let addresses = tokenAddresses;\n\n // If no addresses provided and chainId is known, use all registry tokens\n if (!addresses || addresses.length === 0) {\n if (ctx.chainId != null) {\n const tokens = getGlobalRegistry().listTokens(ctx.chainId);\n addresses = tokens.filter((t) => !t.isNative).map((t) => t.address);\n } else {\n return [];\n }\n }\n\n // Parallel balance fetches\n const results = await Promise.allSettled(\n addresses.map((addr) => getTokenBalance(ctx, addr, target)),\n );\n\n return results\n .filter(\n (r): r is PromiseFulfilledResult<TokenBalanceResult> =>\n r.status === \"fulfilled\",\n )\n .map((r) => r.value);\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nasync function fetchTokenDecimals(\n publicClient: PublicClient,\n tokenAddress: Address,\n): Promise<number> {\n return publicClient.readContract({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"decimals\",\n }) as Promise<number>;\n}\n\nfunction buildGasOptions(options: TransferOptions) {\n const gas: Record<string, bigint> = {};\n if (options.gas != null) gas.gas = options.gas;\n if (options.gasPrice != null) gas.gasPrice = options.gasPrice;\n if (options.maxFeePerGas != null) gas.maxFeePerGas = options.maxFeePerGas;\n if (options.maxPriorityFeePerGas != null)\n gas.maxPriorityFeePerGas = options.maxPriorityFeePerGas;\n return gas;\n}\n\nfunction requirePublicClientChain(ctx: TransferContext): Chain {\n const chain = ctx.publicClient.chain;\n if (!chain) {\n throw new Error(\n \"TransferContext.publicClient must be created with chain (required for walletClient.sendTransaction).\",\n );\n }\n return chain;\n}\n\n/**\n * Encode an ERC-20 transfer call as raw calldata.\n * Useful for building calldata for agentExecute() or multicall.\n */\nexport function encodeERC20Transfer(\n to: Address,\n amount: bigint,\n): `0x${string}` {\n return encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"transfer\",\n args: [to, amount],\n });\n}\n"
|
|
36
|
+
],
|
|
37
|
+
"mappings": "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,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAGA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAAA;AAIO,MAAM,cAAc;AAAA,EACR,SAAkC,IAAI;AAAA,EAEvD,WAAW,CAAC,eAA8B;AAAA,IAExC,WAAW,KAAK,eAAe;AAAA,MAC7B,KAAK,OAAO,CAAC;AAAA,IACf;AAAA,IAEA,YAAY,SAAS,SAAS,QAAQ,MAAM,aAAa,YAAY;AAAA,MACnE,KAAK,OAAO,EAAE,SAAS,SAAS,QAAQ,MAAM,SAAS,CAAC;AAAA,IAC1D;AAAA,IAEA,IAAI,eAAe;AAAA,MACjB,WAAW,KAAK,eAAe;AAAA,QAC7B,KAAK,OAAO,CAAC;AAAA,MACf;AAAA,IACF;AAAA;AAAA,EAGM,IAAI,CAAC,QAAgB,SAAyB;AAAA,IACpD,OAAO,GAAG,OAAO,YAAY,KAAK;AAAA;AAAA,EAG5B,MAAM,CAAC,OAAyB;AAAA,IACtC,MAAM,MAAM,KAAK,KAAK,MAAM,QAAQ,MAAM,OAAO;AAAA,IACjD,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,CAAC;AAAA;AAAA,EAMnC,QAAQ,CAAC,QAA8B;AAAA,IACrC,MAAM,QAAoB;AAAA,MACxB,QAAQ,OAAO;AAAA,MACf,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,MACjB,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO,QAAQ,OAAO;AAAA,MAC5B,UAAU,OAAO,YAAY;AAAA,IAC/B;AAAA,IACA,KAAK,OAAO,KAAK;AAAA;AAAA,EAOnB,QAAQ,CAAC,QAAgB,SAAyC;AAAA,IAChE,OAAO,KAAK,OAAO,IAAI,KAAK,KAAK,QAAQ,OAAO,CAAC;AAAA;AAAA,EAMnD,UAAU,CAAC,SAA+B;AAAA,IACxC,MAAM,SAAuB,CAAC;AAAA,IAC9B,WAAW,SAAS,KAAK,OAAO,OAAO,GAAG;AAAA,MACxC,IAAI,MAAM,YAAY;AAAA,QAAS,OAAO,KAAK,KAAK;AAAA,IAClD;AAAA,IACA,OAAO;AAAA;AAAA,EAMT,iBAAiB,CAAC,SAAkB,SAAyC;AAAA,IAC3E,MAAM,QAAQ,QAAQ,YAAY;AAAA,IAClC,WAAW,SAAS,KAAK,OAAO,OAAO,GAAG;AAAA,MACxC,IAAI,MAAM,YAAY,WAAW,MAAM,QAAQ,YAAY,MAAM,OAAO;AAAA,QACtE,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA;AAAA;AAAA,EAMF,YAAY,GAAiB;AAAA,IAC3B,OAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC;AAAA;AAAA,EAMxC,IAAI,GAAW;AAAA,IACb,OAAO,KAAK,OAAO;AAAA;AAEvB;AAKA,IAAI,kBAAwC;AAGrC,SAAS,iBAAiB,GAAkB;AAAA,EACjD,IAAI,CAAC;AAAA,IAAiB,kBAAkB,IAAI;AAAA,EAC5C,OAAO;AAAA;AAYF,IAAM,oBAAoB,IAAI;AAC9B,IAAM,gBAAgB,IAAI;AAC1B,IAAM,oBAAoB,IAAI;AAC9B,IAAM,oBAAoB,IAAI;AAC9B,IAAM,mBAAmB,IAAI;AAC7B,IAAM,qBAAqB,IAAI;AAC/B,IAAM,oBAAoB,IAAI;AAC9B,IAAM,iBAAiB,IAAI;AAC3B,IAAM,iBAAiB,IAAI;AAC3B,IAAM,sBAAsB,IAAI;AAChC,IAAM,wBAAwB,IAAI;AAGlC,SAAS,cAAc,CAAC,SAAyC;AAAA,EACtE,OACE,kBAAkB,EAAE,SAAS,OAAO,OAAO,KAC3C,kBAAkB,EAAE,SAAS,OAAO,OAAO,KAC3C,kBAAkB,EAAE,SAAS,QAAQ,OAAO,KAC5C,kBAAkB,EAAE,SAAS,KAAK,OAAO;AAAA;;;AC/wBtC,IAAM,iBAA0C;AAAA,EAErD,sBAAsB;AAAA,EAEtB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,UAAU;AAAA,EACV,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,kBAAkB;AACpB;AAGO,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACxIO,SAAS,mBAAmB,CAAC,SAAgC;AAAA,EAClE,MAAM,QAAQ,QAAQ,MAAM,GAAG;AAAA,EAC/B,IAAI,MAAM,SAAS;AAAA,IAAG,OAAO;AAAA,EAC7B,MAAM,KAAK,SAAS,MAAM,MAAM,SAAS,IAAI,EAAE;AAAA,EAC/C,OAAO,OAAO,MAAM,EAAE,IAAI,OAAO;AAAA;AAiB5B,SAAS,mBAAmB,CACjC,OACA,SACgB;AAAA,EAChB,MAAM,UAAU,oBAAoB,OAAO;AAAA,EAC3C,IAAI,WAAW;AAAA,IAAM,OAAO;AAAA,EAE5B,MAAM,WAAW,kBAAkB;AAAA,EAGnC,IAAI,sBAAsB,KAAK,KAAK,GAAG;AAAA,IACrC,MAAM,SAAQ,SAAS,kBAAkB,OAAkB,OAAO;AAAA,IAClE,IAAI;AAAA,MAAO,OAAO,OAAM;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,QAAQ,SAAS,SAAS,MAAM,YAAY,GAAG,OAAO;AAAA,EAC5D,IAAI;AAAA,IAAO,OAAO,MAAM;AAAA,EAExB,OAAO;AAAA;AAWF,SAAS,oBAAoB,CAAC,OAAe,SAAyB;AAAA,EAC3E,MAAM,UAAU,oBAAoB,OAAO;AAAA,EAC3C,IAAI,WAAW;AAAA,IAAM,OAAO;AAAA,EAE5B,MAAM,WAAW,kBAAkB;AAAA,EAGnC,IAAI,sBAAsB,KAAK,KAAK,GAAG;AAAA,IACrC,MAAM,SAAQ,SAAS,kBAAkB,OAAkB,OAAO;AAAA,IAClE,IAAI;AAAA,MAAO,OAAO,OAAM;AAAA,IAExB,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,QAAQ,SAAS,SAAS,MAAM,YAAY,GAAG,OAAO;AAAA,EAC5D,IAAI;AAAA,IAAO,OAAO,MAAM;AAAA,EAExB,OAAO;AAAA;AAWF,SAAS,oBAAoB,CAClC,UACA,UAAoB,CAAC,QAAQ,QAAQ,OAAO,MAAM,GACvB;AAAA,EAC3B,MAAM,SAAoC,CAAC;AAAA,EAC3C,MAAM,WAAW,kBAAkB;AAAA,EAEnC,WAAW,WAAW,UAAU;AAAA,IAC9B,MAAM,UAAU,oBAAoB,OAAO;AAAA,IAC3C,IAAI,WAAW;AAAA,MAAM;AAAA,IAErB,MAAM,QAAmB,CAAC;AAAA,IAE1B,WAAW,UAAU,SAAS;AAAA,MAC5B,MAAM,QAAQ,SAAS,SAAS,QAAQ,OAAO;AAAA,MAC/C,IAAI,SAAS,CAAC,MAAM,UAAU;AAAA,QAC5B,MAAM,KAAK,MAAM,OAAO;AAAA,MAC1B;AAAA,IACF;AAAA,IAGA,MAAM,eAAe,eAAe;AAAA,IACpC,IACE,gBACA,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,aAAa,YAAY,CAAC,GACjE;AAAA,MACA,MAAM,KAAK,YAAY;AAAA,IACzB;AAAA,IAEA,IAAI,MAAM,SAAS,GAAG;AAAA,MACpB,OAAO,WAAW;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAMF,SAAS,YAAY,CAAC,OAAe,SAA0B;AAAA,EACpE,MAAM,WAAW,qBAAqB,OAAO,OAAO;AAAA,EACpD,OAAO,aAAa;AAAA;;;ACrGf,MAAM,WAAW;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,WAAW,CAAC,QAAqB,SAA2B,CAAC,GAAG;AAAA,IAC9D,KAAK,SAAS;AAAA,IACd,KAAK,SAAS;AAAA,MACZ,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,mBAAmB,CAAC,GAAG,0BAA0B;AAAA,SAC9C;AAAA,IACL;AAAA,IACA,KAAK,SAAS,IAAI,kBAAkB,MAAM;AAAA,IAC1C,KAAK,oBAAoB,IAAI,IAAI,KAAK,OAAO,iBAAiB;AAAA;AAAA,OAM1D,MAAK,CAAC,KAAmB,MAAuC;AAAA,IACpE,MAAM,SAAS,IAAI,SAAS;AAAA,IAC5B,MAAM,WAAW,MAAM,WAAW,MAAM,KAAK,IAAI;AAAA,IAEjD,IAAI,SAAS,WAAW,KAAK;AAAA,MAC3B,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,CAAC,KAAK,OAAO,SAAS;AAAA,MACxB,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,kBAAkB,MAAM,KAAK,iBAAiB,QAAQ;AAAA,IAC5D,IAAI,CAAC,iBAAiB;AAAA,MACpB,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,WAAW,KAAK,oBAAoB,gBAAgB,OAAO;AAAA,IACjE,IAAI,CAAC,UAAU;AAAA,MACb,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,SAAS,OAAO,SAAS,MAAM;AAAA,IACrC,MAAM,UAAU,IAAI,IAAI,MAAM,EAAE;AAAA,IAChC,MAAM,cAAc,KAAK,OAAO,YAAY,SAAS,MAAM;AAAA,IAC3D,IAAI,CAAC,YAAY,SAAS;AAAA,MACxB,MAAM,IAAI,wBACR,YAAY,UAAU,uBACtB,QACA,QACF;AAAA,IACF;AAAA,IAGA,IAAI,KAAK,OAAO,iBAAiB;AAAA,MAC/B,MAAM,UAAU,MAAM,KAAK,OAAO,gBAAgB,UAAU,MAAM;AAAA,MAClE,IAAI,CAAC,SAAS;AAAA,QACZ,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAGA,MAAM,gBAAgB,MAAM,KAAK,eAAe,QAAQ;AAAA,IAGxD,MAAM,iBAAqC;AAAA,MACzC,aAAa,gBAAgB;AAAA,MAC7B,UAAU,gBAAgB;AAAA,MAC1B,UAAU;AAAA,MACV,SAAS;AAAA,QACP,QAAQ,cAAc;AAAA,QACtB,SAAS,SAAS;AAAA,MACpB;AAAA,IACF;AAAA,IAGA,MAAM,MAA0B;AAAA,MAC9B,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAAA,MACvC;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,WAAW,SAAS;AAAA,MACpB,QAAQ,cAAc;AAAA,MACtB,SAAS,SAAS;AAAA,MAClB,QAAQ,SAAS;AAAA,MACjB,SAAS;AAAA,IACX;AAAA,IACA,KAAK,OAAO,cAAc,GAAG;AAAA,IAC7B,KAAK,OAAO,oBAAoB,GAAG;AAAA,IAGnC,MAAM,eAAe,IAAI,QAAQ,MAAM,OAAO;AAAA,IAC9C,MAAM,aAAa,KAAK,KAAK,UAAU,cAAc,CAAC;AAAA,IACtD,aAAa,IAAI,aAAa,UAAU;AAAA,IAExC,MAAM,gBAAgB,MAAM,WAAW,MAAM,KAAK;AAAA,SAC7C;AAAA,MACH,SAAS;AAAA,IACX,CAAC;AAAA,IAED,OAAO;AAAA;AAAA,OAMH,iBAAgB,CACpB,UACqC;AAAA,IAErC,MAAM,cACJ,SAAS,QAAQ,IAAI,kBAAkB,KACvC,SAAS,QAAQ,IAAI,oBAAoB;AAAA,IAE3C,IAAI,aAAa;AAAA,MACf,IAAI;AAAA,QACF,MAAM,UAAU,KAAK,MAAM,KAAK,WAAW,CAAC;AAAA,QAC5C,OAAO;AAAA,QACP,MAAM;AAAA,IAGV;AAAA,IAGA,IAAI;AAAA,MACF,MAAM,OAAO,MAAM,SAAS,MAAM,EAAE,KAAK;AAAA,MACzC,IAAI,KAAK,eAAe,KAAK,SAAS;AAAA,QACpC,OAAO;AAAA,MACT;AAAA,MACA,MAAM;AAAA,IAIR,OAAO;AAAA;AAAA,EAUT,mBAAmB,CACjB,SACgC;AAAA,IAEhC,MAAM,aAAa,QAAQ,OAAO,CAAC,QAAQ;AAAA,MACzC,IAAI,CAAC,KAAK,kBAAkB,IAAI,IAAI,OAAO;AAAA,QAAG,OAAO;AAAA,MAGrD,IAAI,KAAK,OAAO,kBAAkB,IAAI,UAAU;AAAA,QAC9C,OAAO,KAAK,OAAO,gBAAgB,IAAI,SAAS,KAC9C,CAAC,MAAM,EAAE,YAAY,MAAM,IAAI,MAAM,YAAY,CACnD;AAAA,MACF;AAAA,MAGA,MAAM,WAAW,oBAAoB,IAAI,OAAO,IAAI,OAAO;AAAA,MAC3D,OAAO,YAAY;AAAA,KACpB;AAAA,IAED,IAAI,WAAW,WAAW;AAAA,MAAG,OAAO;AAAA,IAGpC,MAAM,QAAQ,WAAW,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO;AAAA,IAC3D,MAAM,aAAa,MAAM,SAAS,IAAI,QAAQ;AAAA,IAC9C,WAAW,KAAK,CAAC,GAAG,MAAM,OAAO,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,CAAC,CAAC;AAAA,IAErE,OAAO,WAAW;AAAA;AAAA,OASN,eAAc,CAC1B,KAC2B;AAAA,IAE3B,MAAM,kBAAkB,oBAAoB,IAAI,OAAO,IAAI,OAAO;AAAA,IAClE,IAAI,CAAC,iBAAiB;AAAA,MACpB,MAAM,IAAI,iBACR,yBAAyB,IAAI,sBAAsB,IAAI,kCACvD,GACF;AAAA,IACF;AAAA,IAGA,MAAM,gBAAgB,MAAM,YAAY,KAAK,QAAQ,eAAe;AAAA,IACpE,MAAM,SAAS,OAAO,IAAI,MAAM;AAAA,IAEhC,IAAI,SAAS,cAAc,YAAY;AAAA,MACrC,MAAM,IAAI,iBACR,UAAU,wCAAwC,cAAc,cAChE,GACF;AAAA,IACF;AAAA,IAEA,IAAI,SAAS,cAAc,mBAAmB;AAAA,MAC5C,MAAM,IAAI,iBACR,UAAU,0CAA0C,cAAc,qBAClE,GACF;AAAA,IACF;AAAA,IAGA,MAAM,wBAAwB;AAAA,IAC9B,MAAM,gBAAyB;AAAA,IAC/B,MAAM,YAAa,SAAS,wBAAyB;AAAA,IAErD,IAAI,YAAY,IAAI;AAAA,MAClB,MAAM,mBAAmB,KAAK,QAAQ;AAAA,QACpC,OAAO,IAAI;AAAA,QACX,IAAI;AAAA,QACJ,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,IAGA,MAAM,SAAS,MAAM,mBAAmB,KAAK,QAAQ;AAAA,MACnD,OAAO;AAAA,MACP,IAAI,IAAI;AAAA,MACR;AAAA,IACF,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,MAMd,aAAa,GAAsB;AAAA,IACrC,OAAO,KAAK;AAAA;AAAA,EAId,iBAAiB,CAAC,QAGO;AAAA,IACvB,OAAO,KAAK,OAAO,kBAAkB,MAAM;AAAA;AAAA,EAI7C,oBAAoB,GAAG;AAAA,IACrB,OAAO,KAAK,OAAO,qBAAqB;AAAA;AAE5C;AAAA;AAIO,MAAM,yBAAyB,MAAM;AAAA,EAGxB;AAAA,EAFlB,WAAW,CACT,SACgB,qBAChB;AAAA,IACA,MAAM,uBAAuB,SAAS;AAAA,IAFtB;AAAA,IAGhB,KAAK,OAAO;AAAA;AAEhB;AAAA;AAEO,MAAM,gCAAgC,MAAM;AAAA,EAE/B;AAAA,EACA;AAAA,EACA;AAAA,EAHlB,WAAW,CACO,QACA,KACA,qBAChB;AAAA,IACA,MAAM,yBAAyB,QAAQ;AAAA,IAJvB;AAAA,IACA;AAAA,IACA;AAAA,IAGhB,KAAK,OAAO;AAAA;AAEhB;;AC7SO,SAAS,gBAAgB,CAC9B,QACA,QACY;AAAA,EACZ,OAAO,IAAI,WAAW,QAAQ,MAAM;AAAA;AAc/B,SAAS,eAAe,CAC7B,QACA,QACyB;AAAA,EACzB,MAAM,SAAS,IAAI,WAAW,QAAQ,MAAM;AAAA,EAC5C,MAAM,OAAO,CAAC,OAA+B,SAAuB;AAAA,IAClE,MAAM,MAAM,iBAAiB,UAAU,MAAM,MAAM,MAAM,SAAS;AAAA,IAClE,OAAO,OAAO,MAAM,KAAK,IAAI;AAAA;AAAA,EAE/B,OAAO;AAAA;AAWF,SAAS,YAAY,CAC1B,SACA,QACA,QACyB;AAAA,EACzB,MAAM,gBAAgB,IAAI,WAAW,QAAQ,MAAM;AAAA,EAEnD,MAAM,OAAO,OACX,OACA,SACsB;AAAA,IACtB,MAAM,MAAM,iBAAiB,UAAU,MAAM,MAAM,MAAM,SAAS;AAAA,IAClE,MAAM,WAAW,MAAM,QAAQ,OAAO,IAAI;AAAA,IAE1C,IAAI,SAAS,WAAW,KAAK;AAAA,MAC3B,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,kBAAkB,MAAM,cAAc,iBAAiB,QAAQ;AAAA,IACrE,IAAI,CAAC;AAAA,MAAiB,OAAO;AAAA,IAE7B,MAAM,WAAW,cAAc,oBAAoB,gBAAgB,OAAO;AAAA,IAC1E,IAAI,CAAC;AAAA,MAAU,OAAO;AAAA,IAGtB,OAAO,cAAc,MAAM,KAAK,IAAI;AAAA;AAAA,EAEtC,OAAO;AAAA;;AC9EF,IAAM,sBAAsB;AAAA,EACjC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,qBAAqB,MAAM,SAAS;AAAA,MAC5C,EAAE,MAAM,iBAAiB,MAAM,UAAU;AAAA,MACzC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,qBAAqB,MAAM,UAAU;AAAA,MAC7C,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,wBAAwB,MAAM,SAAS;AAAA,IACjD;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,SAAS,MAAM,SAAS,CAAC;AAAA,EAC7C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,qBAAqB,MAAM,SAAS;AAAA,MAC5C,EAAE,MAAM,iBAAiB,MAAM,UAAU;AAAA,MACzC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,qBAAqB,MAAM,UAAU;AAAA,MAC7C,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,wBAAwB,MAAM,SAAS;AAAA,MAC/C,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,SAAS,MAAM,SAAS,CAAC;AAAA,EAC7C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,EACxC;AACF;AAKO,IAAM,0BAA0B;AAAA,EACrC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,QAAQ;AAAA,MACjC,EAAE,MAAM,eAAe,MAAM,QAAQ;AAAA,IACvC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,WAAW,MAAM,OAAO,CAAC;AAAA,EAC7C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,IACtC,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,EACxC;AACF;AAIO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,MACjC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACrC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AACF;;AClGA;AAAA,wBAEE;AAAA,iBACA;AAAA,UAGA;AAAA;AAAA;AAAA;AAOF;AAAA,cACE;AAAA;AAAA,UAEA;AAAA;AAAA,aAEA;AAAA;AAAA,aAEA;AAAA;;;ACEK,IAAM,kBAA+C;AAAA,EAC1D,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,QAAQ;AACV;AAMO,IAAM,mBAAmD;AAAA,EAC9D,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AACd;AAMO,IAAM,gBAAiD;AAAA,EAC5D,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AACd;AAYA,IAAM,0BACJ;AAEK,IAAM,qBAAsD;AAAA,EACjE,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AACd;AAOA,IAAM,8BACJ;AAEK,IAAM,yBAA0D;AAAA,EACrE,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AACd;AAOO,IAAM,qBAAqB;AAAA,EAChC,MAAM;AAAA,EACN,WAAW;AACb;AAGO,IAAM,yBAAyB;AAE/B,IAAM,wBAAwB;AAE9B,IAAM,+BAA+B;;;ADhF5C,IAAM,cAA6C;AAAA,EACjD;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,gBAAgB,EAAE,MAAM,OAAO,QAAQ,OAAO,UAAU,GAAG;AAAA,IAC3D,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,8BAA8B,EAAE,EAAE;AAAA,EACjE;AAAA,EACA,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,gBAAgB,EAAE,MAAM,KAAK,QAAQ,KAAK,UAAU,GAAG;AAAA,IACvD,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,2BAA2B,EAAE,EAAE;AAAA,EAC9D;AAAA,EACA,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,gBAAgB,EAAE,MAAM,OAAO,QAAQ,OAAO,UAAU,GAAG;AAAA,IAC3D,SAAS;AAAA,MACP,SAAS,EAAE,MAAM,CAAC,iDAAiD,EAAE;AAAA,IACvE;AAAA,EACF;AACF;AAAA;AAEO,MAAM,aAAa;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CACT,cACA,YAA4B,QAC5B,UAA+B,CAAC,GAChC;AAAA,IACA,KAAK,gBAAgB,qBAAqB,YAAY;AAAA,IACtD,KAAK,eAAe;AAAA,IACpB,KAAK,YAAY;AAAA,IACjB,KAAK,eAAe,oBAAmB;AAAA,MACrC,OAAO,YAAY;AAAA,MACnB,WAAW,MAAK,QAAQ,MAAM;AAAA,IAChC,CAAC;AAAA;AAAA,OAGG,OAAM,CACV,QACA,SACA,UAAyB,CAAC,GACH;AAAA,IACvB,MAAM,UAAU,KAAK,IAAI;AAAA,IACzB,KAAK,qBAAqB,QAAQ,OAAO;AAAA,IACzC,MAAM,UAAU,KAAK;AAAA,IACrB,MAAM,YAAY,QAAQ,sBAAsB,QAAQ;AAAA,IACxD,MAAM,uBACJ,QAAQ,wBAAwB,mBAAmB;AAAA,IACrD,MAAM,SAAS,QAAQ,UAAU;AAAA,IACjC,MAAM,oBACJ,QAAQ,qBAAqB;AAAA,IAE/B,MAAM,KAAK,YAAY,MAAM;AAAA,IAC7B,MAAM,aAAa,MAAM,KAAK,eAC5B,QACA,SACA,WACA,sBACA,MACF;AAAA,IACA,MAAM,cAAc,MAAM,KAAK,mBAC7B,WAAW,aACX,KAAK,WACL,iBACF;AAAA,IACA,MAAM,aAAa,MAAM,KAAK,eAC5B,WAAW,cACX,aACA,SACA,QAAQ,iBACV;AAAA,IAEA,OAAO;AAAA,MACL,YAAY,WAAW;AAAA,MACvB;AAAA,MACA;AAAA,MACA,WAAW,KAAK;AAAA,MAChB;AAAA,MACA;AAAA,MACA,OAAO,WAAW;AAAA,MAClB,WAAW,KAAK,IAAI,IAAI;AAAA,IAC1B;AAAA;AAAA,OAGI,KAAI,CACR,QACA,SACA,UAAyB,CAAC,GACL;AAAA,IACrB,KAAK,qBAAqB,QAAQ,OAAO;AAAA,IACzC,MAAM,UAAU,KAAK;AAAA,IACrB,MAAM,YAAY,QAAQ,sBAAsB,QAAQ;AAAA,IACxD,MAAM,uBACJ,QAAQ,wBAAwB,mBAAmB;AAAA,IACrD,MAAM,SAAS,QAAQ,UAAU;AAAA,IACjC,MAAM,KAAK,YAAY,MAAM;AAAA,IAC7B,OAAO,KAAK,eACV,QACA,SACA,WACA,sBACA,MACF;AAAA;AAAA,OAGI,mBAAkB,CACtB,aACA,SAAiB,wBACH;AAAA,IACd,OAAO,KAAK,mBAAmB,aAAa,KAAK,WAAW,MAAM;AAAA;AAAA,OAG9D,KAAI,CACR,cACA,aACA,SACA,mBACe;AAAA,IACf,OAAO,KAAK,eACV,cACA,aACA,SACA,iBACF;AAAA;AAAA,OAGI,eAAc,GAAoB;AAAA,IACtC,MAAM,UAAU,KAAK;AAAA,IACrB,MAAM,OAAO,aAAY;AAAA,MACvB,SAAS,cAAc,KAAK;AAAA,MAC5B,KAAK;AAAA,MACL,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,IACD,OAAO,KAAK,KAAK,UAAU,CAAC,QAAQ,OAAO,CAAC;AAAA;AAAA,OAGxC,iBAAgB,GAAoB;AAAA,IACxC,MAAM,UAAU,KAAK;AAAA,IACrB,MAAM,OAAO,aAAY;AAAA,MACvB,SAAS,cAAc,KAAK;AAAA,MAC5B,KAAK;AAAA,MACL,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,IACD,OAAO,KAAK,KAAK,UAAU;AAAA,MACzB,QAAQ;AAAA,MACR,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA;AAAA,OAGW,YAAW,CAAC,QAA+B;AAAA,IACvD,MAAM,UAAU,KAAK;AAAA,IACrB,MAAM,UAAU,mBAAmB,KAAK;AAAA,IACxC,MAAM,cAAc,cAAc,KAAK;AAAA,IACvC,MAAM,OAAO,aAAY;AAAA,MACvB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,IACD,MAAM,mBAAoB,MAAM,KAAK,KAAK,UAAU;AAAA,MAClD,QAAQ;AAAA,MACR;AAAA,IACF,CAAC;AAAA,IACD,IAAI,oBAAoB;AAAA,MAAQ;AAAA,IAEhC,MAAM,YAAY,aAAY;AAAA,MAC5B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ,EAAE,QAAQ,KAAK,cAAc,QAAQ,KAAK,aAAa;AAAA,IACjE,CAAC;AAAA,IACD,MAAM,gBAAgB,MAAM,UAAU,MAAM,QAAQ,CAAC,SAAS,MAAM,GAAG;AAAA,MACrE;AAAA,MACA,OAAO,YAAY,KAAK;AAAA,IAC1B,CAAC;AAAA,IACD,MAAM,iBAAiB,MAAM,KAAK,aAAa,0BAA0B;AAAA,MACvE,MAAM;AAAA,IACR,CAAC;AAAA,IACD,IAAI,eAAe,WAAW,WAAW;AAAA,MACvC,MAAM,IAAI,YACR,0BACA,4BAA4B,iBAC9B;AAAA,IACF;AAAA;AAAA,OAGY,eAAc,CAC1B,QACA,SACA,WACA,sBACA,QACqB;AAAA,IACrB,MAAM,UAAU,KAAK;AAAA,IACrB,MAAM,oBAAoB,gBAAgB;AAAA,IAC1C,MAAM,mBAAmB,mBAAmB,KAAK;AAAA,IACjD,MAAM,cAAc,cAAc,KAAK;AAAA,IACvC,MAAM,gBAAgB,IAAI,WAAW,EAAE,MAAM,GAAG,CAAC;AAAA,IACjD,MAAM,oBAAoB,IAAI,OAAc,EAAE,MAAM,GAAG,CAAC;AAAA,IAExD,MAAM,YAAY,aAAY;AAAA,MAC5B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ,EAAE,QAAQ,KAAK,cAAc,QAAQ,KAAK,aAAa;AAAA,IACjE,CAAC;AAAA,IAED,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,aAAa,MAAM,UAAU,MAAM,eACjC;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,GACA,EAAE,SAAS,OAAO,YAAY,KAAK,WAAW,CAChD;AAAA,MACA,OAAO,KAAc;AAAA,MACrB,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC3D,MAAM,IAAI,YACR,eACA,+BAA+B,MACjC;AAAA;AAAA,IAGF,MAAM,UAAU,MAAM,KAAK,aAAa,0BAA0B;AAAA,MAChE,MAAM;AAAA,IACR,CAAC;AAAA,IACD,IAAI,QAAQ,WAAW,WAAW;AAAA,MAChC,MAAM,IAAI,YACR,eACA,4CAA4C,cAC9C;AAAA,IACF;AAAA,IAEA,QAAQ,cAAc,aAAa,UACjC,KAAK,mBAAmB,OAAO;AAAA,IACjC,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc,gBAAgB,KAAK;AAAA,MACnC;AAAA,IACF;AAAA;AAAA,EAGM,kBAAkB,CAAC,SAIzB;AAAA,IACA,MAAM,qBACJ;AAAA,IACF,WAAW,OAAO,QAAQ,MAAM;AAAA,MAC9B,IAAI,IAAI,OAAO,IAAI,YAAY,MAAM,mBAAmB,YAAY,GAAG;AAAA,QACrE,MAAM,UAAU,IAAI;AAAA,QACpB,IAAI,QAAQ,SAAS;AAAA,UAAK;AAAA,QAC1B,MAAM,UAAU,QAAQ,MAAM,CAAC;AAAA,QAC/B,MAAM,YAAY,QAAQ,MAAM,IAAI,GAAG;AAAA,QACvC,MAAM,gBAAgB,SAAS,WAAW,EAAE;AAAA,QAC5C,IAAI,kBAAkB;AAAA,UAAG;AAAA,QACzB,MAAM,kBAAkB,QAAQ,MAAM,KAAK,MAAM,gBAAgB,CAAC;AAAA,QAClE,MAAM,eAAe,KAAK;AAAA,QAC1B,MAAM,cAAc,UAAU,YAAY;AAAA,QAC1C,MAAM,gBAAgB,gBAAgB,MAAM,IAAI,EAAE;AAAA,QAClD,MAAM,QAAQ,OAAO,KAAK,eAAe;AAAA,QACzC,OAAO,EAAE,cAAc,aAAa,MAAM;AAAA,MAC5C;AAAA,IACF;AAAA,IACA,MAAM,IAAI,YACR,eACA,+DACF;AAAA;AAAA,OAGY,mBAAkB,CAC9B,aACA,WACA,QACc;AAAA,IACd,MAAM,eAAe,gBAAgB;AAAA,IACrC,MAAM,MAAM,GAAG,sBAAsB,gBAAgB;AAAA,IAErD,SAAS,UAAU,EAAG,UAAU,uBAAuB,WAAW;AAAA,MAChE,IAAI;AAAA,MAKJ,IAAI;AAAA,QAEF,MAAM,MAAM,MAAM,MAAM,KAAK;AAAA,UAC3B,SAAS,EAAE,QAAQ,mBAAmB;AAAA,QACxC,CAAC;AAAA,QACD,IAAI,CAAC,IAAI,IAAI;AAAA,UACX,IAAI,IAAI,WAAW,KAAK;AAAA,YACtB,MAAM,KAAK,MAAM,4BAA4B;AAAA,YAC7C;AAAA,UACF;AAAA,UACA,MAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAAA,UAC5C,MAAM,IAAI,YACR,qBACA,4BAA4B,IAAI,WAAW,OAC7C;AAAA,QACF;AAAA,QACA,WAAY,MAAM,IAAI,KAAK;AAAA,QAC3B,OAAO,KAAc;AAAA,QACrB,IAAI,eAAe;AAAA,UAAa,MAAM;AAAA,QACtC,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC3D,MAAM,IAAI,YACR,qBACA,oCAAoC,MACtC;AAAA;AAAA,MAGF,IAAI,SAAS,WAAW,cAAc,SAAS;AAAA,QAC7C,OAAO,SAAS;AAAA,MAClB,IAAI,SAAS,WAAW,SAAS;AAAA,QAC/B,MAAM,IAAI,YACR,qBACA,8BAA8B,SAAS,SAAS,kBAClD;AAAA,MACF;AAAA,MACA,MAAM,KAAK,MAAM,4BAA4B;AAAA,IAC/C;AAAA,IACA,MAAM,IAAI,YACR,uBACA,kCAAkC,iDAAiD,cACrF;AAAA;AAAA,OAGY,eAAc,CAC1B,cACA,aACA,SACA,mBACe;AAAA,IACf,MAAM,UAAU,KAAK;AAAA,IACrB,MAAM,qBAAqB,uBAAuB;AAAA,IAClD,MAAM,YAAY,YAAY;AAAA,IAC9B,MAAM,mBAAmB,oBAAmB;AAAA,MAC1C,OAAO;AAAA,MACP,WAAW,MAAK,iBAAiB;AAAA,IACnC,CAAC;AAAA,IAED,MAAM,cAAc,aAAY;AAAA,MAC9B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ,EAAE,QAAQ,kBAAkB,QAAQ,KAAK,aAAa;AAAA,IAChE,CAAC;AAAA,IAED,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,aAAa,MAAM,YAAY,MAAM,eACnC,CAAC,cAAc,WAAW,GAC1B,EAAE,SAAS,OAAO,UAAU,CAC9B;AAAA,MACA,OAAO,KAAc;AAAA,MACrB,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC3D,MAAM,IAAI,YACR,eACA,iCAAiC,YAAY,MAC/C;AAAA;AAAA,IAGF,MAAM,cAAc,MAAM,iBAAiB,0BAA0B;AAAA,MACnE,MAAM;AAAA,IACR,CAAC;AAAA,IACD,IAAI,YAAY,WAAW,WAAW;AAAA,MACpC,MAAM,IAAI,YACR,eACA,8BAA8B,gBAAgB,cAChD;AAAA,IACF;AAAA,IACA,OAAO;AAAA;AAAA,EAGD,oBAAoB,CAAC,QAAgB,SAA+B;AAAA,IAC1E,IAAI,UAAU,IAAI;AAAA,MAChB,MAAM,IAAI,YACR,kBACA,mDAAmD,SACrD;AAAA,IACF;AAAA,IACA,IAAI,EAAE,WAAW,kBAAkB;AAAA,MACjC,MAAM,IAAI,YACR,qBACA,UAAU,4BACZ;AAAA,IACF;AAAA,IACA,IAAI,YAAY,KAAK,WAAW;AAAA,MAC9B,MAAM,IAAI,YACR,qBACA,kDACF;AAAA,IACF;AAAA;AAAA,EAGM,KAAK,CAAC,IAA2B;AAAA,IACvC,OAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA;AAE3D;AAAA;AAEO,MAAM,oBAAoB,MAAM;AAAA,EAC5B;AAAA,EACT,WAAW,CAAC,MAAc,SAAiB;AAAA,IACzC,MAAM,iBAAiB,SAAS,SAAS;AAAA,IACzC,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA;AAEhB;AAEO,SAAS,YAAY,CAC1B,cACA,YAA4B,QAC5B,UAA+B,CAAC,GAClB;AAAA,EACd,OAAO,IAAI,aAAa,cAAc,WAAW,OAAO;AAAA;;AExe1D;AAAA,wBAGE;AAAA,iBACA;AAAA,UAGA;AAAA,eACA;AAAA,SAEA;AAAA;AAGF;AAAA,cACE;AAAA,eACA;AAAA,UACA;AAAA,WACA;AAAA,aACA;AAAA,cACA;AAAA,aACA;AAAA;;ACrBF;AAAA,wBAGE;AAAA,iBACA;AAAA,UAGA;AAAA;AAIF;AAAA,cACE;AAAA;AAAA,UAEA;AAAA,iBACA;AAAA,aACA;AAAA,aACA;AAAA;AAKK,IAAM,6BAA6B;AAAA,EAExC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,EAChD;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,YAAY,MAAM,SAAS,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,EAChD;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,YAAY,MAAM,SAAS;AAAA,MACnC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,UACtC,EAAE,MAAM,iBAAiB,MAAM,QAAQ;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,SAAS;AAAA,IACnC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,IACxC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,QAAQ,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC,EAAE,MAAM,iBAAiB,MAAM,QAAQ;AAAA,IACzC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,MACpC,EAAE,MAAM,aAAa,MAAM,QAAQ;AAAA,IACrC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK;AAAA,MAClD,EAAE,MAAM,YAAY,MAAM,UAAU,SAAS,MAAM;AAAA,MACnD,EAAE,MAAM,SAAS,MAAM,WAAW,SAAS,KAAK;AAAA,IAClD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK;AAAA,MAClD,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS,MAAM;AAAA,MACjD,EAAE,MAAM,aAAa,MAAM,WAAW,SAAS,KAAK;AAAA,IACtD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK;AAAA,MAClD,EAAE,MAAM,sBAAsB,MAAM,UAAU,SAAS,KAAK;AAAA,MAC5D,EAAE,MAAM,eAAe,MAAM,UAAU,SAAS,MAAM;AAAA,MACtD,EAAE,MAAM,iBAAiB,MAAM,SAAS,SAAS,MAAM;AAAA,IACzD;AAAA,EACF;AACF;AAgFO,IAAM,gBAAgB;AAAA,EAC3B,cAAc;AAAA,EACd,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,SAAS;AAAA,EACT,cAAc;AAAA,EACd,WAAW;AACb;AAEO,IAAM,yBACX;AAEK,IAAM,2BAGT;AAAA,EACF,UAAU;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,MAAM;AAAA,IACJ,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,gBAAgB;AAAA,IACd,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,oBAAoB;AAAA,IAClB,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AACF;AAEA,IAAM,UAAgC;AAAA,EACpC;AAAA,EACA,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB;AAEA,IAAM,mBACJ;AAAA;AAIK,MAAM,cAAc;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CAAC,QAA6B;AAAA,IAEvC,MAAM,kBACJ,OAAO,mBACP,yBAAyB,OAAO,QAAQ;AAAA,IAC1C,IAAI,CAAC,iBAAiB;AAAA,MACpB,MAAM,IAAI,MACR,+EAA+E,OAAO,QACxF;AAAA,IACF;AAAA,IACA,KAAK,SAAS,KAAK,QAAQ,iBAAiB,gBAAgB;AAAA,IAC5D,MAAM,QAAQ,QAAO,OAAO;AAAA,IAC5B,IAAI,CAAC;AAAA,MACH,MAAM,IAAI,MAAM,qCAAqC,OAAO,QAAQ;AAAA,IACtE,KAAK,QAAQ;AAAA,IACb,KAAK,eAAe,oBAAmB;AAAA,MACrC;AAAA,MACA,WAAW,MAAK,OAAO,MAAM;AAAA,IAC/B,CAAC;AAAA;AAAA,EAGK,eAAe,GAAG;AAAA,IACxB,OAAO,aAAY;AAAA,MACjB,SAAS,KAAK,OAAO;AAAA,MACrB,KAAK;AAAA,MACL,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA;AAAA,EAGK,gBAAgB,CAAC,cAA4B;AAAA,IACnD,OAAO,aAAY;AAAA,MACjB,SAAS,KAAK,OAAO;AAAA,MACrB,KAAK;AAAA,MACL,QAAQ,EAAE,QAAQ,KAAK,cAAc,QAAQ,aAAa;AAAA,IAC5D,CAAC;AAAA;AAAA,OAGG,cAAa,CACjB,cACA,UACA,UACA,iBAC6B;AAAA,IAC7B,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,4CAA4C;AAAA,IAE9D,MAAM,mBAAmB;AAAA,MACvB,MAAM;AAAA,SACH;AAAA,IACL;AAAA,IACA,MAAM,cAAc,YAAY,aAAa,gBAAgB;AAAA,IAC7D,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IAEnD,IAAI;AAAA,IACJ,IAAI,mBAAmB,OAAO,KAAK,eAAe,EAAE,SAAS,GAAG;AAAA,MAC9D,MAAM,UAAU,sBAAsB,eAAe;AAAA,MACrD,SAAS,MAAM,SAAS,MAAM,SAAS,CAAC,aAAa,OAAO,GAAG;AAAA,QAC7D,SAAS,aAAa;AAAA,QACtB,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH,EAAO;AAAA,MACL,SAAS,MAAM,SAAS,MAAM,SAAS,CAAC,WAAW,GAAG;AAAA,QACpD,SAAS,aAAa;AAAA,QACtB,OAAO,KAAK;AAAA,MACd,CAAC;AAAA;AAAA,IAGH,IAAI,UAAyB;AAAA,IAC7B,IAAI;AAAA,MACF,MAAM,UAAU,MAAM,KAAK,aAAa,0BAA0B;AAAA,QAChE,MAAM;AAAA,MACR,CAAC;AAAA,MACD,MAAM,kBAAkB,QAAQ,KAAK,KACnC,CAAC,QACC,IAAI,QAAQ,YAAY,MACtB,KAAK,OAAO,gBAAgB,YAAY,KAC1C,IAAI,OAAO,OAAO,gBACtB;AAAA,MACA,IAAI,iBAAiB,OAAO,IAAI;AAAA,QAC9B,UAAU,OAAO,gBAAgB,OAAO,EAAE;AAAA,MAC5C;AAAA,MACA,MAAM;AAAA,IAIR,OAAO,EAAE,QAAQ,QAAQ;AAAA;AAAA,OAGrB,oBAAmB,CAAC,SAAyC;AAAA,IACjE,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,OAAO,UAAU,eAAe,MAAM,QAAQ,IAAI;AAAA,MACvD,SAAS,KAAK,QAAQ,CAAC,OAAO,CAAC;AAAA,MAC/B,SAAS,KAAK,SAAS,CAAC,OAAO,CAAC;AAAA,MAChC,SAAS,KAAK,eAAe,CAAC,OAAO,CAAC;AAAA,IACxC,CAAC;AAAA,IAED,IAAI,mBAAiD;AAAA,IACrD,IAAI;AAAA,MACF,mBAAmB,MAAM,gBAAgB,QAAkB;AAAA,MAC3D,MAAM;AAAA,IAIR,MAAM,gBAAgB,MAAM,KAAK,kBAAkB,OAAO;AAAA,IAE1D,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAAA,OAGI,mBAAkB,CACtB,cACA,YAAoB,IACW;AAAA,IAC/B,MAAM,OAAO,MAAM,KAAK,aAAa,QAAQ;AAAA,MAC3C,SAAS,KAAK,OAAO;AAAA,MACrB,OAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,EAAE,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK;AAAA,UAClD,EAAE,MAAM,YAAY,MAAM,UAAU,SAAS,MAAM;AAAA,UACnD,EAAE,MAAM,SAAS,MAAM,WAAW,SAAS,KAAK;AAAA,QAClD;AAAA,MACF;AAAA,MACA,MAAM,EAAE,OAAO,aAAa;AAAA,MAC5B;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA,IAED,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO;AAAA,IAC9B,MAAM,YAAY,KAAK,KAAK,SAAS;AAAA,IACrC,MAAM,UAAU,OAAO,UAAU,KAAK,WAAW,CAAC;AAAA,IAClD,OAAO,KAAK,oBAAoB,OAAO;AAAA;AAAA,OAGnC,eAAc,CAClB,cACA,SACA,QACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,YAAY,CAAC,SAAS,MAAM,GAAG;AAAA,MACnD,SAAS,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,IACd,CAAC;AAAA;AAAA,OAGG,mBAAkB,CAAC,SAAiB,KAAkC;AAAA,IAC1E,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,MAAM,QAAQ,MAAM,SAAS,KAAK,YAAY,CAAC,SAAS,GAAG,CAAC;AAAA,IAC5D,OAAO,UAAU,QAAQ,UAAU,OAAO,OAAQ;AAAA;AAAA,OAG9C,mBAAkB,CACtB,cACA,SACA,KACA,OACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D,IAAI,QAAQ,cAAc,cAAc;AAAA,MACtC,MAAM,IAAI,MACR,yEACF;AAAA,IACF;AAAA,IACA,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,MAAM,WAAW,YAAY,KAAK;AAAA,IAClC,OAAO,SAAS,MAAM,YAAY,CAAC,SAAS,KAAK,QAAQ,GAAG;AAAA,MAC1D,SAAS,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,IACd,CAAC;AAAA;AAAA,OAGG,iBAAgB,CACpB,cACA,SACA,OACiB;AAAA,IACjB,MAAM,SAAiB,CAAC;AAAA,IACxB,MAAM,UAA8B,CAAC;AAAA,IACrC,IAAI,MAAM;AAAA,MAAO,QAAQ,KAAK,CAAC,cAAc,OAAO,MAAM,KAAK,CAAC;AAAA,IAChE,IAAI,MAAM;AAAA,MACR,QAAQ,KAAK,CAAC,cAAc,gBAAgB,MAAM,QAAQ,CAAC;AAAA,IAC7D,IAAI,MAAM;AAAA,MAAS,QAAQ,KAAK,CAAC,cAAc,SAAS,MAAM,OAAO,CAAC;AAAA,IACtE,IAAI,MAAM;AAAA,MACR,QAAQ,KAAK,CAAC,cAAc,WAAW,MAAM,SAAS,CAAC;AAAA,IACzD,IAAI,MAAM,cAAc;AAAA,MACtB,QAAQ,KAAK;AAAA,QACX,cAAc;AAAA,QACd,KAAK,UAAU,MAAM,YAAY;AAAA,MACnC,CAAC;AAAA,IAEH,YAAY,KAAK,QAAQ,SAAS;AAAA,MAChC,MAAM,OAAO,MAAM,KAAK,mBACtB,cACA,SACA,KACA,GACF;AAAA,MACA,OAAO,KAAK,IAAI;AAAA,IAClB;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,kBAAiB,CAAC,SAAqD;AAAA,IAC3E,MAAM,OAAO;AAAA,MACX,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,IAChB;AAAA,IACA,MAAM,SAAS,MAAM,QAAQ,IAC3B,KAAK,IAAI,CAAC,MAAM,KAAK,mBAAmB,SAAS,CAAC,CAAC,CACrD;AAAA,IACA,OAAO,UAAU,aAAa,YAAY,cAAc,mBACtD;AAAA,IAEF,IACE,CAAC,YACD,CAAC,eACD,CAAC,cACD,CAAC,gBACD,CAAC;AAAA,MAED,OAAO;AAAA,IAET,MAAM,SAA6B,CAAC;AAAA,IACpC,IAAI;AAAA,MAAU,OAAO,QAAQ,YAAY,QAAQ;AAAA,IACjD,IAAI;AAAA,MAAa,OAAO,WAAW,YAAY,WAAW;AAAA,IAC1D,IAAI;AAAA,MAAY,OAAO,UAAU,YAAY,UAAU;AAAA,IACvD,IAAI;AAAA,MAAc,OAAO,YAAY,YAAY,YAAY;AAAA,IAC7D,IAAI,iBAAiB;AAAA,MACnB,IAAI;AAAA,QACF,OAAO,eAAe,KAAK,MAAM,YAAY,eAAe,CAAC;AAAA,QAC7D,MAAM;AAAA,QACN,OAAO,eAAe,CAAC;AAAA;AAAA,IAE3B;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,eAAc,CAAC,SAAmC;AAAA,IACtD,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,eAAe,CAAC,OAAO,CAAC;AAAA;AAAA,OAGzC,eAAc,CAClB,cACA,SACA,WACA,UACA,WACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,eACpB,CAAC,SAAS,WAAW,UAAU,SAAS,GACxC;AAAA,MACE,SAAS,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,IACd,CACF;AAAA;AAAA,OAGI,iBAAgB,CACpB,cACA,SACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,iBAAiB,CAAC,OAAO,GAAG;AAAA,MAChD,SAAS,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,IACd,CAAC;AAAA;AAEL;AAIO,SAAS,YAAY,CAAC,kBAAiD;AAAA,EAC5E,MAAM,UAAU,KAAK,kBAAkB,MAAM,uBAAuB;AAAA,EACpE,MAAM,OAAO,KAAK,UAAU,OAAO;AAAA,EACnC,MAAM,MAAM,KAAK,SAAS,mBAAmB,IAAI,CAAC,CAAC;AAAA,EACnD,OAAO,gCAAgC;AAAA;AAGlC,SAAS,YAAY,CAAC,KAAoC;AAAA,EAC/D,IAAI,IAAI,WAAW,+BAA+B,GAAG;AAAA,IACnD,MAAM,MAAM,IAAI,QAAQ,iCAAiC,EAAE;AAAA,IAC3D,MAAM,OAAO,mBAAmB,OAAO,KAAK,GAAG,CAAC,CAAC;AAAA,IACjD,OAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EACA,IAAI,IAAI,WAAW,GAAG;AAAA,IAAG,OAAO,KAAK,MAAM,GAAG;AAAA,EAC9C,MAAM,IAAI,MACR,0CAA0C,IAAI,UAAU,GAAG,EAAE,GAC/D;AAAA;AAGF,eAAsB,eAAe,CACnC,KACgC;AAAA,EAChC,IAAI,IAAI,WAAW,OAAO;AAAA,IAAG,OAAO,aAAa,GAAG;AAAA,EACpD,IAAI,IAAI,WAAW,UAAU,KAAK,IAAI,WAAW,SAAS,GAAG;AAAA,IAC3D,MAAM,WAAW,MAAM,MAAM,GAAG;AAAA,IAChC,IAAI,CAAC,SAAS;AAAA,MACZ,MAAM,IAAI,MAAM,yBAAyB,SAAS,cAAc,KAAK;AAAA,IACvE,OAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EACA,MAAM,IAAI,MAAM,4CAA4C,KAAK;AAAA;AAG5D,SAAS,wBAAwB,CACtC,MACU;AAAA,EACV,MAAM,SAAmB,CAAC;AAAA,EAC1B,IAAI,KAAK,SAAS;AAAA,IAChB,OAAO,KAAK,iBAAiB,yBAAyB;AAAA,EACxD,IAAI,CAAC,KAAK,QAAQ,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,KAAK,MAAM;AAAA,IACtE,OAAO,KAAK,kBAAkB;AAAA,EAChC,IAAI,CAAC,KAAK,eAAe,OAAO,KAAK,gBAAgB;AAAA,IACnD,OAAO,KAAK,yBAAyB;AAAA,EACvC,IAAI,KAAK,UAAU;AAAA,IACjB,KAAK,SAAS,QAAQ,CAAC,KAAK,MAAM;AAAA,MAChC,IAAI,CAAC,IAAI;AAAA,QAAM,OAAO,KAAK,YAAY,qBAAqB;AAAA,MAC5D,IAAI,CAAC,IAAI;AAAA,QAAU,OAAO,KAAK,YAAY,yBAAyB;AAAA,KACrE;AAAA,EACH;AAAA,EACA,IAAI,KAAK,eAAe;AAAA,IACtB,KAAK,cAAc,QAAQ,CAAC,KAAK,MAAM;AAAA,MACrC,IAAI,IAAI,YAAY;AAAA,QAClB,OAAO,KAAK,iBAAiB,wBAAwB;AAAA,MACvD,IAAI,CAAC,IAAI;AAAA,QACP,OAAO,KAAK,iBAAiB,8BAA8B;AAAA,KAC9D;AAAA,EACH;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,mBAAmB,CACjC,SACA,iBACQ;AAAA,EACR,OAAO,UAAU,WAAW;AAAA;AAK9B,SAAS,WAAW,CAAC,KAAkB;AAAA,EACrC,MAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,GAAG;AAAA,EAC1C,MAAM,SAAS,MAAM,KAAK,KAAK,EAC5B,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AAAA,EACV,OAAO,KAAK;AAAA;AAGd,SAAS,WAAW,CAAC,KAAkB;AAAA,EACrC,MAAM,WAAW,IAAI,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI;AAAA,EACvD,MAAM,QAAQ,SAAS,MAAM,SAAS;AAAA,EACtC,MAAM,QAAQ,IAAI,WAChB,OAAO,IAAI,CAAC,SAAS,OAAO,SAAS,MAAM,EAAE,CAAC,KAAK,CAAC,CACtD;AAAA,EACA,OAAO,IAAI,YAAY,OAAO,EAAE,OAAO,KAAK;AAAA;AAG9C,SAAS,qBAAqB,CAC5B,SACiB;AAAA,EACjB,OAAO,OAAO,QAAQ,OAAO,EAAE,IAAI,EAAE,KAAK,YAAY;AAAA,IACpD,aAAa;AAAA,IACb,eAAe,YAAY,KAAK;AAAA,EAClC,EAAE;AAAA;;AC1qBJ;AAAA,wBAGE;AAAA,iBACA;AAAA,UAGA;AAAA;AAIF;AAAA,cACE;AAAA,qBACA;AAAA,UACA;AAAA,iBACA;AAAA,aACA;AAAA,aACA;AAAA;AAMK,IAAM,wBAAwB;AAAA,EACnC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,MAChC,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,MAClC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,MAClC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,MAClC,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC,EAAE,MAAM,aAAa,MAAM,SAAS;AAAA,MACpC,EAAE,MAAM,eAAe,MAAM,UAAU;AAAA,IACzC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,IAClC;AAAA,IACA,SAAS;AAAA,MACP,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,MAChC,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,MAClC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,MAClC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,MAClC,EAAE,MAAM,WAAW,MAAM,OAAO;AAAA,IAClC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,WAAW,MAAM,YAAY;AAAA,MACrC,EAAE,MAAM,YAAY,MAAM,SAAS;AAAA,MACnC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,MAClC,EAAE,MAAM,kBAAkB,MAAM,OAAO;AAAA,IACzC;AAAA,IACA,SAAS;AAAA,MACP,EAAE,MAAM,UAAU,MAAM,WAAW;AAAA,MACnC,EAAE,MAAM,cAAc,MAAM,UAAU;AAAA,MACtC,EAAE,MAAM,YAAY,MAAM,WAAW;AAAA,MACrC,EAAE,MAAM,YAAY,MAAM,WAAW;AAAA,MACrC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,WAAW,MAAM,YAAY;AAAA,MACrC,EAAE,MAAM,YAAY,MAAM,SAAS;AAAA,MACnC,EAAE,MAAM,WAAW,MAAM,SAAS;AAAA,IACpC;AAAA,IACA,SAAS;AAAA,MACP,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,MAChC,EAAE,MAAM,cAAc,MAAM,SAAS;AAAA,MACrC,EAAE,MAAM,eAAe,MAAM,QAAQ;AAAA,IACvC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,YAAY,CAAC;AAAA,EAC3C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,MAChC,EAAE,MAAM,YAAY,MAAM,SAAS;AAAA,MACnC,EAAE,MAAM,eAAe,MAAM,UAAU;AAAA,IACzC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,IAClC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,SAAS,MAAM,SAAS;AAAA,MAChC,EAAE,MAAM,cAAc,MAAM,YAAY;AAAA,IAC1C;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AACF;AAqDA,IAAM,UAAgC;AAAA,EACpC;AAAA,EACA,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB;AAAA;AAIO,MAAM,iBAAiB;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CAAC,QAAgC;AAAA,IAC1C,MAAM,kBACJ,OAAO,qBACP,yBAAyB,OAAO,QAAQ;AAAA,IAC1C,IAAI,CAAC,iBAAiB;AAAA,MACpB,MAAM,IAAI,MACR,oFAAoF,OAAO,QAC7F;AAAA,IACF;AAAA,IACA,KAAK,oBAAoB;AAAA,IAEzB,MAAM,QAAQ,QAAO,OAAO;AAAA,IAC5B,IAAI,CAAC;AAAA,MACH,MAAM,IAAI,MAAM,wCAAwC,OAAO,QAAQ;AAAA,IACzE,KAAK,QAAQ;AAAA,IACb,KAAK,eAAe,oBAAmB;AAAA,MACrC;AAAA,MACA,WAAW,MAAK,OAAO,MAAM;AAAA,IAC/B,CAAC;AAAA;AAAA,EAGK,eAAe,GAAG;AAAA,IACxB,OAAO,aAAY;AAAA,MACjB,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA;AAAA,EAGK,gBAAgB,CAAC,cAA4B;AAAA,IACnD,OAAO,aAAY;AAAA,MACjB,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,QAAQ,EAAE,QAAQ,KAAK,cAAc,QAAQ,aAAa;AAAA,IAC5D,CAAC;AAAA;AAAA,OAMG,aAAY,CAChB,cACA,QACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,aACpB;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IACT,GACA,EAAE,SAAS,aAAa,SAAS,OAAO,KAAK,MAAM,CACrD;AAAA;AAAA,OAMI,aAAY,CAChB,SACA,QACA,OACwB;AAAA,IACxB,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,OAAO,UAAU,SAAS,SAAS,WACvC,MAAM,SAAS,KAAK,aAAa,CAAC,SAAS,QAAQ,KAAK,CAAC;AAAA,IAQ5D,OAAO,EAAE,OAAO,UAAU,SAAS,SAAS,QAAQ;AAAA;AAAA,OAMhD,mBAAkB,CACtB,SACA,SACiC;AAAA,IACjC,MAAM,WAAW,KAAK,gBAAgB;AAAA,IAEtC,MAAM,UAAW,MAAM,SAAS,KAAK,WAAW,CAAC,OAAO,CAAC;AAAA,IAEzD,MAAM,gBAAgB,SAAS,WAAW;AAAA,IAC1C,MAAM,WAAW,SAAS,YAAY;AAAA,IACtC,MAAM,UAAU,SAAS,WAAW;AAAA,IAEpC,OAAO,OAAO,YAAY,eAAgB,MAAM,SAAS,KAAK,WAAW;AAAA,MACvE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IAED,OAAO,EAAE,OAAO,YAAY,aAAa,QAAQ;AAAA;AAAA,OAM7C,eAAc,CAClB,SACA,SAC0B;AAAA,IAC1B,MAAM,WAAW,KAAK,gBAAgB;AAAA,IAEtC,MAAM,UAAU,SAAS,WAAW,CAAC;AAAA,IACrC,MAAM,WAAW,SAAS,YAAY;AAAA,IACtC,MAAM,UAAU,SAAS,WAAW;AAAA,IACpC,MAAM,iBAAiB,SAAS,kBAAkB;AAAA,IAElD,OAAO,QAAQ,YAAY,UAAU,UAAU,WAC5C,MAAM,SAAS,KAAK,gBAAgB;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IAEH,OAAO,OAAO,IAAI,CAAC,OAAO,OAAO;AAAA,MAC/B;AAAA,MACA,UAAU,WAAW;AAAA,MACrB,SAAS,SAAS;AAAA,MAClB,SAAS,SAAS;AAAA,MAClB,SAAS,QAAQ;AAAA,IACnB,EAAE;AAAA;AAAA,OAME,kBAAiB,CACrB,cACA,QACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,eACpB;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IACT,GACA,EAAE,SAAS,aAAa,SAAS,OAAO,KAAK,MAAM,CACrD;AAAA;AAAA,OAMI,eAAc,CAClB,cACA,SACA,OACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,eAAe,CAAC,SAAS,KAAK,GAAG;AAAA,MACrD,SAAS,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,IACd,CAAC;AAAA;AAAA,OAMG,oBAAmB,GAAqB;AAAA,IAC5C,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,oBAAoB;AAAA;AAAA,OAMrC,aAAY,CAAC,SAAiB,QAAkC;AAAA,IACpE,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,aAAa,CAAC,SAAS,MAAM,CAAC;AAAA;AAAA,OAM/C,WAAU,CAAC,SAAqC;AAAA,IACpD,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,WAAW,CAAC,OAAO,CAAC;AAAA;AAAA,OAMrC,iBAAgB,CACpB,SACA,QACA,OACA,YACiB;AAAA,IACjB,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,iBAAiB;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAEL;;ACpUA,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAG7B,IAAM,gBAAgD;AAAA,EACpD,UAAU;AAAA,EACV,MAAM;AAAA,EACN,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,SAAS;AACX;AAAA;AAWO,MAAM,aAAa;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,IAAI;AAAA,EAE7B,WAAW,CAAC,SAA6B,CAAC,GAAG;AAAA,IAC3C,KAAK,aAAa,OAAO,aAAa,oBAAoB,QACxD,QACA,EACF;AAAA,IACA,KAAK,SAAS,OAAO;AAAA,IACrB,KAAK,YAAY,OAAO,aAAa;AAAA,IACrC,KAAK,aAAa,OAAO,cAAc;AAAA;AAAA,OAwBnC,QAAO,CAAC,MAAuC;AAAA,IAEnD,MAAM,SAAS,KAAK,MAAM,IAAI,IAAI;AAAA,IAClC,IAAI,UAAU,OAAO,YAAY,KAAK,IAAI,GAAG;AAAA,MAC3C,OAAO,OAAO;AAAA,IAChB;AAAA,IAEA,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,KAAK,cAC1B,OACA,wBAAwB,mBAAmB,IAAI,GACjD;AAAA,MAEA,IAAI,CAAC,SAAS,IAAI;AAAA,QAChB,MAAM,UAAyB;AAAA,UAC7B,UAAU;AAAA,UACV;AAAA,UACA,UAAU;AAAA,UACV,UAAU;AAAA,UACV,kBAAkB;AAAA,UAClB,OAAO,qBAAqB,SAAS;AAAA,QACvC;AAAA,QACA,OAAO;AAAA,MACT;AAAA,MAEA,MAAM,OAAO,MAAM,SAAS,KAAK;AAAA,MAEjC,MAAM,WAAmC;AAAA,QACvC,SAAS,OAAO,KAAK,WAAW,KAAK,YAAY,EAAE;AAAA,QACnD,OAAO,KAAK,SAAS,KAAK,cAAc;AAAA,QACxC,UAAU,KAAK,YAAY,KAAK,eAAe;AAAA,QAC/C,gBAAgB,KAAK,kBAAkB,KAAK,eAAe;AAAA,QAC3D,kBAAkB,KAAK,oBAAoB;AAAA,QAC3C,UAAU,KAAK,YAAY;AAAA,QAC3B,OAAO,KAAK,SAAS;AAAA,QACrB;AAAA,MACF;AAAA,MAEA,MAAM,SAAyB;AAAA,QAC7B,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,UAAU,KAAK,YAAY;AAAA,QAC3B,OAAO,KAAK;AAAA,QACZ,YAAY,KAAK;AAAA,QACjB,kBAAkB,KAAK,YAAY;AAAA,MACrC;AAAA,MAGA,KAAK,MAAM,IAAI,MAAM,EAAE,QAAQ,WAAW,KAAK,IAAI,IAAI,KAAK,WAAW,CAAC;AAAA,MACxE,OAAO;AAAA,MACP,OAAO,OAAgB;AAAA,MACvB,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACrE,OAAO;AAAA,QACL,UAAU;AAAA,QACV;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,QACV,kBAAkB;AAAA,QAClB,OAAO,sBAAsB;AAAA,MAC/B;AAAA;AAAA;AAAA,OAWE,OAAM,CACV,OACA,SAK2B;AAAA,IAC3B,IAAI;AAAA,MACF,MAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAAA,MAC/C,IAAI,SAAS;AAAA,QAAU,OAAO,IAAI,YAAY,QAAQ,QAAQ;AAAA,MAC9D,IAAI,SAAS;AAAA,QAAO,OAAO,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAAA,MAC7D,IAAI,SAAS;AAAA,QACX,OAAO,IAAI,YAAY,OAAO,QAAQ,aAAa,CAAC;AAAA,MAEtD,MAAM,WAAW,MAAM,KAAK,cAC1B,OACA,kBAAkB,QACpB;AAAA,MACA,IAAI,CAAC,SAAS;AAAA,QAAI,OAAO,CAAC;AAAA,MAE1B,MAAM,OAAO,MAAM,SAAS,KAAK;AAAA,MACjC,MAAM,WAA6B,KAAK,UAAU,CAAC,GAAG,IACpD,CAAC,WAAoC;AAAA,QACnC,UAAU;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,UAAU;AAAA,UACR,SAAS,OAAO,MAAM,WAAW,MAAM,YAAY,EAAE;AAAA,UACrD,OAAQ,MAAM,SAAS,MAAM,cAAc;AAAA,UAC3C,UAAW,MAAM,YAAY,MAAM,eAAe;AAAA,UAClD,gBAAiB,MAAM,kBACrB,MAAM,eACN;AAAA,UACF,kBAAmB,MAAM,oBACvB;AAAA,UACF,UAAW,MAAM,YAAY;AAAA,UAC7B,OAAQ,MAAM,SAAS;AAAA,UACvB,MAAM,MAAM;AAAA,QACd;AAAA,QACA,UAAW,MAAM,YAAY;AAAA,QAC7B,OAAO,MAAM;AAAA,QACb,YAAY,MAAM;AAAA,QAClB,kBAAmB,MAAM,YAAY;AAAA,MACvC,EACF;AAAA,MAEA,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO,CAAC;AAAA;AAAA;AAAA,EAYZ,kBAAkB,CAChB,UACA,OACwB;AAAA,IACxB,MAAM,UAAU,cAAc;AAAA,IAC9B,OAAO;AAAA,MACL,SAAS,SAAS,QAAQ,SAAS;AAAA,MACnC,OAAO,SAAS;AAAA,MAChB,UAAU,SAAS;AAAA,MACnB,gBAAgB,SAAS;AAAA,MACzB,kBAAkB,SAAS;AAAA,MAC3B,UAAU;AAAA,MACV,OAAO,UAAU;AAAA,MACjB,MAAM,mBAAmB,WAAW,SAAS,aAAa,SAAS;AAAA,IACrE;AAAA;AAAA,EASF,gBAAgB,CACd,SACA,OACA,cACQ;AAAA,IACR,MAAM,UAAU,cAAc;AAAA,IAC9B,OAAO,mBAAmB,WAAW,oBAAoB;AAAA;AAAA,OAcrD,qBAAoB,CAAC,QAA6C;AAAA,IACtE,IAAI,CAAC,KAAK,QAAQ;AAAA,MAChB,MAAM,IAAI,MACR,6EACF;AAAA,IACF;AAAA,IAEA,MAAM,UAAU,cAAc,OAAO;AAAA,IACrC,MAAM,OAAO,mBAAmB,WAAW,OAAO,mBAAmB,oDAAoD,OAAO;AAAA,IAEhI,MAAM,WAAW,MAAM,KAAK,cAAc,QAAQ,oBAAoB;AAAA,MACpE;AAAA,MACA,UAAU;AAAA,MACV,OAAO,UAAU;AAAA,MACjB,SAAS,OAAO,QAAQ,SAAS;AAAA,MACjC,MAAM,OAAO;AAAA,MACb,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO,gBAAgB,CAAC;AAAA,MACtC,iBACE,OAAO,mBAAmB;AAAA,IAC9B,CAAC;AAAA,IAED,IAAI,CAAC,SAAS,IAAI;AAAA,MAChB,MAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AAAA,MACtD,MAAM,IAAI,MACR,sCAAsC,SAAS,YAAY,WAC7D;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,MAAM,SAAS,KAAK;AAAA,IACjC,OAAO,KAAK,QAAQ;AAAA;AAAA,OAehB,OAAM,CAAC,MAMV;AAAA,IACD,MAAM,aAAa,MAAM,KAAK,QAAQ,IAAI;AAAA,IAE1C,IAAI,CAAC,WAAW,YAAY,CAAC,WAAW,UAAU;AAAA,MAChD,OAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,UAAU,WAAW;AAAA,QACrB,OAAO,WAAW,SAAS;AAAA,MAC7B;AAAA,IACF;AAAA,IAEA,OAAO;AAAA,MACL,UAAU,WAAW;AAAA,MACrB,UAAU,WAAW;AAAA,MACrB,YAAY,WAAW,cAAc;AAAA,MACrC,UAAU,WAAW;AAAA,IACvB;AAAA;AAAA,SAUK,SAAS,CAAC,MAAiC;AAAA,IAChD,IAAI,CAAC,KAAK,WAAW,OAAO;AAAA,MAAG,OAAO;AAAA,IAEtC,MAAM,QAAQ,KAAK,MAAM,GAAG;AAAA,IAC5B,MAAM,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AAAA,IAC3D,MAAM,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM,CAAC;AAAA,IACtD,MAAM,YAAY,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,CAAC;AAAA,IAC1D,MAAM,eAAe,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AAAA,IAEhE,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC;AAAA,MAAW,OAAO;AAAA,IAE/C,OAAO;AAAA,MACL,KAAK;AAAA,MACL,KAAK,QAAQ,QAAQ,aAAa,EAAE;AAAA,MACpC,KAAK,QAAQ,QAAQ,QAAQ,EAAE;AAAA,MAC/B,UAAU,UAAU,QAAQ,UAAU,EAAE;AAAA,MACxC,UAAU,cAAc,QAAQ,aAAa,EAAE;AAAA,IACjD;AAAA;AAAA,EAIF,UAAU,GAAS;AAAA,IACjB,KAAK,MAAM,MAAM;AAAA;AAAA,OAKL,cAAa,CACzB,QACA,MACA,MACmB;AAAA,IACnB,MAAM,MAAM,GAAG,KAAK,YAAY;AAAA,IAChC,MAAM,UAAkC;AAAA,MACtC,QAAQ;AAAA,MACR,cAAc;AAAA,IAChB;AAAA,IACA,IAAI,KAAK,QAAQ;AAAA,MACf,QAAQ,gBAAgB,UAAU,KAAK;AAAA,IACzC;AAAA,IACA,IAAI,MAAM;AAAA,MACR,QAAQ,kBAAkB;AAAA,IAC5B;AAAA,IAEA,MAAM,aAAa,IAAI;AAAA,IACvB,MAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,SAAS;AAAA,IAEnE,IAAI;AAAA,MACF,OAAO,MAAM,MAAM,KAAK;AAAA,QACtB;AAAA,QACA;AAAA,QACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,QACpC,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,cACD;AAAA,MACA,aAAa,OAAO;AAAA;AAAA;AAG1B;;ACpeA;AAAA,wBAGE;AAAA,iBACA;AAAA,UAGA;AAAA;AAIF;AAAA,cACE;AAAA,qBACA;AAAA,UACA;AAAA,iBACA;AAAA,aACA;AAAA,aACA;AAAA;AAMK,IAAM,wBAAwB;AAAA,EACnC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,cAAc,MAAM,SAAS;AAAA,MACrC,EAAE,MAAM,eAAe,MAAM,UAAU;AAAA,IACzC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,eAAe,MAAM,UAAU;AAAA,MACvC,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,MAClC,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC,EAAE,MAAM,gBAAgB,MAAM,UAAU;AAAA,MACxC,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,IAChC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,eAAe,MAAM,UAAU,CAAC;AAAA,IACjD,SAAS;AAAA,MACP,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,cAAc,MAAM,SAAS;AAAA,MACrC,EAAE,MAAM,YAAY,MAAM,QAAQ;AAAA,MAClC,EAAE,MAAM,eAAe,MAAM,SAAS;AAAA,MACtC,EAAE,MAAM,gBAAgB,MAAM,UAAU;AAAA,MACxC,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,MAC9B,EAAE,MAAM,aAAa,MAAM,OAAO;AAAA,IACpC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,iBAAiB,MAAM,YAAY,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,aAAa,MAAM,UAAU,CAAC;AAAA,IAC/C,SAAS,CAAC,EAAE,MAAM,iBAAiB,MAAM,YAAY,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,cAAc,MAAM,YAAY;AAAA,MACxC,EAAE,MAAM,YAAY,MAAM,SAAS;AAAA,IACrC;AAAA,IACA,SAAS;AAAA,MACP,EAAE,MAAM,iBAAiB,MAAM,UAAU;AAAA,MACzC,EAAE,MAAM,kBAAkB,MAAM,UAAU;AAAA,MAC1C,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,IACvC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,EACxC;AAAA,EAEA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,WAAW,SAAS,KAAK;AAAA,MACpD,EAAE,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK;AAAA,MAClD,EAAE,MAAM,cAAc,MAAM,UAAU,SAAS,MAAM;AAAA,MACrD,EAAE,MAAM,eAAe,MAAM,WAAW,SAAS,MAAM;AAAA,IACzD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,aAAa,MAAM,WAAW,SAAS,KAAK;AAAA,MACpD,EAAE,MAAM,WAAW,MAAM,WAAW,SAAS,KAAK;AAAA,MAClD,EAAE,MAAM,eAAe,MAAM,WAAW,SAAS,MAAM;AAAA,MACvD,EAAE,MAAM,YAAY,MAAM,SAAS,SAAS,MAAM;AAAA,MAClD,EAAE,MAAM,eAAe,MAAM,UAAU,SAAS,MAAM;AAAA,MACtD,EAAE,MAAM,gBAAgB,MAAM,WAAW,SAAS,MAAM;AAAA,MACxD,EAAE,MAAM,OAAO,MAAM,UAAU,SAAS,MAAM;AAAA,IAChD;AAAA,EACF;AACF;AA6CA,IAAM,UAAgC;AAAA,EACpC;AAAA,EACA,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB;AAAA;AAIO,MAAM,iBAAiB;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CAAC,QAAgC;AAAA,IAC1C,MAAM,kBACJ,OAAO,qBACP,yBAAyB,OAAO,QAAQ;AAAA,IAC1C,IAAI,CAAC,iBAAiB;AAAA,MACpB,MAAM,IAAI,MACR,oFAAoF,OAAO,4GAC7F;AAAA,IACF;AAAA,IACA,KAAK,oBAAoB;AAAA,IAEzB,MAAM,QAAQ,QAAO,OAAO;AAAA,IAC5B,IAAI,CAAC;AAAA,MACH,MAAM,IAAI,MAAM,wCAAwC,OAAO,QAAQ;AAAA,IACzE,KAAK,QAAQ;AAAA,IACb,KAAK,eAAe,oBAAmB;AAAA,MACrC;AAAA,MACA,WAAW,MAAK,OAAO,MAAM;AAAA,IAC/B,CAAC;AAAA;AAAA,EAGK,eAAe,GAAG;AAAA,IACxB,OAAO,aAAY;AAAA,MACjB,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA;AAAA,EAGK,gBAAgB,CAAC,cAA4B;AAAA,IACnD,OAAO,aAAY;AAAA,MACjB,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,QAAQ,EAAE,QAAQ,KAAK,cAAc,QAAQ,aAAa;AAAA,IAC5D,CAAC;AAAA;AAAA,OAMG,kBAAiB,CACrB,cACA,QACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,kBACpB,CAAC,OAAO,WAAW,OAAO,SAAS,OAAO,YAAY,OAAO,WAAW,GACxE,EAAE,SAAS,aAAa,SAAS,OAAO,KAAK,MAAM,CACrD;AAAA;AAAA,OAMI,oBAAmB,CACvB,cACA,QACe;AAAA,IACf,IAAI,CAAC,aAAa;AAAA,MAChB,MAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE,MAAM,WAAW,KAAK,iBAAiB,YAAY;AAAA,IACnD,OAAO,SAAS,MAAM,mBACpB;AAAA,MACE,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IACT,GACA,EAAE,SAAS,aAAa,SAAS,OAAO,KAAK,MAAM,CACrD;AAAA;AAAA,OAMI,oBAAmB,CAAC,aAA6C;AAAA,IACrE,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACG,MAAM,SAAS,KAAK,oBAAoB,CAAC,WAAW,CAAC;AAAA,IAW1D,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAAA,OAMI,oBAAmB,CAAC,SAAiC;AAAA,IACzD,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,oBAAoB,CAAC,OAAO,CAAC;AAAA;AAAA,OAM9C,qBAAoB,CAAC,kBAA2C;AAAA,IACpE,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,qBAAqB,CAAC,gBAAgB,CAAC;AAAA;AAAA,OAQxD,WAAU,CACd,SACA,YACA,UAC4B;AAAA,IAC5B,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,eAAe,gBAAgB,WAAW,aAC9C,MAAM,SAAS,KAAK,WAAW;AAAA,MAC9B;AAAA,MACA,cAAc,CAAC;AAAA,MACf,YAAY;AAAA,IACd,CAAC;AAAA,IAEH,OAAO,EAAE,eAAe,gBAAgB,WAAW,UAAU;AAAA;AAAA,OAMzD,oBAAmB,GAAqB;AAAA,IAC5C,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,oBAAoB;AAAA;AAAA,OAMrC,WAAU,GAAoB;AAAA,IAClC,MAAM,WAAW,KAAK,gBAAgB;AAAA,IACtC,OAAO,SAAS,KAAK,WAAW;AAAA;AAEpC;;AChXO,IAAM,qBAAqB;AAAA,EAChC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,UACnC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,UACpC,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,UAC9B,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,UACrC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,UACpC,EAAE,MAAM,oBAAoB,MAAM,UAAU;AAAA,UAC5C,EAAE,MAAM,qBAAqB,MAAM,UAAU;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,aAAa,MAAM,UAAU,CAAC;AAAA,EAClD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,QAAQ,MAAM,QAAQ;AAAA,UAC9B,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,UACrC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,UACpC,EAAE,MAAM,oBAAoB,MAAM,UAAU;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,aAAa,MAAM,UAAU,CAAC;AAAA,EAClD;AACF;AAEO,IAAM,uBAAuB;AAAA,EAClC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,UACnC,EAAE,MAAM,YAAY,MAAM,UAAU;AAAA,UACpC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,UAClC,EAAE,MAAM,OAAO,MAAM,SAAS;AAAA,UAC9B,EAAE,MAAM,qBAAqB,MAAM,UAAU;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,qBAAqB,MAAM,UAAU;AAAA,MAC7C,EAAE,MAAM,2BAA2B,MAAM,SAAS;AAAA,MAClD,EAAE,MAAM,eAAe,MAAM,UAAU;AAAA,IACzC;AAAA,EACF;AACF;AAEO,IAAM,WAAW;AAAA,EACtB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,MACjC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACrC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,MAAM,MAAM,UAAU;AAAA,MAC9B,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,QAAQ,CAAC;AAAA,EACvC;AACF;;ACzGA;AAAA;AAAA;;;ACmDO,IAAM,cAAc;AAAA,EACzB,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AACX;AAuCO,IAAM,uBAGT;AAAA,EACF,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AAAA,EACA,UAAU;AAAA,IACR,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AAAA,EACA,UAAU;AAAA,IACR,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AACF;AAGO,IAAM,mBAAmB;AAEzB,IAAM,yBACX;AAEK,IAAM,uBAAuB;;;ADtGpC,IAAM,YAA8B,CAAC,KAAK,KAAK,MAAM,GAAK;AAGnD,SAAS,eAAe,CAAC,QAAgB,QAAwB;AAAA,EACtE,OAAQ,SAAS,OAAO,MAAM,IAAK;AAAA;AAI9B,SAAS,aAAa,CAAC,QAAgB,aAA6B;AAAA,EACzE,OAAQ,SAAS,OAAO,MAAQ,WAAW,IAAK;AAAA;AAI3C,SAAS,YAAY,CAAC,cAA8B;AAAA,EACzD,OAAO,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI,IAAI,YAAY;AAAA;AAAA;AAGrD,MAAM,WAAW;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CACT,cACA,cACA,gBACA,QACA;AAAA,IACA,KAAK,eAAe;AAAA,IACpB,KAAK,eAAe;AAAA,IACpB,KAAK,iBAAiB;AAAA,IACtB,MAAM,QAAmB,QAAQ,SAAS;AAAA,IAC1C,MAAM,iBAAiB,qBAAqB;AAAA,IAC5C,KAAK,SAAS;AAAA,MACZ,eAAe,eAAe;AAAA,MAC9B,eAAe,eAAe;AAAA,MAC9B,QAAQ;AAAA,MACR,WAAW;AAAA,MACX;AAAA,SACG;AAAA,SAEC,QAAQ,gBACR,CAAC,IACD,EAAE,eAAe,eAAe,OAAO;AAAA,SACvC,QAAQ,gBACR,CAAC,IACD,EAAE,eAAe,eAAe,UAAU;AAAA,IAChD;AAAA;AAAA,OAGI,SAAQ,CACZ,SACA,UACA,UACA,UAAyD,CAAC,GACtC;AAAA,IACpB,MAAM,cAAc,QAAQ,eAAe;AAAA,IAC3C,MAAM,aAAa,QAAQ,YAAY;AAAA,IACvC,MAAM,YAAY,gBAAgB,UAAU,KAAK,OAAO,MAAM;AAAA,IAC9D,MAAM,cAAc,WAAW;AAAA,IAC/B,IAAI,eAAe,IAAI;AAAA,MACrB,MAAM,IAAI,MACR,yBAAyB,iCAAgC,0BAC3D;AAAA,IACF;AAAA,IAEA,IAAI,YAIO;AAAA,IACX,WAAW,OAAO,YAAY;AAAA,MAC5B,IAAI;AAAA,QACF,MAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,UAClD,SAAS,KAAK,OAAO;AAAA,UACrB,KAAK;AAAA,UACL,cAAc;AAAA,UACd,MAAM;AAAA,YACJ;AAAA,cACE;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,cACR;AAAA,cACA,mBAAmB;AAAA,YACrB;AAAA,UACF;AAAA,QACF,CAAC;AAAA,QACD,OAAO,eAAe,eAAe;AAAA,QAMrC,IAAI,CAAC,aAAa,YAAY,UAAU,WAAW;AAAA,UACjD,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA,SAAS;AAAA,UACX;AAAA,QACF;AAAA,QACA,MAAM;AAAA,IAGV;AAAA,IAEA,IAAI,CAAC,WAAW;AAAA,MACd,MAAM,IAAI,MACR,4CAA4C,aAAY,eAAe,KAAK,OAAO,QACrF;AAAA,IACF;AAAA,IAEA,MAAM,mBAAmB,cAAc,UAAU,WAAW,WAAW;AAAA,IACvE,MAAM,gBACJ,cAAc,KAAK,OAAO,UAAU,SAAS,IAAI,OAAO,WAAW,IAAI;AAAA,IAEzE,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA,WAAW,UAAU;AAAA,MACrB;AAAA,MACA,aAAa,UAAU;AAAA,MACvB;AAAA,MACA,aAAa,UAAU;AAAA,IACzB;AAAA;AAAA,OAGI,eAAc,CAClB,OACA,SACA,QAC2B;AAAA,IAC3B,MAAM,mBAAoB,MAAM,KAAK,aAAa,aAAa;AAAA,MAC7D,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,KAAK,gBAAgB,OAAO;AAAA,IACrC,CAAC;AAAA,IAED,IAAI,oBAAoB;AAAA,MAAQ;AAAA,IAEhC,MAAM,cACJ;AAAA,IACF,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,yCAAyC;AAAA,IAEvE,MAAM,cAAc,mBAAmB;AAAA,MACrC,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,SAAS,WAAW;AAAA,IAC7B,CAAC;AAAA,IAED,OAAO,KAAK,aAAa,gBAAgB;AAAA,MACvC;AAAA,MACA,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,OAAO,KAAK,aAAa,SAAS;AAAA,IACpC,CAAC;AAAA;AAAA,OAGW,YAAW,CACvB,OACA,WACA,WACe;AAAA,IACf,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,yCAAyC;AAAA,IAEvE,MAAM,eAAe,mBAAmB;AAAA,MACtC,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,WAAW,SAAS;AAAA,IAC7B,CAAC;AAAA,IAED,OAAO,KAAK,aAAa,gBAAgB;AAAA,MACvC;AAAA,MACA,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,OAAO,KAAK,aAAa,SAAS;AAAA,IACpC,CAAC;AAAA;AAAA,OAGG,KAAI,CACR,SACA,UACA,UACA,UAAuB,CAAC,GACH;AAAA,IACrB,MAAM,cAAc,QAAQ,eAAe;AAAA,IAC3C,MAAM,eAAe,QAAQ,gBAAgB;AAAA,IAC7C,MAAM,YAAY,QAAQ,aAAa,KAAK,OAAO;AAAA,IAEnD,MAAM,QAAQ,MAAM,KAAK,SAAS,SAAS,UAAU,UAAU;AAAA,MAC7D;AAAA,MACA,UAAU,QAAQ;AAAA,IACpB,CAAC;AAAA,IAED,IAAI,MAAM,cAAc,UAAU;AAAA,MAChC,QAAQ,KACN,kCAAkC,MAAM,qCAC1C;AAAA,IACF;AAAA,IAEA,MAAM,iBAAiB,MAAM,KAAK,eAChC,SACA,KAAK,OAAO,eACZ,QACF;AAAA,IACA,MAAM,mBAAmB,mBAAmB;AAAA,IAE5C,IAAI;AAAA,IACJ,IAAI,MAAM,YAAY,MAAM,cAAc,KAAK,gBAAgB;AAAA,MAC7D,YAAY,MAAM,KAAK,YAAY,SAAS,MAAM,WAAW,SAAS;AAAA,IACxE;AAAA,IAEA,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,yCAAyC;AAAA,IAEvE,MAAM,YAAY,aAAa,YAAY;AAAA,IAC3C,MAAM,WAAW,mBAAmB;AAAA,MAClC,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM;AAAA,QACJ;AAAA,UACE;AAAA,UACA;AAAA,UACA,KAAK,MAAM;AAAA,UACX,WAAW,KAAK;AAAA,UAChB,UAAU,MAAM;AAAA,UAChB,kBAAkB,MAAM;AAAA,UACxB,mBAAmB;AAAA,QACrB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IAED,MAAM,SAAS,MAAM,KAAK,aAAa,gBAAgB;AAAA,MACrD;AAAA,MACA,IAAI,KAAK,OAAO;AAAA,MAChB,MAAM;AAAA,MACN,OAAO,KAAK,aAAa,SAAS;AAAA,IACpC,CAAC;AAAA,IAED,OAAO,EAAE,QAAQ,WAAW,OAAO,kBAAkB,eAAe;AAAA;AAAA,EAGtE,SAAS,GAAqB;AAAA,IAC5B,OAAO,KAAK,KAAK,OAAO;AAAA;AAAA,EAG1B,YAAY,CAAC,SAAwB;AAAA,IACnC,KAAK,OAAO,YAAY;AAAA;AAE5B;AAEO,SAAS,UAAU,CACxB,QAKA,QACA;AAAA,EACA,MAAM,aAAa,IAAI,WACrB,OAAO,cACP,OAAO,cACP,OAAO,SACP,MACF;AAAA,EACA,OAAO;AAAA,OACF;AAAA,IACH;AAAA,IACA,MAAM,WAAW,KAAK,KAAK,UAAU;AAAA,IACrC,UAAU,WAAW,SAAS,KAAK,UAAU;AAAA,EAC/C;AAAA;;AElRF,qCAA6B;AAC7B;AACA;AAAA,cACE;AAAA,UACA;AAAA,iBACA;AAAA,aACA;AAAA,cACA;AAAA,aACA;AAAA;AAaF,IAAM,YAAmC;AAAA,EACvC;AAAA,EACA,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb;AAAA,EACA,UAAU;AAAA,EACV,KAAK;AAAA,EACL;AAAA,EACA,KAAK;AAAA,EACL;AAAA,EACA,IAAI;AAAA,EACJ;AAAA,EACA,OAAO;AACT;AAGA,IAAM,cAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,gBAAgB;AAAA,EAChB,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AACX;AASA,SAAS,YAAY,CAAC,UAAkC;AAAA,EACtD,IAAI,OAAO,aAAa,UAAU;AAAA,IAChC,MAAM,QAAQ,OAAO,OAAO,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AAAA,IACpE,OAAO,SAAS;AAAA,EAClB;AAAA,EACA,MAAM,MAAM,SAAS,YAAY,EAAE,KAAK;AAAA,EACxC,OAAO,UAAU,QAAQ;AAAA;AAI3B,SAAS,sBAAsB,CAAC,OAA0C;AAAA,EACxE,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,MACH,OAAO;AAAA;AAAA,MAEP,MAAM,IAAI,MACR,sDAAsD,MAAM,YAAY,MAAM,UAC5E,yDACJ;AAAA;AAAA;AAMN,IAAM,gBAAgB;AAQtB,SAAS,SAAS,CAAC,OAA+C;AAAA,EAChE,IAAI,CAAC,SAAS,MAAM,KAAK,MAAM;AAAA,IAAI;AAAA,EACnC,IAAI;AAAA,IACF,OAAO,WAAW,MAAM,KAAK,GAAG,aAAa;AAAA,IAC7C,MAAM;AAAA,IACN,QAAQ,KAAK,iDAAiD,QAAQ;AAAA,IACtE;AAAA;AAAA;AA4BG,SAAS,aAAa,CAAC,SAGM;AAAA,EAElC,MAAM,SAAS,QAAQ,IAAI;AAAA,EAC3B,IAAI,CAAC,UAAU,OAAO,KAAK,MAAM,IAAI;AAAA,IACnC,MAAM,IAAI,MACR,yEACE,sEACJ;AAAA,EACF;AAAA,EACA,MAAM,aAAc,OAAO,WAAW,IAAI,IAAI,SAAS,KAAK;AAAA,EAG5D,MAAM,gBAAgB,QAAQ,IAAI;AAAA,EAClC,IAAI,CAAC,iBAAiB,cAAc,KAAK,MAAM,IAAI;AAAA,IACjD,MAAM,IAAI,MACR,4EACE,qEACJ;AAAA,EACF;AAAA,EAGA,MAAM,cACJ,SAAS,SACT,QAAQ,IAAI,eACX,QAAQ,IAAI,WAAW,QAAQ,IAAI,WAAW;AAAA,EAEjD,MAAM,QAAQ,cACV,aACE,QAAQ,KAAK,OAAO,WAAW,CAAC,IAC5B,SAAS,aAAa,EAAE,IACxB,OAAO,WAAW,CACxB,IACA;AAAA,EAGJ,MAAM,SACJ,SAAS,UACT,QAAQ,IAAI,WACZ,YAAY,MAAM,KAAK,YAAY,MACnC,YAAY;AAAA,EAGd,MAAM,UAAU,oBAAoB,UAAU;AAAA,EAC9C,MAAM,eAAe,mBAAmB;AAAA,IACtC;AAAA,IACA;AAAA,IACA,WAAW,MAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EAGD,OAAO,aAAa;AAAA,IAClB,gBAAgB;AAAA,IAChB,OAAO,uBAAuB,KAAK;AAAA,IACnC;AAAA,IACA;AAAA,EACF,CAAC;AAAA;AAuBH,eAAsB,gBAAgB,CACpC,QACiB;AAAA,EACjB,MAAM,aAAa,UAAU,QAAQ,IAAI,kBAAkB;AAAA,EAC3D,MAAM,cAAc,UAAU,QAAQ,IAAI,iBAAiB;AAAA,EAG3D,MAAM,UAAU,OAAO,MAAM;AAAA,EAC7B,MAAM,aAAa,OAAO,KAAK,cAAc,EAAE,KAAK,CAAC,MAAM;AAAA,IACzD,MAAM,QAAQ,EAAE,MAAM,GAAG;AAAA,IACzB,OAAO,MAAM,WAAW,KAAK,SAAS,MAAM,IAAI,EAAE,MAAM;AAAA,GACzD;AAAA,EAED,MAAM,QAAiB,aAClB,eAAe,cAChB;AAAA,EAGJ,IAAI,eAAe,aAAa,gBAAgB,WAAW;AAAA,IACzD,QAAQ,KACN,iFACE,4FACA,mDACJ;AAAA,IACA,MAAM,QAAO,MAAM,eAAe,QAAQ;AAAA,MACxC;AAAA,MACA,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,QAAQ,KACN,yDAAyD,OAC3D;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,qBAAqB,cAAc;AAAA,EACzC,MAAM,sBAAsB,eAAe;AAAA,EAE3C,MAAM,OAAO,MAAM,eAAe,QAAQ;AAAA,IACxC;AAAA,IACA,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,cAAc;AAAA,EAChB,CAAC;AAAA,EAED,QAAQ,KACN,0CAAyC,oCACvC,UAAU,qCAAqC,OAAO,MAAM,aAAa,MAC7E;AAAA,EAEA,OAAO;AAAA;AAyBF,SAAS,WAAW,CACzB,QACqC;AAAA,EAErC,MAAM,cAAc,QAAQ,IAAI;AAAA,EAChC,MAAM,oBAA8B,cAChC,YACG,MAAM,GAAG,EACT,IAAI,CAAC,MAAc,EAAE,KAAK,CAAC,EAC3B,OAAO,OAAO,IACjB,CAAC,GAAG,0BAA0B;AAAA,EAGlC,MAAM,uBAAuB,UAAU,QAAQ,IAAI,uBAAuB;AAAA,EAC1E,MAAM,0BAA0B,UAAU,QAAQ,IAAI,oBAAoB;AAAA,EAE1E,OAAO,iBAAiB,QAAQ;AAAA,IAC9B;AAAA,OACI,yBAAyB,aAAa;AAAA,MACxC,kBAAkB;AAAA,IACpB;AAAA,OACI,4BAA4B,aAAa;AAAA,MAC3C,qBAAqB;AAAA,IACvB;AAAA,IACA,SAAS;AAAA,IACT,YAAY;AAAA,EACd,CAAC;AAAA;;ACtVI,IAAK;AAAA,CAAL,CAAK,gBAAL;AAAA,EACL,qCAAU,KAAV;AAAA,EACA,oCAAS,KAAT;AAAA,EACA,uCAAY,KAAZ;AAAA,EACA,wCAAa,KAAb;AAAA,EACA,sCAAW,KAAX;AAAA,EACA,uCAAY,KAAZ;AAAA,GANU;;;ACHZ;AAAA,yBAEE;AAAA,wBAEA;AAAA;AAQK,IAAM,qBAGT;AAAA,EAEF,QAAQ;AAAA,IACN,YAAY;AAAA,IACZ,MAAM;AAAA,EACR;AAAA,EAEA,SAAS;AAAA,IACP,YAAY;AAAA,IACZ,MAAM;AAAA,EACR;AACF;AAQO,SAAS,sBAAsB,CACpC,UACA,SACS;AAAA,EACT,IAAI,SAAS,WAAW,IAAI,KAAK,SAAS,WAAW,IAAI;AAAA,IACvD,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,mBAAmB,QAAQ,SAAS;AAAA,EAC3D,IAAI,CAAC,gBAAgB;AAAA,IACnB,MAAM,IAAI,MAAM,8CAA8C,SAAS;AAAA,EACzE;AAAA,EAEA,MAAM,UAAU,eAAe;AAAA,EAC/B,IAAI,CAAC,WAAW,YAAY,8CAA8C;AAAA,IACxE,MAAM,IAAI,MACR,aAAa,mCAAmC,oDAClD;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAQF,SAAS,sBAAsB,CAAC,cAAwB;AAAA,EAC7D,OAAO,qBAAoB,oBAAmB,SAAS,GAAG,CAAC,YAAY,CAAC;AAAA;AAOnE,SAAS,4BAA4B,GAAQ;AAAA,EAClD,OAAO;AAAA;;;ACxDT,IAAM,uBAAuB;AAAA,EAC3B;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,kBAAkB,MAAM,UAAU;AAAA,MAC1C,EAAE,MAAM,eAAe,MAAM,UAAU;AAAA,MACvC,EAAE,MAAM,gBAAgB,MAAM,UAAU;AAAA,MACxC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,iBAAiB,MAAM,QAAQ;AAAA,MACvC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,oBAAoB,MAAM,UAAU;AAAA,IAC9C;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,SAAS,MAAM,UAAU,CAAC;AAAA,EAC9C;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,EAAE,MAAM,SAAS,MAAM,WAAW,SAAS,KAAK;AAAA,MAChD,EAAE,MAAM,SAAS,MAAM,WAAW,SAAS,KAAK;AAAA,MAChD,EAAE,MAAM,UAAU,MAAM,WAAW,SAAS,KAAK;AAAA,MACjD,EAAE,MAAM,SAAS,MAAM,WAAW,SAAS,MAAM;AAAA,MACjD,EAAE,MAAM,iBAAiB,MAAM,WAAW,SAAS,MAAM;AAAA,MACzD,EAAE,MAAM,cAAc,MAAM,WAAW,SAAS,MAAM;AAAA,MACtD,EAAE,MAAM,eAAe,MAAM,WAAW,SAAS,MAAM;AAAA,MACvD,EAAE,MAAM,YAAY,MAAM,WAAW,SAAS,MAAM;AAAA,MACpD,EAAE,MAAM,YAAY,MAAM,WAAW,SAAS,MAAM;AAAA,IACtD;AAAA,EACF;AACF;AAEA,IAAM,gBAAgB;AAAA,EACpB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,SAAS,MAAM,QAAQ,CAAC;AAAA,IACzC,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,YAAY,MAAM,QAAQ,CAAC;AAAA,IAC5C,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,cAAc,MAAM,OAAO,CAAC;AAAA,IAC7C,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,MAClC,EAAE,MAAM,kBAAkB,MAAM,UAAU;AAAA,MAC1C,EAAE,MAAM,eAAe,MAAM,UAAU;AAAA,MACvC,EAAE,MAAM,gBAAgB,MAAM,UAAU;AAAA,MACxC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,aAAa,MAAM,UAAU;AAAA,MACrC,EAAE,MAAM,oBAAoB,MAAM,UAAU;AAAA,MAC5C,EAAE,MAAM,WAAW,MAAM,QAAQ;AAAA,MACjC,EAAE,MAAM,gBAAgB,MAAM,UAAU;AAAA,IAC1C;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,QAAQ,CAAC;AAAA,EACvC;AACF;AAEA,SAAS,YAAY,CAAC,OAA4B;AAAA,EAChD,MAAM,SAAS,OAAO,KAAK;AAAA,EAC3B,IAAI,CAAC,OAAO,UAAU,MAAM,KAAK,EAAE,UAAU,aAAa;AAAA,IACxD,MAAM,IAAI,MAAM,+BAA+B,OAAO,KAAK,GAAG;AAAA,EAChE;AAAA,EACA,OAAO;AAAA;AAGT,IAAM,kBAAkB;AAAA,EACtB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,EACtC;AACF;AAGA,IAAM,YAAqB;AAAA;AAQpB,MAAM,kBAAkB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,WAAW,CAAC,QAKT;AAAA,IACD,KAAK,eAAe,OAAO;AAAA,IAC3B,KAAK,eAAe,OAAO;AAAA,IAC3B,KAAK,iBAAiB,OAAO;AAAA,IAC7B,KAAK,UAAU,OAAO;AAAA;AAAA,OAQlB,OAAM,CAAC,QAAoD;AAAA,IAC/D,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,QAAQ,OAAO,SAAS;AAAA,IAC9B,MAAM,kBAAkB,uBACtB,OAAO,UACP,KAAK,OACP;AAAA,IACA,MAAM,eAAe,OAAO,gBAAgB,6BAA6B;AAAA,IAEzE,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,OAAO,OAAO,QAAQ;AAAA,QACtB,OAAO,OAAO,eAAe;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,MAAM,KAAK,aAAa,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAAA,IAGlE,MAAM,eAAgB,MAAM,KAAK,aAAa,aAAa;AAAA,MACzD,SAAS,KAAK;AAAA,MACd,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,OAAO,OAAO,QAAQ;AAAA,QACtB,OAAO,OAAO,eAAe;AAAA,MAC/B;AAAA,IACF,CAAC;AAAA,IAED,OAAO,EAAE,SAAS,cAAc,OAAO;AAAA;AAAA,OAQnC,KAAI,CAAC,cAAuB,eAA0C;AAAA,IAC1E,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,UAAU,MAAM,KAAK,WAAW,YAAY;AAAA,IAGlD,MAAM,KAAK,aAAa,cAAc;AAAA,MACpC,SAAS,QAAQ;AAAA,MACjB,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,cAAc,aAAa;AAAA,MAClC;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,MACP;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,OAOZ,OAAM,CAAC,cAA0C;AAAA,IACrD,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,UAAU,MAAM,KAAK,WAAW,YAAY;AAAA,IAGlD,MAAM,KAAK,aAAa,cAAc;AAAA,MACpC,SAAS,QAAQ;AAAA,MACjB,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,cAAc,QAAQ,WAAW;AAAA,MACxC;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,MACP;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,OAQZ,QAAO,CAAC,cAAuB,OAA+B;AAAA,IAClE,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,KAAK;AAAA,MACZ;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,OAOZ,OAAM,CAAC,cAA0C;AAAA,IACrD,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,MACP;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,OAQZ,UAAS,CAAC,cAAuB,UAAkC;AAAA,IACvE,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,QAAQ;AAAA,MACf;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,OAOZ,OAAM,CAAC,cAA0C;AAAA,IACrD,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,MACP;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,OAOZ,eAAc,CAAC,cAA0C;AAAA,IAC7D,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,MAAM,oCAAoC;AAAA,IAElE,MAAM,SAAS,MAAM,KAAK,aAAa,cAAc;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,MACP;AAAA,MACA,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,OAAO;AAAA;AAAA,OAOZ,WAAU,CAAC,cAA+C;AAAA,IAC9D,MAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,IACT,CAAC;AAAA,IAED;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE;AAAA,IAcJ,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACF;AAAA;AAAA,OAOI,UAAS,CAAC,cAA4C;AAAA,IAC1D,MAAM,SAAS,MAAM,KAAK,aAAa,aAAa;AAAA,MAClD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC;AAAA,IACT,CAAC;AAAA,IAED,OAAO,aAAa,MAAM;AAAA;AAE9B;;ACxYA,IAAI,aAAa;AACjB,SAAS,MAAM,CAAC,QAAwB;AAAA,EACtC,OAAO,GAAG,UAAU,KAAK,IAAI,KAAK,EAAE;AAAA;AAAA;AAK/B,MAAM,eAAe;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,WAAW,CAAC,QAA8B;AAAA,IACxC,KAAK,SAAS;AAAA,IACd,KAAK,YAAY,IAAI,KAClB,OAAO,qBAAqB,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAC7D;AAAA,IACA,KAAK,cAAc,CAAC;AAAA,IACpB,KAAK,WAAW,CAAC;AAAA,IACjB,KAAK,SAAS,IAAI;AAAA;AAAA,OASd,MAAK,CAAC,SAA+C;AAAA,IACzD,IAAI;AAAA,MACF,OAAO,MAAM,KAAK,OAAO,OAAO;AAAA,MAChC,OAAO,KAAc;AAAA,MACrB,MAAM,SAAS,sCAAsC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MACpG,MAAM,SAAuB,EAAE,QAAQ,YAAY,OAAO;AAAA,MAC1D,MAAM,KAAK,IAAI,SAAS,MAAM,EAAE,MAAM,MAAM,EAE3C;AAAA,MACD,OAAO;AAAA;AAAA;AAAA,OAOL,IAAG,CAAC,SAAwB,QAAqC;AAAA,IACrE,MAAM,QAAoB;AAAA,MACxB,IAAI,OAAO,OAAO;AAAA,MAClB,WAAW,QAAQ,aAAa,IAAI,KAAK,EAAE,YAAY;AAAA,MACvD,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,OAAO;AAAA,MACf,QAAQ,OAAO;AAAA,MACf,SAAS,OAAO;AAAA,IAClB;AAAA,IACA,KAAK,SAAS,KAAK,KAAK;AAAA;AAAA,EAI1B,oBAAoB,GAAa;AAAA,IAC/B,OAAO,MAAM,KAAK,KAAK,SAAS;AAAA;AAAA,EAIlC,WAAW,CAAC,SAAuB;AAAA,IACjC,KAAK,UAAU,IAAI,QAAQ,YAAY,CAAC;AAAA;AAAA,EAI1C,WAAW,GAAiB;AAAA,IAC1B,OAAO,CAAC,GAAG,KAAK,QAAQ;AAAA;AAAA,EAM1B,YAAY,CAAC,SAA0B;AAAA,IACrC,MAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AAAA,IACrC,IAAI,CAAC;AAAA,MAAO,OAAO;AAAA,IACnB,MAAM,WAAW;AAAA,IACjB,OAAO;AAAA;AAAA,EAIT,WAAW,CAAC,SAA0B;AAAA,IACpC,MAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AAAA,IACrC,IAAI,CAAC;AAAA,MAAO,OAAO;AAAA,IACnB,MAAM,WAAW;AAAA,IACjB,OAAO;AAAA;AAAA,EAIT,gBAAgB,GAAiB;AAAA,IAC/B,OAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC,EAAE,OACtC,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,EAAE,QAC3B;AAAA;AAAA,EAIF,YAAY,GAAiB;AAAA,IAC3B,OAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC;AAAA;AAAA,OAK1B,OAAM,CAAC,SAA+C;AAAA,IAElE,IAAI,KAAK,UAAU,OAAO,GAAG;AAAA,MAC3B,MAAM,WAAW,QAAQ,SAAS,YAAY;AAAA,MAC9C,IAAI,CAAC,KAAK,UAAU,IAAI,QAAQ,GAAG;AAAA,QACjC,MAAM,UAAuB;AAAA,UAC3B,QAAQ;AAAA,UACR,QAAQ,aAAa,QAAQ;AAAA,QAC/B;AAAA,QACA,MAAM,KAAK,IAAI,SAAS,OAAM;AAAA,QAC9B,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAGA,IAAI,KAAK,OAAO,YAAY;AAAA,MAC1B,QAAQ,WAAW,aAAa,KAAK,OAAO;AAAA,MAC5C,MAAM,MAAM,KAAK,IAAI;AAAA,MACrB,MAAM,cAAc,MAAM;AAAA,MAG1B,KAAK,cAAc,KAAK,YAAY,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW;AAAA,MAErE,MAAM,QAAQ,KAAK,YAAY,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,QAAQ,CAAC;AAAA,MACnE,IAAI,QAAQ,QAAQ,SAAS,WAAW;AAAA,QACtC,MAAM,UAAuB;AAAA,UAC3B,QAAQ;AAAA,UACR,QAAQ,qCAAqC,cAAc,wBAAwB,QAAQ;AAAA,QAC7F;AAAA,QACA,MAAM,KAAK,IAAI,SAAS,OAAM;AAAA,QAC9B,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAGA,IACE,KAAK,OAAO,mBAAmB,aAC/B,QAAQ,UAAU,KAAK,OAAO,gBAC9B;AAAA,MACA,MAAM,UAAU,OAAO,OAAO;AAAA,MAC9B,MAAM,QAAoB;AAAA,QACxB;AAAA,QACA;AAAA,QACA,UAAU,QAAQ,aAAa,IAAI,KAAK,EAAE,YAAY;AAAA,QACtD,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AAAA,MACA,KAAK,OAAO,IAAI,SAAS,KAAK;AAAA,MAE9B,MAAM,UAAuB;AAAA,QAC3B,QAAQ;AAAA,QACR,QAAQ,UAAU,QAAQ,2CAA2C,KAAK,OAAO;AAAA,QACjF;AAAA,MACF;AAAA,MACA,MAAM,KAAK,IAAI,SAAS,OAAM;AAAA,MAC9B,OAAO;AAAA,IACT;AAAA,IAGA,IAAI,KAAK,OAAO,YAAY;AAAA,MAC1B,KAAK,YAAY,KAAK,EAAE,QAAQ,QAAQ,QAAQ,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,IAClE;AAAA,IAEA,MAAM,SAAuB,EAAE,QAAQ,WAAW;AAAA,IAClD,MAAM,KAAK,IAAI,SAAS,MAAM;AAAA,IAC9B,OAAO;AAAA;AAEX;;AChLA,IAAI,UAAU;AACd,SAAS,OAAM,CAAC,QAAwB;AAAA,EACtC,WAAW;AAAA,EACX,OAAO,GAAG,UAAU,KAAK,IAAI,KAAK;AAAA;AAGpC,SAAS,MAAM,CAAC,OAAwB;AAAA,EACtC,OAAO,SAAS,IAAI,KAAK,EAAE,YAAY;AAAA;AAGzC,SAAS,kBAAkB,CACzB,QACyB;AAAA,EACzB,OAAO;AAAA,OACF;AAAA,IACH,UAAU,OAAO,WAAW,KAAK,OAAO,SAAS,IAAI;AAAA,EACvD;AAAA;AAGF,SAAS,eAAe,CAAC,QAAoD;AAAA,EAC3E,OAAO;AAAA,OACF;AAAA,IACH,UAAU,OAAO,WAAW,KAAK,OAAO,SAAS,IAAI;AAAA,EACvD;AAAA;AAGF,SAAS,UAAU,CAAC,QAA8C;AAAA,EAChE,OAAO,KAAK,OAAO;AAAA;AAAA;AAGd,MAAM,kBAAkB;AAAA,EACrB,iBAAiB,IAAI;AAAA,EACrB,cAAc,IAAI;AAAA,EAClB,SAAS,IAAI;AAAA,EAErB,SAAS,CAAC,SAA4D;AAAA,IACpE,IAAI,QAAQ,aAAa,IAAI;AAAA,MAC3B,MAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAAA,IAEA,MAAM,kBAAkB,QAAQ,mBAAmB,QAAO,WAAW;AAAA,IACrE,IAAI,KAAK,eAAe,IAAI,eAAe,GAAG;AAAA,MAC5C,MAAM,IAAI,MAAM,iCAAiC,iBAAiB;AAAA,IACpE;AAAA,IAEA,MAAM,SAAkC;AAAA,MACtC;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,UAAU,QAAQ;AAAA,MAClB,SAAS,QAAQ;AAAA,MACjB,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,MACf,WAAW,QAAQ;AAAA,MACnB,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,iBAAiB,QAAQ;AAAA,MACzB,cAAc,OAAO,QAAQ,YAAY;AAAA,MACzC,QAAQ;AAAA,MACR,UAAU,QAAQ,WAAW,KAAK,QAAQ,SAAS,IAAI;AAAA,IACzD;AAAA,IAEA,KAAK,eAAe,IAAI,iBAAiB,MAAM;AAAA,IAC/C,KAAK,YAAY,IAAI,iBAAiB,CAAC,CAAC;AAAA,IACxC,KAAK,OAAO,IAAI,iBAAiB;AAAA,MAC/B;AAAA,QACE,SAAS,QAAO,aAAa;AAAA,QAC7B;AAAA,QACA,MAAM;AAAA,QACN,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO;AAAA,QACtB,cAAc;AAAA,QACd,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,IAED,OAAO,mBAAmB,MAAM;AAAA;AAAA,EAGlC,gBAAgB,CACd,iBACA,QACA,UAAiC,CAAC,GACb;AAAA,IACrB,MAAM,OAAO,KAAK,qBAAqB,eAAe;AAAA,IAEtD,IAAI,KAAK,WAAW,aAAa,KAAK,WAAW,YAAY;AAAA,MAC3D,MAAM,IAAI,MAAM,uCAAuC,iBAAiB;AAAA,IAC1E;AAAA,IACA,IAAI,UAAU,IAAI;AAAA,MAChB,MAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAAA,IACA,IAAI,SAAS,KAAK,iBAAiB;AAAA,MACjC,MAAM,IAAI,MACR,qBAAqB,8CAA8C,KAAK,iBAC1E;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,OAAO,QAAQ,SAAS;AAAA,IAC1C,MAAM,aAAmC;AAAA,MACvC,cAAc,QAAO,iBAAiB;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ;AAAA,MAChB,WAAW,QAAQ;AAAA,MACnB,UAAU,QAAQ,WAAW,KAAK,QAAQ,SAAS,IAAI;AAAA,IACzD;AAAA,IAEA,KAAK,iBAAiB;AAAA,IACtB,KAAK,mBAAmB;AAAA,IACxB,KAAK,SAAS,KAAK,oBAAoB,KAAK,YAAY;AAAA,IAExD,MAAM,iBAAiB,KAAK,YAAY,IAAI,eAAe;AAAA,IAC3D,IAAI,CAAC,gBAAgB;AAAA,MACnB,MAAM,IAAI,MACR,6DAA6D,iBAC/D;AAAA,IACF;AAAA,IACA,eAAe,KAAK,UAAU;AAAA,IAE9B,MAAM,SAAS,KAAK,OAAO,IAAI,eAAe;AAAA,IAC9C,IAAI,CAAC,QAAQ;AAAA,MACX,MAAM,IAAI,MACR,wDAAwD,iBAC1D;AAAA,IACF;AAAA,IACA,OAAO,KAAK;AAAA,MACV,SAAS,QAAO,aAAa;AAAA,MAC7B;AAAA,MACA,MAAM;AAAA,MACN,WAAW;AAAA,MACX,eAAe,CAAC;AAAA,MAChB,cAAc;AAAA,MACd,gBAAgB,CAAC;AAAA,MACjB,QAAQ,QAAQ;AAAA,MAChB,WAAW,QAAQ;AAAA,IACrB,CAAC;AAAA,IAED,IAAI,QAAQ,UAAU;AAAA,MACpB,KAAK,sBAAsB,iBAAiB,WAAW,QAAQ,SAAS;AAAA,IAC1E;AAAA,IAEA,OAAO,KAAK,YAAY,eAAe;AAAA;AAAA,EAGzC,qBAAqB,CACnB,iBACA,aACA,WACyB;AAAA,IACzB,MAAM,OAAO,KAAK,qBAAqB,eAAe;AAAA,IACtD,MAAM,SAAS,KAAK,OAAO,IAAI,eAAe;AAAA,IAC9C,IAAI,CAAC,QAAQ;AAAA,MACX,MAAM,IAAI,MACR,wDAAwD,iBAC1D;AAAA,IACF;AAAA,IACA,MAAM,YAAY,OAAO,WAAW;AAAA,IAEpC,IAAI,KAAK,WAAW,aAAa,KAAK,WAAW,YAAY;AAAA,MAC3D,KAAK,cAAc,KAAK,eAAe;AAAA,MACvC,OAAO,mBAAmB,IAAI;AAAA,IAChC;AAAA,IAEA,MAAM,WAAW,KAAK;AAAA,IACtB,KAAK,kBAAkB;AAAA,IACvB,KAAK,kBAAkB;AAAA,IACvB,KAAK,cAAc;AAAA,IACnB,KAAK,SAAS,KAAK,gBAAgB,KAAK,YAAY;AAAA,IAEpD,IAAI,WAAW,IAAI;AAAA,MACjB,OAAO,KAAK;AAAA,QACV,SAAS,QAAO,aAAa;AAAA,QAC7B;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA,eAAe,CAAC;AAAA,QAChB,cAAc;AAAA,QACd,gBAAgB;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,OAAO,mBAAmB,IAAI;AAAA;AAAA,EAGhC,gBAAgB,CAAC,iBAAyD;AAAA,IACxE,MAAM,OAAO,KAAK,eAAe,IAAI,eAAe;AAAA,IACpD,OAAO,OAAO,mBAAmB,IAAI,IAAI;AAAA;AAAA,EAG3C,kBAAkB,GAA8B;AAAA,IAC9C,OAAO,MAAM,KAAK,KAAK,eAAe,OAAO,CAAC,EAAE,IAAI,kBAAkB;AAAA;AAAA,EAGxE,cAAc,CAAC,iBAAiD;AAAA,IAC9D,QAAQ,KAAK,YAAY,IAAI,eAAe,KAAK,CAAC,GAAG,IAAI,eAAe;AAAA;AAAA,EAG1E,qBAAqB,CAAC,iBAA8C;AAAA,IAClE,QAAQ,KAAK,OAAO,IAAI,eAAe,KAAK,CAAC,GAAG,IAAI,UAAU;AAAA;AAAA,EAGhE,WAAW,CAAC,iBAA8C;AAAA,IACxD,OAAO;AAAA,MACL,eAAe,mBACb,KAAK,qBAAqB,eAAe,CAC3C;AAAA,MACA,aAAa,KAAK,eAAe,eAAe;AAAA,MAChD,cAAc,KAAK,sBAAsB,eAAe;AAAA,IAC1D;AAAA;AAAA,EAGF,iBAAiB,CAAC,iBAAiC;AAAA,IACjD,OAAO,KAAK,sBAAsB,eAAe,EAAE,OACjD,CAAC,KAAK,UAAU,MAAM,MAAM,gBAC5B,EACF;AAAA;AAAA,EAGF,iBAAiB,CAAC,iBAAiC;AAAA,IACjD,OAAO,KAAK,sBAAsB,eAAe,EAAE,OACjD,CAAC,KAAK,UAAU,MAAM,MAAM,eAC5B,EACF;AAAA;AAAA,EAGM,oBAAoB,CAC1B,iBACyB;AAAA,IACzB,MAAM,OAAO,KAAK,eAAe,IAAI,eAAe;AAAA,IACpD,IAAI,CAAC,MAAM;AAAA,MACT,MAAM,IAAI,MAAM,0BAA0B,iBAAiB;AAAA,IAC7D;AAAA,IACA,OAAO;AAAA;AAEX;;ACjQA,IAAM,gBAA8B;AAAA,EAClC;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AACF;AAAA;AAIO,MAAM,cAAc;AAAA,EACjB;AAAA,EAEA;AAAA,EAEA;AAAA,EAER,WAAW,CAAC,SAIT;AAAA,IACD,KAAK,QAAQ,SAAS,SAAS;AAAA,IAC/B,KAAK,wBAAwB,SAAS,yBAAyB;AAAA,IAC/D,KAAK,yBAAyB,SAAS,0BAA0B;AAAA;AAAA,EAMnE,KAAK,CAAC,SAA0C;AAAA,IAC9C;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE;AAAA,IAGJ,MAAM,aAAa,KAAK,QAAQ,YAAY;AAAA,IAC5C,IAAI,YAAY,WAAW,UAAU,mBAAmB,QAAQ;AAAA,MAG9D,OAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,sBAAsB;AAAA,QACtB,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IAGA,IAAI,mBAAmB,UAAU;AAAA,MAC/B,MAAM,aAAa,KAAK,QAAQ,aAAa;AAAA,MAC7C,IAAI,YAAY,WAAW,QAAQ;AAAA,QACjC,OAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,sBAAsB;AAAA,UACtB,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IAEF;AAAA,IAGA,IACE,qBACC,kBAAkB,MAAM,KAAK,wBAC9B;AAAA,MACA,MAAM,WAAU,KAAK,QAAQ,KAAK;AAAA,MAClC,IAAI,UAAS,WAAW,QAAQ;AAAA,QAC9B,OAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,2BAA2B;AAAA,UACnC,sBAAsB;AAAA,UACtB,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IAGA,IAAI,SAAS,KAAK,yBAAyB,eAAe,OAAO;AAAA,MAC/D,MAAM,WAAW,KAAK,QAAQ,MAAM;AAAA,MACpC,IAAI,UAAU,WAAW,QAAQ;AAAA,QAC/B,OAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,mBAAmB,SAAS,KAAW,QAAQ,CAAC;AAAA,UACxD,sBAAsB;AAAA,UACtB,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IAGA,MAAM,UAAU,KAAK,QAAQ,KAAK;AAAA,IAClC,IAAI,SAAS,WAAW,UAAU,WAAW,QAAQ,aAAa,IAAI;AAAA,MACpE,OAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,YAAY,SAAS,KAAW,QAAQ,CAAC;AAAA,QACjD,sBAAsB;AAAA,QACtB,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IAGA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,sBAAsB;AAAA,MACtB,QAAQ,KAAK,QAAQ,MAAM,GAAG,WAAW;AAAA,IAC3C;AAAA;AAAA,EAMF,YAAY,GAAiB;AAAA,IAC3B,OAAO,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AAAA;AAAA,EAMrD,UAAU,CAAC,MAA4B;AAAA,IACrC,OAAO,KAAK,QAAQ,IAAI,GAAG,WAAW;AAAA;AAAA,EAGhC,OAAO,CAAC,MAA2C;AAAA,IACzD,OAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA;AAEjD;;ACnLO,SAAS,KAAK,CAAC,QAAyB,UAA0B;AAAA,EACvE,IAAI,OAAO,WAAW;AAAA,IAAU,OAAO;AAAA,EAEvC,MAAM,MAAM,OAAO,KAAK;AAAA,EACxB,IAAI,CAAC,OAAO,QAAQ;AAAA,IAAK,OAAO;AAAA,EAGhC,IAAI,CAAC,kBAAkB,KAAK,GAAG,GAAG;AAAA,IAChC,MAAM,IAAI,MAAM,iCAAiC,SAAS;AAAA,EAC5D;AAAA,EAEA,MAAM,WAAW,IAAI,WAAW,GAAG;AAAA,EACnC,MAAM,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI;AAAA,EAEtC,MAAM,WAAW,IAAI,QAAQ,GAAG;AAAA,EAChC,IAAI,aAAa,IAAI;AAAA,IAEnB,MAAM,SAAS,OAAO,GAAG,IAAI,OAAO,OAAO,QAAQ;AAAA,IACnD,OAAO,WAAW,CAAC,SAAS;AAAA,EAC9B;AAAA,EAEA,MAAM,UAAU,IAAI,MAAM,GAAG,QAAQ;AAAA,EACrC,IAAI,WAAW,IAAI,MAAM,WAAW,CAAC;AAAA,EAGrC,IAAI,SAAS,SAAS,UAAU;AAAA,IAC9B,WAAW,SAAS,MAAM,GAAG,QAAQ;AAAA,EACvC,EAAO;AAAA,IACL,WAAW,SAAS,OAAO,UAAU,GAAG;AAAA;AAAA,EAG1C,MAAM,MACJ,OAAO,WAAW,GAAG,IAAI,OAAO,OAAO,QAAQ,IAAI,OAAO,QAAQ;AAAA,EAEpE,OAAO,WAAW,CAAC,MAAM;AAAA;AAepB,SAAS,OAAO,CAAC,QAAgB,UAA0B;AAAA,EAChE,IAAI,aAAa;AAAA,IAAG,OAAO,OAAO,SAAS;AAAA,EAE3C,MAAM,WAAW,SAAS;AAAA,EAC1B,MAAM,MAAM,WAAW,CAAC,SAAS;AAAA,EAEjC,MAAM,UAAU,OAAO,OAAO,QAAQ;AAAA,EACtC,MAAM,UAAU,MAAM;AAAA,EACtB,MAAM,UAAU,MAAM;AAAA,EAGtB,MAAM,UAAU,QAAQ,SAAS,EAAE,SAAS,UAAU,GAAG;AAAA,EAGzD,MAAM,UAAU,QAAQ,QAAQ,OAAO,EAAE,KAAK;AAAA,EAE9C,MAAM,SAAS,GAAG,WAAW;AAAA,EAC7B,OAAO,WAAW,IAAI,WAAW;AAAA;AAe5B,SAAS,aAAa,CAC3B,QACA,OACA,iBACQ;AAAA,EACR,MAAM,QAAQ,QAAQ,QAAQ,MAAM,QAAQ;AAAA,EAC5C,MAAM,aAAa,oBAAoB,MAAM,YAAY,IAAI,IAAI;AAAA,EAGjE,OAAO,SAAS,WAAW,MAAM,MAAM,MAAM,GAAG;AAAA,EAChD,MAAM,SAAS,SAAS,OAAO,YAAY,GAAG,EAAE,MAAM,GAAG,UAAU;AAAA,EAGnE,OAAO,GAAG,WAAW,UAAU,MAAM;AAAA;AAUhC,SAAS,WAAW,CAAC,QAAyB,UAA0B;AAAA,EAC7E,IAAI,OAAO,WAAW;AAAA,IAAU,OAAO;AAAA,EACvC,OAAO,MAAM,QAAQ,QAAQ;AAAA;;AC5H/B;AA0BO,IAAM,gBAAgB;AAAA,EAE3B,KAAK;AAAA,EAGL,MAAM;AAAA,EAGN,MAAM;AAAA,EAGN,KAAK;AAAA,EAGL,KAAK;AAAA,EAGL,MAAM;AAAA,EAGN,SAAS;AAAA,EAGT,MAAM;AAAA,EAGN,MAAM;AAAA,EAGN,MAAM;AACR;AAYO,IAAM,wBAA2D;AAAA,EACtE,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAIA,eAAe,cAAc,GAA8B;AAAA,EACzD,IAAI;AAAA,IACF,MAAM,MAAM,MAAa;AAAA,IACzB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM,IAAI,MACR,gFACF;AAAA;AAAA;AAIJ,eAAe,YAAY,GAA4B;AAAA,EACrD,IAAI;AAAA,IACF,MAAM,MAAM,MAAa;AAAA,IACzB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM,IAAI,MACR,wGACF;AAAA;AAAA;AAAA;AAmCG,MAAM,aAAa;AAAA,EACP;AAAA,EACA;AAAA,EAGT,cAA+C;AAAA,EAC/C,WAAyC;AAAA,EAEjD,WAAW,CAAC,SAA6B,CAAC,GAAG;AAAA,IAC3C,KAAK,SAAS,OAAO,UAAU;AAAA,IAC/B,KAAK,SAAS;AAAA;AAAA,OAGF,cAAa,GAAG;AAAA,IAC5B,IAAI,KAAK;AAAA,MAAa,OAAO,KAAK;AAAA,IAClC,QAAQ,eAAe,MAAM,eAAe;AAAA,IAC5C,KAAK,cAAc,IAAI,WAAW,KAAK,QAAQ,WAAW;AAAA,IAC1D,OAAO,KAAK;AAAA;AAAA,OAGA,WAAU,GAAG;AAAA,IACzB,IAAI,KAAK;AAAA,MAAU,OAAO,KAAK;AAAA,IAC/B,QAAQ,YAAY,MAAM,eAAe;AAAA,IAEzC,IAAI,KAAK,OAAO,cAAc;AAAA,MAC5B,KAAK,WAAW,QAAQ,cAAc,KAAK,OAAO,YAAY;AAAA,IAChE,EAAO,SAAI,KAAK,OAAO,kBAAkB;AAAA,MACvC,MAAM,UAAU,KAAK,OAAO,KAAK,OAAO,gBAAgB;AAAA,MACxD,KAAK,WAAW,QAAQ,cAAc,OAAO;AAAA,IAC/C,EAAO;AAAA,MACL,MAAM,IAAI,MACR,wFACF;AAAA;AAAA,IAGF,OAAO,KAAK;AAAA;AAAA,OAIR,aAAY,GAAoB;AAAA,IACpC,MAAM,KAAK,MAAM,KAAK,WAAW;AAAA,IACjC,OAAO,GAAG,UAAU,SAAS;AAAA;AAAA,OAOzB,cAAa,CAAC,SAA6C;AAAA,IAC/D,QAAQ,cAAc,MAAM,eAAe;AAAA,IAC3C,MAAM,aAAa,MAAM,KAAK,cAAc;AAAA,IAE5C,IAAI;AAAA,IACJ,IAAI,SAAS;AAAA,MACX,SAAS,IAAI,UAAU,OAAO;AAAA,IAChC,EAAO;AAAA,MACL,MAAM,KAAK,MAAM,KAAK,WAAW;AAAA,MACjC,SAAS,GAAG;AAAA;AAAA,IAGd,MAAM,WAAW,MAAM,WAAW,WAAW,MAAM;AAAA,IACnD,MAAM,aAAa,OAAO,QAAQ;AAAA,IAClC,MAAM,OAAO,WAAW,KAAK,QAAQ,CAAC,EAAE,QAAQ,UAAU,EAAE;AAAA,IAE5D,OAAO,EAAE,YAAY,IAAI;AAAA;AAAA,OAQrB,mBAAkB,CACtB,aACA,OAC2B;AAAA,IAC3B,QAAQ,cAAc,MAAM,eAAe;AAAA,IAC3C,MAAM,WAAW,MAAM,aAAa;AAAA,IACpC,MAAM,aAAa,MAAM,KAAK,cAAc;AAAA,IAE5C,IAAI;AAAA,IACJ,IAAI,OAAO;AAAA,MACT,cAAc,IAAI,UAAU,KAAK;AAAA,IACnC,EAAO;AAAA,MACL,MAAM,KAAK,MAAM,KAAK,WAAW;AAAA,MACjC,cAAc,GAAG;AAAA;AAAA,IAGnB,MAAM,aAAa,IAAI,UAAU,WAAW;AAAA,IAG5C,MAAM,MAAM,MAAM,SAAS,0BACzB,YACA,WACF;AAAA,IAEA,IAAI,aAAa;AAAA,IACjB,IAAI,WAAW;AAAA,IAEf,IAAI;AAAA,MACF,MAAM,cAAc,MAAM,SAAS,WAAW,YAAY,GAAG;AAAA,MAC7D,aAAa,YAAY;AAAA,MAGzB,MAAM,WAAW,MAAM,SAAS,QAAQ,YAAY,UAAU;AAAA,MAC9D,WAAW,SAAS;AAAA,MACpB,MAAM;AAAA,IAIR,MAAM,gBACH,OAAO,UAAU,IAAI,MAAM,UACzB,QAAQ,QAAQ,EAChB,QAAQ,UAAU,EAAE,KAAK;AAAA,IAE9B,OAAO,EAAE,MAAM,aAAa,YAAY,cAAc,SAAS;AAAA;AAAA,OAQ3D,QAAO,CAAC,IAAY,QAAkD;AAAA,IAC1E,QAAQ,WAAW,eAAe,aAAa,8BAC7C,MAAM,eAAe;AAAA,IACvB,MAAM,aAAa,MAAM,KAAK,cAAc;AAAA,IAC5C,MAAM,UAAU,MAAM,KAAK,WAAW;AAAA,IAEtC,IAAI;AAAA,IACJ,IAAI,OAAO,WAAW,UAAU;AAAA,MAE9B,MAAM,QAAQ,OAAO,MAAM,GAAG;AAAA,MAC9B,MAAM,UAAU,OAAO,MAAM,MAAM,GAAG;AAAA,MACtC,MAAM,WAAW,MAAM,MAAM,IAAI,OAAO,GAAG,GAAG,EAAE,MAAM,GAAG,CAAC;AAAA,MAC1D,WAAW,UAAU,cAAiB,OAAO,OAAO;AAAA,IACtD,EAAO;AAAA,MACL,WAAW;AAAA;AAAA,IAGb,MAAM,cAAc,IAAI,YAAY,EAAE,IACpC,cAAc,SAAS;AAAA,MACrB,YAAY,QAAQ;AAAA,MACpB,UAAU,IAAI,UAAU,EAAE;AAAA,MAC1B,UAAU,OAAO,QAAQ;AAAA,IAC3B,CAAC,CACH;AAAA,IAEA,MAAM,YAAY,MAAM,0BAA0B,YAAY,aAAa;AAAA,MACzE;AAAA,IACF,CAAC;AAAA,IACD,OAAO,EAAE,UAAU;AAAA;AAAA,OAWf,aAAY,CAChB,IACA,QACA,aACyB;AAAA,IACzB,QAAQ,cAAc,MAAM,eAAe;AAAA,IAC3C,MAAM,WAAW,MAAM,aAAa;AAAA,IACpC,MAAM,aAAa,MAAM,KAAK,cAAc;AAAA,IAC5C,MAAM,UAAU,MAAM,KAAK,WAAW;AAAA,IAEtC,MAAM,aAAa,IAAI,UAAU,WAAW;AAAA,IAC5C,MAAM,WAAW,IAAI,UAAU,EAAE;AAAA,IAGjC,MAAM,WAAW,MAAM,SAAS,QAAQ,YAAY,UAAU;AAAA,IAC9D,QAAQ,aAAa;AAAA,IAGrB,IAAI;AAAA,IACJ,IAAI,OAAO,WAAW,UAAU;AAAA,MAC9B,MAAM,QAAQ,OAAO,MAAM,GAAG;AAAA,MAC9B,MAAM,UAAU,OAAO,MAAM,MAAM,GAAG;AAAA,MACtC,MAAM,WAAW,MAAM,MAAM,IAAI,OAAO,UAAU,GAAG,EAAE,MAAM,GAAG,QAAQ;AAAA,MACxE,YAAY,UAAU,OAAO,OAAO,QAAQ,IAAI,OAAO,OAAO;AAAA,IAChE,EAAO;AAAA,MACL,YAAY;AAAA;AAAA,IAId,MAAM,UAAU,MAAM,SAAS,0BAC7B,YACA,QAAQ,SACV;AAAA,IAGA,MAAM,QAAQ,MAAM,SAAS,0BAC3B,YACA,QACF;AAAA,IAGA,MAAM,eAAyC,CAAC;AAAA,IAGhD,MAAM,YAAY,MAAM,WAAW,eAAe,KAAK;AAAA,IACvD,IAAI,CAAC,WAAW;AAAA,MACd,aAAa,KACX,SAAS,wCACP,QAAQ,WACR,OACA,UACA,UACF,CACF;AAAA,IACF;AAAA,IAGA,aAAa,KACX,SAAS,0BACP,SACA,OACA,QAAQ,WACR,SACF,CACF;AAAA,IAEA,QAAQ,aAAa,8BAA8B,MAAM,eAAe;AAAA,IACxE,MAAM,cAAc,IAAI,YAAY,EAAE,IAAI,GAAG,YAAY;AAAA,IAEzD,MAAM,YAAY,MAAM,0BAA0B,YAAY,aAAa;AAAA,MACzE;AAAA,IACF,CAAC;AAAA,IACD,OAAO,EAAE,UAAU;AAAA;AAAA,OAMf,qBAAoB,GAExB;AAAA,IACA,MAAM,WAAW,MAAM,aAAa;AAAA,IACpC,MAAM,aAAa,MAAM,KAAK,cAAc;AAAA,IAC5C,MAAM,UAAU,MAAM,KAAK,WAAW;AAAA,IAEtC,MAAM,gBAAgB,MAAM,WAAW,8BACrC,QAAQ,WACR,EAAE,WAAW,SAAS,iBAAiB,CACzC;AAAA,IAEA,OAAO,cAAc,MAAM,IAAI,CAAC,QAA0C;AAAA,MACxE,MAAM,OAAO,IAAI,QAAQ,KAAK,OAAO;AAAA,MACrC,OAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,QAAQ,OAAO,KAAK,YAAY,MAAM;AAAA,QACtC,UAAU,KAAK,YAAY;AAAA,MAC7B;AAAA,KACD;AAAA;AAEL;AAKO,SAAS,kBAAkB,CAAC,QAA0C;AAAA,EAC3E,OAAO,IAAI,aAAa,MAAM;AAAA;;ACrZhC;AAAA,wBAGE;AAAA;AAAA,iBAKA;AAAA;AAOF,IAAM,YAAY,SAAS;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAwDD,eAAsB,SAAS,CAC7B,KACA,IACA,QACA,cACA,UAA2B,CAAC,GACb;AAAA,EACf,IAAI;AAAA,EAEJ,IAAI,OAAO,WAAW,UAAU;AAAA,IAE9B,IAAI;AAAA,IAGJ,IAAI,IAAI,WAAW,MAAM;AAAA,MACvB,MAAM,QAAQ,kBAAkB,EAAE,kBAChC,cACA,IAAI,OACN;AAAA,MACA,WACE,OAAO,YACN,MAAM,mBAAmB,IAAI,cAAc,YAAY;AAAA,IAC5D,EAAO;AAAA,MACL,WAAW,MAAM,mBAAmB,IAAI,cAAc,YAAY;AAAA;AAAA,IAGpE,YAAY,YAAY,QAAQ,QAAQ;AAAA,EAC1C,EAAO;AAAA,IACL,YAAY;AAAA;AAAA,EAGd,MAAM,OAAO,oBAAmB;AAAA,IAC9B,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,IAAI,SAAS;AAAA,EACtB,CAAC;AAAA,EAED,OAAO,IAAI,aAAa,gBAAgB;AAAA,IACtC,SAAS,IAAI;AAAA,IACb,OAAO,yBAAyB,GAAG;AAAA,IACnC,IAAI;AAAA,IACJ;AAAA,OACG,gBAAgB,OAAO;AAAA,EAC5B,CAAC;AAAA;AAWH,eAAsB,UAAU,CAC9B,KACA,IACA,QACA,UAA2B,CAAC,GACb;AAAA,EACf,MAAM,YAAY,YAAY,QAAQ,EAAE;AAAA,EAExC,OAAO,IAAI,aAAa,gBAAgB;AAAA,IACtC,SAAS,IAAI;AAAA,IACb,OAAO,yBAAyB,GAAG;AAAA,IACnC;AAAA,IACA,OAAO;AAAA,OACJ,gBAAgB,OAAO;AAAA,EAC5B,CAAC;AAAA;AAUH,eAAsB,eAAe,CACnC,KACA,cACA,QAC6B;AAAA,EAC7B,MAAM,SAAS,UAAU,IAAI;AAAA,EAG7B,OAAO,YAAY,UAAU,QAAQ,QAAQ,MAAM,QAAQ,IAAI;AAAA,IAC7D,IAAI,aAAa,aAAa;AAAA,MAC5B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,MAAM;AAAA,IACf,CAAC;AAAA,IACD,IAAI,aAAa,aAAa;AAAA,MAC5B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,IAAI,aAAa,aAAa;AAAA,MAC5B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,IACD,IAAI,aAAa,aAAa;AAAA,MAC5B,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AAAA,EAED,MAAM,eAAe,QAAQ,YAAY,QAAQ;AAAA,EACjD,MAAM,YAAY,cAAc,YAAY,EAAE,QAAQ,SAAS,CAAC;AAAA,EAEhE,OAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AASF,eAAsB,gBAAgB,CACpC,KACA,QAC8B;AAAA,EAC9B,MAAM,SAAS,UAAU,IAAI;AAAA,EAC7B,MAAM,aAAa,MAAM,IAAI,aAAa,WAAW,EAAE,SAAS,OAAO,CAAC;AAAA,EAGxE,IAAI,SAAS;AAAA,EACb,IAAI,IAAI,WAAW,MAAM;AAAA,IACvB,MAAM,SAAS,kBAAkB,EAAE,kBACjC,cACA,IAAI,OACN;AAAA,IACA,SAAS,QAAQ,UAAU;AAAA,EAC7B;AAAA,EAEA,MAAM,eAAe,QAAQ,YAAY,EAAE;AAAA,EAE3C,OAAO,EAAE,QAAQ,UAAU,IAAI,YAAY,aAAa;AAAA;AAU1D,eAAsB,WAAW,CAC/B,KACA,gBACA,QAC+B;AAAA,EAC/B,MAAM,SAAS,UAAU,IAAI;AAAA,EAE7B,IAAI,YAAY;AAAA,EAGhB,IAAI,CAAC,aAAa,UAAU,WAAW,GAAG;AAAA,IACxC,IAAI,IAAI,WAAW,MAAM;AAAA,MACvB,MAAM,SAAS,kBAAkB,EAAE,WAAW,IAAI,OAAO;AAAA,MACzD,YAAY,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO;AAAA,IACpE,EAAO;AAAA,MACL,OAAO,CAAC;AAAA;AAAA,EAEZ;AAAA,EAGA,MAAM,UAAU,MAAM,QAAQ,WAC5B,UAAU,IAAI,CAAC,SAAS,gBAAgB,KAAK,MAAM,MAAM,CAAC,CAC5D;AAAA,EAEA,OAAO,QACJ,OACC,CAAC,MACC,EAAE,WAAW,WACjB,EACC,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA;AAKvB,eAAe,kBAAkB,CAC/B,cACA,cACiB;AAAA,EACjB,OAAO,aAAa,aAAa;AAAA,IAC/B,SAAS;AAAA,IACT,KAAK;AAAA,IACL,cAAc;AAAA,EAChB,CAAC;AAAA;AAGH,SAAS,eAAe,CAAC,SAA0B;AAAA,EACjD,MAAM,MAA8B,CAAC;AAAA,EACrC,IAAI,QAAQ,OAAO;AAAA,IAAM,IAAI,MAAM,QAAQ;AAAA,EAC3C,IAAI,QAAQ,YAAY;AAAA,IAAM,IAAI,WAAW,QAAQ;AAAA,EACrD,IAAI,QAAQ,gBAAgB;AAAA,IAAM,IAAI,eAAe,QAAQ;AAAA,EAC7D,IAAI,QAAQ,wBAAwB;AAAA,IAClC,IAAI,uBAAuB,QAAQ;AAAA,EACrC,OAAO;AAAA;AAGT,SAAS,wBAAwB,CAAC,KAA6B;AAAA,EAC7D,MAAM,QAAQ,IAAI,aAAa;AAAA,EAC/B,IAAI,CAAC,OAAO;AAAA,IACV,MAAM,IAAI,MACR,sGACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAOF,SAAS,mBAAmB,CACjC,IACA,QACe;AAAA,EACf,OAAO,oBAAmB;AAAA,IACxB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,IAAI,MAAM;AAAA,EACnB,CAAC;AAAA;;;A9B7PH,IAAM,UAAgC;AAAA,EACpC;AAAA,EACA,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV;AAAA,EACA;AACF;AAMA,eAAsB,YAAY,CAChC,QACA,QACwB;AAAA,EACxB,MAAM,QAAQ,OAAO,SAAS;AAAA,EAC9B,MAAM,OAAO,OAAO,QAAQ;AAAA,EAE5B,MAAM,OAAO,MAAM,OAAO,SAAS,MAAM,aACvC,CAAC,OAAO,IAAI,OAAO,IAAI,GACvB;AAAA,IACE;AAAA,IACA,SAAS,qBAAqB,OAAO,YAAY;AAAA,IACjD,OAAO,OAAO;AAAA,EAChB,CACF;AAAA,EAGA,MAAM,UAAU,MAAM,OAAO,aAAa,0BAA0B,EAAE,KAAK,CAAC;AAAA,EAG5E,MAAM,eACJ;AAAA,EAEF,MAAM,aAAa,OAAO,QAAQ,YAAY;AAAA,EAC9C,MAAM,YAAY,QAAQ,KAAK,KAC7B,CAAC,QACC,IAAI,QAAQ,YAAY,MAAM,cAC9B,IAAI,OAAO,OAAO,YACtB;AAAA,EAEA,MAAM,cAAc,CAAC;AAAA,EAErB,OAAO;AAAA,IACL,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA;AAMF,eAAsB,mBAAmB,CACvC,QACA,SAAiB,IACjB,MACsB;AAAA,EACtB,MAAM,QAAQ,QAAS,MAAM,OAAO,SAAS,KAAK,aAAa;AAAA,EAC/D,MAAM,UAAuB,CAAC;AAAA,EAE9B,SAAS,IAAI,OAAQ,IAAI,OAAO,KAAK;AAAA,IACnC,OAAO,IAAI,OAAO,OAAO,QAAQ,WAAW,UAAU,aACpD,MAAM,OAAO,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC;AAAA,IAE3C,IAAI,CAAC,YAAY,CAAC,aAAa,YAAY,IAAI;AAAA,MAC7C,QAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,WAAW,OAAO,SAAS;AAAA,QAC3B;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAMT,eAAsB,kBAAkB,CACtC,QACA,MACe;AAAA,EACf,OAAO,OAAO,SAAS,MAAM,eAAe,CAAC,IAAI,GAAG;AAAA,IAClD,SAAS,qBAAqB,OAAO,YAAY;AAAA,IACjD,OAAO,OAAO;AAAA,EAChB,CAAC;AAAA;AAMH,eAAsB,iBAAiB,CACrC,QACA,MACe;AAAA,EACf,OAAO,OAAO,SAAS,MAAM,cAAc,CAAC,IAAI,GAAG;AAAA,IACjD,SAAS,qBAAqB,OAAO,YAAY;AAAA,IACjD,OAAO,OAAO;AAAA,EAChB,CAAC;AAAA;AAMH,eAAsB,WAAW,CAC/B,QACA,UACA,YACe;AAAA,EACf,OAAO,OAAO,SAAS,MAAM,YAAY,CAAC,UAAU,UAAU,GAAG;AAAA,IAC/D,SAAS,qBAAqB,OAAO,YAAY;AAAA,IACjD,OAAO,OAAO;AAAA,EAChB,CAAC;AAAA;AASH,eAAsB,YAAY,CAAC,QAOmB;AAAA,EACpD,MAAM,QAAQ,QAAO,OAAO;AAAA,EAC5B,IAAI,CAAC;AAAA,IAAO,MAAM,IAAI,MAAM,sBAAsB,OAAO,OAAO;AAAA,EAEhE,MAAM,eAAe,oBAAmB;AAAA,IACtC;AAAA,IACA,WAAW,MAAK,OAAO,MAAM;AAAA,EAC/B,CAAC;AAAA,EAED,MAAM,UAAU,aAAY;AAAA,IAC1B,SAAS,OAAO;AAAA,IAChB,KAAK;AAAA,IACL,QAAQ,EAAE,QAAQ,cAAc,QAAQ,OAAO,aAAa;AAAA,EAC9D,CAAC;AAAA,EAGD,MAAM,gBAAiB,MAAM,QAAQ,KAAK,WAAW;AAAA,IACnD,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AAAA,EAGD,MAAM,SAAS,MAAM,QAAQ,MAAM,cACjC,CAAC,OAAO,eAAe,OAAO,OAAO,GACrC,EAAE,SAAS,qBAAqB,OAAO,YAAY,GAAG,MAAM,CAC9D;AAAA,EAEA,OAAO,EAAE,eAAe,OAAO;AAAA;AAMjC,eAAsB,gBAAgB,CAAC,QAMlB;AAAA,EACnB,MAAM,QAAQ,QAAO,OAAO;AAAA,EAC5B,IAAI,CAAC;AAAA,IAAO,MAAM,IAAI,MAAM,sBAAsB,OAAO,OAAO;AAAA,EAEhE,MAAM,eAAe,oBAAmB;AAAA,IACtC;AAAA,IACA,WAAW,MAAK,OAAO,MAAM;AAAA,EAC/B,CAAC;AAAA,EAED,MAAM,UAAU,aAAY;AAAA,IAC1B,SAAS,OAAO;AAAA,IAChB,KAAK;AAAA,IACL,QAAQ;AAAA,EACV,CAAC;AAAA,EAED,OAAO,QAAQ,KAAK,WAAW;AAAA,IAC7B,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AAAA;AAUH,eAAsB,iBAAiB,CACrC,QACA,QAAiB,cACjB,KACyB;AAAA,EACzB,OAAO,YAAY,qBACjB,MAAM,OAAO,SAAS,KAAK,gBAAgB,CAAC,KAAK,CAAC;AAAA,EACpD,OAAO,cAAc,aAAa,cAAc,aAAa,eAC3D,MAAM,OAAO,SAAS,KAAK,cAAc,CAAC,KAAK,CAAC;AAAA,EAElD,MAAM,cAAc,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAAA,EACvD,MAAM,YAAY,OAAO,WAAW,IAAI,OAAO,YAAY;AAAA,EAC3D,MAAM,oBAAoB,KAAK,IAAI,GAAG,YAAY,WAAW;AAAA,EAC7D,MAAM,qBACJ,cAAc,KAAK,OAAQ,cAAc,OAAQ,WAAW,IAAI;AAAA,EAElE,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,OAAO,YAAY;AAAA,IACjC;AAAA,IACA,aAAa,OAAO,WAAW;AAAA,IAC/B;AAAA,IACA;AAAA,EACF;AAAA;AAQF,eAAsB,eAAe,CACnC,QACA,mBAA8B,CAAC,GAC/B,gBAA2B,CAAC,YAAY,GACxC,KACuB;AAAA,EAEvB,OAAO,eAAe,SAAS,iBAAiB,MAAM,QAAQ,IAAI;AAAA,IAChE,OAAO,SAAS,KAAK,cAAc;AAAA,IACnC,OAAO,SAAS,KAAK,QAAQ;AAAA,IAC7B,OAAO,SAAS,KAAK,cAAc;AAAA,EACrC,CAAC;AAAA,EAGD,MAAM,kBAAkB,MAAM,QAAQ,IACpC,iBAAiB,IAAI,OAAO,UAAU;AAAA,IACpC,SAAS;AAAA,IACT,QAAS,MAAM,OAAO,SAAS,KAAK,iBAAiB,CAAC,IAAI,CAAC;AAAA,EAC7D,EAAE,CACJ;AAAA,EAGA,MAAM,eAAgB,MAAM,OAAO,SAAS,KAAK,aAAa;AAAA,EAC9D,IAAI,oBAAoB;AAAA,EACxB,SAAS,IAAI,GAAI,IAAI,cAAc,KAAK;AAAA,IACtC,eAAe,WAAW,UAAU,aAClC,MAAM,OAAO,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC;AAAA,IAC3C,IAAI,CAAC,YAAY,CAAC,aAAa,YAAY;AAAA,MAAI;AAAA,EACjD;AAAA,EAGA,MAAM,UAAU,MAAM,QAAQ,IAC5B,cAAc,IAAI,CAAC,MAAM,kBAAkB,QAAQ,GAAG,GAAG,CAAC,CAC5D;AAAA,EAEA,OAAO;AAAA,IACL,SAAS,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AASF,eAAsB,kBAAkB,CACtC,QACA,WACiB;AAAA,EACjB,MAAM,SAAiB,CAAC;AAAA,EACxB,WAAW,KAAK,WAAW;AAAA,IACzB,MAAM,OAAO,MAAM,OAAO,SAAS,MAAM,mBACvC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GACxB;AAAA,MACE,SAAS,qBAAqB,OAAO,YAAY;AAAA,MACjD,OAAO,OAAO;AAAA,IAChB,CACF;AAAA,IACA,OAAO,KAAK,IAAI;AAAA,EAClB;AAAA,EACA,OAAO;AAAA;AAQT,eAAsB,kBAAkB,CACtC,QACA,UAA+D,CAAC,GACtC;AAAA,EAC1B,MAAM,YAAY,QAAQ,aAAa;AAAA,EACvC,MAAM,UAAU,QAAQ,WAAY;AAAA,EAEpC,MAAM,eAAe;AAAA,IACnB,EAAE,WAAW,uBAAgC,MAAM,YAAqB;AAAA,IACxE,EAAE,WAAW,qBAA8B,MAAM,SAAkB;AAAA,IACnE,EAAE,WAAW,uBAAgC,MAAM,WAAoB;AAAA,IACvE,EAAE,WAAW,wBAAiC,MAAM,YAAqB;AAAA,IACzE;AAAA,MACE,WAAW;AAAA,MACX,MAAM;AAAA,IACR;AAAA,IACA,EAAE,WAAW,mBAA4B,MAAM,kBAA2B;AAAA,EAC5E;AAAA,EAEA,MAAM,aAA8B,CAAC;AAAA,EAErC,aAAa,WAAW,UAAU,cAAc;AAAA,IAC9C,MAAM,OAAO,MAAM,OAAO,aAAa,kBAAkB;AAAA,MACvD,SAAS,OAAO;AAAA,MAChB,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IAED,WAAW,OAAO,MAAM;AAAA,MACtB,MAAM,UACJ,OAAO,OAAO,QAAQ,YAAY,UAAU,MACvC,IAA6C,OAC9C;AAAA,MACN,WAAW,KAAK;AAAA,QACd;AAAA,QACA,aAAa,IAAI;AAAA,QACjB,iBAAiB,IAAI;AAAA,QACrB,MAAM,WAAW,CAAC;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAGA,WAAW,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,cAAc,EAAE,WAAW,CAAC;AAAA,EAC/D,OAAO;AAAA;AASF,SAAS,mBAAmB,CACjC,QACA,UACY;AAAA,EACZ,OAAO,OAAO,aAAa,mBAAmB;AAAA,IAC5C,SAAS,OAAO;AAAA,IAChB,KAAK;AAAA,IACL,WAAW;AAAA,IACX,QAAQ,CAAC,SAAS;AAAA,MAChB,WAAW,OAAO,MAAM;AAAA,QACtB,MAAM,OACJ,OAAO,OAAO,QAAQ,YAAY,UAAU,MAEtC,IASA,OACF;AAAA,QACN,IACE,CAAC,QACD,KAAK,SAAS,aACd,KAAK,OAAO,aACZ,KAAK,UAAU,aACf,KAAK,UAAU,aACf,KAAK,WAAW,aAChB,CAAC,IAAI,iBACL;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,MAAM,KAAK;AAAA,UACX,IAAI,KAAK;AAAA,UACT,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,UACZ,QAAQ,KAAK;AAAA,UACb,aAAa,IAAI;AAAA,UACjB,iBAAiB,IAAI;AAAA,QACvB,CAAC;AAAA,MACH;AAAA;AAAA,EAEJ,CAAC;AAAA;AAMI,SAAS,qBAAqB,CACnC,QACA,UAMY;AAAA,EACZ,OAAO,OAAO,aAAa,mBAAmB;AAAA,IAC5C,SAAS,OAAO;AAAA,IAChB,KAAK;AAAA,IACL,WAAW;AAAA,IACX,QAAQ,CAAC,SAAS;AAAA,MAChB,WAAW,OAAO,MAAM;AAAA,QACtB,MAAM,OACJ,OAAO,OAAO,QAAQ,YAAY,UAAU,MAEtC,IAOA,OACF;AAAA,QACN,MAAM,kBAAkB,IAAI;AAAA,QAC5B,IACE,CAAC,QACD,KAAK,WAAW,aAChB,KAAK,UAAU,aACf,KAAK,aAAa,aAClB,CAAC,iBACD;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,QAAQ,KAAK;AAAA,UACb,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf;AAAA,QACF,CAAC;AAAA,MACH;AAAA;AAAA,EAEJ,CAAC;AAAA;",
|
|
38
|
+
"debugId": "552FEB9060579F2864756E2164756E21",
|
|
39
|
+
"names": []
|
|
40
|
+
}
|