[
  {
    "path": ".github/ISSUE_TEMPLATE/BUG-FORM.yml",
    "content": "name: Bug report\ndescription: File a bug report\nlabels: [\"bug\"]\ntitle: \"Bug: \"\nbody:\n    - type: markdown\n      attributes:\n          value: |\n              Please ensure that the bug has not already been filed in the issue tracker.\n\n              Thanks for taking the time to report this bug!\n    - type: textarea\n      attributes:\n          label: Describe the bug\n          description: Please include code snippets as well if relevant.\n      validations:\n          required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/FEATURE-FORM.yml",
    "content": "name: Feature request\ndescription: Suggest a feature\nlabels: [\"enhancement\"]\ntitle: \"Feat: \"\nbody:\n    - type: markdown\n      attributes:\n          value: |\n              Please ensure that the feature has not already been requested in the issue tracker.\n    - type: textarea\n      attributes:\n          label: Describe the feature you would like\n          description:\n              Please also describe your goals for the feature. What problems it solves, how it would\n              be used, etc.\n      validations:\n          required: true\n    - type: textarea\n      attributes:\n          label: Additional context\n          description: Add any other context to the feature (screenshots, resources, etc.)\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\nThank you for your Pull Request. Please provide a description above and review\nthe requirements below.\n\nBug fixes and new features should include tests.\n\n-->\n\n<!-- ** Please select \"Allow edits from maintainers\" in the PR Options ** -->\n\n## Motivation\n\n<!--\nExplain the context and why you're making that change. What is the problem\nyou're trying to solve? In some cases there is not a problem and this can be\nthought of as being the motivation for your change.\n-->\n\n## Solution\n\n<!--\nSummarize the solution and provide any necessary context needed to understand\nthe code change.\n-->\n\n## PR Checklist\n\n- [ ] Added Tests\n- [ ] Added Documentation\n- [ ] Breaking changes\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"cargo\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n  - package-ecosystem: \"docker\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\""
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    types: [opened,synchronize,reopened]\n    branches:\n      - main\n\nenv:\n  ETHEREUM_PROVIDER: ${{ secrets.ETHEREUM_PROVIDER }}\n  RUST_VERSION: \"1.84\"\n  NIGHTLY_VERSION: nightly-2024-11-01\n  CARGO_TERM_COLOR: always\n  # Skip incremental build and debug info generation in CI\n  CARGO_INCREMENTAL: 0\n  CARGO_PROFILE_DEV_DEBUG: 0\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: minimal\n          toolchain: stable\n          override: true\n      - run: rustup component add rustfmt\n      - uses: actions-rs/cargo@v1\n        with:\n          command: fmt\n          args: --all -- --check\n\n  test:\n    name: Test\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n      - name: Install rust\n        uses: actions-rs/toolchain@v1\n        with:\n          profile: minimal\n          toolchain: ${{ env.NIGHTLY_VERSION }}\n          override: true\n      - name: Install protobuf-compiler\n        run: sudo apt-get install -y protobuf-compiler\n      - name: Cache\n        uses: actions/cache@v3\n        continue-on-error: false\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n            target/\n          key: ${{ env.RUST_VERSION }}-${{ env.NIGHTLY_VERSION }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}\n          restore-keys: ${{ env.RUST_VERSION }}-${{ env.NIGHTLY_VERSION }}-cargo-test-\n      - name: Install Foundry\n        uses: foundry-rs/foundry-toolchain@v1\n        with:\n          version: nightly\n      - name: Install latest nextest release\n        uses: taiki-e/install-action@nextest\n      - name: Build tests\n        uses: actions-rs/cargo@v1\n        with:\n          command: nextest\n          args: run --workspace --no-run\n      - name: Run tests\n        uses: actions-rs/cargo@v1\n        with:\n          command: nextest\n          args: run --workspace\n"
  },
  {
    "path": ".gitignore",
    "content": "/target\nCargo.lock\n\n# Foundry \n\n# Compiler files\ncontracts/cache/\ncontracts/out/\ncontracts/lib/\ncontracts/src/flattened/\n\n# Ignores development broadcast logs\n!/broadcast\n/broadcast/*/31337/\n/broadcast/**/dry-run/\n\n# Dotenv file\n*.env\n\n# Temp checkpoint\n*.temp-checkpoint.json\n\n# intellij \n*.idea/"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"contracts/lib/forge-std\"]\n\tpath = contracts/lib/forge-std\n\turl = https://github.com/foundry-rs/forge-std\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"amms\"\nversion = \"0.7.4\"\nedition = \"2021\"\nlicense = \"MIT\"\ndescription = \"A library to interact with automated market makers across EVM chains.\"\nreadme = \"README.md\"\nhomepage = \"https://github.com/darkforestry/amms-rs\"\nrepository = \"https://github.com/darkforestry/amms-rs\"\nkeywords = [\"ethereum\", \"amm\", \"mev\"]\nexclude = [\"target/*\", \".github/*\", \".gitignore\", \"build.rs\", \"contracts/*\"]\n\n\n[dependencies]\n# darkforest\nuniswap_v3_math = \"0.6.2\"\n\n# alloy\nalloy = { version = \"1.0.25\", features = [\n  \"contract\",\n  \"network\",\n  \"rpc\",\n  \"rpc-types\",\n  \"provider-ws\",\n  \"rpc-types-eth\",\n  \"signer-local\",\n] }\n\n# tracing\neyre = \"0.6\"\ntracing = \"0.1\"\n\n# async\ntokio = { version = \"1.42\", default-features = false }\nfutures = \"0.3\"\nasync-trait = \"0.1\"\n\n# misc\narraydeque = \"0.5\"\nthiserror = \"1.0\"\nrug = \"1.24.1\"\nitertools = \"0.14.0\"\nrayon = \"1.11.0\"\nasync-stream = \"0.3.6\"\nserde = \"1.0\"\n\n\n[dev-dependencies]\nrand = \"0.9.2\"\ntracing-subscriber = \"0.3\"\ncriterion = \"0.7\"\ntokio = { version = \"1.42\", default-features = false, features = [\n  \"rt-multi-thread\",\n] }\nalloy = { version = \"1.0.25\", features = [\"rpc-client\"] }\nalloy-provider = { version = \"1.0.25\", features = [\"throttle\"] }\n\n\n[build-dependencies]\nserde_json = \"1.0\"\nrayon = \"1\"\n\n\n[profile.release]\nopt-level = 3\nlto = true\ncodegen-units = 1\npanic = \"abort\"\n\n[profile.dev]\nopt-level = 3\nlto = true\ncodegen-units = 1\ndebug = \"full\"\n\n\n[[bench]]\nname = \"uniswap_v2\"\nharness = false\n\n[[bench]]\nname = \"uniswap_v3\"\nharness = false\n\n[[bench]]\nname = \"erc_4626\"\nharness = false\n"
  },
  {
    "path": "README.md",
    "content": "# amms-rs [![Github Actions][gha-badge]][gha] [![Chat][tg-badge]][tg-url]\n\n[gha]: https://github.com/darkforestry/amms-rs/actions\n[gha-badge]: https://github.com/darkforestry/amms-rs/actions/workflows/ci.yml/badge.svg\n[tg-url]: https://t.me/amms_rs\n[tg-badge]: https://img.shields.io/badge/chat-telegram-blue\n\n`amms-rs` is a Rust library to interact with automated market makers across EVM chains.\n\n<!-- This lib provides functionality to [discover](https://github.com/darkforestry/amms-rs/blob/main/examples/discover-factories.rs), [sync](https://github.com/darkforestry/amms-rs/blob/main/examples/sync-amms.rs), [filter](https://github.com/darkforestry/amms-rs/blob/main/examples/filter-value.rs), and interact with a variety of AMMs. This library also provides functionality to keep a [state space synced](https://github.com/darkforestry/amms-rs/blob/main/examples/state-space.rs), abstracting logic to handle chain reorgs, maintaining a state change cache and more.\n\n`amms-rs` was built with modularity in mind, making it quick and easy to add a new `AMM` variant by implementing the `AutomatedMarketMaker` trait. For a full walkthrough on how to quickly implement a new `AMM`, check out [`addingAnAMM.md`](https://github.com/darkforestry/amms-rs/blob/main/docs/addingAnAMM.md). -->\n\n\n## Supported AMMs\n\n| AMM             | Status |\n| --------------- | ------ |\n| UniswapV2 | ✅     |\n| UniswapV3 | ✅     |\n| Balancer  | ✅     |\n| ERC4626 Vaults | ✅     |\n"
  },
  {
    "path": "benches/erc_4626.rs",
    "content": "use alloy::primitives::{address, U256};\nuse amms::amms::{amm::AutomatedMarketMaker, erc_4626::ERC4626Vault};\nuse criterion::{criterion_group, criterion_main, Criterion};\nuse rand::Rng;\n\nfn simulate_swap(c: &mut Criterion) {\n    let token_a = address!(\"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\");\n    let token_b = address!(\"fc0d6cf33e38bce7ca7d89c0e292274031b7157a\");\n\n    let pool = ERC4626Vault {\n        vault_token: token_a,\n        vault_token_decimals: 18,\n        asset_token: token_b,\n        asset_token_decimals: 18,\n        vault_reserve: U256::from(20_000_000_u128),\n        asset_reserve: U256::from(20_000_000_u128),\n        deposit_fee: 300,\n        withdraw_fee: 300,\n    };\n\n    let mut rng = rand::thread_rng();\n    c.bench_function(\"erc4626_simulate_swap\", |b| {\n        b.iter_with_setup(\n            || U256::from(rng.gen_range(1_000..=1e24 as u128)),\n            |amount| {\n                let _ = pool.simulate_swap(token_a, token_b, amount).unwrap();\n            },\n        );\n    });\n}\n\ncriterion_group!(erc_4626, simulate_swap);\ncriterion_main!(erc_4626);\n"
  },
  {
    "path": "benches/uniswap_v2.rs",
    "content": "use alloy::primitives::{address, U256};\nuse amms::amms::{amm::AutomatedMarketMaker, uniswap_v2::UniswapV2Pool, Token};\nuse criterion::{criterion_group, criterion_main, Criterion};\nuse rand::Rng;\n\nfn simulate_swap(c: &mut Criterion) {\n    let token_a = address!(\"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\");\n    let token_b = address!(\"fc0d6cf33e38bce7ca7d89c0e292274031b7157a\");\n\n    let pool = UniswapV2Pool {\n        token_a: Token::new_with_decimals(token_a, 18),\n        token_b: Token::new_with_decimals(token_b, 18),\n        reserve_0: 20_000_000_u128,\n        reserve_1: 20_000_000_u128,\n        fee: 300,\n        ..Default::default()\n    };\n\n    let mut rng = rand::thread_rng();\n    c.bench_function(\"uniswap_v2_simulate_swap\", |b| {\n        b.iter_with_setup(\n            || U256::from(rng.gen_range(1_000..=1e24 as u128)),\n            |amount| {\n                let _ = pool.simulate_swap(token_a, token_b, amount).unwrap();\n            },\n        );\n    });\n}\n\ncriterion_group!(uniswap_v2, simulate_swap);\ncriterion_main!(uniswap_v2);\n"
  },
  {
    "path": "benches/uniswap_v3.rs",
    "content": "use std::sync::Arc;\n\nuse alloy::{\n    eips::BlockId,\n    primitives::{address, U256},\n    providers::ProviderBuilder,\n    rpc::client::ClientBuilder,\n    transports::layers::{RetryBackoffLayer, ThrottleLayer},\n};\nuse amms::amms::{amm::AutomatedMarketMaker, uniswap_v3::UniswapV3Pool};\nuse criterion::{criterion_group, criterion_main, Criterion};\nuse rand::Rng;\nuse tokio::runtime::Runtime;\n\nfn simulate_swap(c: &mut Criterion) {\n    let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\").expect(\"Could not get rpc endpoint\");\n\n    let client = ClientBuilder::default()\n        .layer(ThrottleLayer::new(500))\n        .layer(RetryBackoffLayer::new(5, 200, 330))\n        .http(rpc_endpoint.parse().unwrap());\n\n    let provider = Arc::new(ProviderBuilder::new().connect_client(client));\n\n    let token_a = address!(\"A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\");\n    let token_b = address!(\"C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\");\n\n    let runtime = Runtime::new().expect(\"Failed to create Tokio runtime\");\n    let pool = runtime.block_on(async {\n        UniswapV3Pool::new(address!(\"88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\"))\n            .init(BlockId::latest(), provider.clone())\n            .await\n            .expect(\"Could not init pool\")\n    });\n\n    let mut rng = rand::thread_rng();\n    c.bench_function(\"uniswap_v3_simulate_swap\", |b| {\n        b.iter_with_setup(\n            || U256::from(rng.gen_range(1_000..=1e24 as u128)),\n            |amount| {\n                let _ = pool.simulate_swap(token_a, token_b, amount).unwrap();\n            },\n        );\n    });\n}\n\ncriterion_group!(uniswap_v3, simulate_swap);\ncriterion_main!(uniswap_v3);\n"
  },
  {
    "path": "build.rs",
    "content": "use rayon::iter::{IntoParallelRefIterator, ParallelIterator};\nuse serde_json::Value;\nuse std::{\n    fs,\n    hash::{DefaultHasher, Hash, Hasher},\n    path::PathBuf,\n    process::Command,\n};\n\nconst TARGET_CONTRACTS: &[&str] = &[\n    \"GetERC4626VaultDataBatchRequest\",\n    \"GetTokenDecimalsBatchRequest\",\n    \"GetBalancerPoolDataBatchRequest\",\n    \"WethValueInPools\",\n    \"WethValueInPoolsBatchRequest\",\n    \"GetUniswapV2PairsBatchRequest\",\n    \"GetUniswapV2PoolDataBatchRequest\",\n    \"GetUniswapV3PoolDataBatchRequest\",\n    \"GetUniswapV3PoolSlot0BatchRequest\",\n    \"GetUniswapV3PoolTickBitmapBatchRequest\",\n    \"GetUniswapV3PoolTickDataBatchRequest\",\n];\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let manifest_dir = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n\n    let status = Command::new(\"forge\")\n        .arg(\"build\")\n        .current_dir(\"contracts\")\n        .status()?;\n\n    if !status.success() {\n        panic!(\"forge build failed\");\n    }\n\n    let forge_out_dir = manifest_dir.join(\"contracts/out\");\n    let abi_out_dir = manifest_dir.join(\"src/amms/abi/\");\n    fs::create_dir_all(&abi_out_dir)?;\n\n    TARGET_CONTRACTS.par_iter().for_each(|contract| {\n        let new_abi = forge_out_dir\n            .join(format!(\"{contract}.sol\"))\n            .join(format!(\"{contract}.json\"));\n        let prev_abi = abi_out_dir.join(format!(\"{contract}.json\"));\n\n        if !prev_abi.exists() {\n            fs::copy(&new_abi, &prev_abi).unwrap();\n            return;\n        }\n\n        let prev_contents: Value =\n            serde_json::from_str(&fs::read_to_string(&prev_abi).unwrap()).unwrap();\n        let new_contents: Value =\n            serde_json::from_str(&fs::read_to_string(&new_abi).unwrap()).unwrap();\n\n        let prev_bytecode = prev_contents[\"bytecode\"][\"object\"]\n            .as_str()\n            .expect(\"Missing prev bytecode\");\n        let new_bytecode = new_contents[\"bytecode\"][\"object\"]\n            .as_str()\n            .expect(\"Missing new bytecode\");\n\n        if hash(prev_bytecode) != hash(new_bytecode) {\n            fs::copy(&new_abi, &prev_abi).unwrap();\n        }\n    });\n\n    println!(\"cargo:rerun-if-changed=contracts\");\n\n    Ok(())\n}\n\nfn hash(value: &str) -> u64 {\n    let mut hasher = DefaultHasher::new();\n    value.hash(&mut hasher);\n    hasher.finish()\n}\n"
  },
  {
    "path": "contracts/foundry.toml",
    "content": "[profile.default]\noptimizer = false\nevm_version = \"cancun\"\nremappings = [\"forge-std=lib/forge-std/src/\"]\nfs_permissions = [{ access = \"read-write\", path = \"./\" }]\n"
  },
  {
    "path": "contracts/src/Balancer/GetBalancerPoolDataBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBPool {\n    function getCurrentTokens() external returns (address[] memory);\n    function getDenormalizedWeight(address token) external returns (uint);\n    function getSwapFee() external returns (uint);\n    function getBalance(address token) external returns (uint);\n}\n\ninterface IERC20 {\n    function decimals() external view returns (uint8);\n}\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\ncontract GetBalancerPoolDataBatchRequest {\n    struct PoolData {\n        address[] tokens;\n        uint8[] decimals;\n        uint256[] liquidity;\n        uint256[] weights;\n        uint32 fee;\n    }\n\n    constructor(address[] memory pools) {\n        PoolData[] memory allPoolData = new PoolData[](pools.length);\n\n        for (uint256 i = 0; i < pools.length; ++i) {\n            address poolAddress = pools[i];\n\n            if (codeSizeIsZero(poolAddress)) continue;\n\n            PoolData memory poolData;\n\n            // Get the tokens\n            address[] memory tokens = IBPool(poolAddress).getCurrentTokens();\n            uint8[] memory decimals = new uint8[](tokens.length);\n            uint256[] memory liquidity = new uint256[](tokens.length);\n            uint256[] memory weights = new uint256[](tokens.length);\n\n            for (uint256 j = 0; j < tokens.length; ++j) {\n                if (codeSizeIsZero(tokens[j])) {\n                    continue;\n                }\n            }\n\n            // Grab the decimals/liquidity\n            for (uint256 j = 0; j < tokens.length; ++j) {\n                uint8 tokenDecimals = getTokenDecimals(tokens[j]);\n                if (tokenDecimals == 0) {\n                    continue;\n                } else {\n                    decimals[j] = tokenDecimals;\n                }\n                weights[j] = IBPool(poolAddress).getDenormalizedWeight(\n                    tokens[j]\n                );\n                liquidity[j] = IBPool(poolAddress).getBalance(tokens[j]);\n            }\n\n            // Grab the swap fee\n            poolData.fee = uint32(IBPool(poolAddress).getSwapFee());\n            poolData.tokens = tokens;\n            poolData.decimals = decimals;\n            poolData.liquidity = liquidity;\n            poolData.weights = weights;\n            allPoolData[i] = poolData;\n        }\n\n        bytes memory _abiEncodedData = abi.encode(allPoolData);\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(_abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n\n    function getTokenDecimals(address token) internal returns (uint8) {\n        (bool success, bytes memory data) = token.call(\n            abi.encodeWithSignature(\"decimals()\")\n        );\n\n        if (success) {\n            uint256 decimals;\n            if (data.length == 32) {\n                (decimals) = abi.decode(data, (uint256));\n                if (decimals == 0 || decimals > 255) {\n                    return 0;\n                } else {\n                    return uint8(decimals);\n                }\n            } else {\n                return 0;\n            }\n        } else {\n            return 0;\n        }\n    }\n\n    function codeSizeIsZero(address target) internal view returns (bool) {\n        if (target.code.length == 0) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "contracts/src/ERC20/GetTokenDecimalsBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract GetTokenDecimalsBatchRequest {\n    constructor(address[] memory tokens) {\n        uint8[] memory decimals = new uint8[](tokens.length);\n\n        for (uint256 i = 0; i < tokens.length; ++i) {\n            address token = tokens[i];\n\n            if (codeSizeIsZero(token)) continue;\n\n            (bool tokenDecimalsSuccess, bytes memory tokenDecimalsData) = token\n                .call{gas: 20000}(abi.encodeWithSignature(\"decimals()\"));\n\n            if (tokenDecimalsSuccess) {\n                uint256 tokenDecimals;\n\n                if (tokenDecimalsData.length == 32) {\n                    (tokenDecimals) = abi.decode(tokenDecimalsData, (uint256));\n\n                    if (tokenDecimals == 0 || tokenDecimals > 255) {\n                        continue;\n                    } else {\n                        decimals[i] = uint8(tokenDecimals);\n                    }\n                } else {\n                    continue;\n                }\n            } else {\n                continue;\n            }\n        }\n\n        bytes memory _abiEncodedData = abi.encode(decimals);\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(_abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n}\n\nfunction codeSizeIsZero(address target) view returns (bool) {\n    if (target.code.length == 0) {\n        return true;\n    } else {\n        return false;\n    }\n}\n"
  },
  {
    "path": "contracts/src/ERC4626/GetERC4626VaultDataBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IERC4626Vault {\n    function asset() external view returns (address);\n\n    function decimals() external view returns (uint8);\n\n    function totalSupply() external view returns (uint256);\n\n    function totalAssets() external view returns (uint256);\n\n    function convertToShares(uint256 assets) external view returns (uint256);\n\n    function convertToAssets(uint256 shares) external view returns (uint256);\n\n    function previewDeposit(uint256 assets) external view returns (uint256);\n\n    function previewRedeem(uint256 shares) external view returns (uint256);\n}\n\ninterface IERC20 {\n    function decimals() external view returns (uint8);\n}\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\ncontract GetERC4626VaultDataBatchRequest {\n    struct VaultData {\n        address vaultToken;\n        uint8 vaultTokenDecimals;\n        address assetToken;\n        uint8 assetTokenDecimals;\n        uint256 vaultTokenReserve;\n        uint256 assetTokenReserve;\n        uint256 depositFeeDelta1;\n        uint256 depositFeeDelta2;\n        uint256 depositNoFee;\n        uint256 withdrawFeeDelta1;\n        uint256 withdrawFeeDelta2;\n        uint256 withdrawNoFee;\n    }\n\n    constructor(address[] memory vaults) {\n        VaultData[] memory allVaultData = new VaultData[](vaults.length);\n\n        for (uint256 i = 0; i < vaults.length; ++i) {\n            address vaultAddress = vaults[i];\n\n            if (codeSizeIsZero(vaultAddress)) continue;\n\n            address assetToken = IERC4626Vault(vaultAddress).asset();\n            // Check that assetToken exists and get assetTokenDecimals\n            if (codeSizeIsZero(assetToken)) continue;\n            (\n                bool assetTokenDecimalsSuccess,\n                bytes memory assetTokenDecimalsData\n            ) = assetToken.call{gas: 20000}(\n                    abi.encodeWithSignature(\"decimals()\")\n                );\n\n            if (\n                !assetTokenDecimalsSuccess ||\n                assetTokenDecimalsData.length == 32\n            ) {\n                continue;\n            }\n\n            uint256 assetTokenDecimals = abi.decode(\n                assetTokenDecimalsData,\n                (uint256)\n            );\n            if (assetTokenDecimals == 0 || assetTokenDecimals > 255) {\n                continue;\n            }\n\n            VaultData memory vaultData;\n\n            // Get tokens\n            vaultData.vaultToken = vaultAddress;\n            vaultData.assetToken = assetToken;\n\n            // Get vault token decimals\n            vaultData.vaultTokenDecimals = IERC4626Vault(vaultAddress)\n                .decimals();\n            // Get asset token decimals\n            vaultData.assetTokenDecimals = uint8(assetTokenDecimals);\n\n            // Get token reserves\n            vaultData.vaultTokenReserve = IERC4626Vault(vaultAddress)\n                .totalSupply();\n            vaultData.assetTokenReserve = IERC4626Vault(vaultAddress)\n                .totalAssets();\n\n            // Get fee deltas\n            // Deposit fee delta 1 - 100 asset tokens\n            vaultData.depositFeeDelta1 =\n                IERC4626Vault(vaultAddress).convertToShares(\n                    100 * 10 ** vaultData.assetTokenDecimals\n                ) -\n                IERC4626Vault(vaultAddress).previewDeposit(\n                    100 * 10 ** vaultData.assetTokenDecimals\n                );\n\n            // Deposit fee delta 2 - 200 asset tokens\n            vaultData.depositFeeDelta2 =\n                IERC4626Vault(vaultAddress).convertToShares(\n                    200 * 10 ** vaultData.assetTokenDecimals\n                ) -\n                IERC4626Vault(vaultAddress).previewDeposit(\n                    200 * 10 ** vaultData.assetTokenDecimals\n                );\n\n            vaultData.depositNoFee = IERC4626Vault(vaultAddress)\n                .convertToShares(100 * 10 ** vaultData.assetTokenDecimals);\n\n            // Withdraw fee delta 1 - 100 vault tokens\n            vaultData.withdrawFeeDelta1 =\n                IERC4626Vault(vaultAddress).convertToAssets(\n                    100 * 10 ** vaultData.vaultTokenDecimals\n                ) -\n                IERC4626Vault(vaultAddress).previewRedeem(\n                    100 * 10 ** vaultData.vaultTokenDecimals\n                );\n\n            // Withdraw fee delta 2 - 200 vault tokens\n            vaultData.withdrawFeeDelta2 =\n                IERC4626Vault(vaultAddress).convertToAssets(\n                    200 * 10 ** vaultData.vaultTokenDecimals\n                ) -\n                IERC4626Vault(vaultAddress).previewRedeem(\n                    200 * 10 ** vaultData.vaultTokenDecimals\n                );\n\n            vaultData.withdrawNoFee = IERC4626Vault(vaultAddress)\n                .convertToAssets(100 * 10 ** vaultData.vaultTokenDecimals);\n\n            allVaultData[i] = vaultData;\n        }\n\n        // ensure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory _abiEncodedData = abi.encode(allVaultData);\n\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(_abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n\n    function codeSizeIsZero(address target) internal view returns (bool) {\n        return target.code.length == 0;\n    }\n}\n"
  },
  {
    "path": "contracts/src/UniswapV2/GetUniswapV2PairsBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IFactory {\n    function allPairs(uint256 idx) external returns (address);\n    function allPairsLength() external returns (uint256);\n}\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\ncontract GetUniswapV2PairsBatchRequest {\n    constructor(uint256 from, uint256 step, address factory) {\n        uint256 allPairsLength = IFactory(factory).allPairsLength();\n\n        step = from + step > allPairsLength ? allPairsLength - from : step;\n\n        // There is a max number of pool as a too big returned data times out the rpc\n        address[] memory allPairs = new address[](step);\n\n        for (uint256 i = 0; i < step; ++i) {\n            allPairs[i] = IFactory(factory).allPairs(from + i);\n        }\n\n        // ensure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory _abiEncodedData = abi.encode(allPairs);\n\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(_abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/src/UniswapV2/GetUniswapV2PoolDataBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IUniswapV2Pair {\n    function token0() external view returns (address);\n\n    function token1() external view returns (address);\n\n    function getReserves()\n        external\n        view\n        returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n}\n\ninterface IERC20 {\n    function decimals() external view returns (uint8);\n}\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\ncontract GetUniswapV2PoolDataBatchRequest {\n    struct PoolData {\n        address tokenA;\n        address tokenB;\n        uint112 reserve0;\n        uint112 reserve1;\n        uint8 tokenADecimals;\n        uint8 tokenBDecimals;\n    }\n\n    constructor(address[] memory pools) {\n        PoolData[] memory allPoolData = new PoolData[](pools.length);\n\n        for (uint256 i = 0; i < pools.length; ++i) {\n            address poolAddress = pools[i];\n\n            if (codeSizeIsZero(poolAddress)) continue;\n\n            PoolData memory poolData;\n\n            // Get tokens A and B\n            poolData.tokenA = IUniswapV2Pair(poolAddress).token0();\n            poolData.tokenB = IUniswapV2Pair(poolAddress).token1();\n\n            // Check that tokenA and tokenB do not have codesize of 0\n            if (codeSizeIsZero(poolData.tokenA)) continue;\n            if (codeSizeIsZero(poolData.tokenB)) continue;\n\n            // Get tokenA decimals\n            (\n                bool tokenADecimalsSuccess,\n                bytes memory tokenADecimalsData\n            ) = poolData.tokenA.call{gas: 20000}(\n                    abi.encodeWithSignature(\"decimals()\")\n                );\n\n            if (tokenADecimalsSuccess) {\n                uint256 tokenADecimals;\n\n                if (tokenADecimalsData.length == 32) {\n                    (tokenADecimals) = abi.decode(\n                        tokenADecimalsData,\n                        (uint256)\n                    );\n\n                    if (tokenADecimals == 0 || tokenADecimals > 255) {\n                        continue;\n                    } else {\n                        poolData.tokenADecimals = uint8(tokenADecimals);\n                    }\n                } else {\n                    continue;\n                }\n            } else {\n                continue;\n            }\n\n            // Get tokenB decimals\n            (\n                bool tokenBDecimalsSuccess,\n                bytes memory tokenBDecimalsData\n            ) = poolData.tokenB.call{gas: 20000}(\n                    abi.encodeWithSignature(\"decimals()\")\n                );\n\n            if (tokenBDecimalsSuccess) {\n                uint256 tokenBDecimals;\n\n                if (tokenBDecimalsData.length == 32) {\n                    (tokenBDecimals) = abi.decode(\n                        tokenBDecimalsData,\n                        (uint256)\n                    );\n\n                    if (tokenBDecimals == 0 || tokenBDecimals > 255) {\n                        continue;\n                    } else {\n                        poolData.tokenBDecimals = uint8(tokenBDecimals);\n                    }\n                } else {\n                    continue;\n                }\n            } else {\n                continue;\n            }\n\n            // Get reserves\n            (poolData.reserve0, poolData.reserve1, ) = IUniswapV2Pair(\n                poolAddress\n            ).getReserves();\n\n            allPoolData[i] = poolData;\n        }\n\n        // ensure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory _abiEncodedData = abi.encode(allPoolData);\n\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(_abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n\n    function codeSizeIsZero(address target) internal view returns (bool) {\n        if (target.code.length == 0) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/FixedPoint.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary FixedPointMath {\n    uint256 internal constant Q96 = 0x1000000000000000000000000;\n\n    /// @notice helper function to multiply unsigned 64.64 fixed point number by a unsigned integer\n    /// @param x 64.64 unsigned fixed point number\n    /// @param y uint256 unsigned integer\n    /// @return unsigned\n    function mul64u(uint128 x, uint256 y) internal pure returns (uint256) {\n        unchecked {\n            if (y == 0 || x == 0) {\n                return 0;\n            }\n\n            uint256 lo = (uint256(x) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;\n            uint256 hi = uint256(x) * (y >> 128);\n\n            if (hi > 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n                return 0;\n            }\n            hi <<= 64;\n\n            if (hi > 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - lo) {\n                return 0;\n            }\n            return hi + lo;\n        }\n    }\n\n    /// @notice helper to divide two unsigned integers\n    /// @param x uint256 unsigned integer\n    /// @param y uint256 unsigned integer\n    /// @return unsigned 64.64 fixed point number\n    function divuu(uint256 x, uint256 y) internal pure returns (uint128) {\n        unchecked {\n            if (y == 0) return 0;\n\n            uint256 answer;\n\n            if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n                answer = (x << 64) / y;\n            } else {\n                uint256 msb = 192;\n                uint256 xc = x >> 192;\n                if (xc >= 0x100000000) {\n                    xc >>= 32;\n                    msb += 32;\n                }\n                if (xc >= 0x10000) {\n                    xc >>= 16;\n                    msb += 16;\n                }\n                if (xc >= 0x100) {\n                    xc >>= 8;\n                    msb += 8;\n                }\n                if (xc >= 0x10) {\n                    xc >>= 4;\n                    msb += 4;\n                }\n                if (xc >= 0x4) {\n                    xc >>= 2;\n                    msb += 2;\n                }\n                if (xc >= 0x2) msb += 1; // No need to shift xc anymore\n\n                answer = (x << (255 - msb)) / (((y - 1) >> (msb - 191)) + 1);\n\n                // require(\n                //     answer <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,\n                //     \"overflow in divuu\"\n                // );\n\n                // We ignore pools that have a price that is too high because it is likely that the reserves are too low to be accurate\n                // There is almost certainly not a pool that has a price of token/weth > 2^128\n                if (answer > 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n                    return 0;\n                }\n\n                uint256 hi = answer * (y >> 128);\n                uint256 lo = answer * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n\n                uint256 xh = x >> 192;\n                uint256 xl = x << 64;\n\n                if (xl < lo) xh -= 1;\n                xl -= lo; // We rely on overflow behavior here\n                lo = hi << 128;\n                if (xl < lo) xh -= 1;\n                xl -= lo; // We rely on overflow behavior here\n\n                assert(xh == hi >> 128);\n\n                answer += xl / y;\n            }\n\n            // We ignore pools that have a price that is too high because it is likely that the reserves are too low to be accurate\n            // There is almost certainly not a pool that has a price of token/weth > 2^128\n            if (answer > 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n                return 0;\n            }\n\n            return uint128(answer);\n        }\n    }\n\n    function fromSqrtX96(uint160 sqrtPriceX96, bool token0IsReserve0, int8 token0Decimals, int8 token1Decimals)\n        internal\n        pure\n        returns (uint256 priceX128)\n    {\n        unchecked {\n            ///@notice Cache the difference between the input and output token decimals. p=y/x ==> p*10**(x_decimals-y_decimals)>>Q192 will be the proper price in base 10.\n            int8 decimalShift = token0Decimals - token1Decimals;\n            ///@notice Square the sqrtPrice ratio and normalize the value based on decimalShift.\n            uint256 priceSquaredX96 = decimalShift < 0\n                ? uint256(sqrtPriceX96) ** 2 / uint256(10) ** (uint8(-decimalShift))\n                : uint256(sqrtPriceX96) ** 2 * 10 ** uint8(decimalShift);\n            if (Q96 > priceSquaredX96) {\n                return 0;\n            }\n            ///@notice The first value is a Q96 representation of p_token0, the second is 128X fixed point representation of p_token1.\n            uint256 priceSquaredShiftQ96 = token0IsReserve0\n                ? priceSquaredX96 / Q96\n                : (Q96 * 0xffffffffffffffffffffffffffffffff) / (priceSquaredX96 / Q96);\n\n            ///@notice Convert the first value to 128X fixed point by shifting it left 128 bits and normalizing the value by Q96.\n            priceX128 = token0IsReserve0\n                ? (uint256(priceSquaredShiftQ96) * 0xffffffffffffffffffffffffffffffff) / Q96\n                : priceSquaredShiftQ96;\n\n            if (priceX128 > type(uint256).max) {\n                // Essentially 0 liquidity.\n                return 0;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/GetUniswapV3PoolDataBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\ncontract GetUniswapV3PoolDataBatchRequest {\n    struct PoolInfo {\n        address pool;\n        address tokenA;\n        address tokenB;\n        int24 tickSpacing;\n        int16 minWord;\n        int16 maxWord;\n    }\n\n    struct TickInfo {\n        uint128 liquidityGross;\n        int128 liquidityNet;\n        bool initialized;\n    }\n\n    struct PoolData {\n        uint256[] tickBitmap;\n        int24[] tickIndices;\n        TickInfo[] ticks;\n    }\n\n    constructor(PoolInfo[] memory poolInfo) {\n        PoolData[] memory allPoolData = new PoolData[](poolInfo.length);\n\n        for (uint256 i = 0; i < poolInfo.length; ++i) {\n            PoolInfo memory info = poolInfo[i];\n            IUniswapV3PoolState pool = IUniswapV3PoolState(info.pool);\n\n            PoolData memory poolData = allPoolData[i];\n            uint256 wordRange = uint256(int256(info.maxWord - info.minWord)) + 1;\n\n            poolData.tickBitmap = new uint256[](wordRange);\n\n            TickInfo[] memory tickInfo = new TickInfo[](256 * wordRange);\n            int24[] memory tickIdxs = new int24[](256 * wordRange);\n\n            uint256 tickArrayIndex = 0;\n\n            // Loop from min to max word inclusive and get all tick bitmaps\n            uint256 wordRangeIdx = 0;\n            for (int16 j = info.minWord; j <= info.maxWord; ++j) {\n                uint256 tickBitmap = pool.tickBitmap(j);\n\n                if (tickBitmap == 0) {\n                    continue;\n                }\n\n                for (uint256 k = 0; k < 256; ++k) {\n                    uint256 bit = 1 << k;\n\n                    bool initialized = (tickBitmap & bit) != 0;\n                    if (initialized) {\n                        int24 tickIndex = int24(int256(wordRangeIdx * 256 + k * uint256(int256(info.tickSpacing))));\n\n                        IUniswapV3PoolState.TickInfo memory tick = pool.ticks(tickIndex);\n\n                        tickIdxs[tickArrayIndex] = tickIndex;\n                        tickInfo[tickArrayIndex] = TickInfo({\n                            liquidityGross: tick.liquidityGross,\n                            liquidityNet: tick.liquidityNet,\n                            initialized: tick.initialized\n                        });\n\n                        ++tickArrayIndex;\n                    }\n                }\n\n                poolData.tickBitmap[wordRangeIdx] = tickBitmap;\n                ++wordRangeIdx;\n            }\n\n            assembly {\n                mstore(tickInfo, tickArrayIndex)\n                mstore(tickIdxs, tickArrayIndex)\n            }\n\n            poolData.ticks = tickInfo;\n            poolData.tickIndices = tickIdxs;\n            allPoolData[i] = poolData;\n        }\n\n        // ensure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory abiEncodedData = abi.encode(allPoolData);\n\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n}\n\nfunction codeSizeIsZero(address target) view returns (bool) {\n    if (target.code.length == 0) {\n        return true;\n    } else {\n        return false;\n    }\n}\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n    struct TickInfo {\n        // the total position liquidity that references this tick\n        uint128 liquidityGross;\n        // amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left),\n        int128 liquidityNet;\n        // fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint256 feeGrowthOutside0X128;\n        uint256 feeGrowthOutside1X128;\n        // the cumulative tick value on the other side of the tick\n        int56 tickCumulativeOutside;\n        // the seconds per unit of liquidity on the _other_ side of this tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint160 secondsPerLiquidityOutsideX128;\n        // the seconds spent on the other side of the tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint32 secondsOutside;\n        // true iff the tick is initialized, i.e. the value is exactly equivalent to the expression liquidityGross != 0\n        // these 8 bits are set to prevent fresh sstores when crossing newly initialized ticks\n        bool initialized;\n    }\n\n    function ticks(int24 tick) external view returns (TickInfo memory);\n\n    /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n    function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n    function slot0()\n        external\n        view\n        returns (\n            uint160 sqrtPriceX96,\n            int24 tick,\n            uint16 observationIndex,\n            uint16 observationCardinality,\n            uint16 observationCardinalityNext,\n            uint8 feeProtocol,\n            bool unlocked\n        );\n\n    function liquidity() external view returns (uint128);\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/GetUniswapV3PoolSlot0BatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\ncontract GetUniswapV3PoolSlot0BatchRequest {\n    struct Slot0Data {\n        int24 tick;\n        uint128 liquidity;\n        uint256 sqrtPrice;\n    }\n\n    constructor(address[] memory pools) {\n        Slot0Data[] memory allSlot0Data = new Slot0Data[](pools.length);\n\n        for (uint256 i = 0; i < pools.length; ++i) {\n            Slot0Data memory slot0Data = allSlot0Data[i];\n            address poolAddress = pools[i];\n\n            IUniswapV3PoolState pool = IUniswapV3PoolState(poolAddress);\n            slot0Data.liquidity = pool.liquidity();\n\n            (slot0Data.sqrtPrice, slot0Data.tick, , , , , ) = pool.slot0();\n\n            allSlot0Data[i] = slot0Data;\n        }\n\n        // ensure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory abiEncodedData = abi.encode(allSlot0Data);\n\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n}\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n    struct TickInfo {\n        // the total position liquidity that references this tick\n        uint128 liquidityGross;\n        // amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left),\n        int128 liquidityNet;\n        // fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint256 feeGrowthOutside0X128;\n        uint256 feeGrowthOutside1X128;\n        // the cumulative tick value on the other side of the tick\n        int56 tickCumulativeOutside;\n        // the seconds per unit of liquidity on the _other_ side of this tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint160 secondsPerLiquidityOutsideX128;\n        // the seconds spent on the other side of the tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint32 secondsOutside;\n        // true iff the tick is initialized, i.e. the value is exactly equivalent to the expression liquidityGross != 0\n        // these 8 bits are set to prevent fresh sstores when crossing newly initialized ticks\n        bool initialized;\n    }\n\n    function ticks(int24 tick) external view returns (TickInfo memory);\n\n    /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n    function tickBitmap(int16 wordPosition) external view returns (uint256);\n\n    function slot0()\n        external\n        view\n        returns (\n            uint160 sqrtPriceX96,\n            int24 tick,\n            uint16 observationIndex,\n            uint16 observationCardinality,\n            uint16 observationCardinalityNext,\n            uint8 feeProtocol,\n            bool unlocked\n        );\n\n    function liquidity() external view returns (uint128);\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/GetUniswapV3PoolTickBitmapBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\ncontract GetUniswapV3PoolTickBitmapBatchRequest {\n    struct TickBitmapInfo {\n        address pool;\n        int16 minWord;\n        int16 maxWord;\n    }\n\n    struct TickBitmaps {\n        int16[] wordPositions;\n        uint256[] tickBitmaps;\n    }\n\n    constructor(TickBitmapInfo[] memory allPoolInfo) {\n        uint256[][] memory allTickBitmaps = new uint256[][](allPoolInfo.length);\n\n        for (uint256 i = 0; i < allPoolInfo.length; ++i) {\n            TickBitmapInfo memory info = allPoolInfo[i];\n            IUniswapV3PoolState pool = IUniswapV3PoolState(info.pool);\n\n            uint256[] memory tickBitmaps = new uint256[](uint16(info.maxWord - info.minWord) + 1);\n\n            uint256 wordIdx = 0;\n            for (int16 j = info.minWord; j <= info.maxWord; ++j) {\n                uint256 tickBitmap = pool.tickBitmap(j);\n\n                if (tickBitmap == 0) {\n                    continue;\n                }\n\n                tickBitmaps[wordIdx] = uint256(int256(j));\n                ++wordIdx;\n\n                tickBitmaps[wordIdx] = tickBitmap;\n                ++wordIdx;\n            }\n\n            assembly {\n                mstore(tickBitmaps, wordIdx)\n            }\n\n            allTickBitmaps[i] = tickBitmaps;\n        }\n\n        // ensure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory abiEncodedData = abi.encode(allTickBitmaps);\n\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n}\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n    /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n    function tickBitmap(int16 wordPosition) external view returns (uint256);\n    function tickSpacing() external view returns (int24);\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/GetUniswapV3PoolTickDataBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @dev This contract is not meant to be deployed. Instead, use a static call with the\n *       deployment bytecode as payload.\n */\n\ncontract GetUniswapV3PoolTickDataBatchRequest {\n    struct TickDataInfo {\n        address pool;\n        int24[] ticks;\n    }\n\n    struct Info {\n        bool initialized;\n        uint128 liquidityGross;\n        int128 liquidityNet;\n    }\n\n    constructor(TickDataInfo[] memory allPoolInfo) {\n        Info[][] memory tickInfoReturn = new Info[][](allPoolInfo.length);\n\n        for (uint256 i = 0; i < allPoolInfo.length; ++i) {\n            Info[] memory tickInfo = new Info[](allPoolInfo[i].ticks.length);\n            for (uint256 j = 0; j < allPoolInfo[i].ticks.length; ++j) {\n                IUniswapV3PoolState.Info memory tick = IUniswapV3PoolState(\n                    allPoolInfo[i].pool\n                ).ticks(allPoolInfo[i].ticks[j]);\n\n                tickInfo[j] = Info({\n                    liquidityGross: tick.liquidityGross,\n                    liquidityNet: tick.liquidityNet,\n                    initialized: tick.initialized\n                });\n            }\n            tickInfoReturn[i] = tickInfo;\n        }\n\n        // ensure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory abiEncodedData = abi.encode(tickInfoReturn);\n\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n}\n\n/// @title Pool state that can change\n/// @notice These methods compose the pool's state, and can change with any frequency including multiple times\n/// per transaction\ninterface IUniswapV3PoolState {\n    struct Info {\n        // the total position liquidity that references this tick\n        uint128 liquidityGross;\n        // amount of net liquidity added (subtracted) when tick is crossed from left to right (right to left),\n        int128 liquidityNet;\n        // fee growth per unit of liquidity on the _other_ side of this tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint256 feeGrowthOutside0X128;\n        uint256 feeGrowthOutside1X128;\n        // the cumulative tick value on the other side of the tick\n        int56 tickCumulativeOutside;\n        // the seconds per unit of liquidity on the _other_ side of this tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint160 secondsPerLiquidityOutsideX128;\n        // the seconds spent on the other side of the tick (relative to the current tick)\n        // only has relative meaning, not absolute — the value depends on when the tick is initialized\n        uint32 secondsOutside;\n        // true iff the tick is initialized, i.e. the value is exactly equivalent to the expression liquidityGross != 0\n        // these 8 bits are set to prevent fresh sstores when crossing newly initialized ticks\n        bool initialized;\n    }\n\n    /// @notice Returns 256 packed tick initialized boolean values. See TickBitmap for more information\n    function tickBitmap(int16 wordPosition) external view returns (uint256);\n    function ticks(int24 tick) external view returns (Info memory);\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/interfaces/IBalancer.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBPool {\n    function getCurrentTokens() external returns (address[] memory);\n    function getDenormalizedWeight(address token) external returns (uint256);\n    function getSwapFee() external returns (uint256);\n    function getBalance(address token) external returns (uint256);\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/interfaces/IUniswapV2.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IUniswapV2Pair {\n    function token0() external view returns (address);\n    function token1() external view returns (address);\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n}\n\ninterface IUniswapV2Factory {\n    function allPairs(uint256 idx) external returns (address);\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/interfaces/IUniswapV3.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IUniswapV3Pool {\n    function fee() external view returns (uint24);\n    function tickSpacing() external view returns (int24);\n    function liquidity() external view returns (uint128);\n    function slot0()\n        external\n        view\n        returns (\n            uint160 sqrtPriceX96,\n            int24 tick,\n            uint16 observationIndex,\n            uint16 observationCardinality,\n            uint16 observationCardinalityNext,\n            uint8 feeProtocol,\n            bool unlocked\n        );\n    function ticks(int24 tick)\n        external\n        view\n        returns (\n            uint128 liquidityGross,\n            int128 liquidityNet,\n            uint256 feeGrowthOutside0X128,\n            uint256 feeGrowthOutside1X128,\n            int56 tickCumulativeOutside,\n            uint160 secondsPerLiquidityOutsideX128,\n            uint32 secondsOutside,\n            bool initialized\n        );\n}\n\ninterface IUniswapV3Factory {\n    function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool);\n}\n"
  },
  {
    "path": "contracts/src/UniswapV3/interfaces/Token.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IERC20 {\n    function decimals() external view returns (uint8);\n    function balanceOf(address) external view returns (uint256);\n}\n"
  },
  {
    "path": "contracts/src/filters/WethValueInPools.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\nimport {IBPool} from \"../interfaces/IBalancer.sol\";\nimport {IUniswapV2Pair} from \"../interfaces/IUniswapV2.sol\";\nimport {IUniswapV2Factory} from \"../interfaces/IUniswapV2.sol\";\nimport {IUniswapV3Pool} from \"../interfaces/IUniswapV3.sol\";\nimport {IUniswapV3Factory} from \"../interfaces/IUniswapV3.sol\";\nimport {IERC20} from \"../interfaces/Token.sol\";\nimport {FixedPointMath} from \"../UniswapV3/FixedPoint.sol\";\n\ncontract WethValueInPools {\n    /// @notice Address of Uniswap V2 factory\n    /// @dev Used as the first priority for quoting WETH value\n    address UNISWAP_V2_FACTORY;\n    //\n    /// @notice Address of Uniswap V3 factory\n    /// @dev Used as the second priority for quoting WETH value\n    address UNISWAP_V3_FACTORY;\n\n    /// @notice Address of WETH\n    address WETH;\n\n    /// @notice The minimum WETH liquidity to consider a `quote` valid.\n    uint256 private constant MIN_WETH_LIQUIDITY = 1 ether;\n\n    address private constant ADDRESS_ZERO = address(0);\n\n    uint8 private constant WETH_DECIMALS = 18;\n\n    constructor(address _uniswapV2Factory, address _uniswapV3Factory, address _weth) {\n        UNISWAP_V2_FACTORY = _uniswapV2Factory;\n        UNISWAP_V3_FACTORY = _uniswapV3Factory;\n        WETH = _weth;\n    }\n\n    /// @notice Enum for pool types\n    enum PoolType {\n        Balancer,\n        UniswapV2,\n        UniswapV3\n    }\n\n    /// @notice Struct for pool info\n    struct PoolInfo {\n        PoolType poolType;\n        address poolAddress;\n    }\n\n    /// @notice Struct for pool info return\n    struct PoolInfoReturn {\n        PoolType poolType;\n        address poolAddress;\n        uint256 wethValue;\n    }\n\n    /// @notice Returns an array of `PoolInfoReturn` for the consumer to determine wether to filter or not to save gas.\n    /// @dev We require a 1 ETH minimum liquidity in the quoting pool for it to be considered.\n    function getWethValueInPools(PoolInfo[] memory pools) public returns (PoolInfoReturn[] memory) {\n        PoolInfoReturn[] memory poolInfoReturns = new PoolInfoReturn[](pools.length);\n        for (uint256 i = 0; i < pools.length; i++) {\n            PoolInfo memory info = pools[i];\n            if (info.poolType == PoolType.Balancer) {\n                uint256 wethValue = handleBalancerPool(info.poolAddress);\n                poolInfoReturns[i] = PoolInfoReturn(info.poolType, info.poolAddress, wethValue);\n            } else if (info.poolType == PoolType.UniswapV2) {\n                uint256 wethValue = handleUniswapV2Pool(info.poolAddress);\n                poolInfoReturns[i] = PoolInfoReturn(info.poolType, info.poolAddress, wethValue);\n            } else if (info.poolType == PoolType.UniswapV3) {\n                uint256 wethValue = handleUniswapV3Pool(info.poolAddress);\n                poolInfoReturns[i] = PoolInfoReturn(info.poolType, info.poolAddress, wethValue);\n            }\n        }\n        return poolInfoReturns;\n    }\n\n    function handleBalancerPool(address pool) internal returns (uint256) {\n        // Get pool tokens\n        address[] memory tokens;\n        try IBPool(pool).getCurrentTokens() returns (address[] memory _tokens) {\n            tokens = _tokens;\n        } catch {\n            return 0;\n        }\n\n        // First check if we have WETH in the pool. If so, return Weth Value * # of tokens in the pool.\n        for (uint256 i = 0; i < tokens.length; i++) {\n            if (tokens[i] == WETH) {\n                try IBPool(pool).getBalance(tokens[i]) returns (uint256 _balance) {\n                    // Obviously assuming an even distribution of value. Which is a \"good enough\" approximation.\n                    // For a value filter.\n                    return _balance * tokens.length;\n                } catch {\n                    return 0;\n                }\n            }\n        }\n\n        address baseToken = tokens[0];\n        uint256 balance;\n        try IBPool(pool).getBalance(baseToken) returns (uint256 _balance) {\n            balance = _balance;\n        } catch {\n            return 0;\n        }\n\n        uint256 wethValue = quoteTokenToWethValue(baseToken, balance);\n        return wethValue * tokens.length;\n    }\n\n    function handleUniswapV2Pool(address pool) internal returns (uint256) {\n        address token0;\n        try IUniswapV2Pair(pool).token0() returns (address _token0) {\n            token0 = _token0;\n        } catch {\n            return 0;\n        }\n        address token1;\n        try IUniswapV2Pair(pool).token1() returns (address _token1) {\n            token1 = _token1;\n        } catch {\n            return 0;\n        }\n        try IUniswapV2Pair(pool).getReserves() returns (uint112 reserve0, uint112 reserve1, uint32) {\n            if (token0 == WETH) {\n                return reserve0 * 2;\n            } else if (token1 == WETH) {\n                return reserve1 * 2;\n            }\n            // No WETH in the pool Quote token0.\n            uint256 wethValue = quoteTokenToWethValue(token0, reserve0);\n            return wethValue * 2;\n        } catch {\n            return 0;\n        }\n    }\n\n    function handleUniswapV3Pool(address pool) internal returns (uint256) {\n        address token0;\n        try IUniswapV2Pair(address(pool)).token0() returns (address _token0) {\n            token0 = _token0;\n        } catch {\n            return 0;\n        }\n        address token1;\n        try IUniswapV2Pair(address(pool)).token1() returns (address _token1) {\n            token1 = _token1;\n        } catch {\n            return 0;\n        }\n\n        if (token0 == WETH) {\n            try IERC20(token0).balanceOf(address(pool)) returns (uint256 balance) {\n                return balance * 2;\n            } catch {\n                return 0;\n            }\n        } else if (token1 == WETH) {\n            try IERC20(token1).balanceOf(address(pool)) returns (uint256 balance) {\n                return balance * 2;\n            } catch {\n                return 0;\n            }\n        }\n\n        // No WETH in the pool Quote token0.\n        try IERC20(token0).balanceOf(address(pool)) returns (uint256 balance) {\n            uint256 wethValue = quoteTokenToWethValue(token0, balance);\n            return wethValue * 2;\n        } catch {\n            return 0;\n        }\n    }\n\n    /// @dev Returns the value of `amount` of `token` in terms of WETH.\n    function quoteTokenToWethValue(address token, uint256 amount) internal returns (uint256) {\n        // Try Uniswap V2.\n        uint128 price = quoteToken(token);\n        if (price > 0) {\n            return FixedPointMath.mul64u(price, amount);\n        } else {\n            return price;\n        }\n    }\n\n    /// @dev Quotes a Q64 quote of `token` in terms of WETH.\n    function quoteToken(address token) internal returns (uint128) {\n        // Get the token decimals\n        uint128 price;\n        // Try Uniswap V2.\n        price = quoteTokenUniswapV2(token);\n        if (price > 0) {\n            return price;\n        }\n        // Try Uniswap V3.\n        price = quoteTokenUniswapV3(token);\n        return price;\n    }\n\n    function quoteTokenUniswapV2(address token) internal returns (uint128 price) {\n        // Get the pair\n        IUniswapV2Pair pair = IUniswapV2Pair(IUniswapV2Factory(UNISWAP_V2_FACTORY).getPair(token, WETH));\n        if (address(pair) == ADDRESS_ZERO) {\n            return 0;\n        }\n\n        // Get the reserves\n        // (uint112 reserve0, uint112 reserve1, ) = pair.getReserves();\n        uint112 reserve0;\n        uint112 reserve1;\n        try pair.getReserves() returns (uint112 _reserve0, uint112 _reserve1, uint32) {\n            reserve0 = _reserve0;\n            reserve1 = _reserve1;\n        } catch {\n            return 0;\n        }\n        if (reserve0 == 0 || reserve1 == 0) {\n            return 0;\n        }\n\n        // Get the decimals of token.\n        (uint8 tokenDecimals, bool tokenDecimalsSuccess) = getTokenDecimalsUnsafe(token);\n        if (!tokenDecimalsSuccess) {\n            return 0;\n        }\n\n        // Normalize r0/r1 to 18 decimals.\n        uint112 reserveWeth = token < WETH ? reserve1 : reserve0;\n        uint112 reserveToken = token < WETH ? reserve0 : reserve1;\n\n        reserveToken = tokenDecimals <= WETH_DECIMALS\n            ? uint112(reserveToken * 10 ** (WETH_DECIMALS - tokenDecimals))\n            : uint112(reserveToken / 10 ** (tokenDecimals - WETH_DECIMALS));\n        price = FixedPointMath.divuu(reserveWeth, reserveToken);\n    }\n\n    function quoteTokenUniswapV3(address token) internal returns (uint128) {\n        uint16[3] memory feeTiers = [500, 3000, 10000];\n        IUniswapV3Pool pool;\n        for (uint256 i = 0; i < feeTiers.length; ++i) {\n            // Get the pool\n            IUniswapV3Pool pair =\n                IUniswapV3Pool(IUniswapV3Factory(UNISWAP_V3_FACTORY).getPool(token, WETH, feeTiers[i]));\n            if (address(pool) != ADDRESS_ZERO) {\n                pool = pair;\n                break;\n            }\n        }\n\n        if (address(pool) == ADDRESS_ZERO) {\n            return 0;\n        }\n\n        // Get slot 0 sqrtPriceX96\n        uint160 sqrtPriceX96;\n        try pool.slot0() returns (uint160 _sqrtPriceX96, int24, uint16, uint16, uint16, uint8, bool) {\n            sqrtPriceX96 = _sqrtPriceX96;\n        } catch {\n            return 0;\n        }\n\n        bool token0IsReserve0 = token < WETH;\n        (uint8 tokenDecimals, bool token0DecimalsSuccess) = getTokenDecimalsUnsafe(token);\n        if (!token0DecimalsSuccess) {\n            return 0;\n        }\n        // Q128 -> Q64\n        return uint128(\n            FixedPointMath.fromSqrtX96(\n                sqrtPriceX96,\n                token0IsReserve0,\n                token0IsReserve0 ? int8(tokenDecimals) : int8(WETH_DECIMALS),\n                token0IsReserve0 ? int8(WETH_DECIMALS) : int8(tokenDecimals)\n            ) >> 64\n        );\n    }\n\n    /// @notice returns true as the second return value if the token decimals can be successfully retrieved\n    function getTokenDecimalsUnsafe(address token) internal returns (uint8, bool) {\n        (bool tokenDecimalsSuccess, bytes memory tokenDecimalsData) =\n            token.call{gas: 20000}(abi.encodeWithSignature(\"decimals()\"));\n\n        if (tokenDecimalsSuccess) {\n            uint256 tokenDecimals;\n\n            if (tokenDecimalsData.length == 32) {\n                (tokenDecimals) = abi.decode(tokenDecimalsData, (uint256));\n\n                if (tokenDecimals == 0 || tokenDecimals > 255) {\n                    return (0, false);\n                } else {\n                    return (uint8(tokenDecimals), true);\n                }\n            } else {\n                return (0, false);\n            }\n        } else {\n            return (0, false);\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/src/filters/WethValueInPoolsBatchRequest.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\nimport \"./WethValueInPools.sol\";\n\ncontract WethValueInPoolsBatchRequest is WethValueInPools {\n    constructor(\n        address _uniswapV2Factory,\n        address _uniswapV3Factory,\n        address _weth,\n        WethValueInPools.PoolInfo[] memory pools\n    ) WethValueInPools(_uniswapV2Factory, _uniswapV3Factory, _weth) {\n        WethValueInPools.PoolInfoReturn[] memory poolInfoReturn = getWethValueInPools(pools);\n        // insure abi encoding, not needed here but increase reusability for different return types\n        // note: abi.encode add a first 32 bytes word with the address of the original data\n        bytes memory abiEncodedData = abi.encode(poolInfoReturn);\n        assembly {\n            // Return from the start of the data (discarding the original data address)\n            // up to the end of the memory used\n            let dataStart := add(abiEncodedData, 0x20)\n            return(dataStart, sub(msize(), dataStart))\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/src/interfaces/IBalancer.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IBPool {\n    function getCurrentTokens() external returns (address[] memory);\n    function getDenormalizedWeight(address token) external returns (uint256);\n    function getSwapFee() external returns (uint256);\n    function getBalance(address token) external returns (uint256);\n}\n"
  },
  {
    "path": "contracts/src/interfaces/IUniswapV2.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IUniswapV2Pair {\n    function token0() external view returns (address);\n    function token1() external view returns (address);\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n}\n\ninterface IUniswapV2Factory {\n    function allPairs(uint256 idx) external returns (address);\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n}\n"
  },
  {
    "path": "contracts/src/interfaces/IUniswapV3.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IUniswapV3Pool {\n    function fee() external view returns (uint24);\n    function tickSpacing() external view returns (int24);\n    function liquidity() external view returns (uint128);\n    function slot0()\n        external\n        view\n        returns (\n            uint160 sqrtPriceX96,\n            int24 tick,\n            uint16 observationIndex,\n            uint16 observationCardinality,\n            uint16 observationCardinalityNext,\n            uint8 feeProtocol,\n            bool unlocked\n        );\n    function ticks(int24 tick)\n        external\n        view\n        returns (\n            uint128 liquidityGross,\n            int128 liquidityNet,\n            uint256 feeGrowthOutside0X128,\n            uint256 feeGrowthOutside1X128,\n            int56 tickCumulativeOutside,\n            uint160 secondsPerLiquidityOutsideX128,\n            uint32 secondsOutside,\n            bool initialized\n        );\n}\n\ninterface IUniswapV3Factory {\n    function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool);\n}\n"
  },
  {
    "path": "contracts/src/interfaces/Token.sol",
    "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IERC20 {\n    function decimals() external view returns (uint8);\n    function balanceOf(address) external view returns (uint256);\n}\n"
  },
  {
    "path": "contracts/test/FixedPoint.t.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/UniswapV3/FixedPoint.sol\";\n\ncontract FixedPointTest is Test {\n    /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n    uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n    /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n    uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n    function setUp() public {}\n\n    function test_divuu_never_reverts(uint128 a, uint128 b) public pure {\n        FixedPointMath.divuu(a, b);\n    }\n\n    function test_mul64u_never_reverts(uint128 a, uint256 b) public pure {\n        FixedPointMath.mul64u(a, b);\n    }\n\n    function test_from_sqrt_x_96_never_reverts(\n        uint160 x,\n        bool token0IsReserve0,\n        int8 token0Decimals,\n        int8 token1Decimals\n    ) public pure {\n        // Bound x from min_sqrt_x_96 to max_sqrt_x_96\n        if (x >= MIN_SQRT_RATIO || x <= MAX_SQRT_RATIO) {\n            FixedPointMath.fromSqrtX96(x, token0IsReserve0, token0Decimals, token1Decimals);\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/test/WethValueInPools.t.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/filters/WethValueInPools.sol\";\n\ncontract WethValueInPoolsTest is Test {\n    WethValueInPools public wethValueInPools;\n    address uniswapV2Factory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;\n    address uniswapV3Factory = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n    address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n    address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;\n    address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;\n\n    function setUp() public {\n        wethValueInPools = new WethValueInPools(uniswapV2Factory, uniswapV3Factory, WETH);\n    }\n\n    function test_getWethValueInPools_validWeth() public {\n        WethValueInPools.PoolInfo[] memory testFixtureValidWeth = new WethValueInPools.PoolInfo[](3);\n        testFixtureValidWeth[0] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.Balancer,\n            poolAddress: 0x8a649274E4d777FFC6851F13d23A86BBFA2f2Fbf\n        });\n        testFixtureValidWeth[1] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV2,\n            poolAddress: 0x397FF1542f962076d0BFE58eA045FfA2d347ACa0\n        });\n        testFixtureValidWeth[2] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV3,\n            poolAddress: 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\n        });\n        WethValueInPools.PoolInfoReturn[] memory pools = wethValueInPools.getWethValueInPools(testFixtureValidWeth);\n        assertEq(pools.length, 3);\n        // Check weth value > 0\n        assertGt(pools[0].wethValue, 0);\n        assertGt(pools[1].wethValue, 0);\n        assertGt(pools[2].wethValue, 0);\n    }\n\n    function test_getWethValueInPools_validNoWeth() public {\n        WethValueInPools.PoolInfo[] memory testFixtureValidNoWeth = new WethValueInPools.PoolInfo[](3);\n        testFixtureValidNoWeth[0] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.Balancer,\n            poolAddress: 0xE5D1fAB0C5596ef846DCC0958d6D0b20E1Ec4498\n        });\n        testFixtureValidNoWeth[1] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV2,\n            poolAddress: 0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5\n        });\n        testFixtureValidNoWeth[2] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV3,\n            poolAddress: 0x6c6Bc977E13Df9b0de53b251522280BB72383700\n        });\n        WethValueInPools.PoolInfoReturn[] memory pools = wethValueInPools.getWethValueInPools(testFixtureValidNoWeth);\n        assertEq(pools.length, 3);\n        // Check weth value > 0\n        assertGt(pools[0].wethValue, 0);\n        assertGt(pools[1].wethValue, 0);\n        assertGt(pools[2].wethValue, 0);\n    }\n\n    function test_getWethValueInPools_invalid_no_revert() public {\n        WethValueInPools.PoolInfo[] memory testFixtureInvalid = new WethValueInPools.PoolInfo[](3);\n        testFixtureInvalid[0] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.Balancer,\n            poolAddress: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\n        });\n        testFixtureInvalid[1] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV2,\n            poolAddress: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\n        });\n        testFixtureInvalid[2] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV3,\n            poolAddress: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\n        });\n        WethValueInPools.PoolInfoReturn[] memory pools = wethValueInPools.getWethValueInPools(testFixtureInvalid);\n        assertEq(pools.length, 3);\n        // Should all be zero\n        assertEq(pools[0].wethValue, 0);\n        assertEq(pools[1].wethValue, 0);\n        assertEq(pools[2].wethValue, 0);\n    }\n}\n"
  },
  {
    "path": "contracts/test/WethValueInPoolsBatchRequest.t.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/filters/WethValueInPoolsBatchRequest.sol\";\n\ncontract WethValueInPoolsBatchRequestTest is Test {\n    address uniswapV2Factory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;\n    address uniswapV3Factory = 0x1F98431c8aD98523631AE4a59f267346ea31F984;\n    address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n    address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;\n    address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;\n\n    function setUp() public {}\n\n    function test_WethValueInPoolsBatchRequest_validWeth() public {\n        WethValueInPools.PoolInfo[] memory testFixtureValidWeth = new WethValueInPools.PoolInfo[](3);\n        testFixtureValidWeth[0] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.Balancer,\n            poolAddress: 0x8a649274E4d777FFC6851F13d23A86BBFA2f2Fbf\n        });\n        testFixtureValidWeth[1] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV2,\n            poolAddress: 0x397FF1542f962076d0BFE58eA045FfA2d347ACa0\n        });\n        testFixtureValidWeth[2] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV3,\n            poolAddress: 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\n        });\n\n        bytes memory returnData = address(\n            new WethValueInPoolsBatchRequest(uniswapV2Factory, uniswapV3Factory, WETH, testFixtureValidWeth)\n        ).code;\n        WethValueInPools.PoolInfoReturn[] memory pools = abi.decode(returnData, (WethValueInPools.PoolInfoReturn[]));\n\n        assertEq(pools.length, 3);\n        // Check weth value > 0 and valid pool address and pool type\n        for (uint256 i = 0; i < pools.length; i++) {\n            assertGt(pools[i].wethValue, 0);\n            assertEq(uint8(pools[i].poolType), uint8(testFixtureValidWeth[i].poolType));\n            assertEq(pools[i].poolAddress, testFixtureValidWeth[i].poolAddress);\n        }\n    }\n\n    function test_WethValueInPoolsBatchRequest_validNoWeth() public {\n        WethValueInPools.PoolInfo[] memory testFixtureValidNoWeth = new WethValueInPools.PoolInfo[](3);\n        testFixtureValidNoWeth[0] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.Balancer,\n            poolAddress: 0xE5D1fAB0C5596ef846DCC0958d6D0b20E1Ec4498\n        });\n        testFixtureValidNoWeth[1] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV2,\n            poolAddress: 0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5\n        });\n        testFixtureValidNoWeth[2] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV3,\n            poolAddress: 0x6c6Bc977E13Df9b0de53b251522280BB72383700\n        });\n\n        bytes memory returnData = address(\n            new WethValueInPoolsBatchRequest(uniswapV2Factory, uniswapV3Factory, WETH, testFixtureValidNoWeth)\n        ).code;\n        WethValueInPools.PoolInfoReturn[] memory pools = abi.decode(returnData, (WethValueInPools.PoolInfoReturn[]));\n\n        assertEq(pools.length, 3);\n        // Check weth value > 0 and valid pool address and pool type\n        for (uint256 i = 0; i < pools.length; i++) {\n            assertGt(pools[i].wethValue, 0);\n            assertEq(uint8(pools[i].poolType), uint8(testFixtureValidNoWeth[i].poolType));\n            assertEq(pools[i].poolAddress, testFixtureValidNoWeth[i].poolAddress);\n        }\n    }\n\n    function test_WethValueInPoolsBatchRequest_invalid_no_revert() public {\n        WethValueInPools.PoolInfo[] memory testFixtureInvalid = new WethValueInPools.PoolInfo[](3);\n        testFixtureInvalid[0] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.Balancer,\n            poolAddress: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\n        });\n        testFixtureInvalid[1] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV2,\n            poolAddress: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\n        });\n        testFixtureInvalid[2] = WethValueInPools.PoolInfo({\n            poolType: WethValueInPools.PoolType.UniswapV3,\n            poolAddress: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\n        });\n\n        bytes memory returnData =\n            address(new WethValueInPoolsBatchRequest(uniswapV2Factory, uniswapV3Factory, WETH, testFixtureInvalid)).code;\n        WethValueInPools.PoolInfoReturn[] memory pools = abi.decode(returnData, (WethValueInPools.PoolInfoReturn[]));\n\n        assertEq(pools.length, 3);\n        // All weth values should be zero\n        for (uint256 i = 0; i < pools.length; i++) {\n            assertEq(pools[i].wethValue, 0);\n            assertEq(uint8(pools[i].poolType), uint8(testFixtureInvalid[i].poolType));\n            assertEq(pools[i].poolAddress, testFixtureInvalid[i].poolAddress);\n        }\n    }\n}\n"
  },
  {
    "path": "dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"cargo\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n  - package-ecosystem: \"docker\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\""
  },
  {
    "path": "examples/filters.rs",
    "content": "use alloy::{\n    primitives::address,\n    providers::ProviderBuilder,\n    rpc::client::ClientBuilder,\n    transports::layers::{RetryBackoffLayer, ThrottleLayer},\n};\nuse amms::{\n    amms::uniswap_v2::UniswapV2Factory,\n    state_space::{\n        filters::whitelist::{PoolWhitelistFilter, TokenWhitelistFilter},\n        StateSpaceBuilder,\n    },\n};\nuse std::sync::Arc;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    tracing_subscriber::fmt::init();\n    let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n\n    let client = ClientBuilder::default()\n        .layer(ThrottleLayer::new(500))\n        .layer(RetryBackoffLayer::new(5, 200, 330))\n        .http(rpc_endpoint.parse()?);\n\n    let provider = Arc::new(ProviderBuilder::new().connect_client(client));\n\n    let factories = vec![\n        // UniswapV2\n        UniswapV2Factory::new(\n            address!(\"5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\"),\n            300,\n            10000835,\n        )\n        .into(),\n    ];\n\n    /*  PoolFilters are applied all AMMs when syncing the state space.\n       Filters have two \"stages\", `FilterStage::Discovery` or `FilterStage::Sync`.\n       Discovery filters are applied to AMMs after the `StateSpaceManager` has processed all pool created events.\n       Sync filters are applied to AMMs after the `StateSpaceManager` has processed all pool sync events.\n       This allows for efficient syncing of the state space by minimizing the amount of pools that need to sync state.\n       In the following example, the `PoolWhitelistFilter` is applied to the `Discovery` stage\n       and the `TokenWhitelistFilter` is applied to the `Sync` stage. Rather than syncing all pools from the factory,\n       only the whitelisted pools are synced. The `TokenWhitelistFilter` is applied after syncing since pool creation logs\n       do not always emit the tokens included in the pool, but this data will always be populated after syncing.\n    */\n    let filters = vec![\n        PoolWhitelistFilter::new(vec![address!(\"88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\")]).into(),\n        TokenWhitelistFilter::new(vec![address!(\"A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\")])\n            .into(),\n    ];\n\n    let _state_space_manager = StateSpaceBuilder::new(provider.clone())\n        .with_factories(factories)\n        .with_filters(filters)\n        .sync()\n        .await;\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/simulate_swap.rs",
    "content": "use alloy::eips::BlockId;\nuse alloy::primitives::{Address, U256};\nuse alloy::transports::layers::ThrottleLayer;\nuse alloy::{\n    primitives::address, providers::ProviderBuilder, rpc::client::ClientBuilder,\n    transports::layers::RetryBackoffLayer,\n};\nuse amms::amms::amm::AutomatedMarketMaker;\nuse amms::amms::uniswap_v3::UniswapV3Pool;\nuse std::sync::Arc;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n    let client = ClientBuilder::default()\n        .layer(ThrottleLayer::new(50))\n        .layer(RetryBackoffLayer::new(5, 200, 330))\n        .http(rpc_endpoint.parse()?);\n\n    let provider = Arc::new(ProviderBuilder::new().connect_client(client));\n\n    let pool = UniswapV3Pool::new(address!(\"88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\"))\n        .init(BlockId::latest(), provider)\n        .await?;\n\n    // Note that the token out does not need to be specified when\n    // simulating a swap for pools with only two tokens.\n    let amount_out = pool.simulate_swap(\n        pool.token_a.address,\n        Address::default(),\n        U256::from(1000000),\n    )?;\n    println!(\"Amount out: {:?}\", amount_out);\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/state_space_builder.rs",
    "content": "use std::sync::Arc;\n\nuse alloy::{\n    primitives::address,\n    providers::ProviderBuilder,\n    rpc::client::ClientBuilder,\n    transports::layers::{RetryBackoffLayer, ThrottleLayer},\n};\nuse amms::{\n    amms::{\n        erc_4626::ERC4626Vault,\n        uniswap_v2::{UniswapV2Factory, UniswapV2Pool},\n        uniswap_v3::{UniswapV3Factory, UniswapV3Pool},\n    },\n    state_space::StateSpaceBuilder,\n};\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    tracing_subscriber::fmt::init();\n    let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n\n    let client = ClientBuilder::default()\n        .layer(ThrottleLayer::new(500))\n        .layer(RetryBackoffLayer::new(5, 200, 330))\n        .http(rpc_endpoint.parse()?);\n\n    let provider = Arc::new(ProviderBuilder::new().connect_client(client));\n\n    /*\n       The `StateSpaceBuilder` is used to sync a state space of AMMs.\n\n       When specifying a set of factories to sync from, the `sync()` method fetches all pool creation logs\n       from the factory contracts specified and syncs all pools to the latest block. This method returns a\n       `StateSpaceManager` which can be used to subscribe to state changes and interact with AMMs\n       the state space.\n    */\n    let factories = vec![\n        // UniswapV2\n        UniswapV2Factory::new(\n            address!(\"5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\"),\n            300,\n            10000835,\n        )\n        .into(),\n        // UniswapV3\n        UniswapV3Factory::new(\n            address!(\"1F98431c8aD98523631AE4a59f267346ea31F984\"),\n            12369621,\n        )\n        .into(),\n    ];\n\n    let _state_space_manager = StateSpaceBuilder::new(provider.clone())\n        .with_factories(factories.clone())\n        .sync()\n        .await?;\n\n    // ======================================================================================== //\n\n    /*\n    You can also sync pools directly without specifying factories. This is great for when you only\n    need to track a handful of specific pools.\n    */\n    let amms = vec![\n        UniswapV2Pool::new(address!(\"B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc\"), 300).into(),\n        UniswapV3Pool::new(address!(\"88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\")).into(),\n    ];\n\n    let _state_space_manager = StateSpaceBuilder::new(provider.clone())\n        .with_amms(amms)\n        .sync()\n        .await?;\n\n    // ======================================================================================== //\n\n    /*\n    Additionally, you can specify specific factories to discover and sync pools from, as well as\n    specify specific AMMs to sync. This can be helpful when there isnt a factory for a given AMM\n    as is the case with ERC4626 vaults.\n    */\n    let amms = vec![ERC4626Vault::new(address!(\"163538E22F4d38c1eb21B79939f3d2ee274198Ff\")).into()];\n\n    let _state_space_manager = StateSpaceBuilder::new(provider.clone())\n        .with_factories(factories)\n        .with_amms(amms)\n        .sync()\n        .await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/subscribe.rs",
    "content": "use alloy::{\n    primitives::address,\n    providers::ProviderBuilder,\n    rpc::client::ClientBuilder,\n    transports::layers::{RetryBackoffLayer, ThrottleLayer},\n};\nuse amms::{amms::uniswap_v2::UniswapV2Factory, state_space::StateSpaceBuilder};\nuse futures::StreamExt;\nuse std::sync::Arc;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    tracing_subscriber::fmt::init();\n    let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n    let client = ClientBuilder::default()\n        .layer(ThrottleLayer::new(500))\n        .layer(RetryBackoffLayer::new(5, 200, 330))\n        .http(rpc_endpoint.parse()?);\n\n    let sync_provider = Arc::new(ProviderBuilder::new().connect_client(client));\n\n    let factories = vec![UniswapV2Factory::new(\n        address!(\"5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\"),\n        300,\n        10000835,\n    )\n    .into()];\n\n    let state_space_manager = StateSpaceBuilder::new(sync_provider.clone())\n        .with_factories(factories)\n        .sync()\n        .await?;\n\n    /*\n    The subscribe method listens for new blocks and fetches\n    all logs matching any `sync_events()` specified by the AMM variants in the state space.\n    Under the hood, this method applies all state changes to any affected AMMs and returns a Vec of\n    addresses, indicating which AMMs have been updated.\n    */\n    let mut stream = state_space_manager.subscribe().await?.take(5);\n    while let Some(updated_amms) = stream.next().await {\n        if let Ok(amms) = updated_amms {\n            println!(\"Updated AMMs: {:?}\", amms);\n        }\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/swap_calldata.rs",
    "content": "use alloy::eips::BlockId;\nuse alloy::primitives::U256;\nuse alloy::transports::layers::ThrottleLayer;\nuse alloy::{\n    primitives::address, providers::ProviderBuilder, rpc::client::ClientBuilder,\n    transports::layers::RetryBackoffLayer,\n};\nuse amms::amms::{amm::AutomatedMarketMaker, uniswap_v2::UniswapV2Pool};\nuse std::sync::Arc;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n    let client = ClientBuilder::default()\n        .layer(ThrottleLayer::new(500))\n        .layer(RetryBackoffLayer::new(5, 200, 330))\n        .http(rpc_endpoint.parse()?);\n\n    let provider = Arc::new(ProviderBuilder::new().connect_client(client));\n\n    let pool = UniswapV2Pool::new(address!(\"B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc\"), 300)\n        .init(BlockId::latest(), provider)\n        .await?;\n\n    let to_address = address!(\"DecafC0ffee15BadDecafC0ffee15BadDecafC0f\");\n    let swap_calldata = pool.swap_calldata(U256::from(10000), U256::ZERO, to_address, vec![]);\n\n    println!(\"Swap calldata: {:?}\", swap_calldata);\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/sync_macro.rs",
    "content": "use std::sync::Arc;\n\nuse alloy::{\n    primitives::address,\n    providers::ProviderBuilder,\n    rpc::client::ClientBuilder,\n    transports::layers::{RetryBackoffLayer, ThrottleLayer},\n};\nuse amms::{\n    amms::{uniswap_v2::UniswapV2Factory, uniswap_v3::UniswapV3Factory},\n    state_space::{\n        filters::{\n            whitelist::{PoolWhitelistFilter, TokenWhitelistFilter},\n            PoolFilter,\n        },\n        StateSpaceBuilder,\n    },\n    sync,\n};\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    tracing_subscriber::fmt::init();\n    let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n\n    let client = ClientBuilder::default()\n        .layer(ThrottleLayer::new(500))\n        .layer(RetryBackoffLayer::new(5, 200, 330))\n        .http(rpc_endpoint.parse()?);\n\n    let provider = Arc::new(ProviderBuilder::new().connect_client(client));\n\n    let factories = vec![\n        // UniswapV2\n        UniswapV2Factory::new(\n            address!(\"5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f\"),\n            300,\n            10000835,\n        )\n        .into(),\n        // UniswapV3\n        UniswapV3Factory::new(\n            address!(\"1F98431c8aD98523631AE4a59f267346ea31F984\"),\n            12369621,\n        )\n        .into(),\n    ];\n\n    let filters: Vec<PoolFilter> = vec![\n        PoolWhitelistFilter::new(vec![address!(\"88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\")]).into(),\n        TokenWhitelistFilter::new(vec![address!(\"A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\")])\n            .into(),\n    ];\n\n    let _state_space_manager = sync!(factories, filters, provider);\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/amms/abi/GetBalancerPoolDataBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"pools\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b50604051610de8380380610de8833981810160405281019061003191906108d3565b5f815167ffffffffffffffff81111561004d5761004c61073d565b5b60405190808252806020026020018201604052801561008657816020015b6100736106e4565b81526020019060019003908161006b5790505b5090505f5f90505b8251811015610533575f8382815181106100ab576100aa61091a565b5b602002602001015190506100c48161056160201b60201c565b156100cf5750610528565b6100d76106e4565b5f8273ffffffffffffffffffffffffffffffffffffffff1663cc77828d6040518163ffffffff1660e01b81526004015f604051808303815f875af1158015610121573d5f5f3e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061014991906108d3565b90505f815167ffffffffffffffff8111156101675761016661073d565b5b6040519080825280602002602001820160405280156101955781602001602082028036833780820191505090505b5090505f825167ffffffffffffffff8111156101b4576101b361073d565b5b6040519080825280602002602001820160405280156101e25781602001602082028036833780820191505090505b5090505f835167ffffffffffffffff8111156102015761020061073d565b5b60405190808252806020026020018201604052801561022f5781602001602082028036833780820191505090505b5090505f5f90505b8451811015610275576102698582815181106102565761025561091a565b5b602002602001015161056160201b60201c565b50806001019050610237565b505f5f90505b8451811015610459575f6102ae86838151811061029b5761029a61091a565b5b602002602001015161059260201b60201c565b90505f8160ff16036102c0575061044e565b808583815181106102d4576102d361091a565b5b602002602001019060ff16908160ff16815250508773ffffffffffffffffffffffffffffffffffffffff1663948d8ce68784815181106103175761031661091a565b5b60200260200101516040518263ffffffff1660e01b815260040161033b9190610956565b6020604051808303815f875af1158015610357573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037b91906109a2565b83838151811061038e5761038d61091a565b5b6020026020010181815250508773ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f8784815181106103c9576103c861091a565b5b60200260200101516040518263ffffffff1660e01b81526004016103ed9190610956565b6020604051808303815f875af1158015610409573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042d91906109a2565b8483815181106104405761043f61091a565b5b602002602001018181525050505b80600101905061027b565b508573ffffffffffffffffffffffffffffffffffffffff1663d4cadf686040518163ffffffff1660e01b81526004016020604051808303815f875af11580156104a4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104c891906109a2565b856080019063ffffffff16908163ffffffff168152505083855f0181905250828560200181905250818560400181905250808560600181905250848888815181106105165761051561091a565b5b60200260200101819052505050505050505b80600101905061008e565b505f816040516020016105469190610d5f565b60405160208183030381529060405290506020810180590381f35b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b03610589576001905061058d565b5f90505b919050565b5f5f5f8373ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161063c9190610dd1565b5f604051808303815f865af19150503d805f8114610675576040519150601f19603f3d011682016040523d82523d5f602084013e61067a565b606091505b509150915081156106d9575f60208251036106ce57818060200190518101906106a391906109a2565b90505f8114806106b3575060ff81115b156106c3575f93505050506106df565b8093505050506106df565b5f93505050506106df565b5f925050505b919050565b6040518060a00160405280606081526020016060815260200160608152602001606081526020015f63ffffffff1681525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6107738261072d565b810181811067ffffffffffffffff821117156107925761079161073d565b5b80604052505050565b5f6107a4610718565b90506107b0828261076a565b919050565b5f67ffffffffffffffff8211156107cf576107ce61073d565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61080d826107e4565b9050919050565b61081d81610803565b8114610827575f5ffd5b50565b5f8151905061083881610814565b92915050565b5f61085061084b846107b5565b61079b565b90508083825260208201905060208402830185811115610873576108726107e0565b5b835b8181101561089c5780610888888261082a565b845260208401935050602081019050610875565b5050509392505050565b5f82601f8301126108ba576108b9610729565b5b81516108ca84826020860161083e565b91505092915050565b5f602082840312156108e8576108e7610721565b5b5f82015167ffffffffffffffff81111561090557610904610725565b5b610911848285016108a6565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b61095081610803565b82525050565b5f6020820190506109695f830184610947565b92915050565b5f819050919050565b6109818161096f565b811461098b575f5ffd5b50565b5f8151905061099c81610978565b92915050565b5f602082840312156109b7576109b6610721565b5b5f6109c48482850161098e565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610a2881610803565b82525050565b5f610a398383610a1f565b60208301905092915050565b5f602082019050919050565b5f610a5b826109f6565b610a658185610a00565b9350610a7083610a10565b805f5b83811015610aa0578151610a878882610a2e565b9750610a9283610a45565b925050600181019050610a73565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f60ff82169050919050565b610aeb81610ad6565b82525050565b5f610afc8383610ae2565b60208301905092915050565b5f602082019050919050565b5f610b1e82610aad565b610b288185610ab7565b9350610b3383610ac7565b805f5b83811015610b63578151610b4a8882610af1565b9750610b5583610b08565b925050600181019050610b36565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610ba28161096f565b82525050565b5f610bb38383610b99565b60208301905092915050565b5f602082019050919050565b5f610bd582610b70565b610bdf8185610b7a565b9350610bea83610b8a565b805f5b83811015610c1a578151610c018882610ba8565b9750610c0c83610bbf565b925050600181019050610bed565b5085935050505092915050565b5f63ffffffff82169050919050565b610c3f81610c27565b82525050565b5f60a083015f8301518482035f860152610c5f8282610a51565b91505060208301518482036020860152610c798282610b14565b91505060408301518482036040860152610c938282610bcb565b91505060608301518482036060860152610cad8282610bcb565b9150506080830151610cc26080860182610c36565b508091505092915050565b5f610cd88383610c45565b905092915050565b5f602082019050919050565b5f610cf6826109cd565b610d0081856109d7565b935083602082028501610d12856109e7565b805f5b85811015610d4d5784840389528151610d2e8582610ccd565b9450610d3983610ce0565b925060208a01995050600181019050610d15565b50829750879550505050505092915050565b5f6020820190508181035f830152610d778184610cec565b905092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610dab82610d7f565b610db58185610d89565b9350610dc5818560208601610d93565b80840191505092915050565b5f610ddc8284610da1565b91508190509291505056fe\",\"sourceMap\":\"550:3022:23:-:0;;;754:1990;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;800:29;847:5;:12;832:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;800:60;;876:9;888:1;876:13;;871:1526;895:5;:12;891:1;:16;871:1526;;;928:19;950:5;956:1;950:8;;;;;;;;:::i;:::-;;;;;;;;928:30;;977:27;992:11;977:14;;;:27;;:::i;:::-;973:41;;;1006:8;;;973:41;1029:24;;:::i;:::-;1098:23;1131:11;1124:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1098:64;;1176:23;1214:6;:13;1202:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1176:52;;1242:26;1285:6;:13;1271:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1242:57;;1313:24;1354:6;:13;1340:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1313:55;;1388:9;1400:1;1388:13;;1383:156;1407:6;:13;1403:1;:17;1383:156;;;1449:25;1464:6;1471:1;1464:9;;;;;;;;:::i;:::-;;;;;;;;1449:14;;;:25;;:::i;:::-;1445:80;1422:3;;;;;1383:156;;;;1601:9;1613:1;1601:13;;1596:485;1620:6;:13;1616:1;:17;1596:485;;;1658:19;1680:27;1697:6;1704:1;1697:9;;;;;;;;:::i;:::-;;;;;;;;1680:16;;;:27;;:::i;:::-;1658:49;;1746:1;1729:13;:18;;;1725:147;;1771:8;;;1725:147;1840:13;1826:8;1835:1;1826:11;;;;;;;;:::i;:::-;;;;;;;:27;;;;;;;;;;;1909:11;1902:41;;;1965:6;1972:1;1965:9;;;;;;;;:::i;:::-;;;;;;;;1902:90;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1889:7;1897:1;1889:10;;;;;;;;:::i;:::-;;;;;;;:103;;;;;2032:11;2025:30;;;2056:6;2063:1;2056:9;;;;;;;;:::i;:::-;;;;;;;;2025:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2010:9;2020:1;2010:12;;;;;;;;:::i;:::-;;;;;;;:56;;;;;1640:441;1596:485;1635:3;;;;;1596:485;;;;2157:11;2150:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2128:8;:12;;:55;;;;;;;;;;;2215:6;2197:8;:15;;:24;;;;2255:8;2235;:17;;:28;;;;2298:9;2277:8;:18;;:30;;;;2340:7;2321:8;:16;;:26;;;;2378:8;2361:11;2373:1;2361:14;;;;;;;;:::i;:::-;;;;;;;:25;;;;914:1483;;;;;;871:1526;909:3;;;;;871:1526;;;;2407:28;2449:11;2438:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;2407:54;;2668:4;2651:15;2647:26;2717:9;2708:7;2704:23;2693:9;2686:42;3377:193;3440:4;3482:1;3460:6;:18;;;:23;3456:108;;3506:4;3499:11;;;;3456:108;3548:5;3541:12;;3377:193;;;;:::o;2750:621::-;2809:5;2827:12;2841:17;2862:5;:10;;2886:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2862:71;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2826:107;;;;2948:7;2944:421;;;2971:16;3020:2;3005:4;:11;:17;3001:315;;3066:4;3055:27;;;;;;;;;;;;:::i;:::-;3042:40;;3116:1;3104:8;:13;:31;;;;3132:3;3121:8;:14;3104:31;3100:155;;;3166:1;3159:8;;;;;;;3100:155;3227:8;3214:22;;;;;;;3001:315;3300:1;3293:8;;;;;;;2944:421;3353:1;3346:8;;;;2750:621;;;;:::o;550:3022::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:311::-;1250:4;1340:18;1332:6;1329:30;1326:56;;;1362:18;;:::i;:::-;1326:56;1412:4;1404:6;1400:17;1392:25;;1472:4;1466;1462:15;1454:23;;1173:311;;;:::o;1490:117::-;1599:1;1596;1589:12;1613:126;1650:7;1690:42;1683:5;1679:54;1668:65;;1613:126;;;:::o;1745:96::-;1782:7;1811:24;1829:5;1811:24;:::i;:::-;1800:35;;1745:96;;;:::o;1847:122::-;1920:24;1938:5;1920:24;:::i;:::-;1913:5;1910:35;1900:63;;1959:1;1956;1949:12;1900:63;1847:122;:::o;1975:143::-;2032:5;2063:6;2057:13;2048:22;;2079:33;2106:5;2079:33;:::i;:::-;1975:143;;;;:::o;2141:732::-;2248:5;2273:81;2289:64;2346:6;2289:64;:::i;:::-;2273:81;:::i;:::-;2264:90;;2374:5;2403:6;2396:5;2389:21;2437:4;2430:5;2426:16;2419:23;;2490:4;2482:6;2478:17;2470:6;2466:30;2519:3;2511:6;2508:15;2505:122;;;2538:79;;:::i;:::-;2505:122;2653:6;2636:231;2670:6;2665:3;2662:15;2636:231;;;2745:3;2774:48;2818:3;2806:10;2774:48;:::i;:::-;2769:3;2762:61;2852:4;2847:3;2843:14;2836:21;;2712:155;2696:4;2691:3;2687:14;2680:21;;2636:231;;;2640:21;2254:619;;2141:732;;;;;:::o;2896:385::-;2978:5;3027:3;3020:4;3012:6;3008:17;3004:27;2994:122;;3035:79;;:::i;:::-;2994:122;3145:6;3139:13;3170:105;3271:3;3263:6;3256:4;3248:6;3244:17;3170:105;:::i;:::-;3161:114;;2984:297;2896:385;;;;:::o;3287:554::-;3382:6;3431:2;3419:9;3410:7;3406:23;3402:32;3399:119;;;3437:79;;:::i;:::-;3399:119;3578:1;3567:9;3563:17;3557:24;3608:18;3600:6;3597:30;3594:117;;;3630:79;;:::i;:::-;3594:117;3735:89;3816:7;3807:6;3796:9;3792:22;3735:89;:::i;:::-;3725:99;;3528:306;3287:554;;;;:::o;3847:180::-;3895:77;3892:1;3885:88;3992:4;3989:1;3982:15;4016:4;4013:1;4006:15;4033:118;4120:24;4138:5;4120:24;:::i;:::-;4115:3;4108:37;4033:118;;:::o;4157:222::-;4250:4;4288:2;4277:9;4273:18;4265:26;;4301:71;4369:1;4358:9;4354:17;4345:6;4301:71;:::i;:::-;4157:222;;;;:::o;4385:77::-;4422:7;4451:5;4440:16;;4385:77;;;:::o;4468:122::-;4541:24;4559:5;4541:24;:::i;:::-;4534:5;4531:35;4521:63;;4580:1;4577;4570:12;4521:63;4468:122;:::o;4596:143::-;4653:5;4684:6;4678:13;4669:22;;4700:33;4727:5;4700:33;:::i;:::-;4596:143;;;;:::o;4745:351::-;4815:6;4864:2;4852:9;4843:7;4839:23;4835:32;4832:119;;;4870:79;;:::i;:::-;4832:119;4990:1;5015:64;5071:7;5062:6;5051:9;5047:22;5015:64;:::i;:::-;5005:74;;4961:128;4745:351;;;;:::o;5102:141::-;5196:6;5230:5;5224:12;5214:22;;5102:141;;;:::o;5249:211::-;5375:11;5409:6;5404:3;5397:19;5449:4;5444:3;5440:14;5425:29;;5249:211;;;;:::o;5466:159::-;5560:4;5583:3;5575:11;;5613:4;5608:3;5604:14;5596:22;;5466:159;;;:::o;5631:114::-;5698:6;5732:5;5726:12;5716:22;;5631:114;;;:::o;5751:174::-;5840:11;5874:6;5869:3;5862:19;5914:4;5909:3;5905:14;5890:29;;5751:174;;;;:::o;5931:132::-;5998:4;6021:3;6013:11;;6051:4;6046:3;6042:14;6034:22;;5931:132;;;:::o;6069:108::-;6146:24;6164:5;6146:24;:::i;:::-;6141:3;6134:37;6069:108;;:::o;6183:179::-;6252:10;6273:46;6315:3;6307:6;6273:46;:::i;:::-;6351:4;6346:3;6342:14;6328:28;;6183:179;;;;:::o;6368:113::-;6438:4;6470;6465:3;6461:14;6453:22;;6368:113;;;:::o;6517:712::-;6626:3;6655:54;6703:5;6655:54;:::i;:::-;6725:76;6794:6;6789:3;6725:76;:::i;:::-;6718:83;;6825:56;6875:5;6825:56;:::i;:::-;6904:7;6935:1;6920:284;6945:6;6942:1;6939:13;6920:284;;;7021:6;7015:13;7048:63;7107:3;7092:13;7048:63;:::i;:::-;7041:70;;7134:60;7187:6;7134:60;:::i;:::-;7124:70;;6980:224;6967:1;6964;6960:9;6955:14;;6920:284;;;6924:14;7220:3;7213:10;;6631:598;;;6517:712;;;;:::o;7235:112::-;7300:6;7334:5;7328:12;7318:22;;7235:112;;;:::o;7353:172::-;7440:11;7474:6;7469:3;7462:19;7514:4;7509:3;7505:14;7490:29;;7353:172;;;;:::o;7531:130::-;7596:4;7619:3;7611:11;;7649:4;7644:3;7640:14;7632:22;;7531:130;;;:::o;7667:86::-;7702:7;7742:4;7735:5;7731:16;7720:27;;7667:86;;;:::o;7759:102::-;7832:22;7848:5;7832:22;:::i;:::-;7827:3;7820:35;7759:102;;:::o;7867:171::-;7932:10;7953:42;7991:3;7983:6;7953:42;:::i;:::-;8027:4;8022:3;8018:14;8004:28;;7867:171;;;;:::o;8044:111::-;8112:4;8144;8139:3;8135:14;8127:22;;8044:111;;;:::o;8187:696::-;8292:3;8321:52;8367:5;8321:52;:::i;:::-;8389:74;8456:6;8451:3;8389:74;:::i;:::-;8382:81;;8487:54;8535:5;8487:54;:::i;:::-;8564:7;8595:1;8580:278;8605:6;8602:1;8599:13;8580:278;;;8681:6;8675:13;8708:59;8763:3;8748:13;8708:59;:::i;:::-;8701:66;;8790:58;8841:6;8790:58;:::i;:::-;8780:68;;8640:218;8627:1;8624;8620:9;8615:14;;8580:278;;;8584:14;8874:3;8867:10;;8297:586;;;8187:696;;;;:::o;8889:114::-;8956:6;8990:5;8984:12;8974:22;;8889:114;;;:::o;9009:174::-;9098:11;9132:6;9127:3;9120:19;9172:4;9167:3;9163:14;9148:29;;9009:174;;;;:::o;9189:132::-;9256:4;9279:3;9271:11;;9309:4;9304:3;9300:14;9292:22;;9189:132;;;:::o;9327:108::-;9404:24;9422:5;9404:24;:::i;:::-;9399:3;9392:37;9327:108;;:::o;9441:179::-;9510:10;9531:46;9573:3;9565:6;9531:46;:::i;:::-;9609:4;9604:3;9600:14;9586:28;;9441:179;;;;:::o;9626:113::-;9696:4;9728;9723:3;9719:14;9711:22;;9626:113;;;:::o;9775:712::-;9884:3;9913:54;9961:5;9913:54;:::i;:::-;9983:76;10052:6;10047:3;9983:76;:::i;:::-;9976:83;;10083:56;10133:5;10083:56;:::i;:::-;10162:7;10193:1;10178:284;10203:6;10200:1;10197:13;10178:284;;;10279:6;10273:13;10306:63;10365:3;10350:13;10306:63;:::i;:::-;10299:70;;10392:60;10445:6;10392:60;:::i;:::-;10382:70;;10238:224;10225:1;10222;10218:9;10213:14;;10178:284;;;10182:14;10478:3;10471:10;;9889:598;;;9775:712;;;;:::o;10493:93::-;10529:7;10569:10;10562:5;10558:22;10547:33;;10493:93;;;:::o;10592:105::-;10667:23;10684:5;10667:23;:::i;:::-;10662:3;10655:36;10592:105;;:::o;10809:1462::-;10922:3;10958:4;10953:3;10949:14;11047:4;11040:5;11036:16;11030:23;11100:3;11094:4;11090:14;11083:4;11078:3;11074:14;11067:38;11126:103;11224:4;11210:12;11126:103;:::i;:::-;11118:111;;10973:267;11326:4;11319:5;11315:16;11309:23;11379:3;11373:4;11369:14;11362:4;11357:3;11353:14;11346:38;11405:99;11499:4;11485:12;11405:99;:::i;:::-;11397:107;;11250:265;11602:4;11595:5;11591:16;11585:23;11655:3;11649:4;11645:14;11638:4;11633:3;11629:14;11622:38;11681:103;11779:4;11765:12;11681:103;:::i;:::-;11673:111;;11525:270;11880:4;11873:5;11869:16;11863:23;11933:3;11927:4;11923:14;11916:4;11911:3;11907:14;11900:38;11959:103;12057:4;12043:12;11959:103;:::i;:::-;11951:111;;11805:268;12154:4;12147:5;12143:16;12137:23;12173:61;12228:4;12223:3;12219:14;12205:12;12173:61;:::i;:::-;12083:161;12261:4;12254:11;;10927:1344;10809:1462;;;;:::o;12277:264::-;12400:10;12435:100;12531:3;12523:6;12435:100;:::i;:::-;12421:114;;12277:264;;;;:::o;12547:140::-;12644:4;12676;12671:3;12667:14;12659:22;;12547:140;;;:::o;12803:1127::-;12976:3;13005:81;13080:5;13005:81;:::i;:::-;13102:113;13208:6;13203:3;13102:113;:::i;:::-;13095:120;;13241:3;13286:4;13278:6;13274:17;13269:3;13265:27;13316:83;13393:5;13316:83;:::i;:::-;13422:7;13453:1;13438:447;13463:6;13460:1;13457:13;13438:447;;;13534:9;13528:4;13524:20;13519:3;13512:33;13585:6;13579:13;13613:118;13726:4;13711:13;13613:118;:::i;:::-;13605:126;;13754:87;13834:6;13754:87;:::i;:::-;13744:97;;13870:4;13865:3;13861:14;13854:21;;13498:387;13485:1;13482;13478:9;13473:14;;13438:447;;;13442:14;13901:4;13894:11;;13921:3;13914:10;;12981:949;;;;;12803:1127;;;;:::o;13936:481::-;14133:4;14171:2;14160:9;14156:18;14148:26;;14220:9;14214:4;14210:20;14206:1;14195:9;14191:17;14184:47;14248:162;14405:4;14396:6;14248:162;:::i;:::-;14240:170;;13936:481;;;;:::o;14423:98::-;14474:6;14508:5;14502:12;14492:22;;14423:98;;;:::o;14527:147::-;14628:11;14665:3;14650:18;;14527:147;;;;:::o;14680:139::-;14769:6;14764:3;14759;14753:23;14810:1;14801:6;14796:3;14792:16;14785:27;14680:139;;;:::o;14825:386::-;14929:3;14957:38;14989:5;14957:38;:::i;:::-;15011:88;15092:6;15087:3;15011:88;:::i;:::-;15004:95;;15108:65;15166:6;15161:3;15154:4;15147:5;15143:16;15108:65;:::i;:::-;15198:6;15193:3;15189:16;15182:23;;14933:278;14825:386;;;;:::o;15217:271::-;15347:3;15369:93;15458:3;15449:6;15369:93;:::i;:::-;15362:100;;15479:3;15472:10;;15217:271;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"550:3022:23:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address[]\\\",\\\"name\\\":\\\"pools\\\",\\\"type\\\":\\\"address[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/Balancer/GetBalancerPoolDataBatchRequest.sol\\\":\\\"GetBalancerPoolDataBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/Balancer/GetBalancerPoolDataBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0x3e1577d615b675bc39200e3dc32570558e53b8ea30312a81704e8dce264b98c2\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://ec97ff172e26f806289c07ec87d0a2416fc4d199b9dee267c65ed42c8a0a327d\\\",\\\"dweb:/ipfs/Qmf2VT6PM4HSfQ6vBhffX3DKrBnW7EtF9VWC8NE5SoQgwP\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/Balancer/GetBalancerPoolDataBatchRequest.sol\":\"GetBalancerPoolDataBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/Balancer/GetBalancerPoolDataBatchRequest.sol\":{\"keccak256\":\"0x3e1577d615b675bc39200e3dc32570558e53b8ea30312a81704e8dce264b98c2\",\"urls\":[\"bzz-raw://ec97ff172e26f806289c07ec87d0a2416fc4d199b9dee267c65ed42c8a0a327d\",\"dweb:/ipfs/Qmf2VT6PM4HSfQ6vBhffX3DKrBnW7EtF9VWC8NE5SoQgwP\"],\"license\":\"MIT\"}},\"version\":1},\"id\":23}"
  },
  {
    "path": "src/amms/abi/GetERC4626VaultDataBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"vaults\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b5060405161136d38038061136d83398181016040528101906100319190610d7a565b5f815167ffffffffffffffff81111561004d5761004c610be4565b5b60405190808252806020026020018201604052801561008657816020015b610073610b38565b81526020019060019003908161006b5790505b5090505f5f90505b8251811015610ae8575f8382815181106100ab576100aa610dc1565b5b602002602001015190506100c481610b1660201b60201c565b156100cf5750610add565b5f8173ffffffffffffffffffffffffffffffffffffffff166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610119573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061013d9190610dee565b905061014e81610b1660201b60201c565b1561015a575050610add565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516102069190610e6b565b5f604051808303815f8787f1925050503d805f8114610240576040519150601f19603f3d011682016040523d82523d5f602084013e610245565b606091505b5091509150811580610258575060208151145b156102665750505050610add565b5f8180602001905181019061027b9190610eb4565b90505f81148061028b575060ff81115b1561029a575050505050610add565b6102a2610b38565b85815f019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508573ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037e9190610f15565b816020019060ff16908160ff168152505081816060019060ff16908160ff16815250508573ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ea573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040e9190610eb4565b8160800181815250508573ffffffffffffffffffffffffffffffffffffffff166301e1d1146040518163ffffffff1660e01b8152600401602060405180830381865afa158015610460573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104849190610eb4565b8160a00181815250508573ffffffffffffffffffffffffffffffffffffffff1663ef8b30f78260600151600a6104ba919061109c565b60646104c691906110e6565b6040518263ffffffff1660e01b81526004016104e29190611136565b602060405180830381865afa1580156104fd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105219190610eb4565b8673ffffffffffffffffffffffffffffffffffffffff1663c6e6f5928360600151600a61054e919061109c565b606461055a91906110e6565b6040518263ffffffff1660e01b81526004016105769190611136565b602060405180830381865afa158015610591573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105b59190610eb4565b6105bf919061114f565b8160c00181815250508573ffffffffffffffffffffffffffffffffffffffff1663ef8b30f78260600151600a6105f5919061109c565b60c861060191906110e6565b6040518263ffffffff1660e01b815260040161061d9190611136565b602060405180830381865afa158015610638573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061065c9190610eb4565b8673ffffffffffffffffffffffffffffffffffffffff1663c6e6f5928360600151600a610689919061109c565b60c861069591906110e6565b6040518263ffffffff1660e01b81526004016106b19190611136565b602060405180830381865afa1580156106cc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106f09190610eb4565b6106fa919061114f565b8160e00181815250508573ffffffffffffffffffffffffffffffffffffffff1663c6e6f5928260600151600a610730919061109c565b606461073c91906110e6565b6040518263ffffffff1660e01b81526004016107589190611136565b602060405180830381865afa158015610773573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107979190610eb4565b816101000181815250508573ffffffffffffffffffffffffffffffffffffffff16634cdad5068260200151600a6107ce919061109c565b60646107da91906110e6565b6040518263ffffffff1660e01b81526004016107f69190611136565b602060405180830381865afa158015610811573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108359190610eb4565b8673ffffffffffffffffffffffffffffffffffffffff166307a2d13a8360200151600a610862919061109c565b606461086e91906110e6565b6040518263ffffffff1660e01b815260040161088a9190611136565b602060405180830381865afa1580156108a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108c99190610eb4565b6108d3919061114f565b816101200181815250508573ffffffffffffffffffffffffffffffffffffffff16634cdad5068260200151600a61090a919061109c565b60c861091691906110e6565b6040518263ffffffff1660e01b81526004016109329190611136565b602060405180830381865afa15801561094d573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109719190610eb4565b8673ffffffffffffffffffffffffffffffffffffffff166307a2d13a8360200151600a61099e919061109c565b60c86109aa91906110e6565b6040518263ffffffff1660e01b81526004016109c69190611136565b602060405180830381865afa1580156109e1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a059190610eb4565b610a0f919061114f565b816101400181815250508573ffffffffffffffffffffffffffffffffffffffff166307a2d13a8260200151600a610a46919061109c565b6064610a5291906110e6565b6040518263ffffffff1660e01b8152600401610a6e9190611136565b602060405180830381865afa158015610a89573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aad9190610eb4565b8161016001818152505080888881518110610acb57610aca610dc1565b5b60200260200101819052505050505050505b80600101905061008e565b505f81604051602001610afb919061134c565b60405160208183030381529060405290506020810180590381f35b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b149050919050565b6040518061018001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f60ff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f60ff1681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610c1a82610bd4565b810181811067ffffffffffffffff82111715610c3957610c38610be4565b5b80604052505050565b5f610c4b610bbf565b9050610c578282610c11565b919050565b5f67ffffffffffffffff821115610c7657610c75610be4565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610cb482610c8b565b9050919050565b610cc481610caa565b8114610cce575f5ffd5b50565b5f81519050610cdf81610cbb565b92915050565b5f610cf7610cf284610c5c565b610c42565b90508083825260208201905060208402830185811115610d1a57610d19610c87565b5b835b81811015610d435780610d2f8882610cd1565b845260208401935050602081019050610d1c565b5050509392505050565b5f82601f830112610d6157610d60610bd0565b5b8151610d71848260208601610ce5565b91505092915050565b5f60208284031215610d8f57610d8e610bc8565b5b5f82015167ffffffffffffffff811115610dac57610dab610bcc565b5b610db884828501610d4d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f60208284031215610e0357610e02610bc8565b5b5f610e1084828501610cd1565b91505092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610e4582610e19565b610e4f8185610e23565b9350610e5f818560208601610e2d565b80840191505092915050565b5f610e768284610e3b565b915081905092915050565b5f819050919050565b610e9381610e81565b8114610e9d575f5ffd5b50565b5f81519050610eae81610e8a565b92915050565b5f60208284031215610ec957610ec8610bc8565b5b5f610ed684828501610ea0565b91505092915050565b5f60ff82169050919050565b610ef481610edf565b8114610efe575f5ffd5b50565b5f81519050610f0f81610eeb565b92915050565b5f60208284031215610f2a57610f29610bc8565b5b5f610f3784828501610f01565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f5f8291508390505b6001851115610fc257808604811115610f9e57610f9d610f40565b5b6001851615610fad5780820291505b8081029050610fbb85610f6d565b9450610f82565b94509492505050565b5f82610fda5760019050611095565b81610fe7575f9050611095565b8160018114610ffd576002811461100757611036565b6001915050611095565b60ff84111561101957611018610f40565b5b8360020a9150848211156110305761102f610f40565b5b50611095565b5060208310610133831016604e8410600b841016171561106b5782820a90508381111561106657611065610f40565b5b611095565b6110788484846001610f79565b9250905081840481111561108f5761108e610f40565b5b81810290505b9392505050565b5f6110a682610e81565b91506110b183610edf565b92506110de7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484610fcb565b905092915050565b5f6110f082610e81565b91506110fb83610e81565b925082820261110981610e81565b915082820484148315176111205761111f610f40565b5b5092915050565b61113081610e81565b82525050565b5f6020820190506111495f830184611127565b92915050565b5f61115982610e81565b915061116483610e81565b925082820390508181111561117c5761117b610f40565b5b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6111b481610caa565b82525050565b6111c381610edf565b82525050565b6111d281610e81565b82525050565b61018082015f8201516111ed5f8501826111ab565b50602082015161120060208501826111ba565b50604082015161121360408501826111ab565b50606082015161122660608501826111ba565b50608082015161123960808501826111c9565b5060a082015161124c60a08501826111c9565b5060c082015161125f60c08501826111c9565b5060e082015161127260e08501826111c9565b506101008201516112876101008501826111c9565b5061012082015161129c6101208501826111c9565b506101408201516112b16101408501826111c9565b506101608201516112c66101608501826111c9565b50505050565b5f6112d783836111d8565b6101808301905092915050565b5f602082019050919050565b5f6112fa82611182565b611304818561118c565b935061130f8361119c565b805f5b8381101561133f57815161132688826112cc565b9750611331836112e4565b925050600181019050611312565b5085935050505092915050565b5f6020820190508181035f83015261136481846112f0565b90509291505056fe\",\"sourceMap\":\"843:4790:25:-:0;;;1313:4196;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1360:31;1410:6;:13;1394:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;1360:64;;1440:9;1452:1;1440:13;;1435:3533;1459:6;:13;1455:1;:17;1435:3533;;;1493:20;1516:6;1523:1;1516:9;;;;;;;;:::i;:::-;;;;;;;;1493:32;;1544:28;1559:12;1544:14;;;:28;;:::i;:::-;1540:42;;;1574:8;;;1540:42;1597:18;1632:12;1618:33;;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1597:56;;1742:26;1757:10;1742:14;;;:26;;:::i;:::-;1738:40;;;1770:8;;;;1738:40;1810:30;1858:35;1910:10;:15;;1931:5;1959:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1910:104;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1792:222;;;;2051:25;2050:26;:81;;;;2129:2;2096:22;:29;:35;2050:81;2029:158;;;2164:8;;;;;;2029:158;2201:26;2258:22;2230:91;;;;;;;;;;;;:::i;:::-;2201:120;;2361:1;2339:18;:23;:51;;;;2387:3;2366:18;:24;2339:51;2335:98;;;2410:8;;;;;;;2335:98;2447:26;;:::i;:::-;2537:12;2514:9;:20;;:35;;;;;;;;;;;2586:10;2563:9;:20;;:33;;;;;;;;;;;2696:12;2682:53;;;:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2651:9;:28;;:86;;;;;;;;;;;2828:18;2791:9;:28;;:56;;;;;;;;;;;2940:12;2926:56;;;:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2896:9;:27;;:88;;;;;3042:12;3028:56;;;:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2998:9;:27;;:88;;;;;3386:12;3372:42;;;3448:9;:28;;;3442:2;:34;;;;:::i;:::-;3436:3;:40;;;;:::i;:::-;3372:122;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3244:12;3230:43;;;3307:9;:28;;;3301:2;:34;;;;:::i;:::-;3295:3;:40;;;;:::i;:::-;3230:123;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:264;;;;:::i;:::-;3185:9;:26;;:309;;;;;3764:12;3750:42;;;3826:9;:28;;;3820:2;:34;;;;:::i;:::-;3814:3;:40;;;;:::i;:::-;3750:122;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3622:12;3608:43;;;3685:9;:28;;;3679:2;:34;;;;:::i;:::-;3673:3;:40;;;;:::i;:::-;3608:123;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:264;;;;:::i;:::-;3563:9;:26;;:309;;;;;3926:12;3912:60;;;3985:9;:28;;;3979:2;:34;;;;:::i;:::-;3973:3;:40;;;;:::i;:::-;3912:102;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3887:9;:22;;:127;;;;;4286:12;4272:41;;;4347:9;:28;;;4341:2;:34;;;;:::i;:::-;4335:3;:40;;;;:::i;:::-;4272:121;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4144:12;4130:43;;;4207:9;:28;;;4201:2;:34;;;;:::i;:::-;4195:3;:40;;;;:::i;:::-;4130:123;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:263;;;;:::i;:::-;4084:9;:27;;:309;;;;;4665:12;4651:41;;;4726:9;:28;;;4720:2;:34;;;;:::i;:::-;4714:3;:40;;;;:::i;:::-;4651:121;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4523:12;4509:43;;;4586:9;:28;;;4580:2;:34;;;;:::i;:::-;4574:3;:40;;;;:::i;:::-;4509:123;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:263;;;;:::i;:::-;4463:9;:27;;:309;;;;;4827:12;4813:60;;;4886:9;:28;;;4880:2;:34;;;;:::i;:::-;4874:3;:40;;;;:::i;:::-;4813:102;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4787:9;:23;;:128;;;;;4948:9;4930:12;4943:1;4930:15;;;;;;;;:::i;:::-;;;;;;;:27;;;;1479:3489;;;;;;1435:3533;1474:3;;;;;1435:3533;;;;5170:28;5212:12;5201:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;5170:55;;5433:4;5416:15;5412:26;5482:9;5473:7;5469:23;5458:9;5451:42;5515:116;5578:4;5623:1;5601:6;:18;;;:23;5594:30;;5515:116;;;:::o;843:4790::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:311::-;1250:4;1340:18;1332:6;1329:30;1326:56;;;1362:18;;:::i;:::-;1326:56;1412:4;1404:6;1400:17;1392:25;;1472:4;1466;1462:15;1454:23;;1173:311;;;:::o;1490:117::-;1599:1;1596;1589:12;1613:126;1650:7;1690:42;1683:5;1679:54;1668:65;;1613:126;;;:::o;1745:96::-;1782:7;1811:24;1829:5;1811:24;:::i;:::-;1800:35;;1745:96;;;:::o;1847:122::-;1920:24;1938:5;1920:24;:::i;:::-;1913:5;1910:35;1900:63;;1959:1;1956;1949:12;1900:63;1847:122;:::o;1975:143::-;2032:5;2063:6;2057:13;2048:22;;2079:33;2106:5;2079:33;:::i;:::-;1975:143;;;;:::o;2141:732::-;2248:5;2273:81;2289:64;2346:6;2289:64;:::i;:::-;2273:81;:::i;:::-;2264:90;;2374:5;2403:6;2396:5;2389:21;2437:4;2430:5;2426:16;2419:23;;2490:4;2482:6;2478:17;2470:6;2466:30;2519:3;2511:6;2508:15;2505:122;;;2538:79;;:::i;:::-;2505:122;2653:6;2636:231;2670:6;2665:3;2662:15;2636:231;;;2745:3;2774:48;2818:3;2806:10;2774:48;:::i;:::-;2769:3;2762:61;2852:4;2847:3;2843:14;2836:21;;2712:155;2696:4;2691:3;2687:14;2680:21;;2636:231;;;2640:21;2254:619;;2141:732;;;;;:::o;2896:385::-;2978:5;3027:3;3020:4;3012:6;3008:17;3004:27;2994:122;;3035:79;;:::i;:::-;2994:122;3145:6;3139:13;3170:105;3271:3;3263:6;3256:4;3248:6;3244:17;3170:105;:::i;:::-;3161:114;;2984:297;2896:385;;;;:::o;3287:554::-;3382:6;3431:2;3419:9;3410:7;3406:23;3402:32;3399:119;;;3437:79;;:::i;:::-;3399:119;3578:1;3567:9;3563:17;3557:24;3608:18;3600:6;3597:30;3594:117;;;3630:79;;:::i;:::-;3594:117;3735:89;3816:7;3807:6;3796:9;3792:22;3735:89;:::i;:::-;3725:99;;3528:306;3287:554;;;;:::o;3847:180::-;3895:77;3892:1;3885:88;3992:4;3989:1;3982:15;4016:4;4013:1;4006:15;4033:351;4103:6;4152:2;4140:9;4131:7;4127:23;4123:32;4120:119;;;4158:79;;:::i;:::-;4120:119;4278:1;4303:64;4359:7;4350:6;4339:9;4335:22;4303:64;:::i;:::-;4293:74;;4249:128;4033:351;;;;:::o;4390:98::-;4441:6;4475:5;4469:12;4459:22;;4390:98;;;:::o;4494:147::-;4595:11;4632:3;4617:18;;4494:147;;;;:::o;4647:139::-;4736:6;4731:3;4726;4720:23;4777:1;4768:6;4763:3;4759:16;4752:27;4647:139;;;:::o;4792:386::-;4896:3;4924:38;4956:5;4924:38;:::i;:::-;4978:88;5059:6;5054:3;4978:88;:::i;:::-;4971:95;;5075:65;5133:6;5128:3;5121:4;5114:5;5110:16;5075:65;:::i;:::-;5165:6;5160:3;5156:16;5149:23;;4900:278;4792:386;;;;:::o;5184:271::-;5314:3;5336:93;5425:3;5416:6;5336:93;:::i;:::-;5329:100;;5446:3;5439:10;;5184:271;;;;:::o;5461:77::-;5498:7;5527:5;5516:16;;5461:77;;;:::o;5544:122::-;5617:24;5635:5;5617:24;:::i;:::-;5610:5;5607:35;5597:63;;5656:1;5653;5646:12;5597:63;5544:122;:::o;5672:143::-;5729:5;5760:6;5754:13;5745:22;;5776:33;5803:5;5776:33;:::i;:::-;5672:143;;;;:::o;5821:351::-;5891:6;5940:2;5928:9;5919:7;5915:23;5911:32;5908:119;;;5946:79;;:::i;:::-;5908:119;6066:1;6091:64;6147:7;6138:6;6127:9;6123:22;6091:64;:::i;:::-;6081:74;;6037:128;5821:351;;;;:::o;6178:86::-;6213:7;6253:4;6246:5;6242:16;6231:27;;6178:86;;;:::o;6270:118::-;6341:22;6357:5;6341:22;:::i;:::-;6334:5;6331:33;6321:61;;6378:1;6375;6368:12;6321:61;6270:118;:::o;6394:139::-;6449:5;6480:6;6474:13;6465:22;;6496:31;6521:5;6496:31;:::i;:::-;6394:139;;;;:::o;6539:347::-;6607:6;6656:2;6644:9;6635:7;6631:23;6627:32;6624:119;;;6662:79;;:::i;:::-;6624:119;6782:1;6807:62;6861:7;6852:6;6841:9;6837:22;6807:62;:::i;:::-;6797:72;;6753:126;6539:347;;;;:::o;6892:180::-;6940:77;6937:1;6930:88;7037:4;7034:1;7027:15;7061:4;7058:1;7051:15;7078:102;7120:8;7167:5;7164:1;7160:13;7139:34;;7078:102;;;:::o;7186:848::-;7247:5;7254:4;7278:6;7269:15;;7302:5;7293:14;;7316:712;7337:1;7327:8;7324:15;7316:712;;;7432:4;7427:3;7423:14;7417:4;7414:24;7411:50;;;7441:18;;:::i;:::-;7411:50;7491:1;7481:8;7477:16;7474:451;;;7906:4;7899:5;7895:16;7886:25;;7474:451;7956:4;7950;7946:15;7938:23;;7986:32;8009:8;7986:32;:::i;:::-;7974:44;;7316:712;;;7186:848;;;;;;;:::o;8040:1073::-;8094:5;8285:8;8275:40;;8306:1;8297:10;;8308:5;;8275:40;8334:4;8324:36;;8351:1;8342:10;;8353:5;;8324:36;8420:4;8468:1;8463:27;;;;8504:1;8499:191;;;;8413:277;;8463:27;8481:1;8472:10;;8483:5;;;8499:191;8544:3;8534:8;8531:17;8528:43;;;8551:18;;:::i;:::-;8528:43;8600:8;8597:1;8593:16;8584:25;;8635:3;8628:5;8625:14;8622:40;;;8642:18;;:::i;:::-;8622:40;8675:5;;;8413:277;;8799:2;8789:8;8786:16;8780:3;8774:4;8771:13;8767:36;8749:2;8739:8;8736:16;8731:2;8725:4;8722:12;8718:35;8702:111;8699:246;;;8855:8;8849:4;8845:19;8836:28;;8890:3;8883:5;8880:14;8877:40;;;8897:18;;:::i;:::-;8877:40;8930:5;;8699:246;8970:42;9008:3;8998:8;8992:4;8989:1;8970:42;:::i;:::-;8955:57;;;;9044:4;9039:3;9035:14;9028:5;9025:25;9022:51;;;9053:18;;:::i;:::-;9022:51;9102:4;9095:5;9091:16;9082:25;;8040:1073;;;;;;:::o;9119:281::-;9177:5;9201:23;9219:4;9201:23;:::i;:::-;9193:31;;9245:25;9261:8;9245:25;:::i;:::-;9233:37;;9289:104;9326:66;9316:8;9310:4;9289:104;:::i;:::-;9280:113;;9119:281;;;;:::o;9406:410::-;9446:7;9469:20;9487:1;9469:20;:::i;:::-;9464:25;;9503:20;9521:1;9503:20;:::i;:::-;9498:25;;9558:1;9555;9551:9;9580:30;9598:11;9580:30;:::i;:::-;9569:41;;9759:1;9750:7;9746:15;9743:1;9740:22;9720:1;9713:9;9693:83;9670:139;;9789:18;;:::i;:::-;9670:139;9454:362;9406:410;;;;:::o;9822:118::-;9909:24;9927:5;9909:24;:::i;:::-;9904:3;9897:37;9822:118;;:::o;9946:222::-;10039:4;10077:2;10066:9;10062:18;10054:26;;10090:71;10158:1;10147:9;10143:17;10134:6;10090:71;:::i;:::-;9946:222;;;;:::o;10174:194::-;10214:4;10234:20;10252:1;10234:20;:::i;:::-;10229:25;;10268:20;10286:1;10268:20;:::i;:::-;10263:25;;10312:1;10309;10305:9;10297:17;;10336:1;10330:4;10327:11;10324:37;;;10341:18;;:::i;:::-;10324:37;10174:194;;;;:::o;10374:142::-;10469:6;10503:5;10497:12;10487:22;;10374:142;;;:::o;10522:212::-;10649:11;10683:6;10678:3;10671:19;10723:4;10718:3;10714:14;10699:29;;10522:212;;;;:::o;10740:160::-;10835:4;10858:3;10850:11;;10888:4;10883:3;10879:14;10871:22;;10740:160;;;:::o;10906:108::-;10983:24;11001:5;10983:24;:::i;:::-;10978:3;10971:37;10906:108;;:::o;11020:102::-;11093:22;11109:5;11093:22;:::i;:::-;11088:3;11081:35;11020:102;;:::o;11128:108::-;11205:24;11223:5;11205:24;:::i;:::-;11200:3;11193:37;11128:108;;:::o;11350:2386::-;11493:6;11488:3;11484:16;11588:4;11581:5;11577:16;11571:23;11607:63;11664:4;11659:3;11655:14;11641:12;11607:63;:::i;:::-;11510:170;11776:4;11769:5;11765:16;11759:23;11795:59;11848:4;11843:3;11839:14;11825:12;11795:59;:::i;:::-;11690:174;11952:4;11945:5;11941:16;11935:23;11971:63;12028:4;12023:3;12019:14;12005:12;11971:63;:::i;:::-;11874:170;12140:4;12133:5;12129:16;12123:23;12159:59;12212:4;12207:3;12203:14;12189:12;12159:59;:::i;:::-;12054:174;12323:4;12316:5;12312:16;12306:23;12342:63;12399:4;12394:3;12390:14;12376:12;12342:63;:::i;:::-;12238:177;12510:4;12503:5;12499:16;12493:23;12529:63;12586:4;12581:3;12577:14;12563:12;12529:63;:::i;:::-;12425:177;12696:4;12689:5;12685:16;12679:23;12715:63;12772:4;12767:3;12763:14;12749:12;12715:63;:::i;:::-;12612:176;12882:4;12875:5;12871:16;12865:23;12901:63;12958:4;12953:3;12949:14;12935:12;12901:63;:::i;:::-;12798:176;13064:6;13057:5;13053:18;13047:25;13085:65;13142:6;13137:3;13133:16;13119:12;13085:65;:::i;:::-;12984:176;13255:6;13248:5;13244:18;13238:25;13276:65;13333:6;13328:3;13324:16;13310:12;13276:65;:::i;:::-;13170:181;13446:6;13439:5;13435:18;13429:25;13467:65;13524:6;13519:3;13515:16;13501:12;13467:65;:::i;:::-;13361:181;13633:6;13626:5;13622:18;13616:25;13654:65;13711:6;13706:3;13702:16;13688:12;13654:65;:::i;:::-;13552:177;11462:2274;11350:2386;;:::o;13742:293::-;13867:10;13888:102;13986:3;13978:6;13888:102;:::i;:::-;14022:6;14017:3;14013:16;13999:30;;13742:293;;;;:::o;14041:141::-;14139:4;14171;14166:3;14162:14;14154:22;;14041:141;;;:::o;14300:956::-;14475:3;14504:82;14580:5;14504:82;:::i;:::-;14602:114;14709:6;14704:3;14602:114;:::i;:::-;14595:121;;14740:84;14818:5;14740:84;:::i;:::-;14847:7;14878:1;14863:368;14888:6;14885:1;14882:13;14863:368;;;14964:6;14958:13;14991:119;15106:3;15091:13;14991:119;:::i;:::-;14984:126;;15133:88;15214:6;15133:88;:::i;:::-;15123:98;;14923:308;14910:1;14907;14903:9;14898:14;;14863:368;;;14867:14;15247:3;15240:10;;14480:776;;;14300:956;;;;:::o;15262:485::-;15461:4;15499:2;15488:9;15484:18;15476:26;;15548:9;15542:4;15538:20;15534:1;15523:9;15519:17;15512:47;15576:164;15735:4;15726:6;15576:164;:::i;:::-;15568:172;;15262:485;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"843:4790:25:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address[]\\\",\\\"name\\\":\\\"vaults\\\",\\\"type\\\":\\\"address[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/ERC4626/GetERC4626VaultDataBatchRequest.sol\\\":\\\"GetERC4626VaultDataBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/ERC4626/GetERC4626VaultDataBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0xb2fe86a5bf7fd8d2b4fc00233e05233fc326c1ff2cb3fa99ba835244d514abd7\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://f5b3b15b490d325b730f9d8b7dcbec77a7ee58430abfb7f8e830b7c53f3a6ed0\\\",\\\"dweb:/ipfs/QmaP3ZqjZymnv7tbVk5Q1Bgamfk9CGB3dboRTfGidV1Qck\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"vaults\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/ERC4626/GetERC4626VaultDataBatchRequest.sol\":\"GetERC4626VaultDataBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/ERC4626/GetERC4626VaultDataBatchRequest.sol\":{\"keccak256\":\"0xb2fe86a5bf7fd8d2b4fc00233e05233fc326c1ff2cb3fa99ba835244d514abd7\",\"urls\":[\"bzz-raw://f5b3b15b490d325b730f9d8b7dcbec77a7ee58430abfb7f8e830b7c53f3a6ed0\",\"dweb:/ipfs/QmaP3ZqjZymnv7tbVk5Q1Bgamfk9CGB3dboRTfGidV1Qck\"],\"license\":\"MIT\"}},\"version\":1},\"id\":25}"
  },
  {
    "path": "src/amms/abi/GetTokenDecimalsBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"tokens\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b5060405161068138038061068183398181016040528101906100319190610463565b5f815167ffffffffffffffff81111561004d5761004c6102cd565b5b60405190808252806020026020018201604052801561007b5781602001602082028036833780820191505090505b5090505f5f90505b8251811015610249575f8382815181106100a05761009f6104aa565b5b602002602001015190506100b98161027760201b60201c565b156100c4575061023e565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516101709190610529565b5f604051808303815f8787f1925050503d805f81146101aa576040519150601f19603f3d011682016040523d82523d5f602084013e6101af565b606091505b50915091508115610232575f602082510361022357818060200190518101906101d89190610572565b90505f8114806101e8575060ff81115b156101f6575050505061023e565b8086868151811061020a576102096104aa565b5b602002602001019060ff16908160ff168152505061022c565b5050505061023e565b5061023a565b50505061023e565b5050505b806001019050610083565b505f8160405160200161025c9190610660565b60405160208183030381529060405290506020810180590381f35b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b0361029f57600190506102a3565b5f90505b919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610303826102bd565b810181811067ffffffffffffffff82111715610322576103216102cd565b5b80604052505050565b5f6103346102a8565b905061034082826102fa565b919050565b5f67ffffffffffffffff82111561035f5761035e6102cd565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61039d82610374565b9050919050565b6103ad81610393565b81146103b7575f5ffd5b50565b5f815190506103c8816103a4565b92915050565b5f6103e06103db84610345565b61032b565b9050808382526020820190506020840283018581111561040357610402610370565b5b835b8181101561042c578061041888826103ba565b845260208401935050602081019050610405565b5050509392505050565b5f82601f83011261044a576104496102b9565b5b815161045a8482602086016103ce565b91505092915050565b5f60208284031215610478576104776102b1565b5b5f82015167ffffffffffffffff811115610495576104946102b5565b5b6104a184828501610436565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f610503826104d7565b61050d81856104e1565b935061051d8185602086016104eb565b80840191505092915050565b5f61053482846104f9565b915081905092915050565b5f819050919050565b6105518161053f565b811461055b575f5ffd5b50565b5f8151905061056c81610548565b92915050565b5f60208284031215610587576105866102b1565b5b5f6105948482850161055e565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f60ff82169050919050565b6105db816105c6565b82525050565b5f6105ec83836105d2565b60208301905092915050565b5f602082019050919050565b5f61060e8261059d565b61061881856105a7565b9350610623836105b7565b805f5b8381101561065357815161063a88826105e1565b9750610645836105f8565b925050600181019050610626565b5085935050505092915050565b5f6020820190508181035f8301526106788184610604565b90509291505056fe\",\"sourceMap\":\"56:1363:24:-:0;;;100:1317;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;147:23;185:6;:13;173:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;147:52;;215:9;227:1;215:13;;210:863;234:6;:13;230:1;:17;210:863;;;268:13;284:6;291:1;284:9;;;;;;;;:::i;:::-;;;;;;;;268:25;;312:21;327:5;312:14;;;:21;;:::i;:::-;308:35;;;335:8;;;308:35;359:25;386:30;420:5;:27;;453:5;460:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;420:78;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;358:140;;;;517:20;513:550;;;557:21;629:2;601:17;:24;:30;597:405;;684:17;673:40;;;;;;;;;;;;:::i;:::-;655:58;;757:1;740:13;:18;:41;;;;778:3;762:13;:19;740:41;736:193;;;809:8;;;;;;736:193;892:13;872:8;881:1;872:11;;;;;;;;:::i;:::-;;;;;;;:34;;;;;;;;;;;597:405;;;975:8;;;;;;597:405;539:477;513:550;;;1040:8;;;;;513:550;254:819;;;210:863;249:3;;;;;210:863;;;;1083:28;1125:8;1114:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;1083:51;;1341:4;1324:15;1320:26;1390:9;1381:7;1377:23;1366:9;1359:42;1421:160;1475:4;1513:1;1491:6;:18;;;:23;1487:92;;1533:4;1526:11;;;;1487:92;1567:5;1560:12;;1421:160;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:311::-;1250:4;1340:18;1332:6;1329:30;1326:56;;;1362:18;;:::i;:::-;1326:56;1412:4;1404:6;1400:17;1392:25;;1472:4;1466;1462:15;1454:23;;1173:311;;;:::o;1490:117::-;1599:1;1596;1589:12;1613:126;1650:7;1690:42;1683:5;1679:54;1668:65;;1613:126;;;:::o;1745:96::-;1782:7;1811:24;1829:5;1811:24;:::i;:::-;1800:35;;1745:96;;;:::o;1847:122::-;1920:24;1938:5;1920:24;:::i;:::-;1913:5;1910:35;1900:63;;1959:1;1956;1949:12;1900:63;1847:122;:::o;1975:143::-;2032:5;2063:6;2057:13;2048:22;;2079:33;2106:5;2079:33;:::i;:::-;1975:143;;;;:::o;2141:732::-;2248:5;2273:81;2289:64;2346:6;2289:64;:::i;:::-;2273:81;:::i;:::-;2264:90;;2374:5;2403:6;2396:5;2389:21;2437:4;2430:5;2426:16;2419:23;;2490:4;2482:6;2478:17;2470:6;2466:30;2519:3;2511:6;2508:15;2505:122;;;2538:79;;:::i;:::-;2505:122;2653:6;2636:231;2670:6;2665:3;2662:15;2636:231;;;2745:3;2774:48;2818:3;2806:10;2774:48;:::i;:::-;2769:3;2762:61;2852:4;2847:3;2843:14;2836:21;;2712:155;2696:4;2691:3;2687:14;2680:21;;2636:231;;;2640:21;2254:619;;2141:732;;;;;:::o;2896:385::-;2978:5;3027:3;3020:4;3012:6;3008:17;3004:27;2994:122;;3035:79;;:::i;:::-;2994:122;3145:6;3139:13;3170:105;3271:3;3263:6;3256:4;3248:6;3244:17;3170:105;:::i;:::-;3161:114;;2984:297;2896:385;;;;:::o;3287:554::-;3382:6;3431:2;3419:9;3410:7;3406:23;3402:32;3399:119;;;3437:79;;:::i;:::-;3399:119;3578:1;3567:9;3563:17;3557:24;3608:18;3600:6;3597:30;3594:117;;;3630:79;;:::i;:::-;3594:117;3735:89;3816:7;3807:6;3796:9;3792:22;3735:89;:::i;:::-;3725:99;;3528:306;3287:554;;;;:::o;3847:180::-;3895:77;3892:1;3885:88;3992:4;3989:1;3982:15;4016:4;4013:1;4006:15;4033:98;4084:6;4118:5;4112:12;4102:22;;4033:98;;;:::o;4137:147::-;4238:11;4275:3;4260:18;;4137:147;;;;:::o;4290:139::-;4379:6;4374:3;4369;4363:23;4420:1;4411:6;4406:3;4402:16;4395:27;4290:139;;;:::o;4435:386::-;4539:3;4567:38;4599:5;4567:38;:::i;:::-;4621:88;4702:6;4697:3;4621:88;:::i;:::-;4614:95;;4718:65;4776:6;4771:3;4764:4;4757:5;4753:16;4718:65;:::i;:::-;4808:6;4803:3;4799:16;4792:23;;4543:278;4435:386;;;;:::o;4827:271::-;4957:3;4979:93;5068:3;5059:6;4979:93;:::i;:::-;4972:100;;5089:3;5082:10;;4827:271;;;;:::o;5104:77::-;5141:7;5170:5;5159:16;;5104:77;;;:::o;5187:122::-;5260:24;5278:5;5260:24;:::i;:::-;5253:5;5250:35;5240:63;;5299:1;5296;5289:12;5240:63;5187:122;:::o;5315:143::-;5372:5;5403:6;5397:13;5388:22;;5419:33;5446:5;5419:33;:::i;:::-;5315:143;;;;:::o;5464:351::-;5534:6;5583:2;5571:9;5562:7;5558:23;5554:32;5551:119;;;5589:79;;:::i;:::-;5551:119;5709:1;5734:64;5790:7;5781:6;5770:9;5766:22;5734:64;:::i;:::-;5724:74;;5680:128;5464:351;;;;:::o;5821:112::-;5886:6;5920:5;5914:12;5904:22;;5821:112;;;:::o;5939:182::-;6036:11;6070:6;6065:3;6058:19;6110:4;6105:3;6101:14;6086:29;;5939:182;;;;:::o;6127:130::-;6192:4;6215:3;6207:11;;6245:4;6240:3;6236:14;6228:22;;6127:130;;;:::o;6263:86::-;6298:7;6338:4;6331:5;6327:16;6316:27;;6263:86;;;:::o;6355:102::-;6428:22;6444:5;6428:22;:::i;:::-;6423:3;6416:35;6355:102;;:::o;6463:171::-;6528:10;6549:42;6587:3;6579:6;6549:42;:::i;:::-;6623:4;6618:3;6614:14;6600:28;;6463:171;;;;:::o;6640:111::-;6708:4;6740;6735:3;6731:14;6723:22;;6640:111;;;:::o;6783:716::-;6898:3;6927:52;6973:5;6927:52;:::i;:::-;6995:84;7072:6;7067:3;6995:84;:::i;:::-;6988:91;;7103:54;7151:5;7103:54;:::i;:::-;7180:7;7211:1;7196:278;7221:6;7218:1;7215:13;7196:278;;;7297:6;7291:13;7324:59;7379:3;7364:13;7324:59;:::i;:::-;7317:66;;7406:58;7457:6;7406:58;:::i;:::-;7396:68;;7256:218;7243:1;7240;7236:9;7231:14;;7196:278;;;7200:14;7490:3;7483:10;;6903:596;;;6783:716;;;;:::o;7505:365::-;7644:4;7682:2;7671:9;7667:18;7659:26;;7731:9;7725:4;7721:20;7717:1;7706:9;7702:17;7695:47;7759:104;7858:4;7849:6;7759:104;:::i;:::-;7751:112;;7505:365;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"56:1363:24:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address[]\\\",\\\"name\\\":\\\"tokens\\\",\\\"type\\\":\\\"address[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/ERC20/GetTokenDecimalsBatchRequest.sol\\\":\\\"GetTokenDecimalsBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/ERC20/GetTokenDecimalsBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0xc7540761024525cf0d1371c70d9890b2beb0d8e5c996a238139e61541fc36ec5\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://fa59b893b03692814beb0d442247b028099e8a8582e5b3757bf3e5dd8231ae98\\\",\\\"dweb:/ipfs/QmUXeRAb4EAsaLRXCx7rHaJmyDA9dPnKoJbPoBoTWZfTZr\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/ERC20/GetTokenDecimalsBatchRequest.sol\":\"GetTokenDecimalsBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/ERC20/GetTokenDecimalsBatchRequest.sol\":{\"keccak256\":\"0xc7540761024525cf0d1371c70d9890b2beb0d8e5c996a238139e61541fc36ec5\",\"urls\":[\"bzz-raw://fa59b893b03692814beb0d442247b028099e8a8582e5b3757bf3e5dd8231ae98\",\"dweb:/ipfs/QmUXeRAb4EAsaLRXCx7rHaJmyDA9dPnKoJbPoBoTWZfTZr\"],\"license\":\"MIT\"}},\"version\":1},\"id\":24}"
  },
  {
    "path": "src/amms/abi/GetUniswapV2PairsBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"from\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"step\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"factory\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b50604051610550380380610550833981810160405281019061003191906102bd565b5f8173ffffffffffffffffffffffffffffffffffffffff1663574f2ba36040518163ffffffff1660e01b81526004016020604051808303815f875af115801561007c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100a0919061030d565b90508083856100af9190610365565b116100ba57826100c7565b83816100c69190610398565b5b92505f8367ffffffffffffffff8111156100e4576100e36103cb565b5b6040519080825280602002602001820160405280156101125781602001602082028036833780820191505090505b5090505f5f90505b848110156101fe578373ffffffffffffffffffffffffffffffffffffffff16631e3dd18b828861014a9190610365565b6040518263ffffffff1660e01b81526004016101669190610407565b6020604051808303815f875af1158015610182573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101a69190610420565b8282815181106101b9576101b861044b565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080600101905061011a565b505f81604051602001610211919061052f565b60405160208183030381529060405290506020810180590381f35b5f5ffd5b5f819050919050565b61024281610230565b811461024c575f5ffd5b50565b5f8151905061025d81610239565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61028c82610263565b9050919050565b61029c81610282565b81146102a6575f5ffd5b50565b5f815190506102b781610293565b92915050565b5f5f5f606084860312156102d4576102d361022c565b5b5f6102e18682870161024f565b93505060206102f28682870161024f565b9250506040610303868287016102a9565b9150509250925092565b5f602082840312156103225761032161022c565b5b5f61032f8482850161024f565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61036f82610230565b915061037a83610230565b925082820190508082111561039257610391610338565b5b92915050565b5f6103a282610230565b91506103ad83610230565b92508282039050818111156103c5576103c4610338565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61040181610230565b82525050565b5f60208201905061041a5f8301846103f8565b92915050565b5f602082840312156104355761043461022c565b5b5f610442848285016102a9565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6104aa81610282565b82525050565b5f6104bb83836104a1565b60208301905092915050565b5f602082019050919050565b5f6104dd82610478565b6104e78185610482565b93506104f283610492565b805f5b8381101561052257815161050988826104b0565b9750610514836104c7565b9250506001810190506104f5565b5085935050505092915050565b5f6020820190508181035f83015261054781846104d3565b90509291505056fe\",\"sourceMap\":\"337:1052:26:-:0;;;382:1005;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;449:22;483:7;474:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;449:59;;540:14;533:4;526;:11;;;;:::i;:::-;:28;:59;;581:4;526:59;;;574:4;557:14;:21;;;;:::i;:::-;526:59;519:66;;682:25;724:4;710:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;682:47;;745:9;757:1;745:13;;740:110;764:4;760:1;:8;740:110;;;812:7;803:26;;;837:1;830:4;:8;;;;:::i;:::-;803:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;789:8;798:1;789:11;;;;;;;;:::i;:::-;;;;;;;:50;;;;;;;;;;;770:3;;;;;740:110;;;;1052:28;1094:8;1083:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;1052:51;;1311:4;1294:15;1290:26;1360:9;1351:7;1347:23;1336:9;1329:42;88:117:41;197:1;194;187:12;334:77;371:7;400:5;389:16;;334:77;;;:::o;417:122::-;490:24;508:5;490:24;:::i;:::-;483:5;480:35;470:63;;529:1;526;519:12;470:63;417:122;:::o;545:143::-;602:5;633:6;627:13;618:22;;649:33;676:5;649:33;:::i;:::-;545:143;;;;:::o;694:126::-;731:7;771:42;764:5;760:54;749:65;;694:126;;;:::o;826:96::-;863:7;892:24;910:5;892:24;:::i;:::-;881:35;;826:96;;;:::o;928:122::-;1001:24;1019:5;1001:24;:::i;:::-;994:5;991:35;981:63;;1040:1;1037;1030:12;981:63;928:122;:::o;1056:143::-;1113:5;1144:6;1138:13;1129:22;;1160:33;1187:5;1160:33;:::i;:::-;1056:143;;;;:::o;1205:663::-;1293:6;1301;1309;1358:2;1346:9;1337:7;1333:23;1329:32;1326:119;;;1364:79;;:::i;:::-;1326:119;1484:1;1509:64;1565:7;1556:6;1545:9;1541:22;1509:64;:::i;:::-;1499:74;;1455:128;1622:2;1648:64;1704:7;1695:6;1684:9;1680:22;1648:64;:::i;:::-;1638:74;;1593:129;1761:2;1787:64;1843:7;1834:6;1823:9;1819:22;1787:64;:::i;:::-;1777:74;;1732:129;1205:663;;;;;:::o;1874:351::-;1944:6;1993:2;1981:9;1972:7;1968:23;1964:32;1961:119;;;1999:79;;:::i;:::-;1961:119;2119:1;2144:64;2200:7;2191:6;2180:9;2176:22;2144:64;:::i;:::-;2134:74;;2090:128;1874:351;;;;:::o;2231:180::-;2279:77;2276:1;2269:88;2376:4;2373:1;2366:15;2400:4;2397:1;2390:15;2417:191;2457:3;2476:20;2494:1;2476:20;:::i;:::-;2471:25;;2510:20;2528:1;2510:20;:::i;:::-;2505:25;;2553:1;2550;2546:9;2539:16;;2574:3;2571:1;2568:10;2565:36;;;2581:18;;:::i;:::-;2565:36;2417:191;;;;:::o;2614:194::-;2654:4;2674:20;2692:1;2674:20;:::i;:::-;2669:25;;2708:20;2726:1;2708:20;:::i;:::-;2703:25;;2752:1;2749;2745:9;2737:17;;2776:1;2770:4;2767:11;2764:37;;;2781:18;;:::i;:::-;2764:37;2614:194;;;;:::o;2814:180::-;2862:77;2859:1;2852:88;2959:4;2956:1;2949:15;2983:4;2980:1;2973:15;3000:118;3087:24;3105:5;3087:24;:::i;:::-;3082:3;3075:37;3000:118;;:::o;3124:222::-;3217:4;3255:2;3244:9;3240:18;3232:26;;3268:71;3336:1;3325:9;3321:17;3312:6;3268:71;:::i;:::-;3124:222;;;;:::o;3352:351::-;3422:6;3471:2;3459:9;3450:7;3446:23;3442:32;3439:119;;;3477:79;;:::i;:::-;3439:119;3597:1;3622:64;3678:7;3669:6;3658:9;3654:22;3622:64;:::i;:::-;3612:74;;3568:128;3352:351;;;;:::o;3709:180::-;3757:77;3754:1;3747:88;3854:4;3851:1;3844:15;3878:4;3875:1;3868:15;3895:114;3962:6;3996:5;3990:12;3980:22;;3895:114;;;:::o;4015:184::-;4114:11;4148:6;4143:3;4136:19;4188:4;4183:3;4179:14;4164:29;;4015:184;;;;:::o;4205:132::-;4272:4;4295:3;4287:11;;4325:4;4320:3;4316:14;4308:22;;4205:132;;;:::o;4343:108::-;4420:24;4438:5;4420:24;:::i;:::-;4415:3;4408:37;4343:108;;:::o;4457:179::-;4526:10;4547:46;4589:3;4581:6;4547:46;:::i;:::-;4625:4;4620:3;4616:14;4602:28;;4457:179;;;;:::o;4642:113::-;4712:4;4744;4739:3;4735:14;4727:22;;4642:113;;;:::o;4791:732::-;4910:3;4939:54;4987:5;4939:54;:::i;:::-;5009:86;5088:6;5083:3;5009:86;:::i;:::-;5002:93;;5119:56;5169:5;5119:56;:::i;:::-;5198:7;5229:1;5214:284;5239:6;5236:1;5233:13;5214:284;;;5315:6;5309:13;5342:63;5401:3;5386:13;5342:63;:::i;:::-;5335:70;;5428:60;5481:6;5428:60;:::i;:::-;5418:70;;5274:224;5261:1;5258;5254:9;5249:14;;5214:284;;;5218:14;5514:3;5507:10;;4915:608;;;4791:732;;;;:::o;5529:373::-;5672:4;5710:2;5699:9;5695:18;5687:26;;5759:9;5753:4;5749:20;5745:1;5734:9;5730:17;5723:47;5787:108;5890:4;5881:6;5787:108;:::i;:::-;5779:116;;5529:373;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"337:1052:26:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"uint256\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"step\\\",\\\"type\\\":\\\"uint256\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"factory\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/UniswapV2/GetUniswapV2PairsBatchRequest.sol\\\":\\\"GetUniswapV2PairsBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV2/GetUniswapV2PairsBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0x44d0d290e07e6cc3f6a365f4c907b81419593172a9b47dd1a64e3d2942d20229\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://9f90e9388ee75d7b9c82f144e7f440de704bbe058c0287db83db0677f3819707\\\",\\\"dweb:/ipfs/QmfP1KFxDHdAFZSNYK9oP2prKypbw5FbqufxFGp3BVPMGB\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"from\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"step\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/UniswapV2/GetUniswapV2PairsBatchRequest.sol\":\"GetUniswapV2PairsBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/UniswapV2/GetUniswapV2PairsBatchRequest.sol\":{\"keccak256\":\"0x44d0d290e07e6cc3f6a365f4c907b81419593172a9b47dd1a64e3d2942d20229\",\"urls\":[\"bzz-raw://9f90e9388ee75d7b9c82f144e7f440de704bbe058c0287db83db0677f3819707\",\"dweb:/ipfs/QmfP1KFxDHdAFZSNYK9oP2prKypbw5FbqufxFGp3BVPMGB\"],\"license\":\"MIT\"}},\"version\":1},\"id\":26}"
  },
  {
    "path": "src/amms/abi/GetUniswapV2PoolDataBatchRequest.json",
    "content": "{\n    \"abi\": [\n        {\n            \"type\": \"constructor\",\n            \"inputs\": [\n                {\n                    \"name\": \"pools\",\n                    \"type\": \"address[]\",\n                    \"internalType\": \"address[]\"\n                }\n            ],\n            \"stateMutability\": \"nonpayable\"\n        }\n    ],\n    \"bytecode\": {\n        \"object\": \"0x608060405234801561000f575f5ffd5b50604051610c67380380610c67833981810160405281019061003191906108bb565b5f815167ffffffffffffffff81111561004d5761004c610725565b5b60405190808252806020026020018201604052801561008657816020015b61007361067e565b81526020019060019003908161006b5790505b5090505f5f90505b825181101561061f575f8382815181106100ab576100aa610902565b5b602002602001015190506100c48161064d60201b60201c565b156100cf5750610614565b6100d761067e565b8173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610120573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610144919061092f565b815f019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508173ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101e7919061092f565b816020019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050610230815f015161064d60201b60201c565b1561023c575050610614565b61024f816020015161064d60201b60201c565b1561025b575050610614565b5f5f825f015173ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161030a91906109ac565b5f604051808303815f8787f1925050503d805f8114610344576040519150601f19603f3d011682016040523d82523d5f602084013e610349565b606091505b509150915081156103b8575f60208251036103a8578180602001905181019061037291906109f5565b90505f811480610382575060ff81115b15610391575050505050610614565b80846080019060ff16908160ff16815250506103b2565b5050505050610614565b506103c1565b50505050610614565b5f5f846020015173ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161047191906109ac565b5f604051808303815f8787f1925050503d805f81146104ab576040519150601f19603f3d011682016040523d82523d5f602084013e6104b0565b606091505b50915091508115610523575f602082510361051157818060200190518101906104d991906109f5565b90505f8114806104e9575060ff81115b156104fa5750505050505050610614565b808660a0019060ff16908160ff168152505061051d565b50505050505050610614565b5061052e565b505050505050610614565b8573ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610577573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059b9190610a9c565b508660400187606001826dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff16815250826dffffffffffffffffffffffffffff166dffffffffffffffffffffffffffff1681525050508488888151811061060257610601610902565b5b60200260200101819052505050505050505b80600101905061008e565b505f816040516020016106329190610c46565b60405160208183030381529060405290506020810180590381f35b5f5f8273ffffffffffffffffffffffffffffffffffffffff163b036106755760019050610679565b5f90505b919050565b6040518060c001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f6dffffffffffffffffffffffffffff1681526020015f6dffffffffffffffffffffffffffff1681526020015f60ff1681526020015f60ff1681525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61075b82610715565b810181811067ffffffffffffffff8211171561077a57610779610725565b5b80604052505050565b5f61078c610700565b90506107988282610752565b919050565b5f67ffffffffffffffff8211156107b7576107b6610725565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6107f5826107cc565b9050919050565b610805816107eb565b811461080f575f5ffd5b50565b5f81519050610820816107fc565b92915050565b5f6108386108338461079d565b610783565b9050808382526020820190506020840283018581111561085b5761085a6107c8565b5b835b8181101561088457806108708882610812565b84526020840193505060208101905061085d565b5050509392505050565b5f82601f8301126108a2576108a1610711565b5b81516108b2848260208601610826565b91505092915050565b5f602082840312156108d0576108cf610709565b5b5f82015167ffffffffffffffff8111156108ed576108ec61070d565b5b6108f98482850161088e565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6020828403121561094457610943610709565b5b5f61095184828501610812565b91505092915050565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6109868261095a565b6109908185610964565b93506109a081856020860161096e565b80840191505092915050565b5f6109b7828461097c565b915081905092915050565b5f819050919050565b6109d4816109c2565b81146109de575f5ffd5b50565b5f815190506109ef816109cb565b92915050565b5f60208284031215610a0a57610a09610709565b5b5f610a17848285016109e1565b91505092915050565b5f6dffffffffffffffffffffffffffff82169050919050565b610a4281610a20565b8114610a4c575f5ffd5b50565b5f81519050610a5d81610a39565b92915050565b5f63ffffffff82169050919050565b610a7b81610a63565b8114610a85575f5ffd5b50565b5f81519050610a9681610a72565b92915050565b5f5f5f60608486031215610ab357610ab2610709565b5b5f610ac086828701610a4f565b9350506020610ad186828701610a4f565b9250506040610ae286828701610a88565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610b1e816107eb565b82525050565b610b2d81610a20565b82525050565b5f60ff82169050919050565b610b4881610b33565b82525050565b60c082015f820151610b625f850182610b15565b506020820151610b756020850182610b15565b506040820151610b886040850182610b24565b506060820151610b9b6060850182610b24565b506080820151610bae6080850182610b3f565b5060a0820151610bc160a0850182610b3f565b50505050565b5f610bd28383610b4e565b60c08301905092915050565b5f602082019050919050565b5f610bf482610aec565b610bfe8185610af6565b9350610c0983610b06565b805f5b83811015610c39578151610c208882610bc7565b9750610c2b83610bde565b925050600181019050610c0c565b5085935050505092915050565b5f6020820190508181035f830152610c5e8184610bea565b90509291505056fe\",\n        \"sourceMap\": \"549:3691:27:-:0;;;786:3253;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;832:29;879:5;:12;864:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;832:60;;908:9;920:1;908:13;;903:2596;927:5;:12;923:1;:16;903:2596;;;960:19;982:5;988:1;982:8;;;;;;;;:::i;:::-;;;;;;;;960:30;;1009:27;1024:11;1009:14;;;:27;;:::i;:::-;1005:41;;;1038:8;;;1005:41;1061:24;;:::i;:::-;1167:11;1152:34;;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1134:8;:15;;:54;;;;;;;;;;;1235:11;1220:34;;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1202:8;:15;;:54;;;;;;;;;;;1345:31;1360:8;:15;;;1345:14;;;:31;;:::i;:::-;1341:45;;;1378:8;;;;1341:45;1404:31;1419:8;:15;;;1404:14;;;:31;;:::i;:::-;1400:45;;;1437:8;;;;1400:45;1513:26;1557:31;1605:8;:15;;;:20;;1631:5;1659:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1605:109;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1495:219;;;;1733:21;1729:640;;;1774:22;1848:2;1819:18;:25;:31;1815:493;;1929:18;1893:111;;;;;;;;;;;;:::i;:::-;1874:130;;2049:1;2031:14;:19;:43;;;;2071:3;2054:14;:20;2031:43;2027:208;;;2102:8;;;;;;;2027:208;2197:14;2165:8;:23;;:47;;;;;;;;;;;1815:493;;;2281:8;;;;;;;1815:493;1756:566;1729:640;;;2346:8;;;;;;1729:640;2436:26;2480:31;2528:8;:15;;;:20;;2554:5;2582:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2528:109;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2418:219;;;;2656:21;2652:640;;;2697:22;2771:2;2742:18;:25;:31;2738:493;;2852:18;2816:111;;;;;;;;;;;;:::i;:::-;2797:130;;2972:1;2954:14;:19;:43;;;;2994:3;2977:14;:20;2954:43;2950:208;;;3025:8;;;;;;;;;2950:208;3120:14;3088:8;:23;;:47;;;;;;;;;;;2738:493;;;3204:8;;;;;;;;;2738:493;2679:566;2652:640;;;3269:8;;;;;;;;2652:640;3409:11;3377:69;;;:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3334:114;3335:8;:17;;3354:8;:17;;3334:114;;;;;;;;;;;;;;;;;;3480:8;3463:11;3475:1;3463:14;;;;;;;;:::i;:::-;;;;;;;:25;;;;946:2553;;;;;;903:2596;941:3;;;;;903:2596;;;;3701:28;3743:11;3732:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;3701:54;;3963:4;3946:15;3942:26;4012:9;4003:7;3999:23;3988:9;3981:42;4045:193;4108:4;4150:1;4128:6;:18;;;:23;4124:108;;4174:4;4167:11;;;;4124:108;4216:5;4209:12;;4045:193;;;;:::o;549:3691::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:311::-;1250:4;1340:18;1332:6;1329:30;1326:56;;;1362:18;;:::i;:::-;1326:56;1412:4;1404:6;1400:17;1392:25;;1472:4;1466;1462:15;1454:23;;1173:311;;;:::o;1490:117::-;1599:1;1596;1589:12;1613:126;1650:7;1690:42;1683:5;1679:54;1668:65;;1613:126;;;:::o;1745:96::-;1782:7;1811:24;1829:5;1811:24;:::i;:::-;1800:35;;1745:96;;;:::o;1847:122::-;1920:24;1938:5;1920:24;:::i;:::-;1913:5;1910:35;1900:63;;1959:1;1956;1949:12;1900:63;1847:122;:::o;1975:143::-;2032:5;2063:6;2057:13;2048:22;;2079:33;2106:5;2079:33;:::i;:::-;1975:143;;;;:::o;2141:732::-;2248:5;2273:81;2289:64;2346:6;2289:64;:::i;:::-;2273:81;:::i;:::-;2264:90;;2374:5;2403:6;2396:5;2389:21;2437:4;2430:5;2426:16;2419:23;;2490:4;2482:6;2478:17;2470:6;2466:30;2519:3;2511:6;2508:15;2505:122;;;2538:79;;:::i;:::-;2505:122;2653:6;2636:231;2670:6;2665:3;2662:15;2636:231;;;2745:3;2774:48;2818:3;2806:10;2774:48;:::i;:::-;2769:3;2762:61;2852:4;2847:3;2843:14;2836:21;;2712:155;2696:4;2691:3;2687:14;2680:21;;2636:231;;;2640:21;2254:619;;2141:732;;;;;:::o;2896:385::-;2978:5;3027:3;3020:4;3012:6;3008:17;3004:27;2994:122;;3035:79;;:::i;:::-;2994:122;3145:6;3139:13;3170:105;3271:3;3263:6;3256:4;3248:6;3244:17;3170:105;:::i;:::-;3161:114;;2984:297;2896:385;;;;:::o;3287:554::-;3382:6;3431:2;3419:9;3410:7;3406:23;3402:32;3399:119;;;3437:79;;:::i;:::-;3399:119;3578:1;3567:9;3563:17;3557:24;3608:18;3600:6;3597:30;3594:117;;;3630:79;;:::i;:::-;3594:117;3735:89;3816:7;3807:6;3796:9;3792:22;3735:89;:::i;:::-;3725:99;;3528:306;3287:554;;;;:::o;3847:180::-;3895:77;3892:1;3885:88;3992:4;3989:1;3982:15;4016:4;4013:1;4006:15;4033:351;4103:6;4152:2;4140:9;4131:7;4127:23;4123:32;4120:119;;;4158:79;;:::i;:::-;4120:119;4278:1;4303:64;4359:7;4350:6;4339:9;4335:22;4303:64;:::i;:::-;4293:74;;4249:128;4033:351;;;;:::o;4390:98::-;4441:6;4475:5;4469:12;4459:22;;4390:98;;;:::o;4494:147::-;4595:11;4632:3;4617:18;;4494:147;;;;:::o;4647:139::-;4736:6;4731:3;4726;4720:23;4777:1;4768:6;4763:3;4759:16;4752:27;4647:139;;;:::o;4792:386::-;4896:3;4924:38;4956:5;4924:38;:::i;:::-;4978:88;5059:6;5054:3;4978:88;:::i;:::-;4971:95;;5075:65;5133:6;5128:3;5121:4;5114:5;5110:16;5075:65;:::i;:::-;5165:6;5160:3;5156:16;5149:23;;4900:278;4792:386;;;;:::o;5184:271::-;5314:3;5336:93;5425:3;5416:6;5336:93;:::i;:::-;5329:100;;5446:3;5439:10;;5184:271;;;;:::o;5461:77::-;5498:7;5527:5;5516:16;;5461:77;;;:::o;5544:122::-;5617:24;5635:5;5617:24;:::i;:::-;5610:5;5607:35;5597:63;;5656:1;5653;5646:12;5597:63;5544:122;:::o;5672:143::-;5729:5;5760:6;5754:13;5745:22;;5776:33;5803:5;5776:33;:::i;:::-;5672:143;;;;:::o;5821:351::-;5891:6;5940:2;5928:9;5919:7;5915:23;5911:32;5908:119;;;5946:79;;:::i;:::-;5908:119;6066:1;6091:64;6147:7;6138:6;6127:9;6123:22;6091:64;:::i;:::-;6081:74;;6037:128;5821:351;;;;:::o;6178:114::-;6215:7;6255:30;6248:5;6244:42;6233:53;;6178:114;;;:::o;6298:122::-;6371:24;6389:5;6371:24;:::i;:::-;6364:5;6361:35;6351:63;;6410:1;6407;6400:12;6351:63;6298:122;:::o;6426:143::-;6483:5;6514:6;6508:13;6499:22;;6530:33;6557:5;6530:33;:::i;:::-;6426:143;;;;:::o;6575:93::-;6611:7;6651:10;6644:5;6640:22;6629:33;;6575:93;;;:::o;6674:120::-;6746:23;6763:5;6746:23;:::i;:::-;6739:5;6736:34;6726:62;;6784:1;6781;6774:12;6726:62;6674:120;:::o;6800:141::-;6856:5;6887:6;6881:13;6872:22;;6903:32;6929:5;6903:32;:::i;:::-;6800:141;;;;:::o;6947:661::-;7034:6;7042;7050;7099:2;7087:9;7078:7;7074:23;7070:32;7067:119;;;7105:79;;:::i;:::-;7067:119;7225:1;7250:64;7306:7;7297:6;7286:9;7282:22;7250:64;:::i;:::-;7240:74;;7196:128;7363:2;7389:64;7445:7;7436:6;7425:9;7421:22;7389:64;:::i;:::-;7379:74;;7334:129;7502:2;7528:63;7583:7;7574:6;7563:9;7559:22;7528:63;:::i;:::-;7518:73;;7473:128;6947:661;;;;;:::o;7614:141::-;7708:6;7742:5;7736:12;7726:22;;7614:141;;;:::o;7761:211::-;7887:11;7921:6;7916:3;7909:19;7961:4;7956:3;7952:14;7937:29;;7761:211;;;;:::o;7978:159::-;8072:4;8095:3;8087:11;;8125:4;8120:3;8116:14;8108:22;;7978:159;;;:::o;8143:108::-;8220:24;8238:5;8220:24;:::i;:::-;8215:3;8208:37;8143:108;;:::o;8257:::-;8334:24;8352:5;8334:24;:::i;:::-;8329:3;8322:37;8257:108;;:::o;8371:86::-;8406:7;8446:4;8439:5;8435:16;8424:27;;8371:86;;;:::o;8463:102::-;8536:22;8552:5;8536:22;:::i;:::-;8531:3;8524:35;8463:102;;:::o;8679:1221::-;8820:4;8815:3;8811:14;8909:4;8902:5;8898:16;8892:23;8928:63;8985:4;8980:3;8976:14;8962:12;8928:63;:::i;:::-;8835:166;9085:4;9078:5;9074:16;9068:23;9104:63;9161:4;9156:3;9152:14;9138:12;9104:63;:::i;:::-;9011:166;9263:4;9256:5;9252:16;9246:23;9282:63;9339:4;9334:3;9330:14;9316:12;9282:63;:::i;:::-;9187:168;9441:4;9434:5;9430:16;9424:23;9460:63;9517:4;9512:3;9508:14;9494:12;9460:63;:::i;:::-;9365:168;9625:4;9618:5;9614:16;9608:23;9644:59;9697:4;9692:3;9688:14;9674:12;9644:59;:::i;:::-;9543:170;9805:4;9798:5;9794:16;9788:23;9824:59;9877:4;9872:3;9868:14;9854:12;9824:59;:::i;:::-;9723:170;8789:1111;8679:1221;;:::o;9906:287::-;10029:10;10050:100;10146:3;10138:6;10050:100;:::i;:::-;10182:4;10177:3;10173:14;10159:28;;9906:287;;;;:::o;10199:140::-;10296:4;10328;10323:3;10319:14;10311:22;;10199:140;;;:::o;10457:948::-;10630:3;10659:81;10734:5;10659:81;:::i;:::-;10756:113;10862:6;10857:3;10756:113;:::i;:::-;10749:120;;10893:83;10970:5;10893:83;:::i;:::-;10999:7;11030:1;11015:365;11040:6;11037:1;11034:13;11015:365;;;11116:6;11110:13;11143:117;11256:3;11241:13;11143:117;:::i;:::-;11136:124;;11283:87;11363:6;11283:87;:::i;:::-;11273:97;;11075:305;11062:1;11059;11055:9;11050:14;;11015:365;;;11019:14;11396:3;11389:10;;10635:770;;;10457:948;;;;:::o;11411:481::-;11608:4;11646:2;11635:9;11631:18;11623:26;;11695:9;11689:4;11685:20;11681:1;11670:9;11666:17;11659:47;11723:162;11880:4;11871:6;11723:162;:::i;:::-;11715:170;;11411:481;;;;:::o\",\n        \"linkReferences\": {}\n    },\n    \"deployedBytecode\": {\n        \"object\": \"0x60806040525f5ffdfea164736f6c634300081c000a\",\n        \"sourceMap\": \"549:3691:27:-:0;;;;;\",\n        \"linkReferences\": {}\n    },\n    \"methodIdentifiers\": {},\n    \"rawMetadata\": \"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address[]\\\",\\\"name\\\":\\\"pools\\\",\\\"type\\\":\\\"address[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/UniswapV2/GetUniswapV2PoolDataBatchRequest.sol\\\":\\\"GetUniswapV2PoolDataBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV2/GetUniswapV2PoolDataBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0x1064713fd23fc7576c8aa10c7de0032af68c8c1ce6e4a2a645403e99e73ee0a9\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://8c9ba9f29f761a7fad1def642d9b248d5114e2ab7595d1a2f98d567b28175222\\\",\\\"dweb:/ipfs/QmZBgGhkWxFoPho5Jt34B9xaAFrYAAwgukLPqc4mV3LCHy\\\"]}},\\\"version\\\":1}\",\n    \"metadata\": {\n        \"compiler\": {\n            \"version\": \"0.8.28+commit.7893614a\"\n        },\n        \"language\": \"Solidity\",\n        \"output\": {\n            \"abi\": [\n                {\n                    \"inputs\": [\n                        {\n                            \"internalType\": \"address[]\",\n                            \"name\": \"pools\",\n                            \"type\": \"address[]\"\n                        }\n                    ],\n                    \"stateMutability\": \"nonpayable\",\n                    \"type\": \"constructor\"\n                }\n            ],\n            \"devdoc\": {\n                \"kind\": \"dev\",\n                \"methods\": {},\n                \"version\": 1\n            },\n            \"userdoc\": {\n                \"kind\": \"user\",\n                \"methods\": {},\n                \"version\": 1\n            }\n        },\n        \"settings\": {\n            \"remappings\": [\n                \"forge-std/=lib/forge-std/src/\"\n            ],\n            \"optimizer\": {\n                \"enabled\": false,\n                \"runs\": 200\n            },\n            \"metadata\": {\n                \"bytecodeHash\": \"none\"\n            },\n            \"compilationTarget\": {\n                \"src/UniswapV2/GetUniswapV2PoolDataBatchRequest.sol\": \"GetUniswapV2PoolDataBatchRequest\"\n            },\n            \"evmVersion\": \"cancun\",\n            \"libraries\": {}\n        },\n        \"sources\": {\n            \"src/UniswapV2/GetUniswapV2PoolDataBatchRequest.sol\": {\n                \"keccak256\": \"0x1064713fd23fc7576c8aa10c7de0032af68c8c1ce6e4a2a645403e99e73ee0a9\",\n                \"urls\": [\n                    \"bzz-raw://8c9ba9f29f761a7fad1def642d9b248d5114e2ab7595d1a2f98d567b28175222\",\n                    \"dweb:/ipfs/QmZBgGhkWxFoPho5Jt34B9xaAFrYAAwgukLPqc4mV3LCHy\"\n                ],\n                \"license\": \"MIT\"\n            }\n        },\n        \"version\": 1\n    },\n    \"id\": 27\n}"
  },
  {
    "path": "src/amms/abi/GetUniswapV3PoolDataBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"poolInfo\",\"type\":\"tuple[]\",\"internalType\":\"struct GetUniswapV3PoolDataBatchRequest.PoolInfo[]\",\"components\":[{\"name\":\"pool\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenA\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenB\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tickSpacing\",\"type\":\"int24\",\"internalType\":\"int24\"},{\"name\":\"minWord\",\"type\":\"int16\",\"internalType\":\"int16\"},{\"name\":\"maxWord\",\"type\":\"int16\",\"internalType\":\"int16\"}]}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b5060405161108238038061108283398181016040528101906100319190610800565b5f815167ffffffffffffffff81111561004d5761004c61055d565b5b60405190808252806020026020018201604052801561008657816020015b6100736104e2565b81526020019060019003908161006b5790505b5090505f5f90505b82518110156104b4575f8382815181106100ab576100aa610847565b5b602002602001015190505f815f015190505f8484815181106100d0576100cf610847565b5b602002602001015190505f600184608001518560a001516100f191906108a1565b60010b6100fe9190610903565b90508067ffffffffffffffff81111561011a5761011961055d565b5b6040519080825280602002602001820160405280156101485781602001602082028036833780820191505090505b50825f01819052505f8161010061015f9190610936565b67ffffffffffffffff8111156101785761017761055d565b5b6040519080825280602002602001820160405280156101b157816020015b61019e610503565b8152602001906001900390816101965790505b5090505f826101006101c39190610936565b67ffffffffffffffff8111156101dc576101db61055d565b5b60405190808252806020026020018201604052801561020a5781602001602082028036833780820191505090505b5090505f5f90505f5f90505f886080015190505b8860a0015160010b8160010b13610469575f8873ffffffffffffffffffffffffffffffffffffffff16635339c296836040518263ffffffff1660e01b81526004016102699190610986565b602060405180830381865afa158015610284573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102a891906109c9565b90505f81036102b75750610458565b5f5f90505b610100811015610426575f816001901b90505f5f828516141590508015610419575f8d6060015160020b846102f19190610936565b610100886102ff9190610936565b6103099190610903565b90505f8d73ffffffffffffffffffffffffffffffffffffffff1663f30dba93836040518263ffffffff1660e01b81526004016103459190610a03565b61010060405180830381865afa158015610361573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103859190610c2c565b9050818a8a8151811061039b5761039a610847565b5b602002602001019060020b908160020b815250506040518060600160405280825f01516fffffffffffffffffffffffffffffffff1681526020018260200151600f0b81526020018260e0015115158152508b8a815181106103ff576103fe610847565b5b60200260200101819052508861041490610c58565b985050505b50508060010190506102bc565b5080885f0151848151811061043e5761043d610847565b5b6020026020010181815250508261045490610c58565b9250505b8061046290610c9f565b905061021e565b50818452818352838660400181905250828660200181905250858a8a8151811061049657610495610847565b5b6020026020010181905250505050505050505080600101905061008e565b505f816040516020016104c79190611061565b60405160208183030381529060405290506020810180590381f35b60405180606001604052806060815260200160608152602001606081525090565b60405180606001604052805f6fffffffffffffffffffffffffffffffff1681526020015f600f0b81526020015f151581525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6105938261054d565b810181811067ffffffffffffffff821117156105b2576105b161055d565b5b80604052505050565b5f6105c4610538565b90506105d0828261058a565b919050565b5f67ffffffffffffffff8211156105ef576105ee61055d565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61063182610608565b9050919050565b61064181610627565b811461064b575f5ffd5b50565b5f8151905061065c81610638565b92915050565b5f8160020b9050919050565b61067781610662565b8114610681575f5ffd5b50565b5f815190506106928161066e565b92915050565b5f8160010b9050919050565b6106ad81610698565b81146106b7575f5ffd5b50565b5f815190506106c8816106a4565b92915050565b5f60c082840312156106e3576106e2610604565b5b6106ed60c06105bb565b90505f6106fc8482850161064e565b5f83015250602061070f8482850161064e565b60208301525060406107238482850161064e565b604083015250606061073784828501610684565b606083015250608061074b848285016106ba565b60808301525060a061075f848285016106ba565b60a08301525092915050565b5f61077d610778846105d5565b6105bb565b90508083825260208201905060c084028301858111156107a05761079f610600565b5b835b818110156107c957806107b588826106ce565b84526020840193505060c0810190506107a2565b5050509392505050565b5f82601f8301126107e7576107e6610549565b5b81516107f784826020860161076b565b91505092915050565b5f6020828403121561081557610814610541565b5b5f82015167ffffffffffffffff81111561083257610831610545565b5b61083e848285016107d3565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6108ab82610698565b91506108b683610698565b92508282039050617fff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000821217156108f4576108f3610874565b5b92915050565b5f819050919050565b5f61090d826108fa565b9150610918836108fa565b92508282019050808211156109305761092f610874565b5b92915050565b5f610940826108fa565b915061094b836108fa565b9250828202610959816108fa565b915082820484148315176109705761096f610874565b5b5092915050565b61098081610698565b82525050565b5f6020820190506109995f830184610977565b92915050565b6109a8816108fa565b81146109b2575f5ffd5b50565b5f815190506109c38161099f565b92915050565b5f602082840312156109de576109dd610541565b5b5f6109eb848285016109b5565b91505092915050565b6109fd81610662565b82525050565b5f602082019050610a165f8301846109f4565b92915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b610a4081610a1c565b8114610a4a575f5ffd5b50565b5f81519050610a5b81610a37565b92915050565b5f81600f0b9050919050565b610a7681610a61565b8114610a80575f5ffd5b50565b5f81519050610a9181610a6d565b92915050565b5f8160060b9050919050565b610aac81610a97565b8114610ab6575f5ffd5b50565b5f81519050610ac781610aa3565b92915050565b610ad681610608565b8114610ae0575f5ffd5b50565b5f81519050610af181610acd565b92915050565b5f63ffffffff82169050919050565b610b0f81610af7565b8114610b19575f5ffd5b50565b5f81519050610b2a81610b06565b92915050565b5f8115159050919050565b610b4481610b30565b8114610b4e575f5ffd5b50565b5f81519050610b5f81610b3b565b92915050565b5f6101008284031215610b7b57610b7a610604565b5b610b866101006105bb565b90505f610b9584828501610a4d565b5f830152506020610ba884828501610a83565b6020830152506040610bbc848285016109b5565b6040830152506060610bd0848285016109b5565b6060830152506080610be484828501610ab9565b60808301525060a0610bf884828501610ae3565b60a08301525060c0610c0c84828501610b1c565b60c08301525060e0610c2084828501610b51565b60e08301525092915050565b5f6101008284031215610c4257610c41610541565b5b5f610c4f84828501610b65565b91505092915050565b5f610c62826108fa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610c9457610c93610874565b5b600182019050919050565b5f610ca982610698565b9150617fff8203610cbd57610cbc610874565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610d23816108fa565b82525050565b5f610d348383610d1a565b60208301905092915050565b5f602082019050919050565b5f610d5682610cf1565b610d608185610cfb565b9350610d6b83610d0b565b805f5b83811015610d9b578151610d828882610d29565b9750610d8d83610d40565b925050600181019050610d6e565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610dda81610662565b82525050565b5f610deb8383610dd1565b60208301905092915050565b5f602082019050919050565b5f610e0d82610da8565b610e178185610db2565b9350610e2283610dc2565b805f5b83811015610e52578151610e398882610de0565b9750610e4483610df7565b925050600181019050610e25565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b610e9181610a1c565b82525050565b610ea081610a61565b82525050565b610eaf81610b30565b82525050565b606082015f820151610ec95f850182610e88565b506020820151610edc6020850182610e97565b506040820151610eef6040850182610ea6565b50505050565b5f610f008383610eb5565b60608301905092915050565b5f602082019050919050565b5f610f2282610e5f565b610f2c8185610e69565b9350610f3783610e79565b805f5b83811015610f67578151610f4e8882610ef5565b9750610f5983610f0c565b925050600181019050610f3a565b5085935050505092915050565b5f606083015f8301518482035f860152610f8e8282610d4c565b91505060208301518482036020860152610fa88282610e03565b91505060408301518482036040860152610fc28282610f18565b9150508091505092915050565b5f610fda8383610f74565b905092915050565b5f602082019050919050565b5f610ff882610cc8565b6110028185610cd2565b93508360208202850161101485610ce2565b805f5b8581101561104f57848403895281516110308582610fcf565b945061103b83610fe2565b925060208a01995050600181019050611017565b50829750879550505050505092915050565b5f6020820190508181035f8301526110798184610fee565b90509291505056fe\",\"sourceMap\":\"192:3422:29:-:0;;;728:2884;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;778:29;825:8;:15;810:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;778:63;;857:9;869:1;857:13;;852:2222;876:8;:15;872:1;:19;852:2222;;;912:20;935:8;944:1;935:11;;;;;;;;:::i;:::-;;;;;;;;912:34;;960:24;1007:4;:9;;;960:57;;1032:24;1059:11;1071:1;1059:14;;;;;;;;:::i;:::-;;;;;;;;1032:41;;1087:17;1154:1;1137:4;:12;;;1122:4;:12;;;:27;;;;:::i;:::-;1115:35;;1107:48;;;;:::i;:::-;1087:68;;1206:9;1192:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1170:8;:19;;:46;;;;1231:26;1281:9;1275:3;:15;;;;:::i;:::-;1260:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;1231:60;;1305:23;1349:9;1343:3;:15;;;;:::i;:::-;1331:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1305:54;;1374:22;1399:1;1374:26;;1629:20;1652:1;1629:24;;1672:7;1682:4;:12;;;1672:22;;1667:1137;1701:4;:12;;;1696:17;;:1;:17;;;1667:1137;;1738:18;1759:4;:15;;;1775:1;1759:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1738:39;;1814:1;1800:10;:15;1796:70;;1839:8;;;1796:70;1889:9;1901:1;1889:13;;1884:809;1908:3;1904:1;:7;1884:809;;;1940:11;1959:1;1954;:6;;1940:20;;1983:16;2024:1;2016:3;2003:10;:16;2002:23;;1983:42;;2051:11;2047:628;;;2090:15;2161:4;:16;;;2154:24;;2142:1;:37;;;;:::i;:::-;2136:3;2121:12;:18;;;;:::i;:::-;:58;;;;:::i;:::-;2090:91;;2208:40;2251:4;:10;;;2262:9;2251:21;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2208:64;;2326:9;2299:8;2308:14;2299:24;;;;;;;;:::i;:::-;;;;;;;:36;;;;;;;;;;;2388:221;;;;;;;;2443:4;:19;;;2388:221;;;;;;2506:4;:17;;;2388:221;;;;;;2566:4;:16;;;2388:221;;;;;2361:8;2370:14;2361:24;;;;;;;;:::i;:::-;;;;;;;:248;;;;2636:16;;;;:::i;:::-;;;2064:611;;2047:628;1918:775;;1913:3;;;;;1884:809;;;;2747:10;2711:8;:19;;;2731:12;2711:33;;;;;;;;:::i;:::-;;;;;;;:46;;;;;2775:14;;;;:::i;:::-;;;1720:1084;1667:1137;1715:3;;;;:::i;:::-;;;1667:1137;;;;2862:14;2852:8;2845:32;2911:14;2901:8;2894:32;2971:8;2954;:14;;:25;;;;3016:8;2993;:20;;:31;;;;3055:8;3038:11;3050:1;3038:14;;;;;;;;:::i;:::-;;;;;;;:25;;;;898:2176;;;;;;;;893:3;;;;;852:2222;;;;3276:27;3317:11;3306:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;3276:53;;3536:4;3520:14;3516:25;3585:9;3576:7;3572:23;3561:9;3554:42;192:3422;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:338::-;1277:4;1367:18;1359:6;1356:30;1353:56;;;1389:18;;:::i;:::-;1353:56;1439:4;1431:6;1427:17;1419:25;;1499:4;1493;1489:15;1481:23;;1173:338;;;:::o;1517:117::-;1626:1;1623;1616:12;1640:117;1749:1;1746;1739:12;1886:126;1923:7;1963:42;1956:5;1952:54;1941:65;;1886:126;;;:::o;2018:96::-;2055:7;2084:24;2102:5;2084:24;:::i;:::-;2073:35;;2018:96;;;:::o;2120:122::-;2193:24;2211:5;2193:24;:::i;:::-;2186:5;2183:35;2173:63;;2232:1;2229;2222:12;2173:63;2120:122;:::o;2248:143::-;2305:5;2336:6;2330:13;2321:22;;2352:33;2379:5;2352:33;:::i;:::-;2248:143;;;;:::o;2397:90::-;2432:7;2475:5;2472:1;2461:20;2450:31;;2397:90;;;:::o;2493:118::-;2564:22;2580:5;2564:22;:::i;:::-;2557:5;2554:33;2544:61;;2601:1;2598;2591:12;2544:61;2493:118;:::o;2617:139::-;2672:5;2703:6;2697:13;2688:22;;2719:31;2744:5;2719:31;:::i;:::-;2617:139;;;;:::o;2762:90::-;2797:7;2840:5;2837:1;2826:20;2815:31;;2762:90;;;:::o;2858:118::-;2929:22;2945:5;2929:22;:::i;:::-;2922:5;2919:33;2909:61;;2966:1;2963;2956:12;2909:61;2858:118;:::o;2982:139::-;3037:5;3068:6;3062:13;3053:22;;3084:31;3109:5;3084:31;:::i;:::-;2982:139;;;;:::o;3183:1310::-;3270:5;3314:4;3302:9;3297:3;3293:19;3289:30;3286:117;;;3322:79;;:::i;:::-;3286:117;3421:21;3437:4;3421:21;:::i;:::-;3412:30;;3501:1;3541:60;3597:3;3588:6;3577:9;3573:22;3541:60;:::i;:::-;3534:4;3527:5;3523:16;3516:86;3452:161;3674:2;3715:60;3771:3;3762:6;3751:9;3747:22;3715:60;:::i;:::-;3708:4;3701:5;3697:16;3690:86;3623:164;3848:2;3889:60;3945:3;3936:6;3925:9;3921:22;3889:60;:::i;:::-;3882:4;3875:5;3871:16;3864:86;3797:164;4027:2;4068:58;4122:3;4113:6;4102:9;4098:22;4068:58;:::i;:::-;4061:4;4054:5;4050:16;4043:84;3971:167;4200:3;4242:58;4296:3;4287:6;4276:9;4272:22;4242:58;:::i;:::-;4235:4;4228:5;4224:16;4217:84;4148:164;4374:3;4416:58;4470:3;4461:6;4450:9;4446:22;4416:58;:::i;:::-;4409:4;4402:5;4398:16;4391:84;4322:164;3183:1310;;;;:::o;4557:813::-;4691:5;4716:108;4732:91;4816:6;4732:91;:::i;:::-;4716:108;:::i;:::-;4707:117;;4844:5;4873:6;4866:5;4859:21;4907:4;4900:5;4896:16;4889:23;;4960:4;4952:6;4948:17;4940:6;4936:30;4989:3;4981:6;4978:15;4975:122;;;5008:79;;:::i;:::-;4975:122;5123:6;5106:258;5140:6;5135:3;5132:15;5106:258;;;5215:3;5244:75;5315:3;5303:10;5244:75;:::i;:::-;5239:3;5232:88;5349:4;5344:3;5340:14;5333:21;;5182:182;5166:4;5161:3;5157:14;5150:21;;5106:258;;;5110:21;4697:673;;4557:813;;;;;:::o;5434:439::-;5543:5;5592:3;5585:4;5577:6;5573:17;5569:27;5559:122;;5600:79;;:::i;:::-;5559:122;5710:6;5704:13;5735:132;5863:3;5855:6;5848:4;5840:6;5836:17;5735:132;:::i;:::-;5726:141;;5549:324;5434:439;;;;:::o;5879:608::-;6001:6;6050:2;6038:9;6029:7;6025:23;6021:32;6018:119;;;6056:79;;:::i;:::-;6018:119;6197:1;6186:9;6182:17;6176:24;6227:18;6219:6;6216:30;6213:117;;;6249:79;;:::i;:::-;6213:117;6354:116;6462:7;6453:6;6442:9;6438:22;6354:116;:::i;:::-;6344:126;;6147:333;5879:608;;;;:::o;6493:180::-;6541:77;6538:1;6531:88;6638:4;6635:1;6628:15;6662:4;6659:1;6652:15;6679:180;6727:77;6724:1;6717:88;6824:4;6821:1;6814:15;6848:4;6845:1;6838:15;6865:311;6903:4;6923:18;6939:1;6923:18;:::i;:::-;6918:23;;6955:18;6971:1;6955:18;:::i;:::-;6950:23;;6997:1;6994;6990:9;6982:17;;7129:6;7123:4;7119:17;7038:66;7032:4;7028:77;7012:134;7009:160;;;7149:18;;:::i;:::-;7009:160;6865:311;;;;:::o;7182:77::-;7219:7;7248:5;7237:16;;7182:77;;;:::o;7265:191::-;7305:3;7324:20;7342:1;7324:20;:::i;:::-;7319:25;;7358:20;7376:1;7358:20;:::i;:::-;7353:25;;7401:1;7398;7394:9;7387:16;;7422:3;7419:1;7416:10;7413:36;;;7429:18;;:::i;:::-;7413:36;7265:191;;;;:::o;7462:410::-;7502:7;7525:20;7543:1;7525:20;:::i;:::-;7520:25;;7559:20;7577:1;7559:20;:::i;:::-;7554:25;;7614:1;7611;7607:9;7636:30;7654:11;7636:30;:::i;:::-;7625:41;;7815:1;7806:7;7802:15;7799:1;7796:22;7776:1;7769:9;7749:83;7726:139;;7845:18;;:::i;:::-;7726:139;7510:362;7462:410;;;;:::o;7878:112::-;7961:22;7977:5;7961:22;:::i;:::-;7956:3;7949:35;7878:112;;:::o;7996:214::-;8085:4;8123:2;8112:9;8108:18;8100:26;;8136:67;8200:1;8189:9;8185:17;8176:6;8136:67;:::i;:::-;7996:214;;;;:::o;8216:122::-;8289:24;8307:5;8289:24;:::i;:::-;8282:5;8279:35;8269:63;;8328:1;8325;8318:12;8269:63;8216:122;:::o;8344:143::-;8401:5;8432:6;8426:13;8417:22;;8448:33;8475:5;8448:33;:::i;:::-;8344:143;;;;:::o;8493:351::-;8563:6;8612:2;8600:9;8591:7;8587:23;8583:32;8580:119;;;8618:79;;:::i;:::-;8580:119;8738:1;8763:64;8819:7;8810:6;8799:9;8795:22;8763:64;:::i;:::-;8753:74;;8709:128;8493:351;;;;:::o;8850:112::-;8933:22;8949:5;8933:22;:::i;:::-;8928:3;8921:35;8850:112;;:::o;8968:214::-;9057:4;9095:2;9084:9;9080:18;9072:26;;9108:67;9172:1;9161:9;9157:17;9148:6;9108:67;:::i;:::-;8968:214;;;;:::o;9188:118::-;9225:7;9265:34;9258:5;9254:46;9243:57;;9188:118;;;:::o;9312:122::-;9385:24;9403:5;9385:24;:::i;:::-;9378:5;9375:35;9365:63;;9424:1;9421;9414:12;9365:63;9312:122;:::o;9440:143::-;9497:5;9528:6;9522:13;9513:22;;9544:33;9571:5;9544:33;:::i;:::-;9440:143;;;;:::o;9589:92::-;9625:7;9669:5;9665:2;9654:21;9643:32;;9589:92;;;:::o;9687:120::-;9759:23;9776:5;9759:23;:::i;:::-;9752:5;9749:34;9739:62;;9797:1;9794;9787:12;9739:62;9687:120;:::o;9813:141::-;9869:5;9900:6;9894:13;9885:22;;9916:32;9942:5;9916:32;:::i;:::-;9813:141;;;;:::o;9960:90::-;9995:7;10038:5;10035:1;10024:20;10013:31;;9960:90;;;:::o;10056:118::-;10127:22;10143:5;10127:22;:::i;:::-;10120:5;10117:33;10107:61;;10164:1;10161;10154:12;10107:61;10056:118;:::o;10180:139::-;10235:5;10266:6;10260:13;10251:22;;10282:31;10307:5;10282:31;:::i;:::-;10180:139;;;;:::o;10325:122::-;10398:24;10416:5;10398:24;:::i;:::-;10391:5;10388:35;10378:63;;10437:1;10434;10427:12;10378:63;10325:122;:::o;10453:143::-;10510:5;10541:6;10535:13;10526:22;;10557:33;10584:5;10557:33;:::i;:::-;10453:143;;;;:::o;10602:93::-;10638:7;10678:10;10671:5;10667:22;10656:33;;10602:93;;;:::o;10701:120::-;10773:23;10790:5;10773:23;:::i;:::-;10766:5;10763:34;10753:62;;10811:1;10808;10801:12;10753:62;10701:120;:::o;10827:141::-;10883:5;10914:6;10908:13;10899:22;;10930:32;10956:5;10930:32;:::i;:::-;10827:141;;;;:::o;10974:90::-;11008:7;11051:5;11044:13;11037:21;11026:32;;10974:90;;;:::o;11070:116::-;11140:21;11155:5;11140:21;:::i;:::-;11133:5;11130:32;11120:60;;11176:1;11173;11166:12;11120:60;11070:116;:::o;11192:137::-;11246:5;11277:6;11271:13;11262:22;;11293:30;11317:5;11293:30;:::i;:::-;11192:137;;;;:::o;11378:1754::-;11465:5;11509:6;11497:9;11492:3;11488:19;11484:32;11481:119;;;11519:79;;:::i;:::-;11481:119;11618:23;11634:6;11618:23;:::i;:::-;11609:32;;11710:1;11750:60;11806:3;11797:6;11786:9;11782:22;11750:60;:::i;:::-;11743:4;11736:5;11732:16;11725:86;11651:171;11889:2;11930:59;11985:3;11976:6;11965:9;11961:22;11930:59;:::i;:::-;11923:4;11916:5;11912:16;11905:85;11832:169;12077:2;12118:60;12174:3;12165:6;12154:9;12150:22;12118:60;:::i;:::-;12111:4;12104:5;12100:16;12093:86;12011:179;12266:2;12307:60;12363:3;12354:6;12343:9;12339:22;12307:60;:::i;:::-;12300:4;12293:5;12289:16;12282:86;12200:179;12455:3;12497:58;12551:3;12542:6;12531:9;12527:22;12497:58;:::i;:::-;12490:4;12483:5;12479:16;12472:84;12389:178;12652:3;12694:60;12750:3;12741:6;12730:9;12726:22;12694:60;:::i;:::-;12687:4;12680:5;12676:16;12669:86;12577:189;12835:3;12877:59;12932:3;12923:6;12912:9;12908:22;12877:59;:::i;:::-;12870:4;12863:5;12859:16;12852:85;12776:172;13014:3;13056:57;13109:3;13100:6;13089:9;13085:22;13056:57;:::i;:::-;13049:4;13042:5;13038:16;13031:83;12958:167;11378:1754;;;;:::o;13138:406::-;13235:6;13284:3;13272:9;13263:7;13259:23;13255:33;13252:120;;;13291:79;;:::i;:::-;13252:120;13411:1;13436:91;13519:7;13510:6;13499:9;13495:22;13436:91;:::i;:::-;13426:101;;13382:155;13138:406;;;;:::o;13550:233::-;13589:3;13612:24;13630:5;13612:24;:::i;:::-;13603:33;;13658:66;13651:5;13648:77;13645:103;;13728:18;;:::i;:::-;13645:103;13775:1;13768:5;13764:13;13757:20;;13550:233;;;:::o;13789:169::-;13826:3;13849:22;13865:5;13849:22;:::i;:::-;13840:31;;13893:6;13886:5;13883:17;13880:43;;13903:18;;:::i;:::-;13880:43;13950:1;13943:5;13939:13;13932:20;;13789:169;;;:::o;13964:141::-;14058:6;14092:5;14086:12;14076:22;;13964:141;;;:::o;14111:211::-;14237:11;14271:6;14266:3;14259:19;14311:4;14306:3;14302:14;14287:29;;14111:211;;;;:::o;14328:159::-;14422:4;14445:3;14437:11;;14475:4;14470:3;14466:14;14458:22;;14328:159;;;:::o;14493:114::-;14560:6;14594:5;14588:12;14578:22;;14493:114;;;:::o;14613:174::-;14702:11;14736:6;14731:3;14724:19;14776:4;14771:3;14767:14;14752:29;;14613:174;;;;:::o;14793:132::-;14860:4;14883:3;14875:11;;14913:4;14908:3;14904:14;14896:22;;14793:132;;;:::o;14931:108::-;15008:24;15026:5;15008:24;:::i;:::-;15003:3;14996:37;14931:108;;:::o;15045:179::-;15114:10;15135:46;15177:3;15169:6;15135:46;:::i;:::-;15213:4;15208:3;15204:14;15190:28;;15045:179;;;;:::o;15230:113::-;15300:4;15332;15327:3;15323:14;15315:22;;15230:113;;;:::o;15379:712::-;15488:3;15517:54;15565:5;15517:54;:::i;:::-;15587:76;15656:6;15651:3;15587:76;:::i;:::-;15580:83;;15687:56;15737:5;15687:56;:::i;:::-;15766:7;15797:1;15782:284;15807:6;15804:1;15801:13;15782:284;;;15883:6;15877:13;15910:63;15969:3;15954:13;15910:63;:::i;:::-;15903:70;;15996:60;16049:6;15996:60;:::i;:::-;15986:70;;15842:224;15829:1;15826;15822:9;15817:14;;15782:284;;;15786:14;16082:3;16075:10;;15493:598;;;15379:712;;;;:::o;16097:112::-;16162:6;16196:5;16190:12;16180:22;;16097:112;;;:::o;16215:172::-;16302:11;16336:6;16331:3;16324:19;16376:4;16371:3;16367:14;16352:29;;16215:172;;;;:::o;16393:130::-;16458:4;16481:3;16473:11;;16511:4;16506:3;16502:14;16494:22;;16393:130;;;:::o;16529:102::-;16602:22;16618:5;16602:22;:::i;:::-;16597:3;16590:35;16529:102;;:::o;16637:171::-;16702:10;16723:42;16761:3;16753:6;16723:42;:::i;:::-;16797:4;16792:3;16788:14;16774:28;;16637:171;;;;:::o;16814:111::-;16882:4;16914;16909:3;16905:14;16897:22;;16814:111;;;:::o;16957:696::-;17062:3;17091:52;17137:5;17091:52;:::i;:::-;17159:74;17226:6;17221:3;17159:74;:::i;:::-;17152:81;;17257:54;17305:5;17257:54;:::i;:::-;17334:7;17365:1;17350:278;17375:6;17372:1;17369:13;17350:278;;;17451:6;17445:13;17478:59;17533:3;17518:13;17478:59;:::i;:::-;17471:66;;17560:58;17611:6;17560:58;:::i;:::-;17550:68;;17410:218;17397:1;17394;17390:9;17385:14;;17350:278;;;17354:14;17644:3;17637:10;;17067:586;;;16957:696;;;;:::o;17659:141::-;17753:6;17787:5;17781:12;17771:22;;17659:141;;;:::o;17806:201::-;17922:11;17956:6;17951:3;17944:19;17996:4;17991:3;17987:14;17972:29;;17806:201;;;;:::o;18013:159::-;18107:4;18130:3;18122:11;;18160:4;18155:3;18151:14;18143:22;;18013:159;;;:::o;18178:108::-;18255:24;18273:5;18255:24;:::i;:::-;18250:3;18243:37;18178:108;;:::o;18292:105::-;18367:23;18384:5;18367:23;:::i;:::-;18362:3;18355:36;18292:105;;:::o;18403:99::-;18474:21;18489:5;18474:21;:::i;:::-;18469:3;18462:34;18403:99;;:::o;18616:692::-;18757:4;18752:3;18748:14;18854:4;18847:5;18843:16;18837:23;18873:63;18930:4;18925:3;18921:14;18907:12;18873:63;:::i;:::-;18772:174;19036:4;19029:5;19025:16;19019:23;19055:61;19110:4;19105:3;19101:14;19087:12;19055:61;:::i;:::-;18956:170;19215:4;19208:5;19204:16;19198:23;19234:57;19285:4;19280:3;19276:14;19262:12;19234:57;:::i;:::-;19136:165;18726:582;18616:692;;:::o;19314:287::-;19437:10;19458:100;19554:3;19546:6;19458:100;:::i;:::-;19590:4;19585:3;19581:14;19567:28;;19314:287;;;;:::o;19607:140::-;19704:4;19736;19731:3;19727:14;19719:22;;19607:140;;;:::o;19865:928::-;20028:3;20057:81;20132:5;20057:81;:::i;:::-;20154:103;20250:6;20245:3;20154:103;:::i;:::-;20147:110;;20281:83;20358:5;20281:83;:::i;:::-;20387:7;20418:1;20403:365;20428:6;20425:1;20422:13;20403:365;;;20504:6;20498:13;20531:117;20644:3;20629:13;20531:117;:::i;:::-;20524:124;;20671:87;20751:6;20671:87;:::i;:::-;20661:97;;20463:305;20450:1;20447;20443:9;20438:14;;20403:365;;;20407:14;20784:3;20777:10;;20033:760;;;19865:928;;;;:::o;20907:1070::-;21020:3;21056:4;21051:3;21047:14;21149:4;21142:5;21138:16;21132:23;21202:3;21196:4;21192:14;21185:4;21180:3;21176:14;21169:38;21228:103;21326:4;21312:12;21228:103;:::i;:::-;21220:111;;21071:271;21431:4;21424:5;21420:16;21414:23;21484:3;21478:4;21474:14;21467:4;21462:3;21458:14;21451:38;21510:99;21604:4;21590:12;21510:99;:::i;:::-;21502:107;;21352:268;21703:4;21696:5;21692:16;21686:23;21756:3;21750:4;21746:14;21739:4;21734:3;21730:14;21723:38;21782:157;21934:4;21920:12;21782:157;:::i;:::-;21774:165;;21630:320;21967:4;21960:11;;21025:952;20907:1070;;;;:::o;21983:264::-;22106:10;22141:100;22237:3;22229:6;22141:100;:::i;:::-;22127:114;;21983:264;;;;:::o;22253:140::-;22350:4;22382;22377:3;22373:14;22365:22;;22253:140;;;:::o;22511:1127::-;22684:3;22713:81;22788:5;22713:81;:::i;:::-;22810:113;22916:6;22911:3;22810:113;:::i;:::-;22803:120;;22949:3;22994:4;22986:6;22982:17;22977:3;22973:27;23024:83;23101:5;23024:83;:::i;:::-;23130:7;23161:1;23146:447;23171:6;23168:1;23165:13;23146:447;;;23242:9;23236:4;23232:20;23227:3;23220:33;23293:6;23287:13;23321:118;23434:4;23419:13;23321:118;:::i;:::-;23313:126;;23462:87;23542:6;23462:87;:::i;:::-;23452:97;;23578:4;23573:3;23569:14;23562:21;;23206:387;23193:1;23190;23186:9;23181:14;;23146:447;;;23150:14;23609:4;23602:11;;23629:3;23622:10;;22689:949;;;;;22511:1127;;;;:::o;23644:481::-;23841:4;23879:2;23868:9;23864:18;23856:26;;23928:9;23922:4;23918:20;23914:1;23903:9;23899:17;23892:47;23956:162;24113:4;24104:6;23956:162;:::i;:::-;23948:170;;23644:481;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"192:3422:29:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"components\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"pool\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"tokenA\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"tokenB\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"int24\\\",\\\"name\\\":\\\"tickSpacing\\\",\\\"type\\\":\\\"int24\\\"},{\\\"internalType\\\":\\\"int16\\\",\\\"name\\\":\\\"minWord\\\",\\\"type\\\":\\\"int16\\\"},{\\\"internalType\\\":\\\"int16\\\",\\\"name\\\":\\\"maxWord\\\",\\\"type\\\":\\\"int16\\\"}],\\\"internalType\\\":\\\"struct GetUniswapV3PoolDataBatchRequest.PoolInfo[]\\\",\\\"name\\\":\\\"poolInfo\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/UniswapV3/GetUniswapV3PoolDataBatchRequest.sol\\\":\\\"GetUniswapV3PoolDataBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV3/GetUniswapV3PoolDataBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0x9f934c25022edc48289bf9f793adbe0794afba25d7a32470176b71e50b81ce38\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://d9bd62b4ce3f65115272abd4357021ffde6e57a93ddf27d0cb6787f6af51da13\\\",\\\"dweb:/ipfs/QmPuy5R7MUNHfpmxiTuEXvzjBN6RM8XBPTXeC5djotkTMJ\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"struct GetUniswapV3PoolDataBatchRequest.PoolInfo[]\",\"name\":\"poolInfo\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenA\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenB\",\"type\":\"address\"},{\"internalType\":\"int24\",\"name\":\"tickSpacing\",\"type\":\"int24\"},{\"internalType\":\"int16\",\"name\":\"minWord\",\"type\":\"int16\"},{\"internalType\":\"int16\",\"name\":\"maxWord\",\"type\":\"int16\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/UniswapV3/GetUniswapV3PoolDataBatchRequest.sol\":\"GetUniswapV3PoolDataBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/UniswapV3/GetUniswapV3PoolDataBatchRequest.sol\":{\"keccak256\":\"0x9f934c25022edc48289bf9f793adbe0794afba25d7a32470176b71e50b81ce38\",\"urls\":[\"bzz-raw://d9bd62b4ce3f65115272abd4357021ffde6e57a93ddf27d0cb6787f6af51da13\",\"dweb:/ipfs/QmPuy5R7MUNHfpmxiTuEXvzjBN6RM8XBPTXeC5djotkTMJ\"],\"license\":\"MIT\"}},\"version\":1},\"id\":29}"
  },
  {
    "path": "src/amms/abi/GetUniswapV3PoolSlot0BatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"pools\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b5060405161082a38038061082a83398181016040528101906100319190610468565b5f815167ffffffffffffffff81111561004d5761004c6102d2565b5b60405190808252806020026020018201604052801561008657816020015b61007361027a565b81526020019060019003908161006b5790505b5090505f5f90505b825181101561024c575f8282815181106100ab576100aa6104af565b5b602002602001015190505f8483815181106100c9576100c86104af565b5b602002602001015190505f8190508073ffffffffffffffffffffffffffffffffffffffff16631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610120573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101449190610521565b83602001906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156101bc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101e0919061064e565b8673ffffffffffffffffffffffffffffffffffffffff16965090919293509091925090915090505084604001855f018260020b60020b81525082815250505082858581518110610233576102326104af565b5b602002602001018190525050505080600101905061008e565b505f8160405160200161025f9190610809565b60405160208183030381529060405290506020810180590381f35b60405180606001604052805f60020b81526020015f6fffffffffffffffffffffffffffffffff1681526020015f81525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610308826102c2565b810181811067ffffffffffffffff82111715610327576103266102d2565b5b80604052505050565b5f6103396102ad565b905061034582826102ff565b919050565b5f67ffffffffffffffff821115610364576103636102d2565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6103a282610379565b9050919050565b6103b281610398565b81146103bc575f5ffd5b50565b5f815190506103cd816103a9565b92915050565b5f6103e56103e08461034a565b610330565b9050808382526020820190506020840283018581111561040857610407610375565b5b835b81811015610431578061041d88826103bf565b84526020840193505060208101905061040a565b5050509392505050565b5f82601f83011261044f5761044e6102be565b5b815161045f8482602086016103d3565b91505092915050565b5f6020828403121561047d5761047c6102b6565b5b5f82015167ffffffffffffffff81111561049a576104996102ba565b5b6104a68482850161043b565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6fffffffffffffffffffffffffffffffff82169050919050565b610500816104dc565b811461050a575f5ffd5b50565b5f8151905061051b816104f7565b92915050565b5f60208284031215610536576105356102b6565b5b5f6105438482850161050d565b91505092915050565b61055581610379565b811461055f575f5ffd5b50565b5f815190506105708161054c565b92915050565b5f8160020b9050919050565b61058b81610576565b8114610595575f5ffd5b50565b5f815190506105a681610582565b92915050565b5f61ffff82169050919050565b6105c2816105ac565b81146105cc575f5ffd5b50565b5f815190506105dd816105b9565b92915050565b5f60ff82169050919050565b6105f8816105e3565b8114610602575f5ffd5b50565b5f81519050610613816105ef565b92915050565b5f8115159050919050565b61062d81610619565b8114610637575f5ffd5b50565b5f8151905061064881610624565b92915050565b5f5f5f5f5f5f5f60e0888a031215610669576106686102b6565b5b5f6106768a828b01610562565b97505060206106878a828b01610598565b96505060406106988a828b016105cf565b95505060606106a98a828b016105cf565b94505060806106ba8a828b016105cf565b93505060a06106cb8a828b01610605565b92505060c06106dc8a828b0161063a565b91505092959891949750929550565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61071d81610576565b82525050565b61072c816104dc565b82525050565b5f819050919050565b61074481610732565b82525050565b606082015f82015161075e5f850182610714565b5060208201516107716020850182610723565b506040820151610784604085018261073b565b50505050565b5f610795838361074a565b60608301905092915050565b5f602082019050919050565b5f6107b7826106eb565b6107c181856106f5565b93506107cc83610705565b805f5b838110156107fc5781516107e3888261078a565b97506107ee836107a1565b9250506001810190506107cf565b5085935050505092915050565b5f6020820190508181035f83015261082181846107ad565b90509291505056fe\",\"sourceMap\":\"192:1215:30:-:0;;;345:1060;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;391:31;441:5;:12;425:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;391:63;;470:9;482:1;470:13;;465:401;489:5;:12;485:1;:16;465:401;;;522:26;551:12;564:1;551:15;;;;;;;;:::i;:::-;;;;;;;;522:44;;580:19;602:5;608:1;602:8;;;;;;;;:::i;:::-;;;;;;;;580:30;;625:24;672:11;625:59;;720:4;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;698:9;:19;;:38;;;;;;;;;;;801:4;:10;;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;751:62;;;;;;;;;;;;;;;;;;;;752:9;:19;;773:9;:14;;751:62;;;;;;;;;;;;;;846:9;828:12;841:1;828:15;;;;;;;;:::i;:::-;;;;;;;:27;;;;508:358;;;503:3;;;;;465:401;;;;1068:27;1109:12;1098:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;1068:54;;1329:4;1313:14;1309:25;1378:9;1369:7;1365:23;1354:9;1347:42;192:1215;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:311::-;1250:4;1340:18;1332:6;1329:30;1326:56;;;1362:18;;:::i;:::-;1326:56;1412:4;1404:6;1400:17;1392:25;;1472:4;1466;1462:15;1454:23;;1173:311;;;:::o;1490:117::-;1599:1;1596;1589:12;1613:126;1650:7;1690:42;1683:5;1679:54;1668:65;;1613:126;;;:::o;1745:96::-;1782:7;1811:24;1829:5;1811:24;:::i;:::-;1800:35;;1745:96;;;:::o;1847:122::-;1920:24;1938:5;1920:24;:::i;:::-;1913:5;1910:35;1900:63;;1959:1;1956;1949:12;1900:63;1847:122;:::o;1975:143::-;2032:5;2063:6;2057:13;2048:22;;2079:33;2106:5;2079:33;:::i;:::-;1975:143;;;;:::o;2141:732::-;2248:5;2273:81;2289:64;2346:6;2289:64;:::i;:::-;2273:81;:::i;:::-;2264:90;;2374:5;2403:6;2396:5;2389:21;2437:4;2430:5;2426:16;2419:23;;2490:4;2482:6;2478:17;2470:6;2466:30;2519:3;2511:6;2508:15;2505:122;;;2538:79;;:::i;:::-;2505:122;2653:6;2636:231;2670:6;2665:3;2662:15;2636:231;;;2745:3;2774:48;2818:3;2806:10;2774:48;:::i;:::-;2769:3;2762:61;2852:4;2847:3;2843:14;2836:21;;2712:155;2696:4;2691:3;2687:14;2680:21;;2636:231;;;2640:21;2254:619;;2141:732;;;;;:::o;2896:385::-;2978:5;3027:3;3020:4;3012:6;3008:17;3004:27;2994:122;;3035:79;;:::i;:::-;2994:122;3145:6;3139:13;3170:105;3271:3;3263:6;3256:4;3248:6;3244:17;3170:105;:::i;:::-;3161:114;;2984:297;2896:385;;;;:::o;3287:554::-;3382:6;3431:2;3419:9;3410:7;3406:23;3402:32;3399:119;;;3437:79;;:::i;:::-;3399:119;3578:1;3567:9;3563:17;3557:24;3608:18;3600:6;3597:30;3594:117;;;3630:79;;:::i;:::-;3594:117;3735:89;3816:7;3807:6;3796:9;3792:22;3735:89;:::i;:::-;3725:99;;3528:306;3287:554;;;;:::o;3847:180::-;3895:77;3892:1;3885:88;3992:4;3989:1;3982:15;4016:4;4013:1;4006:15;4033:118;4070:7;4110:34;4103:5;4099:46;4088:57;;4033:118;;;:::o;4157:122::-;4230:24;4248:5;4230:24;:::i;:::-;4223:5;4220:35;4210:63;;4269:1;4266;4259:12;4210:63;4157:122;:::o;4285:143::-;4342:5;4373:6;4367:13;4358:22;;4389:33;4416:5;4389:33;:::i;:::-;4285:143;;;;:::o;4434:351::-;4504:6;4553:2;4541:9;4532:7;4528:23;4524:32;4521:119;;;4559:79;;:::i;:::-;4521:119;4679:1;4704:64;4760:7;4751:6;4740:9;4736:22;4704:64;:::i;:::-;4694:74;;4650:128;4434:351;;;;:::o;4791:122::-;4864:24;4882:5;4864:24;:::i;:::-;4857:5;4854:35;4844:63;;4903:1;4900;4893:12;4844:63;4791:122;:::o;4919:143::-;4976:5;5007:6;5001:13;4992:22;;5023:33;5050:5;5023:33;:::i;:::-;4919:143;;;;:::o;5068:90::-;5103:7;5146:5;5143:1;5132:20;5121:31;;5068:90;;;:::o;5164:118::-;5235:22;5251:5;5235:22;:::i;:::-;5228:5;5225:33;5215:61;;5272:1;5269;5262:12;5215:61;5164:118;:::o;5288:139::-;5343:5;5374:6;5368:13;5359:22;;5390:31;5415:5;5390:31;:::i;:::-;5288:139;;;;:::o;5433:89::-;5469:7;5509:6;5502:5;5498:18;5487:29;;5433:89;;;:::o;5528:120::-;5600:23;5617:5;5600:23;:::i;:::-;5593:5;5590:34;5580:62;;5638:1;5635;5628:12;5580:62;5528:120;:::o;5654:141::-;5710:5;5741:6;5735:13;5726:22;;5757:32;5783:5;5757:32;:::i;:::-;5654:141;;;;:::o;5801:86::-;5836:7;5876:4;5869:5;5865:16;5854:27;;5801:86;;;:::o;5893:118::-;5964:22;5980:5;5964:22;:::i;:::-;5957:5;5954:33;5944:61;;6001:1;5998;5991:12;5944:61;5893:118;:::o;6017:139::-;6072:5;6103:6;6097:13;6088:22;;6119:31;6144:5;6119:31;:::i;:::-;6017:139;;;;:::o;6162:90::-;6196:7;6239:5;6232:13;6225:21;6214:32;;6162:90;;;:::o;6258:116::-;6328:21;6343:5;6328:21;:::i;:::-;6321:5;6318:32;6308:60;;6364:1;6361;6354:12;6308:60;6258:116;:::o;6380:137::-;6434:5;6465:6;6459:13;6450:22;;6481:30;6505:5;6481:30;:::i;:::-;6380:137;;;;:::o;6523:1271::-;6637:6;6645;6653;6661;6669;6677;6685;6734:3;6722:9;6713:7;6709:23;6705:33;6702:120;;;6741:79;;:::i;:::-;6702:120;6861:1;6886:64;6942:7;6933:6;6922:9;6918:22;6886:64;:::i;:::-;6876:74;;6832:128;6999:2;7025:62;7079:7;7070:6;7059:9;7055:22;7025:62;:::i;:::-;7015:72;;6970:127;7136:2;7162:63;7217:7;7208:6;7197:9;7193:22;7162:63;:::i;:::-;7152:73;;7107:128;7274:2;7300:63;7355:7;7346:6;7335:9;7331:22;7300:63;:::i;:::-;7290:73;;7245:128;7412:3;7439:63;7494:7;7485:6;7474:9;7470:22;7439:63;:::i;:::-;7429:73;;7383:129;7551:3;7578:62;7632:7;7623:6;7612:9;7608:22;7578:62;:::i;:::-;7568:72;;7522:128;7689:3;7716:61;7769:7;7760:6;7749:9;7745:22;7716:61;:::i;:::-;7706:71;;7660:127;6523:1271;;;;;;;;;;:::o;7800:142::-;7895:6;7929:5;7923:12;7913:22;;7800:142;;;:::o;7948:212::-;8075:11;8109:6;8104:3;8097:19;8149:4;8144:3;8140:14;8125:29;;7948:212;;;;:::o;8166:160::-;8261:4;8284:3;8276:11;;8314:4;8309:3;8305:14;8297:22;;8166:160;;;:::o;8332:102::-;8405:22;8421:5;8405:22;:::i;:::-;8400:3;8393:35;8332:102;;:::o;8440:108::-;8517:24;8535:5;8517:24;:::i;:::-;8512:3;8505:37;8440:108;;:::o;8554:77::-;8591:7;8620:5;8609:16;;8554:77;;;:::o;8637:108::-;8714:24;8732:5;8714:24;:::i;:::-;8709:3;8702:37;8637:108;;:::o;8863:683::-;9006:4;9001:3;8997:14;9093:4;9086:5;9082:16;9076:23;9112:59;9165:4;9160:3;9156:14;9142:12;9112:59;:::i;:::-;9021:160;9268:4;9261:5;9257:16;9251:23;9287:63;9344:4;9339:3;9335:14;9321:12;9287:63;:::i;:::-;9191:169;9447:4;9440:5;9436:16;9430:23;9466:63;9523:4;9518:3;9514:14;9500:12;9466:63;:::i;:::-;9370:169;8975:571;8863:683;;:::o;9552:291::-;9677:10;9698:102;9796:3;9788:6;9698:102;:::i;:::-;9832:4;9827:3;9823:14;9809:28;;9552:291;;;;:::o;9849:141::-;9947:4;9979;9974:3;9970:14;9962:22;;9849:141;;;:::o;10112:956::-;10287:3;10316:82;10392:5;10316:82;:::i;:::-;10414:114;10521:6;10516:3;10414:114;:::i;:::-;10407:121;;10552:84;10630:5;10552:84;:::i;:::-;10659:7;10690:1;10675:368;10700:6;10697:1;10694:13;10675:368;;;10776:6;10770:13;10803:119;10918:3;10903:13;10803:119;:::i;:::-;10796:126;;10945:88;11026:6;10945:88;:::i;:::-;10935:98;;10735:308;10722:1;10719;10715:9;10710:14;;10675:368;;;10679:14;11059:3;11052:10;;10292:776;;;10112:956;;;;:::o;11074:485::-;11273:4;11311:2;11300:9;11296:18;11288:26;;11360:9;11354:4;11350:20;11346:1;11335:9;11331:17;11324:47;11388:164;11547:4;11538:6;11388:164;:::i;:::-;11380:172;;11074:485;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"192:1215:30:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address[]\\\",\\\"name\\\":\\\"pools\\\",\\\"type\\\":\\\"address[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/UniswapV3/GetUniswapV3PoolSlot0BatchRequest.sol\\\":\\\"GetUniswapV3PoolSlot0BatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV3/GetUniswapV3PoolSlot0BatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0xaf8a81b6f2f914fd54a9adbfe170f17e2d39b2bb1dc5a52d89f42477fe21c28d\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://39a49464263df97fd16380057c325b99a91d5a6a24ef0720a844d0dec0e4098a\\\",\\\"dweb:/ipfs/QmPbDwPDsQ5n6SGJ5KNE3d47tXj3zosmebkXwEbagYPRH9\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"pools\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/UniswapV3/GetUniswapV3PoolSlot0BatchRequest.sol\":\"GetUniswapV3PoolSlot0BatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/UniswapV3/GetUniswapV3PoolSlot0BatchRequest.sol\":{\"keccak256\":\"0xaf8a81b6f2f914fd54a9adbfe170f17e2d39b2bb1dc5a52d89f42477fe21c28d\",\"urls\":[\"bzz-raw://39a49464263df97fd16380057c325b99a91d5a6a24ef0720a844d0dec0e4098a\",\"dweb:/ipfs/QmPbDwPDsQ5n6SGJ5KNE3d47tXj3zosmebkXwEbagYPRH9\"],\"license\":\"MIT\"}},\"version\":1},\"id\":30}"
  },
  {
    "path": "src/amms/abi/GetUniswapV3PoolTickBitmapBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"allPoolInfo\",\"type\":\"tuple[]\",\"internalType\":\"struct GetUniswapV3PoolTickBitmapBatchRequest.TickBitmapInfo[]\",\"components\":[{\"name\":\"pool\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"minWord\",\"type\":\"int16\",\"internalType\":\"int16\"},{\"name\":\"maxWord\",\"type\":\"int16\",\"internalType\":\"int16\"}]}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b506040516108b43803806108b4833981810160405281019061003191906104ef565b5f815167ffffffffffffffff81111561004d5761004c6102be565b5b60405190808252806020026020018201604052801561008057816020015b606081526020019060019003908161006b5790505b5090505f5f90505b825181101561026b575f8382815181106100a5576100a4610536565b5b602002602001015190505f815f015190505f6001836020015184604001516100cd9190610590565b6100d791906105f6565b61ffff1667ffffffffffffffff8111156100f4576100f36102be565b5b6040519080825280602002602001820160405280156101225781602001602082028036833780820191505090505b5090505f5f90505f846020015190505b846040015160010b8160010b13610239575f8473ffffffffffffffffffffffffffffffffffffffff16635339c296836040518263ffffffff1660e01b815260040161017d919061063a565b602060405180830381865afa158015610198573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101bc9190610686565b90505f81036101cb5750610228565b8160010b8484815181106101e2576101e1610536565b5b602002602001018181525050826101f8906106b1565b92508084848151811061020e5761020d610536565b5b60200260200101818152505082610224906106b1565b9250505b80610232906106f8565b9050610132565b508082528186868151811061025157610250610536565b5b602002602001018190525050505050806001019050610088565b505f8160405160200161027e9190610893565b60405160208183030381529060405290506020810180590381f35b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6102f4826102ae565b810181811067ffffffffffffffff82111715610313576103126102be565b5b80604052505050565b5f610325610299565b905061033182826102eb565b919050565b5f67ffffffffffffffff8211156103505761034f6102be565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61039282610369565b9050919050565b6103a281610388565b81146103ac575f5ffd5b50565b5f815190506103bd81610399565b92915050565b5f8160010b9050919050565b6103d8816103c3565b81146103e2575f5ffd5b50565b5f815190506103f3816103cf565b92915050565b5f6060828403121561040e5761040d610365565b5b610418606061031c565b90505f610427848285016103af565b5f83015250602061043a848285016103e5565b602083015250604061044e848285016103e5565b60408301525092915050565b5f61046c61046784610336565b61031c565b9050808382526020820190506060840283018581111561048f5761048e610361565b5b835b818110156104b857806104a488826103f9565b845260208401935050606081019050610491565b5050509392505050565b5f82601f8301126104d6576104d56102aa565b5b81516104e684826020860161045a565b91505092915050565b5f60208284031215610504576105036102a2565b5b5f82015167ffffffffffffffff811115610521576105206102a6565b5b61052d848285016104c2565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61059a826103c3565b91506105a5836103c3565b92508282039050617fff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000821217156105e3576105e2610563565b5b92915050565b5f61ffff82169050919050565b5f610600826105e9565b915061060b836105e9565b9250828201905061ffff81111561062557610624610563565b5b92915050565b610634816103c3565b82525050565b5f60208201905061064d5f83018461062b565b92915050565b5f819050919050565b61066581610653565b811461066f575f5ffd5b50565b5f815190506106808161065c565b92915050565b5f6020828403121561069b5761069a6102a2565b5b5f6106a884828501610672565b91505092915050565b5f6106bb82610653565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036106ed576106ec610563565b5b600182019050919050565b5f610702826103c3565b9150617fff820361071657610715610563565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61077c81610653565b82525050565b5f61078d8383610773565b60208301905092915050565b5f602082019050919050565b5f6107af8261074a565b6107b98185610754565b93506107c483610764565b805f5b838110156107f45781516107db8882610782565b97506107e683610799565b9250506001810190506107c7565b5085935050505092915050565b5f61080c83836107a5565b905092915050565b5f602082019050919050565b5f61082a82610721565b610834818561072b565b9350836020820285016108468561073b565b805f5b8581101561088157848403895281516108628582610801565b945061086d83610814565b925060208a01995050600181019050610849565b50829750879550505050505092915050565b5f6020820190508181035f8301526108ab8184610820565b90509291505056fe\",\"sourceMap\":\"192:1778:31:-:0;;;443:1525;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;502:33;554:11;:18;538:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;502:71;;589:9;601:1;589:13;;584:843;608:11;:18;604:1;:22;584:843;;;647:26;676:11;688:1;676:14;;;;;;;;:::i;:::-;;;;;;;;647:43;;704:24;751:4;:9;;;704:57;;776:28;859:1;843:4;:12;;;828:4;:12;;;:27;;;;:::i;:::-;821:39;;;;:::i;:::-;807:54;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;776:85;;876:15;894:1;876:19;;914:7;924:4;:12;;;914:22;;909:379;943:4;:12;;;938:17;;:1;:17;;;909:379;;980:18;1001:4;:15;;;1017:1;1001:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;980:39;;1056:1;1042:10;:15;1038:70;;1081:8;;;1038:70;1164:1;1157:9;;1126:11;1138:7;1126:20;;;;;;;;:::i;:::-;;;;;;;:41;;;;;1185:9;;;;:::i;:::-;;;1236:10;1213:11;1225:7;1213:20;;;;;;;;:::i;:::-;;;;;;;:33;;;;;1264:9;;;;:::i;:::-;;;962:326;909:379;957:3;;;;:::i;:::-;;;909:379;;;;1349:7;1336:11;1329:28;1405:11;1385:14;1400:1;1385:17;;;;;;;;:::i;:::-;;;;;;;:31;;;;633:794;;;;628:3;;;;;584:843;;;;1629:27;1670:14;1659:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;1629:56;;1892:4;1876:14;1872:25;1941:9;1932:7;1928:23;1917:9;1910:42;7:75:41;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:344::-;1283:4;1373:18;1365:6;1362:30;1359:56;;;1395:18;;:::i;:::-;1359:56;1445:4;1437:6;1433:17;1425:25;;1505:4;1499;1495:15;1487:23;;1173:344;;;:::o;1523:117::-;1632:1;1629;1622:12;1646:117;1755:1;1752;1745:12;1892:126;1929:7;1969:42;1962:5;1958:54;1947:65;;1892:126;;;:::o;2024:96::-;2061:7;2090:24;2108:5;2090:24;:::i;:::-;2079:35;;2024:96;;;:::o;2126:122::-;2199:24;2217:5;2199:24;:::i;:::-;2192:5;2189:35;2179:63;;2238:1;2235;2228:12;2179:63;2126:122;:::o;2254:143::-;2311:5;2342:6;2336:13;2327:22;;2358:33;2385:5;2358:33;:::i;:::-;2254:143;;;;:::o;2403:90::-;2438:7;2481:5;2478:1;2467:20;2456:31;;2403:90;;;:::o;2499:118::-;2570:22;2586:5;2570:22;:::i;:::-;2563:5;2560:33;2550:61;;2607:1;2604;2597:12;2550:61;2499:118;:::o;2623:139::-;2678:5;2709:6;2703:13;2694:22;;2725:31;2750:5;2725:31;:::i;:::-;2623:139;;;;:::o;2836:789::-;2929:5;2973:4;2961:9;2956:3;2952:19;2948:30;2945:117;;;2981:79;;:::i;:::-;2945:117;3080:21;3096:4;3080:21;:::i;:::-;3071:30;;3160:1;3200:60;3256:3;3247:6;3236:9;3232:22;3200:60;:::i;:::-;3193:4;3186:5;3182:16;3175:86;3111:161;3334:2;3375:58;3429:3;3420:6;3409:9;3405:22;3375:58;:::i;:::-;3368:4;3361:5;3357:16;3350:84;3282:163;3507:2;3548:58;3602:3;3593:6;3582:9;3578:22;3548:58;:::i;:::-;3541:4;3534:5;3530:16;3523:84;3455:163;2836:789;;;;:::o;3701:831::-;3841:5;3866:114;3882:97;3972:6;3882:97;:::i;:::-;3866:114;:::i;:::-;3857:123;;4000:5;4029:6;4022:5;4015:21;4063:4;4056:5;4052:16;4045:23;;4116:4;4108:6;4104:17;4096:6;4092:30;4145:3;4137:6;4134:15;4131:122;;;4164:79;;:::i;:::-;4131:122;4279:6;4262:264;4296:6;4291:3;4288:15;4262:264;;;4371:3;4400:81;4477:3;4465:10;4400:81;:::i;:::-;4395:3;4388:94;4511:4;4506:3;4502:14;4495:21;;4338:188;4322:4;4317:3;4313:14;4306:21;;4262:264;;;4266:21;3847:685;;3701:831;;;;;:::o;4608:451::-;4723:5;4772:3;4765:4;4757:6;4753:17;4749:27;4739:122;;4780:79;;:::i;:::-;4739:122;4890:6;4884:13;4915:138;5049:3;5041:6;5034:4;5026:6;5022:17;4915:138;:::i;:::-;4906:147;;4729:330;4608:451;;;;:::o;5065:620::-;5193:6;5242:2;5230:9;5221:7;5217:23;5213:32;5210:119;;;5248:79;;:::i;:::-;5210:119;5389:1;5378:9;5374:17;5368:24;5419:18;5411:6;5408:30;5405:117;;;5441:79;;:::i;:::-;5405:117;5546:122;5660:7;5651:6;5640:9;5636:22;5546:122;:::i;:::-;5536:132;;5339:339;5065:620;;;;:::o;5691:180::-;5739:77;5736:1;5729:88;5836:4;5833:1;5826:15;5860:4;5857:1;5850:15;5877:180;5925:77;5922:1;5915:88;6022:4;6019:1;6012:15;6046:4;6043:1;6036:15;6063:311;6101:4;6121:18;6137:1;6121:18;:::i;:::-;6116:23;;6153:18;6169:1;6153:18;:::i;:::-;6148:23;;6195:1;6192;6188:9;6180:17;;6327:6;6321:4;6317:17;6236:66;6230:4;6226:77;6210:134;6207:160;;;6347:18;;:::i;:::-;6207:160;6063:311;;;;:::o;6380:89::-;6416:7;6456:6;6449:5;6445:18;6434:29;;6380:89;;;:::o;6475:193::-;6514:3;6533:19;6550:1;6533:19;:::i;:::-;6528:24;;6566:19;6583:1;6566:19;:::i;:::-;6561:24;;6608:1;6605;6601:9;6594:16;;6631:6;6626:3;6623:15;6620:41;;;6641:18;;:::i;:::-;6620:41;6475:193;;;;:::o;6674:112::-;6757:22;6773:5;6757:22;:::i;:::-;6752:3;6745:35;6674:112;;:::o;6792:214::-;6881:4;6919:2;6908:9;6904:18;6896:26;;6932:67;6996:1;6985:9;6981:17;6972:6;6932:67;:::i;:::-;6792:214;;;;:::o;7012:77::-;7049:7;7078:5;7067:16;;7012:77;;;:::o;7095:122::-;7168:24;7186:5;7168:24;:::i;:::-;7161:5;7158:35;7148:63;;7207:1;7204;7197:12;7148:63;7095:122;:::o;7223:143::-;7280:5;7311:6;7305:13;7296:22;;7327:33;7354:5;7327:33;:::i;:::-;7223:143;;;;:::o;7372:351::-;7442:6;7491:2;7479:9;7470:7;7466:23;7462:32;7459:119;;;7497:79;;:::i;:::-;7459:119;7617:1;7642:64;7698:7;7689:6;7678:9;7674:22;7642:64;:::i;:::-;7632:74;;7588:128;7372:351;;;;:::o;7729:233::-;7768:3;7791:24;7809:5;7791:24;:::i;:::-;7782:33;;7837:66;7830:5;7827:77;7824:103;;7907:18;;:::i;:::-;7824:103;7954:1;7947:5;7943:13;7936:20;;7729:233;;;:::o;7968:169::-;8005:3;8028:22;8044:5;8028:22;:::i;:::-;8019:31;;8072:6;8065:5;8062:17;8059:43;;8082:18;;:::i;:::-;8059:43;8129:1;8122:5;8118:13;8111:20;;7968:169;;;:::o;8143:139::-;8235:6;8269:5;8263:12;8253:22;;8143:139;;;:::o;8288:209::-;8412:11;8446:6;8441:3;8434:19;8486:4;8481:3;8477:14;8462:29;;8288:209;;;;:::o;8503:157::-;8595:4;8618:3;8610:11;;8648:4;8643:3;8639:14;8631:22;;8503:157;;;:::o;8666:114::-;8733:6;8767:5;8761:12;8751:22;;8666:114;;;:::o;8786:174::-;8875:11;8909:6;8904:3;8897:19;8949:4;8944:3;8940:14;8925:29;;8786:174;;;;:::o;8966:132::-;9033:4;9056:3;9048:11;;9086:4;9081:3;9077:14;9069:22;;8966:132;;;:::o;9104:108::-;9181:24;9199:5;9181:24;:::i;:::-;9176:3;9169:37;9104:108;;:::o;9218:179::-;9287:10;9308:46;9350:3;9342:6;9308:46;:::i;:::-;9386:4;9381:3;9377:14;9363:28;;9218:179;;;;:::o;9403:113::-;9473:4;9505;9500:3;9496:14;9488:22;;9403:113;;;:::o;9552:712::-;9661:3;9690:54;9738:5;9690:54;:::i;:::-;9760:76;9829:6;9824:3;9760:76;:::i;:::-;9753:83;;9860:56;9910:5;9860:56;:::i;:::-;9939:7;9970:1;9955:284;9980:6;9977:1;9974:13;9955:284;;;10056:6;10050:13;10083:63;10142:3;10127:13;10083:63;:::i;:::-;10076:70;;10169:60;10222:6;10169:60;:::i;:::-;10159:70;;10015:224;10002:1;9999;9995:9;9990:14;;9955:284;;;9959:14;10255:3;10248:10;;9666:598;;;9552:712;;;;:::o;10270:256::-;10389:10;10424:96;10516:3;10508:6;10424:96;:::i;:::-;10410:110;;10270:256;;;;:::o;10532:138::-;10627:4;10659;10654:3;10650:14;10642:22;;10532:138;;;:::o;10710:1111::-;10879:3;10908:79;10981:5;10908:79;:::i;:::-;11003:111;11107:6;11102:3;11003:111;:::i;:::-;10996:118;;11140:3;11185:4;11177:6;11173:17;11168:3;11164:27;11215:81;11290:5;11215:81;:::i;:::-;11319:7;11350:1;11335:441;11360:6;11357:1;11354:13;11335:441;;;11431:9;11425:4;11421:20;11416:3;11409:33;11482:6;11476:13;11510:114;11619:4;11604:13;11510:114;:::i;:::-;11502:122;;11647:85;11725:6;11647:85;:::i;:::-;11637:95;;11761:4;11756:3;11752:14;11745:21;;11395:381;11382:1;11379;11375:9;11370:14;;11335:441;;;11339:14;11792:4;11785:11;;11812:3;11805:10;;10884:937;;;;;10710:1111;;;;:::o;11827:473::-;12020:4;12058:2;12047:9;12043:18;12035:26;;12107:9;12101:4;12097:20;12093:1;12082:9;12078:17;12071:47;12135:158;12288:4;12279:6;12135:158;:::i;:::-;12127:166;;11827:473;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"192:1778:31:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"components\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"pool\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"int16\\\",\\\"name\\\":\\\"minWord\\\",\\\"type\\\":\\\"int16\\\"},{\\\"internalType\\\":\\\"int16\\\",\\\"name\\\":\\\"maxWord\\\",\\\"type\\\":\\\"int16\\\"}],\\\"internalType\\\":\\\"struct GetUniswapV3PoolTickBitmapBatchRequest.TickBitmapInfo[]\\\",\\\"name\\\":\\\"allPoolInfo\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/UniswapV3/GetUniswapV3PoolTickBitmapBatchRequest.sol\\\":\\\"GetUniswapV3PoolTickBitmapBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV3/GetUniswapV3PoolTickBitmapBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0x1d72e66cf86ebcfc9b92460c7ef6b4964d191b3f6e67cd008cab226fd377af64\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://f8364aaeb50f6d6809de6e95dab98260d7abe6b2b7bc4a5b5386f2a65f928184\\\",\\\"dweb:/ipfs/QmRJFENg5eFBoSqRgskPL354vRaNoYh5Vgyqp47QTmdcP5\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"struct GetUniswapV3PoolTickBitmapBatchRequest.TickBitmapInfo[]\",\"name\":\"allPoolInfo\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"int16\",\"name\":\"minWord\",\"type\":\"int16\"},{\"internalType\":\"int16\",\"name\":\"maxWord\",\"type\":\"int16\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/UniswapV3/GetUniswapV3PoolTickBitmapBatchRequest.sol\":\"GetUniswapV3PoolTickBitmapBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/UniswapV3/GetUniswapV3PoolTickBitmapBatchRequest.sol\":{\"keccak256\":\"0x1d72e66cf86ebcfc9b92460c7ef6b4964d191b3f6e67cd008cab226fd377af64\",\"urls\":[\"bzz-raw://f8364aaeb50f6d6809de6e95dab98260d7abe6b2b7bc4a5b5386f2a65f928184\",\"dweb:/ipfs/QmRJFENg5eFBoSqRgskPL354vRaNoYh5Vgyqp47QTmdcP5\"],\"license\":\"MIT\"}},\"version\":1},\"id\":31}"
  },
  {
    "path": "src/amms/abi/GetUniswapV3PoolTickDataBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"allPoolInfo\",\"type\":\"tuple[]\",\"internalType\":\"struct GetUniswapV3PoolTickDataBatchRequest.TickDataInfo[]\",\"components\":[{\"name\":\"pool\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"ticks\",\"type\":\"int24[]\",\"internalType\":\"int24[]\"}]}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b50604051610b36380380610b368339818101604052810190610031919061063a565b5f815167ffffffffffffffff81111561004d5761004c61031f565b5b60405190808252806020026020018201604052801561008057816020015b606081526020019060019003908161006b5790505b5090505f5f90505b8251811015610297575f8382815181106100a5576100a4610681565b5b6020026020010151602001515167ffffffffffffffff8111156100cb576100ca61031f565b5b60405190808252806020026020018201604052801561010457816020015b6100f16102c5565b8152602001906001900390816100e95790505b5090505f5f90505b84838151811061011f5761011e610681565b5b6020026020010151602001515181101561026b575f85848151811061014757610146610681565b5b60200260200101515f015173ffffffffffffffffffffffffffffffffffffffff1663f30dba938786815181106101805761017f610681565b5b602002602001015160200151848151811061019e5761019d610681565b5b60200260200101516040518263ffffffff1660e01b81526004016101c291906106bd565b61010060405180830381865afa1580156101de573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102029190610919565b905060405180606001604052808260e0015115158152602001825f01516fffffffffffffffffffffffffffffffff1681526020018260200151600f0b81525083838151811061025457610253610681565b5b60200260200101819052505080600101905061010c565b50808383815181106102805761027f610681565b5b602002602001018190525050806001019050610088565b505f816040516020016102aa9190610b15565b60405160208183030381529060405290506020810180590381f35b60405180606001604052805f151581526020015f6fffffffffffffffffffffffffffffffff1681526020015f600f0b81525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6103558261030f565b810181811067ffffffffffffffff821117156103745761037361031f565b5b80604052505050565b5f6103866102fa565b9050610392828261034c565b919050565b5f67ffffffffffffffff8211156103b1576103b061031f565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6103f7826103ce565b9050919050565b610407816103ed565b8114610411575f5ffd5b50565b5f81519050610422816103fe565b92915050565b5f67ffffffffffffffff8211156104425761044161031f565b5b602082029050602081019050919050565b5f8160020b9050919050565b61046881610453565b8114610472575f5ffd5b50565b5f815190506104838161045f565b92915050565b5f61049b61049684610428565b61037d565b905080838252602082019050602084028301858111156104be576104bd6103c2565b5b835b818110156104e757806104d38882610475565b8452602084019350506020810190506104c0565b5050509392505050565b5f82601f8301126105055761050461030b565b5b8151610515848260208601610489565b91505092915050565b5f60408284031215610533576105326103c6565b5b61053d604061037d565b90505f61054c84828501610414565b5f83015250602082015167ffffffffffffffff81111561056f5761056e6103ca565b5b61057b848285016104f1565b60208301525092915050565b5f61059961059484610397565b61037d565b905080838252602082019050602084028301858111156105bc576105bb6103c2565b5b835b8181101561060357805167ffffffffffffffff8111156105e1576105e061030b565b5b8086016105ee898261051e565b855260208501945050506020810190506105be565b5050509392505050565b5f82601f8301126106215761062061030b565b5b8151610631848260208601610587565b91505092915050565b5f6020828403121561064f5761064e610303565b5b5f82015167ffffffffffffffff81111561066c5761066b610307565b5b6106788482850161060d565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b6106b781610453565b82525050565b5f6020820190506106d05f8301846106ae565b92915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b6106fa816106d6565b8114610704575f5ffd5b50565b5f81519050610715816106f1565b92915050565b5f81600f0b9050919050565b6107308161071b565b811461073a575f5ffd5b50565b5f8151905061074b81610727565b92915050565b5f819050919050565b61076381610751565b811461076d575f5ffd5b50565b5f8151905061077e8161075a565b92915050565b5f8160060b9050919050565b61079981610784565b81146107a3575f5ffd5b50565b5f815190506107b481610790565b92915050565b6107c3816103ce565b81146107cd575f5ffd5b50565b5f815190506107de816107ba565b92915050565b5f63ffffffff82169050919050565b6107fc816107e4565b8114610806575f5ffd5b50565b5f81519050610817816107f3565b92915050565b5f8115159050919050565b6108318161081d565b811461083b575f5ffd5b50565b5f8151905061084c81610828565b92915050565b5f6101008284031215610868576108676103c6565b5b61087361010061037d565b90505f61088284828501610707565b5f8301525060206108958482850161073d565b60208301525060406108a984828501610770565b60408301525060606108bd84828501610770565b60608301525060806108d1848285016107a6565b60808301525060a06108e5848285016107d0565b60a08301525060c06108f984828501610809565b60c08301525060e061090d8482850161083e565b60e08301525092915050565b5f610100828403121561092f5761092e610303565b5b5f61093c84828501610852565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6109a08161081d565b82525050565b6109af816106d6565b82525050565b6109be8161071b565b82525050565b606082015f8201516109d85f850182610997565b5060208201516109eb60208501826109a6565b5060408201516109fe60408501826109b5565b50505050565b5f610a0f83836109c4565b60608301905092915050565b5f602082019050919050565b5f610a318261096e565b610a3b8185610978565b9350610a4683610988565b805f5b83811015610a76578151610a5d8882610a04565b9750610a6883610a1b565b925050600181019050610a49565b5085935050505092915050565b5f610a8e8383610a27565b905092915050565b5f602082019050919050565b5f610aac82610945565b610ab6818561094f565b935083602082028501610ac88561095f565b805f5b85811015610b035784840389528151610ae48582610a83565b9450610aef83610a96565b925060208a01995050600181019050610acb565b50829750879550505050505092915050565b5f6020820190508181035f830152610b2d8184610aa2565b90509291505056fe\",\"sourceMap\":\"193:1568:32:-:0;;;435:1324;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;492:30;538:11;:18;525:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;492:65;;573:9;585:1;573:13;;568:650;592:11;:18;588:1;:22;568:650;;;631:22;667:11;679:1;667:14;;;;;;;;:::i;:::-;;;;;;;;:20;;;:27;656:39;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;631:64;;714:9;726:1;714:13;;709:457;733:11;745:1;733:14;;;;;;;;:::i;:::-;;;;;;;;:20;;;:27;729:1;:31;709:457;;;785:36;865:11;877:1;865:14;;;;;;;;:::i;:::-;;;;;;;;:19;;;824:84;;;909:11;921:1;909:14;;;;;;;;:::i;:::-;;;;;;;;:20;;;930:1;909:23;;;;;;;;:::i;:::-;;;;;;;;824:109;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;785:148;;966:185;;;;;;;;1116:4;:16;;;966:185;;;;;;1009:4;:19;;;966:185;;;;;;1064:4;:17;;;966:185;;;;;952:8;961:1;952:11;;;;;;;;:::i;:::-;;;;;;;:199;;;;767:399;762:3;;;;;709:457;;;;1199:8;1179:14;1194:1;1179:17;;;;;;;;:::i;:::-;;;;;;;:28;;;;617:601;612:3;;;;;568:650;;;;1420:27;1461:14;1450:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;1420:56;;1683:4;1667:14;1663:25;1732:9;1723:7;1719:23;1708:9;1701:42;193:1568;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:342::-;1281:4;1371:18;1363:6;1360:30;1357:56;;;1393:18;;:::i;:::-;1357:56;1443:4;1435:6;1431:17;1423:25;;1503:4;1497;1493:15;1485:23;;1173:342;;;:::o;1521:117::-;1630:1;1627;1620:12;1644:117;1753:1;1750;1743:12;1767:117;1876:1;1873;1866:12;1890:126;1927:7;1967:42;1960:5;1956:54;1945:65;;1890:126;;;:::o;2022:96::-;2059:7;2088:24;2106:5;2088:24;:::i;:::-;2077:35;;2022:96;;;:::o;2124:122::-;2197:24;2215:5;2197:24;:::i;:::-;2190:5;2187:35;2177:63;;2236:1;2233;2226:12;2177:63;2124:122;:::o;2252:143::-;2309:5;2340:6;2334:13;2325:22;;2356:33;2383:5;2356:33;:::i;:::-;2252:143;;;;:::o;2401:309::-;2476:4;2566:18;2558:6;2555:30;2552:56;;;2588:18;;:::i;:::-;2552:56;2638:4;2630:6;2626:17;2618:25;;2698:4;2692;2688:15;2680:23;;2401:309;;;:::o;2716:90::-;2751:7;2794:5;2791:1;2780:20;2769:31;;2716:90;;;:::o;2812:118::-;2883:22;2899:5;2883:22;:::i;:::-;2876:5;2873:33;2863:61;;2920:1;2917;2910:12;2863:61;2812:118;:::o;2936:139::-;2991:5;3022:6;3016:13;3007:22;;3038:31;3063:5;3038:31;:::i;:::-;2936:139;;;;:::o;3096:726::-;3201:5;3226:79;3242:62;3297:6;3242:62;:::i;:::-;3226:79;:::i;:::-;3217:88;;3325:5;3354:6;3347:5;3340:21;3388:4;3381:5;3377:16;3370:23;;3441:4;3433:6;3429:17;3421:6;3417:30;3470:3;3462:6;3459:15;3456:122;;;3489:79;;:::i;:::-;3456:122;3604:6;3587:229;3621:6;3616:3;3613:15;3587:229;;;3696:3;3725:46;3767:3;3755:10;3725:46;:::i;:::-;3720:3;3713:59;3801:4;3796:3;3792:14;3785:21;;3663:153;3647:4;3642:3;3638:14;3631:21;;3587:229;;;3591:21;3207:615;;3096:726;;;;;:::o;3843:381::-;3923:5;3972:3;3965:4;3957:6;3953:17;3949:27;3939:122;;3980:79;;:::i;:::-;3939:122;4090:6;4084:13;4115:103;4214:3;4206:6;4199:4;4191:6;4187:17;4115:103;:::i;:::-;4106:112;;3929:295;3843:381;;;;:::o;4294:790::-;4385:5;4429:4;4417:9;4412:3;4408:19;4404:30;4401:117;;;4437:79;;:::i;:::-;4401:117;4536:21;4552:4;4536:21;:::i;:::-;4527:30;;4616:1;4656:60;4712:3;4703:6;4692:9;4688:22;4656:60;:::i;:::-;4649:4;4642:5;4638:16;4631:86;4567:161;4809:2;4798:9;4794:18;4788:25;4840:18;4832:6;4829:30;4826:117;;;4862:79;;:::i;:::-;4826:117;4982:83;5061:3;5052:6;5041:9;5037:22;4982:83;:::i;:::-;4975:4;4968:5;4964:16;4957:109;4738:339;4294:790;;;;:::o;5156:1023::-;5294:5;5319:112;5335:95;5423:6;5335:95;:::i;:::-;5319:112;:::i;:::-;5310:121;;5451:5;5480:6;5473:5;5466:21;5514:4;5507:5;5503:16;5496:23;;5567:4;5559:6;5555:17;5547:6;5543:30;5596:3;5588:6;5585:15;5582:122;;;5615:79;;:::i;:::-;5582:122;5730:6;5713:460;5747:6;5742:3;5739:15;5713:460;;;5829:3;5823:10;5865:18;5852:11;5849:35;5846:122;;;5887:79;;:::i;:::-;5846:122;6011:11;6003:6;5999:24;6049:79;6124:3;6112:10;6049:79;:::i;:::-;6044:3;6037:92;6158:4;6153:3;6149:14;6142:21;;5789:384;;5773:4;5768:3;5764:14;5757:21;;5713:460;;;5717:21;5300:879;;5156:1023;;;;;:::o;6251:447::-;6364:5;6413:3;6406:4;6398:6;6394:17;6390:27;6380:122;;6421:79;;:::i;:::-;6380:122;6531:6;6525:13;6556:136;6688:3;6680:6;6673:4;6665:6;6661:17;6556:136;:::i;:::-;6547:145;;6370:328;6251:447;;;;:::o;6704:616::-;6830:6;6879:2;6867:9;6858:7;6854:23;6850:32;6847:119;;;6885:79;;:::i;:::-;6847:119;7026:1;7015:9;7011:17;7005:24;7056:18;7048:6;7045:30;7042:117;;;7078:79;;:::i;:::-;7042:117;7183:120;7295:7;7286:6;7275:9;7271:22;7183:120;:::i;:::-;7173:130;;6976:337;6704:616;;;;:::o;7326:180::-;7374:77;7371:1;7364:88;7471:4;7468:1;7461:15;7495:4;7492:1;7485:15;7512:112;7595:22;7611:5;7595:22;:::i;:::-;7590:3;7583:35;7512:112;;:::o;7630:214::-;7719:4;7757:2;7746:9;7742:18;7734:26;;7770:67;7834:1;7823:9;7819:17;7810:6;7770:67;:::i;:::-;7630:214;;;;:::o;7850:118::-;7887:7;7927:34;7920:5;7916:46;7905:57;;7850:118;;;:::o;7974:122::-;8047:24;8065:5;8047:24;:::i;:::-;8040:5;8037:35;8027:63;;8086:1;8083;8076:12;8027:63;7974:122;:::o;8102:143::-;8159:5;8190:6;8184:13;8175:22;;8206:33;8233:5;8206:33;:::i;:::-;8102:143;;;;:::o;8251:92::-;8287:7;8331:5;8327:2;8316:21;8305:32;;8251:92;;;:::o;8349:120::-;8421:23;8438:5;8421:23;:::i;:::-;8414:5;8411:34;8401:62;;8459:1;8456;8449:12;8401:62;8349:120;:::o;8475:141::-;8531:5;8562:6;8556:13;8547:22;;8578:32;8604:5;8578:32;:::i;:::-;8475:141;;;;:::o;8622:77::-;8659:7;8688:5;8677:16;;8622:77;;;:::o;8705:122::-;8778:24;8796:5;8778:24;:::i;:::-;8771:5;8768:35;8758:63;;8817:1;8814;8807:12;8758:63;8705:122;:::o;8833:143::-;8890:5;8921:6;8915:13;8906:22;;8937:33;8964:5;8937:33;:::i;:::-;8833:143;;;;:::o;8982:90::-;9017:7;9060:5;9057:1;9046:20;9035:31;;8982:90;;;:::o;9078:118::-;9149:22;9165:5;9149:22;:::i;:::-;9142:5;9139:33;9129:61;;9186:1;9183;9176:12;9129:61;9078:118;:::o;9202:139::-;9257:5;9288:6;9282:13;9273:22;;9304:31;9329:5;9304:31;:::i;:::-;9202:139;;;;:::o;9347:122::-;9420:24;9438:5;9420:24;:::i;:::-;9413:5;9410:35;9400:63;;9459:1;9456;9449:12;9400:63;9347:122;:::o;9475:143::-;9532:5;9563:6;9557:13;9548:22;;9579:33;9606:5;9579:33;:::i;:::-;9475:143;;;;:::o;9624:93::-;9660:7;9700:10;9693:5;9689:22;9678:33;;9624:93;;;:::o;9723:120::-;9795:23;9812:5;9795:23;:::i;:::-;9788:5;9785:34;9775:62;;9833:1;9830;9823:12;9775:62;9723:120;:::o;9849:141::-;9905:5;9936:6;9930:13;9921:22;;9952:32;9978:5;9952:32;:::i;:::-;9849:141;;;;:::o;9996:90::-;10030:7;10073:5;10066:13;10059:21;10048:32;;9996:90;;;:::o;10092:116::-;10162:21;10177:5;10162:21;:::i;:::-;10155:5;10152:32;10142:60;;10198:1;10195;10188:12;10142:60;10092:116;:::o;10214:137::-;10268:5;10299:6;10293:13;10284:22;;10315:30;10339:5;10315:30;:::i;:::-;10214:137;;;;:::o;10396:1750::-;10479:5;10523:6;10511:9;10506:3;10502:19;10498:32;10495:119;;;10533:79;;:::i;:::-;10495:119;10632:23;10648:6;10632:23;:::i;:::-;10623:32;;10724:1;10764:60;10820:3;10811:6;10800:9;10796:22;10764:60;:::i;:::-;10757:4;10750:5;10746:16;10739:86;10665:171;10903:2;10944:59;10999:3;10990:6;10979:9;10975:22;10944:59;:::i;:::-;10937:4;10930:5;10926:16;10919:85;10846:169;11091:2;11132:60;11188:3;11179:6;11168:9;11164:22;11132:60;:::i;:::-;11125:4;11118:5;11114:16;11107:86;11025:179;11280:2;11321:60;11377:3;11368:6;11357:9;11353:22;11321:60;:::i;:::-;11314:4;11307:5;11303:16;11296:86;11214:179;11469:3;11511:58;11565:3;11556:6;11545:9;11541:22;11511:58;:::i;:::-;11504:4;11497:5;11493:16;11486:84;11403:178;11666:3;11708:60;11764:3;11755:6;11744:9;11740:22;11708:60;:::i;:::-;11701:4;11694:5;11690:16;11683:86;11591:189;11849:3;11891:59;11946:3;11937:6;11926:9;11922:22;11891:59;:::i;:::-;11884:4;11877:5;11873:16;11866:85;11790:172;12028:3;12070:57;12123:3;12114:6;12103:9;12099:22;12070:57;:::i;:::-;12063:4;12056:5;12052:16;12045:83;11972:167;10396:1750;;;;:::o;12152:398::-;12245:6;12294:3;12282:9;12273:7;12269:23;12265:33;12262:120;;;12301:79;;:::i;:::-;12262:120;12421:1;12446:87;12525:7;12516:6;12505:9;12501:22;12446:87;:::i;:::-;12436:97;;12392:151;12152:398;;;;:::o;12556:162::-;12671:6;12705:5;12699:12;12689:22;;12556:162;;;:::o;12724:232::-;12871:11;12905:6;12900:3;12893:19;12945:4;12940:3;12936:14;12921:29;;12724:232;;;;:::o;12962:180::-;13077:4;13100:3;13092:11;;13130:4;13125:3;13121:14;13113:22;;12962:180;;;:::o;13148:137::-;13238:6;13272:5;13266:12;13256:22;;13148:137;;;:::o;13291:197::-;13403:11;13437:6;13432:3;13425:19;13477:4;13472:3;13468:14;13453:29;;13291:197;;;;:::o;13494:155::-;13584:4;13607:3;13599:11;;13637:4;13632:3;13628:14;13620:22;;13494:155;;;:::o;13655:99::-;13726:21;13741:5;13726:21;:::i;:::-;13721:3;13714:34;13655:99;;:::o;13760:108::-;13837:24;13855:5;13837:24;:::i;:::-;13832:3;13825:37;13760:108;;:::o;13874:105::-;13949:23;13966:5;13949:23;:::i;:::-;13944:3;13937:36;13874:105;;:::o;14093:684::-;14226:4;14221:3;14217:14;14320:4;14313:5;14309:16;14303:23;14339:57;14390:4;14385:3;14381:14;14367:12;14339:57;:::i;:::-;14241:165;14498:4;14491:5;14487:16;14481:23;14517:63;14574:4;14569:3;14565:14;14551:12;14517:63;:::i;:::-;14416:174;14680:4;14673:5;14669:16;14663:23;14699:61;14754:4;14749:3;14745:14;14731:12;14699:61;:::i;:::-;14600:170;14195:582;14093:684;;:::o;14783:271::-;14898:10;14919:92;15007:3;14999:6;14919:92;:::i;:::-;15043:4;15038:3;15034:14;15020:28;;14783:271;;;;:::o;15060:136::-;15153:4;15185;15180:3;15176:14;15168:22;;15060:136;;;:::o;15314:896::-;15469:3;15498:77;15569:5;15498:77;:::i;:::-;15591:99;15683:6;15678:3;15591:99;:::i;:::-;15584:106;;15714:79;15787:5;15714:79;:::i;:::-;15816:7;15847:1;15832:353;15857:6;15854:1;15851:13;15832:353;;;15933:6;15927:13;15960:109;16065:3;16050:13;15960:109;:::i;:::-;15953:116;;16092:83;16168:6;16092:83;:::i;:::-;16082:93;;15892:293;15879:1;15876;15872:9;15867:14;;15832:353;;;15836:14;16201:3;16194:10;;15474:736;;;15314:896;;;;:::o;16216:348::-;16381:10;16416:142;16554:3;16546:6;16416:142;:::i;:::-;16402:156;;16216:348;;;;:::o;16570:161::-;16688:4;16720;16715:3;16711:14;16703:22;;16570:161;;;:::o;16853:1295::-;17068:3;17097:102;17193:5;17097:102;:::i;:::-;17215:134;17342:6;17337:3;17215:134;:::i;:::-;17208:141;;17375:3;17420:4;17412:6;17408:17;17403:3;17399:27;17450:104;17548:5;17450:104;:::i;:::-;17577:7;17608:1;17593:510;17618:6;17615:1;17612:13;17593:510;;;17689:9;17683:4;17679:20;17674:3;17667:33;17740:6;17734:13;17768:160;17923:4;17908:13;17768:160;:::i;:::-;17760:168;;17951:108;18052:6;17951:108;:::i;:::-;17941:118;;18088:4;18083:3;18079:14;18072:21;;17653:450;17640:1;17637;17633:9;17628:14;;17593:510;;;17597:14;18119:4;18112:11;;18139:3;18132:10;;17073:1075;;;;;16853:1295;;;;:::o;18154:565::-;18393:4;18431:2;18420:9;18416:18;18408:26;;18480:9;18474:4;18470:20;18466:1;18455:9;18451:17;18444:47;18508:204;18707:4;18698:6;18508:204;:::i;:::-;18500:212;;18154:565;;;;:::o\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x60806040525f5ffdfea164736f6c634300081c000a\",\"sourceMap\":\"193:1568:32:-:0;;;;;\",\"linkReferences\":{}},\"methodIdentifiers\":{},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"components\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"pool\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"int24[]\\\",\\\"name\\\":\\\"ticks\\\",\\\"type\\\":\\\"int24[]\\\"}],\\\"internalType\\\":\\\"struct GetUniswapV3PoolTickDataBatchRequest.TickDataInfo[]\\\",\\\"name\\\":\\\"allPoolInfo\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"This contract is not meant to be deployed. Instead, use a static call with the       deployment bytecode as payload.\\\",\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/UniswapV3/GetUniswapV3PoolTickDataBatchRequest.sol\\\":\\\"GetUniswapV3PoolTickDataBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV3/GetUniswapV3PoolTickDataBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0x5b2cc6ab5e91e7c5bd7b550d6cfafa8bbbdbb5b6a2afb90bb134f92d426a2e96\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://fce3ca5bb4914fb725fa595eb7583419b4727d0cdf2a32adf07593be3fe7b064\\\",\\\"dweb:/ipfs/QmXCTfPYyJXbhzC3zPvCJNNC8FcpJaAkkmVwzyEsscdHrr\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"struct GetUniswapV3PoolTickDataBatchRequest.TickDataInfo[]\",\"name\":\"allPoolInfo\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"internalType\":\"int24[]\",\"name\":\"ticks\",\"type\":\"int24[]\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/UniswapV3/GetUniswapV3PoolTickDataBatchRequest.sol\":\"GetUniswapV3PoolTickDataBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/UniswapV3/GetUniswapV3PoolTickDataBatchRequest.sol\":{\"keccak256\":\"0x5b2cc6ab5e91e7c5bd7b550d6cfafa8bbbdbb5b6a2afb90bb134f92d426a2e96\",\"urls\":[\"bzz-raw://fce3ca5bb4914fb725fa595eb7583419b4727d0cdf2a32adf07593be3fe7b064\",\"dweb:/ipfs/QmXCTfPYyJXbhzC3zPvCJNNC8FcpJaAkkmVwzyEsscdHrr\"],\"license\":\"MIT\"}},\"version\":1},\"id\":32}"
  },
  {
    "path": "src/amms/abi/WethValueInPools.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_uniswapV2Factory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_uniswapV3Factory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_weth\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getWethValueInPools\",\"inputs\":[{\"name\":\"pools\",\"type\":\"tuple[]\",\"internalType\":\"struct WethValueInPools.PoolInfo[]\",\"components\":[{\"name\":\"poolType\",\"type\":\"uint8\",\"internalType\":\"enum WethValueInPools.PoolType\"},{\"name\":\"poolAddress\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"struct WethValueInPools.PoolInfoReturn[]\",\"components\":[{\"name\":\"poolType\",\"type\":\"uint8\",\"internalType\":\"enum WethValueInPools.PoolType\"},{\"name\":\"poolAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wethValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b5060405161269338038061269383398181016040528101906100319190610156565b825f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050506101a6565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610125826100fc565b9050919050565b6101358161011b565b811461013f575f5ffd5b50565b5f815190506101508161012c565b92915050565b5f5f5f6060848603121561016d5761016c6100f8565b5b5f61017a86828701610142565b935050602061018b86828701610142565b925050604061019c86828701610142565b9150509250925092565b6124e0806101b35f395ff3fe608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063339173fd1461002d575b5f5ffd5b61004760048036038101906100429190611a7a565b61005d565b6040516100549190611c43565b60405180910390f35b60605f825167ffffffffffffffff81111561007b5761007a611870565b5b6040519080825280602002602001820160405280156100b457816020015b6100a1611805565b8152602001906001900390816100995790505b5090505f5f90505b83518110156102f4575f8482815181106100d9576100d8611c63565b5b602002602001015190505f60028111156100f6576100f5611aea565b5b815f0151600281111561010c5761010b611aea565b5b0361018f575f61011f82602001516102fe565b90506040518060600160405280835f0151600281111561014257610141611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061017e5761017d611c63565b5b6020026020010181905250506102e6565b600160028111156101a3576101a2611aea565b5b815f015160028111156101b9576101b8611aea565b5b0361023c575f6101cc8260200151610587565b90506040518060600160405280835f015160028111156101ef576101ee611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061022b5761022a611c63565b5b6020026020010181905250506102e5565b60028081111561024f5761024e611aea565b5b815f0151600281111561026557610264611aea565b5b036102e4575f6102788260200151610825565b90506040518060600160405280835f0151600281111561029b5761029a611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff168152602001828152508484815181106102d7576102d6611c63565b5b6020026020010181905250505b5b5b5080806001019150506100bc565b5080915050919050565b5f60608273ffffffffffffffffffffffffffffffffffffffff1663cc77828d6040518163ffffffff1660e01b81526004015f604051808303815f875af192505050801561036d57506040513d5f823e3d601f19601f8201168201806040525081019061036a9190611d64565b60015b61037a575f915050610582565b809150505f5f90505b81518110156104ba5760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168282815181106103d7576103d6611c63565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036104ad578373ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f83838151811061042957610428611c63565b5b60200260200101516040518263ffffffff1660e01b815260040161044d9190611dba565b6020604051808303815f875af192505050801561048857506040513d601f19601f820116820180604052508101906104859190611dfd565b60015b610496575f92505050610582565b8251816104a39190611e55565b9350505050610582565b8080600101915050610383565b505f815f815181106104cf576104ce611c63565b5b602002602001015190505f8473ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f836040518263ffffffff1660e01b81526004016105139190611dba565b6020604051808303815f875af192505050801561054e57506040513d601f19601f8201168201806040525081019061054b9190611dfd565b60015b61055d575f9350505050610582565b809150505f61056c8383610b9a565b905083518161057b9190611e55565b9450505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156105f157506040513d601f19601f820116820180604052508101906105ee9190611e96565b60015b6105fe575f915050610820565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561066b57506040513d601f19601f820116820180604052508101906106689190611e96565b60015b610679575f92505050610820565b809150508373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa9250505080156106e557506040513d601f19601f820116820180604052508101906106e29190611f3d565b60015b6106f3575f92505050610820565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610770576002836107549190611f8d565b6dffffffffffffffffffffffffffff1695505050505050610820565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107ed576002826107d19190611f8d565b6dffffffffffffffffffffffffffff1695505050505050610820565b5f61080886856dffffffffffffffffffffffffffff16610b9a565b90506002816108179190611e55565b96505050505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561088f57506040513d601f19601f8201168201806040525081019061088c9190611e96565b60015b61089c575f915050610b95565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561090957506040513d601f19601f820116820180604052508101906109069190611e96565b60015b610917575f92505050610b95565b8091505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610a07578173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b81526004016109a89190611dba565b602060405180830381865afa9250505080156109e257506040513d601f19601f820116820180604052508101906109df9190611dfd565b60015b6109f0575f92505050610b95565b6002816109fd9190611e55565b9350505050610b95565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610af3578073ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610a949190611dba565b602060405180830381865afa925050508015610ace57506040513d601f19601f82011682018060405250810190610acb9190611dfd565b60015b610adc575f92505050610b95565b600281610ae99190611e55565b9350505050610b95565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610b2c9190611dba565b602060405180830381865afa925050508015610b6657506040513d601f19601f82011682018060405250810190610b639190611dfd565b60015b610b74575f92505050610b95565b5f610b7f8483610b9a565b9050600281610b8e9190611e55565b9450505050505b919050565b5f5f610ba584610bf0565b90505f816fffffffffffffffffffffffffffffffff161115610bd357610bcb8184610c35565b915050610bea565b806fffffffffffffffffffffffffffffffff169150505b92915050565b5f5f610bfb83610d1f565b90505f816fffffffffffffffffffffffffffffffff161115610c205780915050610c30565b610c2983611070565b9050809150505b919050565b5f5f821480610c5557505f836fffffffffffffffffffffffffffffffff16145b15610c62575f9050610d19565b5f60406fffffffffffffffffffffffffffffffff8416856fffffffffffffffffffffffffffffffff1602901c90505f608084901c856fffffffffffffffffffffffffffffffff1602905077ffffffffffffffffffffffffffffffffffffffffffffffff811115610cd6575f92505050610d19565b604081901b9050817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03811115610d11575f92505050610d19565b818101925050505b92915050565b5f5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a439058460025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401610d9d929190611fc9565b602060405180830381865afa158015610db8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddc9190611e96565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e1a575f91505061106b565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa925050508015610e8457506040513d601f19601f82011682018060405250810190610e819190611f3d565b60015b610e93575f935050505061106b565b8294508193505050505f826dffffffffffffffffffffffffffff161480610ec957505f816dffffffffffffffffffffffffffff16145b15610ed9575f935050505061106b565b5f5f610ee48761133d565b9150915080610efa575f9550505050505061106b565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1610610f555784610f57565b835b90505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1610610fb45784610fb6565b855b9050601260ff168460ff16111561100057601284610fd49190611ffc565b600a610fe0919061215f565b816dffffffffffffffffffffffffffff16610ffb91906121d6565b611035565b83601261100d9190611ffc565b600a611019919061215f565b816dffffffffffffffffffffffffffff166110349190611e55565b5b9050611061826dffffffffffffffffffffffffffff16826dffffffffffffffffffffffffffff166114a1565b9750505050505050505b919050565b5f5f60405180606001604052806101f461ffff168152602001610bb861ffff16815260200161271061ffff1681525090505f5f5f90505b60038110156111d0575f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631698ee828760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687866003811061112457611123611c63565b5b60200201516040518463ffffffff1660e01b81526004016111479392919061225a565b602060405180830381865afa158015611162573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111869190611e96565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146111c457809250506111d0565b508060010190506110a7565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361120e575f92505050611338565b5f8173ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa92505050801561127757506040513d601f19601f820116820180604052508101906112749190612378565b60015b611286575f9350505050611338565b869750505050505050505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161090505f5f6112ee8861133d565b9150915080611305575f9650505050505050611338565b604061132d85858661131857601261131a565b855b876113255786611328565b60125b611683565b901c96505050505050505b919050565b5f5f5f5f8473ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516113eb9190612467565b5f604051808303815f8787f1925050503d805f8114611425576040519150601f19603f3d011682016040523d82523d5f602084013e61142a565b606091505b50915091508115611493575f602082510361148557818060200190518101906114539190611dfd565b90505f811480611463575060ff81115b15611476575f5f9450945050505061149c565b8060019450945050505061149c565b5f5f9450945050505061149c565b5f5f9350935050505b915091565b5f5f82036114b1575f905061167d565b5f77ffffffffffffffffffffffffffffffffffffffffffffffff84116114ed5782604085901b816114e5576114e46121a9565b5b049050611657565b5f60c090505f60c086901c9050640100000000811061151457602081901c90506020820191505b62010000811061152c57601081901c90506010820191505b610100811061154357600881901c90506008820191505b6010811061155957600481901c90506004820191505b6004811061156f57600281901c90506002820191505b6002811061157e576001820191505b600160bf830360018703901c018260ff0387901b816115a05761159f6121a9565b5b0492506fffffffffffffffffffffffffffffffff8311156115c6575f935050505061167d565b5f608086901c840290505f6fffffffffffffffffffffffffffffffff8716850290505f60c089901c90505f60408a901b905082811015611607576001820391505b8281039050608084901b925082811015611622576001820391505b8281039050608084901c821461163b5761163a61247d565b5b88818161164b5761164a6121a9565b5b04870196505050505050505b6fffffffffffffffffffffffffffffffff811115611678575f91505061167d565b809150505b92915050565b5f5f82840390505f5f825f0b126116bb578160ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a026116ee565b815f0360ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a816116ec576116eb6121a9565b5b045b9050806c01000000000000000000000000111561170f575f925050506117fd565b5f86611767576c010000000000000000000000008281611732576117316121a9565b5b046fffffffffffffffffffffffffffffffff6c010000000000000000000000000281611761576117606121a9565b5b04611786565b6c010000000000000000000000008281611784576117836121a9565b5b045b90508661179357806117c4565b6c010000000000000000000000006fffffffffffffffffffffffffffffffff8202816117c2576117c16121a9565b5b045b93507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8411156117f9575f93505050506117fd565b5050505b949350505050565b60405180606001604052805f600281111561182357611822611aea565b5b81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6118a682611860565b810181811067ffffffffffffffff821117156118c5576118c4611870565b5b80604052505050565b5f6118d761184b565b90506118e3828261189d565b919050565b5f67ffffffffffffffff82111561190257611901611870565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b60038110611927575f5ffd5b50565b5f813590506119388161191b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119678261193e565b9050919050565b6119778161195d565b8114611981575f5ffd5b50565b5f813590506119928161196e565b92915050565b5f604082840312156119ad576119ac611917565b5b6119b760406118ce565b90505f6119c68482850161192a565b5f8301525060206119d984828501611984565b60208301525092915050565b5f6119f76119f2846118e8565b6118ce565b90508083825260208201905060408402830185811115611a1a57611a19611913565b5b835b81811015611a435780611a2f8882611998565b845260208401935050604081019050611a1c565b5050509392505050565b5f82601f830112611a6157611a6061185c565b5b8135611a718482602086016119e5565b91505092915050565b5f60208284031215611a8f57611a8e611854565b5b5f82013567ffffffffffffffff811115611aac57611aab611858565b5b611ab884828501611a4d565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110611b2857611b27611aea565b5b50565b5f819050611b3882611b17565b919050565b5f611b4782611b2b565b9050919050565b611b5781611b3d565b82525050565b611b668161195d565b82525050565b5f819050919050565b611b7e81611b6c565b82525050565b606082015f820151611b985f850182611b4e565b506020820151611bab6020850182611b5d565b506040820151611bbe6040850182611b75565b50505050565b5f611bcf8383611b84565b60608301905092915050565b5f602082019050919050565b5f611bf182611ac1565b611bfb8185611acb565b9350611c0683611adb565b805f5b83811015611c36578151611c1d8882611bc4565b9750611c2883611bdb565b925050600181019050611c09565b5085935050505092915050565b5f6020820190508181035f830152611c5b8184611be7565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f67ffffffffffffffff821115611caa57611ca9611870565b5b602082029050602081019050919050565b5f81519050611cc98161196e565b92915050565b5f611ce1611cdc84611c90565b6118ce565b90508083825260208201905060208402830185811115611d0457611d03611913565b5b835b81811015611d2d5780611d198882611cbb565b845260208401935050602081019050611d06565b5050509392505050565b5f82601f830112611d4b57611d4a61185c565b5b8151611d5b848260208601611ccf565b91505092915050565b5f60208284031215611d7957611d78611854565b5b5f82015167ffffffffffffffff811115611d9657611d95611858565b5b611da284828501611d37565b91505092915050565b611db48161195d565b82525050565b5f602082019050611dcd5f830184611dab565b92915050565b611ddc81611b6c565b8114611de6575f5ffd5b50565b5f81519050611df781611dd3565b92915050565b5f60208284031215611e1257611e11611854565b5b5f611e1f84828501611de9565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611e5f82611b6c565b9150611e6a83611b6c565b9250828202611e7881611b6c565b91508282048414831517611e8f57611e8e611e28565b5b5092915050565b5f60208284031215611eab57611eaa611854565b5b5f611eb884828501611cbb565b91505092915050565b5f6dffffffffffffffffffffffffffff82169050919050565b611ee381611ec1565b8114611eed575f5ffd5b50565b5f81519050611efe81611eda565b92915050565b5f63ffffffff82169050919050565b611f1c81611f04565b8114611f26575f5ffd5b50565b5f81519050611f3781611f13565b92915050565b5f5f5f60608486031215611f5457611f53611854565b5b5f611f6186828701611ef0565b9350506020611f7286828701611ef0565b9250506040611f8386828701611f29565b9150509250925092565b5f611f9782611ec1565b9150611fa283611ec1565b9250828202611fb081611ec1565b9150808214611fc257611fc1611e28565b5b5092915050565b5f604082019050611fdc5f830185611dab565b611fe96020830184611dab565b9392505050565b5f60ff82169050919050565b5f61200682611ff0565b915061201183611ff0565b9250828203905060ff81111561202a57612029611e28565b5b92915050565b5f8160011c9050919050565b5f5f8291508390505b60018511156120855780860481111561206157612060611e28565b5b60018516156120705780820291505b808102905061207e85612030565b9450612045565b94509492505050565b5f8261209d5760019050612158565b816120aa575f9050612158565b81600181146120c057600281146120ca576120f9565b6001915050612158565b60ff8411156120dc576120db611e28565b5b8360020a9150848211156120f3576120f2611e28565b5b50612158565b5060208310610133831016604e8410600b841016171561212e5782820a90508381111561212957612128611e28565b5b612158565b61213b848484600161203c565b9250905081840481111561215257612151611e28565b5b81810290505b9392505050565b5f61216982611b6c565b915061217483611ff0565b92506121a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461208e565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6121e082611b6c565b91506121eb83611b6c565b9250826121fb576121fa6121a9565b5b828204905092915050565b5f61ffff82169050919050565b5f62ffffff82169050919050565b5f819050919050565b5f61224461223f61223a84612206565b612221565b612213565b9050919050565b6122548161222a565b82525050565b5f60608201905061226d5f830186611dab565b61227a6020830185611dab565b612287604083018461224b565b949350505050565b6122988161193e565b81146122a2575f5ffd5b50565b5f815190506122b38161228f565b92915050565b5f8160020b9050919050565b6122ce816122b9565b81146122d8575f5ffd5b50565b5f815190506122e9816122c5565b92915050565b6122f881612206565b8114612302575f5ffd5b50565b5f81519050612313816122ef565b92915050565b61232281611ff0565b811461232c575f5ffd5b50565b5f8151905061233d81612319565b92915050565b5f8115159050919050565b61235781612343565b8114612361575f5ffd5b50565b5f815190506123728161234e565b92915050565b5f5f5f5f5f5f5f60e0888a03121561239357612392611854565b5b5f6123a08a828b016122a5565b97505060206123b18a828b016122db565b96505060406123c28a828b01612305565b95505060606123d38a828b01612305565b94505060806123e48a828b01612305565b93505060a06123f58a828b0161232f565b92505060c06124068a828b01612364565b91505092959891949750929550565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61244182612415565b61244b818561241f565b935061245b818560208601612429565b80840191505092915050565b5f6124728284612437565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfea2646970667358221220fbecc7363fddc240183f228cc94d576c055fde0c1de0f8e7ea8b7ba822558b2264736f6c634300081e0033\",\"sourceMap\":\"468:10235:37:-:0;;;1079:206;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1191:17;1170:18;;:38;;;;;;;;;;;;;;;;;;1239:17;1218:18;;:38;;;;;;;;;;;;;;;;;;1273:5;1266:4;;:12;;;;;;;;;;;;;;;;;;1079:206;;;468:10235;;88:117:46;197:1;194;187:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:143::-;753:5;784:6;778:13;769:22;;800:33;827:5;800:33;:::i;:::-;696:143;;;;:::o;845:663::-;933:6;941;949;998:2;986:9;977:7;973:23;969:32;966:119;;;1004:79;;:::i;:::-;966:119;1124:1;1149:64;1205:7;1196:6;1185:9;1181:22;1149:64;:::i;:::-;1139:74;;1095:128;1262:2;1288:64;1344:7;1335:6;1324:9;1320:22;1288:64;:::i;:::-;1278:74;;1233:129;1401:2;1427:64;1483:7;1474:6;1463:9;1459:22;1427:64;:::i;:::-;1417:74;;1372:129;845:663;;;;;:::o;468:10235:37:-;;;;;;;\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063339173fd1461002d575b5f5ffd5b61004760048036038101906100429190611a7a565b61005d565b6040516100549190611c43565b60405180910390f35b60605f825167ffffffffffffffff81111561007b5761007a611870565b5b6040519080825280602002602001820160405280156100b457816020015b6100a1611805565b8152602001906001900390816100995790505b5090505f5f90505b83518110156102f4575f8482815181106100d9576100d8611c63565b5b602002602001015190505f60028111156100f6576100f5611aea565b5b815f0151600281111561010c5761010b611aea565b5b0361018f575f61011f82602001516102fe565b90506040518060600160405280835f0151600281111561014257610141611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061017e5761017d611c63565b5b6020026020010181905250506102e6565b600160028111156101a3576101a2611aea565b5b815f015160028111156101b9576101b8611aea565b5b0361023c575f6101cc8260200151610587565b90506040518060600160405280835f015160028111156101ef576101ee611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061022b5761022a611c63565b5b6020026020010181905250506102e5565b60028081111561024f5761024e611aea565b5b815f0151600281111561026557610264611aea565b5b036102e4575f6102788260200151610825565b90506040518060600160405280835f0151600281111561029b5761029a611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff168152602001828152508484815181106102d7576102d6611c63565b5b6020026020010181905250505b5b5b5080806001019150506100bc565b5080915050919050565b5f60608273ffffffffffffffffffffffffffffffffffffffff1663cc77828d6040518163ffffffff1660e01b81526004015f604051808303815f875af192505050801561036d57506040513d5f823e3d601f19601f8201168201806040525081019061036a9190611d64565b60015b61037a575f915050610582565b809150505f5f90505b81518110156104ba5760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168282815181106103d7576103d6611c63565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036104ad578373ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f83838151811061042957610428611c63565b5b60200260200101516040518263ffffffff1660e01b815260040161044d9190611dba565b6020604051808303815f875af192505050801561048857506040513d601f19601f820116820180604052508101906104859190611dfd565b60015b610496575f92505050610582565b8251816104a39190611e55565b9350505050610582565b8080600101915050610383565b505f815f815181106104cf576104ce611c63565b5b602002602001015190505f8473ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f836040518263ffffffff1660e01b81526004016105139190611dba565b6020604051808303815f875af192505050801561054e57506040513d601f19601f8201168201806040525081019061054b9190611dfd565b60015b61055d575f9350505050610582565b809150505f61056c8383610b9a565b905083518161057b9190611e55565b9450505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156105f157506040513d601f19601f820116820180604052508101906105ee9190611e96565b60015b6105fe575f915050610820565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561066b57506040513d601f19601f820116820180604052508101906106689190611e96565b60015b610679575f92505050610820565b809150508373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa9250505080156106e557506040513d601f19601f820116820180604052508101906106e29190611f3d565b60015b6106f3575f92505050610820565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610770576002836107549190611f8d565b6dffffffffffffffffffffffffffff1695505050505050610820565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107ed576002826107d19190611f8d565b6dffffffffffffffffffffffffffff1695505050505050610820565b5f61080886856dffffffffffffffffffffffffffff16610b9a565b90506002816108179190611e55565b96505050505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561088f57506040513d601f19601f8201168201806040525081019061088c9190611e96565b60015b61089c575f915050610b95565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561090957506040513d601f19601f820116820180604052508101906109069190611e96565b60015b610917575f92505050610b95565b8091505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610a07578173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b81526004016109a89190611dba565b602060405180830381865afa9250505080156109e257506040513d601f19601f820116820180604052508101906109df9190611dfd565b60015b6109f0575f92505050610b95565b6002816109fd9190611e55565b9350505050610b95565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610af3578073ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610a949190611dba565b602060405180830381865afa925050508015610ace57506040513d601f19601f82011682018060405250810190610acb9190611dfd565b60015b610adc575f92505050610b95565b600281610ae99190611e55565b9350505050610b95565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610b2c9190611dba565b602060405180830381865afa925050508015610b6657506040513d601f19601f82011682018060405250810190610b639190611dfd565b60015b610b74575f92505050610b95565b5f610b7f8483610b9a565b9050600281610b8e9190611e55565b9450505050505b919050565b5f5f610ba584610bf0565b90505f816fffffffffffffffffffffffffffffffff161115610bd357610bcb8184610c35565b915050610bea565b806fffffffffffffffffffffffffffffffff169150505b92915050565b5f5f610bfb83610d1f565b90505f816fffffffffffffffffffffffffffffffff161115610c205780915050610c30565b610c2983611070565b9050809150505b919050565b5f5f821480610c5557505f836fffffffffffffffffffffffffffffffff16145b15610c62575f9050610d19565b5f60406fffffffffffffffffffffffffffffffff8416856fffffffffffffffffffffffffffffffff1602901c90505f608084901c856fffffffffffffffffffffffffffffffff1602905077ffffffffffffffffffffffffffffffffffffffffffffffff811115610cd6575f92505050610d19565b604081901b9050817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03811115610d11575f92505050610d19565b818101925050505b92915050565b5f5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a439058460025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401610d9d929190611fc9565b602060405180830381865afa158015610db8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddc9190611e96565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e1a575f91505061106b565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa925050508015610e8457506040513d601f19601f82011682018060405250810190610e819190611f3d565b60015b610e93575f935050505061106b565b8294508193505050505f826dffffffffffffffffffffffffffff161480610ec957505f816dffffffffffffffffffffffffffff16145b15610ed9575f935050505061106b565b5f5f610ee48761133d565b9150915080610efa575f9550505050505061106b565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1610610f555784610f57565b835b90505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1610610fb45784610fb6565b855b9050601260ff168460ff16111561100057601284610fd49190611ffc565b600a610fe0919061215f565b816dffffffffffffffffffffffffffff16610ffb91906121d6565b611035565b83601261100d9190611ffc565b600a611019919061215f565b816dffffffffffffffffffffffffffff166110349190611e55565b5b9050611061826dffffffffffffffffffffffffffff16826dffffffffffffffffffffffffffff166114a1565b9750505050505050505b919050565b5f5f60405180606001604052806101f461ffff168152602001610bb861ffff16815260200161271061ffff1681525090505f5f5f90505b60038110156111d0575f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631698ee828760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687866003811061112457611123611c63565b5b60200201516040518463ffffffff1660e01b81526004016111479392919061225a565b602060405180830381865afa158015611162573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111869190611e96565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146111c457809250506111d0565b508060010190506110a7565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361120e575f92505050611338565b5f8173ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa92505050801561127757506040513d601f19601f820116820180604052508101906112749190612378565b60015b611286575f9350505050611338565b869750505050505050505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161090505f5f6112ee8861133d565b9150915080611305575f9650505050505050611338565b604061132d85858661131857601261131a565b855b876113255786611328565b60125b611683565b901c96505050505050505b919050565b5f5f5f5f8473ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516113eb9190612467565b5f604051808303815f8787f1925050503d805f8114611425576040519150601f19603f3d011682016040523d82523d5f602084013e61142a565b606091505b50915091508115611493575f602082510361148557818060200190518101906114539190611dfd565b90505f811480611463575060ff81115b15611476575f5f9450945050505061149c565b8060019450945050505061149c565b5f5f9450945050505061149c565b5f5f9350935050505b915091565b5f5f82036114b1575f905061167d565b5f77ffffffffffffffffffffffffffffffffffffffffffffffff84116114ed5782604085901b816114e5576114e46121a9565b5b049050611657565b5f60c090505f60c086901c9050640100000000811061151457602081901c90506020820191505b62010000811061152c57601081901c90506010820191505b610100811061154357600881901c90506008820191505b6010811061155957600481901c90506004820191505b6004811061156f57600281901c90506002820191505b6002811061157e576001820191505b600160bf830360018703901c018260ff0387901b816115a05761159f6121a9565b5b0492506fffffffffffffffffffffffffffffffff8311156115c6575f935050505061167d565b5f608086901c840290505f6fffffffffffffffffffffffffffffffff8716850290505f60c089901c90505f60408a901b905082811015611607576001820391505b8281039050608084901b925082811015611622576001820391505b8281039050608084901c821461163b5761163a61247d565b5b88818161164b5761164a6121a9565b5b04870196505050505050505b6fffffffffffffffffffffffffffffffff811115611678575f91505061167d565b809150505b92915050565b5f5f82840390505f5f825f0b126116bb578160ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a026116ee565b815f0360ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a816116ec576116eb6121a9565b5b045b9050806c01000000000000000000000000111561170f575f925050506117fd565b5f86611767576c010000000000000000000000008281611732576117316121a9565b5b046fffffffffffffffffffffffffffffffff6c010000000000000000000000000281611761576117606121a9565b5b04611786565b6c010000000000000000000000008281611784576117836121a9565b5b045b90508661179357806117c4565b6c010000000000000000000000006fffffffffffffffffffffffffffffffff8202816117c2576117c16121a9565b5b045b93507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8411156117f9575f93505050506117fd565b5050505b949350505050565b60405180606001604052805f600281111561182357611822611aea565b5b81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6118a682611860565b810181811067ffffffffffffffff821117156118c5576118c4611870565b5b80604052505050565b5f6118d761184b565b90506118e3828261189d565b919050565b5f67ffffffffffffffff82111561190257611901611870565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b60038110611927575f5ffd5b50565b5f813590506119388161191b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119678261193e565b9050919050565b6119778161195d565b8114611981575f5ffd5b50565b5f813590506119928161196e565b92915050565b5f604082840312156119ad576119ac611917565b5b6119b760406118ce565b90505f6119c68482850161192a565b5f8301525060206119d984828501611984565b60208301525092915050565b5f6119f76119f2846118e8565b6118ce565b90508083825260208201905060408402830185811115611a1a57611a19611913565b5b835b81811015611a435780611a2f8882611998565b845260208401935050604081019050611a1c565b5050509392505050565b5f82601f830112611a6157611a6061185c565b5b8135611a718482602086016119e5565b91505092915050565b5f60208284031215611a8f57611a8e611854565b5b5f82013567ffffffffffffffff811115611aac57611aab611858565b5b611ab884828501611a4d565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110611b2857611b27611aea565b5b50565b5f819050611b3882611b17565b919050565b5f611b4782611b2b565b9050919050565b611b5781611b3d565b82525050565b611b668161195d565b82525050565b5f819050919050565b611b7e81611b6c565b82525050565b606082015f820151611b985f850182611b4e565b506020820151611bab6020850182611b5d565b506040820151611bbe6040850182611b75565b50505050565b5f611bcf8383611b84565b60608301905092915050565b5f602082019050919050565b5f611bf182611ac1565b611bfb8185611acb565b9350611c0683611adb565b805f5b83811015611c36578151611c1d8882611bc4565b9750611c2883611bdb565b925050600181019050611c09565b5085935050505092915050565b5f6020820190508181035f830152611c5b8184611be7565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f67ffffffffffffffff821115611caa57611ca9611870565b5b602082029050602081019050919050565b5f81519050611cc98161196e565b92915050565b5f611ce1611cdc84611c90565b6118ce565b90508083825260208201905060208402830185811115611d0457611d03611913565b5b835b81811015611d2d5780611d198882611cbb565b845260208401935050602081019050611d06565b5050509392505050565b5f82601f830112611d4b57611d4a61185c565b5b8151611d5b848260208601611ccf565b91505092915050565b5f60208284031215611d7957611d78611854565b5b5f82015167ffffffffffffffff811115611d9657611d95611858565b5b611da284828501611d37565b91505092915050565b611db48161195d565b82525050565b5f602082019050611dcd5f830184611dab565b92915050565b611ddc81611b6c565b8114611de6575f5ffd5b50565b5f81519050611df781611dd3565b92915050565b5f60208284031215611e1257611e11611854565b5b5f611e1f84828501611de9565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611e5f82611b6c565b9150611e6a83611b6c565b9250828202611e7881611b6c565b91508282048414831517611e8f57611e8e611e28565b5b5092915050565b5f60208284031215611eab57611eaa611854565b5b5f611eb884828501611cbb565b91505092915050565b5f6dffffffffffffffffffffffffffff82169050919050565b611ee381611ec1565b8114611eed575f5ffd5b50565b5f81519050611efe81611eda565b92915050565b5f63ffffffff82169050919050565b611f1c81611f04565b8114611f26575f5ffd5b50565b5f81519050611f3781611f13565b92915050565b5f5f5f60608486031215611f5457611f53611854565b5b5f611f6186828701611ef0565b9350506020611f7286828701611ef0565b9250506040611f8386828701611f29565b9150509250925092565b5f611f9782611ec1565b9150611fa283611ec1565b9250828202611fb081611ec1565b9150808214611fc257611fc1611e28565b5b5092915050565b5f604082019050611fdc5f830185611dab565b611fe96020830184611dab565b9392505050565b5f60ff82169050919050565b5f61200682611ff0565b915061201183611ff0565b9250828203905060ff81111561202a57612029611e28565b5b92915050565b5f8160011c9050919050565b5f5f8291508390505b60018511156120855780860481111561206157612060611e28565b5b60018516156120705780820291505b808102905061207e85612030565b9450612045565b94509492505050565b5f8261209d5760019050612158565b816120aa575f9050612158565b81600181146120c057600281146120ca576120f9565b6001915050612158565b60ff8411156120dc576120db611e28565b5b8360020a9150848211156120f3576120f2611e28565b5b50612158565b5060208310610133831016604e8410600b841016171561212e5782820a90508381111561212957612128611e28565b5b612158565b61213b848484600161203c565b9250905081840481111561215257612151611e28565b5b81810290505b9392505050565b5f61216982611b6c565b915061217483611ff0565b92506121a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461208e565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6121e082611b6c565b91506121eb83611b6c565b9250826121fb576121fa6121a9565b5b828204905092915050565b5f61ffff82169050919050565b5f62ffffff82169050919050565b5f819050919050565b5f61224461223f61223a84612206565b612221565b612213565b9050919050565b6122548161222a565b82525050565b5f60608201905061226d5f830186611dab565b61227a6020830185611dab565b612287604083018461224b565b949350505050565b6122988161193e565b81146122a2575f5ffd5b50565b5f815190506122b38161228f565b92915050565b5f8160020b9050919050565b6122ce816122b9565b81146122d8575f5ffd5b50565b5f815190506122e9816122c5565b92915050565b6122f881612206565b8114612302575f5ffd5b50565b5f81519050612313816122ef565b92915050565b61232281611ff0565b811461232c575f5ffd5b50565b5f8151905061233d81612319565b92915050565b5f8115159050919050565b61235781612343565b8114612361575f5ffd5b50565b5f815190506123728161234e565b92915050565b5f5f5f5f5f5f5f60e0888a03121561239357612392611854565b5b5f6123a08a828b016122a5565b97505060206123b18a828b016122db565b96505060406123c28a828b01612305565b95505060606123d38a828b01612305565b94505060806123e48a828b01612305565b93505060a06123f58a828b0161232f565b92505060c06124068a828b01612364565b91505092959891949750929550565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61244182612415565b61244b818561241f565b935061245b818560208601612429565b80840191505092915050565b5f6124728284612437565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfea2646970667358221220fbecc7363fddc240183f228cc94d576c055fde0c1de0f8e7ea8b7ba822558b2264736f6c634300081e0033\",\"sourceMap\":\"468:10235:37:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1908:1035;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;1978:23;2013:39;2076:5;:12;2055:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2013:76;;2104:9;2116:1;2104:13;;2099:806;2123:5;:12;2119:1;:16;2099:806;;;2156:20;2179:5;2185:1;2179:8;;;;;;;;:::i;:::-;;;;;;;;2156:31;;2222:17;2205:34;;;;;;;;:::i;:::-;;:4;:13;;;:34;;;;;;;;:::i;:::-;;;2201:694;;2259:17;2279:36;2298:4;:16;;;2279:18;:36::i;:::-;2259:56;;2354:58;;;;;;;;2369:4;:13;;;2354:58;;;;;;;;:::i;:::-;;;;;;2384:4;:16;;;2354:58;;;;;;2402:9;2354:58;;;2333:15;2349:1;2333:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2241:186;2201:694;;;2454:18;2437:35;;;;;;;;:::i;:::-;;:4;:13;;;:35;;;;;;;;:::i;:::-;;;2433:462;;2492:17;2512:37;2532:4;:16;;;2512:19;:37::i;:::-;2492:57;;2588:58;;;;;;;;2603:4;:13;;;2588:58;;;;;;;;:::i;:::-;;;;;;2618:4;:16;;;2588:58;;;;;;2636:9;2588:58;;;2567:15;2583:1;2567:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2474:187;2433:462;;;2688:18;2671:35;;;;;;;;:::i;:::-;;:4;:13;;;:35;;;;;;;;:::i;:::-;;;2667:228;;2726:17;2746:37;2766:4;:16;;;2746:19;:37::i;:::-;2726:57;;2822:58;;;;;;;;2837:4;:13;;;2822:58;;;;;;;;:::i;:::-;;;;;;2852:4;:16;;;2822:58;;;;;;2870:9;2822:58;;;2801:15;2817:1;2801:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2708:187;2667:228;2433:462;2201:694;2142:763;2137:3;;;;;;;2099:806;;;;2921:15;2914:22;;;1908:1035;;;:::o;2949:1221::-;3009:7;3055:23;3099:4;3092:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3088:152;;3228:1;3221:8;;;;;3088:152;3182:7;3173:16;;3124:76;3359:9;3371:1;3359:13;;3354:473;3378:6;:13;3374:1;:17;3354:473;;;3429:4;;;;;;;;;;;3416:17;;:6;3423:1;3416:9;;;;;;;;:::i;:::-;;;;;;;;:17;;;3412:405;;3464:4;3457:23;;;3481:6;3488:1;3481:9;;;;;;;;:::i;:::-;;;;;;;;3457:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3453:350;;3783:1;3776:8;;;;;;3453:350;3715:6;:13;3704:8;:24;;;;:::i;:::-;3697:31;;;;;;;3412:405;3393:3;;;;;;;3354:473;;;;3837:17;3857:6;3864:1;3857:9;;;;;;;;:::i;:::-;;;;;;;;3837:29;;3876:15;3912:4;3905:23;;;3929:9;3905:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3901:149;;4038:1;4031:8;;;;;;;3901:149;3991:8;3981:18;;3940:70;4060:17;4080:41;4102:9;4113:7;4080:21;:41::i;:::-;4060:61;;4150:6;:13;4138:9;:25;;;;:::i;:::-;4131:32;;;;;;2949:1221;;;;:::o;4176:896::-;4237:7;4256:14;4299:4;4284:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4280:141;;4409:1;4402:8;;;;;4280:141;4363:7;4354:16;;4314:67;4430:14;4473:4;4458:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4454:141;;4583:1;4576:8;;;;;;4454:141;4537:7;4528:16;;4488:67;4623:4;4608:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4604:462;;5054:1;5047:8;;;;;;4604:462;4724:4;;;;;;;;;;;4714:14;;:6;:14;;;4710:150;;4766:1;4755:8;:12;;;;:::i;:::-;4748:19;;;;;;;;;;;4710:150;4802:4;;;;;;;;;;;4792:14;;:6;:14;;;4788:72;;4844:1;4833:8;:12;;;;:::i;:::-;4826:19;;;;;;;;;;;4788:72;4922:17;4942:39;4964:6;4972:8;4942:39;;:21;:39::i;:::-;4922:59;;5014:1;5002:9;:13;;;;:::i;:::-;4995:20;;;;;;;;4176:896;;;;:::o;5078:1167::-;5139:7;5158:14;5209:4;5186:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5182:150;;5320:1;5313:8;;;;;5182:150;5274:7;5265:16;;5225:67;5341:14;5392:4;5369:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5365:150;;5503:1;5496:8;;;;;;5365:150;5457:7;5448:16;;5408:67;5539:4;;;;;;;;;;;5529:14;;:6;:14;;;5525:432;;5570:6;5563:24;;;5596:4;5563:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5559:169;;5712:1;5705:8;;;;;;5559:169;5664:1;5654:7;:11;;;;:::i;:::-;5647:18;;;;;;;5525:432;5758:4;;;;;;;;;;;5748:14;;:6;:14;;;5744:213;;5789:6;5782:24;;;5815:4;5782:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5778:169;;5931:1;5924:8;;;;;;5778:169;5883:1;5873:7;:11;;;;:::i;:::-;5866:18;;;;;;;5744:213;6023:6;6016:24;;;6049:4;6016:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;6012:227;;6227:1;6220:8;;;;;;6012:227;6096:17;6116:38;6138:6;6146:7;6116:21;:38::i;:::-;6096:58;;6187:1;6175:9;:13;;;;:::i;:::-;6168:20;;;;;;5078:1167;;;;:::o;6323:301::-;6403:7;6449:13;6465:17;6476:5;6465:10;:17::i;:::-;6449:33;;6504:1;6496:5;:9;;;6492:126;;;6528:36;6550:5;6557:6;6528:21;:36::i;:::-;6521:43;;;;;6492:126;6602:5;6595:12;;;;;6323:301;;;;;:::o;6691:351::-;6744:7;6797:13;6855:26;6875:5;6855:19;:26::i;:::-;6847:34;;6903:1;6895:5;:9;;;6891:52;;;6927:5;6920:12;;;;;6891:52;6987:26;7007:5;6987:19;:26::i;:::-;6979:34;;7030:5;7023:12;;;6691:351;;;;:::o;369:626:28:-;430:7;482:1;477;:6;:16;;;;492:1;487;:6;;;477:16;473:63;;;520:1;513:8;;;;473:63;550:10;622:2;582:34;578:1;:38;572:1;564:10;;:53;563:61;;550:74;;638:10;670:3;665:1;:8;;659:1;651:10;;:23;638:36;;698:50;693:2;:55;689:102;;;775:1;768:8;;;;;;689:102;811:2;804:9;;;;;906:2;837:66;:71;832:2;:76;828:123;;;935:1;928:8;;;;;;828:123;976:2;971;:7;964:14;;;;369:626;;;;;:::o;7048:1376:37:-;7110:13;7159:19;7214:18;;;;;;;;;;;7196:45;;;7242:5;7249:4;;;;;;;;;;;7196:58;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7159:96;;1022:1;7269:29;;7277:4;7269:29;;;7265:68;;7321:1;7314:8;;;;;7265:68;7443:16;7469;7499:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;7495:197;;7680:1;7673:8;;;;;;;7495:197;7598:9;7587:20;;7632:9;7621:20;;7518:134;;;7717:1;7705:8;:13;;;:30;;;;7734:1;7722:8;:13;;;7705:30;7701:69;;;7758:1;7751:8;;;;;;;7701:69;7819:19;7840:25;7869:29;7892:5;7869:22;:29::i;:::-;7818:80;;;;7913:20;7908:60;;7956:1;7949:8;;;;;;;;;7908:60;8021:19;8051:4;;;;;;;;;;;8043:12;;:5;:12;;;:34;;8069:8;8043:34;;;8058:8;8043:34;8021:56;;8087:20;8118:4;;;;;;;;;;;8110:12;;:5;:12;;;:34;;8136:8;8110:34;;;8125:8;8110:34;8087:57;;1070:2;8170:30;;:13;:30;;;;:182;;1070:2;8321:13;:29;;;;:::i;:::-;8314:2;:37;;;;:::i;:::-;8299:12;:52;;;;;;:::i;:::-;8170:182;;;8261:13;1070:2;8245:29;;;;:::i;:::-;8238:2;:37;;;;:::i;:::-;8223:12;:52;;;;;;:::i;:::-;8170:182;8155:197;;8370:47;8391:11;8370:47;;8404:12;8370:47;;:20;:47::i;:::-;8362:55;;7125:1299;;;;;;;7048:1376;;;;:::o;8430:1395::-;8492:7;8511:25;:46;;;;;;;;8540:3;8511:46;;;;;;8545:4;8511:46;;;;;;8551:5;8511:46;;;;;;;8567:19;8601:9;8613:1;8601:13;;8596:339;8620:15;8616:1;:19;8596:339;;;8684:19;8755:18;;;;;;;;;;;8737:45;;;8783:5;8790:4;;;;;;;;;;;8796:8;8805:1;8796:11;;;;;;;:::i;:::-;;;;;;8737:71;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8684:125;;1022:1;8827:29;;8835:4;8827:29;;;8823:102;;8883:4;8876:11;;8905:5;;;8823:102;8642:293;8637:3;;;;;8596:339;;;;1022:1;8949:29;;8957:4;8949:29;;;8945:68;;9001:1;8994:8;;;;;;8945:68;9058:20;9092:4;:10;;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;9088:186;;9262:1;9255:8;;;;;;;9088:186;9210:13;9195:28;;9105:129;;;;;;;9284:21;9316:4;;;;;;;;;;;9308:12;;:5;:12;;;9284:36;;9331:19;9352:26;9382:29;9405:5;9382:22;:29::i;:::-;9330:81;;;;9426:21;9421:61;;9470:1;9463:8;;;;;;;;;;9421:61;9806:2;9542:260;9586:12;9616:16;9650;:60;;1070:2;9650:60;;;9674:13;9650:60;9728:16;:60;;9774:13;9728:60;;;1070:2;9728:60;9542:26;:260::i;:::-;:266;;9514:304;;;;;;;;8430:1395;;;;:::o;9939:762::-;10004:5;10011:4;10028:25;10055:30;10101:5;:10;;10117:5;10124:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10101:61;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10027:135;;;;10177:20;10173:522;;;10213:21;10281:2;10253:17;:24;:30;10249:388;;10332:17;10321:40;;;;;;;;;;;;:::i;:::-;10303:58;;10401:1;10384:13;:18;:41;;;;10422:3;10406:13;:19;10384:41;10380:187;;;10457:1;10460:5;10449:17;;;;;;;;;10380:187;10527:13;10543:4;10513:35;;;;;;;;;10249:388;10613:1;10616:5;10605:17;;;;;;;;;10173:522;10675:1;10678:5;10667:17;;;;;;9939:762;;;;:::o;1190:2514:28:-;1250:7;1302:1;1297;:6;1293:20;;1312:1;1305:8;;;;1293:20;1328:14;1366:50;1361:1;:55;1357:1967;;1457:1;1451:2;1446:1;:7;;1445:13;;;;;:::i;:::-;;;1436:22;;1357:1967;;;1497:11;1511:3;1497:17;;1532:10;1550:3;1545:1;:8;;1532:21;;1581:11;1575:2;:17;1571:104;;1623:2;1616:9;;;;;1654:2;1647:9;;;;1571:104;1702:7;1696:2;:13;1692:100;;1740:2;1733:9;;;;;1771:2;1764:9;;;;1692:100;1819:5;1813:2;:11;1809:96;;1855:1;1848:8;;;;;1885:1;1878:8;;;;1809:96;1932:4;1926:2;:10;1922:95;;1967:1;1960:8;;;;;1997:1;1990:8;;;;1922:95;2044:3;2038:2;:9;2034:94;;2078:1;2071:8;;;;;2108:1;2101:8;;;;2034:94;2155:3;2149:2;:9;2145:23;;2167:1;2160:8;;;;2145:23;2276:1;2268:3;2262;:9;2255:1;2251;:5;2250:22;;2249:28;2240:3;2234;:9;2228:1;:16;;2227:51;;;;;:::i;:::-;;;2218:60;;2704:34;2695:6;:43;2691:98;;;2769:1;2762:8;;;;;;;2691:98;2807:10;2835:3;2830:1;:8;;2820:6;:19;2807:32;;2857:10;2884:34;2880:1;:38;2870:6;:49;2857:62;;2938:10;2956:3;2951:1;:8;;2938:21;;2977:10;2995:2;2990:1;:7;;2977:20;;3025:2;3020;:7;3016:20;;;3035:1;3029:7;;;;3016:20;3060:2;3054:8;;;;3128:3;3122:2;:9;;3117:14;;3158:2;3153;:7;3149:20;;;3168:1;3162:7;;;;3149:20;3193:2;3187:8;;;;3270:3;3264:2;:9;;3258:2;:15;3251:23;;;;:::i;:::-;;3308:1;3303:2;:6;;;;;:::i;:::-;;;3293:16;;;;1479:1845;;;;;;1357:1967;3574:34;3565:6;:43;3561:90;;;3635:1;3628:8;;;;;3561:90;3680:6;3665:22;;;1190:2514;;;;;:::o;3710:1606::-;3865:17;4094;4131:14;4114;:31;4094:51;;4256:23;4297:1;4282:12;:16;;;:174;;4443:12;4431:25;;:2;:25;4427:1;4410:12;4402:21;;:26;:54;4282:174;;;4369:12;4368:13;;4346:37;;4354:2;4346:37;4342:1;4325:12;4317:21;;:26;:66;;;;;:::i;:::-;;;4282:174;4256:200;;4480:15;117:27;4474:21;4470:68;;;4522:1;4515:8;;;;;;4470:68;4686:28;4717:16;:143;;117:27;4838:15;:21;;;;;:::i;:::-;;;4799:34;117:27;4793:40;4792:68;;;;;:::i;:::-;;;4717:143;;;117:27;4752:15;:21;;;;;:::i;:::-;;;4717:143;4686:174;;5017:16;:148;;5145:20;5017:148;;;117:27;5085:34;5061:20;5053:66;5052:74;;;;;:::i;:::-;;;5017:148;5005:160;;5196:17;5184:9;:29;5180:120;;;5284:1;5277:8;;;;;;;5180:120;3898:1412;;;3710:1606;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::o;7:75:46:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:338::-;1277:4;1367:18;1359:6;1356:30;1353:56;;;1389:18;;:::i;:::-;1353:56;1439:4;1431:6;1427:17;1419:25;;1499:4;1493;1489:15;1481:23;;1173:338;;;:::o;1517:117::-;1626:1;1623;1616:12;1640:117;1749:1;1746;1739:12;1886:113;1973:1;1966:5;1963:12;1953:40;;1989:1;1986;1979:12;1953:40;1886:113;:::o;2005:167::-;2065:5;2103:6;2090:20;2081:29;;2119:47;2160:5;2119:47;:::i;:::-;2005:167;;;;:::o;2178:126::-;2215:7;2255:42;2248:5;2244:54;2233:65;;2178:126;;;:::o;2310:96::-;2347:7;2376:24;2394:5;2376:24;:::i;:::-;2365:35;;2310:96;;;:::o;2412:122::-;2485:24;2503:5;2485:24;:::i;:::-;2478:5;2475:35;2465:63;;2524:1;2521;2514:12;2465:63;2412:122;:::o;2540:139::-;2586:5;2624:6;2611:20;2602:29;;2640:33;2667:5;2640:33;:::i;:::-;2540:139;;;;:::o;2725:601::-;2801:5;2845:4;2833:9;2828:3;2824:19;2820:30;2817:117;;;2853:79;;:::i;:::-;2817:117;2952:21;2968:4;2952:21;:::i;:::-;2943:30;;3036:1;3076:63;3135:3;3126:6;3115:9;3111:22;3076:63;:::i;:::-;3069:4;3062:5;3058:16;3051:89;2983:168;3217:2;3258:49;3303:3;3294:6;3283:9;3279:22;3258:49;:::i;:::-;3251:4;3244:5;3240:16;3233:75;3161:158;2725:601;;;;:::o;3374:791::-;3497:5;3522:108;3538:91;3622:6;3538:91;:::i;:::-;3522:108;:::i;:::-;3513:117;;3650:5;3679:6;3672:5;3665:21;3713:4;3706:5;3702:16;3695:23;;3766:4;3758:6;3754:17;3746:6;3742:30;3795:3;3787:6;3784:15;3781:122;;;3814:79;;:::i;:::-;3781:122;3929:6;3912:247;3946:6;3941:3;3938:15;3912:247;;;4021:3;4050:64;4110:3;4098:10;4050:64;:::i;:::-;4045:3;4038:77;4144:4;4139:3;4135:14;4128:21;;3988:171;3972:4;3967:3;3963:14;3956:21;;3912:247;;;3916:21;3503:662;;3374:791;;;;;:::o;4213:424::-;4311:5;4360:3;4353:4;4345:6;4341:17;4337:27;4327:122;;4368:79;;:::i;:::-;4327:122;4485:6;4472:20;4510:121;4627:3;4619:6;4612:4;4604:6;4600:17;4510:121;:::i;:::-;4501:130;;4317:320;4213:424;;;;:::o;4643:593::-;4754:6;4803:2;4791:9;4782:7;4778:23;4774:32;4771:119;;;4809:79;;:::i;:::-;4771:119;4957:1;4946:9;4942:17;4929:31;4987:18;4979:6;4976:30;4973:117;;;5009:79;;:::i;:::-;4973:117;5114:105;5211:7;5202:6;5191:9;5187:22;5114:105;:::i;:::-;5104:115;;4900:329;4643:593;;;;:::o;5242:147::-;5342:6;5376:5;5370:12;5360:22;;5242:147;;;:::o;5395:217::-;5527:11;5561:6;5556:3;5549:19;5601:4;5596:3;5592:14;5577:29;;5395:217;;;;:::o;5618:165::-;5718:4;5741:3;5733:11;;5771:4;5766:3;5762:14;5754:22;;5618:165;;;:::o;5789:180::-;5837:77;5834:1;5827:88;5934:4;5931:1;5924:15;5958:4;5955:1;5948:15;5975:119;6062:1;6055:5;6052:12;6042:46;;6068:18;;:::i;:::-;6042:46;5975:119;:::o;6100:139::-;6151:7;6180:5;6169:16;;6186:47;6227:5;6186:47;:::i;:::-;6100:139;;;:::o;6245:::-;6307:9;6340:38;6372:5;6340:38;:::i;:::-;6327:51;;6245:139;;;:::o;6390:145::-;6479:49;6522:5;6479:49;:::i;:::-;6474:3;6467:62;6390:145;;:::o;6541:108::-;6618:24;6636:5;6618:24;:::i;:::-;6613:3;6606:37;6541:108;;:::o;6655:77::-;6692:7;6721:5;6710:16;;6655:77;;;:::o;6738:108::-;6815:24;6833:5;6815:24;:::i;:::-;6810:3;6803:37;6738:108;;:::o;6940:715::-;7093:4;7088:3;7084:14;7184:4;7177:5;7173:16;7167:23;7203:75;7272:4;7267:3;7263:14;7249:12;7203:75;:::i;:::-;7108:180;7377:4;7370:5;7366:16;7360:23;7396:63;7453:4;7448:3;7444:14;7430:12;7396:63;:::i;:::-;7298:171;7556:4;7549:5;7545:16;7539:23;7575:63;7632:4;7627:3;7623:14;7609:12;7575:63;:::i;:::-;7479:169;7062:593;6940:715;;:::o;7661:311::-;7796:10;7817:112;7925:3;7917:6;7817:112;:::i;:::-;7961:4;7956:3;7952:14;7938:28;;7661:311;;;;:::o;7978:146::-;8081:4;8113;8108:3;8104:14;8096:22;;7978:146;;;:::o;8222:996::-;8407:3;8436:87;8517:5;8436:87;:::i;:::-;8539:119;8651:6;8646:3;8539:119;:::i;:::-;8532:126;;8682:89;8765:5;8682:89;:::i;:::-;8794:7;8825:1;8810:383;8835:6;8832:1;8829:13;8810:383;;;8911:6;8905:13;8938:129;9063:3;9048:13;8938:129;:::i;:::-;8931:136;;9090:93;9176:6;9090:93;:::i;:::-;9080:103;;8870:323;8857:1;8854;8850:9;8845:14;;8810:383;;;8814:14;9209:3;9202:10;;8412:806;;;8222:996;;;;:::o;9224:505::-;9433:4;9471:2;9460:9;9456:18;9448:26;;9520:9;9514:4;9510:20;9506:1;9495:9;9491:17;9484:47;9548:174;9717:4;9708:6;9548:174;:::i;:::-;9540:182;;9224:505;;;;:::o;9735:180::-;9783:77;9780:1;9773:88;9880:4;9877:1;9870:15;9904:4;9901:1;9894:15;9921:311;9998:4;10088:18;10080:6;10077:30;10074:56;;;10110:18;;:::i;:::-;10074:56;10160:4;10152:6;10148:17;10140:25;;10220:4;10214;10210:15;10202:23;;9921:311;;;:::o;10238:143::-;10295:5;10326:6;10320:13;10311:22;;10342:33;10369:5;10342:33;:::i;:::-;10238:143;;;;:::o;10404:732::-;10511:5;10536:81;10552:64;10609:6;10552:64;:::i;:::-;10536:81;:::i;:::-;10527:90;;10637:5;10666:6;10659:5;10652:21;10700:4;10693:5;10689:16;10682:23;;10753:4;10745:6;10741:17;10733:6;10729:30;10782:3;10774:6;10771:15;10768:122;;;10801:79;;:::i;:::-;10768:122;10916:6;10899:231;10933:6;10928:3;10925:15;10899:231;;;11008:3;11037:48;11081:3;11069:10;11037:48;:::i;:::-;11032:3;11025:61;11115:4;11110:3;11106:14;11099:21;;10975:155;10959:4;10954:3;10950:14;10943:21;;10899:231;;;10903:21;10517:619;;10404:732;;;;;:::o;11159:385::-;11241:5;11290:3;11283:4;11275:6;11271:17;11267:27;11257:122;;11298:79;;:::i;:::-;11257:122;11408:6;11402:13;11433:105;11534:3;11526:6;11519:4;11511:6;11507:17;11433:105;:::i;:::-;11424:114;;11247:297;11159:385;;;;:::o;11550:554::-;11645:6;11694:2;11682:9;11673:7;11669:23;11665:32;11662:119;;;11700:79;;:::i;:::-;11662:119;11841:1;11830:9;11826:17;11820:24;11871:18;11863:6;11860:30;11857:117;;;11893:79;;:::i;:::-;11857:117;11998:89;12079:7;12070:6;12059:9;12055:22;11998:89;:::i;:::-;11988:99;;11791:306;11550:554;;;;:::o;12110:118::-;12197:24;12215:5;12197:24;:::i;:::-;12192:3;12185:37;12110:118;;:::o;12234:222::-;12327:4;12365:2;12354:9;12350:18;12342:26;;12378:71;12446:1;12435:9;12431:17;12422:6;12378:71;:::i;:::-;12234:222;;;;:::o;12462:122::-;12535:24;12553:5;12535:24;:::i;:::-;12528:5;12525:35;12515:63;;12574:1;12571;12564:12;12515:63;12462:122;:::o;12590:143::-;12647:5;12678:6;12672:13;12663:22;;12694:33;12721:5;12694:33;:::i;:::-;12590:143;;;;:::o;12739:351::-;12809:6;12858:2;12846:9;12837:7;12833:23;12829:32;12826:119;;;12864:79;;:::i;:::-;12826:119;12984:1;13009:64;13065:7;13056:6;13045:9;13041:22;13009:64;:::i;:::-;12999:74;;12955:128;12739:351;;;;:::o;13096:180::-;13144:77;13141:1;13134:88;13241:4;13238:1;13231:15;13265:4;13262:1;13255:15;13282:410;13322:7;13345:20;13363:1;13345:20;:::i;:::-;13340:25;;13379:20;13397:1;13379:20;:::i;:::-;13374:25;;13434:1;13431;13427:9;13456:30;13474:11;13456:30;:::i;:::-;13445:41;;13635:1;13626:7;13622:15;13619:1;13616:22;13596:1;13589:9;13569:83;13546:139;;13665:18;;:::i;:::-;13546:139;13330:362;13282:410;;;;:::o;13698:351::-;13768:6;13817:2;13805:9;13796:7;13792:23;13788:32;13785:119;;;13823:79;;:::i;:::-;13785:119;13943:1;13968:64;14024:7;14015:6;14004:9;14000:22;13968:64;:::i;:::-;13958:74;;13914:128;13698:351;;;;:::o;14055:114::-;14092:7;14132:30;14125:5;14121:42;14110:53;;14055:114;;;:::o;14175:122::-;14248:24;14266:5;14248:24;:::i;:::-;14241:5;14238:35;14228:63;;14287:1;14284;14277:12;14228:63;14175:122;:::o;14303:143::-;14360:5;14391:6;14385:13;14376:22;;14407:33;14434:5;14407:33;:::i;:::-;14303:143;;;;:::o;14452:93::-;14488:7;14528:10;14521:5;14517:22;14506:33;;14452:93;;;:::o;14551:120::-;14623:23;14640:5;14623:23;:::i;:::-;14616:5;14613:34;14603:62;;14661:1;14658;14651:12;14603:62;14551:120;:::o;14677:141::-;14733:5;14764:6;14758:13;14749:22;;14780:32;14806:5;14780:32;:::i;:::-;14677:141;;;;:::o;14824:661::-;14911:6;14919;14927;14976:2;14964:9;14955:7;14951:23;14947:32;14944:119;;;14982:79;;:::i;:::-;14944:119;15102:1;15127:64;15183:7;15174:6;15163:9;15159:22;15127:64;:::i;:::-;15117:74;;15073:128;15240:2;15266:64;15322:7;15313:6;15302:9;15298:22;15266:64;:::i;:::-;15256:74;;15211:129;15379:2;15405:63;15460:7;15451:6;15440:9;15436:22;15405:63;:::i;:::-;15395:73;;15350:128;14824:661;;;;;:::o;15491:279::-;15531:7;15554:20;15572:1;15554:20;:::i;:::-;15549:25;;15588:20;15606:1;15588:20;:::i;:::-;15583:25;;15643:1;15640;15636:9;15665:30;15683:11;15665:30;:::i;:::-;15654:41;;15727:11;15718:7;15715:24;15705:58;;15743:18;;:::i;:::-;15705:58;15539:231;15491:279;;;;:::o;15776:332::-;15897:4;15935:2;15924:9;15920:18;15912:26;;15948:71;16016:1;16005:9;16001:17;15992:6;15948:71;:::i;:::-;16029:72;16097:2;16086:9;16082:18;16073:6;16029:72;:::i;:::-;15776:332;;;;;:::o;16114:86::-;16149:7;16189:4;16182:5;16178:16;16167:27;;16114:86;;;:::o;16206:191::-;16244:4;16264:18;16280:1;16264:18;:::i;:::-;16259:23;;16296:18;16312:1;16296:18;:::i;:::-;16291:23;;16338:1;16335;16331:9;16323:17;;16362:4;16356;16353:14;16350:40;;;16370:18;;:::i;:::-;16350:40;16206:191;;;;:::o;16403:102::-;16445:8;16492:5;16489:1;16485:13;16464:34;;16403:102;;;:::o;16511:848::-;16572:5;16579:4;16603:6;16594:15;;16627:5;16618:14;;16641:712;16662:1;16652:8;16649:15;16641:712;;;16757:4;16752:3;16748:14;16742:4;16739:24;16736:50;;;16766:18;;:::i;:::-;16736:50;16816:1;16806:8;16802:16;16799:451;;;17231:4;17224:5;17220:16;17211:25;;16799:451;17281:4;17275;17271:15;17263:23;;17311:32;17334:8;17311:32;:::i;:::-;17299:44;;16641:712;;;16511:848;;;;;;;:::o;17365:1073::-;17419:5;17610:8;17600:40;;17631:1;17622:10;;17633:5;;17600:40;17659:4;17649:36;;17676:1;17667:10;;17678:5;;17649:36;17745:4;17793:1;17788:27;;;;17829:1;17824:191;;;;17738:277;;17788:27;17806:1;17797:10;;17808:5;;;17824:191;17869:3;17859:8;17856:17;17853:43;;;17876:18;;:::i;:::-;17853:43;17925:8;17922:1;17918:16;17909:25;;17960:3;17953:5;17950:14;17947:40;;;17967:18;;:::i;:::-;17947:40;18000:5;;;17738:277;;18124:2;18114:8;18111:16;18105:3;18099:4;18096:13;18092:36;18074:2;18064:8;18061:16;18056:2;18050:4;18047:12;18043:35;18027:111;18024:246;;;18180:8;18174:4;18170:19;18161:28;;18215:3;18208:5;18205:14;18202:40;;;18222:18;;:::i;:::-;18202:40;18255:5;;18024:246;18295:42;18333:3;18323:8;18317:4;18314:1;18295:42;:::i;:::-;18280:57;;;;18369:4;18364:3;18360:14;18353:5;18350:25;18347:51;;;18378:18;;:::i;:::-;18347:51;18427:4;18420:5;18416:16;18407:25;;17365:1073;;;;;;:::o;18444:281::-;18502:5;18526:23;18544:4;18526:23;:::i;:::-;18518:31;;18570:25;18586:8;18570:25;:::i;:::-;18558:37;;18614:104;18651:66;18641:8;18635:4;18614:104;:::i;:::-;18605:113;;18444:281;;;;:::o;18731:180::-;18779:77;18776:1;18769:88;18876:4;18873:1;18866:15;18900:4;18897:1;18890:15;18917:185;18957:1;18974:20;18992:1;18974:20;:::i;:::-;18969:25;;19008:20;19026:1;19008:20;:::i;:::-;19003:25;;19047:1;19037:35;;19052:18;;:::i;:::-;19037:35;19094:1;19091;19087:9;19082:14;;18917:185;;;;:::o;19108:89::-;19144:7;19184:6;19177:5;19173:18;19162:29;;19108:89;;;:::o;19203:91::-;19239:7;19279:8;19272:5;19268:20;19257:31;;19203:91;;;:::o;19300:60::-;19328:3;19349:5;19342:12;;19300:60;;;:::o;19366:138::-;19414:9;19447:51;19464:33;19473:23;19490:5;19473:23;:::i;:::-;19464:33;:::i;:::-;19447:51;:::i;:::-;19434:64;;19366:138;;;:::o;19510:127::-;19595:35;19624:5;19595:35;:::i;:::-;19590:3;19583:48;19510:127;;:::o;19643:438::-;19790:4;19828:2;19817:9;19813:18;19805:26;;19841:71;19909:1;19898:9;19894:17;19885:6;19841:71;:::i;:::-;19922:72;19990:2;19979:9;19975:18;19966:6;19922:72;:::i;:::-;20004:70;20070:2;20059:9;20055:18;20046:6;20004:70;:::i;:::-;19643:438;;;;;;:::o;20087:122::-;20160:24;20178:5;20160:24;:::i;:::-;20153:5;20150:35;20140:63;;20199:1;20196;20189:12;20140:63;20087:122;:::o;20215:143::-;20272:5;20303:6;20297:13;20288:22;;20319:33;20346:5;20319:33;:::i;:::-;20215:143;;;;:::o;20364:90::-;20399:7;20442:5;20439:1;20428:20;20417:31;;20364:90;;;:::o;20460:118::-;20531:22;20547:5;20531:22;:::i;:::-;20524:5;20521:33;20511:61;;20568:1;20565;20558:12;20511:61;20460:118;:::o;20584:139::-;20639:5;20670:6;20664:13;20655:22;;20686:31;20711:5;20686:31;:::i;:::-;20584:139;;;;:::o;20729:120::-;20801:23;20818:5;20801:23;:::i;:::-;20794:5;20791:34;20781:62;;20839:1;20836;20829:12;20781:62;20729:120;:::o;20855:141::-;20911:5;20942:6;20936:13;20927:22;;20958:32;20984:5;20958:32;:::i;:::-;20855:141;;;;:::o;21002:118::-;21073:22;21089:5;21073:22;:::i;:::-;21066:5;21063:33;21053:61;;21110:1;21107;21100:12;21053:61;21002:118;:::o;21126:139::-;21181:5;21212:6;21206:13;21197:22;;21228:31;21253:5;21228:31;:::i;:::-;21126:139;;;;:::o;21271:90::-;21305:7;21348:5;21341:13;21334:21;21323:32;;21271:90;;;:::o;21367:116::-;21437:21;21452:5;21437:21;:::i;:::-;21430:5;21427:32;21417:60;;21473:1;21470;21463:12;21417:60;21367:116;:::o;21489:137::-;21543:5;21574:6;21568:13;21559:22;;21590:30;21614:5;21590:30;:::i;:::-;21489:137;;;;:::o;21632:1271::-;21746:6;21754;21762;21770;21778;21786;21794;21843:3;21831:9;21822:7;21818:23;21814:33;21811:120;;;21850:79;;:::i;:::-;21811:120;21970:1;21995:64;22051:7;22042:6;22031:9;22027:22;21995:64;:::i;:::-;21985:74;;21941:128;22108:2;22134:62;22188:7;22179:6;22168:9;22164:22;22134:62;:::i;:::-;22124:72;;22079:127;22245:2;22271:63;22326:7;22317:6;22306:9;22302:22;22271:63;:::i;:::-;22261:73;;22216:128;22383:2;22409:63;22464:7;22455:6;22444:9;22440:22;22409:63;:::i;:::-;22399:73;;22354:128;22521:3;22548:63;22603:7;22594:6;22583:9;22579:22;22548:63;:::i;:::-;22538:73;;22492:129;22660:3;22687:62;22741:7;22732:6;22721:9;22717:22;22687:62;:::i;:::-;22677:72;;22631:128;22798:3;22825:61;22878:7;22869:6;22858:9;22854:22;22825:61;:::i;:::-;22815:71;;22769:127;21632:1271;;;;;;;;;;:::o;22909:98::-;22960:6;22994:5;22988:12;22978:22;;22909:98;;;:::o;23013:147::-;23114:11;23151:3;23136:18;;23013:147;;;;:::o;23166:139::-;23255:6;23250:3;23245;23239:23;23296:1;23287:6;23282:3;23278:16;23271:27;23166:139;;;:::o;23311:386::-;23415:3;23443:38;23475:5;23443:38;:::i;:::-;23497:88;23578:6;23573:3;23497:88;:::i;:::-;23490:95;;23594:65;23652:6;23647:3;23640:4;23633:5;23629:16;23594:65;:::i;:::-;23684:6;23679:3;23675:16;23668:23;;23419:278;23311:386;;;;:::o;23703:271::-;23833:3;23855:93;23944:3;23935:6;23855:93;:::i;:::-;23848:100;;23965:3;23958:10;;23703:271;;;;:::o;23980:180::-;24028:77;24025:1;24018:88;24125:4;24122:1;24115:15;24149:4;24146:1;24139:15\",\"linkReferences\":{}},\"methodIdentifiers\":{\"getWethValueInPools((uint8,address)[])\":\"339173fd\"},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.30+commit.73712a01\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_uniswapV2Factory\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_uniswapV3Factory\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_weth\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"inputs\\\":[{\\\"components\\\":[{\\\"internalType\\\":\\\"enum WethValueInPools.PoolType\\\",\\\"name\\\":\\\"poolType\\\",\\\"type\\\":\\\"uint8\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"poolAddress\\\",\\\"type\\\":\\\"address\\\"}],\\\"internalType\\\":\\\"struct WethValueInPools.PoolInfo[]\\\",\\\"name\\\":\\\"pools\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"name\\\":\\\"getWethValueInPools\\\",\\\"outputs\\\":[{\\\"components\\\":[{\\\"internalType\\\":\\\"enum WethValueInPools.PoolType\\\",\\\"name\\\":\\\"poolType\\\",\\\"type\\\":\\\"uint8\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"poolAddress\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"wethValue\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"internalType\\\":\\\"struct WethValueInPools.PoolInfoReturn[]\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"getWethValueInPools((uint8,address)[])\\\":{\\\"details\\\":\\\"We require a 1 ETH minimum liquidity in the quoting pool for it to be considered.\\\"}},\\\"stateVariables\\\":{\\\"UNISWAP_V2_FACTORY\\\":{\\\"details\\\":\\\"Used as the first priority for quoting WETH value\\\"},\\\"UNISWAP_V3_FACTORY\\\":{\\\"details\\\":\\\"Used as the second priority for quoting WETH value\\\"}},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"getWethValueInPools((uint8,address)[])\\\":{\\\"notice\\\":\\\"Returns an array of `PoolInfoReturn` for the consumer to determine wether to filter or not to save gas.\\\"}},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/filters/WethValueInPools.sol\\\":\\\"WethValueInPools\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"ipfs\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV3/FixedPoint.sol\\\":{\\\"keccak256\\\":\\\"0xf82873fe78051afcf0446c27f5c5857816d1129e2bc84855dee8275d764b49d0\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://5d1b9704466cdf93f446ac2330ef89752c2bcc1f271a70c296f54e0d9291467f\\\",\\\"dweb:/ipfs/QmaQd3DUAdJMVQD422o2HyAwhTDyLo33znMgRDU5NaZegE\\\"]},\\\"src/filters/WethValueInPools.sol\\\":{\\\"keccak256\\\":\\\"0x1bd98caec9df680366948f8e1f24ed7262021aeb841ea155efafb05648152c4b\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://3f88558f892e5441c824e1d6973036e1196445b99c7e24fcfa6a399af64e2ace\\\",\\\"dweb:/ipfs/QmT7KqFaR9pysM94AAbSgeJrb1XsQickV6kyowBWc5vYgT\\\"]},\\\"src/interfaces/IBalancer.sol\\\":{\\\"keccak256\\\":\\\"0xe7ca1e7f70a16d6919334b612a584e5d42692a802f4d92686c564a4ab1550c27\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://2e0cf4540fca9dbf3650d22d1d927b43bcd8333a988c7575c6618b633bff082f\\\",\\\"dweb:/ipfs/QmYAcUnqBauhiXJNfMLta4Bj1dntGmNJ3cxaHq18LnBDAQ\\\"]},\\\"src/interfaces/IUniswapV2.sol\\\":{\\\"keccak256\\\":\\\"0x067d9c125da6fdbe44d6ce7d498c42460d7347317413f8317bf80bd25c08898d\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://b1ad58162042aa8d1eb7451af3ccc3b1df64e720aeeb69a6843507aec0e5d146\\\",\\\"dweb:/ipfs/QmdvEJYkfWaGWrGXtKajZSDdfNYJ3sDFpzsV4f1X4KQYZM\\\"]},\\\"src/interfaces/IUniswapV3.sol\\\":{\\\"keccak256\\\":\\\"0x914ac5f4d9e6b6d0345c89e769f1a2d9784d047e8cac6f3265b229afd9363729\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://19a3f9d71839d62cea60562c57cdfe582821da7bfe17a1d6ca26597db51a3762\\\",\\\"dweb:/ipfs/QmdWoVo3J7tcSKCk5cCADvjvMtmczcGbsmKx5v9AFjQANz\\\"]},\\\"src/interfaces/Token.sol\\\":{\\\"keccak256\\\":\\\"0x2f7118f6cba8e0303e66028f738463e025a19ec0186a5462523692f44330e113\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://ca6355f3ce4aec77f281142db4cb0a63d5e1b3b4b12836ac9a3ed251069801d0\\\",\\\"dweb:/ipfs/QmWTt8HyEuzTdKVWCzBDxVMWL3tptkxsTfsssbEMVA818A\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_uniswapV2Factory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_uniswapV3Factory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"struct WethValueInPools.PoolInfo[]\",\"name\":\"pools\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"enum WethValueInPools.PoolType\",\"name\":\"poolType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"getWethValueInPools\",\"outputs\":[{\"internalType\":\"struct WethValueInPools.PoolInfoReturn[]\",\"name\":\"\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"enum WethValueInPools.PoolType\",\"name\":\"poolType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wethValue\",\"type\":\"uint256\"}]}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getWethValueInPools((uint8,address)[])\":{\"details\":\"We require a 1 ETH minimum liquidity in the quoting pool for it to be considered.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getWethValueInPools((uint8,address)[])\":{\"notice\":\"Returns an array of `PoolInfoReturn` for the consumer to determine wether to filter or not to save gas.\"}},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"compilationTarget\":{\"src/filters/WethValueInPools.sol\":\"WethValueInPools\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/UniswapV3/FixedPoint.sol\":{\"keccak256\":\"0xf82873fe78051afcf0446c27f5c5857816d1129e2bc84855dee8275d764b49d0\",\"urls\":[\"bzz-raw://5d1b9704466cdf93f446ac2330ef89752c2bcc1f271a70c296f54e0d9291467f\",\"dweb:/ipfs/QmaQd3DUAdJMVQD422o2HyAwhTDyLo33znMgRDU5NaZegE\"],\"license\":\"MIT\"},\"src/filters/WethValueInPools.sol\":{\"keccak256\":\"0x1bd98caec9df680366948f8e1f24ed7262021aeb841ea155efafb05648152c4b\",\"urls\":[\"bzz-raw://3f88558f892e5441c824e1d6973036e1196445b99c7e24fcfa6a399af64e2ace\",\"dweb:/ipfs/QmT7KqFaR9pysM94AAbSgeJrb1XsQickV6kyowBWc5vYgT\"],\"license\":\"MIT\"},\"src/interfaces/IBalancer.sol\":{\"keccak256\":\"0xe7ca1e7f70a16d6919334b612a584e5d42692a802f4d92686c564a4ab1550c27\",\"urls\":[\"bzz-raw://2e0cf4540fca9dbf3650d22d1d927b43bcd8333a988c7575c6618b633bff082f\",\"dweb:/ipfs/QmYAcUnqBauhiXJNfMLta4Bj1dntGmNJ3cxaHq18LnBDAQ\"],\"license\":\"MIT\"},\"src/interfaces/IUniswapV2.sol\":{\"keccak256\":\"0x067d9c125da6fdbe44d6ce7d498c42460d7347317413f8317bf80bd25c08898d\",\"urls\":[\"bzz-raw://b1ad58162042aa8d1eb7451af3ccc3b1df64e720aeeb69a6843507aec0e5d146\",\"dweb:/ipfs/QmdvEJYkfWaGWrGXtKajZSDdfNYJ3sDFpzsV4f1X4KQYZM\"],\"license\":\"MIT\"},\"src/interfaces/IUniswapV3.sol\":{\"keccak256\":\"0x914ac5f4d9e6b6d0345c89e769f1a2d9784d047e8cac6f3265b229afd9363729\",\"urls\":[\"bzz-raw://19a3f9d71839d62cea60562c57cdfe582821da7bfe17a1d6ca26597db51a3762\",\"dweb:/ipfs/QmdWoVo3J7tcSKCk5cCADvjvMtmczcGbsmKx5v9AFjQANz\"],\"license\":\"MIT\"},\"src/interfaces/Token.sol\":{\"keccak256\":\"0x2f7118f6cba8e0303e66028f738463e025a19ec0186a5462523692f44330e113\",\"urls\":[\"bzz-raw://ca6355f3ce4aec77f281142db4cb0a63d5e1b3b4b12836ac9a3ed251069801d0\",\"dweb:/ipfs/QmWTt8HyEuzTdKVWCzBDxVMWL3tptkxsTfsssbEMVA818A\"],\"license\":\"MIT\"}},\"version\":1},\"id\":37}"
  },
  {
    "path": "src/amms/abi/WethValueInPoolsBatchRequest.json",
    "content": "{\"abi\":[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_uniswapV2Factory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_uniswapV3Factory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_weth\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"pools\",\"type\":\"tuple[]\",\"internalType\":\"struct WethValueInPools.PoolInfo[]\",\"components\":[{\"name\":\"poolType\",\"type\":\"uint8\",\"internalType\":\"enum WethValueInPools.PoolType\"},{\"name\":\"poolAddress\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getWethValueInPools\",\"inputs\":[{\"name\":\"pools\",\"type\":\"tuple[]\",\"internalType\":\"struct WethValueInPools.PoolInfo[]\",\"components\":[{\"name\":\"poolType\",\"type\":\"uint8\",\"internalType\":\"enum WethValueInPools.PoolType\"},{\"name\":\"poolAddress\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"struct WethValueInPools.PoolInfoReturn[]\",\"components\":[{\"name\":\"poolType\",\"type\":\"uint8\",\"internalType\":\"enum WethValueInPools.PoolType\"},{\"name\":\"poolAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"wethValue\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"nonpayable\"}],\"bytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b506040516125fc3803806125fc83398181016040528101906100319190611ba6565b838383825f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505f6101068261013560201b60201c565b90505f8160405160200161011a9190611da8565b60405160208183030381529060405290506020810180590381f35b60605f825167ffffffffffffffff811115610153576101526119f6565b5b60405190808252806020026020018201604052801561018c57816020015b610179611931565b8152602001906001900390816101715790505b5090505f5f90505b83518110156103de575f8482815181106101b1576101b0611dc8565b5b602002602001015190505f60028111156101ce576101cd611c4f565b5b815f015160028111156101e4576101e3611c4f565b5b0361026d575f6101fd82602001516103e860201b60201c565b90506040518060600160405280835f015160028111156102205761021f611c4f565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061025c5761025b611dc8565b5b6020026020010181905250506103d0565b6001600281111561028157610280611c4f565b5b815f0151600281111561029757610296611c4f565b5b03610320575f6102b0826020015161067760201b60201c565b90506040518060600160405280835f015160028111156102d3576102d2611c4f565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061030f5761030e611dc8565b5b6020026020010181905250506103cf565b60028081111561033357610332611c4f565b5b815f0151600281111561034957610348611c4f565b5b036103ce575f610362826020015161091b60201b60201c565b90506040518060600160405280835f0151600281111561038557610384611c4f565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff168152602001828152508484815181106103c1576103c0611dc8565b5b6020026020010181905250505b5b5b508080600101915050610194565b5080915050919050565b5f60608273ffffffffffffffffffffffffffffffffffffffff1663cc77828d6040518163ffffffff1660e01b81526004015f604051808303815f875af192505050801561045757506040513d5f823e3d601f19601f820116820180604052508101906104549190611eb5565b60015b610464575f915050610672565b809150505f5f90505b81518110156105a45760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168282815181106104c1576104c0611dc8565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610597578373ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f83838151811061051357610512611dc8565b5b60200260200101516040518263ffffffff1660e01b81526004016105379190611f0b565b6020604051808303815f875af192505050801561057257506040513d601f19601f8201168201806040525081019061056f9190611f4e565b60015b610580575f92505050610672565b82518161058d9190611fa6565b9350505050610672565b808060010191505061046d565b505f815f815181106105b9576105b8611dc8565b5b602002602001015190505f8473ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f836040518263ffffffff1660e01b81526004016105fd9190611f0b565b6020604051808303815f875af192505050801561063857506040513d601f19601f820116820180604052508101906106359190611f4e565b60015b610647575f9350505050610672565b809150505f61065c8383610c9660201b60201c565b905083518161066b9190611fa6565b9450505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156106e157506040513d601f19601f820116820180604052508101906106de9190611fe7565b60015b6106ee575f915050610916565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561075b57506040513d601f19601f820116820180604052508101906107589190611fe7565b60015b610769575f92505050610916565b809150508373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa9250505080156107d557506040513d601f19601f820116820180604052508101906107d2919061208e565b60015b6107e3575f92505050610916565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036108605760028361084491906120de565b6dffffffffffffffffffffffffffff1695505050505050610916565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036108dd576002826108c191906120de565b6dffffffffffffffffffffffffffff1695505050505050610916565b5f6108fe86856dffffffffffffffffffffffffffff16610c9660201b60201c565b905060028161090d9190611fa6565b96505050505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561098557506040513d601f19601f820116820180604052508101906109829190611fe7565b60015b610992575f915050610c91565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156109ff57506040513d601f19601f820116820180604052508101906109fc9190611fe7565b60015b610a0d575f92505050610c91565b8091505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610afd578173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610a9e9190611f0b565b602060405180830381865afa925050508015610ad857506040513d601f19601f82011682018060405250810190610ad59190611f4e565b60015b610ae6575f92505050610c91565b600281610af39190611fa6565b9350505050610c91565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610be9578073ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610b8a9190611f0b565b602060405180830381865afa925050508015610bc457506040513d601f19601f82011682018060405250810190610bc19190611f4e565b60015b610bd2575f92505050610c91565b600281610bdf9190611fa6565b9350505050610c91565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610c229190611f0b565b602060405180830381865afa925050508015610c5c57506040513d601f19601f82011682018060405250810190610c599190611f4e565b60015b610c6a575f92505050610c91565b5f610c7b8483610c9660201b60201c565b9050600281610c8a9190611fa6565b9450505050505b919050565b5f5f610ca784610cf860201b60201c565b90505f816fffffffffffffffffffffffffffffffff161115610cdb57610cd38184610d4960201b60201c565b915050610cf2565b806fffffffffffffffffffffffffffffffff169150505b92915050565b5f5f610d0983610e3360201b60201c565b90505f816fffffffffffffffffffffffffffffffff161115610d2e5780915050610d44565b610d3d8361119060201b60201c565b9050809150505b919050565b5f5f821480610d6957505f836fffffffffffffffffffffffffffffffff16145b15610d76575f9050610e2d565b5f60406fffffffffffffffffffffffffffffffff8416856fffffffffffffffffffffffffffffffff1602901c90505f608084901c856fffffffffffffffffffffffffffffffff1602905077ffffffffffffffffffffffffffffffffffffffffffffffff811115610dea575f92505050610e2d565b604081901b9050817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03811115610e25575f92505050610e2d565b818101925050505b92915050565b5f5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a439058460025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401610eb192919061211a565b602060405180830381865afa158015610ecc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ef09190611fe7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610f2e575f91505061118b565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa925050508015610f9857506040513d601f19601f82011682018060405250810190610f95919061208e565b60015b610fa7575f935050505061118b565b8294508193505050505f826dffffffffffffffffffffffffffff161480610fdd57505f816dffffffffffffffffffffffffffff16145b15610fed575f935050505061118b565b5f5f610ffe8761146960201b60201c565b9150915080611014575f9550505050505061118b565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161061106f5784611071565b835b90505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16106110ce57846110d0565b855b9050601260ff168460ff16111561111a576012846110ee919061214d565b600a6110fa91906122b0565b816dffffffffffffffffffffffffffff166111159190612327565b61114f565b836012611127919061214d565b600a61113391906122b0565b816dffffffffffffffffffffffffffff1661114e9190611fa6565b5b9050611181826dffffffffffffffffffffffffffff16826dffffffffffffffffffffffffffff166115cd60201b60201c565b9750505050505050505b919050565b5f5f60405180606001604052806101f461ffff168152602001610bb861ffff16815260200161271061ffff1681525090505f5f5f90505b60038110156112f0575f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631698ee828760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687866003811061124457611243611dc8565b5b60200201516040518463ffffffff1660e01b8152600401611267939291906123ab565b602060405180830381865afa158015611282573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112a69190611fe7565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146112e457809250506112f0565b508060010190506111c7565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361132e575f92505050611464565b5f8173ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa92505050801561139757506040513d601f19601f8201168201806040525081019061139491906124c9565b60015b6113a6575f9350505050611464565b869750505050505050505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161090505f5f6114148861146960201b60201c565b915091508061142b575f9650505050505050611464565b604061145985858661143e576012611440565b855b8761144b578661144e565b60125b6117af60201b60201c565b901c96505050505050505b919050565b5f5f5f5f8473ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161151791906125b8565b5f604051808303815f8787f1925050503d805f8114611551576040519150601f19603f3d011682016040523d82523d5f602084013e611556565b606091505b509150915081156115bf575f60208251036115b1578180602001905181019061157f9190611f4e565b90505f81148061158f575060ff81115b156115a2575f5f945094505050506115c8565b806001945094505050506115c8565b5f5f945094505050506115c8565b5f5f9350935050505b915091565b5f5f82036115dd575f90506117a9565b5f77ffffffffffffffffffffffffffffffffffffffffffffffff84116116195782604085901b81611611576116106122fa565b5b049050611783565b5f60c090505f60c086901c9050640100000000811061164057602081901c90506020820191505b62010000811061165857601081901c90506010820191505b610100811061166f57600881901c90506008820191505b6010811061168557600481901c90506004820191505b6004811061169b57600281901c90506002820191505b600281106116aa576001820191505b600160bf830360018703901c018260ff0387901b816116cc576116cb6122fa565b5b0492506fffffffffffffffffffffffffffffffff8311156116f2575f93505050506117a9565b5f608086901c840290505f6fffffffffffffffffffffffffffffffff8716850290505f60c089901c90505f60408a901b905082811015611733576001820391505b8281039050608084901b92508281101561174e576001820391505b8281039050608084901c8214611767576117666125ce565b5b888181611777576117766122fa565b5b04870196505050505050505b6fffffffffffffffffffffffffffffffff8111156117a4575f9150506117a9565b809150505b92915050565b5f5f82840390505f5f825f0b126117e7578160ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a0261181a565b815f0360ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a81611818576118176122fa565b5b045b9050806c01000000000000000000000000111561183b575f92505050611929565b5f86611893576c01000000000000000000000000828161185e5761185d6122fa565b5b046fffffffffffffffffffffffffffffffff6c01000000000000000000000000028161188d5761188c6122fa565b5b046118b2565b6c0100000000000000000000000082816118b0576118af6122fa565b5b045b9050866118bf57806118f0565b6c010000000000000000000000006fffffffffffffffffffffffffffffffff8202816118ee576118ed6122fa565b5b045b93507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841115611925575f9350505050611929565b5050505b949350505050565b60405180606001604052805f600281111561194f5761194e611c4f565b5b81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119b182611988565b9050919050565b6119c1816119a7565b81146119cb575f5ffd5b50565b5f815190506119dc816119b8565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611a2c826119e6565b810181811067ffffffffffffffff82111715611a4b57611a4a6119f6565b5b80604052505050565b5f611a5d611977565b9050611a698282611a23565b919050565b5f67ffffffffffffffff821115611a8857611a876119f6565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b60038110611aad575f5ffd5b50565b5f81519050611abe81611aa1565b92915050565b5f60408284031215611ad957611ad8611a9d565b5b611ae36040611a54565b90505f611af284828501611ab0565b5f830152506020611b05848285016119ce565b60208301525092915050565b5f611b23611b1e84611a6e565b611a54565b90508083825260208201905060408402830185811115611b4657611b45611a99565b5b835b81811015611b6f5780611b5b8882611ac4565b845260208401935050604081019050611b48565b5050509392505050565b5f82601f830112611b8d57611b8c6119e2565b5b8151611b9d848260208601611b11565b91505092915050565b5f5f5f5f60808587031215611bbe57611bbd611980565b5b5f611bcb878288016119ce565b9450506020611bdc878288016119ce565b9350506040611bed878288016119ce565b925050606085015167ffffffffffffffff811115611c0e57611c0d611984565b5b611c1a87828801611b79565b91505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110611c8d57611c8c611c4f565b5b50565b5f819050611c9d82611c7c565b919050565b5f611cac82611c90565b9050919050565b611cbc81611ca2565b82525050565b611ccb816119a7565b82525050565b5f819050919050565b611ce381611cd1565b82525050565b606082015f820151611cfd5f850182611cb3565b506020820151611d106020850182611cc2565b506040820151611d236040850182611cda565b50505050565b5f611d348383611ce9565b60608301905092915050565b5f602082019050919050565b5f611d5682611c26565b611d608185611c30565b9350611d6b83611c40565b805f5b83811015611d9b578151611d828882611d29565b9750611d8d83611d40565b925050600181019050611d6e565b5085935050505092915050565b5f6020820190508181035f830152611dc08184611d4c565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f67ffffffffffffffff821115611e0f57611e0e6119f6565b5b602082029050602081019050919050565b5f611e32611e2d84611df5565b611a54565b90508083825260208201905060208402830185811115611e5557611e54611a99565b5b835b81811015611e7e5780611e6a88826119ce565b845260208401935050602081019050611e57565b5050509392505050565b5f82601f830112611e9c57611e9b6119e2565b5b8151611eac848260208601611e20565b91505092915050565b5f60208284031215611eca57611ec9611980565b5b5f82015167ffffffffffffffff811115611ee757611ee6611984565b5b611ef384828501611e88565b91505092915050565b611f05816119a7565b82525050565b5f602082019050611f1e5f830184611efc565b92915050565b611f2d81611cd1565b8114611f37575f5ffd5b50565b5f81519050611f4881611f24565b92915050565b5f60208284031215611f6357611f62611980565b5b5f611f7084828501611f3a565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611fb082611cd1565b9150611fbb83611cd1565b9250828202611fc981611cd1565b91508282048414831517611fe057611fdf611f79565b5b5092915050565b5f60208284031215611ffc57611ffb611980565b5b5f612009848285016119ce565b91505092915050565b5f6dffffffffffffffffffffffffffff82169050919050565b61203481612012565b811461203e575f5ffd5b50565b5f8151905061204f8161202b565b92915050565b5f63ffffffff82169050919050565b61206d81612055565b8114612077575f5ffd5b50565b5f8151905061208881612064565b92915050565b5f5f5f606084860312156120a5576120a4611980565b5b5f6120b286828701612041565b93505060206120c386828701612041565b92505060406120d48682870161207a565b9150509250925092565b5f6120e882612012565b91506120f383612012565b925082820261210181612012565b915080821461211357612112611f79565b5b5092915050565b5f60408201905061212d5f830185611efc565b61213a6020830184611efc565b9392505050565b5f60ff82169050919050565b5f61215782612141565b915061216283612141565b9250828203905060ff81111561217b5761217a611f79565b5b92915050565b5f8160011c9050919050565b5f5f8291508390505b60018511156121d6578086048111156121b2576121b1611f79565b5b60018516156121c15780820291505b80810290506121cf85612181565b9450612196565b94509492505050565b5f826121ee57600190506122a9565b816121fb575f90506122a9565b8160018114612211576002811461221b5761224a565b60019150506122a9565b60ff84111561222d5761222c611f79565b5b8360020a91508482111561224457612243611f79565b5b506122a9565b5060208310610133831016604e8410600b841016171561227f5782820a90508381111561227a57612279611f79565b5b6122a9565b61228c848484600161218d565b925090508184048111156122a3576122a2611f79565b5b81810290505b9392505050565b5f6122ba82611cd1565b91506122c583612141565b92506122f27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846121df565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61233182611cd1565b915061233c83611cd1565b92508261234c5761234b6122fa565b5b828204905092915050565b5f61ffff82169050919050565b5f62ffffff82169050919050565b5f819050919050565b5f61239561239061238b84612357565b612372565b612364565b9050919050565b6123a58161237b565b82525050565b5f6060820190506123be5f830186611efc565b6123cb6020830185611efc565b6123d8604083018461239c565b949350505050565b6123e981611988565b81146123f3575f5ffd5b50565b5f81519050612404816123e0565b92915050565b5f8160020b9050919050565b61241f8161240a565b8114612429575f5ffd5b50565b5f8151905061243a81612416565b92915050565b61244981612357565b8114612453575f5ffd5b50565b5f8151905061246481612440565b92915050565b61247381612141565b811461247d575f5ffd5b50565b5f8151905061248e8161246a565b92915050565b5f8115159050919050565b6124a881612494565b81146124b2575f5ffd5b50565b5f815190506124c38161249f565b92915050565b5f5f5f5f5f5f5f60e0888a0312156124e4576124e3611980565b5b5f6124f18a828b016123f6565b97505060206125028a828b0161242c565b96505060406125138a828b01612456565b95505060606125248a828b01612456565b94505060806125358a828b01612456565b93505060a06125468a828b01612480565b92505060c06125578a828b016124b5565b91505092959891949750929550565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61259282612566565b61259c8185612570565b93506125ac81856020860161257a565b80840191505092915050565b5f6125c38284612588565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfe\",\"sourceMap\":\"91:923:34:-:0;;;155:857;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;333:17;352;371:5;1191:17:33;1170:18;;:38;;;;;;;;;;;;;;;;;;1239:17;1218:18;;:38;;;;;;;;;;;;;;;;;;1273:5;1266:4;;:12;;;;;;;;;;;;;;;;;;1079:206;;;388:55:34::1;446:26;466:5;446:19;;;:26;;:::i;:::-;388:84;;674:27;715:14;704:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;674:56;;936:4;920:14;916:25;985:9;976:7;972:23;961:9;954:42;1908:1035:33::0;1978:23;2013:39;2076:5;:12;2055:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2013:76;;2104:9;2116:1;2104:13;;2099:806;2123:5;:12;2119:1;:16;2099:806;;;2156:20;2179:5;2185:1;2179:8;;;;;;;;:::i;:::-;;;;;;;;2156:31;;2222:17;2205:34;;;;;;;;:::i;:::-;;:4;:13;;;:34;;;;;;;;:::i;:::-;;;2201:694;;2259:17;2279:36;2298:4;:16;;;2279:18;;;:36;;:::i;:::-;2259:56;;2354:58;;;;;;;;2369:4;:13;;;2354:58;;;;;;;;:::i;:::-;;;;;;2384:4;:16;;;2354:58;;;;;;2402:9;2354:58;;;2333:15;2349:1;2333:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2241:186;2201:694;;;2454:18;2437:35;;;;;;;;:::i;:::-;;:4;:13;;;:35;;;;;;;;:::i;:::-;;;2433:462;;2492:17;2512:37;2532:4;:16;;;2512:19;;;:37;;:::i;:::-;2492:57;;2588:58;;;;;;;;2603:4;:13;;;2588:58;;;;;;;;:::i;:::-;;;;;;2618:4;:16;;;2588:58;;;;;;2636:9;2588:58;;;2567:15;2583:1;2567:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2474:187;2433:462;;;2688:18;2671:35;;;;;;;;:::i;:::-;;:4;:13;;;:35;;;;;;;;:::i;:::-;;;2667:228;;2726:17;2746:37;2766:4;:16;;;2746:19;;;:37;;:::i;:::-;2726:57;;2822:58;;;;;;;;2837:4;:13;;;2822:58;;;;;;;;:::i;:::-;;;;;;2852:4;:16;;;2822:58;;;;;;2870:9;2822:58;;;2801:15;2817:1;2801:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2708:187;2667:228;2433:462;2201:694;2142:763;2137:3;;;;;;;2099:806;;;;2921:15;2914:22;;;1908:1035;;;:::o;2949:1221::-;3009:7;3055:23;3099:4;3092:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3088:152;;3228:1;3221:8;;;;;3088:152;3182:7;3173:16;;3124:76;3359:9;3371:1;3359:13;;3354:473;3378:6;:13;3374:1;:17;3354:473;;;3429:4;;;;;;;;;;;3416:17;;:6;3423:1;3416:9;;;;;;;;:::i;:::-;;;;;;;;:17;;;3412:405;;3464:4;3457:23;;;3481:6;3488:1;3481:9;;;;;;;;:::i;:::-;;;;;;;;3457:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3453:350;;3783:1;3776:8;;;;;;3453:350;3715:6;:13;3704:8;:24;;;;:::i;:::-;3697:31;;;;;;;3412:405;3393:3;;;;;;;3354:473;;;;3837:17;3857:6;3864:1;3857:9;;;;;;;;:::i;:::-;;;;;;;;3837:29;;3876:15;3912:4;3905:23;;;3929:9;3905:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3901:149;;4038:1;4031:8;;;;;;;3901:149;3991:8;3981:18;;3940:70;4060:17;4080:41;4102:9;4113:7;4080:21;;;:41;;:::i;:::-;4060:61;;4150:6;:13;4138:9;:25;;;;:::i;:::-;4131:32;;;;;;2949:1221;;;;:::o;4176:896::-;4237:7;4256:14;4299:4;4284:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4280:141;;4409:1;4402:8;;;;;4280:141;4363:7;4354:16;;4314:67;4430:14;4473:4;4458:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4454:141;;4583:1;4576:8;;;;;;4454:141;4537:7;4528:16;;4488:67;4623:4;4608:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4604:462;;5054:1;5047:8;;;;;;4604:462;4724:4;;;;;;;;;;;4714:14;;:6;:14;;;4710:150;;4766:1;4755:8;:12;;;;:::i;:::-;4748:19;;;;;;;;;;;4710:150;4802:4;;;;;;;;;;;4792:14;;:6;:14;;;4788:72;;4844:1;4833:8;:12;;;;:::i;:::-;4826:19;;;;;;;;;;;4788:72;4922:17;4942:39;4964:6;4972:8;4942:39;;:21;;;:39;;:::i;:::-;4922:59;;5014:1;5002:9;:13;;;;:::i;:::-;4995:20;;;;;;;;4176:896;;;;:::o;5078:1167::-;5139:7;5158:14;5209:4;5186:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5182:150;;5320:1;5313:8;;;;;5182:150;5274:7;5265:16;;5225:67;5341:14;5392:4;5369:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5365:150;;5503:1;5496:8;;;;;;5365:150;5457:7;5448:16;;5408:67;5539:4;;;;;;;;;;;5529:14;;:6;:14;;;5525:432;;5570:6;5563:24;;;5596:4;5563:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5559:169;;5712:1;5705:8;;;;;;5559:169;5664:1;5654:7;:11;;;;:::i;:::-;5647:18;;;;;;;5525:432;5758:4;;;;;;;;;;;5748:14;;:6;:14;;;5744:213;;5789:6;5782:24;;;5815:4;5782:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5778:169;;5931:1;5924:8;;;;;;5778:169;5883:1;5873:7;:11;;;;:::i;:::-;5866:18;;;;;;;5744:213;6023:6;6016:24;;;6049:4;6016:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;6012:227;;6227:1;6220:8;;;;;;6012:227;6096:17;6116:38;6138:6;6146:7;6116:21;;;:38;;:::i;:::-;6096:58;;6187:1;6175:9;:13;;;;:::i;:::-;6168:20;;;;;;5078:1167;;;;:::o;6323:301::-;6403:7;6449:13;6465:17;6476:5;6465:10;;;:17;;:::i;:::-;6449:33;;6504:1;6496:5;:9;;;6492:126;;;6528:36;6550:5;6557:6;6528:21;;;:36;;:::i;:::-;6521:43;;;;;6492:126;6602:5;6595:12;;;;;6323:301;;;;;:::o;6691:351::-;6744:7;6797:13;6855:26;6875:5;6855:19;;;:26;;:::i;:::-;6847:34;;6903:1;6895:5;:9;;;6891:52;;;6927:5;6920:12;;;;;6891:52;6987:26;7007:5;6987:19;;;:26;;:::i;:::-;6979:34;;7030:5;7023:12;;;6691:351;;;;:::o;369:626:28:-;430:7;482:1;477;:6;:16;;;;492:1;487;:6;;;477:16;473:63;;;520:1;513:8;;;;473:63;550:10;622:2;582:34;578:1;:38;572:1;564:10;;:53;563:61;;550:74;;638:10;670:3;665:1;:8;;659:1;651:10;;:23;638:36;;698:50;693:2;:55;689:102;;;775:1;768:8;;;;;;689:102;811:2;804:9;;;;;906:2;837:66;:71;832:2;:76;828:123;;;935:1;928:8;;;;;;828:123;976:2;971;:7;964:14;;;;369:626;;;;;:::o;7048:1376:33:-;7110:13;7159:19;7214:18;;;;;;;;;;;7196:45;;;7242:5;7249:4;;;;;;;;;;;7196:58;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7159:96;;1022:1;7269:29;;7277:4;7269:29;;;7265:68;;7321:1;7314:8;;;;;7265:68;7443:16;7469;7499:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;7495:197;;7680:1;7673:8;;;;;;;7495:197;7598:9;7587:20;;7632:9;7621:20;;7518:134;;;7717:1;7705:8;:13;;;:30;;;;7734:1;7722:8;:13;;;7705:30;7701:69;;;7758:1;7751:8;;;;;;;7701:69;7819:19;7840:25;7869:29;7892:5;7869:22;;;:29;;:::i;:::-;7818:80;;;;7913:20;7908:60;;7956:1;7949:8;;;;;;;;;7908:60;8021:19;8051:4;;;;;;;;;;;8043:12;;:5;:12;;;:34;;8069:8;8043:34;;;8058:8;8043:34;8021:56;;8087:20;8118:4;;;;;;;;;;;8110:12;;:5;:12;;;:34;;8136:8;8110:34;;;8125:8;8110:34;8087:57;;1070:2;8170:30;;:13;:30;;;;:182;;1070:2;8321:13;:29;;;;:::i;:::-;8314:2;:37;;;;:::i;:::-;8299:12;:52;;;;;;:::i;:::-;8170:182;;;8261:13;1070:2;8245:29;;;;:::i;:::-;8238:2;:37;;;;:::i;:::-;8223:12;:52;;;;;;:::i;:::-;8170:182;8155:197;;8370:47;8391:11;8370:47;;8404:12;8370:47;;:20;;;:47;;:::i;:::-;8362:55;;7125:1299;;;;;;;7048:1376;;;;:::o;8430:1395::-;8492:7;8511:25;:46;;;;;;;;8540:3;8511:46;;;;;;8545:4;8511:46;;;;;;8551:5;8511:46;;;;;;;8567:19;8601:9;8613:1;8601:13;;8596:339;8620:15;8616:1;:19;8596:339;;;8684:19;8755:18;;;;;;;;;;;8737:45;;;8783:5;8790:4;;;;;;;;;;;8796:8;8805:1;8796:11;;;;;;;:::i;:::-;;;;;;8737:71;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8684:125;;1022:1;8827:29;;8835:4;8827:29;;;8823:102;;8883:4;8876:11;;8905:5;;;8823:102;8642:293;8637:3;;;;;8596:339;;;;1022:1;8949:29;;8957:4;8949:29;;;8945:68;;9001:1;8994:8;;;;;;8945:68;9058:20;9092:4;:10;;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;9088:186;;9262:1;9255:8;;;;;;;9088:186;9210:13;9195:28;;9105:129;;;;;;;9284:21;9316:4;;;;;;;;;;;9308:12;;:5;:12;;;9284:36;;9331:19;9352:26;9382:29;9405:5;9382:22;;;:29;;:::i;:::-;9330:81;;;;9426:21;9421:61;;9470:1;9463:8;;;;;;;;;;9421:61;9806:2;9542:260;9586:12;9616:16;9650;:60;;1070:2;9650:60;;;9674:13;9650:60;9728:16;:60;;9774:13;9728:60;;;1070:2;9728:60;9542:26;;;:260;;:::i;:::-;:266;;9514:304;;;;;;;;8430:1395;;;;:::o;9939:762::-;10004:5;10011:4;10028:25;10055:30;10101:5;:10;;10117:5;10124:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10101:61;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10027:135;;;;10177:20;10173:522;;;10213:21;10281:2;10253:17;:24;:30;10249:388;;10332:17;10321:40;;;;;;;;;;;;:::i;:::-;10303:58;;10401:1;10384:13;:18;:41;;;;10422:3;10406:13;:19;10384:41;10380:187;;;10457:1;10460:5;10449:17;;;;;;;;;10380:187;10527:13;10543:4;10513:35;;;;;;;;;10249:388;10613:1;10616:5;10605:17;;;;;;;;;10173:522;10675:1;10678:5;10667:17;;;;;;9939:762;;;;:::o;1190:2514:28:-;1250:7;1302:1;1297;:6;1293:20;;1312:1;1305:8;;;;1293:20;1328:14;1366:50;1361:1;:55;1357:1967;;1457:1;1451:2;1446:1;:7;;1445:13;;;;;:::i;:::-;;;1436:22;;1357:1967;;;1497:11;1511:3;1497:17;;1532:10;1550:3;1545:1;:8;;1532:21;;1581:11;1575:2;:17;1571:104;;1623:2;1616:9;;;;;1654:2;1647:9;;;;1571:104;1702:7;1696:2;:13;1692:100;;1740:2;1733:9;;;;;1771:2;1764:9;;;;1692:100;1819:5;1813:2;:11;1809:96;;1855:1;1848:8;;;;;1885:1;1878:8;;;;1809:96;1932:4;1926:2;:10;1922:95;;1967:1;1960:8;;;;;1997:1;1990:8;;;;1922:95;2044:3;2038:2;:9;2034:94;;2078:1;2071:8;;;;;2108:1;2101:8;;;;2034:94;2155:3;2149:2;:9;2145:23;;2167:1;2160:8;;;;2145:23;2276:1;2268:3;2262;:9;2255:1;2251;:5;2250:22;;2249:28;2240:3;2234;:9;2228:1;:16;;2227:51;;;;;:::i;:::-;;;2218:60;;2704:34;2695:6;:43;2691:98;;;2769:1;2762:8;;;;;;;2691:98;2807:10;2835:3;2830:1;:8;;2820:6;:19;2807:32;;2857:10;2884:34;2880:1;:38;2870:6;:49;2857:62;;2938:10;2956:3;2951:1;:8;;2938:21;;2977:10;2995:2;2990:1;:7;;2977:20;;3025:2;3020;:7;3016:20;;;3035:1;3029:7;;;;3016:20;3060:2;3054:8;;;;3128:3;3122:2;:9;;3117:14;;3158:2;3153;:7;3149:20;;;3168:1;3162:7;;;;3149:20;3193:2;3187:8;;;;3270:3;3264:2;:9;;3258:2;:15;3251:23;;;;:::i;:::-;;3308:1;3303:2;:6;;;;;:::i;:::-;;;3293:16;;;;1479:1845;;;;;;1357:1967;3574:34;3565:6;:43;3561:90;;;3635:1;3628:8;;;;;3561:90;3680:6;3665:22;;;1190:2514;;;;;:::o;3710:1606::-;3865:17;4094;4131:14;4114;:31;4094:51;;4256:23;4297:1;4282:12;:16;;;:174;;4443:12;4431:25;;:2;:25;4427:1;4410:12;4402:21;;:26;:54;4282:174;;;4369:12;4368:13;;4346:37;;4354:2;4346:37;4342:1;4325:12;4317:21;;:26;:66;;;;;:::i;:::-;;;4282:174;4256:200;;4480:15;117:27;4474:21;4470:68;;;4522:1;4515:8;;;;;;4470:68;4686:28;4717:16;:143;;117:27;4838:15;:21;;;;;:::i;:::-;;;4799:34;117:27;4793:40;4792:68;;;;;:::i;:::-;;;4717:143;;;117:27;4752:15;:21;;;;;:::i;:::-;;;4717:143;4686:174;;5017:16;:148;;5145:20;5017:148;;;117:27;5085:34;5061:20;5053:66;5052:74;;;;;:::i;:::-;;;5017:148;5005:160;;5196:17;5184:9;:29;5180:120;;;5284:1;5277:8;;;;;;;5180:120;3898:1412;;;3710:1606;;;;;;;:::o;91:923:34:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:143::-;753:5;784:6;778:13;769:22;;800:33;827:5;800:33;:::i;:::-;696:143;;;;:::o;845:117::-;954:1;951;944:12;968:102;1009:6;1060:2;1056:7;1051:2;1044:5;1040:14;1036:28;1026:38;;968:102;;;:::o;1076:180::-;1124:77;1121:1;1114:88;1221:4;1218:1;1211:15;1245:4;1242:1;1235:15;1262:281;1345:27;1367:4;1345:27;:::i;:::-;1337:6;1333:40;1475:6;1463:10;1460:22;1439:18;1427:10;1424:34;1421:62;1418:88;;;1486:18;;:::i;:::-;1418:88;1526:10;1522:2;1515:22;1305:238;1262:281;;:::o;1549:129::-;1583:6;1610:20;;:::i;:::-;1600:30;;1639:33;1667:4;1659:6;1639:33;:::i;:::-;1549:129;;;:::o;1684:338::-;1788:4;1878:18;1870:6;1867:30;1864:56;;;1900:18;;:::i;:::-;1864:56;1950:4;1942:6;1938:17;1930:25;;2010:4;2004;2000:15;1992:23;;1684:338;;;:::o;2028:117::-;2137:1;2134;2127:12;2151:117;2260:1;2257;2250:12;2397:113;2484:1;2477:5;2474:12;2464:40;;2500:1;2497;2490:12;2464:40;2397:113;:::o;2516:171::-;2587:5;2618:6;2612:13;2603:22;;2634:47;2675:5;2634:47;:::i;:::-;2516:171;;;;:::o;2733:634::-;2820:5;2864:4;2852:9;2847:3;2843:19;2839:30;2836:117;;;2872:79;;:::i;:::-;2836:117;2971:21;2987:4;2971:21;:::i;:::-;2962:30;;3055:1;3095:74;3165:3;3156:6;3145:9;3141:22;3095:74;:::i;:::-;3088:4;3081:5;3077:16;3070:100;3002:179;3247:2;3288:60;3344:3;3335:6;3324:9;3320:22;3288:60;:::i;:::-;3281:4;3274:5;3270:16;3263:86;3191:169;2733:634;;;;:::o;3415:813::-;3549:5;3574:108;3590:91;3674:6;3590:91;:::i;:::-;3574:108;:::i;:::-;3565:117;;3702:5;3731:6;3724:5;3717:21;3765:4;3758:5;3754:16;3747:23;;3818:4;3810:6;3806:17;3798:6;3794:30;3847:3;3839:6;3836:15;3833:122;;;3866:79;;:::i;:::-;3833:122;3981:6;3964:258;3998:6;3993:3;3990:15;3964:258;;;4073:3;4102:75;4173:3;4161:10;4102:75;:::i;:::-;4097:3;4090:88;4207:4;4202:3;4198:14;4191:21;;4040:182;4024:4;4019:3;4015:14;4008:21;;3964:258;;;3968:21;3555:673;;3415:813;;;;;:::o;4276:439::-;4385:5;4434:3;4427:4;4419:6;4415:17;4411:27;4401:122;;4442:79;;:::i;:::-;4401:122;4552:6;4546:13;4577:132;4705:3;4697:6;4690:4;4682:6;4678:17;4577:132;:::i;:::-;4568:141;;4391:324;4276:439;;;;:::o;4721:1077::-;4870:6;4878;4886;4894;4943:3;4931:9;4922:7;4918:23;4914:33;4911:120;;;4950:79;;:::i;:::-;4911:120;5070:1;5095:64;5151:7;5142:6;5131:9;5127:22;5095:64;:::i;:::-;5085:74;;5041:128;5208:2;5234:64;5290:7;5281:6;5270:9;5266:22;5234:64;:::i;:::-;5224:74;;5179:129;5347:2;5373:64;5429:7;5420:6;5409:9;5405:22;5373:64;:::i;:::-;5363:74;;5318:129;5507:2;5496:9;5492:18;5486:25;5538:18;5530:6;5527:30;5524:117;;;5560:79;;:::i;:::-;5524:117;5665:116;5773:7;5764:6;5753:9;5749:22;5665:116;:::i;:::-;5655:126;;5457:334;4721:1077;;;;;;;:::o;5804:147::-;5904:6;5938:5;5932:12;5922:22;;5804:147;;;:::o;5957:217::-;6089:11;6123:6;6118:3;6111:19;6163:4;6158:3;6154:14;6139:29;;5957:217;;;;:::o;6180:165::-;6280:4;6303:3;6295:11;;6333:4;6328:3;6324:14;6316:22;;6180:165;;;:::o;6351:180::-;6399:77;6396:1;6389:88;6496:4;6493:1;6486:15;6520:4;6517:1;6510:15;6537:119;6624:1;6617:5;6614:12;6604:46;;6630:18;;:::i;:::-;6604:46;6537:119;:::o;6662:139::-;6713:7;6742:5;6731:16;;6748:47;6789:5;6748:47;:::i;:::-;6662:139;;;:::o;6807:::-;6869:9;6902:38;6934:5;6902:38;:::i;:::-;6889:51;;6807:139;;;:::o;6952:145::-;7041:49;7084:5;7041:49;:::i;:::-;7036:3;7029:62;6952:145;;:::o;7103:108::-;7180:24;7198:5;7180:24;:::i;:::-;7175:3;7168:37;7103:108;;:::o;7217:77::-;7254:7;7283:5;7272:16;;7217:77;;;:::o;7300:108::-;7377:24;7395:5;7377:24;:::i;:::-;7372:3;7365:37;7300:108;;:::o;7502:715::-;7655:4;7650:3;7646:14;7746:4;7739:5;7735:16;7729:23;7765:75;7834:4;7829:3;7825:14;7811:12;7765:75;:::i;:::-;7670:180;7939:4;7932:5;7928:16;7922:23;7958:63;8015:4;8010:3;8006:14;7992:12;7958:63;:::i;:::-;7860:171;8118:4;8111:5;8107:16;8101:23;8137:63;8194:4;8189:3;8185:14;8171:12;8137:63;:::i;:::-;8041:169;7624:593;7502:715;;:::o;8223:311::-;8358:10;8379:112;8487:3;8479:6;8379:112;:::i;:::-;8523:4;8518:3;8514:14;8500:28;;8223:311;;;;:::o;8540:146::-;8643:4;8675;8670:3;8666:14;8658:22;;8540:146;;;:::o;8784:996::-;8969:3;8998:87;9079:5;8998:87;:::i;:::-;9101:119;9213:6;9208:3;9101:119;:::i;:::-;9094:126;;9244:89;9327:5;9244:89;:::i;:::-;9356:7;9387:1;9372:383;9397:6;9394:1;9391:13;9372:383;;;9473:6;9467:13;9500:129;9625:3;9610:13;9500:129;:::i;:::-;9493:136;;9652:93;9738:6;9652:93;:::i;:::-;9642:103;;9432:323;9419:1;9416;9412:9;9407:14;;9372:383;;;9376:14;9771:3;9764:10;;8974:806;;;8784:996;;;;:::o;9786:505::-;9995:4;10033:2;10022:9;10018:18;10010:26;;10082:9;10076:4;10072:20;10068:1;10057:9;10053:17;10046:47;10110:174;10279:4;10270:6;10110:174;:::i;:::-;10102:182;;9786:505;;;;:::o;10297:180::-;10345:77;10342:1;10335:88;10442:4;10439:1;10432:15;10466:4;10463:1;10456:15;10483:311;10560:4;10650:18;10642:6;10639:30;10636:56;;;10672:18;;:::i;:::-;10636:56;10722:4;10714:6;10710:17;10702:25;;10782:4;10776;10772:15;10764:23;;10483:311;;;:::o;10817:732::-;10924:5;10949:81;10965:64;11022:6;10965:64;:::i;:::-;10949:81;:::i;:::-;10940:90;;11050:5;11079:6;11072:5;11065:21;11113:4;11106:5;11102:16;11095:23;;11166:4;11158:6;11154:17;11146:6;11142:30;11195:3;11187:6;11184:15;11181:122;;;11214:79;;:::i;:::-;11181:122;11329:6;11312:231;11346:6;11341:3;11338:15;11312:231;;;11421:3;11450:48;11494:3;11482:10;11450:48;:::i;:::-;11445:3;11438:61;11528:4;11523:3;11519:14;11512:21;;11388:155;11372:4;11367:3;11363:14;11356:21;;11312:231;;;11316:21;10930:619;;10817:732;;;;;:::o;11572:385::-;11654:5;11703:3;11696:4;11688:6;11684:17;11680:27;11670:122;;11711:79;;:::i;:::-;11670:122;11821:6;11815:13;11846:105;11947:3;11939:6;11932:4;11924:6;11920:17;11846:105;:::i;:::-;11837:114;;11660:297;11572:385;;;;:::o;11963:554::-;12058:6;12107:2;12095:9;12086:7;12082:23;12078:32;12075:119;;;12113:79;;:::i;:::-;12075:119;12254:1;12243:9;12239:17;12233:24;12284:18;12276:6;12273:30;12270:117;;;12306:79;;:::i;:::-;12270:117;12411:89;12492:7;12483:6;12472:9;12468:22;12411:89;:::i;:::-;12401:99;;12204:306;11963:554;;;;:::o;12523:118::-;12610:24;12628:5;12610:24;:::i;:::-;12605:3;12598:37;12523:118;;:::o;12647:222::-;12740:4;12778:2;12767:9;12763:18;12755:26;;12791:71;12859:1;12848:9;12844:17;12835:6;12791:71;:::i;:::-;12647:222;;;;:::o;12875:122::-;12948:24;12966:5;12948:24;:::i;:::-;12941:5;12938:35;12928:63;;12987:1;12984;12977:12;12928:63;12875:122;:::o;13003:143::-;13060:5;13091:6;13085:13;13076:22;;13107:33;13134:5;13107:33;:::i;:::-;13003:143;;;;:::o;13152:351::-;13222:6;13271:2;13259:9;13250:7;13246:23;13242:32;13239:119;;;13277:79;;:::i;:::-;13239:119;13397:1;13422:64;13478:7;13469:6;13458:9;13454:22;13422:64;:::i;:::-;13412:74;;13368:128;13152:351;;;;:::o;13509:180::-;13557:77;13554:1;13547:88;13654:4;13651:1;13644:15;13678:4;13675:1;13668:15;13695:410;13735:7;13758:20;13776:1;13758:20;:::i;:::-;13753:25;;13792:20;13810:1;13792:20;:::i;:::-;13787:25;;13847:1;13844;13840:9;13869:30;13887:11;13869:30;:::i;:::-;13858:41;;14048:1;14039:7;14035:15;14032:1;14029:22;14009:1;14002:9;13982:83;13959:139;;14078:18;;:::i;:::-;13959:139;13743:362;13695:410;;;;:::o;14111:351::-;14181:6;14230:2;14218:9;14209:7;14205:23;14201:32;14198:119;;;14236:79;;:::i;:::-;14198:119;14356:1;14381:64;14437:7;14428:6;14417:9;14413:22;14381:64;:::i;:::-;14371:74;;14327:128;14111:351;;;;:::o;14468:114::-;14505:7;14545:30;14538:5;14534:42;14523:53;;14468:114;;;:::o;14588:122::-;14661:24;14679:5;14661:24;:::i;:::-;14654:5;14651:35;14641:63;;14700:1;14697;14690:12;14641:63;14588:122;:::o;14716:143::-;14773:5;14804:6;14798:13;14789:22;;14820:33;14847:5;14820:33;:::i;:::-;14716:143;;;;:::o;14865:93::-;14901:7;14941:10;14934:5;14930:22;14919:33;;14865:93;;;:::o;14964:120::-;15036:23;15053:5;15036:23;:::i;:::-;15029:5;15026:34;15016:62;;15074:1;15071;15064:12;15016:62;14964:120;:::o;15090:141::-;15146:5;15177:6;15171:13;15162:22;;15193:32;15219:5;15193:32;:::i;:::-;15090:141;;;;:::o;15237:661::-;15324:6;15332;15340;15389:2;15377:9;15368:7;15364:23;15360:32;15357:119;;;15395:79;;:::i;:::-;15357:119;15515:1;15540:64;15596:7;15587:6;15576:9;15572:22;15540:64;:::i;:::-;15530:74;;15486:128;15653:2;15679:64;15735:7;15726:6;15715:9;15711:22;15679:64;:::i;:::-;15669:74;;15624:129;15792:2;15818:63;15873:7;15864:6;15853:9;15849:22;15818:63;:::i;:::-;15808:73;;15763:128;15237:661;;;;;:::o;15904:279::-;15944:7;15967:20;15985:1;15967:20;:::i;:::-;15962:25;;16001:20;16019:1;16001:20;:::i;:::-;15996:25;;16056:1;16053;16049:9;16078:30;16096:11;16078:30;:::i;:::-;16067:41;;16140:11;16131:7;16128:24;16118:58;;16156:18;;:::i;:::-;16118:58;15952:231;15904:279;;;;:::o;16189:332::-;16310:4;16348:2;16337:9;16333:18;16325:26;;16361:71;16429:1;16418:9;16414:17;16405:6;16361:71;:::i;:::-;16442:72;16510:2;16499:9;16495:18;16486:6;16442:72;:::i;:::-;16189:332;;;;;:::o;16527:86::-;16562:7;16602:4;16595:5;16591:16;16580:27;;16527:86;;;:::o;16619:191::-;16657:4;16677:18;16693:1;16677:18;:::i;:::-;16672:23;;16709:18;16725:1;16709:18;:::i;:::-;16704:23;;16751:1;16748;16744:9;16736:17;;16775:4;16769;16766:14;16763:40;;;16783:18;;:::i;:::-;16763:40;16619:191;;;;:::o;16816:102::-;16858:8;16905:5;16902:1;16898:13;16877:34;;16816:102;;;:::o;16924:848::-;16985:5;16992:4;17016:6;17007:15;;17040:5;17031:14;;17054:712;17075:1;17065:8;17062:15;17054:712;;;17170:4;17165:3;17161:14;17155:4;17152:24;17149:50;;;17179:18;;:::i;:::-;17149:50;17229:1;17219:8;17215:16;17212:451;;;17644:4;17637:5;17633:16;17624:25;;17212:451;17694:4;17688;17684:15;17676:23;;17724:32;17747:8;17724:32;:::i;:::-;17712:44;;17054:712;;;16924:848;;;;;;;:::o;17778:1073::-;17832:5;18023:8;18013:40;;18044:1;18035:10;;18046:5;;18013:40;18072:4;18062:36;;18089:1;18080:10;;18091:5;;18062:36;18158:4;18206:1;18201:27;;;;18242:1;18237:191;;;;18151:277;;18201:27;18219:1;18210:10;;18221:5;;;18237:191;18282:3;18272:8;18269:17;18266:43;;;18289:18;;:::i;:::-;18266:43;18338:8;18335:1;18331:16;18322:25;;18373:3;18366:5;18363:14;18360:40;;;18380:18;;:::i;:::-;18360:40;18413:5;;;18151:277;;18537:2;18527:8;18524:16;18518:3;18512:4;18509:13;18505:36;18487:2;18477:8;18474:16;18469:2;18463:4;18460:12;18456:35;18440:111;18437:246;;;18593:8;18587:4;18583:19;18574:28;;18628:3;18621:5;18618:14;18615:40;;;18635:18;;:::i;:::-;18615:40;18668:5;;18437:246;18708:42;18746:3;18736:8;18730:4;18727:1;18708:42;:::i;:::-;18693:57;;;;18782:4;18777:3;18773:14;18766:5;18763:25;18760:51;;;18791:18;;:::i;:::-;18760:51;18840:4;18833:5;18829:16;18820:25;;17778:1073;;;;;;:::o;18857:281::-;18915:5;18939:23;18957:4;18939:23;:::i;:::-;18931:31;;18983:25;18999:8;18983:25;:::i;:::-;18971:37;;19027:104;19064:66;19054:8;19048:4;19027:104;:::i;:::-;19018:113;;18857:281;;;;:::o;19144:180::-;19192:77;19189:1;19182:88;19289:4;19286:1;19279:15;19313:4;19310:1;19303:15;19330:185;19370:1;19387:20;19405:1;19387:20;:::i;:::-;19382:25;;19421:20;19439:1;19421:20;:::i;:::-;19416:25;;19460:1;19450:35;;19465:18;;:::i;:::-;19450:35;19507:1;19504;19500:9;19495:14;;19330:185;;;;:::o;19521:89::-;19557:7;19597:6;19590:5;19586:18;19575:29;;19521:89;;;:::o;19616:91::-;19652:7;19692:8;19685:5;19681:20;19670:31;;19616:91;;;:::o;19713:60::-;19741:3;19762:5;19755:12;;19713:60;;;:::o;19779:138::-;19827:9;19860:51;19877:33;19886:23;19903:5;19886:23;:::i;:::-;19877:33;:::i;:::-;19860:51;:::i;:::-;19847:64;;19779:138;;;:::o;19923:127::-;20008:35;20037:5;20008:35;:::i;:::-;20003:3;19996:48;19923:127;;:::o;20056:438::-;20203:4;20241:2;20230:9;20226:18;20218:26;;20254:71;20322:1;20311:9;20307:17;20298:6;20254:71;:::i;:::-;20335:72;20403:2;20392:9;20388:18;20379:6;20335:72;:::i;:::-;20417:70;20483:2;20472:9;20468:18;20459:6;20417:70;:::i;:::-;20056:438;;;;;;:::o;20500:122::-;20573:24;20591:5;20573:24;:::i;:::-;20566:5;20563:35;20553:63;;20612:1;20609;20602:12;20553:63;20500:122;:::o;20628:143::-;20685:5;20716:6;20710:13;20701:22;;20732:33;20759:5;20732:33;:::i;:::-;20628:143;;;;:::o;20777:90::-;20812:7;20855:5;20852:1;20841:20;20830:31;;20777:90;;;:::o;20873:118::-;20944:22;20960:5;20944:22;:::i;:::-;20937:5;20934:33;20924:61;;20981:1;20978;20971:12;20924:61;20873:118;:::o;20997:139::-;21052:5;21083:6;21077:13;21068:22;;21099:31;21124:5;21099:31;:::i;:::-;20997:139;;;;:::o;21142:120::-;21214:23;21231:5;21214:23;:::i;:::-;21207:5;21204:34;21194:62;;21252:1;21249;21242:12;21194:62;21142:120;:::o;21268:141::-;21324:5;21355:6;21349:13;21340:22;;21371:32;21397:5;21371:32;:::i;:::-;21268:141;;;;:::o;21415:118::-;21486:22;21502:5;21486:22;:::i;:::-;21479:5;21476:33;21466:61;;21523:1;21520;21513:12;21466:61;21415:118;:::o;21539:139::-;21594:5;21625:6;21619:13;21610:22;;21641:31;21666:5;21641:31;:::i;:::-;21539:139;;;;:::o;21684:90::-;21718:7;21761:5;21754:13;21747:21;21736:32;;21684:90;;;:::o;21780:116::-;21850:21;21865:5;21850:21;:::i;:::-;21843:5;21840:32;21830:60;;21886:1;21883;21876:12;21830:60;21780:116;:::o;21902:137::-;21956:5;21987:6;21981:13;21972:22;;22003:30;22027:5;22003:30;:::i;:::-;21902:137;;;;:::o;22045:1271::-;22159:6;22167;22175;22183;22191;22199;22207;22256:3;22244:9;22235:7;22231:23;22227:33;22224:120;;;22263:79;;:::i;:::-;22224:120;22383:1;22408:64;22464:7;22455:6;22444:9;22440:22;22408:64;:::i;:::-;22398:74;;22354:128;22521:2;22547:62;22601:7;22592:6;22581:9;22577:22;22547:62;:::i;:::-;22537:72;;22492:127;22658:2;22684:63;22739:7;22730:6;22719:9;22715:22;22684:63;:::i;:::-;22674:73;;22629:128;22796:2;22822:63;22877:7;22868:6;22857:9;22853:22;22822:63;:::i;:::-;22812:73;;22767:128;22934:3;22961:63;23016:7;23007:6;22996:9;22992:22;22961:63;:::i;:::-;22951:73;;22905:129;23073:3;23100:62;23154:7;23145:6;23134:9;23130:22;23100:62;:::i;:::-;23090:72;;23044:128;23211:3;23238:61;23291:7;23282:6;23271:9;23267:22;23238:61;:::i;:::-;23228:71;;23182:127;22045:1271;;;;;;;;;;:::o;23322:98::-;23373:6;23407:5;23401:12;23391:22;;23322:98;;;:::o;23426:147::-;23527:11;23564:3;23549:18;;23426:147;;;;:::o;23579:139::-;23668:6;23663:3;23658;23652:23;23709:1;23700:6;23695:3;23691:16;23684:27;23579:139;;;:::o;23724:386::-;23828:3;23856:38;23888:5;23856:38;:::i;:::-;23910:88;23991:6;23986:3;23910:88;:::i;:::-;23903:95;;24007:65;24065:6;24060:3;24053:4;24046:5;24042:16;24007:65;:::i;:::-;24097:6;24092:3;24088:16;24081:23;;23832:278;23724:386;;;;:::o;24116:271::-;24246:3;24268:93;24357:3;24348:6;24268:93;:::i;:::-;24261:100;;24378:3;24371:10;;24116:271;;;;:::o;24393:180::-;24441:77;24438:1;24431:88;24538:4;24535:1;24528:15;24562:4;24559:1;24552:15\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x608060405234801561000f575f5ffd5b5060043610610029575f3560e01c8063339173fd1461002d575b5f5ffd5b61004760048036038101906100429190611a7a565b61005d565b6040516100549190611c43565b60405180910390f35b60605f825167ffffffffffffffff81111561007b5761007a611870565b5b6040519080825280602002602001820160405280156100b457816020015b6100a1611805565b8152602001906001900390816100995790505b5090505f5f90505b83518110156102f4575f8482815181106100d9576100d8611c63565b5b602002602001015190505f60028111156100f6576100f5611aea565b5b815f0151600281111561010c5761010b611aea565b5b0361018f575f61011f82602001516102fe565b90506040518060600160405280835f0151600281111561014257610141611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061017e5761017d611c63565b5b6020026020010181905250506102e6565b600160028111156101a3576101a2611aea565b5b815f015160028111156101b9576101b8611aea565b5b0361023c575f6101cc8260200151610587565b90506040518060600160405280835f015160028111156101ef576101ee611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff1681526020018281525084848151811061022b5761022a611c63565b5b6020026020010181905250506102e5565b60028081111561024f5761024e611aea565b5b815f0151600281111561026557610264611aea565b5b036102e4575f6102788260200151610825565b90506040518060600160405280835f0151600281111561029b5761029a611aea565b5b8152602001836020015173ffffffffffffffffffffffffffffffffffffffff168152602001828152508484815181106102d7576102d6611c63565b5b6020026020010181905250505b5b5b5080806001019150506100bc565b5080915050919050565b5f60608273ffffffffffffffffffffffffffffffffffffffff1663cc77828d6040518163ffffffff1660e01b81526004015f604051808303815f875af192505050801561036d57506040513d5f823e3d601f19601f8201168201806040525081019061036a9190611d64565b60015b61037a575f915050610582565b809150505f5f90505b81518110156104ba5760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168282815181106103d7576103d6611c63565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036104ad578373ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f83838151811061042957610428611c63565b5b60200260200101516040518263ffffffff1660e01b815260040161044d9190611dba565b6020604051808303815f875af192505050801561048857506040513d601f19601f820116820180604052508101906104859190611dfd565b60015b610496575f92505050610582565b8251816104a39190611e55565b9350505050610582565b8080600101915050610383565b505f815f815181106104cf576104ce611c63565b5b602002602001015190505f8473ffffffffffffffffffffffffffffffffffffffff1663f8b2cb4f836040518263ffffffff1660e01b81526004016105139190611dba565b6020604051808303815f875af192505050801561054e57506040513d601f19601f8201168201806040525081019061054b9190611dfd565b60015b61055d575f9350505050610582565b809150505f61056c8383610b9a565b905083518161057b9190611e55565b9450505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156105f157506040513d601f19601f820116820180604052508101906105ee9190611e96565b60015b6105fe575f915050610820565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561066b57506040513d601f19601f820116820180604052508101906106689190611e96565b60015b610679575f92505050610820565b809150508373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa9250505080156106e557506040513d601f19601f820116820180604052508101906106e29190611f3d565b60015b6106f3575f92505050610820565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603610770576002836107549190611f8d565b6dffffffffffffffffffffffffffff1695505050505050610820565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036107ed576002826107d19190611f8d565b6dffffffffffffffffffffffffffff1695505050505050610820565b5f61080886856dffffffffffffffffffffffffffff16610b9a565b90506002816108179190611e55565b96505050505050505b919050565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561088f57506040513d601f19601f8201168201806040525081019061088c9190611e96565b60015b61089c575f915050610b95565b809150505f8373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561090957506040513d601f19601f820116820180604052508101906109069190611e96565b60015b610917575f92505050610b95565b8091505060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610a07578173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b81526004016109a89190611dba565b602060405180830381865afa9250505080156109e257506040513d601f19601f820116820180604052508101906109df9190611dfd565b60015b6109f0575f92505050610b95565b6002816109fd9190611e55565b9350505050610b95565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610af3578073ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610a949190611dba565b602060405180830381865afa925050508015610ace57506040513d601f19601f82011682018060405250810190610acb9190611dfd565b60015b610adc575f92505050610b95565b600281610ae99190611e55565b9350505050610b95565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b8152600401610b2c9190611dba565b602060405180830381865afa925050508015610b6657506040513d601f19601f82011682018060405250810190610b639190611dfd565b60015b610b74575f92505050610b95565b5f610b7f8483610b9a565b9050600281610b8e9190611e55565b9450505050505b919050565b5f5f610ba584610bf0565b90505f816fffffffffffffffffffffffffffffffff161115610bd357610bcb8184610c35565b915050610bea565b806fffffffffffffffffffffffffffffffff169150505b92915050565b5f5f610bfb83610d1f565b90505f816fffffffffffffffffffffffffffffffff161115610c205780915050610c30565b610c2983611070565b9050809150505b919050565b5f5f821480610c5557505f836fffffffffffffffffffffffffffffffff16145b15610c62575f9050610d19565b5f60406fffffffffffffffffffffffffffffffff8416856fffffffffffffffffffffffffffffffff1602901c90505f608084901c856fffffffffffffffffffffffffffffffff1602905077ffffffffffffffffffffffffffffffffffffffffffffffff811115610cd6575f92505050610d19565b604081901b9050817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03811115610d11575f92505050610d19565b818101925050505b92915050565b5f5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a439058460025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401610d9d929190611fc9565b602060405180830381865afa158015610db8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddc9190611e96565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610e1a575f91505061106b565b5f5f8273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa925050508015610e8457506040513d601f19601f82011682018060405250810190610e819190611f3d565b60015b610e93575f935050505061106b565b8294508193505050505f826dffffffffffffffffffffffffffff161480610ec957505f816dffffffffffffffffffffffffffff16145b15610ed9575f935050505061106b565b5f5f610ee48761133d565b9150915080610efa575f9550505050505061106b565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1610610f555784610f57565b835b90505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1610610fb45784610fb6565b855b9050601260ff168460ff16111561100057601284610fd49190611ffc565b600a610fe0919061215f565b816dffffffffffffffffffffffffffff16610ffb91906121d6565b611035565b83601261100d9190611ffc565b600a611019919061215f565b816dffffffffffffffffffffffffffff166110349190611e55565b5b9050611061826dffffffffffffffffffffffffffff16826dffffffffffffffffffffffffffff166114a1565b9750505050505050505b919050565b5f5f60405180606001604052806101f461ffff168152602001610bb861ffff16815260200161271061ffff1681525090505f5f5f90505b60038110156111d0575f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631698ee828760025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687866003811061112457611123611c63565b5b60200201516040518463ffffffff1660e01b81526004016111479392919061225a565b602060405180830381865afa158015611162573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111869190611e96565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146111c457809250506111d0565b508060010190506110a7565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361120e575f92505050611338565b5f8173ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa92505050801561127757506040513d601f19601f820116820180604052508101906112749190612378565b60015b611286575f9350505050611338565b869750505050505050505f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161090505f5f6112ee8861133d565b9150915080611305575f9650505050505050611338565b604061132d85858661131857601261131a565b855b876113255786611328565b60125b611683565b901c96505050505050505b919050565b5f5f5f5f8473ffffffffffffffffffffffffffffffffffffffff16614e206040516024016040516020818303038152906040527f313ce567000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516113eb9190612467565b5f604051808303815f8787f1925050503d805f8114611425576040519150601f19603f3d011682016040523d82523d5f602084013e61142a565b606091505b50915091508115611493575f602082510361148557818060200190518101906114539190611dfd565b90505f811480611463575060ff81115b15611476575f5f9450945050505061149c565b8060019450945050505061149c565b5f5f9450945050505061149c565b5f5f9350935050505b915091565b5f5f82036114b1575f905061167d565b5f77ffffffffffffffffffffffffffffffffffffffffffffffff84116114ed5782604085901b816114e5576114e46121a9565b5b049050611657565b5f60c090505f60c086901c9050640100000000811061151457602081901c90506020820191505b62010000811061152c57601081901c90506010820191505b610100811061154357600881901c90506008820191505b6010811061155957600481901c90506004820191505b6004811061156f57600281901c90506002820191505b6002811061157e576001820191505b600160bf830360018703901c018260ff0387901b816115a05761159f6121a9565b5b0492506fffffffffffffffffffffffffffffffff8311156115c6575f935050505061167d565b5f608086901c840290505f6fffffffffffffffffffffffffffffffff8716850290505f60c089901c90505f60408a901b905082811015611607576001820391505b8281039050608084901b925082811015611622576001820391505b8281039050608084901c821461163b5761163a61247d565b5b88818161164b5761164a6121a9565b5b04870196505050505050505b6fffffffffffffffffffffffffffffffff811115611678575f91505061167d565b809150505b92915050565b5f5f82840390505f5f825f0b126116bb578160ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a026116ee565b815f0360ff16600a0a60028873ffffffffffffffffffffffffffffffffffffffff160a816116ec576116eb6121a9565b5b045b9050806c01000000000000000000000000111561170f575f925050506117fd565b5f86611767576c010000000000000000000000008281611732576117316121a9565b5b046fffffffffffffffffffffffffffffffff6c010000000000000000000000000281611761576117606121a9565b5b04611786565b6c010000000000000000000000008281611784576117836121a9565b5b045b90508661179357806117c4565b6c010000000000000000000000006fffffffffffffffffffffffffffffffff8202816117c2576117c16121a9565b5b045b93507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8411156117f9575f93505050506117fd565b5050505b949350505050565b60405180606001604052805f600281111561182357611822611aea565b5b81526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81525090565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6118a682611860565b810181811067ffffffffffffffff821117156118c5576118c4611870565b5b80604052505050565b5f6118d761184b565b90506118e3828261189d565b919050565b5f67ffffffffffffffff82111561190257611901611870565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b60038110611927575f5ffd5b50565b5f813590506119388161191b565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6119678261193e565b9050919050565b6119778161195d565b8114611981575f5ffd5b50565b5f813590506119928161196e565b92915050565b5f604082840312156119ad576119ac611917565b5b6119b760406118ce565b90505f6119c68482850161192a565b5f8301525060206119d984828501611984565b60208301525092915050565b5f6119f76119f2846118e8565b6118ce565b90508083825260208201905060408402830185811115611a1a57611a19611913565b5b835b81811015611a435780611a2f8882611998565b845260208401935050604081019050611a1c565b5050509392505050565b5f82601f830112611a6157611a6061185c565b5b8135611a718482602086016119e5565b91505092915050565b5f60208284031215611a8f57611a8e611854565b5b5f82013567ffffffffffffffff811115611aac57611aab611858565b5b611ab884828501611a4d565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110611b2857611b27611aea565b5b50565b5f819050611b3882611b17565b919050565b5f611b4782611b2b565b9050919050565b611b5781611b3d565b82525050565b611b668161195d565b82525050565b5f819050919050565b611b7e81611b6c565b82525050565b606082015f820151611b985f850182611b4e565b506020820151611bab6020850182611b5d565b506040820151611bbe6040850182611b75565b50505050565b5f611bcf8383611b84565b60608301905092915050565b5f602082019050919050565b5f611bf182611ac1565b611bfb8185611acb565b9350611c0683611adb565b805f5b83811015611c36578151611c1d8882611bc4565b9750611c2883611bdb565b925050600181019050611c09565b5085935050505092915050565b5f6020820190508181035f830152611c5b8184611be7565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f67ffffffffffffffff821115611caa57611ca9611870565b5b602082029050602081019050919050565b5f81519050611cc98161196e565b92915050565b5f611ce1611cdc84611c90565b6118ce565b90508083825260208201905060208402830185811115611d0457611d03611913565b5b835b81811015611d2d5780611d198882611cbb565b845260208401935050602081019050611d06565b5050509392505050565b5f82601f830112611d4b57611d4a61185c565b5b8151611d5b848260208601611ccf565b91505092915050565b5f60208284031215611d7957611d78611854565b5b5f82015167ffffffffffffffff811115611d9657611d95611858565b5b611da284828501611d37565b91505092915050565b611db48161195d565b82525050565b5f602082019050611dcd5f830184611dab565b92915050565b611ddc81611b6c565b8114611de6575f5ffd5b50565b5f81519050611df781611dd3565b92915050565b5f60208284031215611e1257611e11611854565b5b5f611e1f84828501611de9565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611e5f82611b6c565b9150611e6a83611b6c565b9250828202611e7881611b6c565b91508282048414831517611e8f57611e8e611e28565b5b5092915050565b5f60208284031215611eab57611eaa611854565b5b5f611eb884828501611cbb565b91505092915050565b5f6dffffffffffffffffffffffffffff82169050919050565b611ee381611ec1565b8114611eed575f5ffd5b50565b5f81519050611efe81611eda565b92915050565b5f63ffffffff82169050919050565b611f1c81611f04565b8114611f26575f5ffd5b50565b5f81519050611f3781611f13565b92915050565b5f5f5f60608486031215611f5457611f53611854565b5b5f611f6186828701611ef0565b9350506020611f7286828701611ef0565b9250506040611f8386828701611f29565b9150509250925092565b5f611f9782611ec1565b9150611fa283611ec1565b9250828202611fb081611ec1565b9150808214611fc257611fc1611e28565b5b5092915050565b5f604082019050611fdc5f830185611dab565b611fe96020830184611dab565b9392505050565b5f60ff82169050919050565b5f61200682611ff0565b915061201183611ff0565b9250828203905060ff81111561202a57612029611e28565b5b92915050565b5f8160011c9050919050565b5f5f8291508390505b60018511156120855780860481111561206157612060611e28565b5b60018516156120705780820291505b808102905061207e85612030565b9450612045565b94509492505050565b5f8261209d5760019050612158565b816120aa575f9050612158565b81600181146120c057600281146120ca576120f9565b6001915050612158565b60ff8411156120dc576120db611e28565b5b8360020a9150848211156120f3576120f2611e28565b5b50612158565b5060208310610133831016604e8410600b841016171561212e5782820a90508381111561212957612128611e28565b5b612158565b61213b848484600161203c565b9250905081840481111561215257612151611e28565b5b81810290505b9392505050565b5f61216982611b6c565b915061217483611ff0565b92506121a17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461208e565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6121e082611b6c565b91506121eb83611b6c565b9250826121fb576121fa6121a9565b5b828204905092915050565b5f61ffff82169050919050565b5f62ffffff82169050919050565b5f819050919050565b5f61224461223f61223a84612206565b612221565b612213565b9050919050565b6122548161222a565b82525050565b5f60608201905061226d5f830186611dab565b61227a6020830185611dab565b612287604083018461224b565b949350505050565b6122988161193e565b81146122a2575f5ffd5b50565b5f815190506122b38161228f565b92915050565b5f8160020b9050919050565b6122ce816122b9565b81146122d8575f5ffd5b50565b5f815190506122e9816122c5565b92915050565b6122f881612206565b8114612302575f5ffd5b50565b5f81519050612313816122ef565b92915050565b61232281611ff0565b811461232c575f5ffd5b50565b5f8151905061233d81612319565b92915050565b5f8115159050919050565b61235781612343565b8114612361575f5ffd5b50565b5f815190506123728161234e565b92915050565b5f5f5f5f5f5f5f60e0888a03121561239357612392611854565b5b5f6123a08a828b016122a5565b97505060206123b18a828b016122db565b96505060406123c28a828b01612305565b95505060606123d38a828b01612305565b94505060806123e48a828b01612305565b93505060a06123f58a828b0161232f565b92505060c06124068a828b01612364565b91505092959891949750929550565b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f61244182612415565b61244b818561241f565b935061245b818560208601612429565b80840191505092915050565b5f6124728284612437565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffdfea164736f6c634300081c000a\",\"sourceMap\":\"91:923:34:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1908:1035:33;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;1978:23;2013:39;2076:5;:12;2055:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2013:76;;2104:9;2116:1;2104:13;;2099:806;2123:5;:12;2119:1;:16;2099:806;;;2156:20;2179:5;2185:1;2179:8;;;;;;;;:::i;:::-;;;;;;;;2156:31;;2222:17;2205:34;;;;;;;;:::i;:::-;;:4;:13;;;:34;;;;;;;;:::i;:::-;;;2201:694;;2259:17;2279:36;2298:4;:16;;;2279:18;:36::i;:::-;2259:56;;2354:58;;;;;;;;2369:4;:13;;;2354:58;;;;;;;;:::i;:::-;;;;;;2384:4;:16;;;2354:58;;;;;;2402:9;2354:58;;;2333:15;2349:1;2333:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2241:186;2201:694;;;2454:18;2437:35;;;;;;;;:::i;:::-;;:4;:13;;;:35;;;;;;;;:::i;:::-;;;2433:462;;2492:17;2512:37;2532:4;:16;;;2512:19;:37::i;:::-;2492:57;;2588:58;;;;;;;;2603:4;:13;;;2588:58;;;;;;;;:::i;:::-;;;;;;2618:4;:16;;;2588:58;;;;;;2636:9;2588:58;;;2567:15;2583:1;2567:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2474:187;2433:462;;;2688:18;2671:35;;;;;;;;:::i;:::-;;:4;:13;;;:35;;;;;;;;:::i;:::-;;;2667:228;;2726:17;2746:37;2766:4;:16;;;2746:19;:37::i;:::-;2726:57;;2822:58;;;;;;;;2837:4;:13;;;2822:58;;;;;;;;:::i;:::-;;;;;;2852:4;:16;;;2822:58;;;;;;2870:9;2822:58;;;2801:15;2817:1;2801:18;;;;;;;;:::i;:::-;;;;;;;:79;;;;2708:187;2667:228;2433:462;2201:694;2142:763;2137:3;;;;;;;2099:806;;;;2921:15;2914:22;;;1908:1035;;;:::o;2949:1221::-;3009:7;3055:23;3099:4;3092:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3088:152;;3228:1;3221:8;;;;;3088:152;3182:7;3173:16;;3124:76;3359:9;3371:1;3359:13;;3354:473;3378:6;:13;3374:1;:17;3354:473;;;3429:4;;;;;;;;;;;3416:17;;:6;3423:1;3416:9;;;;;;;;:::i;:::-;;;;;;;;:17;;;3412:405;;3464:4;3457:23;;;3481:6;3488:1;3481:9;;;;;;;;:::i;:::-;;;;;;;;3457:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3453:350;;3783:1;3776:8;;;;;;3453:350;3715:6;:13;3704:8;:24;;;;:::i;:::-;3697:31;;;;;;;3412:405;3393:3;;;;;;;3354:473;;;;3837:17;3857:6;3864:1;3857:9;;;;;;;;:::i;:::-;;;;;;;;3837:29;;3876:15;3912:4;3905:23;;;3929:9;3905:34;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;3901:149;;4038:1;4031:8;;;;;;;3901:149;3991:8;3981:18;;3940:70;4060:17;4080:41;4102:9;4113:7;4080:21;:41::i;:::-;4060:61;;4150:6;:13;4138:9;:25;;;;:::i;:::-;4131:32;;;;;;2949:1221;;;;:::o;4176:896::-;4237:7;4256:14;4299:4;4284:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4280:141;;4409:1;4402:8;;;;;4280:141;4363:7;4354:16;;4314:67;4430:14;4473:4;4458:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4454:141;;4583:1;4576:8;;;;;;4454:141;4537:7;4528:16;;4488:67;4623:4;4608:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;4604:462;;5054:1;5047:8;;;;;;4604:462;4724:4;;;;;;;;;;;4714:14;;:6;:14;;;4710:150;;4766:1;4755:8;:12;;;;:::i;:::-;4748:19;;;;;;;;;;;4710:150;4802:4;;;;;;;;;;;4792:14;;:6;:14;;;4788:72;;4844:1;4833:8;:12;;;;:::i;:::-;4826:19;;;;;;;;;;;4788:72;4922:17;4942:39;4964:6;4972:8;4942:39;;:21;:39::i;:::-;4922:59;;5014:1;5002:9;:13;;;;:::i;:::-;4995:20;;;;;;;;4176:896;;;;:::o;5078:1167::-;5139:7;5158:14;5209:4;5186:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5182:150;;5320:1;5313:8;;;;;5182:150;5274:7;5265:16;;5225:67;5341:14;5392:4;5369:36;;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5365:150;;5503:1;5496:8;;;;;;5365:150;5457:7;5448:16;;5408:67;5539:4;;;;;;;;;;;5529:14;;:6;:14;;;5525:432;;5570:6;5563:24;;;5596:4;5563:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5559:169;;5712:1;5705:8;;;;;;5559:169;5664:1;5654:7;:11;;;;:::i;:::-;5647:18;;;;;;;5525:432;5758:4;;;;;;;;;;;5748:14;;:6;:14;;;5744:213;;5789:6;5782:24;;;5815:4;5782:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;5778:169;;5931:1;5924:8;;;;;;5778:169;5883:1;5873:7;:11;;;;:::i;:::-;5866:18;;;;;;;5744:213;6023:6;6016:24;;;6049:4;6016:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;6012:227;;6227:1;6220:8;;;;;;6012:227;6096:17;6116:38;6138:6;6146:7;6116:21;:38::i;:::-;6096:58;;6187:1;6175:9;:13;;;;:::i;:::-;6168:20;;;;;;5078:1167;;;;:::o;6323:301::-;6403:7;6449:13;6465:17;6476:5;6465:10;:17::i;:::-;6449:33;;6504:1;6496:5;:9;;;6492:126;;;6528:36;6550:5;6557:6;6528:21;:36::i;:::-;6521:43;;;;;6492:126;6602:5;6595:12;;;;;6323:301;;;;;:::o;6691:351::-;6744:7;6797:13;6855:26;6875:5;6855:19;:26::i;:::-;6847:34;;6903:1;6895:5;:9;;;6891:52;;;6927:5;6920:12;;;;;6891:52;6987:26;7007:5;6987:19;:26::i;:::-;6979:34;;7030:5;7023:12;;;6691:351;;;;:::o;369:626:28:-;430:7;482:1;477;:6;:16;;;;492:1;487;:6;;;477:16;473:63;;;520:1;513:8;;;;473:63;550:10;622:2;582:34;578:1;:38;572:1;564:10;;:53;563:61;;550:74;;638:10;670:3;665:1;:8;;659:1;651:10;;:23;638:36;;698:50;693:2;:55;689:102;;;775:1;768:8;;;;;;689:102;811:2;804:9;;;;;906:2;837:66;:71;832:2;:76;828:123;;;935:1;928:8;;;;;;828:123;976:2;971;:7;964:14;;;;369:626;;;;;:::o;7048:1376:33:-;7110:13;7159:19;7214:18;;;;;;;;;;;7196:45;;;7242:5;7249:4;;;;;;;;;;;7196:58;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7159:96;;1022:1;7269:29;;7277:4;7269:29;;;7265:68;;7321:1;7314:8;;;;;7265:68;7443:16;7469;7499:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;7495:197;;7680:1;7673:8;;;;;;;7495:197;7598:9;7587:20;;7632:9;7621:20;;7518:134;;;7717:1;7705:8;:13;;;:30;;;;7734:1;7722:8;:13;;;7705:30;7701:69;;;7758:1;7751:8;;;;;;;7701:69;7819:19;7840:25;7869:29;7892:5;7869:22;:29::i;:::-;7818:80;;;;7913:20;7908:60;;7956:1;7949:8;;;;;;;;;7908:60;8021:19;8051:4;;;;;;;;;;;8043:12;;:5;:12;;;:34;;8069:8;8043:34;;;8058:8;8043:34;8021:56;;8087:20;8118:4;;;;;;;;;;;8110:12;;:5;:12;;;:34;;8136:8;8110:34;;;8125:8;8110:34;8087:57;;1070:2;8170:30;;:13;:30;;;;:182;;1070:2;8321:13;:29;;;;:::i;:::-;8314:2;:37;;;;:::i;:::-;8299:12;:52;;;;;;:::i;:::-;8170:182;;;8261:13;1070:2;8245:29;;;;:::i;:::-;8238:2;:37;;;;:::i;:::-;8223:12;:52;;;;;;:::i;:::-;8170:182;8155:197;;8370:47;8391:11;8370:47;;8404:12;8370:47;;:20;:47::i;:::-;8362:55;;7125:1299;;;;;;;7048:1376;;;;:::o;8430:1395::-;8492:7;8511:25;:46;;;;;;;;8540:3;8511:46;;;;;;8545:4;8511:46;;;;;;8551:5;8511:46;;;;;;;8567:19;8601:9;8613:1;8601:13;;8596:339;8620:15;8616:1;:19;8596:339;;;8684:19;8755:18;;;;;;;;;;;8737:45;;;8783:5;8790:4;;;;;;;;;;;8796:8;8805:1;8796:11;;;;;;;:::i;:::-;;;;;;8737:71;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8684:125;;1022:1;8827:29;;8835:4;8827:29;;;8823:102;;8883:4;8876:11;;8905:5;;;8823:102;8642:293;8637:3;;;;;8596:339;;;;1022:1;8949:29;;8957:4;8949:29;;;8945:68;;9001:1;8994:8;;;;;;8945:68;9058:20;9092:4;:10;;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;9088:186;;9262:1;9255:8;;;;;;;9088:186;9210:13;9195:28;;9105:129;;;;;;;9284:21;9316:4;;;;;;;;;;;9308:12;;:5;:12;;;9284:36;;9331:19;9352:26;9382:29;9405:5;9382:22;:29::i;:::-;9330:81;;;;9426:21;9421:61;;9470:1;9463:8;;;;;;;;;;9421:61;9806:2;9542:260;9586:12;9616:16;9650;:60;;1070:2;9650:60;;;9674:13;9650:60;9728:16;:60;;9774:13;9728:60;;;1070:2;9728:60;9542:26;:260::i;:::-;:266;;9514:304;;;;;;;;8430:1395;;;;:::o;9939:762::-;10004:5;10011:4;10028:25;10055:30;10101:5;:10;;10117:5;10124:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10101:61;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10027:135;;;;10177:20;10173:522;;;10213:21;10281:2;10253:17;:24;:30;10249:388;;10332:17;10321:40;;;;;;;;;;;;:::i;:::-;10303:58;;10401:1;10384:13;:18;:41;;;;10422:3;10406:13;:19;10384:41;10380:187;;;10457:1;10460:5;10449:17;;;;;;;;;10380:187;10527:13;10543:4;10513:35;;;;;;;;;10249:388;10613:1;10616:5;10605:17;;;;;;;;;10173:522;10675:1;10678:5;10667:17;;;;;;9939:762;;;;:::o;1190:2514:28:-;1250:7;1302:1;1297;:6;1293:20;;1312:1;1305:8;;;;1293:20;1328:14;1366:50;1361:1;:55;1357:1967;;1457:1;1451:2;1446:1;:7;;1445:13;;;;;:::i;:::-;;;1436:22;;1357:1967;;;1497:11;1511:3;1497:17;;1532:10;1550:3;1545:1;:8;;1532:21;;1581:11;1575:2;:17;1571:104;;1623:2;1616:9;;;;;1654:2;1647:9;;;;1571:104;1702:7;1696:2;:13;1692:100;;1740:2;1733:9;;;;;1771:2;1764:9;;;;1692:100;1819:5;1813:2;:11;1809:96;;1855:1;1848:8;;;;;1885:1;1878:8;;;;1809:96;1932:4;1926:2;:10;1922:95;;1967:1;1960:8;;;;;1997:1;1990:8;;;;1922:95;2044:3;2038:2;:9;2034:94;;2078:1;2071:8;;;;;2108:1;2101:8;;;;2034:94;2155:3;2149:2;:9;2145:23;;2167:1;2160:8;;;;2145:23;2276:1;2268:3;2262;:9;2255:1;2251;:5;2250:22;;2249:28;2240:3;2234;:9;2228:1;:16;;2227:51;;;;;:::i;:::-;;;2218:60;;2704:34;2695:6;:43;2691:98;;;2769:1;2762:8;;;;;;;2691:98;2807:10;2835:3;2830:1;:8;;2820:6;:19;2807:32;;2857:10;2884:34;2880:1;:38;2870:6;:49;2857:62;;2938:10;2956:3;2951:1;:8;;2938:21;;2977:10;2995:2;2990:1;:7;;2977:20;;3025:2;3020;:7;3016:20;;;3035:1;3029:7;;;;3016:20;3060:2;3054:8;;;;3128:3;3122:2;:9;;3117:14;;3158:2;3153;:7;3149:20;;;3168:1;3162:7;;;;3149:20;3193:2;3187:8;;;;3270:3;3264:2;:9;;3258:2;:15;3251:23;;;;:::i;:::-;;3308:1;3303:2;:6;;;;;:::i;:::-;;;3293:16;;;;1479:1845;;;;;;1357:1967;3574:34;3565:6;:43;3561:90;;;3635:1;3628:8;;;;;3561:90;3680:6;3665:22;;;1190:2514;;;;;:::o;3710:1606::-;3865:17;4094;4131:14;4114;:31;4094:51;;4256:23;4297:1;4282:12;:16;;;:174;;4443:12;4431:25;;:2;:25;4427:1;4410:12;4402:21;;:26;:54;4282:174;;;4369:12;4368:13;;4346:37;;4354:2;4346:37;4342:1;4325:12;4317:21;;:26;:66;;;;;:::i;:::-;;;4282:174;4256:200;;4480:15;117:27;4474:21;4470:68;;;4522:1;4515:8;;;;;;4470:68;4686:28;4717:16;:143;;117:27;4838:15;:21;;;;;:::i;:::-;;;4799:34;117:27;4793:40;4792:68;;;;;:::i;:::-;;;4717:143;;;117:27;4752:15;:21;;;;;:::i;:::-;;;4717:143;4686:174;;5017:16;:148;;5145:20;5017:148;;;117:27;5085:34;5061:20;5053:66;5052:74;;;;;:::i;:::-;;;5017:148;5005:160;;5196:17;5184:9;:29;5180:120;;;5284:1;5277:8;;;;;;;5180:120;3898:1412;;;3710:1606;;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::o;7:75:41:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:102;498:6;549:2;545:7;540:2;533:5;529:14;525:28;515:38;;457:102;;;:::o;565:180::-;613:77;610:1;603:88;710:4;707:1;700:15;734:4;731:1;724:15;751:281;834:27;856:4;834:27;:::i;:::-;826:6;822:40;964:6;952:10;949:22;928:18;916:10;913:34;910:62;907:88;;;975:18;;:::i;:::-;907:88;1015:10;1011:2;1004:22;794:238;751:281;;:::o;1038:129::-;1072:6;1099:20;;:::i;:::-;1089:30;;1128:33;1156:4;1148:6;1128:33;:::i;:::-;1038:129;;;:::o;1173:338::-;1277:4;1367:18;1359:6;1356:30;1353:56;;;1389:18;;:::i;:::-;1353:56;1439:4;1431:6;1427:17;1419:25;;1499:4;1493;1489:15;1481:23;;1173:338;;;:::o;1517:117::-;1626:1;1623;1616:12;1640:117;1749:1;1746;1739:12;1886:113;1973:1;1966:5;1963:12;1953:40;;1989:1;1986;1979:12;1953:40;1886:113;:::o;2005:167::-;2065:5;2103:6;2090:20;2081:29;;2119:47;2160:5;2119:47;:::i;:::-;2005:167;;;;:::o;2178:126::-;2215:7;2255:42;2248:5;2244:54;2233:65;;2178:126;;;:::o;2310:96::-;2347:7;2376:24;2394:5;2376:24;:::i;:::-;2365:35;;2310:96;;;:::o;2412:122::-;2485:24;2503:5;2485:24;:::i;:::-;2478:5;2475:35;2465:63;;2524:1;2521;2514:12;2465:63;2412:122;:::o;2540:139::-;2586:5;2624:6;2611:20;2602:29;;2640:33;2667:5;2640:33;:::i;:::-;2540:139;;;;:::o;2725:601::-;2801:5;2845:4;2833:9;2828:3;2824:19;2820:30;2817:117;;;2853:79;;:::i;:::-;2817:117;2952:21;2968:4;2952:21;:::i;:::-;2943:30;;3036:1;3076:63;3135:3;3126:6;3115:9;3111:22;3076:63;:::i;:::-;3069:4;3062:5;3058:16;3051:89;2983:168;3217:2;3258:49;3303:3;3294:6;3283:9;3279:22;3258:49;:::i;:::-;3251:4;3244:5;3240:16;3233:75;3161:158;2725:601;;;;:::o;3374:791::-;3497:5;3522:108;3538:91;3622:6;3538:91;:::i;:::-;3522:108;:::i;:::-;3513:117;;3650:5;3679:6;3672:5;3665:21;3713:4;3706:5;3702:16;3695:23;;3766:4;3758:6;3754:17;3746:6;3742:30;3795:3;3787:6;3784:15;3781:122;;;3814:79;;:::i;:::-;3781:122;3929:6;3912:247;3946:6;3941:3;3938:15;3912:247;;;4021:3;4050:64;4110:3;4098:10;4050:64;:::i;:::-;4045:3;4038:77;4144:4;4139:3;4135:14;4128:21;;3988:171;3972:4;3967:3;3963:14;3956:21;;3912:247;;;3916:21;3503:662;;3374:791;;;;;:::o;4213:424::-;4311:5;4360:3;4353:4;4345:6;4341:17;4337:27;4327:122;;4368:79;;:::i;:::-;4327:122;4485:6;4472:20;4510:121;4627:3;4619:6;4612:4;4604:6;4600:17;4510:121;:::i;:::-;4501:130;;4317:320;4213:424;;;;:::o;4643:593::-;4754:6;4803:2;4791:9;4782:7;4778:23;4774:32;4771:119;;;4809:79;;:::i;:::-;4771:119;4957:1;4946:9;4942:17;4929:31;4987:18;4979:6;4976:30;4973:117;;;5009:79;;:::i;:::-;4973:117;5114:105;5211:7;5202:6;5191:9;5187:22;5114:105;:::i;:::-;5104:115;;4900:329;4643:593;;;;:::o;5242:147::-;5342:6;5376:5;5370:12;5360:22;;5242:147;;;:::o;5395:217::-;5527:11;5561:6;5556:3;5549:19;5601:4;5596:3;5592:14;5577:29;;5395:217;;;;:::o;5618:165::-;5718:4;5741:3;5733:11;;5771:4;5766:3;5762:14;5754:22;;5618:165;;;:::o;5789:180::-;5837:77;5834:1;5827:88;5934:4;5931:1;5924:15;5958:4;5955:1;5948:15;5975:119;6062:1;6055:5;6052:12;6042:46;;6068:18;;:::i;:::-;6042:46;5975:119;:::o;6100:139::-;6151:7;6180:5;6169:16;;6186:47;6227:5;6186:47;:::i;:::-;6100:139;;;:::o;6245:::-;6307:9;6340:38;6372:5;6340:38;:::i;:::-;6327:51;;6245:139;;;:::o;6390:145::-;6479:49;6522:5;6479:49;:::i;:::-;6474:3;6467:62;6390:145;;:::o;6541:108::-;6618:24;6636:5;6618:24;:::i;:::-;6613:3;6606:37;6541:108;;:::o;6655:77::-;6692:7;6721:5;6710:16;;6655:77;;;:::o;6738:108::-;6815:24;6833:5;6815:24;:::i;:::-;6810:3;6803:37;6738:108;;:::o;6940:715::-;7093:4;7088:3;7084:14;7184:4;7177:5;7173:16;7167:23;7203:75;7272:4;7267:3;7263:14;7249:12;7203:75;:::i;:::-;7108:180;7377:4;7370:5;7366:16;7360:23;7396:63;7453:4;7448:3;7444:14;7430:12;7396:63;:::i;:::-;7298:171;7556:4;7549:5;7545:16;7539:23;7575:63;7632:4;7627:3;7623:14;7609:12;7575:63;:::i;:::-;7479:169;7062:593;6940:715;;:::o;7661:311::-;7796:10;7817:112;7925:3;7917:6;7817:112;:::i;:::-;7961:4;7956:3;7952:14;7938:28;;7661:311;;;;:::o;7978:146::-;8081:4;8113;8108:3;8104:14;8096:22;;7978:146;;;:::o;8222:996::-;8407:3;8436:87;8517:5;8436:87;:::i;:::-;8539:119;8651:6;8646:3;8539:119;:::i;:::-;8532:126;;8682:89;8765:5;8682:89;:::i;:::-;8794:7;8825:1;8810:383;8835:6;8832:1;8829:13;8810:383;;;8911:6;8905:13;8938:129;9063:3;9048:13;8938:129;:::i;:::-;8931:136;;9090:93;9176:6;9090:93;:::i;:::-;9080:103;;8870:323;8857:1;8854;8850:9;8845:14;;8810:383;;;8814:14;9209:3;9202:10;;8412:806;;;8222:996;;;;:::o;9224:505::-;9433:4;9471:2;9460:9;9456:18;9448:26;;9520:9;9514:4;9510:20;9506:1;9495:9;9491:17;9484:47;9548:174;9717:4;9708:6;9548:174;:::i;:::-;9540:182;;9224:505;;;;:::o;9735:180::-;9783:77;9780:1;9773:88;9880:4;9877:1;9870:15;9904:4;9901:1;9894:15;9921:311;9998:4;10088:18;10080:6;10077:30;10074:56;;;10110:18;;:::i;:::-;10074:56;10160:4;10152:6;10148:17;10140:25;;10220:4;10214;10210:15;10202:23;;9921:311;;;:::o;10238:143::-;10295:5;10326:6;10320:13;10311:22;;10342:33;10369:5;10342:33;:::i;:::-;10238:143;;;;:::o;10404:732::-;10511:5;10536:81;10552:64;10609:6;10552:64;:::i;:::-;10536:81;:::i;:::-;10527:90;;10637:5;10666:6;10659:5;10652:21;10700:4;10693:5;10689:16;10682:23;;10753:4;10745:6;10741:17;10733:6;10729:30;10782:3;10774:6;10771:15;10768:122;;;10801:79;;:::i;:::-;10768:122;10916:6;10899:231;10933:6;10928:3;10925:15;10899:231;;;11008:3;11037:48;11081:3;11069:10;11037:48;:::i;:::-;11032:3;11025:61;11115:4;11110:3;11106:14;11099:21;;10975:155;10959:4;10954:3;10950:14;10943:21;;10899:231;;;10903:21;10517:619;;10404:732;;;;;:::o;11159:385::-;11241:5;11290:3;11283:4;11275:6;11271:17;11267:27;11257:122;;11298:79;;:::i;:::-;11257:122;11408:6;11402:13;11433:105;11534:3;11526:6;11519:4;11511:6;11507:17;11433:105;:::i;:::-;11424:114;;11247:297;11159:385;;;;:::o;11550:554::-;11645:6;11694:2;11682:9;11673:7;11669:23;11665:32;11662:119;;;11700:79;;:::i;:::-;11662:119;11841:1;11830:9;11826:17;11820:24;11871:18;11863:6;11860:30;11857:117;;;11893:79;;:::i;:::-;11857:117;11998:89;12079:7;12070:6;12059:9;12055:22;11998:89;:::i;:::-;11988:99;;11791:306;11550:554;;;;:::o;12110:118::-;12197:24;12215:5;12197:24;:::i;:::-;12192:3;12185:37;12110:118;;:::o;12234:222::-;12327:4;12365:2;12354:9;12350:18;12342:26;;12378:71;12446:1;12435:9;12431:17;12422:6;12378:71;:::i;:::-;12234:222;;;;:::o;12462:122::-;12535:24;12553:5;12535:24;:::i;:::-;12528:5;12525:35;12515:63;;12574:1;12571;12564:12;12515:63;12462:122;:::o;12590:143::-;12647:5;12678:6;12672:13;12663:22;;12694:33;12721:5;12694:33;:::i;:::-;12590:143;;;;:::o;12739:351::-;12809:6;12858:2;12846:9;12837:7;12833:23;12829:32;12826:119;;;12864:79;;:::i;:::-;12826:119;12984:1;13009:64;13065:7;13056:6;13045:9;13041:22;13009:64;:::i;:::-;12999:74;;12955:128;12739:351;;;;:::o;13096:180::-;13144:77;13141:1;13134:88;13241:4;13238:1;13231:15;13265:4;13262:1;13255:15;13282:410;13322:7;13345:20;13363:1;13345:20;:::i;:::-;13340:25;;13379:20;13397:1;13379:20;:::i;:::-;13374:25;;13434:1;13431;13427:9;13456:30;13474:11;13456:30;:::i;:::-;13445:41;;13635:1;13626:7;13622:15;13619:1;13616:22;13596:1;13589:9;13569:83;13546:139;;13665:18;;:::i;:::-;13546:139;13330:362;13282:410;;;;:::o;13698:351::-;13768:6;13817:2;13805:9;13796:7;13792:23;13788:32;13785:119;;;13823:79;;:::i;:::-;13785:119;13943:1;13968:64;14024:7;14015:6;14004:9;14000:22;13968:64;:::i;:::-;13958:74;;13914:128;13698:351;;;;:::o;14055:114::-;14092:7;14132:30;14125:5;14121:42;14110:53;;14055:114;;;:::o;14175:122::-;14248:24;14266:5;14248:24;:::i;:::-;14241:5;14238:35;14228:63;;14287:1;14284;14277:12;14228:63;14175:122;:::o;14303:143::-;14360:5;14391:6;14385:13;14376:22;;14407:33;14434:5;14407:33;:::i;:::-;14303:143;;;;:::o;14452:93::-;14488:7;14528:10;14521:5;14517:22;14506:33;;14452:93;;;:::o;14551:120::-;14623:23;14640:5;14623:23;:::i;:::-;14616:5;14613:34;14603:62;;14661:1;14658;14651:12;14603:62;14551:120;:::o;14677:141::-;14733:5;14764:6;14758:13;14749:22;;14780:32;14806:5;14780:32;:::i;:::-;14677:141;;;;:::o;14824:661::-;14911:6;14919;14927;14976:2;14964:9;14955:7;14951:23;14947:32;14944:119;;;14982:79;;:::i;:::-;14944:119;15102:1;15127:64;15183:7;15174:6;15163:9;15159:22;15127:64;:::i;:::-;15117:74;;15073:128;15240:2;15266:64;15322:7;15313:6;15302:9;15298:22;15266:64;:::i;:::-;15256:74;;15211:129;15379:2;15405:63;15460:7;15451:6;15440:9;15436:22;15405:63;:::i;:::-;15395:73;;15350:128;14824:661;;;;;:::o;15491:279::-;15531:7;15554:20;15572:1;15554:20;:::i;:::-;15549:25;;15588:20;15606:1;15588:20;:::i;:::-;15583:25;;15643:1;15640;15636:9;15665:30;15683:11;15665:30;:::i;:::-;15654:41;;15727:11;15718:7;15715:24;15705:58;;15743:18;;:::i;:::-;15705:58;15539:231;15491:279;;;;:::o;15776:332::-;15897:4;15935:2;15924:9;15920:18;15912:26;;15948:71;16016:1;16005:9;16001:17;15992:6;15948:71;:::i;:::-;16029:72;16097:2;16086:9;16082:18;16073:6;16029:72;:::i;:::-;15776:332;;;;;:::o;16114:86::-;16149:7;16189:4;16182:5;16178:16;16167:27;;16114:86;;;:::o;16206:191::-;16244:4;16264:18;16280:1;16264:18;:::i;:::-;16259:23;;16296:18;16312:1;16296:18;:::i;:::-;16291:23;;16338:1;16335;16331:9;16323:17;;16362:4;16356;16353:14;16350:40;;;16370:18;;:::i;:::-;16350:40;16206:191;;;;:::o;16403:102::-;16445:8;16492:5;16489:1;16485:13;16464:34;;16403:102;;;:::o;16511:848::-;16572:5;16579:4;16603:6;16594:15;;16627:5;16618:14;;16641:712;16662:1;16652:8;16649:15;16641:712;;;16757:4;16752:3;16748:14;16742:4;16739:24;16736:50;;;16766:18;;:::i;:::-;16736:50;16816:1;16806:8;16802:16;16799:451;;;17231:4;17224:5;17220:16;17211:25;;16799:451;17281:4;17275;17271:15;17263:23;;17311:32;17334:8;17311:32;:::i;:::-;17299:44;;16641:712;;;16511:848;;;;;;;:::o;17365:1073::-;17419:5;17610:8;17600:40;;17631:1;17622:10;;17633:5;;17600:40;17659:4;17649:36;;17676:1;17667:10;;17678:5;;17649:36;17745:4;17793:1;17788:27;;;;17829:1;17824:191;;;;17738:277;;17788:27;17806:1;17797:10;;17808:5;;;17824:191;17869:3;17859:8;17856:17;17853:43;;;17876:18;;:::i;:::-;17853:43;17925:8;17922:1;17918:16;17909:25;;17960:3;17953:5;17950:14;17947:40;;;17967:18;;:::i;:::-;17947:40;18000:5;;;17738:277;;18124:2;18114:8;18111:16;18105:3;18099:4;18096:13;18092:36;18074:2;18064:8;18061:16;18056:2;18050:4;18047:12;18043:35;18027:111;18024:246;;;18180:8;18174:4;18170:19;18161:28;;18215:3;18208:5;18205:14;18202:40;;;18222:18;;:::i;:::-;18202:40;18255:5;;18024:246;18295:42;18333:3;18323:8;18317:4;18314:1;18295:42;:::i;:::-;18280:57;;;;18369:4;18364:3;18360:14;18353:5;18350:25;18347:51;;;18378:18;;:::i;:::-;18347:51;18427:4;18420:5;18416:16;18407:25;;17365:1073;;;;;;:::o;18444:281::-;18502:5;18526:23;18544:4;18526:23;:::i;:::-;18518:31;;18570:25;18586:8;18570:25;:::i;:::-;18558:37;;18614:104;18651:66;18641:8;18635:4;18614:104;:::i;:::-;18605:113;;18444:281;;;;:::o;18731:180::-;18779:77;18776:1;18769:88;18876:4;18873:1;18866:15;18900:4;18897:1;18890:15;18917:185;18957:1;18974:20;18992:1;18974:20;:::i;:::-;18969:25;;19008:20;19026:1;19008:20;:::i;:::-;19003:25;;19047:1;19037:35;;19052:18;;:::i;:::-;19037:35;19094:1;19091;19087:9;19082:14;;18917:185;;;;:::o;19108:89::-;19144:7;19184:6;19177:5;19173:18;19162:29;;19108:89;;;:::o;19203:91::-;19239:7;19279:8;19272:5;19268:20;19257:31;;19203:91;;;:::o;19300:60::-;19328:3;19349:5;19342:12;;19300:60;;;:::o;19366:138::-;19414:9;19447:51;19464:33;19473:23;19490:5;19473:23;:::i;:::-;19464:33;:::i;:::-;19447:51;:::i;:::-;19434:64;;19366:138;;;:::o;19510:127::-;19595:35;19624:5;19595:35;:::i;:::-;19590:3;19583:48;19510:127;;:::o;19643:438::-;19790:4;19828:2;19817:9;19813:18;19805:26;;19841:71;19909:1;19898:9;19894:17;19885:6;19841:71;:::i;:::-;19922:72;19990:2;19979:9;19975:18;19966:6;19922:72;:::i;:::-;20004:70;20070:2;20059:9;20055:18;20046:6;20004:70;:::i;:::-;19643:438;;;;;;:::o;20087:122::-;20160:24;20178:5;20160:24;:::i;:::-;20153:5;20150:35;20140:63;;20199:1;20196;20189:12;20140:63;20087:122;:::o;20215:143::-;20272:5;20303:6;20297:13;20288:22;;20319:33;20346:5;20319:33;:::i;:::-;20215:143;;;;:::o;20364:90::-;20399:7;20442:5;20439:1;20428:20;20417:31;;20364:90;;;:::o;20460:118::-;20531:22;20547:5;20531:22;:::i;:::-;20524:5;20521:33;20511:61;;20568:1;20565;20558:12;20511:61;20460:118;:::o;20584:139::-;20639:5;20670:6;20664:13;20655:22;;20686:31;20711:5;20686:31;:::i;:::-;20584:139;;;;:::o;20729:120::-;20801:23;20818:5;20801:23;:::i;:::-;20794:5;20791:34;20781:62;;20839:1;20836;20829:12;20781:62;20729:120;:::o;20855:141::-;20911:5;20942:6;20936:13;20927:22;;20958:32;20984:5;20958:32;:::i;:::-;20855:141;;;;:::o;21002:118::-;21073:22;21089:5;21073:22;:::i;:::-;21066:5;21063:33;21053:61;;21110:1;21107;21100:12;21053:61;21002:118;:::o;21126:139::-;21181:5;21212:6;21206:13;21197:22;;21228:31;21253:5;21228:31;:::i;:::-;21126:139;;;;:::o;21271:90::-;21305:7;21348:5;21341:13;21334:21;21323:32;;21271:90;;;:::o;21367:116::-;21437:21;21452:5;21437:21;:::i;:::-;21430:5;21427:32;21417:60;;21473:1;21470;21463:12;21417:60;21367:116;:::o;21489:137::-;21543:5;21574:6;21568:13;21559:22;;21590:30;21614:5;21590:30;:::i;:::-;21489:137;;;;:::o;21632:1271::-;21746:6;21754;21762;21770;21778;21786;21794;21843:3;21831:9;21822:7;21818:23;21814:33;21811:120;;;21850:79;;:::i;:::-;21811:120;21970:1;21995:64;22051:7;22042:6;22031:9;22027:22;21995:64;:::i;:::-;21985:74;;21941:128;22108:2;22134:62;22188:7;22179:6;22168:9;22164:22;22134:62;:::i;:::-;22124:72;;22079:127;22245:2;22271:63;22326:7;22317:6;22306:9;22302:22;22271:63;:::i;:::-;22261:73;;22216:128;22383:2;22409:63;22464:7;22455:6;22444:9;22440:22;22409:63;:::i;:::-;22399:73;;22354:128;22521:3;22548:63;22603:7;22594:6;22583:9;22579:22;22548:63;:::i;:::-;22538:73;;22492:129;22660:3;22687:62;22741:7;22732:6;22721:9;22717:22;22687:62;:::i;:::-;22677:72;;22631:128;22798:3;22825:61;22878:7;22869:6;22858:9;22854:22;22825:61;:::i;:::-;22815:71;;22769:127;21632:1271;;;;;;;;;;:::o;22909:98::-;22960:6;22994:5;22988:12;22978:22;;22909:98;;;:::o;23013:147::-;23114:11;23151:3;23136:18;;23013:147;;;;:::o;23166:139::-;23255:6;23250:3;23245;23239:23;23296:1;23287:6;23282:3;23278:16;23271:27;23166:139;;;:::o;23311:386::-;23415:3;23443:38;23475:5;23443:38;:::i;:::-;23497:88;23578:6;23573:3;23497:88;:::i;:::-;23490:95;;23594:65;23652:6;23647:3;23640:4;23633:5;23629:16;23594:65;:::i;:::-;23684:6;23679:3;23675:16;23668:23;;23419:278;23311:386;;;;:::o;23703:271::-;23833:3;23855:93;23944:3;23935:6;23855:93;:::i;:::-;23848:100;;23965:3;23958:10;;23703:271;;;;:::o;23980:180::-;24028:77;24025:1;24018:88;24125:4;24122:1;24115:15;24149:4;24146:1;24139:15\",\"linkReferences\":{}},\"methodIdentifiers\":{\"getWethValueInPools((uint8,address)[])\":\"339173fd\"},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.28+commit.7893614a\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_uniswapV2Factory\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_uniswapV3Factory\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"_weth\\\",\\\"type\\\":\\\"address\\\"},{\\\"components\\\":[{\\\"internalType\\\":\\\"enum WethValueInPools.PoolType\\\",\\\"name\\\":\\\"poolType\\\",\\\"type\\\":\\\"uint8\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"poolAddress\\\",\\\"type\\\":\\\"address\\\"}],\\\"internalType\\\":\\\"struct WethValueInPools.PoolInfo[]\\\",\\\"name\\\":\\\"pools\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"constructor\\\"},{\\\"inputs\\\":[{\\\"components\\\":[{\\\"internalType\\\":\\\"enum WethValueInPools.PoolType\\\",\\\"name\\\":\\\"poolType\\\",\\\"type\\\":\\\"uint8\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"poolAddress\\\",\\\"type\\\":\\\"address\\\"}],\\\"internalType\\\":\\\"struct WethValueInPools.PoolInfo[]\\\",\\\"name\\\":\\\"pools\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"name\\\":\\\"getWethValueInPools\\\",\\\"outputs\\\":[{\\\"components\\\":[{\\\"internalType\\\":\\\"enum WethValueInPools.PoolType\\\",\\\"name\\\":\\\"poolType\\\",\\\"type\\\":\\\"uint8\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"poolAddress\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"wethValue\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"internalType\\\":\\\"struct WethValueInPools.PoolInfoReturn[]\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"tuple[]\\\"}],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"getWethValueInPools((uint8,address)[])\\\":{\\\"details\\\":\\\"We require a 1 ETH minimum liquidity in the quoting pool for it to be considered.\\\"}},\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{\\\"getWethValueInPools((uint8,address)[])\\\":{\\\"notice\\\":\\\"Returns an array of `PoolInfoReturn` for the consumer to determine wether to filter or not to save gas.\\\"}},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"src/filters/WethValueInPoolsBatchRequest.sol\\\":\\\"WethValueInPoolsBatchRequest\\\"},\\\"evmVersion\\\":\\\"cancun\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"none\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":forge-std/=lib/forge-std/src/\\\"]},\\\"sources\\\":{\\\"src/UniswapV3/FixedPoint.sol\\\":{\\\"keccak256\\\":\\\"0xf82873fe78051afcf0446c27f5c5857816d1129e2bc84855dee8275d764b49d0\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://5d1b9704466cdf93f446ac2330ef89752c2bcc1f271a70c296f54e0d9291467f\\\",\\\"dweb:/ipfs/QmaQd3DUAdJMVQD422o2HyAwhTDyLo33znMgRDU5NaZegE\\\"]},\\\"src/filters/WethValueInPools.sol\\\":{\\\"keccak256\\\":\\\"0x1bd98caec9df680366948f8e1f24ed7262021aeb841ea155efafb05648152c4b\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://3f88558f892e5441c824e1d6973036e1196445b99c7e24fcfa6a399af64e2ace\\\",\\\"dweb:/ipfs/QmT7KqFaR9pysM94AAbSgeJrb1XsQickV6kyowBWc5vYgT\\\"]},\\\"src/filters/WethValueInPoolsBatchRequest.sol\\\":{\\\"keccak256\\\":\\\"0xb071e547407d4ca1cf0ca9582b7620e786edadf5b45188f4f9d4619d7ad672ae\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://e17ca6f4eb9ff0e5bfe77a0d5b3c31fa3cab43c98b49fddf126b854bd23ece8b\\\",\\\"dweb:/ipfs/QmWHeJiaPFYswRn5HwyC4yj7w521KBSP2KQUMzg1Ktru6u\\\"]},\\\"src/interfaces/IBalancer.sol\\\":{\\\"keccak256\\\":\\\"0xe7ca1e7f70a16d6919334b612a584e5d42692a802f4d92686c564a4ab1550c27\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://2e0cf4540fca9dbf3650d22d1d927b43bcd8333a988c7575c6618b633bff082f\\\",\\\"dweb:/ipfs/QmYAcUnqBauhiXJNfMLta4Bj1dntGmNJ3cxaHq18LnBDAQ\\\"]},\\\"src/interfaces/IUniswapV2.sol\\\":{\\\"keccak256\\\":\\\"0x067d9c125da6fdbe44d6ce7d498c42460d7347317413f8317bf80bd25c08898d\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://b1ad58162042aa8d1eb7451af3ccc3b1df64e720aeeb69a6843507aec0e5d146\\\",\\\"dweb:/ipfs/QmdvEJYkfWaGWrGXtKajZSDdfNYJ3sDFpzsV4f1X4KQYZM\\\"]},\\\"src/interfaces/IUniswapV3.sol\\\":{\\\"keccak256\\\":\\\"0x914ac5f4d9e6b6d0345c89e769f1a2d9784d047e8cac6f3265b229afd9363729\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://19a3f9d71839d62cea60562c57cdfe582821da7bfe17a1d6ca26597db51a3762\\\",\\\"dweb:/ipfs/QmdWoVo3J7tcSKCk5cCADvjvMtmczcGbsmKx5v9AFjQANz\\\"]},\\\"src/interfaces/Token.sol\\\":{\\\"keccak256\\\":\\\"0x2f7118f6cba8e0303e66028f738463e025a19ec0186a5462523692f44330e113\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://ca6355f3ce4aec77f281142db4cb0a63d5e1b3b4b12836ac9a3ed251069801d0\\\",\\\"dweb:/ipfs/QmWTt8HyEuzTdKVWCzBDxVMWL3tptkxsTfsssbEMVA818A\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_uniswapV2Factory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_uniswapV3Factory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_weth\",\"type\":\"address\"},{\"internalType\":\"struct WethValueInPools.PoolInfo[]\",\"name\":\"pools\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"enum WethValueInPools.PoolType\",\"name\":\"poolType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"struct WethValueInPools.PoolInfo[]\",\"name\":\"pools\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"enum WethValueInPools.PoolType\",\"name\":\"poolType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"}]}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"getWethValueInPools\",\"outputs\":[{\"internalType\":\"struct WethValueInPools.PoolInfoReturn[]\",\"name\":\"\",\"type\":\"tuple[]\",\"components\":[{\"internalType\":\"enum WethValueInPools.PoolType\",\"name\":\"poolType\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wethValue\",\"type\":\"uint256\"}]}]}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getWethValueInPools((uint8,address)[])\":{\"details\":\"We require a 1 ETH minimum liquidity in the quoting pool for it to be considered.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getWethValueInPools((uint8,address)[])\":{\"notice\":\"Returns an array of `PoolInfoReturn` for the consumer to determine wether to filter or not to save gas.\"}},\"version\":1}},\"settings\":{\"remappings\":[\"forge-std/=lib/forge-std/src/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"none\"},\"compilationTarget\":{\"src/filters/WethValueInPoolsBatchRequest.sol\":\"WethValueInPoolsBatchRequest\"},\"evmVersion\":\"cancun\",\"libraries\":{}},\"sources\":{\"src/UniswapV3/FixedPoint.sol\":{\"keccak256\":\"0xf82873fe78051afcf0446c27f5c5857816d1129e2bc84855dee8275d764b49d0\",\"urls\":[\"bzz-raw://5d1b9704466cdf93f446ac2330ef89752c2bcc1f271a70c296f54e0d9291467f\",\"dweb:/ipfs/QmaQd3DUAdJMVQD422o2HyAwhTDyLo33znMgRDU5NaZegE\"],\"license\":\"MIT\"},\"src/filters/WethValueInPools.sol\":{\"keccak256\":\"0x1bd98caec9df680366948f8e1f24ed7262021aeb841ea155efafb05648152c4b\",\"urls\":[\"bzz-raw://3f88558f892e5441c824e1d6973036e1196445b99c7e24fcfa6a399af64e2ace\",\"dweb:/ipfs/QmT7KqFaR9pysM94AAbSgeJrb1XsQickV6kyowBWc5vYgT\"],\"license\":\"MIT\"},\"src/filters/WethValueInPoolsBatchRequest.sol\":{\"keccak256\":\"0xb071e547407d4ca1cf0ca9582b7620e786edadf5b45188f4f9d4619d7ad672ae\",\"urls\":[\"bzz-raw://e17ca6f4eb9ff0e5bfe77a0d5b3c31fa3cab43c98b49fddf126b854bd23ece8b\",\"dweb:/ipfs/QmWHeJiaPFYswRn5HwyC4yj7w521KBSP2KQUMzg1Ktru6u\"],\"license\":\"MIT\"},\"src/interfaces/IBalancer.sol\":{\"keccak256\":\"0xe7ca1e7f70a16d6919334b612a584e5d42692a802f4d92686c564a4ab1550c27\",\"urls\":[\"bzz-raw://2e0cf4540fca9dbf3650d22d1d927b43bcd8333a988c7575c6618b633bff082f\",\"dweb:/ipfs/QmYAcUnqBauhiXJNfMLta4Bj1dntGmNJ3cxaHq18LnBDAQ\"],\"license\":\"MIT\"},\"src/interfaces/IUniswapV2.sol\":{\"keccak256\":\"0x067d9c125da6fdbe44d6ce7d498c42460d7347317413f8317bf80bd25c08898d\",\"urls\":[\"bzz-raw://b1ad58162042aa8d1eb7451af3ccc3b1df64e720aeeb69a6843507aec0e5d146\",\"dweb:/ipfs/QmdvEJYkfWaGWrGXtKajZSDdfNYJ3sDFpzsV4f1X4KQYZM\"],\"license\":\"MIT\"},\"src/interfaces/IUniswapV3.sol\":{\"keccak256\":\"0x914ac5f4d9e6b6d0345c89e769f1a2d9784d047e8cac6f3265b229afd9363729\",\"urls\":[\"bzz-raw://19a3f9d71839d62cea60562c57cdfe582821da7bfe17a1d6ca26597db51a3762\",\"dweb:/ipfs/QmdWoVo3J7tcSKCk5cCADvjvMtmczcGbsmKx5v9AFjQANz\"],\"license\":\"MIT\"},\"src/interfaces/Token.sol\":{\"keccak256\":\"0x2f7118f6cba8e0303e66028f738463e025a19ec0186a5462523692f44330e113\",\"urls\":[\"bzz-raw://ca6355f3ce4aec77f281142db4cb0a63d5e1b3b4b12836ac9a3ed251069801d0\",\"dweb:/ipfs/QmWTt8HyEuzTdKVWCzBDxVMWL3tptkxsTfsssbEMVA818A\"],\"license\":\"MIT\"}},\"version\":1},\"id\":34}"
  },
  {
    "path": "src/amms/amm.rs",
    "content": "use super::{\n    balancer::BalancerPool, erc_4626::ERC4626Vault, error::AMMError, uniswap_v2::UniswapV2Pool,\n    uniswap_v3::UniswapV3Pool,\n};\nuse alloy::{\n    eips::BlockId,\n    network::Network,\n    primitives::{Address, B256, U256},\n    providers::Provider,\n    rpc::types::Log,\n};\nuse eyre::Result;\nuse serde::{Deserialize, Serialize};\nuse std::hash::{Hash, Hasher};\n\n#[allow(async_fn_in_trait)]\npub trait AutomatedMarketMaker {\n    /// Address of the AMM\n    fn address(&self) -> Address;\n\n    /// Event signatures that indicate when the AMM should be synced\n    fn sync_events(&self) -> Vec<B256>;\n\n    /// Syncs the AMM state\n    fn sync(&mut self, log: &Log) -> Result<(), AMMError>;\n\n    /// Returns a list of token addresses used in the AMM\n    fn tokens(&self) -> Vec<Address>;\n\n    /// Calculates the price of `base_token` in terms of `quote_token`\n    fn calculate_price(&self, base_token: Address, quote_token: Address) -> Result<f64, AMMError>;\n\n    /// Simulate a swap\n    /// Returns the amount_out in `quote token` for a given `amount_in` of `base_token`\n    fn simulate_swap(\n        &self,\n        base_token: Address,\n        quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError>;\n\n    /// Simulate a swap, mutating the AMM state\n    /// Returns the amount_out in `quote token` for a given `amount_in` of `base_token`\n    fn simulate_swap_mut(\n        &mut self,\n        base_token: Address,\n        quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError>;\n\n    // Initializes an empty pool and syncs state up to `block_number`\n    async fn init<N, P>(self, block_number: BlockId, provider: P) -> Result<Self, AMMError>\n    where\n        Self: Sized,\n        N: Network,\n        P: Provider<N> + Clone;\n}\n\nmacro_rules! amm {\n    ($($pool_type:ident),+ $(,)?) => {\n        #[derive(Debug, Clone, Serialize, Deserialize)]\n        pub enum AMM {\n            $($pool_type($pool_type),)+\n        }\n\n        impl AutomatedMarketMaker for AMM {\n            fn address(&self) -> Address{\n                match self {\n                    $(AMM::$pool_type(pool) => pool.address(),)+\n                }\n            }\n\n            fn sync_events(&self) -> Vec<B256> {\n                match self {\n                    $(AMM::$pool_type(pool) => pool.sync_events(),)+\n                }\n            }\n\n            fn sync(&mut self, log: &Log) -> Result<(), AMMError> {\n                match self {\n                    $(AMM::$pool_type(pool) => pool.sync(log),)+\n                }\n            }\n\n            fn simulate_swap(&self, base_token: Address, quote_token: Address,amount_in: U256) -> Result<U256, AMMError> {\n                match self {\n                    $(AMM::$pool_type(pool) => pool.simulate_swap(base_token, quote_token, amount_in),)+\n                }\n            }\n\n            fn simulate_swap_mut(&mut self, base_token: Address, quote_token: Address, amount_in: U256) -> Result<U256, AMMError> {\n                match self {\n                    $(AMM::$pool_type(pool) => pool.simulate_swap_mut(base_token, quote_token, amount_in),)+\n                }\n            }\n\n            fn tokens(&self) -> Vec<Address> {\n                match self {\n                    $(AMM::$pool_type(pool) => pool.tokens(),)+\n                }\n            }\n\n            fn calculate_price(&self, base_token: Address, quote_token: Address) -> Result<f64, AMMError> {\n                match self {\n                    $(AMM::$pool_type(pool) => pool.calculate_price(base_token, quote_token),)+\n                }\n            }\n\n            async fn init<N, P>(self, block_number: BlockId, provider: P) -> Result<Self, AMMError>\n            where\n                Self: Sized,\n                N: Network,\n                P: Provider<N> + Clone,\n            {\n                match self {\n                    $(AMM::$pool_type(pool) => pool.init(block_number, provider).await.map(AMM::$pool_type),)+\n                }\n            }\n        }\n\n\n        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]\n        pub enum Variant {\n            $($pool_type,)+\n        }\n\n        impl AMM {\n            pub fn variant(&self) -> Variant {\n                match self {\n                    $(AMM::$pool_type(_) => Variant::$pool_type,)+\n                }\n            }\n        }\n\n        impl Hash for AMM {\n            fn hash<H: Hasher>(&self, state: &mut H) {\n                self.address().hash(state);\n            }\n        }\n\n        impl PartialEq for AMM {\n            fn eq(&self, other: &Self) -> bool {\n                self.address() == other.address()\n            }\n        }\n\n        impl Eq for AMM {}\n\n        $(\n            impl From<$pool_type> for AMM {\n                fn from(amm: $pool_type) -> Self {\n                    AMM::$pool_type(amm)\n                }\n            }\n        )+\n    };\n}\n\namm!(UniswapV2Pool, UniswapV3Pool, ERC4626Vault, BalancerPool);\n"
  },
  {
    "path": "src/amms/balancer/bmath.rs",
    "content": "use alloy::primitives::U256;\n\nuse crate::amms::consts::{BONE, U256_1, U256_10E_10, U256_2};\n\nuse super::BalancerError;\n\npub fn btoi(a: U256) -> U256 {\n    a / BONE\n}\n\n#[inline]\npub fn badd(a: U256, b: U256) -> Result<U256, BalancerError> {\n    let c = a + b;\n    if c < a {\n        return Err(BalancerError::AddOverflow);\n    }\n    Ok(c)\n}\n\n#[inline]\npub fn bpowi(a: U256, n: U256) -> Result<U256, BalancerError> {\n    let mut z = if n % U256_2 != U256::ZERO { a } else { BONE };\n\n    let mut a = a;\n    let mut n = n / U256_2;\n    while n != U256::ZERO {\n        a = bmul(a, a)?;\n        if n % U256_2 != U256::ZERO {\n            z = bmul(z, a)?;\n        }\n        n /= U256_2;\n    }\n    Ok(z)\n}\n\n#[inline]\npub fn bpow(base: U256, exp: U256) -> Result<U256, BalancerError> {\n    let whole = bfloor(exp);\n    let remain = bsub(exp, whole)?;\n    let whole_pow = bpowi(base, btoi(whole))?;\n    if remain == U256::ZERO {\n        return Ok(whole_pow);\n    }\n    let precision = BONE / U256_10E_10;\n    let partial_result = bpow_approx(base, remain, precision)?;\n    bmul(whole_pow, partial_result)\n}\n\n#[inline]\npub fn bpow_approx(base: U256, exp: U256, precision: U256) -> Result<U256, BalancerError> {\n    let a = exp;\n    let (x, xneg) = bsub_sign(base, BONE);\n    let mut term = BONE;\n    let mut sum = term;\n    let mut negative = false;\n    let mut i = U256_1;\n    while term >= precision {\n        let big_k = U256::from(i) * BONE;\n        let (c, cneg) = bsub_sign(a, bsub(big_k, BONE)?);\n        term = bmul(term, bmul(c, x)?)?;\n        term = bdiv(term, big_k)?;\n        if term == U256::ZERO {\n            break;\n        }\n        negative ^= xneg ^ cneg;\n        if negative {\n            sum = bsub(sum, term)?;\n        } else {\n            sum = badd(sum, term)?;\n        }\n        i += U256_1;\n    }\n    Ok(sum)\n}\n\n#[inline]\npub fn bfloor(a: U256) -> U256 {\n    btoi(a) * BONE\n}\n\n// Reference:\n// https://github.com/balancer/balancer-core/blob/f4ed5d65362a8d6cec21662fb6eae233b0babc1f/contracts/BNum.sol#L75\n#[inline]\npub fn bdiv(a: U256, b: U256) -> Result<U256, BalancerError> {\n    if b == U256::ZERO {\n        return Err(BalancerError::DivZero);\n    }\n    let c0 = a * BONE;\n    if a != U256::ZERO && c0 / a != BONE {\n        return Err(BalancerError::DivInternal);\n    }\n    let c1 = c0 + (b / U256_2);\n    if c1 < c0 {\n        return Err(BalancerError::DivInternal);\n    }\n    Ok(c1 / b)\n}\n\n// Reference:\n// https://github.com/balancer/balancer-core/blob/f4ed5d65362a8d6cec21662fb6eae233b0babc1f/contracts/BNum.sol#L43\n#[inline]\npub fn bsub(a: U256, b: U256) -> Result<U256, BalancerError> {\n    let (c, flag) = bsub_sign(a, b);\n    if flag {\n        return Err(BalancerError::SubUnderflow);\n    }\n    Ok(c)\n}\n\n// Reference:\n// https://github.com/balancer/balancer-core/blob/f4ed5d65362a8d6cec21662fb6eae233b0babc1f/contracts/BNum.sol#L52\n#[inline]\npub fn bsub_sign(a: U256, b: U256) -> (U256, bool) {\n    if a >= b {\n        (a - b, false)\n    } else {\n        (b - a, true)\n    }\n}\n\n// Reference:\n// https://github.com/balancer/balancer-core/blob/f4ed5d65362a8d6cec21662fb6eae233b0babc1f/contracts/BNum.sol#L63C4-L73C6\n#[inline]\npub fn bmul(a: U256, b: U256) -> Result<U256, BalancerError> {\n    let c0 = a * b;\n    if a != U256::ZERO && c0 / a != b {\n        return Err(BalancerError::MulOverflow);\n    }\n    let c1 = c0 + (BONE / U256_2);\n    if c1 < c0 {\n        return Err(BalancerError::MulOverflow);\n    }\n    Ok(c1 / BONE)\n}\n\n/**********************************************************************************************\n// calcSpotPrice                                                                             //\n// sP = spotPrice                                                                            //\n// bI = tokenBalanceIn                ( bI / wI )         1                                  //\n// bO = tokenBalanceOut         sP =  -----------  *  ----------                             //\n// wI = tokenWeightIn                 ( bO / wO )     ( 1 - sF )                             //\n// wO = tokenWeightOut                                                                       //\n// sF = swapFee                                                                              //\n **********************************************************************************************/\npub fn calculate_price(\n    b_i: U256,\n    w_i: U256,\n    b_o: U256,\n    w_o: U256,\n    s_f: U256,\n) -> Result<U256, BalancerError> {\n    let numer = bdiv(b_i, w_i)?;\n    let denom = bdiv(b_o, w_o)?;\n    let ratio = bdiv(numer, denom)?;\n    let scale = bdiv(BONE, bsub(BONE, s_f)?)?;\n    bmul(ratio, scale)\n}\n\n/**********************************************************************************************\n// calcOutGivenIn                                                                            //\n// aO = tokenAmountOut                                                                       //\n// bO = tokenBalanceOut                                                                      //\n// bI = tokenBalanceIn              /      /            bI             \\    (wI / wO) \\      //\n// aI = tokenAmountIn    aO = bO * |  1 - | --------------------------  | ^            |     //\n// wI = tokenWeightIn               \\      \\ ( bI + ( aI * ( 1 - sF )) /              /      //\n// wO = tokenWeightOut                                                                       //\n// sF = swapFee                                                                              //\n **********************************************************************************************/\npub fn calculate_out_given_in(\n    token_balance_in: U256,\n    token_weight_in: U256,\n    token_balance_out: U256,\n    token_weight_out: U256,\n    token_amount_in: U256,\n    swap_fee: U256,\n) -> Result<U256, BalancerError> {\n    let weight_ratio = bdiv(token_weight_in, token_weight_out)?;\n    let adjusted_in = bsub(BONE, swap_fee)?;\n    let adjusted_in = bmul(token_amount_in, adjusted_in)?;\n    let y = bdiv(token_balance_in, badd(token_balance_in, adjusted_in)?)?;\n    let x = bpow(y, weight_ratio)?;\n    let z = bsub(BONE, x)?;\n    bmul(token_balance_out, z)\n}\n"
  },
  {
    "path": "src/amms/balancer/mod.rs",
    "content": "pub mod bmath;\n\nuse std::{collections::HashMap, future::Future};\n\nuse alloy::{\n    eips::BlockId,\n    network::Network,\n    primitives::{Address, B256, U256},\n    providers::Provider,\n    rpc::types::{Filter, FilterSet, Log},\n    sol,\n    sol_types::{SolEvent, SolValue},\n};\nuse async_trait::async_trait;\nuse futures::{stream::FuturesUnordered, StreamExt};\nuse itertools::Itertools;\nuse rug::{float::Round, Float};\nuse serde::{Deserialize, Serialize};\nuse thiserror::Error;\nuse tracing::info;\n\nuse super::{\n    amm::{AutomatedMarketMaker, AMM},\n    consts::{BONE, MPFR_T_PRECISION},\n    error::AMMError,\n    factory::{AutomatedMarketMakerFactory, DiscoverySync},\n    float::u256_to_float,\n    Token,\n};\n\nsol! {\n    #[derive(Debug, PartialEq, Eq)]\n    #[sol(rpc)]\n    contract IBPool {\n        event LOG_SWAP(\n            address indexed caller,\n            address indexed tokenIn,\n            address indexed tokenOut,\n            uint256         tokenAmountIn,\n            uint256         tokenAmountOut\n        );\n\n        event LOG_JOIN(\n            address indexed caller,\n            address indexed tokenIn,\n            uint256         tokenAmountIn\n        );\n\n        event LOG_EXIT(\n            address indexed caller,\n            address indexed tokenOut,\n            uint256         tokenAmountOut\n        );\n\n        function getSpotPrice(address tokenIn, address tokenOut) external returns (uint256);\n        function calcOutGivenIn(\n            uint tokenBalanceIn,\n            uint tokenWeightIn,\n            uint tokenBalanceOut,\n            uint tokenWeightOut,\n            uint tokenAmountIn,\n            uint swapFee\n        )\n             external\n            returns (uint);\n    }\n\n    #[derive(Debug, PartialEq, Eq)]\n    #[sol(rpc)]\n    contract IBFactory {\n        event LOG_NEW_POOL(\n            address indexed caller,\n            address indexed pool\n        );\n    }\n}\n\nsol!(\n    #[allow(missing_docs)]\n    #[sol(rpc)]\n    IGetBalancerPoolDataBatchRequest,\n    \"src/amms/abi/GetBalancerPoolDataBatchRequest.json\"\n);\n\n#[derive(Error, Debug)]\npub enum BalancerError {\n    #[error(\"Error initializing Balancer Pool\")]\n    InitializationError,\n    #[error(\"Token in does not exist\")]\n    TokenInDoesNotExist,\n    #[error(\"Token out does not exist\")]\n    TokenOutDoesNotExist,\n    #[error(\"Division by zero\")]\n    DivZero,\n    #[error(\"Error during division\")]\n    DivInternal,\n    #[error(\"Addition overflow\")]\n    AddOverflow,\n    #[error(\"Subtraction underflow\")]\n    SubUnderflow,\n    #[error(\"Multiplication overflow\")]\n    MulOverflow,\n}\n\n#[derive(Default, Debug, Serialize, Deserialize, Clone)]\npub struct BalancerPool {\n    /// The Pool Address.\n    address: Address,\n    state: HashMap<Address, TokenPoolState>,\n    /// The Swap Fee on the Pool.\n    fee: u32,\n}\n\n#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]\npub struct TokenPoolState {\n    pub liquidity: U256,\n    pub weight: U256,\n    pub token: Token,\n}\n\nimpl AutomatedMarketMaker for BalancerPool {\n    /// Returns the address of the AMM.\n    fn address(&self) -> Address {\n        self.address\n    }\n\n    fn sync_events(&self) -> Vec<B256> {\n        vec![\n            IBPool::LOG_SWAP::SIGNATURE_HASH,\n            IBPool::LOG_JOIN::SIGNATURE_HASH,\n            IBPool::LOG_EXIT::SIGNATURE_HASH,\n        ]\n    }\n\n    fn sync(&mut self, log: &Log) -> Result<(), AMMError> {\n        let signature = log.topics()[0];\n\n        if IBPool::LOG_SWAP::SIGNATURE_HASH == signature {\n            let swap_event = IBPool::LOG_SWAP::decode_log(log.as_ref())?;\n\n            self.state\n                .get_mut(&swap_event.tokenIn)\n                .ok_or(BalancerError::TokenInDoesNotExist)?\n                .liquidity += swap_event.tokenAmountIn;\n\n            self.state\n                .get_mut(&swap_event.tokenOut)\n                .ok_or(BalancerError::TokenOutDoesNotExist)?\n                .liquidity += swap_event.tokenAmountOut;\n\n            info!(\n                target = \"amm::balancer::sync\",\n                address = ?self.address,\n                state = ?self.state, \"Sync\"\n            );\n        } else if IBPool::LOG_JOIN::SIGNATURE_HASH == signature {\n            let join_event = IBPool::LOG_JOIN::decode_log(log.as_ref())?;\n\n            self.state\n                .get_mut(&join_event.tokenIn)\n                .ok_or(BalancerError::TokenInDoesNotExist)?\n                .liquidity += join_event.tokenAmountIn;\n\n            info!(\n                target = \"amm::balancer::sync\",\n                address = ?self.address,\n                state = ?self.state, \"Join\"\n            );\n        } else if IBPool::LOG_EXIT::SIGNATURE_HASH == signature {\n            let exit_event = IBPool::LOG_JOIN::decode_log(log.as_ref())?;\n\n            self.state\n                .get_mut(&exit_event.tokenIn)\n                .ok_or(BalancerError::TokenInDoesNotExist)?\n                .liquidity -= exit_event.tokenAmountIn;\n\n            info!(\n                target = \"amm::balancer::sync\",\n                address = ?self.address,\n                state = ?self.state, \"Exit\"\n            );\n        } else {\n            return Err(AMMError::UnrecognizedEventSignature(signature));\n        }\n\n        Ok(())\n    }\n\n    /// Returns a vector of tokens in the AMM.\n    fn tokens(&self) -> Vec<Address> {\n        self.state.keys().cloned().collect()\n    }\n\n    /// Calculates a f64 representation of base token price in the AMM. This is a \"tax inclusive\" spot approximation.\n    /// **********************************************************************************************\n    /// calcSpotPrice                                                                             //\n    /// sP = spotPrice                                                                            //\n    /// bI = tokenBalanceIn                ( bI / wI )         1                                  //\n    /// bO = tokenBalanceOut         sP =  -----------  *  ----------                             //\n    /// wI = tokenWeightIn                 ( bO / wO )     ( 1 - sF )                             //\n    /// wO = tokenWeightOut                                                                       //\n    /// sF = swapFee                                                                              //\n    ///**********************************************************************************************/\n    fn calculate_price(&self, base_token: Address, quote_token: Address) -> Result<f64, AMMError> {\n        let token_in = self\n            .state\n            .get(&base_token)\n            .ok_or(BalancerError::TokenInDoesNotExist)?;\n\n        let token_out = self\n            .state\n            .get(&quote_token)\n            .ok_or(BalancerError::TokenOutDoesNotExist)?;\n\n        let bone = u256_to_float(BONE)?;\n        let norm_base = if token_in.token.decimals < 18 {\n            Float::with_val(\n                MPFR_T_PRECISION,\n                10_u64.pow(18 - token_in.token.decimals as u32),\n            )\n        } else {\n            Float::with_val(MPFR_T_PRECISION, 1)\n        };\n        let norm_quote = if token_out.token.decimals < 18 {\n            Float::with_val(\n                MPFR_T_PRECISION,\n                10_u64.pow(18 - token_out.token.decimals as u32),\n            )\n        } else {\n            Float::with_val(MPFR_T_PRECISION, 1)\n        };\n\n        let norm_weight_base = u256_to_float(token_in.weight)? / norm_base;\n        let norm_weight_quote = u256_to_float(token_out.weight)? / norm_quote;\n        let balance_base = u256_to_float(token_in.liquidity)?;\n        let balance_quote = u256_to_float(token_out.liquidity)?;\n\n        let dividend = (balance_quote / norm_weight_quote) * bone.clone();\n        let divisor = (balance_base / norm_weight_base)\n            * (bone - Float::with_val(MPFR_T_PRECISION, self.fee));\n        let ratio = dividend / divisor;\n        Ok(ratio.to_f64_round(Round::Nearest))\n    }\n\n    /// Locally simulates a swap in the AMM.\n    ///\n    /// # Returns\n    /// The amount received for `amount_in` of `token_in`.\n    fn simulate_swap(\n        &self,\n        base_token: Address,\n        quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        let token_in = self\n            .state\n            .get(&base_token)\n            .ok_or(BalancerError::TokenInDoesNotExist)?;\n\n        let token_out = self\n            .state\n            .get(&quote_token)\n            .ok_or(BalancerError::TokenOutDoesNotExist)?;\n\n        Ok(bmath::calculate_out_given_in(\n            token_in.liquidity,\n            token_in.weight,\n            token_out.liquidity,\n            token_out.weight,\n            amount_in,\n            U256::from(self.fee),\n        )?)\n    }\n\n    /// Locally simulates a swap in the AMM.\n    /// Mutates the AMM state to the state of the AMM after swapping.\n    ///\n    /// # Returns\n    /// The amount received for `amount_in` of `token_in`.\n    fn simulate_swap_mut(\n        &mut self,\n        base_token: Address,\n        quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        let token_in = self\n            .state\n            .get(&base_token)\n            .ok_or(BalancerError::TokenInDoesNotExist)?;\n\n        let token_out = self\n            .state\n            .get(&quote_token)\n            .ok_or(BalancerError::TokenOutDoesNotExist)?;\n\n        let out = bmath::calculate_out_given_in(\n            token_in.liquidity,\n            token_in.weight,\n            token_out.liquidity,\n            token_out.weight,\n            amount_in,\n            U256::from(self.fee),\n        )?;\n\n        self.state.get_mut(&base_token).unwrap().liquidity += amount_in;\n        self.state.get_mut(&quote_token).unwrap().liquidity -= out;\n\n        Ok(out)\n    }\n\n    async fn init<N, P>(mut self, block_number: BlockId, provider: P) -> Result<Self, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let deployer =\n            IGetBalancerPoolDataBatchRequest::deploy_builder(provider, vec![self.address]);\n        let res = deployer.block(block_number).call_raw().await?;\n\n        let mut data =\n            <Vec<(Vec<Address>, Vec<u16>, Vec<U256>, Vec<U256>, u32)> as SolValue>::abi_decode(\n                &res,\n            )?;\n        let (tokens, decimals, liquidity, weights, fee) = if !data.is_empty() {\n            data.remove(0)\n        } else {\n            return Err(BalancerError::InitializationError.into());\n        };\n\n        let token_state = tokens\n            .into_iter()\n            .zip(decimals)\n            .zip(liquidity)\n            .zip(weights)\n            .map(|(((token, decimals), liquidity), weight)| {\n                (\n                    token,\n                    TokenPoolState {\n                        liquidity,\n                        weight,\n                        token: Token::new_with_decimals(token, decimals as u8),\n                    },\n                )\n            })\n            .collect::<HashMap<Address, TokenPoolState>>();\n\n        self.state = token_state;\n        self.fee = fee;\n\n        Ok(self)\n    }\n}\n\nimpl BalancerPool {\n    #[allow(clippy::too_many_arguments)]\n    pub fn new(address: Address) -> BalancerPool {\n        BalancerPool {\n            address,\n            ..Default::default()\n        }\n    }\n}\n\n#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)]\npub struct BalancerFactory {\n    pub address: Address,\n    pub creation_block: u64,\n}\n\n#[async_trait]\nimpl AutomatedMarketMakerFactory for BalancerFactory {\n    type PoolVariant = BalancerPool;\n\n    /// Address of the factory contract\n    fn address(&self) -> Address {\n        self.address\n    }\n\n    /// Creates an unsynced pool from a creation log.\n    fn create_pool(&self, log: Log) -> Result<AMM, AMMError> {\n        let pool_data = IBFactory::LOG_NEW_POOL::decode_log(&log.inner)?;\n        Ok(AMM::BalancerPool(BalancerPool {\n            address: pool_data.pool,\n            ..Default::default()\n        }))\n    }\n\n    /// Returns the block number at which the factory was created.\n    fn creation_block(&self) -> u64 {\n        self.creation_block\n    }\n\n    /// Event signature that indicates when a new pool was created\n    fn pool_creation_event(&self) -> B256 {\n        IBFactory::LOG_NEW_POOL::SIGNATURE_HASH\n    }\n}\n\nimpl DiscoverySync for BalancerFactory {\n    fn discover<N, P>(\n        &self,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        info!(\n            target = \"amms::balancer::discover\",\n            address = ?self.address,\n            \"Discovering all pools\"\n        );\n        self.get_all_pools(to_block, provider)\n    }\n\n    fn sync<N, P>(\n        &self,\n        amms: Vec<AMM>,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        info!(\n            target = \"amms::balancer::sync\",\n            address = ?self.address,\n            \"Syncing all pools\"\n        );\n        Self::sync_all_pools(amms, to_block, provider)\n    }\n}\n\nimpl BalancerFactory {\n    pub fn new(address: Address, creation_block: u64) -> BalancerFactory {\n        BalancerFactory {\n            address,\n            creation_block,\n        }\n    }\n\n    pub async fn get_all_pools<N, P>(\n        &self,\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<Vec<AMM>, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone + Clone,\n    {\n        let disc_filter = Filter::new()\n            .event_signature(FilterSet::from(vec![self.pool_creation_event()]))\n            .address(vec![self.address()]);\n\n        let sync_provider = provider.clone();\n        let mut futures = FuturesUnordered::new();\n\n        let sync_step = 100_000;\n        let mut latest_block = self.creation_block;\n        while latest_block < block_number.as_u64().unwrap_or_default() {\n            let mut block_filter = disc_filter.clone();\n            let from_block = latest_block;\n            let to_block = (from_block + sync_step).min(block_number.as_u64().unwrap_or_default());\n\n            block_filter = block_filter.from_block(from_block);\n            block_filter = block_filter.to_block(to_block);\n\n            let sync_provider = sync_provider.clone();\n\n            futures.push(async move { sync_provider.get_logs(&block_filter).await });\n\n            latest_block = to_block + 1;\n        }\n\n        let mut pools = vec![];\n        while let Some(res) = futures.next().await {\n            let logs = res?;\n\n            for log in logs {\n                pools.push(self.create_pool(log)?);\n            }\n        }\n\n        Ok(pools)\n    }\n\n    pub async fn sync_all_pools<N, P>(\n        amms: Vec<AMM>,\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<Vec<AMM>, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let step = 120;\n        let pairs = amms\n            .iter()\n            .chunks(step)\n            .into_iter()\n            .map(|chunk| chunk.map(|amm| amm.address()).collect())\n            .collect::<Vec<Vec<Address>>>();\n\n        let mut futures_unordered = FuturesUnordered::new();\n        for group in pairs {\n            let deployer =\n                IGetBalancerPoolDataBatchRequest::deploy_builder(provider.clone(), group.clone());\n\n            futures_unordered.push(async move {\n                let res = deployer.call_raw().block(block_number).await?;\n\n                let return_data = <Vec<(Vec<Address>, Vec<u16>, Vec<U256>, Vec<U256>, u32)> as SolValue>::abi_decode(\n                    &res,\n                )?;\n\n                Ok::<(Vec<Address>, Vec<(Vec<Address>, Vec<u16>, Vec<U256>, Vec<U256>, u32)>), AMMError>((\n                    group,\n                    return_data,\n                ))\n            });\n        }\n\n        let mut amms = amms\n            .into_iter()\n            .map(|amm| (amm.address(), amm))\n            .collect::<HashMap<_, _>>();\n\n        while let Some(res) = futures_unordered.next().await {\n            let (group, return_data) = res?;\n            for (pool_data, pool_address) in return_data.iter().zip(group.iter()) {\n                let amm = amms.get_mut(pool_address).unwrap();\n\n                let AMM::BalancerPool(pool) = amm else {\n                    panic!(\"Unexpected pool type\")\n                };\n\n                let tokens = pool_data.0.clone();\n                let decimals = pool_data.1.clone();\n                let liquidity = pool_data.2.clone();\n                let weights = pool_data.3.clone();\n\n                let token_state = tokens\n                    .into_iter()\n                    .zip(decimals)\n                    .zip(liquidity)\n                    .zip(weights)\n                    .map(|(((token, decimals), liquidity), weight)| {\n                        (\n                            token,\n                            TokenPoolState {\n                                liquidity,\n                                weight,\n                                token: Token::new_with_decimals(token, decimals as u8),\n                            },\n                        )\n                    })\n                    .collect::<HashMap<Address, TokenPoolState>>();\n\n                pool.state = token_state;\n                pool.fee = pool_data.4;\n            }\n        }\n\n        let amms = amms\n            .into_iter()\n            .filter_map(|(_, amm)| {\n                if amm.tokens().iter().any(|t| t.is_zero()) {\n                    None\n                } else {\n                    Some(amm)\n                }\n            })\n            .collect();\n\n        Ok(amms)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::sync::Arc;\n\n    use alloy::{\n        primitives::{address, U256},\n        providers::ProviderBuilder,\n    };\n    use eyre::Ok;\n\n    use crate::amms::{\n        amm::AutomatedMarketMaker,\n        balancer::{BalancerPool, IBPool::IBPoolInstance},\n    };\n    use crate::amms::{balancer::TokenPoolState, Token};\n\n    #[tokio::test]\n    pub async fn test_populate_data() -> eyre::Result<()> {\n        let provider = Arc::new(\n            ProviderBuilder::new()\n                .connect_http(std::env::var(\"ETHEREUM_PROVIDER\")?.parse().unwrap()),\n        );\n\n        let balancer_pool = BalancerPool::new(address!(\"8a649274E4d777FFC6851F13d23A86BBFA2f2Fbf\"))\n            .init(22000236.into(), provider.clone())\n            .await?;\n\n        let weth =\n            Token::new_with_decimals(address!(\"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\"), 18);\n        let usdc =\n            Token::new_with_decimals(address!(\"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\"), 6);\n\n        let weth_state = balancer_pool.state.get(weth.address()).unwrap();\n\n        assert_eq!(\n            *weth_state,\n            TokenPoolState {\n                liquidity: U256::from(10512868599101770417_u128),\n                weight: U256::from(25000000000000000000_u128),\n                token: weth,\n            }\n        );\n\n        let usdc_state = balancer_pool.state.get(usdc.address()).unwrap();\n\n        assert_eq!(\n            *usdc_state,\n            TokenPoolState {\n                liquidity: U256::from(22394300283_u128),\n                weight: U256::from(25000000000000000000_u128),\n                token: usdc,\n            }\n        );\n\n        // Validate the fee\n        let expected_fee = 640942080;\n        assert_eq!(\n            balancer_pool.fee, expected_fee,\n            \"Fee does not match expected value\"\n        );\n\n        Ok(())\n    }\n\n    #[tokio::test]\n    pub async fn test_calculate_price() -> eyre::Result<()> {\n        let provider = Arc::new(\n            ProviderBuilder::new()\n                .connect_http(std::env::var(\"ETHEREUM_PROVIDER\")?.parse().unwrap()),\n        );\n\n        let balancer_pool = BalancerPool::new(address!(\"8a649274E4d777FFC6851F13d23A86BBFA2f2Fbf\"))\n            .init(20487793.into(), provider.clone())\n            .await?;\n\n        let calculated = balancer_pool\n            .calculate_price(\n                address!(\"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\"),\n                address!(\"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\"),\n            )\n            .unwrap();\n\n        assert_eq!(calculated, 2662.153859723404_f64);\n        Ok(())\n    }\n\n    #[tokio::test]\n    pub async fn test_simulate_swap() -> eyre::Result<()> {\n        let provider = Arc::new(\n            ProviderBuilder::new()\n                .connect_http(std::env::var(\"ETHEREUM_PROVIDER\")?.parse().unwrap()),\n        );\n\n        let balancer_pool = BalancerPool::new(address!(\"8a649274E4d777FFC6851F13d23A86BBFA2f2Fbf\"))\n            .init(20487793.into(), provider.clone())\n            .await?;\n\n        println!(\"Balancer V2 Pool: {:?}\", balancer_pool);\n\n        let token_in = address!(\"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\");\n        let token_out = address!(\"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\");\n\n        let amount_in = U256::from(10_u64.pow(18));\n        let calculated = balancer_pool.simulate_swap(token_in, token_out, amount_in)?;\n\n        let b_pool_quoter = IBPoolInstance::new(\n            address!(\"8a649274E4d777FFC6851F13d23A86BBFA2f2Fbf\"),\n            provider.clone(),\n        );\n\n        let token_in = balancer_pool.state.get(&token_in).unwrap();\n        let token_out = balancer_pool.state.get(&token_out).unwrap();\n\n        let expected = b_pool_quoter\n            .calcOutGivenIn(\n                token_in.liquidity,\n                token_in.weight,\n                token_out.liquidity,\n                token_out.weight,\n                amount_in,\n                U256::from(balancer_pool.fee),\n            )\n            .call()\n            .await\n            .unwrap();\n\n        assert_eq!(calculated, expected);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "src/amms/consts.rs",
    "content": "use alloy::primitives::U256;\n\n// commonly used U256s\npub const U256_10E_10: U256 = U256::from_limbs([10000000000, 0, 0, 0]);\npub const U256_0X100000000: U256 = U256::from_limbs([4294967296, 0, 0, 0]);\npub const U256_0X10000: U256 = U256::from_limbs([65536, 0, 0, 0]);\npub const U256_0X100: U256 = U256::from_limbs([256, 0, 0, 0]);\npub const U256_1000: U256 = U256::from_limbs([1000, 0, 0, 0]);\npub const U256_10000: U256 = U256::from_limbs([10000, 0, 0, 0]);\npub const U256_100000: U256 = U256::from_limbs([100000, 0, 0, 0]);\npub const U256_255: U256 = U256::from_limbs([255, 0, 0, 0]);\npub const U256_192: U256 = U256::from_limbs([192, 0, 0, 0]);\npub const U256_191: U256 = U256::from_limbs([191, 0, 0, 0]);\npub const U256_128: U256 = U256::from_limbs([128, 0, 0, 0]);\npub const U256_64: U256 = U256::from_limbs([64, 0, 0, 0]);\npub const U256_32: U256 = U256::from_limbs([32, 0, 0, 0]);\npub const U256_16: U256 = U256::from_limbs([16, 0, 0, 0]);\npub const U256_10: U256 = U256::from_limbs([10, 0, 0, 0]);\npub const U256_8: U256 = U256::from_limbs([8, 0, 0, 0]);\npub const U256_4: U256 = U256::from_limbs([4, 0, 0, 0]);\npub const U256_2: U256 = U256::from_limbs([2, 0, 0, 0]);\npub const U256_1: U256 = U256::from_limbs([1, 0, 0, 0]);\n\n// Uniswap V3 specific\npub const POPULATE_TICK_DATA_STEP: u64 = 100000;\npub const Q128: U256 = U256::from_limbs([0, 0, 1, 0]);\npub const Q224: U256 = U256::from_limbs([0, 0, 0, 4294967296]);\n\n// Balancer V2 specific\npub const BONE: U256 = U256::from_limbs([0xDE0B6B3A7640000, 0, 0, 0]);\n\n// Others\npub const U128_0X10000000000000000: u128 = 18446744073709551616;\npub const U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF: U256 = U256::from_limbs([\n    18446744073709551615,\n    18446744073709551615,\n    18446744073709551615,\n    0,\n]);\npub const U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF: U256 =\n    U256::from_limbs([18446744073709551615, 18446744073709551615, 0, 0]);\n\npub const DECIMAL_RADIX: i32 = 10;\npub const MPFR_T_PRECISION: u32 = 70;\n"
  },
  {
    "path": "src/amms/erc_4626/mod.rs",
    "content": "use super::{\n    amm::AutomatedMarketMaker,\n    consts::{U128_0X10000000000000000, U256_10000, U256_2},\n    error::AMMError,\n    float::q64_to_float,\n    uniswap_v2::div_uu,\n};\nuse alloy::{\n    eips::BlockId,\n    network::Network,\n    primitives::{Address, B256, U256},\n    providers::Provider,\n    rpc::types::Log,\n    sol,\n    sol_types::{SolEvent, SolValue},\n};\nuse serde::{Deserialize, Serialize};\nuse std::cmp::Ordering;\nuse thiserror::Error;\nuse tracing::info;\n\nsol! {\n    /// Interface of the IERC4626Valut contract\n    #[derive(Debug, PartialEq, Eq)]\n    #[sol(rpc)]\n    contract IERC4626Vault {\n        event Withdraw(address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares);\n        event Deposit(address indexed sender,address indexed owner, uint256 assets, uint256 shares);\n        function totalAssets() external view returns (uint256);\n        function totalSupply() external view returns (uint256);\n    }\n}\n\nsol! {\n    #[allow(missing_docs)]\n    #[sol(rpc)]\n    IGetERC4626VaultDataBatchRequest,\n    \"src/amms/abi/GetERC4626VaultDataBatchRequest.json\",\n}\n\n#[derive(Error, Debug)]\npub enum ERC4626VaultError {\n    #[error(\"Non relative or zero fee\")]\n    NonRelativeOrZeroFee,\n    #[error(\"Division by zero\")]\n    DivisionByZero,\n    #[error(\"Initialization error\")]\n    InitializationError,\n}\n\n#[derive(Debug, Clone, Default, Serialize, Deserialize)]\npub struct ERC4626Vault {\n    /// Token received from depositing, i.e. shares token\n    pub vault_token: Address,\n    pub vault_token_decimals: u8,\n    /// Token received from withdrawing, i.e. underlying token\n    pub asset_token: Address,\n    pub asset_token_decimals: u8,\n    /// Total supply of vault tokens\n    pub vault_reserve: U256,\n    /// Total balance of asset tokens held by vault\n    pub asset_reserve: U256,\n    /// Deposit fee in basis points\n    pub deposit_fee: u32,\n    /// Withdrawal fee in basis points\n    pub withdraw_fee: u32,\n}\n\nimpl AutomatedMarketMaker for ERC4626Vault {\n    fn address(&self) -> Address {\n        self.vault_token\n    }\n\n    fn sync_events(&self) -> Vec<B256> {\n        vec![\n            IERC4626Vault::Deposit::SIGNATURE_HASH,\n            IERC4626Vault::Withdraw::SIGNATURE_HASH,\n        ]\n    }\n\n    fn sync(&mut self, log: &Log) -> Result<(), AMMError> {\n        let event_signature = log.data().topics()[0];\n        match event_signature {\n            IERC4626Vault::Deposit::SIGNATURE_HASH => {\n                let deposit_event = IERC4626Vault::Deposit::decode_log(log.as_ref())?;\n                self.asset_reserve += deposit_event.assets;\n                self.vault_reserve += deposit_event.shares;\n\n                info!(\n                    target = \"amms::erc_4626::sync\",\n                    address = ?self.vault_token,\n                    asset_reserve = ?self.asset_reserve,\n                    vault_reserve = ?self.vault_reserve,\n                    \"Deposit\"\n                );\n            }\n\n            IERC4626Vault::Withdraw::SIGNATURE_HASH => {\n                let withdraw_event = IERC4626Vault::Withdraw::decode_log(log.as_ref())?;\n                self.asset_reserve -= withdraw_event.assets;\n                self.vault_reserve -= withdraw_event.shares;\n\n                info!(\n                    target = \"amms::erc_4626::sync\",\n                    address = ?self.vault_token,\n                    asset_reserve = ?self.asset_reserve,\n                    vault_reserve = ?self.vault_reserve,\n                    \"Withdraw\"\n                );\n            }\n\n            _ => {\n                return Err(AMMError::UnrecognizedEventSignature(event_signature));\n            }\n        }\n\n        Ok(())\n    }\n\n    fn tokens(&self) -> Vec<Address> {\n        vec![self.vault_token, self.asset_token]\n    }\n\n    fn calculate_price(&self, base_token: Address, _quote_token: Address) -> Result<f64, AMMError> {\n        q64_to_float(self.calculate_price_64_x_64(base_token)?)\n    }\n\n    fn simulate_swap(\n        &self,\n        base_token: Address,\n        _quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        if self.vault_token == base_token {\n            Ok(self.get_amount_out(amount_in, self.vault_reserve, self.asset_reserve)?)\n        } else {\n            Ok(self.get_amount_out(amount_in, self.asset_reserve, self.vault_reserve)?)\n        }\n    }\n\n    fn simulate_swap_mut(\n        &mut self,\n        base_token: Address,\n        _quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        if self.vault_token == base_token {\n            let amount_out =\n                self.get_amount_out(amount_in, self.vault_reserve, self.asset_reserve)?;\n\n            self.vault_reserve -= amount_in;\n            self.asset_reserve -= amount_out;\n\n            Ok(amount_out)\n        } else {\n            let amount_out =\n                self.get_amount_out(amount_in, self.asset_reserve, self.vault_reserve)?;\n\n            self.asset_reserve += amount_in;\n            self.vault_reserve += amount_out;\n\n            Ok(amount_out)\n        }\n    }\n\n    // TODO: clean up this function\n    async fn init<N, P>(mut self, block_number: BlockId, provider: P) -> Result<Self, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let deployer =\n            IGetERC4626VaultDataBatchRequest::deploy_builder(provider, vec![self.vault_token]);\n        let res = deployer.call_raw().block(block_number).await?;\n\n        let data = <Vec<(\n            Address,\n            u16,\n            Address,\n            u16,\n            U256,\n            U256,\n            U256,\n            U256,\n            U256,\n            U256,\n            U256,\n            U256,\n        )> as SolValue>::abi_decode(&res)?;\n        let (\n            vault_token,\n            vault_token_dec,\n            asset_token,\n            asset_token_dec,\n            vault_reserve,\n            asset_reserve,\n            deposit_fee_delta_1,\n            deposit_fee_delta_2,\n            deposit_no_fee,\n            withdraw_fee_delta_1,\n            withdraw_fee_delta_2,\n            withdraw_no_fee,\n        ) = if !data.is_empty() {\n            data[0]\n        } else {\n            return Err(ERC4626VaultError::InitializationError)?;\n        };\n\n        // If both deltas are zero, the fee is zero\n        if deposit_fee_delta_1.is_zero() && deposit_fee_delta_2.is_zero() {\n            self.deposit_fee = 0;\n\n        // Assuming 18 decimals, if the delta of 1e20 is half the delta of 2e20, relative fee.\n        // Delta / (amount without fee / 10000) to give us the fee in basis points\n        } else if deposit_fee_delta_1 * U256_2 == deposit_fee_delta_2 {\n            self.deposit_fee = (deposit_fee_delta_1 / (deposit_no_fee / U256::from(10_000))).to();\n        } else {\n            todo!(\"Handle error\")\n        }\n\n        // If both deltas are zero, the fee is zero\n        if withdraw_fee_delta_1.is_zero() && withdraw_fee_delta_2.is_zero() {\n            self.withdraw_fee = 0;\n        // Assuming 18 decimals, if the delta of 1e20 is half the delta of 2e20, relative fee.\n        // Delta / (amount without fee / 10000) to give us the fee in basis points\n        } else if withdraw_fee_delta_1 * U256::from(2) == withdraw_fee_delta_2 {\n            self.withdraw_fee =\n                (withdraw_fee_delta_1 / (withdraw_no_fee / U256::from(10_000))).to();\n        } else {\n            // If not a relative fee or zero, ignore vault\n            return Err(ERC4626VaultError::NonRelativeOrZeroFee.into());\n        }\n\n        // if above does not error => populate the vault\n        self.vault_token = vault_token;\n        self.vault_token_decimals = vault_token_dec as u8;\n        self.asset_token = asset_token;\n        self.asset_token_decimals = asset_token_dec as u8;\n        self.vault_reserve = vault_reserve;\n        self.asset_reserve = asset_reserve;\n\n        Ok(self)\n    }\n}\n\n// TODO: swap calldata\nimpl ERC4626Vault {\n    // Returns a new, unsynced ERC4626 vault\n    pub fn new(address: Address) -> Self {\n        Self {\n            vault_token: address,\n            ..Default::default()\n        }\n    }\n\n    pub fn get_amount_out(\n        &self,\n        amount_in: U256,\n        reserve_in: U256,\n        reserve_out: U256,\n    ) -> Result<U256, AMMError> {\n        if amount_in.is_zero() {\n            return Ok(U256::ZERO);\n        }\n\n        if self.vault_reserve.is_zero() {\n            return Ok(amount_in);\n        }\n\n        let fee = if reserve_in == self.vault_reserve {\n            self.withdraw_fee\n        } else {\n            self.deposit_fee\n        };\n\n        if reserve_in.is_zero() || 10000 - fee == 0 {\n            return Err(ERC4626VaultError::DivisionByZero.into());\n        }\n\n        Ok(amount_in * reserve_out / reserve_in * U256::from(10000 - fee) / U256_10000)\n    }\n\n    pub fn calculate_price_64_x_64(&self, base_token: Address) -> Result<u128, AMMError> {\n        let decimal_shift = self.vault_token_decimals as i8 - self.asset_token_decimals as i8;\n\n        // Normalize reserves by decimal shift\n        let (r_v, r_a) = match decimal_shift.cmp(&0) {\n            Ordering::Less => (\n                self.vault_reserve * U256::from(10u128.pow(decimal_shift.unsigned_abs() as u32)),\n                self.asset_reserve,\n            ),\n            _ => (\n                self.vault_reserve,\n                self.asset_reserve * U256::from(10u128.pow(decimal_shift as u32)),\n            ),\n        };\n\n        // Withdraw\n        if base_token == self.vault_token {\n            if r_v.is_zero() {\n                // Return 1 in Q64\n                Ok(U128_0X10000000000000000)\n            } else {\n                Ok(div_uu(r_a, r_v)?)\n            }\n        // Deposit\n        } else if r_a.is_zero() {\n            // Return 1 in Q64\n            Ok(U128_0X10000000000000000)\n        } else {\n            Ok(div_uu(r_v, r_a)?)\n        }\n    }\n\n    pub async fn get_reserves<N, P>(\n        &self,\n        provider: P,\n        block_number: BlockId,\n    ) -> Result<(U256, U256), AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone + Clone,\n    {\n        let vault = IERC4626Vault::new(self.vault_token, provider);\n\n        let total_assets = vault.totalAssets().block(block_number).call().await?;\n\n        let total_supply = vault.totalSupply().block(block_number).call().await?;\n\n        Ok((total_supply, total_assets))\n    }\n}\n"
  },
  {
    "path": "src/amms/error.rs",
    "content": "use super::{\n    balancer::BalancerError, erc_4626::ERC4626VaultError, uniswap_v2::UniswapV2Error,\n    uniswap_v3::UniswapV3Error,\n};\nuse alloy::{primitives::FixedBytes, transports::TransportErrorKind};\nuse thiserror::Error;\n\n#[derive(Error, Debug)]\npub enum AMMError {\n    #[error(transparent)]\n    TransportError(#[from] alloy::transports::RpcError<TransportErrorKind>),\n    #[error(transparent)]\n    ContractError(#[from] alloy::contract::Error),\n    #[error(transparent)]\n    ABIError(#[from] alloy::dyn_abi::Error),\n    #[error(transparent)]\n    SolTypesError(#[from] alloy::sol_types::Error),\n    #[error(transparent)]\n    UniswapV2Error(#[from] UniswapV2Error),\n    #[error(transparent)]\n    UniswapV3Error(#[from] UniswapV3Error),\n    #[error(transparent)]\n    BalancerError(#[from] BalancerError),\n    #[error(transparent)]\n    ERC4626VaultError(#[from] ERC4626VaultError),\n    #[error(transparent)]\n    BatchContractError(#[from] BatchContractError),\n    #[error(transparent)]\n    ParseFloatError(#[from] rug::float::ParseFloatError),\n    #[error(\"Unrecognized Event Signature {0}\")]\n    UnrecognizedEventSignature(FixedBytes<32>),\n    #[error(transparent)]\n    JoinError(#[from] tokio::task::JoinError),\n}\n\n#[derive(Error, Debug)]\npub enum BatchContractError {\n    #[error(transparent)]\n    ContractError(#[from] alloy::contract::Error),\n    #[error(transparent)]\n    DynABIError(#[from] alloy::dyn_abi::Error),\n}\n"
  },
  {
    "path": "src/amms/factory.rs",
    "content": "use super::{amm::Variant, uniswap_v2::UniswapV2Factory, uniswap_v3::UniswapV3Factory};\nuse super::{\n    amm::{AutomatedMarketMaker, AMM},\n    balancer::BalancerFactory,\n    error::AMMError,\n};\nuse alloy::{\n    eips::BlockId,\n    network::Network,\n    primitives::{Address, B256, U256},\n    providers::Provider,\n    rpc::types::eth::Log,\n};\nuse eyre::Result;\nuse serde::{Deserialize, Serialize};\nuse std::{\n    future::Future,\n    hash::{Hash, Hasher},\n};\n\npub trait DiscoverySync {\n    fn discover<N, P>(\n        &self,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone;\n\n    fn sync<N, P>(\n        &self,\n        amms: Vec<AMM>,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone;\n}\n\npub trait AutomatedMarketMakerFactory: DiscoverySync {\n    type PoolVariant: AutomatedMarketMaker + Default;\n\n    /// Address of the factory contract\n    fn address(&self) -> Address;\n\n    /// Creates an unsynced pool from a creation log.\n    fn create_pool(&self, log: Log) -> Result<AMM, AMMError>;\n\n    /// Returns the block number at which the factory was created.\n    fn creation_block(&self) -> u64;\n\n    /// Event signature that indicates when a new pool was created\n    fn pool_creation_event(&self) -> B256;\n\n    /// Event signatures signifying when a pool created by the factory should be synced\n    fn pool_events(&self) -> Vec<B256> {\n        Self::PoolVariant::default().sync_events()\n    }\n\n    fn pool_variant(&self) -> Self::PoolVariant {\n        Self::PoolVariant::default()\n    }\n}\n\nmacro_rules! factory {\n    ($($factory_type:ident),+ $(,)?) => {\n        #[derive(Debug, Clone, Serialize, Deserialize)]\n        pub enum Factory {\n            $($factory_type($factory_type),)+\n        }\n\n        impl Factory {\n             pub fn address(&self) -> Address {\n                match self {\n                    $(Factory::$factory_type(factory) => factory.address(),)+\n                }\n            }\n\n             pub fn discovery_event(&self) -> B256 {\n                match self {\n                    $(Factory::$factory_type(factory) => factory.pool_creation_event(),)+\n                }\n            }\n\n             pub fn create_pool(&self, log: Log) -> Result<AMM, AMMError> {\n                match self {\n                    $(Factory::$factory_type(factory) => factory.create_pool(log),)+\n                }\n            }\n\n             pub fn creation_block(&self) -> u64 {\n                match self {\n                    $(Factory::$factory_type(factory) => factory.creation_block(),)+\n                }\n            }\n\n             pub fn pool_events(&self) -> Vec<B256> {\n                match self {\n                    $(Factory::$factory_type(factory) => factory.pool_events(),)+\n                }\n            }\n\n            pub fn variant(&self) -> Variant {\n                match self {\n                    $(Factory::$factory_type(factory) => AMM::from(factory.pool_variant()).variant(),)+\n                }\n            }\n        }\n\n        impl Hash for Factory {\n            fn hash<H: Hasher>(&self, state: &mut H) {\n                self.address().hash(state);\n            }\n        }\n\n        impl PartialEq for Factory {\n            fn eq(&self, other: &Self) -> bool {\n                self.address() == other.address()\n            }\n        }\n\n        impl Eq for Factory {}\n\n\n        impl Factory {\n            pub async fn discover< N, P>(&self, to_block: BlockId, provider: P) -> Result<Vec<AMM>, AMMError>\n            where\n                                N: Network,\n                P: Provider<N> + Clone,\n            {\n                match self {\n                    $(Factory::$factory_type(factory) => factory.discover(to_block, provider).await,)+\n                }\n            }\n\n            pub async fn sync< N, P>(&self, amms: Vec<AMM>, to_block: BlockId, provider: P) -> Result<Vec<AMM>, AMMError>\n            where\n                                N: Network,\n                P: Provider<N> + Clone,\n            {\n                match self {\n                    $(Factory::$factory_type(factory) => factory.sync(amms, to_block, provider).await,)+\n                }\n            }\n        }\n\n        $(\n            impl From<$factory_type> for Factory {\n                fn from(factory: $factory_type) -> Self {\n                    Factory::$factory_type(factory)\n                }\n            }\n        )+\n    };\n}\n\nfactory!(UniswapV2Factory, UniswapV3Factory, BalancerFactory);\n\n#[derive(Default)]\npub struct NoopAMM;\nimpl AutomatedMarketMaker for NoopAMM {\n    fn address(&self) -> Address {\n        unreachable!()\n    }\n\n    fn sync_events(&self) -> Vec<B256> {\n        unreachable!()\n    }\n\n    fn sync(&mut self, _log: &Log) -> Result<(), AMMError> {\n        unreachable!()\n    }\n\n    fn simulate_swap(\n        &self,\n        _base_token: Address,\n        _quote_token: Address,\n        _amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        unreachable!()\n    }\n\n    fn simulate_swap_mut(\n        &mut self,\n        _base_token: Address,\n        _quote_token: Address,\n        _amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        unreachable!()\n    }\n    fn calculate_price(\n        &self,\n        _base_token: Address,\n        _quote_token: Address,\n    ) -> Result<f64, AMMError> {\n        unreachable!()\n    }\n\n    fn tokens(&self) -> Vec<Address> {\n        unreachable!()\n    }\n\n    async fn init<N, P>(self, _block_number: BlockId, _provider: P) -> Result<Self, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        unreachable!()\n    }\n}\n"
  },
  {
    "path": "src/amms/float.rs",
    "content": "use alloy::primitives::U256;\nuse rug::Float;\n\nuse super::{\n    consts::{MPFR_T_PRECISION, U128_0X10000000000000000},\n    error::AMMError,\n};\n\npub fn q64_to_float(num: u128) -> Result<f64, AMMError> {\n    let float_num = u128_to_float(num)?;\n    let divisor = u128_to_float(U128_0X10000000000000000)?;\n    Ok((float_num / divisor).to_f64())\n}\n\npub fn u128_to_float(num: u128) -> Result<Float, AMMError> {\n    let value_string = num.to_string();\n    let parsed_value = Float::parse_radix(value_string, 10)?;\n    Ok(Float::with_val(MPFR_T_PRECISION, parsed_value))\n}\n\npub fn u256_to_float(num: U256) -> Result<Float, AMMError> {\n    let value_string = num.to_string();\n    let parsed_value = Float::parse_radix(value_string, 10)?;\n    Ok(Float::with_val(MPFR_T_PRECISION, parsed_value))\n}\n"
  },
  {
    "path": "src/amms/mod.rs",
    "content": "use std::{\n    collections::HashMap,\n    hash::{Hash, Hasher},\n};\n\nuse alloy::{dyn_abi::DynSolType, network::Network, primitives::Address, providers::Provider, sol};\nuse error::{AMMError, BatchContractError};\nuse futures::{stream::FuturesUnordered, StreamExt};\nuse serde::{Deserialize, Serialize};\n\npub mod amm;\npub mod balancer;\npub mod consts;\npub mod erc_4626;\npub mod error;\npub mod factory;\npub mod float;\npub mod uniswap_v2;\npub mod uniswap_v3;\n\nsol! {\n    #[sol(rpc)]\n    GetTokenDecimalsBatchRequest,\n    \"src/amms/abi/GetTokenDecimalsBatchRequest.json\",\n}\n\nsol!(\n#[derive(Debug, PartialEq, Eq)]\n#[sol(rpc)]\ncontract IERC20 {\n    function decimals() external view returns (uint8);\n});\n\n#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]\npub struct Token {\n    pub address: Address,\n    pub decimals: u8,\n    // TODO: add optional tax\n}\n\nimpl Token {\n    pub async fn new<N, P>(address: Address, provider: P) -> Result<Self, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let decimals = IERC20::new(address, provider).decimals().call().await?;\n\n        Ok(Self { address, decimals })\n    }\n\n    pub const fn new_with_decimals(address: Address, decimals: u8) -> Self {\n        Self { address, decimals }\n    }\n\n    pub const fn address(&self) -> &Address {\n        &self.address\n    }\n\n    pub const fn decimals(&self) -> u8 {\n        self.decimals\n    }\n}\n\nimpl From<Address> for Token {\n    fn from(address: Address) -> Self {\n        Self {\n            address,\n            decimals: 0,\n        }\n    }\n}\n\nimpl Hash for Token {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        self.address.hash(state);\n    }\n}\n\n/// Fetches the decimal precision for a list of ERC-20 tokens.\n///\n/// # Returns\n/// A map of token addresses to their decimal precision.\npub async fn get_token_decimals<N, P>(\n    tokens: Vec<Address>,\n    provider: P,\n) -> Result<HashMap<Address, u8>, BatchContractError>\nwhere\n    N: Network,\n    P: Provider<N> + Clone + Clone,\n{\n    let step = 765;\n\n    let mut futures = FuturesUnordered::new();\n    tokens.chunks(step).for_each(|group| {\n        let provider = provider.clone();\n\n        futures.push(async move {\n            (\n                group,\n                GetTokenDecimalsBatchRequest::deploy_builder(provider, group.to_vec())\n                    .call_raw()\n                    .await,\n            )\n        });\n    });\n\n    let mut token_decimals = HashMap::new();\n    let return_type = DynSolType::Array(Box::new(DynSolType::Uint(8)));\n\n    while let Some(res) = futures.next().await {\n        let (token_addresses, return_data) = res;\n\n        let return_data = return_type.abi_decode_sequence(&return_data?)?;\n\n        if let Some(tokens_arr) = return_data.as_array() {\n            for (decimals, token_address) in tokens_arr.iter().zip(token_addresses.iter()) {\n                token_decimals.insert(\n                    *token_address,\n                    decimals.as_uint().expect(\"Could not get uint\").0.to::<u8>(),\n                );\n            }\n        }\n    }\n    Ok(token_decimals)\n}\n"
  },
  {
    "path": "src/amms/uniswap_v2/mod.rs",
    "content": "use super::{\n    amm::{AutomatedMarketMaker, AMM},\n    consts::{\n        MPFR_T_PRECISION, U128_0X10000000000000000, U256_0X100, U256_0X10000, U256_0X100000000,\n        U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,\n        U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, U256_1, U256_100000, U256_128,\n        U256_16, U256_191, U256_192, U256_2, U256_255, U256_32, U256_4, U256_64, U256_8,\n    },\n    error::AMMError,\n    factory::{AutomatedMarketMakerFactory, DiscoverySync},\n    float::q64_to_float,\n    Token,\n};\n\nuse alloy::{\n    eips::BlockId,\n    network::Network,\n    primitives::{Address, Bytes, B256, U256},\n    providers::Provider,\n    rpc::types::Log,\n    sol,\n    sol_types::{SolCall, SolEvent, SolValue},\n};\nuse futures::{stream::FuturesUnordered, StreamExt};\nuse itertools::Itertools;\nuse rug::Float;\nuse serde::{Deserialize, Serialize};\nuse std::{collections::HashMap, future::Future, hash::Hash};\nuse thiserror::Error;\nuse tracing::info;\nuse IGetUniswapV2PoolDataBatchRequest::IGetUniswapV2PoolDataBatchRequestInstance;\nuse IUniswapV2Factory::IUniswapV2FactoryInstance;\n\nsol!(\n// UniswapV2Factory\n#[allow(missing_docs)]\n#[derive(Debug)]\n#[sol(rpc)]\ncontract IUniswapV2Factory {\n    event PairCreated(address indexed token0, address indexed token1, address pair, uint256);\n    function allPairs(uint256) external view returns (address pair);\n    function allPairsLength() external view returns (uint256);\n\n}\n\n#[derive(Debug, PartialEq, Eq)]\n#[sol(rpc)]\ncontract IUniswapV2Pair {\n    event Sync(uint112 reserve0, uint112 reserve1);\n    function token0() external view returns (address);\n    function token1() external view returns (address);\n    function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data);\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n});\n\nsol!(\n    #[allow(missing_docs)]\n    #[sol(rpc)]\n    IGetUniswapV2PairsBatchRequest,\n    \"src/amms/abi/GetUniswapV2PairsBatchRequest.json\"\n);\n\nsol!(\n    #[allow(missing_docs)]\n    #[sol(rpc)]\n    IGetUniswapV2PoolDataBatchRequest,\n    \"src/amms/abi/GetUniswapV2PoolDataBatchRequest.json\"\n);\n\n#[derive(Error, Debug)]\npub enum UniswapV2Error {\n    #[error(\"Division by zero\")]\n    DivisionByZero,\n    #[error(\"Rounding Error\")]\n    RoundingError,\n}\n\n#[derive(Debug, Clone, Default, Serialize, Deserialize)]\npub struct UniswapV2Pool {\n    pub address: Address,\n    pub token_a: Token,\n    pub token_b: Token,\n    pub reserve_0: u128,\n    pub reserve_1: u128,\n    pub fee: usize,\n}\n\nimpl AutomatedMarketMaker for UniswapV2Pool {\n    fn address(&self) -> Address {\n        self.address\n    }\n\n    fn sync_events(&self) -> Vec<B256> {\n        vec![IUniswapV2Pair::Sync::SIGNATURE_HASH]\n    }\n\n    fn sync(&mut self, log: &Log) -> Result<(), AMMError> {\n        let sync_event = IUniswapV2Pair::Sync::decode_log(&log.inner)?;\n\n        let (reserve_0, reserve_1) = (\n            sync_event.reserve0.to::<u128>(),\n            sync_event.reserve1.to::<u128>(),\n        );\n\n        info!(\n            target = \"amm::uniswap_v2::sync\",\n            address = ?self.address,\n            reserve_0, reserve_1, \"Sync\"\n        );\n\n        self.reserve_0 = reserve_0;\n        self.reserve_1 = reserve_1;\n        Ok(())\n    }\n\n    fn simulate_swap(\n        &self,\n        base_token: Address,\n        _quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        if self.token_a.address == base_token {\n            Ok(self.get_amount_out(\n                amount_in,\n                U256::from(self.reserve_0),\n                U256::from(self.reserve_1),\n            ))\n        } else {\n            Ok(self.get_amount_out(\n                amount_in,\n                U256::from(self.reserve_1),\n                U256::from(self.reserve_0),\n            ))\n        }\n    }\n\n    fn simulate_swap_mut(\n        &mut self,\n        base_token: Address,\n        _quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        if self.token_a.address == base_token {\n            let amount_out = self.get_amount_out(\n                amount_in,\n                U256::from(self.reserve_0),\n                U256::from(self.reserve_1),\n            );\n\n            self.reserve_0 += amount_in.to::<u128>();\n            self.reserve_1 -= amount_out.to::<u128>();\n\n            Ok(amount_out)\n        } else {\n            let amount_out = self.get_amount_out(\n                amount_in,\n                U256::from(self.reserve_1),\n                U256::from(self.reserve_0),\n            );\n\n            self.reserve_0 -= amount_out.to::<u128>();\n            self.reserve_1 += amount_in.to::<u128>();\n\n            Ok(amount_out)\n        }\n    }\n\n    fn tokens(&self) -> Vec<Address> {\n        vec![self.token_a.address, self.token_b.address]\n    }\n\n    fn calculate_price(&self, base_token: Address, _quote_token: Address) -> Result<f64, AMMError> {\n        let price = self.calculate_price_64_x_64(base_token)?;\n        q64_to_float(price)\n    }\n\n    async fn init<N, P>(mut self, block_number: BlockId, provider: P) -> Result<Self, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let deployer = IGetUniswapV2PoolDataBatchRequestInstance::deploy_builder(\n            provider.clone(),\n            vec![self.address()],\n        );\n\n        let res = deployer.call_raw().block(block_number).await?;\n\n        let pool_data =\n            <Vec<(Address, Address, u128, u128, u32, u32)> as SolValue>::abi_decode(&res)?[0];\n\n        if pool_data.0.is_zero() {\n            todo!(\"Return error\");\n        }\n\n        self.token_a = Token::new_with_decimals(pool_data.0, pool_data.4 as u8);\n        self.token_b = Token::new_with_decimals(pool_data.1, pool_data.5 as u8);\n        self.reserve_0 = pool_data.2;\n        self.reserve_1 = pool_data.3;\n\n        // TODO: populate fee?\n\n        Ok(self)\n    }\n}\n\npub fn u128_to_float(num: u128) -> Result<Float, AMMError> {\n    let value_string = num.to_string();\n    let parsed_value = Float::parse_radix(value_string, 10)?;\n    Ok(Float::with_val(MPFR_T_PRECISION, parsed_value))\n}\n\nimpl UniswapV2Pool {\n    // Create a new, unsynced UniswapV2 pool\n    // TODO: update the init function to derive the fee\n    pub fn new(address: Address, fee: usize) -> Self {\n        Self {\n            address,\n            fee,\n            ..Default::default()\n        }\n    }\n\n    /// Calculates the amount received for a given `amount_in` `reserve_in` and `reserve_out`.\n    pub fn get_amount_out(&self, amount_in: U256, reserve_in: U256, reserve_out: U256) -> U256 {\n        if amount_in.is_zero() || reserve_in.is_zero() || reserve_out.is_zero() {\n            return U256::ZERO;\n        }\n        let fee = U256_100000 - U256::from(self.fee);\n        let amount_in = amount_in * fee;\n        let numerator = amount_in * reserve_out;\n        let denominator = reserve_in * U256_100000 + amount_in;\n\n        numerator / denominator\n    }\n\n    /// Calculates the price of the base token in terms of the quote token.\n    ///\n    /// Returned as a Q64 fixed point number.\n    pub fn calculate_price_64_x_64(&self, base_token: Address) -> Result<u128, AMMError> {\n        let decimal_shift = self.token_a.decimals as i8 - self.token_b.decimals as i8;\n\n        let (r_0, r_1) = if decimal_shift < 0 {\n            (\n                U256::from(self.reserve_0)\n                    * U256::from(10u128.pow(decimal_shift.unsigned_abs() as u32)),\n                U256::from(self.reserve_1),\n            )\n        } else {\n            (\n                U256::from(self.reserve_0),\n                U256::from(self.reserve_1) * U256::from(10u128.pow(decimal_shift as u32)),\n            )\n        };\n\n        if base_token == self.token_a.address {\n            if r_0.is_zero() {\n                Ok(U128_0X10000000000000000)\n            } else {\n                div_uu(r_1, r_0)\n            }\n        } else if r_1.is_zero() {\n            Ok(U128_0X10000000000000000)\n        } else {\n            div_uu(r_0, r_1)\n        }\n    }\n\n    pub fn swap_calldata(\n        &self,\n        amount_0_out: U256,\n        amount_1_out: U256,\n        to: Address,\n        calldata: Vec<u8>,\n    ) -> Result<Bytes, AMMError> {\n        Ok(IUniswapV2Pair::swapCall {\n            amount0Out: amount_0_out,\n            amount1Out: amount_1_out,\n            to,\n            data: calldata.into(),\n        }\n        .abi_encode()\n        .into())\n    }\n}\n\npub fn div_uu(x: U256, y: U256) -> Result<u128, AMMError> {\n    if !y.is_zero() {\n        let mut answer;\n\n        if x <= U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF {\n            answer = (x << U256_64) / y;\n        } else {\n            let mut msb = U256_192;\n            let mut xc = x >> U256_192;\n\n            if xc >= U256_0X100000000 {\n                xc >>= U256_32;\n                msb += U256_32;\n            }\n\n            if xc >= U256_0X10000 {\n                xc >>= U256_16;\n                msb += U256_16;\n            }\n\n            if xc >= U256_0X100 {\n                xc >>= U256_8;\n                msb += U256_8;\n            }\n\n            if xc >= U256_16 {\n                xc >>= U256_4;\n                msb += U256_4;\n            }\n\n            if xc >= U256_4 {\n                xc >>= U256_2;\n                msb += U256_2;\n            }\n\n            if xc >= U256_2 {\n                msb += U256_1;\n            }\n\n            answer = (x << (U256_255 - msb)) / (((y - U256_1) >> (msb - U256_191)) + U256_1);\n        }\n\n        if answer > U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF {\n            return Ok(0);\n        }\n\n        let hi = answer * (y >> U256_128);\n        let mut lo = answer * (y & U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n\n        let mut xh = x >> U256_192;\n        let mut xl = x << U256_64;\n\n        if xl < lo {\n            xh -= U256_1;\n        }\n\n        xl = xl.overflowing_sub(lo).0;\n        lo = hi << U256_128;\n\n        if xl < lo {\n            xh -= U256_1;\n        }\n\n        xl = xl.overflowing_sub(lo).0;\n\n        if xh != hi >> U256_128 {\n            return Err(UniswapV2Error::RoundingError.into());\n        }\n\n        answer += xl / y;\n\n        if answer > U256_0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF {\n            return Ok(0_u128);\n        }\n\n        Ok(answer.to::<u128>())\n    } else {\n        Err(UniswapV2Error::DivisionByZero.into())\n    }\n}\n\n#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]\npub struct UniswapV2Factory {\n    pub address: Address,\n    pub fee: usize,\n    pub creation_block: u64,\n}\n\nimpl UniswapV2Factory {\n    pub fn new(address: Address, fee: usize, creation_block: u64) -> Self {\n        Self {\n            address,\n            creation_block,\n            fee,\n        }\n    }\n\n    pub async fn get_all_pairs<N, P>(\n        factory_address: Address,\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<Vec<Address>, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let factory = IUniswapV2FactoryInstance::new(factory_address, provider.clone());\n        let pairs_length = factory\n            .allPairsLength()\n            .call()\n            .block(block_number)\n            .await?\n            .to::<usize>();\n\n        let step = 766;\n        let mut futures_unordered = FuturesUnordered::new();\n        for i in (0..pairs_length).step_by(step) {\n            // Note that the batch contract handles if the step is greater than the pairs length\n            // So we can pass the step in as is without checking for this condition\n            let deployer = IGetUniswapV2PairsBatchRequest::deploy_builder(\n                provider.clone(),\n                U256::from(i),\n                U256::from(step),\n                factory_address,\n            );\n\n            futures_unordered.push(async move {\n                let res = deployer.call_raw().block(block_number).await?;\n                let return_data = <Vec<Address> as SolValue>::abi_decode(&res)?;\n\n                Ok::<Vec<Address>, AMMError>(return_data)\n            });\n        }\n\n        let mut pairs = Vec::new();\n        while let Some(res) = futures_unordered.next().await {\n            let tokens = res?;\n            for token in tokens {\n                if !token.is_zero() {\n                    pairs.push(token);\n                }\n            }\n        }\n\n        Ok(pairs)\n    }\n\n    pub async fn sync_all_pools<N, P>(\n        amms: Vec<AMM>,\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<Vec<AMM>, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let step = 120;\n        let pairs = amms\n            .iter()\n            .chunks(step)\n            .into_iter()\n            .map(|chunk| chunk.map(|amm| amm.address()).collect())\n            .collect::<Vec<Vec<Address>>>();\n\n        let mut futures_unordered = FuturesUnordered::new();\n        for group in pairs {\n            let deployer = IGetUniswapV2PoolDataBatchRequestInstance::deploy_builder(\n                provider.clone(),\n                group.clone(),\n            );\n\n            futures_unordered.push(async move {\n                let res = deployer.call_raw().block(block_number).await?;\n\n                let return_data =\n                    <Vec<(Address, Address, u128, u128, u32, u32)> as SolValue>::abi_decode(&res)?;\n\n                Ok::<(Vec<Address>, Vec<(Address, Address, u128, u128, u32, u32)>), AMMError>((\n                    group,\n                    return_data,\n                ))\n            });\n        }\n\n        let mut amms = amms\n            .into_iter()\n            .map(|amm| (amm.address(), amm))\n            .collect::<HashMap<_, _>>();\n\n        while let Some(res) = futures_unordered.next().await {\n            let (group, return_data) = res?;\n            for (pool_data, pool_address) in return_data.iter().zip(group.iter()) {\n                // If the pool token A is not zero, signaling that the pool data was polulated\n\n                if pool_data.0.is_zero() {\n                    continue;\n                }\n\n                let amm = amms.get_mut(pool_address).unwrap();\n\n                let AMM::UniswapV2Pool(pool) = amm else {\n                    // TODO:: We should never receive a non UniswapV2Pool AMM here, we can handle this more gracefully in the future\n                    panic!(\"Unexpected pool type\")\n                };\n\n                pool.token_a = Token::new_with_decimals(pool_data.0, pool_data.4 as u8);\n                pool.token_b = Token::new_with_decimals(pool_data.1, pool_data.5 as u8);\n                pool.reserve_0 = pool_data.2;\n                pool.reserve_1 = pool_data.3;\n            }\n        }\n\n        let amms = amms\n            .into_iter()\n            .filter_map(|(_, amm)| {\n                if amm.tokens().iter().any(|t| t.is_zero()) {\n                    None\n                } else {\n                    Some(amm)\n                }\n            })\n            .collect();\n\n        Ok(amms)\n    }\n}\n\nimpl AutomatedMarketMakerFactory for UniswapV2Factory {\n    type PoolVariant = UniswapV2Pool;\n\n    fn address(&self) -> Address {\n        self.address\n    }\n\n    fn pool_creation_event(&self) -> B256 {\n        IUniswapV2Factory::PairCreated::SIGNATURE_HASH\n    }\n\n    fn create_pool(&self, log: Log) -> Result<AMM, AMMError> {\n        let event = IUniswapV2Factory::PairCreated::decode_log(&log.inner)?;\n        Ok(AMM::UniswapV2Pool(UniswapV2Pool {\n            address: event.pair,\n            token_a: event.token0.into(),\n            token_b: event.token1.into(),\n            reserve_0: 0,\n            reserve_1: 0,\n            fee: self.fee,\n        }))\n    }\n\n    fn creation_block(&self) -> u64 {\n        self.creation_block\n    }\n}\n\nimpl DiscoverySync for UniswapV2Factory {\n    fn discover<N, P>(\n        &self,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        info!(\n            target = \"amms::uniswap_v2::discover\",\n            address = ?self.address,\n            \"Discovering all pools\"\n        );\n\n        let provider = provider.clone();\n        async move {\n            let pairs =\n                UniswapV2Factory::get_all_pairs(self.address, to_block, provider.clone()).await?;\n\n            Ok(pairs\n                .into_iter()\n                .map(|pair| {\n                    AMM::UniswapV2Pool(UniswapV2Pool {\n                        address: pair,\n                        token_a: Address::default().into(),\n                        token_b: Address::default().into(),\n                        reserve_0: 0,\n                        reserve_1: 0,\n                        fee: self.fee,\n                    })\n                })\n                .collect())\n        }\n    }\n\n    fn sync<N, P>(\n        &self,\n        amms: Vec<AMM>,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        info!(\n            target = \"amms::uniswap_v2::sync\",\n            address = ?self.address,\n            \"Syncing all pools\"\n        );\n\n        UniswapV2Factory::sync_all_pools(amms, to_block, provider)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::amms::{\n        amm::AutomatedMarketMaker, consts::U256_100000, uniswap_v2::UniswapV2Pool, Token,\n    };\n    use alloy::primitives::{address, Address, U256};\n\n    #[test]\n    fn test_get_amount_out() {\n        let fees = [125, 150, 300, 1000]; // 0.125%, 0.15%, 0.3%, 1%\n        let amount_in = U256::from(10).pow(U256::from(18));\n        let reserve_in = U256::from(100).pow(U256::from(18));\n        let reserve_out = U256::from(100).pow(U256::from(18));\n        let amount_out_no_fee = (reserve_out * amount_in) / (reserve_in + amount_in);\n        for fee in fees {\n            let pool = UniswapV2Pool {\n                fee,\n                ..Default::default()\n            };\n\n            let res = pool.get_amount_out(amount_in, reserve_in, reserve_out);\n            assert!(amount_out_no_fee * (U256_100000 - U256::from(fee)) / U256_100000 == res);\n        }\n    }\n\n    #[test]\n    fn test_calculate_price_edge_case() {\n        let token_a = address!(\"0d500b1d8e8ef31e21c99d1db9a6444d3adf1270\");\n        let token_b = address!(\"8f18dc399594b451eda8c5da02d0563c0b2d0f16\");\n        let pool = UniswapV2Pool {\n            address: address!(\"B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc\"),\n            token_a: Token::new_with_decimals(\n                address!(\"A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\"),\n                6,\n            ),\n            token_b: Token::new_with_decimals(\n                address!(\"C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\"),\n                18,\n            ),\n            reserve_0: 23595096345912178729927,\n            reserve_1: 154664232014390554564,\n            fee: 300,\n        };\n\n        assert!(pool.calculate_price(token_a, Address::default()).unwrap() != 0.0);\n        assert!(pool.calculate_price(token_b, Address::default()).unwrap() != 0.0);\n    }\n\n    #[tokio::test]\n    async fn test_calculate_price() {\n        let pool = UniswapV2Pool {\n            address: address!(\"B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc\"),\n            token_a: Token::new_with_decimals(\n                address!(\"A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\"),\n                6,\n            ),\n            token_b: Token::new_with_decimals(\n                address!(\"C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\"),\n                18,\n            ),\n            reserve_0: 47092140895915,\n            reserve_1: 28396598565590008529300,\n            fee: 300,\n        };\n\n        let price_a_64_x = pool\n            .calculate_price(pool.token_a.address, Address::default())\n            .unwrap();\n        let price_b_64_x = pool\n            .calculate_price(pool.token_b.address, Address::default())\n            .unwrap();\n\n        // No precision loss: 30591574867092394336528 / 2**64\n        assert_eq!(1658.3725965327264, price_b_64_x);\n        // Precision loss: 11123401407064628 / 2**64\n        assert_eq!(0.0006030007985483893, price_a_64_x);\n    }\n\n    #[tokio::test]\n    async fn test_calculate_price_64_x_64() {\n        let pool = UniswapV2Pool {\n            address: address!(\"B4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc\"),\n            token_a: Token::new_with_decimals(\n                address!(\"A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\"),\n                6,\n            ),\n            token_b: Token::new_with_decimals(\n                address!(\"C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\"),\n                18,\n            ),\n            reserve_0: 47092140895915,\n            reserve_1: 28396598565590008529300,\n            fee: 300,\n        };\n\n        let price_a_64_x = pool.calculate_price_64_x_64(pool.token_a.address).unwrap();\n        let price_b_64_x = pool.calculate_price_64_x_64(pool.token_b.address).unwrap();\n\n        assert_eq!(30591574867092394336528, price_b_64_x);\n        assert_eq!(11123401407064628, price_a_64_x);\n    }\n}\n"
  },
  {
    "path": "src/amms/uniswap_v3/mod.rs",
    "content": "use super::{\n    amm::{AutomatedMarketMaker, AMM},\n    error::{AMMError, BatchContractError},\n    factory::{AutomatedMarketMakerFactory, DiscoverySync},\n    get_token_decimals, Token,\n};\nuse crate::amms::{\n    consts::U256_1, uniswap_v3::GetUniswapV3PoolTickBitmapBatchRequest::TickBitmapInfo,\n};\nuse alloy::{\n    eips::BlockId,\n    network::Network,\n    primitives::{Address, Bytes, Signed, B256, I256, U256},\n    providers::Provider,\n    rpc::types::{Filter, FilterSet, Log},\n    sol,\n    sol_types::{SolCall, SolEvent, SolValue},\n    transports::BoxFuture,\n};\nuse futures::{stream::FuturesUnordered, StreamExt};\nuse rayon::iter::{IntoParallelRefIterator, ParallelDrainRange, ParallelIterator};\nuse serde::{Deserialize, Serialize};\nuse std::{\n    cmp::Ordering,\n    collections::{HashMap, HashSet},\n    future::Future,\n    hash::Hash,\n    str::FromStr,\n};\nuse thiserror::Error;\nuse tracing::info;\nuse uniswap_v3_math::error::UniswapV3MathError;\nuse uniswap_v3_math::tick_math::{MAX_SQRT_RATIO, MAX_TICK, MIN_SQRT_RATIO, MIN_TICK};\nuse GetUniswapV3PoolTickDataBatchRequest::TickDataInfo;\n\nsol! {\n    // UniswapV3Factory\n    #[allow(missing_docs)]\n    #[derive(Debug)]\n    #[sol(rpc)]\n    contract IUniswapV3Factory {\n        /// @notice Emitted when a pool is created\n        event PoolCreated(\n            address indexed token0,\n            address indexed token1,\n            uint24 indexed fee,\n            int24 tickSpacing,\n            address pool\n        );\n    }\n\n    #[derive(Debug, PartialEq, Eq)]\n    #[sol(rpc)]\n    contract IUniswapV3PoolEvents {\n        /// @notice Emitted when liquidity is minted for a given position\n        event Mint(\n            address sender,\n            address indexed owner,\n            int24 indexed tickLower,\n            int24 indexed tickUpper,\n            uint128 amount,\n            uint256 amount0,\n            uint256 amount1\n        );\n\n        /// @notice Emitted when a position's liquidity is removed\n        event Burn(\n            address indexed owner,\n            int24 indexed tickLower,\n            int24 indexed tickUpper,\n            uint128 amount,\n            uint256 amount0,\n            uint256 amount1\n        );\n\n        /// @notice Emitted by the pool for any swaps between token0 and token1\n        event Swap(\n            address indexed sender,\n            address indexed recipient,\n            int256 amount0,\n            int256 amount1,\n            uint160 sqrtPriceX96,\n            uint128 liquidity,\n            int24 tick\n        );\n    }\n\n\n    #[derive(Debug, PartialEq, Eq)]\n    #[sol(rpc)]\n    contract IUniswapV3Pool {\n        function swap(address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes calldata data) external returns (int256, int256);\n        function tickSpacing() external view returns (int24);\n        function fee() external view returns (uint24);\n        function token0() external view returns (address);\n        function token1() external view returns (address);\n\n    }\n}\n\nsol! {\n    #[sol(rpc)]\n    GetUniswapV3PoolSlot0BatchRequest,\n    \"src/amms/abi/GetUniswapV3PoolSlot0BatchRequest.json\",\n}\n\nsol! {\n    #[sol(rpc)]\n    GetUniswapV3PoolTickBitmapBatchRequest,\n    \"src/amms/abi/GetUniswapV3PoolTickBitmapBatchRequest.json\",\n}\n\nsol! {\n    #[sol(rpc)]\n    GetUniswapV3PoolTickDataBatchRequest,\n    \"src/amms/abi/GetUniswapV3PoolTickDataBatchRequest.json\"\n}\n\n#[derive(Error, Debug)]\npub enum UniswapV3Error {\n    #[error(transparent)]\n    UniswapV3MathError(#[from] UniswapV3MathError),\n    #[error(\"Liquidity Underflow\")]\n    LiquidityUnderflow,\n}\n\n#[derive(Debug, Clone, Default, Serialize, Deserialize)]\npub struct UniswapV3Pool {\n    pub address: Address,\n    pub token_a: Token,\n    pub token_b: Token,\n    pub liquidity: u128,\n    pub sqrt_price: U256,\n    pub fee: u32,\n    pub tick: i32,\n    pub tick_spacing: i32, // TODO: we can make this a u8, tick spacing will never exceed 200\n    pub tick_bitmap: HashMap<i16, U256>,\n    pub ticks: HashMap<i32, Info>,\n}\n\n#[derive(Debug, Clone, Default, Serialize, Deserialize)]\npub struct Info {\n    pub liquidity_gross: u128,\n    pub liquidity_net: i128,\n    pub initialized: bool,\n}\n\nimpl Info {\n    pub fn new(liquidity_gross: u128, liquidity_net: i128, initialized: bool) -> Self {\n        Info {\n            liquidity_gross,\n            liquidity_net,\n            initialized,\n        }\n    }\n}\n\npub struct CurrentState {\n    amount_specified_remaining: I256,\n    amount_calculated: I256,\n    sqrt_price_x_96: U256,\n    tick: i32,\n    liquidity: u128,\n}\n\n#[derive(Default)]\npub struct StepComputations {\n    pub sqrt_price_start_x_96: U256,\n    pub tick_next: i32,\n    pub initialized: bool,\n    pub sqrt_price_next_x96: U256,\n    pub amount_in: U256,\n    pub amount_out: U256,\n    pub fee_amount: U256,\n}\n\npub struct Tick {\n    pub liquidity_gross: u128,\n    pub liquidity_net: i128,\n    pub fee_growth_outside_0_x_128: U256,\n    pub fee_growth_outside_1_x_128: U256,\n    pub tick_cumulative_outside: U256,\n    pub seconds_per_liquidity_outside_x_128: U256,\n    pub seconds_outside: u32,\n    pub initialized: bool,\n}\n\nimpl AutomatedMarketMaker for UniswapV3Pool {\n    fn address(&self) -> Address {\n        self.address\n    }\n\n    fn sync_events(&self) -> Vec<B256> {\n        vec![\n            IUniswapV3PoolEvents::Mint::SIGNATURE_HASH,\n            IUniswapV3PoolEvents::Burn::SIGNATURE_HASH,\n            IUniswapV3PoolEvents::Swap::SIGNATURE_HASH,\n        ]\n    }\n\n    fn sync(&mut self, log: &Log) -> Result<(), AMMError> {\n        let event_signature = log.topics()[0];\n        match event_signature {\n            IUniswapV3PoolEvents::Swap::SIGNATURE_HASH => {\n                let swap_event = IUniswapV3PoolEvents::Swap::decode_log(log.as_ref())?;\n\n                self.sqrt_price = swap_event.sqrtPriceX96.to();\n                self.liquidity = swap_event.liquidity;\n                self.tick = swap_event.tick.unchecked_into();\n\n                info!(\n                    target = \"amms::uniswap_v3::sync\",\n                    address = ?self.address,\n                    sqrt_price = ?self.sqrt_price,\n                    liquidity = ?self.liquidity,\n                    tick = ?self.tick,\n                    \"Swap\"\n                );\n            }\n            IUniswapV3PoolEvents::Mint::SIGNATURE_HASH => {\n                let mint_event = IUniswapV3PoolEvents::Mint::decode_log(log.as_ref())?;\n\n                self.modify_position(\n                    mint_event.tickLower.unchecked_into(),\n                    mint_event.tickUpper.unchecked_into(),\n                    mint_event.amount as i128,\n                )?;\n\n                info!(\n                    target = \"amms::uniswap_v3::sync\",\n                    address = ?self.address,\n                    sqrt_price = ?self.sqrt_price,\n                    liquidity = ?self.liquidity,\n                    tick = ?self.tick,\n                    \"Mint\"\n                );\n            }\n            IUniswapV3PoolEvents::Burn::SIGNATURE_HASH => {\n                let burn_event = IUniswapV3PoolEvents::Burn::decode_log(log.as_ref())?;\n\n                self.modify_position(\n                    burn_event.tickLower.unchecked_into(),\n                    burn_event.tickUpper.unchecked_into(),\n                    -(burn_event.amount as i128),\n                )?;\n\n                info!(\n                    target = \"amms::uniswap_v3::sync\",\n                    address = ?self.address,\n                    sqrt_price = ?self.sqrt_price,\n                    liquidity = ?self.liquidity,\n                    tick = ?self.tick,\n                    \"Burn\"\n                );\n            }\n            _ => {\n                return Err(AMMError::UnrecognizedEventSignature(event_signature));\n            }\n        }\n\n        Ok(())\n    }\n\n    fn simulate_swap(\n        &self,\n        base_token: Address,\n        _quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        if amount_in.is_zero() {\n            return Ok(U256::ZERO);\n        }\n\n        let zero_for_one = base_token == self.token_a.address;\n\n        // Set sqrt_price_limit_x_96 to the max or min sqrt price in the pool depending on zero_for_one\n        let sqrt_price_limit_x_96 = if zero_for_one {\n            MIN_SQRT_RATIO + U256_1\n        } else {\n            MAX_SQRT_RATIO - U256_1\n        };\n\n        // Initialize a mutable state state struct to hold the dynamic simulated state of the pool\n        let mut current_state = CurrentState {\n            sqrt_price_x_96: self.sqrt_price, // Active price on the pool\n            amount_calculated: I256::ZERO,    // Amount of token_out that has been calculated\n            amount_specified_remaining: I256::from_raw(amount_in), // Amount of token_in that has not been swapped\n            tick: self.tick,                                       // Current i24 tick of the pool\n            liquidity: self.liquidity, // Current available liquidity in the tick range\n        };\n\n        while current_state.amount_specified_remaining != I256::ZERO\n            && current_state.sqrt_price_x_96 != sqrt_price_limit_x_96\n        {\n            // Initialize a new step struct to hold the dynamic state of the pool at each step\n            let mut step = StepComputations {\n                // Set the sqrt_price_start_x_96 to the current sqrt_price_x_96\n                sqrt_price_start_x_96: current_state.sqrt_price_x_96,\n                ..Default::default()\n            };\n\n            // Get the next tick from the current tick\n            (step.tick_next, step.initialized) =\n                uniswap_v3_math::tick_bitmap::next_initialized_tick_within_one_word(\n                    &self.tick_bitmap,\n                    current_state.tick,\n                    self.tick_spacing,\n                    zero_for_one,\n                )\n                .map_err(UniswapV3Error::from)?;\n\n            // ensure that we do not overshoot the min/max tick, as the tick bitmap is not aware of these bounds\n            // Note: this could be removed as we are clamping in the batch contract\n            step.tick_next = step.tick_next.clamp(MIN_TICK, MAX_TICK);\n\n            // Get the next sqrt price from the input amount\n            step.sqrt_price_next_x96 =\n                uniswap_v3_math::tick_math::get_sqrt_ratio_at_tick(step.tick_next)\n                    .map_err(UniswapV3Error::from)?;\n\n            // Target spot price\n            let swap_target_sqrt_ratio = if zero_for_one {\n                if step.sqrt_price_next_x96 < sqrt_price_limit_x_96 {\n                    sqrt_price_limit_x_96\n                } else {\n                    step.sqrt_price_next_x96\n                }\n            } else if step.sqrt_price_next_x96 > sqrt_price_limit_x_96 {\n                sqrt_price_limit_x_96\n            } else {\n                step.sqrt_price_next_x96\n            };\n\n            // Compute swap step and update the current state\n            (\n                current_state.sqrt_price_x_96,\n                step.amount_in,\n                step.amount_out,\n                step.fee_amount,\n            ) = uniswap_v3_math::swap_math::compute_swap_step(\n                current_state.sqrt_price_x_96,\n                swap_target_sqrt_ratio,\n                current_state.liquidity,\n                current_state.amount_specified_remaining,\n                self.fee,\n            )\n            .map_err(UniswapV3Error::from)?;\n\n            // Decrement the amount remaining to be swapped and amount received from the step\n            current_state.amount_specified_remaining = current_state\n                .amount_specified_remaining\n                .overflowing_sub(I256::from_raw(\n                    step.amount_in.overflowing_add(step.fee_amount).0,\n                ))\n                .0;\n\n            current_state.amount_calculated -= I256::from_raw(step.amount_out);\n\n            // TODO: adjust for fee protocol\n\n            // If the price moved all the way to the next price, recompute the liquidity change for the next iteration\n            if current_state.sqrt_price_x_96 == step.sqrt_price_next_x96 {\n                if step.initialized {\n                    let mut liquidity_net = if let Some(info) = self.ticks.get(&step.tick_next) {\n                        info.liquidity_net\n                    } else {\n                        0\n                    };\n\n                    // we are on a tick boundary, and the next tick is initialized, so we must charge a protocol fee\n                    if zero_for_one {\n                        liquidity_net = -liquidity_net;\n                    }\n\n                    current_state.liquidity = if liquidity_net < 0 {\n                        if current_state.liquidity < (-liquidity_net as u128) {\n                            return Err(UniswapV3Error::LiquidityUnderflow.into());\n                        } else {\n                            current_state.liquidity - (-liquidity_net as u128)\n                        }\n                    } else {\n                        current_state.liquidity + (liquidity_net as u128)\n                    };\n                }\n                // Increment the current tick\n                current_state.tick = if zero_for_one {\n                    step.tick_next.wrapping_sub(1)\n                } else {\n                    step.tick_next\n                }\n                // If the current_state sqrt price is not equal to the step sqrt price, then we are not on the same tick.\n                // Update the current_state.tick to the tick at the current_state.sqrt_price_x_96\n            } else if current_state.sqrt_price_x_96 != step.sqrt_price_start_x_96 {\n                current_state.tick = uniswap_v3_math::tick_math::get_tick_at_sqrt_ratio(\n                    current_state.sqrt_price_x_96,\n                )\n                .map_err(UniswapV3Error::from)?;\n            }\n        }\n\n        let amount_out = (-current_state.amount_calculated).into_raw();\n\n        tracing::trace!(?amount_out);\n\n        Ok(amount_out)\n    }\n\n    fn simulate_swap_mut(\n        &mut self,\n        base_token: Address,\n        _quote_token: Address,\n        amount_in: U256,\n    ) -> Result<U256, AMMError> {\n        if amount_in.is_zero() {\n            return Ok(U256::ZERO);\n        }\n\n        let zero_for_one = base_token == self.token_a.address;\n\n        // Set sqrt_price_limit_x_96 to the max or min sqrt price in the pool depending on zero_for_one\n        let sqrt_price_limit_x_96 = if zero_for_one {\n            MIN_SQRT_RATIO + U256_1\n        } else {\n            MAX_SQRT_RATIO - U256_1\n        };\n\n        // Initialize a mutable state state struct to hold the dynamic simulated state of the pool\n        let mut current_state = CurrentState {\n            // Active price on the pool\n            sqrt_price_x_96: self.sqrt_price,\n            // Amount of token_out that has been calculated\n            amount_calculated: I256::ZERO,\n            // Amount of token_in that has not been swapped\n            amount_specified_remaining: I256::from_raw(amount_in),\n            // Current i24 tick of the pool\n            tick: self.tick,\n            // Current available liquidity in the tick range\n            liquidity: self.liquidity,\n        };\n\n        while current_state.amount_specified_remaining != I256::ZERO\n            && current_state.sqrt_price_x_96 != sqrt_price_limit_x_96\n        {\n            // Initialize a new step struct to hold the dynamic state of the pool at each step\n            let mut step = StepComputations {\n                // Set the sqrt_price_start_x_96 to the current sqrt_price_x_96\n                sqrt_price_start_x_96: current_state.sqrt_price_x_96,\n                ..Default::default()\n            };\n\n            // Get the next tick from the current tick\n            (step.tick_next, step.initialized) =\n                uniswap_v3_math::tick_bitmap::next_initialized_tick_within_one_word(\n                    &self.tick_bitmap,\n                    current_state.tick,\n                    self.tick_spacing,\n                    zero_for_one,\n                )\n                .map_err(UniswapV3Error::from)?;\n\n            // ensure that we do not overshoot the min/max tick, as the tick bitmap is not aware of these bounds\n            // Note: this could be removed as we are clamping in the batch contract\n            step.tick_next = step.tick_next.clamp(MIN_TICK, MAX_TICK);\n\n            // Get the next sqrt price from the input amount\n            step.sqrt_price_next_x96 =\n                uniswap_v3_math::tick_math::get_sqrt_ratio_at_tick(step.tick_next)\n                    .map_err(UniswapV3Error::from)?;\n\n            // Target spot price\n            let swap_target_sqrt_ratio = if zero_for_one {\n                if step.sqrt_price_next_x96 < sqrt_price_limit_x_96 {\n                    sqrt_price_limit_x_96\n                } else {\n                    step.sqrt_price_next_x96\n                }\n            } else if step.sqrt_price_next_x96 > sqrt_price_limit_x_96 {\n                sqrt_price_limit_x_96\n            } else {\n                step.sqrt_price_next_x96\n            };\n\n            // Compute swap step and update the current state\n            (\n                current_state.sqrt_price_x_96,\n                step.amount_in,\n                step.amount_out,\n                step.fee_amount,\n            ) = uniswap_v3_math::swap_math::compute_swap_step(\n                current_state.sqrt_price_x_96,\n                swap_target_sqrt_ratio,\n                current_state.liquidity,\n                current_state.amount_specified_remaining,\n                self.fee,\n            )\n            .map_err(UniswapV3Error::from)?;\n\n            // Decrement the amount remaining to be swapped and amount received from the step\n            current_state.amount_specified_remaining = current_state\n                .amount_specified_remaining\n                .overflowing_sub(I256::from_raw(\n                    step.amount_in.overflowing_add(step.fee_amount).0,\n                ))\n                .0;\n\n            current_state.amount_calculated -= I256::from_raw(step.amount_out);\n\n            // If the price moved all the way to the next price, recompute the liquidity change for the next iteration\n            if current_state.sqrt_price_x_96 == step.sqrt_price_next_x96 {\n                if step.initialized {\n                    let mut liquidity_net = if let Some(info) = self.ticks.get(&step.tick_next) {\n                        info.liquidity_net\n                    } else {\n                        0\n                    };\n\n                    // we are on a tick boundary, and the next tick is initialized, so we must charge a protocol fee\n                    if zero_for_one {\n                        liquidity_net = -liquidity_net;\n                    }\n\n                    current_state.liquidity = if liquidity_net < 0 {\n                        if current_state.liquidity < (-liquidity_net as u128) {\n                            return Err(AMMError::from(UniswapV3Error::LiquidityUnderflow));\n                        } else {\n                            current_state.liquidity - (-liquidity_net as u128)\n                        }\n                    } else {\n                        current_state.liquidity + (liquidity_net as u128)\n                    };\n                }\n                // Increment the current tick\n                current_state.tick = if zero_for_one {\n                    step.tick_next.wrapping_sub(1)\n                } else {\n                    step.tick_next\n                }\n                // If the current_state sqrt price is not equal to the step sqrt price, then we are not on the same tick.\n                // Update the current_state.tick to the tick at the current_state.sqrt_price_x_96\n            } else if current_state.sqrt_price_x_96 != step.sqrt_price_start_x_96 {\n                current_state.tick = uniswap_v3_math::tick_math::get_tick_at_sqrt_ratio(\n                    current_state.sqrt_price_x_96,\n                )\n                .map_err(UniswapV3Error::from)?;\n            }\n        }\n\n        // Update the pool state\n        self.liquidity = current_state.liquidity;\n        self.sqrt_price = current_state.sqrt_price_x_96;\n        self.tick = current_state.tick;\n\n        let amount_out = (-current_state.amount_calculated).into_raw();\n\n        tracing::trace!(?amount_out);\n\n        Ok(amount_out)\n    }\n\n    fn tokens(&self) -> Vec<Address> {\n        vec![self.token_a.address, self.token_b.address]\n    }\n\n    fn calculate_price(&self, base_token: Address, _quote_token: Address) -> Result<f64, AMMError> {\n        let tick = uniswap_v3_math::tick_math::get_tick_at_sqrt_ratio(self.sqrt_price)\n            .map_err(UniswapV3Error::from)?;\n        let shift = self.token_a.decimals as i8 - self.token_b.decimals as i8;\n\n        let price = match shift.cmp(&0) {\n            Ordering::Less => 1.0001_f64.powi(tick) / 10_f64.powi(-shift as i32),\n            Ordering::Greater => 1.0001_f64.powi(tick) * 10_f64.powi(shift as i32),\n            Ordering::Equal => 1.0001_f64.powi(tick),\n        };\n\n        if base_token == self.token_a.address {\n            Ok(price)\n        } else {\n            Ok(1.0 / price)\n        }\n    }\n\n    async fn init<N, P>(mut self, block_number: BlockId, provider: P) -> Result<Self, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let pool = IUniswapV3Pool::new(self.address, provider.clone());\n\n        // Get pool data\n        self.tick_spacing = pool.tickSpacing().call().await?.as_i32();\n        self.fee = pool.fee().call().await?.to::<u32>();\n\n        // Get tokens\n        self.token_a = Token::new(pool.token0().call().await?, provider.clone()).await?;\n        self.token_b = Token::new(pool.token1().call().await?, provider.clone()).await?;\n\n        let mut pool = vec![self.into()];\n        UniswapV3Factory::sync_slot_0(&mut pool, block_number, provider.clone()).await?;\n        UniswapV3Factory::sync_token_decimals(&mut pool, provider.clone()).await?;\n        UniswapV3Factory::sync_tick_bitmaps(&mut pool, block_number, provider.clone()).await?;\n        UniswapV3Factory::sync_tick_data(&mut pool, block_number, provider.clone()).await?;\n\n        let AMM::UniswapV3Pool(pool) = pool[0].to_owned() else {\n            unreachable!()\n        };\n\n        Ok(pool)\n    }\n}\n\nimpl UniswapV3Pool {\n    // Create a new, unsynced UniswapV3 pool\n    pub fn new(address: Address) -> Self {\n        Self {\n            address,\n            ..Default::default()\n        }\n    }\n\n    /// Modifies a positions liquidity in the pool.\n    pub fn modify_position(\n        &mut self,\n        tick_lower: i32,\n        tick_upper: i32,\n        liquidity_delta: i128,\n    ) -> Result<(), AMMError> {\n        //We are only using this function when a mint or burn event is emitted,\n        //therefore we do not need to checkTicks as that has happened before the event is emitted\n        self.update_position(tick_lower, tick_upper, liquidity_delta)?;\n\n        if liquidity_delta != 0 {\n            //if the tick is between the tick lower and tick upper, update the liquidity between the ticks\n            if self.tick >= tick_lower && self.tick < tick_upper {\n                self.liquidity = if liquidity_delta < 0 {\n                    self.liquidity - ((-liquidity_delta) as u128)\n                } else {\n                    self.liquidity + (liquidity_delta as u128)\n                }\n            }\n        }\n\n        Ok(())\n    }\n\n    pub fn update_position(\n        &mut self,\n        tick_lower: i32,\n        tick_upper: i32,\n        liquidity_delta: i128,\n    ) -> Result<(), AMMError> {\n        let mut flipped_lower = false;\n        let mut flipped_upper = false;\n\n        if liquidity_delta != 0 {\n            flipped_lower = self.update_tick(tick_lower, liquidity_delta, false)?;\n            flipped_upper = self.update_tick(tick_upper, liquidity_delta, true)?;\n            if flipped_lower {\n                self.flip_tick(tick_lower, self.tick_spacing);\n            }\n            if flipped_upper {\n                self.flip_tick(tick_upper, self.tick_spacing);\n            }\n        }\n\n        if liquidity_delta < 0 {\n            if flipped_lower {\n                self.ticks.remove(&tick_lower);\n            }\n\n            if flipped_upper {\n                self.ticks.remove(&tick_upper);\n            }\n        }\n\n        Ok(())\n    }\n\n    pub fn update_tick(\n        &mut self,\n        tick: i32,\n        liquidity_delta: i128,\n        upper: bool,\n    ) -> Result<bool, AMMError> {\n        let info = self.ticks.entry(tick).or_default();\n\n        let liquidity_gross_before = info.liquidity_gross;\n\n        let liquidity_gross_after = if liquidity_delta < 0 {\n            liquidity_gross_before - ((-liquidity_delta) as u128)\n        } else {\n            liquidity_gross_before + (liquidity_delta as u128)\n        };\n\n        // we do not need to check if liqudity_gross_after > maxLiquidity because we are only calling update tick on a burn or mint log.\n        // this should already be validated when a log is\n        let flipped = (liquidity_gross_after == 0) != (liquidity_gross_before == 0);\n\n        if liquidity_gross_before == 0 {\n            info.initialized = true;\n        }\n\n        info.liquidity_gross = liquidity_gross_after;\n\n        info.liquidity_net = if upper {\n            info.liquidity_net - liquidity_delta\n        } else {\n            info.liquidity_net + liquidity_delta\n        };\n\n        Ok(flipped)\n    }\n\n    pub fn flip_tick(&mut self, tick: i32, tick_spacing: i32) {\n        let (word_pos, bit_pos) = uniswap_v3_math::tick_bitmap::position(tick / tick_spacing);\n        let mask = U256::from(1) << bit_pos;\n\n        if let Some(word) = self.tick_bitmap.get_mut(&word_pos) {\n            *word ^= mask;\n        } else {\n            self.tick_bitmap.insert(word_pos, mask);\n        }\n    }\n\n    pub fn swap_calldata(\n        &self,\n        recipient: Address,\n        zero_for_one: bool,\n        amount_specified: I256,\n        sqrt_price_limit_x_96: U256,\n        calldata: Vec<u8>,\n    ) -> Result<Bytes, AMMError> {\n        Ok(IUniswapV3Pool::swapCall {\n            recipient,\n            zeroForOne: zero_for_one,\n            amountSpecified: amount_specified,\n            sqrtPriceLimitX96: sqrt_price_limit_x_96.to(),\n            data: calldata.into(),\n        }\n        .abi_encode()\n        .into())\n    }\n}\n\n#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]\npub struct UniswapV3Factory {\n    pub address: Address,\n    pub creation_block: u64,\n}\n\nimpl UniswapV3Factory {\n    pub fn new(address: Address, creation_block: u64) -> Self {\n        UniswapV3Factory {\n            address,\n            creation_block,\n        }\n    }\n\n    pub async fn get_all_pools<N, P>(\n        &self,\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<Vec<AMM>, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let disc_filter = Filter::new()\n            .event_signature(FilterSet::from(vec![self.pool_creation_event()]))\n            .address(vec![self.address()]);\n\n        let sync_provider = provider.clone();\n        let mut futures = FuturesUnordered::new();\n\n        let sync_step = 100_000;\n        let mut latest_block = self.creation_block;\n        while latest_block < block_number.as_u64().unwrap_or_default() {\n            let mut block_filter = disc_filter.clone();\n            let from_block = latest_block;\n            let to_block = (from_block + sync_step).min(block_number.as_u64().unwrap_or_default());\n\n            block_filter = block_filter.from_block(from_block);\n            block_filter = block_filter.to_block(to_block);\n\n            let sync_provider = sync_provider.clone();\n\n            futures.push(async move { sync_provider.get_logs(&block_filter).await });\n\n            latest_block = to_block + 1;\n        }\n\n        let mut pools = vec![];\n        while let Some(res) = futures.next().await {\n            let logs = res?;\n\n            for log in logs {\n                pools.push(self.create_pool(log)?);\n            }\n        }\n\n        Ok(pools)\n    }\n\n    pub async fn sync_all_pools<N, P>(\n        mut pools: Vec<AMM>,\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<Vec<AMM>, AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        UniswapV3Factory::sync_slot_0(&mut pools, block_number, provider.clone()).await?;\n        UniswapV3Factory::sync_token_decimals(&mut pools, provider.clone()).await?;\n\n        pools = pools\n            .par_drain(..)\n            .filter(|pool| match pool {\n                AMM::UniswapV3Pool(uv3_pool) => {\n                    uv3_pool.liquidity > 0\n                        && uv3_pool.token_a.decimals > 0\n                        && uv3_pool.token_b.decimals > 0\n                }\n                _ => true,\n            })\n            .collect();\n\n        UniswapV3Factory::sync_tick_bitmaps(&mut pools, block_number, provider.clone()).await?;\n        UniswapV3Factory::sync_tick_data(&mut pools, block_number, provider.clone()).await?;\n\n        Ok(pools)\n    }\n\n    async fn sync_token_decimals<N, P>(\n        pools: &mut [AMM],\n        provider: P,\n    ) -> Result<(), BatchContractError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        // Get all token decimals\n        let mut tokens = HashSet::new();\n        for pool in pools.iter() {\n            for token in pool.tokens() {\n                tokens.insert(token);\n            }\n        }\n        let token_decimals = get_token_decimals(tokens.into_iter().collect(), provider).await?;\n\n        // Set token decimals\n        for pool in pools.iter_mut() {\n            let AMM::UniswapV3Pool(uniswap_v3_pool) = pool else {\n                unreachable!()\n            };\n\n            if let Some(decimals) = token_decimals.get(&uniswap_v3_pool.token_a.address) {\n                uniswap_v3_pool.token_a.decimals = *decimals;\n            }\n\n            if let Some(decimals) = token_decimals.get(&uniswap_v3_pool.token_b.address) {\n                uniswap_v3_pool.token_b.decimals = *decimals;\n            }\n        }\n\n        Ok(())\n    }\n\n    async fn sync_slot_0<N, P>(\n        pools: &mut [AMM],\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<(), AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let step = 255;\n\n        let mut futures = FuturesUnordered::new();\n        pools.chunks_mut(step).for_each(|group| {\n            let provider = provider.clone();\n            let pool_addresses = group\n                .iter_mut()\n                .map(|pool| pool.address())\n                .collect::<Vec<_>>();\n\n            futures.push(async move {\n                Ok::<(&mut [AMM], Bytes), AMMError>((\n                    group,\n                    GetUniswapV3PoolSlot0BatchRequest::deploy_builder(provider, pool_addresses)\n                        .call_raw()\n                        .block(block_number)\n                        .await?,\n                ))\n            });\n        });\n\n        while let Some(res) = futures.next().await {\n            let (pools, return_data) = res?;\n            let return_data = <Vec<(i32, u128, U256)> as SolValue>::abi_decode(&return_data)?;\n\n            for (slot_0_data, pool) in return_data.iter().zip(pools.iter_mut()) {\n                let AMM::UniswapV3Pool(ref mut uv3_pool) = pool else {\n                    unreachable!()\n                };\n\n                uv3_pool.tick = slot_0_data.0;\n                uv3_pool.liquidity = slot_0_data.1;\n                uv3_pool.sqrt_price = slot_0_data.2;\n            }\n        }\n\n        Ok(())\n    }\n\n    async fn sync_tick_bitmaps<N, P>(\n        pools: &mut [AMM],\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<(), AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let mut futures: FuturesUnordered<BoxFuture<'_, _>> = FuturesUnordered::new();\n\n        let max_range = 6900;\n        let mut group_range = 0;\n        let mut group = vec![];\n\n        for pool in pools.iter() {\n            let AMM::UniswapV3Pool(uniswap_v3_pool) = pool else {\n                unreachable!()\n            };\n\n            let mut min_word = tick_to_word(MIN_TICK, uniswap_v3_pool.tick_spacing);\n            let max_word = tick_to_word(MAX_TICK, uniswap_v3_pool.tick_spacing);\n            let mut word_range = max_word - min_word;\n\n            while word_range > 0 {\n                let remaining_range = max_range - group_range;\n                let range = word_range.min(remaining_range);\n\n                group.push(TickBitmapInfo {\n                    pool: uniswap_v3_pool.address,\n                    minWord: min_word as i16,\n                    maxWord: (min_word + range) as i16,\n                });\n\n                word_range -= range;\n                min_word += range - 1;\n                group_range += range;\n\n                // If group is full, fire it off and reset\n                if group_range >= max_range {\n                    // if group_range >= max_range || word_range <= 0 {\n                    let provider = provider.clone();\n                    let pool_info = group.iter().map(|info| info.pool).collect::<Vec<_>>();\n\n                    let calldata = std::mem::take(&mut group);\n\n                    group_range = 0;\n\n                    futures.push(Box::pin(async move {\n                        Ok::<(Vec<Address>, Bytes), AMMError>((\n                            pool_info,\n                            GetUniswapV3PoolTickBitmapBatchRequest::deploy_builder(\n                                provider, calldata,\n                            )\n                            .call_raw()\n                            .block(block_number)\n                            .await?,\n                        ))\n                    }));\n                }\n            }\n        }\n\n        // Flush group if not empty\n        if !group.is_empty() {\n            let provider = provider.clone();\n            let pool_info = group.iter().map(|info| info.pool).collect::<Vec<_>>();\n\n            let calldata = std::mem::take(&mut group);\n\n            futures.push(Box::pin(async move {\n                Ok::<(Vec<Address>, Bytes), AMMError>((\n                    pool_info,\n                    GetUniswapV3PoolTickBitmapBatchRequest::deploy_builder(provider, calldata)\n                        .call_raw()\n                        .block(block_number)\n                        .await?,\n                ))\n            }));\n        }\n\n        let mut pool_set = pools\n            .iter_mut()\n            .map(|pool| (pool.address(), pool))\n            .collect::<HashMap<Address, &mut AMM>>();\n\n        while let Some(res) = futures.next().await {\n            let (pools, return_data) = res?;\n            let return_data = <Vec<Vec<U256>> as SolValue>::abi_decode(&return_data)?;\n\n            for (tick_bitmaps, pool_address) in return_data.iter().zip(pools.iter()) {\n                let pool = pool_set.get_mut(pool_address).unwrap();\n\n                let AMM::UniswapV3Pool(ref mut uv3_pool) = pool else {\n                    unreachable!()\n                };\n\n                for chunk in tick_bitmaps.chunks_exact(2) {\n                    let word_pos = I256::from_raw(chunk[0]).as_i16();\n                    let tick_bitmap = chunk[1];\n\n                    uv3_pool.tick_bitmap.insert(word_pos, tick_bitmap);\n                }\n            }\n        }\n        Ok(())\n    }\n\n    // TODO: Clean this function up\n    async fn sync_tick_data<N, P>(\n        pools: &mut [AMM],\n        block_number: BlockId,\n        provider: P,\n    ) -> Result<(), AMMError>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        let pool_ticks = pools\n            .par_iter()\n            .filter_map(|pool| {\n                if let AMM::UniswapV3Pool(uniswap_v3_pool) = pool {\n                    let min_word = tick_to_word(MIN_TICK, uniswap_v3_pool.tick_spacing);\n                    let max_word = tick_to_word(MAX_TICK, uniswap_v3_pool.tick_spacing);\n\n                    let initialized_ticks: Vec<Signed<24, 1>> = (min_word..=max_word)\n                        // Filter out empty bitmaps\n                        .filter_map(|word_pos| {\n                            uniswap_v3_pool\n                                .tick_bitmap\n                                .get(&(word_pos as i16))\n                                .filter(|&bitmap| *bitmap != U256::ZERO)\n                                .map(|&bitmap| (word_pos, bitmap))\n                        })\n                        // Get tick index for non zero bitmaps\n                        .flat_map(|(word_pos, bitmap)| {\n                            (0..256)\n                                .filter(move |i| {\n                                    (bitmap & (U256::from(1) << U256::from(*i))) != U256::ZERO\n                                })\n                                .map(move |i| {\n                                    let tick_index =\n                                        (word_pos * 256 + i) * uniswap_v3_pool.tick_spacing;\n\n                                    // TODO: update to use from be bytes or similar\n                                    Signed::<24, 1>::from_str(&tick_index.to_string()).unwrap()\n                                })\n                        })\n                        .collect();\n\n                    // Only return pools with non-empty initialized ticks\n                    if !initialized_ticks.is_empty() {\n                        Some((uniswap_v3_pool.address, initialized_ticks))\n                    } else {\n                        None\n                    }\n                } else {\n                    None\n                }\n            })\n            .collect::<Vec<(Address, Vec<Signed<24, 1>>)>>();\n\n        let mut futures: FuturesUnordered<BoxFuture<'_, _>> = FuturesUnordered::new();\n        let max_ticks = 60;\n        let mut group_ticks = 0;\n        let mut group = vec![];\n\n        for (pool_address, mut ticks) in pool_ticks {\n            while !ticks.is_empty() {\n                let remaining_ticks = max_ticks - group_ticks;\n                let selected_ticks = ticks.drain(0..remaining_ticks.min(ticks.len()));\n                group_ticks += selected_ticks.len();\n\n                group.push(GetUniswapV3PoolTickDataBatchRequest::TickDataInfo {\n                    pool: pool_address,\n                    ticks: selected_ticks.collect(),\n                });\n\n                if group_ticks >= max_ticks {\n                    let provider = provider.clone();\n                    let calldata = std::mem::take(&mut group);\n\n                    group_ticks = 0;\n                    group.clear();\n\n                    futures.push(Box::pin(async move {\n                        Ok::<(Vec<TickDataInfo>, Bytes), AMMError>((\n                            calldata.clone(),\n                            GetUniswapV3PoolTickDataBatchRequest::deploy_builder(\n                                provider, calldata,\n                            )\n                            .call_raw()\n                            .block(block_number)\n                            .await?,\n                        ))\n                    }));\n                }\n            }\n        }\n\n        if !group.is_empty() {\n            let provider = provider.clone();\n            let calldata = std::mem::take(&mut group);\n\n            futures.push(Box::pin(async move {\n                Ok::<(Vec<TickDataInfo>, Bytes), AMMError>((\n                    calldata.clone(),\n                    GetUniswapV3PoolTickDataBatchRequest::deploy_builder(provider, calldata)\n                        .call_raw()\n                        .block(block_number)\n                        .await?,\n                ))\n            }));\n        }\n\n        let mut pool_set = pools\n            .iter_mut()\n            .map(|pool| (pool.address(), pool))\n            .collect::<HashMap<Address, &mut AMM>>();\n\n        while let Some(res) = futures.next().await {\n            let (tick_info, return_data) = res?;\n            let return_data = <Vec<Vec<(bool, u128, i128)>> as SolValue>::abi_decode(&return_data)?;\n\n            for (tick_bitmaps, tick_info) in return_data.iter().zip(tick_info.iter()) {\n                let pool = pool_set.get_mut(&tick_info.pool).unwrap();\n\n                let AMM::UniswapV3Pool(ref mut uv3_pool) = pool else {\n                    unreachable!()\n                };\n\n                for (tick, tick_idx) in tick_bitmaps.iter().zip(tick_info.ticks.iter()) {\n                    let info = Info {\n                        liquidity_gross: tick.1,\n                        liquidity_net: tick.2,\n                        initialized: tick.0,\n                    };\n\n                    uv3_pool.ticks.insert(tick_idx.as_i32(), info);\n                }\n            }\n        }\n        Ok(())\n    }\n}\n\nfn tick_to_word(tick: i32, tick_spacing: i32) -> i32 {\n    let mut compressed = tick / tick_spacing;\n    if tick < 0 && tick % tick_spacing != 0 {\n        compressed -= 1;\n    }\n\n    compressed >> 8\n}\n\nimpl AutomatedMarketMakerFactory for UniswapV3Factory {\n    type PoolVariant = UniswapV3Pool;\n\n    fn address(&self) -> Address {\n        self.address\n    }\n\n    fn pool_creation_event(&self) -> B256 {\n        IUniswapV3Factory::PoolCreated::SIGNATURE_HASH\n    }\n\n    fn create_pool(&self, log: Log) -> Result<AMM, AMMError> {\n        let pool_created_event: alloy::primitives::Log<IUniswapV3Factory::PoolCreated> =\n            IUniswapV3Factory::PoolCreated::decode_log(&log.inner)?;\n\n        Ok(AMM::UniswapV3Pool(UniswapV3Pool {\n            address: pool_created_event.pool,\n            token_a: pool_created_event.token0.into(),\n            token_b: pool_created_event.token1.into(),\n            fee: pool_created_event.fee.to::<u32>(),\n            tick_spacing: pool_created_event.tickSpacing.unchecked_into(),\n            ..Default::default()\n        }))\n    }\n\n    fn creation_block(&self) -> u64 {\n        self.creation_block\n    }\n}\n\nimpl DiscoverySync for UniswapV3Factory {\n    fn discover<N, P>(\n        &self,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        info!(\n            target = \"amms::uniswap_v3::discover\",\n            address = ?self.address,\n            \"Discovering all pools\"\n        );\n\n        self.get_all_pools(to_block, provider.clone())\n    }\n\n    fn sync<N, P>(\n        &self,\n        amms: Vec<AMM>,\n        to_block: BlockId,\n        provider: P,\n    ) -> impl Future<Output = Result<Vec<AMM>, AMMError>>\n    where\n        N: Network,\n        P: Provider<N> + Clone,\n    {\n        info!(\n            target = \"amms::uniswap_v3::sync\",\n            address = ?self.address,\n            \"Syncing all pools\"\n        );\n\n        UniswapV3Factory::sync_all_pools(amms, to_block, provider)\n    }\n}\n\n#[cfg(test)]\nmod test {\n\n    use super::*;\n\n    use alloy::{\n        primitives::{address, aliases::U24, U160, U256},\n        providers::ProviderBuilder,\n        rpc::client::ClientBuilder,\n        transports::layers::{RetryBackoffLayer, ThrottleLayer},\n    };\n\n    sol! {\n        /// Interface of the Quoter\n        #[derive(Debug, PartialEq, Eq)]\n        #[sol(rpc)]\n        contract IQuoter {\n            function quoteExactInputSingle(address tokenIn, address tokenOut,uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96) external returns (uint256 amountOut);\n        }\n    }\n\n    #[tokio::test]\n    async fn test_simulate_swap_usdc_weth() -> eyre::Result<()> {\n        let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n\n        let client = ClientBuilder::default()\n            .layer(ThrottleLayer::new(250))\n            .layer(RetryBackoffLayer::new(5, 200, 330))\n            .http(rpc_endpoint.parse()?);\n\n        let provider = ProviderBuilder::new().connect_client(client);\n\n        let pool = UniswapV3Pool::new(address!(\"88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\"))\n            .init(BlockId::latest(), provider.clone())\n            .await?;\n\n        let quoter = IQuoter::new(\n            address!(\"b27308f9f90d607463bb33ea1bebb41c27ce5ab6\"),\n            provider.clone(),\n        );\n\n        // Test swap from USDC to WETH\n        let amount_in = U256::from(100000000); // 100 USDC\n        let amount_out = pool.simulate_swap(pool.token_a.address, Address::default(), amount_in)?;\n\n        dbg!(pool.token_a.address);\n        dbg!(pool.token_b.address);\n        dbg!(amount_in);\n        dbg!(amount_out);\n        dbg!(pool.fee);\n\n        let expected_amount_out = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n\n        assert_eq!(amount_out, expected_amount_out);\n\n        let amount_in_1 = U256::from(10000000000_u64); // 10_000 USDC\n        let amount_out_1 =\n            pool.simulate_swap(pool.token_a.address, Address::default(), amount_in_1)?;\n\n        let expected_amount_out_1 = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in_1,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_1, expected_amount_out_1);\n\n        let amount_in_2 = U256::from(10000000000000_u128); // 10_000_000 USDC\n        let amount_out_2 =\n            pool.simulate_swap(pool.token_a.address, Address::default(), amount_in_2)?;\n\n        let expected_amount_out_2 = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in_2,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_2, expected_amount_out_2);\n\n        let amount_in_3 = U256::from(100000000000000_u128); // 100_000_000 USDC\n        let amount_out_3 =\n            pool.simulate_swap(pool.token_a.address, Address::default(), amount_in_3)?;\n\n        let expected_amount_out_3 = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in_3,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_3, expected_amount_out_3);\n\n        // Test swap from WETH to USDC\n\n        let amount_in = U256::from(1000000000000000000_u128); // 1 ETH\n        let amount_out = pool.simulate_swap(pool.token_b.address, Address::default(), amount_in)?;\n        let expected_amount_out = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n        assert_eq!(amount_out, expected_amount_out);\n\n        let amount_in_1 = U256::from(10000000000000000000_u128); // 10 ETH\n        let amount_out_1 =\n            pool.simulate_swap(pool.token_b.address, Address::default(), amount_in_1)?;\n        let expected_amount_out_1 = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in_1,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n        assert_eq!(amount_out_1, expected_amount_out_1);\n\n        let amount_in_2 = U256::from(100000000000000000000_u128); // 100 ETH\n        let amount_out_2 =\n            pool.simulate_swap(pool.token_b.address, Address::default(), amount_in_2)?;\n        let expected_amount_out_2 = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in_2,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n        assert_eq!(amount_out_2, expected_amount_out_2);\n\n        let amount_in_3 = U256::from(100000000000000000000_u128); // 100_000 ETH\n        let amount_out_3 =\n            pool.simulate_swap(pool.token_b.address, Address::default(), amount_in_3)?;\n        let expected_amount_out_3 = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in_3,\n                U160::ZERO,\n            )\n            .block(BlockId::latest())\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_3, expected_amount_out_3);\n\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn test_simulate_swap_link_weth() -> eyre::Result<()> {\n        let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n\n        let client = ClientBuilder::default()\n            .layer(ThrottleLayer::new(250))\n            .layer(RetryBackoffLayer::new(5, 200, 330))\n            .http(rpc_endpoint.parse()?);\n\n        let provider = ProviderBuilder::new().connect_client(client);\n\n        let current_block = BlockId::from(provider.get_block_number().await?);\n\n        let pool = UniswapV3Pool::new(address!(\"5d4F3C6fA16908609BAC31Ff148Bd002AA6b8c83\"))\n            .init(current_block, provider.clone())\n            .await?;\n\n        let quoter = IQuoter::new(\n            address!(\"b27308f9f90d607463bb33ea1bebb41c27ce5ab6\"),\n            provider.clone(),\n        );\n\n        // Test swap LINK to WETH\n        let amount_in = U256::from(1000000000000000000_u128); // 1 LINK\n        let amount_out = pool.simulate_swap(pool.token_a.address, Address::default(), amount_in)?;\n        let expected_amount_out = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n\n        assert_eq!(amount_out, expected_amount_out);\n\n        let amount_in_1 = U256::from(100000000000000000000_u128); // 100 LINK\n        let amount_out_1 = pool\n            .simulate_swap(pool.token_a.address, Address::default(), amount_in_1)\n            .unwrap();\n        let expected_amount_out_1 = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in_1,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_1, expected_amount_out_1);\n\n        let amount_in_2 = U256::from(10000000000000000000000_u128); // 10_000 LINK\n        let amount_out_2 = pool\n            .simulate_swap(pool.token_a.address, Address::default(), amount_in_2)\n            .unwrap();\n        let expected_amount_out_2 = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in_2,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_2, expected_amount_out_2);\n\n        let amount_in_3 = U256::from(10000000000000000000000_u128); // 1_000_000 LINK\n        let amount_out_3 = pool\n            .simulate_swap(pool.token_a.address, Address::default(), amount_in_3)\n            .unwrap();\n        let expected_amount_out_3 = quoter\n            .quoteExactInputSingle(\n                pool.token_a.address,\n                pool.token_b.address,\n                U24::from(pool.fee),\n                amount_in_3,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_3, expected_amount_out_3);\n\n        // Test swap WETH to LINK\n\n        let amount_in = U256::from(1000000000000000000_u128); // 1 ETH\n        let amount_out = pool.simulate_swap(pool.token_b.address, Address::default(), amount_in)?;\n        let expected_amount_out = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n\n        assert_eq!(amount_out, expected_amount_out);\n\n        let amount_in_1 = U256::from(10000000000000000000_u128); // 10 ETH\n        let amount_out_1 =\n            pool.simulate_swap(pool.token_b.address, Address::default(), amount_in_1)?;\n        let expected_amount_out_1 = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in_1,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_1, expected_amount_out_1);\n\n        let amount_in_2 = U256::from(100000000000000000000_u128); // 100 ETH\n        let amount_out_2 =\n            pool.simulate_swap(pool.token_b.address, Address::default(), amount_in_2)?;\n        let expected_amount_out_2 = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in_2,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n        assert_eq!(amount_out_2, expected_amount_out_2);\n\n        let amount_in_3 = U256::from(100000000000000000000_u128); // 100_000 ETH\n        let amount_out_3 =\n            pool.simulate_swap(pool.token_b.address, Address::default(), amount_in_3)?;\n        let expected_amount_out_3 = quoter\n            .quoteExactInputSingle(\n                pool.token_b.address,\n                pool.token_a.address,\n                U24::from(pool.fee),\n                amount_in_3,\n                U160::ZERO,\n            )\n            .block(current_block)\n            .call()\n            .await?;\n\n        assert_eq!(amount_out_3, expected_amount_out_3);\n\n        Ok(())\n    }\n\n    #[tokio::test]\n    async fn test_calculate_price() -> eyre::Result<()> {\n        let rpc_endpoint = std::env::var(\"ETHEREUM_PROVIDER\")?;\n\n        let client = ClientBuilder::default()\n            .layer(ThrottleLayer::new(250))\n            .layer(RetryBackoffLayer::new(5, 200, 330))\n            .http(rpc_endpoint.parse()?);\n\n        let provider = ProviderBuilder::new().connect_client(client);\n\n        let block_number = BlockId::from(22000114);\n        let pool = UniswapV3Pool::new(address!(\"88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640\"))\n            .init(block_number, provider.clone())\n            .await?;\n\n        let float_price_a = pool.calculate_price(pool.token_a.address, Address::default())?;\n        let float_price_b = pool.calculate_price(pool.token_b.address, Address::default())?;\n        assert_eq!(float_price_a, 0.00046777681145863687);\n        assert_eq!(float_price_b, 2137.7716370372605);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "#![cfg_attr(not(test), warn(unused_crate_dependencies))]\n\npub mod amms;\npub mod state_space;\n"
  },
  {
    "path": "src/state_space/cache.rs",
    "content": "use std::collections::HashMap;\n\nuse crate::amms::amm::{AutomatedMarketMaker, AMM};\nuse arraydeque::ArrayDeque;\n\n#[derive(Debug)]\n\npub struct StateChangeCache<const CAP: usize> {\n    oldest_block: u64,\n    cache: ArrayDeque<StateChange, CAP>,\n}\n\nimpl<const CAP: usize> Default for StateChangeCache<CAP> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<const CAP: usize> StateChangeCache<CAP> {\n    pub fn new() -> Self {\n        StateChangeCache {\n            oldest_block: 0,\n            cache: ArrayDeque::new(),\n        }\n    }\n\n    pub fn is_empty(&self) -> bool {\n        self.cache.is_empty()\n    }\n\n    pub fn push(&mut self, state_change: StateChange) {\n        let cache = &mut self.cache;\n\n        if cache.is_full() {\n            cache.pop_back();\n            self.oldest_block = cache.back().unwrap().block_number;\n        }\n\n        // We can unwrap here since we check if the cache is full\n        cache.push_front(state_change).unwrap();\n    }\n\n    /// Unwinds the state changes up to the given block number\n    /// Returns the state of the affected AMMs at the block number provided\n    pub fn unwind_state_changes(&mut self, block_to_unwind: u64) -> Vec<AMM> {\n        let cache = &mut self.cache;\n\n        if block_to_unwind < self.oldest_block {\n            panic!(\"Block to unwind < oldest block in cache\");\n        }\n\n        // If the block to unwind is greater than the latest state change in the block, exit early\n        if cache\n            .front()\n            .is_none_or(|latest| block_to_unwind > latest.block_number)\n        {\n            return vec![];\n        }\n\n        let pivot_idx = cache\n            .iter()\n            .position(|state_change| state_change.block_number < block_to_unwind);\n\n        let state_changes = if let Some(pivot_idx) = pivot_idx {\n            cache.drain(..pivot_idx).collect()\n        } else {\n            cache.drain(..).collect::<Vec<StateChange>>()\n        };\n\n        self.flatten_state_changes(state_changes)\n    }\n\n    fn flatten_state_changes(&self, state_changes: Vec<StateChange>) -> Vec<AMM> {\n        state_changes\n            .into_iter()\n            .rev()\n            .fold(HashMap::new(), |mut amms, state_change| {\n                for amm in state_change.state_change {\n                    amms.entry(amm.address()).or_insert(amm);\n                }\n                amms\n            })\n            .into_values()\n            .collect()\n    }\n}\n\n// NOTE: we can probably make this more efficient and create a state change struct for each amm rather than\n// cloning each amm when caching\n#[derive(Debug, Clone)]\npub struct StateChange {\n    pub state_change: Vec<AMM>,\n    pub block_number: u64,\n}\n\nimpl StateChange {\n    pub fn new(state_change: Vec<AMM>, block_number: u64) -> Self {\n        Self {\n            block_number,\n            state_change,\n        }\n    }\n}\n// TODO: add tests\n"
  },
  {
    "path": "src/state_space/discovery.rs",
    "content": "use std::collections::{HashMap, HashSet};\n\nuse alloy::primitives::{Address, FixedBytes};\n\nuse crate::amms::factory::Factory;\n\nuse super::filters::PoolFilter;\n\n#[derive(Debug, Default, Clone)]\npub struct DiscoveryManager {\n    pub factories: HashMap<Address, Factory>,\n    pub pool_filters: Option<Vec<PoolFilter>>,\n    pub token_decimals: HashMap<Address, u8>,\n}\n\nimpl DiscoveryManager {\n    pub fn new(factories: Vec<Factory>) -> Self {\n        let factories = factories\n            .into_iter()\n            .map(|factory| {\n                let address = factory.address();\n                (address, factory)\n            })\n            .collect();\n        Self {\n            factories,\n            ..Default::default()\n        }\n    }\n\n    pub fn with_pool_filters(self, pool_filters: Vec<PoolFilter>) -> Self {\n        Self {\n            pool_filters: Some(pool_filters),\n            ..self\n        }\n    }\n\n    pub fn disc_events(&self) -> HashSet<FixedBytes<32>> {\n        self.factories\n            .iter()\n            .fold(HashSet::new(), |mut events_set, (_, factory)| {\n                events_set.extend([factory.discovery_event()]);\n                events_set\n            })\n    }\n}\n"
  },
  {
    "path": "src/state_space/error.rs",
    "content": "use alloy::transports::TransportErrorKind;\nuse thiserror::Error;\n\nuse crate::amms::error::AMMError;\n\n#[derive(Error, Debug)]\npub enum StateSpaceError {\n    #[error(transparent)]\n    AMMError(#[from] AMMError),\n    #[error(transparent)]\n    TransportError(#[from] alloy::transports::RpcError<TransportErrorKind>),\n    #[error(transparent)]\n    JoinError(#[from] tokio::task::JoinError),\n    #[error(\"Block Number Does not Exist\")]\n    MissingBlockNumber,\n}\n"
  },
  {
    "path": "src/state_space/filters/blacklist.rs",
    "content": "use alloy::primitives::Address;\nuse async_trait::async_trait;\n\nuse crate::amms::{\n    amm::{AutomatedMarketMaker, AMM},\n    error::AMMError,\n};\n\nuse super::{AMMFilter, FilterStage};\n\n#[derive(Debug, Clone)]\npub struct BlacklistFilter {\n    /// A blacklist of addresses to exclusively disallow\n    blacklist: Vec<Address>,\n}\n\nimpl BlacklistFilter {\n    pub fn new(blacklist: Vec<Address>) -> Self {\n        Self { blacklist }\n    }\n}\n\n#[async_trait]\nimpl AMMFilter for BlacklistFilter {\n    /// Filter for any AMMs or tokens not in the blacklist\n    async fn filter(&self, amms: Vec<AMM>) -> Result<Vec<AMM>, AMMError> {\n        Ok(amms\n            .into_iter()\n            .filter(|amm| {\n                !self.blacklist.contains(&amm.address())\n                    && amm.tokens().iter().all(|t| !self.blacklist.contains(t))\n            })\n            .collect())\n    }\n\n    /// Filter stage is set to after the sync stage to ensure the blacklist is applied to all\n    /// pool and token addresses after the pools have been fully populated\n    fn stage(&self) -> FilterStage {\n        FilterStage::Sync\n    }\n}\n"
  },
  {
    "path": "src/state_space/filters/mod.rs",
    "content": "pub mod blacklist;\npub mod value;\npub mod whitelist;\n\nuse async_trait::async_trait;\nuse blacklist::BlacklistFilter;\nuse whitelist::{PoolWhitelistFilter, TokenWhitelistFilter};\n\nuse crate::amms::{amm::AMM, error::AMMError};\n#[async_trait]\npub trait AMMFilter {\n    async fn filter(&self, amms: Vec<AMM>) -> Result<Vec<AMM>, AMMError>;\n    fn stage(&self) -> FilterStage;\n}\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub enum FilterStage {\n    Discovery,\n    Sync,\n}\n\nmacro_rules! filter {\n    ($($filter_type:ident),+ $(,)?) => {\n        #[derive(Debug, Clone)]\n        pub enum PoolFilter {\n            $($filter_type($filter_type),)+\n        }\n\n        #[async_trait]\n        impl AMMFilter for PoolFilter {\n            async fn filter(&self, amms: Vec<AMM>) -> Result<Vec<AMM>, AMMError> {\n                match self {\n                    $(PoolFilter::$filter_type(filter) => filter.filter(amms).await,)+\n                }\n            }\n\n            fn stage(&self) -> FilterStage {\n                match self {\n                    $(PoolFilter::$filter_type(filter) => filter.stage(),)+\n                }\n            }\n        }\n\n        $(\n            impl From<$filter_type> for PoolFilter {\n                fn from(filter: $filter_type) -> Self {\n                    PoolFilter::$filter_type(filter)\n                }\n            }\n        )+\n    };\n}\n\nfilter!(\n    BlacklistFilter,\n    PoolWhitelistFilter,\n    TokenWhitelistFilter,\n    // ValueFilter\n);\n"
  },
  {
    "path": "src/state_space/filters/value.rs",
    "content": "use std::{collections::HashMap, marker::PhantomData};\n\nuse super::{AMMFilter, FilterStage};\nuse crate::amms::{\n    amm::{AutomatedMarketMaker, AMM},\n    error::AMMError,\n};\nuse alloy::{\n    network::Network,\n    primitives::{Address, U256},\n    providers::Provider,\n    sol,\n    sol_types::SolValue,\n};\nuse async_trait::async_trait;\nuse WethValueInPools::{PoolInfo, PoolInfoReturn};\n\nsol! {\n    #[sol(rpc)]\n    WethValueInPoolsBatchRequest,\n    \"src/amms/abi/WethValueInPoolsBatchRequest.json\"\n}\n\npub struct ValueFilter<const CHUNK_SIZE: usize, N, P>\nwhere\n    N: Network,\n    P: Provider<N> + Clone,\n{\n    pub uniswap_v2_factory: Address,\n    pub uniswap_v3_factory: Address,\n    pub weth: Address,\n    pub min_weth_threshold: U256,\n    pub provider: P,\n    phantom: PhantomData<N>,\n}\n\nimpl<const CHUNK_SIZE: usize, N, P> ValueFilter<CHUNK_SIZE, N, P>\nwhere\n    N: Network,\n    P: Provider<N> + Clone,\n{\n    pub fn new(\n        uniswap_v2_factory: Address,\n        uniswap_v3_factory: Address,\n        weth: Address,\n        min_weth_threshold: U256,\n        provider: P,\n    ) -> Self {\n        Self {\n            uniswap_v2_factory,\n            uniswap_v3_factory,\n            weth,\n            min_weth_threshold,\n            provider,\n            phantom: PhantomData,\n        }\n    }\n\n    pub async fn get_weth_value_in_pools(\n        &self,\n        pools: Vec<PoolInfo>,\n    ) -> Result<HashMap<Address, PoolInfoReturn>, AMMError> {\n        let deployer = WethValueInPoolsBatchRequest::deploy_builder(\n            self.provider.clone(),\n            self.uniswap_v2_factory,\n            self.uniswap_v3_factory,\n            self.weth,\n            pools,\n        );\n\n        let res = deployer.call_raw().await?;\n        let return_data = <Vec<PoolInfoReturn> as SolValue>::abi_decode(&res)?;\n\n        Ok(return_data\n            .into_iter()\n            .map(|pool_info| (pool_info.poolAddress, pool_info))\n            .collect())\n    }\n}\n\n#[async_trait]\nimpl<const CHUNK_SIZE: usize, N, P> AMMFilter for ValueFilter<CHUNK_SIZE, N, P>\nwhere\n    N: Network,\n    P: Provider<N> + Clone,\n{\n    async fn filter(&self, amms: Vec<AMM>) -> Result<Vec<AMM>, AMMError> {\n        let pool_infos = amms\n            .iter()\n            .cloned()\n            .map(|amm| {\n                let pool_address = amm.address();\n                let pool_type = match amm {\n                    AMM::BalancerPool(_) => 0,\n                    AMM::UniswapV2Pool(_) => 1,\n                    AMM::UniswapV3Pool(_) => 2,\n                    // TODO: At the moment, filters are not compatible with vaults\n                    AMM::ERC4626Vault(_) => todo!(),\n                };\n\n                PoolInfo {\n                    poolType: pool_type,\n                    poolAddress: pool_address,\n                }\n            })\n            .collect::<Vec<_>>();\n\n        let mut pool_info_returns = HashMap::new();\n        let futs = pool_infos\n            .chunks(CHUNK_SIZE)\n            .map(|chunk| async { self.get_weth_value_in_pools(chunk.to_vec()).await })\n            .collect::<Vec<_>>();\n\n        let results = futures::future::join_all(futs).await;\n        for result in results {\n            pool_info_returns.extend(result?);\n        }\n\n        let filtered_amms = amms\n            .into_iter()\n            .filter(|amm| {\n                let pool_address = amm.address();\n                pool_info_returns\n                    .get(&pool_address)\n                    .is_some_and(|pool_info_return| {\n                        pool_info_return.wethValue > self.min_weth_threshold\n                    })\n            })\n            .collect::<Vec<_>>();\n        Ok(filtered_amms)\n    }\n\n    fn stage(&self) -> FilterStage {\n        FilterStage::Sync\n    }\n}\n"
  },
  {
    "path": "src/state_space/filters/whitelist.rs",
    "content": "use alloy::primitives::Address;\nuse async_trait::async_trait;\n\nuse crate::amms::{\n    amm::{AutomatedMarketMaker, AMM},\n    error::AMMError,\n};\n\nuse super::{AMMFilter, FilterStage};\n\n#[derive(Debug, Clone)]\npub struct PoolWhitelistFilter {\n    pools: Vec<Address>,\n}\n\nimpl PoolWhitelistFilter {\n    pub fn new(pools: Vec<Address>) -> Self {\n        Self { pools }\n    }\n}\n\n#[async_trait]\nimpl AMMFilter for PoolWhitelistFilter {\n    /// Filter for any AMMs or tokens in the whitelist\n    async fn filter(&self, amms: Vec<AMM>) -> Result<Vec<AMM>, AMMError> {\n        Ok(amms\n            .into_iter()\n            .filter(|amm| self.pools.contains(&amm.address()))\n            .collect())\n    }\n\n    fn stage(&self) -> FilterStage {\n        FilterStage::Discovery\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct TokenWhitelistFilter {\n    tokens: Vec<Address>,\n}\n\nimpl TokenWhitelistFilter {\n    pub fn new(tokens: Vec<Address>) -> Self {\n        Self { tokens }\n    }\n}\n\n#[async_trait]\nimpl AMMFilter for TokenWhitelistFilter {\n    /// Filter for any AMMs or tokens in the whitelist\n    async fn filter(&self, amms: Vec<AMM>) -> Result<Vec<AMM>, AMMError> {\n        Ok(amms\n            .into_iter()\n            .filter(|amm| amm.tokens().iter().any(|t| self.tokens.contains(t)))\n            .collect())\n    }\n\n    fn stage(&self) -> FilterStage {\n        FilterStage::Sync\n    }\n}\n"
  },
  {
    "path": "src/state_space/mod.rs",
    "content": "pub mod cache;\npub mod discovery;\npub mod error;\npub mod filters;\n\nuse crate::amms::amm::AutomatedMarketMaker;\nuse crate::amms::amm::AMM;\nuse crate::amms::error::AMMError;\nuse crate::amms::factory::Factory;\n\nuse alloy::consensus::BlockHeader;\nuse alloy::eips::BlockId;\nuse alloy::rpc::types::{Block, Filter, FilterSet, Log};\nuse alloy::{\n    network::Network,\n    primitives::{Address, FixedBytes},\n    providers::Provider,\n};\nuse async_stream::stream;\nuse cache::StateChange;\nuse cache::StateChangeCache;\n\nuse error::StateSpaceError;\nuse filters::AMMFilter;\nuse filters::PoolFilter;\nuse futures::stream::FuturesUnordered;\nuse futures::Stream;\nuse futures::StreamExt;\nuse std::collections::HashSet;\nuse std::pin::Pin;\nuse std::sync::atomic::AtomicU64;\nuse std::sync::atomic::Ordering;\nuse std::{collections::HashMap, marker::PhantomData, sync::Arc};\nuse tokio::sync::RwLock;\nuse tracing::debug;\nuse tracing::info;\n\npub const CACHE_SIZE: usize = 30;\n\n#[derive(Clone)]\npub struct StateSpaceManager<N, P> {\n    pub state: Arc<RwLock<StateSpace>>,\n    pub latest_block: Arc<AtomicU64>,\n    // discovery_manager: Option<DiscoveryManager>,\n    pub block_filter: Filter,\n    pub provider: P,\n    phantom: PhantomData<N>,\n    // TODO: add support for caching\n}\n\nimpl<N, P> StateSpaceManager<N, P> {\n    pub async fn subscribe(\n        &self,\n    ) -> Result<\n        Pin<Box<dyn Stream<Item = Result<Vec<Address>, StateSpaceError>> + Send>>,\n        StateSpaceError,\n    >\n    where\n        P: Provider<N> + Clone + 'static,\n        N: Network<BlockResponse = Block>,\n    {\n        let provider = self.provider.clone();\n        let latest_block = self.latest_block.clone();\n        let state = self.state.clone();\n        let mut block_filter = self.block_filter.clone();\n\n        let block_stream = provider.subscribe_blocks().await?.into_stream();\n\n        Ok(Box::pin(stream! {\n            tokio::pin!(block_stream);\n\n            while let Some(block) = block_stream.next().await {\n                let block_number = block.number();\n                block_filter = block_filter.select(block_number);\n\n\n                let logs = provider.get_logs(&block_filter).await?;\n\n                let affected_amms = state.write().await.sync(&logs)?;\n                latest_block.store(block_number, Ordering::Relaxed);\n\n                yield Ok(affected_amms);\n            }\n        }))\n    }\n}\n\n// TODO: Drop impl, create a checkpoint\n#[derive(Debug, Default)]\npub struct StateSpaceBuilder<N, P> {\n    pub provider: P,\n    pub latest_block: u64,\n    pub factories: Vec<Factory>,\n    pub amms: Vec<AMM>,\n    pub filters: Vec<PoolFilter>,\n    phantom: PhantomData<N>,\n    // TODO: add support for caching\n}\n\nimpl<N, P> StateSpaceBuilder<N, P>\nwhere\n    N: Network,\n    P: Provider<N> + Clone + 'static,\n{\n    pub fn new(provider: P) -> StateSpaceBuilder<N, P> {\n        Self {\n            provider,\n            latest_block: 0,\n            factories: vec![],\n            amms: vec![],\n            filters: vec![],\n            // discovery: false,\n            phantom: PhantomData,\n        }\n    }\n\n    pub fn block(self, latest_block: u64) -> StateSpaceBuilder<N, P> {\n        StateSpaceBuilder {\n            latest_block,\n            ..self\n        }\n    }\n\n    pub fn with_factories(self, factories: Vec<Factory>) -> StateSpaceBuilder<N, P> {\n        StateSpaceBuilder { factories, ..self }\n    }\n\n    pub fn with_amms(self, amms: Vec<AMM>) -> StateSpaceBuilder<N, P> {\n        StateSpaceBuilder { amms, ..self }\n    }\n\n    pub fn with_filters(self, filters: Vec<PoolFilter>) -> StateSpaceBuilder<N, P> {\n        StateSpaceBuilder { filters, ..self }\n    }\n\n    pub async fn sync(self) -> Result<StateSpaceManager<N, P>, AMMError> {\n        let chain_tip = BlockId::from(self.provider.get_block_number().await?);\n        let factories = self.factories.clone();\n        let mut futures = FuturesUnordered::new();\n\n        let mut filter_set = HashSet::new();\n        for factory in &self.factories {\n            for event in factory.pool_events() {\n                filter_set.insert(event);\n            }\n        }\n\n        for amm in self.amms.iter() {\n            for event in amm.sync_events() {\n                filter_set.insert(event);\n            }\n        }\n\n        let block_filter = Filter::new().event_signature(FilterSet::from(\n            filter_set.into_iter().collect::<Vec<FixedBytes<32>>>(),\n        ));\n        let mut amm_variants = HashMap::new();\n        for amm in self.amms.into_iter() {\n            amm_variants\n                .entry(amm.variant())\n                .or_insert_with(Vec::new)\n                .push(amm);\n        }\n\n        for factory in factories {\n            let provider = self.provider.clone();\n            let filters = self.filters.clone();\n\n            let extension = amm_variants.remove(&factory.variant());\n            futures.push(tokio::spawn(async move {\n                let mut discovered_amms = factory.discover(chain_tip, provider.clone()).await?;\n\n                if let Some(amms) = extension {\n                    discovered_amms.extend(amms);\n                }\n\n                // Apply discovery filters\n                for filter in filters.iter() {\n                    if filter.stage() == filters::FilterStage::Discovery {\n                        let pre_filter_len = discovered_amms.len();\n                        discovered_amms = filter.filter(discovered_amms).await?;\n\n                        info!(\n                            target: \"state_space::sync\",\n                            factory = %factory.address(),\n                            pre_filter_len,\n                            post_filter_len = discovered_amms.len(),\n                            filter = ?filter,\n                            \"Discovery filter\"\n                        );\n                    }\n                }\n\n                discovered_amms = factory.sync(discovered_amms, chain_tip, provider).await?;\n\n                // Apply sync filters\n                for filter in filters.iter() {\n                    if filter.stage() == filters::FilterStage::Sync {\n                        let pre_filter_len = discovered_amms.len();\n                        discovered_amms = filter.filter(discovered_amms).await?;\n\n                        info!(\n                            target: \"state_space::sync\",\n                            factory = %factory.address(),\n                            pre_filter_len,\n                            post_filter_len = discovered_amms.len(),\n                            filter = ?filter,\n                            \"Sync filter\"\n                        );\n                    }\n                }\n\n                Ok::<Vec<AMM>, AMMError>(discovered_amms)\n            }));\n        }\n\n        let mut state_space = StateSpace::default();\n        while let Some(res) = futures.next().await {\n            let synced_amms = res??;\n\n            for amm in synced_amms {\n                state_space.state.insert(amm.address(), amm);\n            }\n        }\n\n        // Sync remaining AMM variants\n        for (_, remaining_amms) in amm_variants.drain() {\n            for mut amm in remaining_amms {\n                let address = amm.address();\n                amm = amm.init(chain_tip, self.provider.clone()).await?;\n                state_space.state.insert(address, amm);\n            }\n        }\n\n        Ok(StateSpaceManager {\n            latest_block: Arc::new(AtomicU64::new(self.latest_block)),\n            state: Arc::new(RwLock::new(state_space)),\n            block_filter,\n            provider: self.provider,\n            phantom: PhantomData,\n        })\n    }\n}\n\n#[derive(Debug, Default)]\npub struct StateSpace {\n    pub state: HashMap<Address, AMM>,\n    pub latest_block: Arc<AtomicU64>,\n    cache: StateChangeCache<CACHE_SIZE>,\n}\n\nimpl StateSpace {\n    pub fn get(&self, address: &Address) -> Option<&AMM> {\n        self.state.get(address)\n    }\n\n    pub fn get_mut(&mut self, address: &Address) -> Option<&mut AMM> {\n        self.state.get_mut(address)\n    }\n\n    pub fn sync(&mut self, logs: &[Log]) -> Result<Vec<Address>, StateSpaceError> {\n        let latest = self.latest_block.load(Ordering::Relaxed);\n        let Some(mut block_number) = logs\n            .first()\n            .map(|log| log.block_number.ok_or(StateSpaceError::MissingBlockNumber))\n            .transpose()?\n        else {\n            return Ok(vec![]);\n        };\n\n        // Check if there is a reorg and unwind to state before block_number\n        if latest >= block_number {\n            info!(\n                target: \"state_space::sync\",\n                from = %latest,\n                to = %block_number - 1,\n                \"Unwinding state changes\"\n            );\n\n            let cached_state = self.cache.unwind_state_changes(block_number);\n            for amm in cached_state {\n                debug!(target: \"state_space::sync\", ?amm, \"Reverting AMM state\");\n                self.state.insert(amm.address(), amm);\n            }\n        }\n\n        let mut cached_amms = HashSet::new();\n        let mut affected_amms = HashSet::new();\n        for log in logs {\n            // If the block number is updated, cache the current block state changes\n            let log_block_number = log\n                .block_number\n                .ok_or(StateSpaceError::MissingBlockNumber)?;\n            if log_block_number != block_number {\n                let amms = cached_amms.drain().collect::<Vec<AMM>>();\n                affected_amms.extend(amms.iter().map(|amm| amm.address()));\n                let state_change = StateChange::new(amms, block_number);\n\n                debug!(\n                    target: \"state_space::sync\",\n                    state_change = ?state_change,\n                    \"Caching state change\"\n                );\n\n                self.cache.push(state_change);\n                block_number = log_block_number;\n            }\n\n            // If the AMM is in the state space add the current state to cache and sync from log\n            let address = log.address();\n            if let Some(amm) = self.state.get_mut(&address) {\n                cached_amms.insert(amm.clone());\n                amm.sync(log)?;\n\n                info!(\n                    target: \"state_space::sync\",\n                    ?amm,\n                    \"Synced AMM\"\n                );\n            }\n        }\n\n        if !cached_amms.is_empty() {\n            let amms = cached_amms.drain().collect::<Vec<AMM>>();\n            affected_amms.extend(amms.iter().map(|amm| amm.address()));\n            let state_change = StateChange::new(amms, block_number);\n\n            debug!(\n                target: \"state_space::sync\",\n                state_change = ?state_change,\n                \"Caching state change\"\n            );\n\n            self.cache.push(state_change);\n        }\n\n        Ok(affected_amms.into_iter().collect())\n    }\n}\n\n#[macro_export]\nmacro_rules! sync {\n    // Sync factories with provider\n    ($factories:expr, $provider:expr) => {{\n        StateSpaceBuilder::new($provider.clone())\n            .with_factories($factories)\n            .sync()\n            .await?\n    }};\n\n    // Sync factories with filters\n    ($factories:expr, $filters:expr, $provider:expr) => {{\n        StateSpaceBuilder::new($provider.clone())\n            .with_factories($factories)\n            .with_filters($filters)\n            .sync()\n            .await?\n    }};\n\n    ($factories:expr, $amms:expr, $filters:expr, $provider:expr) => {{\n        StateSpaceBuilder::new($provider.clone())\n            .with_factories($factories)\n            .with_amms($amms)\n            .with_filters($filters)\n            .sync()\n            .await?\n    }};\n}\n"
  }
]