Contract 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c

 
Txn Hash
Block
From
To
Value [Txn Fee]
0xdf229f28a9478ee55a7eaaad9646acb9a863067a731a6e481027087668d58f2f82864452021-06-14 9:38:539 mins ago0x93623ba07c49ac9d93755f56bb5facbebcafaa18 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000930115
0x36723b934c9205e2d0506457941a6ee5afe3d03aa4dbe06132281b91ad654b5f82864452021-06-14 9:38:539 mins ago0xdcecf5c2c67345afbe67b8308ec9c8c3dab80eb4 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00098801
0x87f733c9008da472e4e8ea7a6efadbd91f7577f0364bd7327348c604f655592a82863112021-06-14 9:32:1116 mins ago0x4f8382f3d38108128e98b621f7370179dd99e1b6 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000695245
0xb3d2bf317c09e2337f722d05920e7a81e69d91e4c5becc6a57030c96ba81cea282862622021-06-14 9:29:4418 mins ago0xa746fa7aa9d6235dfa390f355ad4d05e03a61364 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00061068
0x99f9ad3014e5913aac55c31e0ced0a1abf6d1ea7fadc96582f39a826540976d282862502021-06-14 9:29:0819 mins ago0xa746fa7aa9d6235dfa390f355ad4d05e03a61364 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000796675
0x7cc783195dccabe7434b5d70d0a6e59faf9ae422aa12da887eb9188ebea9d06d82862472021-06-14 9:28:5919 mins ago0x6e6f8b141d9417e9201911aa22b6bf0d3eb0610e IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.29 BNB0.00072711
0xcf90e02a7bfab0cf316c26faf134918a0b4129acdae8876342333cab0a780f1e82862442021-06-14 9:28:5019 mins ago0x77604dde71f6f8b5c6230408deb4ca49277d31ab IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00095879
0x486987d644b0698138c308a5e2f144aff3798bdd0af4ac98785cb9d010890b8382862192021-06-14 9:27:3521 mins ago0xdcecf5c2c67345afbe67b8308ec9c8c3dab80eb4 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.001007525
0x2aa74faab4c9cd96a4a621e7bd1c989029ccfb0b06ae298af8bd0cf05d8ce5ec82861462021-06-14 9:23:5624 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00092188
0x444eb1f9a508244bfb6bedea4a9cb5c609c9935bb82a993b86708415fbb37ebe82861342021-06-14 9:23:1825 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00069945
0x4617fb502bb0cb5b220607fe485e11acda1717a110d728232a941ccefb898c9d82861242021-06-14 9:22:4625 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.3 BNB0.001039655
0x721a599e947558033472907f70a192b47b52f549c5cc34796e16b7742176a75e82861162021-06-14 9:22:2026 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.3 BNB0.001039655
0xc7f25d4f3331f31bacd2adc3d3a07c119d71d6dff8a11d83447654b4b60d2dbe82860852021-06-14 9:20:2628 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00092194
0xfe702f3480d5f1efdebe9048de4c1bb1bc41e92e6cd91b3b1bad0afa9d473cd382860712021-06-14 9:19:3928 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00069951
0x372d544f3c62cfc7f9736e130f677a0c68427642c7cf4c27028dffb3b58f760882860592021-06-14 9:18:5829 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.3 BNB0.001039655
0x1303a56470ed4a7e466337d77e568670fa9931c4ea370fa12db74b7b7d0bb90b82860532021-06-14 9:18:4029 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.3 BNB0.001039655
0xa8f68aecc94dc6479fd7d3573daac75959dcbefe856f8778a14f274c3512a04882860412021-06-14 9:18:0430 mins ago0xfc44c2256b273bdd37dfcc53eb08d82fad7b9249 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c10 BNB0.00072717
0x4e27630c395478593dfc481035decc43a88b58dcaa1a6d8fe5a90839d19094df82860262021-06-14 9:17:1631 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00092194
0x7fece149a5fb20d5bf8bc6d05ed20fd2536f4e401d49c74313dbe5126547f81b82860122021-06-14 9:16:3232 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00069945
0xaad2ef2982b4ee691109e1ceb04073b1fe1491eae52822dff299a0010aea94d982859852021-06-14 9:15:1133 mins ago0x0bf6bbdb102811412839480b7cb904f9719fe380 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.001082345
0x5d07f0403aae7c9095fc712df1ed1a5047a73a0745c3c6dc07485b21cd5ba14d82859762021-06-14 9:14:4433 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.3 BNB0.001039655
0x5ad8fb8fb6bd7b04c4edfe9d439f9a2a4e85bd9f0ac9434730f67b8bcb55d34e82859702021-06-14 9:14:2634 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.3 BNB0.001039715
0x95a58d0bcde99fc505f4537745eca03e4453e9e9beb65456f3a91b9b38debb4782859332021-06-14 9:12:3536 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00094552
0x7cd09b40e72e7eff1a9bef36976d1228a889b098987c1f7b8406b99424ffd2a082859182021-06-14 9:11:5036 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00077463
0x614f7bcecd9f34cd3e6825d2bd496800616b89e24e326aedf72b3914b95df57f82859022021-06-14 9:11:0137 mins ago0xa6e479a1c61fbdf0098d94fcfed5a477349f9f06 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.3 BNB0.001039715
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x87f733c9008da472e4e8ea7a6efadbd91f7577f0364bd7327348c604f655592a82863112021-06-14 9:32:1116 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x4f8382f3d38108128e98b621f7370179dd99e1b60.007554744870912683 BNB
0x87f733c9008da472e4e8ea7a6efadbd91f7577f0364bd7327348c604f655592a82863112021-06-14 9:32:1116 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.007554744870912683 BNB
0x7cc783195dccabe7434b5d70d0a6e59faf9ae422aa12da887eb9188ebea9d06d82862472021-06-14 9:28:5919 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.29 BNB
0x4617fb502bb0cb5b220607fe485e11acda1717a110d728232a941ccefb898c9d82861242021-06-14 9:22:4625 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0x721a599e947558033472907f70a192b47b52f549c5cc34796e16b7742176a75e82861162021-06-14 9:22:2026 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0x372d544f3c62cfc7f9736e130f677a0c68427642c7cf4c27028dffb3b58f760882860592021-06-14 9:18:5829 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0x1303a56470ed4a7e466337d77e568670fa9931c4ea370fa12db74b7b7d0bb90b82860532021-06-14 9:18:4029 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0xa8f68aecc94dc6479fd7d3573daac75959dcbefe856f8778a14f274c3512a04882860412021-06-14 9:18:0430 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token10 BNB
0x5d07f0403aae7c9095fc712df1ed1a5047a73a0745c3c6dc07485b21cd5ba14d82859762021-06-14 9:14:4433 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0x5ad8fb8fb6bd7b04c4edfe9d439f9a2a4e85bd9f0ac9434730f67b8bcb55d34e82859702021-06-14 9:14:2634 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0x614f7bcecd9f34cd3e6825d2bd496800616b89e24e326aedf72b3914b95df57f82859022021-06-14 9:11:0137 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0xc005224eaf60eff5afe283556aedc2b90852d9cee273f4bff737f09942607dae82858952021-06-14 9:10:3737 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.3 BNB
0xe8afe542dd32ad6a60c46397be0f2f2a18e5d87239a2fec5571ae58579557af582856382021-06-14 8:56:4451 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x13ba4e364bf9b5e3c62062e54defbb04e5ca79210.004952496827604073 BNB
0xe8afe542dd32ad6a60c46397be0f2f2a18e5d87239a2fec5571ae58579557af582856382021-06-14 8:56:4451 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.004952496827604073 BNB
0xbcbe49029cd638c1e28f56a0963ff341b187d50c3f25a5756edd7d3911892ef882855062021-06-14 8:50:0858 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x6acb4fc9d9542df9e3e6d4ce32aeb5a1c0d0cecd0.015678374700880854 BNB
0xbcbe49029cd638c1e28f56a0963ff341b187d50c3f25a5756edd7d3911892ef882855062021-06-14 8:50:0858 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.015678374700880854 BNB
0x7b5ccc5cd43c4420687e3b25189c39029239f9be3fd138453928e92ddb71728082854072021-06-14 8:44:461 hr 3 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x47c2259e9fa49bc649d85d47f93fdda279bb588c1.567824830355576409 BNB
0x7b5ccc5cd43c4420687e3b25189c39029239f9be3fd138453928e92ddb71728082854072021-06-14 8:44:461 hr 3 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c1.567824830355576409 BNB
0x5319ff477fe86670337d00c81fd91222858de98625ccf18df1d67562e8cb662482853462021-06-14 8:41:401 hr 6 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0xdc1b140342966fd258885e51fcd16d2cf68be4bc0.099515179247357385 BNB
0x5319ff477fe86670337d00c81fd91222858de98625ccf18df1d67562e8cb662482853462021-06-14 8:41:401 hr 6 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.099515179247357385 BNB
0x7e868173fd295bc57e07f9f05fbfbb6fd86da48fd55f1246e221aba5213779ec82851142021-06-14 8:30:021 hr 18 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x33d2af307e7d45cd35a72628ef008dd82588a7460.22966050204191905 BNB
0x7e868173fd295bc57e07f9f05fbfbb6fd86da48fd55f1246e221aba5213779ec82851142021-06-14 8:30:021 hr 18 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.22966050204191905 BNB
0xa650b4d2f1f32f226b092f29a9722ef0a8f162a865cded925db43656039c6bc782847892021-06-14 8:13:471 hr 34 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x64c23a442f43f69d3377f403f22cb87aab34849e0.061843273157352138 BNB
0xa650b4d2f1f32f226b092f29a9722ef0a8f162a865cded925db43656039c6bc782847892021-06-14 8:13:471 hr 34 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.061843273157352138 BNB
0xe9d2912ae0eb303e98086885686552f7738ef4df4f72c538121a811f67e650cf82845332021-06-14 8:00:591 hr 47 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0xd9f64ae2001926f4824dba9ffc78f83f3ac8acba0.00232726848290683 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ValueLiquidRouter

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at BscScan.com on 2021-02-23
*/

// SPDX-License-Identifier: SEE LICENSE IN LICENSE

pragma solidity >=0.7.6;
pragma abicoder v2;

interface IValueLiquidFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint32 tokenWeight0, uint32 swapFee, uint256);

    function feeTo() external view returns (address);

    function formula() external view returns (address);

    function protocolFee() external view returns (uint256);

    function feeToSetter() external view returns (address);

    function getPair(
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee
    ) external view returns (address pair);

    function allPairs(uint256) external view returns (address pair);

    function isPair(address) external view returns (bool);

    function allPairsLength() external view returns (uint256);

    function createPair(
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee
    ) external returns (address pair);

    function getWeightsAndSwapFee(address pair)
        external
        view
        returns (
            uint32 tokenWeight0,
            uint32 tokenWeight1,
            uint32 swapFee
        );

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;

    function setProtocolFee(uint256) external;
}

/*
    Bancor Formula interface
*/
interface IValueLiquidFormula {
    function getReserveAndWeights(address pair, address tokenA)
        external
        view
        returns (
            address tokenB,
            uint256 reserveA,
            uint256 reserveB,
            uint32 tokenWeightA,
            uint32 tokenWeightB,
            uint32 swapFee
        );

    function getFactoryReserveAndWeights(
        address factory,
        address pair,
        address tokenA
    )
        external
        view
        returns (
            address tokenB,
            uint256 reserveA,
            uint256 reserveB,
            uint32 tokenWeightA,
            uint32 tokenWeightB,
            uint32 swapFee
        );

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut,
        uint32 tokenWeightIn,
        uint32 tokenWeightOut,
        uint32 swapFee
    ) external view returns (uint256 amountIn);

    function getPairAmountIn(
        address pair,
        address tokenIn,
        uint256 amountOut
    ) external view returns (uint256 amountIn);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut,
        uint32 tokenWeightIn,
        uint32 tokenWeightOut,
        uint32 swapFee
    ) external view returns (uint256 amountOut);

    function getPairAmountOut(
        address pair,
        address tokenIn,
        uint256 amountIn
    ) external view returns (uint256 amountOut);

    function getAmountsIn(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getFactoryAmountsIn(
        address factory,
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getAmountsOut(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function getFactoryAmountsOut(
        address factory,
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts);

    function ensureConstantValue(
        uint256 reserve0,
        uint256 reserve1,
        uint256 balance0Adjusted,
        uint256 balance1Adjusted,
        uint32 tokenWeight0
    ) external view returns (bool);

    function getReserves(
        address pair,
        address tokenA,
        address tokenB
    ) external view returns (uint256 reserveA, uint256 reserveB);

    function getOtherToken(address pair, address tokenA) external view returns (address tokenB);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function sortTokens(address tokenA, address tokenB) external pure returns (address token0, address token1);

    function mintLiquidityFee(
        uint256 totalLiquidity,
        uint112 reserve0,
        uint112 reserve1,
        uint32 tokenWeight0,
        uint32 tokenWeight1,
        uint112 collectedFee0,
        uint112 collectedFee1
    ) external view returns (uint256 amount);
}

interface IValueLiquidPair {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event PaidProtocolFee(uint112 collectedFee0, uint112 collectedFee1);
    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
    event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to);
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function getCollectedFees() external view returns (uint112 _collectedFee0, uint112 _collectedFee1);

    function getTokenWeights() external view returns (uint32 tokenWeight0, uint32 tokenWeight1);

    function getSwapFee() external view returns (uint32);

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to) external returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(
        address,
        address,
        uint32,
        uint32
    ) external;
}

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: APPROVE_FAILED");
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FAILED");
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FROM_FAILED");
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper: ETH_TRANSFER_FAILED");
    }
}

interface IValueLiquidRouter {
    event Exchange(address pair, uint256 amountOut, address output);
    struct Swap {
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount; // tokenInAmount / tokenOutAmount
        uint256 limitReturnAmount; // minAmountOut / maxAmountIn
        uint256 maxPrice;
    }

    function factory() external view returns (address);

    function controller() external view returns (address);

    function formula() external view returns (address);

    function WETH() external view returns (address);

    function addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address pair,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function swapExactTokensForTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        address tokenIn,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        address tokenOut,
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 totalAmountIn,
        uint256 minTotalAmountOut,
        uint256 deadline
    ) external payable returns (uint256 totalAmountOut);

    function multihopBatchSwapExactOut(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 maxTotalAmountIn,
        uint256 deadline
    ) external payable returns (uint256 totalAmountIn);

    function createPair(
        address tokenA,
        address tokenB,
        uint256 amountA,
        uint256 amountB,
        uint32 tokenWeightA,
        uint32 swapFee,
        address to
    ) external returns (uint256 liquidity);

    function createPairETH(
        address token,
        uint256 amountToken,
        uint32 tokenWeight,
        uint32 swapFee,
        address to
    ) external payable returns (uint256 liquidity);

    function removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);
}

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require(b > 0, "ds-math-division-by-zero");
        c = a / b;
    }
}

interface IWETH {
    function deposit() external payable;

    function transfer(address to, uint256 value) external returns (bool);

    function withdraw(uint256) external;

    function balanceOf(address account) external view returns (uint256);
}

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

interface IBPool is IERC20 {
    function version() external view returns (uint256);

    function swapExactAmountIn(
        address,
        uint256,
        address,
        uint256,
        uint256
    ) external returns (uint256, uint256);

    function swapExactAmountOut(
        address,
        uint256,
        address,
        uint256,
        uint256
    ) external returns (uint256, uint256);

    function calcInGivenOut(
        uint256,
        uint256,
        uint256,
        uint256,
        uint256,
        uint256
    ) external pure returns (uint256);

    function calcOutGivenIn(
        uint256,
        uint256,
        uint256,
        uint256,
        uint256,
        uint256
    ) external pure returns (uint256);

    function getDenormalizedWeight(address) external view returns (uint256);

    function swapFee() external view returns (uint256);

    function setSwapFee(uint256 _swapFee) external;

    function bind(
        address token,
        uint256 balance,
        uint256 denorm
    ) external;

    function rebind(
        address token,
        uint256 balance,
        uint256 denorm
    ) external;

    function finalize(
        uint256 _swapFee,
        uint256 _initPoolSupply,
        address[] calldata _bindTokens,
        uint256[] calldata _bindDenorms
    ) external;

    function setPublicSwap(bool _publicSwap) external;

    function setController(address _controller) external;

    function setExchangeProxy(address _exchangeProxy) external;

    function getFinalTokens() external view returns (address[] memory tokens);

    function getTotalDenormalizedWeight() external view returns (uint256);

    function getBalance(address token) external view returns (uint256);

    function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external;

    function joinPoolFor(
        address account,
        uint256 rewardAmountOut,
        uint256[] calldata maxAmountsIn
    ) external;

    function joinswapPoolAmountOut(
        address tokenIn,
        uint256 poolAmountOut,
        uint256 maxAmountIn
    ) external returns (uint256 tokenAmountIn);

    function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external;

    function exitswapPoolAmountIn(
        address tokenOut,
        uint256 poolAmountIn,
        uint256 minAmountOut
    ) external returns (uint256 tokenAmountOut);

    function exitswapExternAmountOut(
        address tokenOut,
        uint256 tokenAmountOut,
        uint256 maxPoolAmountIn
    ) external returns (uint256 poolAmountIn);

    function joinswapExternAmountIn(
        address tokenIn,
        uint256 tokenAmountIn,
        uint256 minPoolAmountOut
    ) external returns (uint256 poolAmountOut);

    function finalizeRewardFundInfo(address _rewardFund, uint256 _unstakingFrozenTime) external;

    function addRewardPool(
        IERC20 _rewardToken,
        uint256 _startBlock,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock,
        uint256 _lockRewardPercent,
        uint256 _startVestingBlock,
        uint256 _endVestingBlock
    ) external;

    function isBound(address t) external view returns (bool);

    function getSpotPrice(address tokenIn, address tokenOut) external view returns (uint256 spotPrice);
}

contract ValueLiquidRouter is IValueLiquidRouter {
    using SafeMath for uint256;
    address public immutable override factory;
    address public immutable override controller;
    address public immutable override formula;
    address public immutable override WETH;
    address private constant ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    modifier ensure(uint256 deadline) {
        require(deadline >= block.timestamp, "Router: EXPIRED");
        _;
    }

    constructor(
        address _factory,
        address _controller,
        address _WETH
    ) {
        factory = _factory;
        controller = _controller;
        formula = IValueLiquidFactory(_factory).formula();
        WETH = _WETH;
    }

    receive() external payable {
        assert(msg.sender == WETH);
        // only accept ETH via fallback from the WETH contract
    }

    // **** ADD LIQUIDITY ****
    function _addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin
    ) internal virtual returns (uint256 amountA, uint256 amountB) {
        require(IValueLiquidFactory(factory).isPair(pair), "Router: Invalid pair");
        (uint256 reserveA, uint256 reserveB) = IValueLiquidFormula(formula).getReserves(pair, tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint256 amountBOptimal = IValueLiquidFormula(formula).quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, "Router: INSUFFICIENT_B_AMOUNT");
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint256 amountAOptimal = IValueLiquidFormula(formula).quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, "Router: INSUFFICIENT_A_AMOUNT");
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }

    function _addLiquidityToken(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin
    ) internal returns (uint256 amountA, uint256 amountB) {
        (amountA, amountB) = _addLiquidity(pair, tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
    }

    function createPair(
        address tokenA,
        address tokenB,
        uint256 amountA,
        uint256 amountB,
        uint32 tokenWeightA,
        uint32 swapFee,
        address to
    ) public virtual override returns (uint256 liquidity) {
        address pair = IValueLiquidFactory(factory).createPair(tokenA, tokenB, tokenWeightA, swapFee);
        _addLiquidityToken(pair, tokenA, tokenB, amountA, amountB, 0, 0);
        liquidity = IValueLiquidPair(pair).mint(to);
    }

    function addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        )
    {
        (amountA, amountB) = _addLiquidityToken(pair, tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        liquidity = IValueLiquidPair(pair).mint(to);
    }

    function _addLiquidityETH(
        address pair,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to
    )
        internal
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        )
    {
        (amountToken, amountETH) = _addLiquidity(pair, token, WETH, amountTokenDesired, msg.value, amountTokenMin, amountETHMin);
        TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
        transferETHTo(amountETH, pair);
        liquidity = IValueLiquidPair(pair).mint(to);
        // refund dust eth, if any
        if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
    }

    function createPairETH(
        address token,
        uint256 amountToken,
        uint32 tokenWeight,
        uint32 swapFee,
        address to
    ) public payable virtual override returns (uint256 liquidity) {
        address pair = IValueLiquidFactory(factory).createPair(token, WETH, tokenWeight, swapFee);
        (, , liquidity) = _addLiquidityETH(pair, token, amountToken, 0, 0, to);
    }

    function addLiquidityETH(
        address pair,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        public
        payable
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        )
    {
        (amountToken, amountETH, liquidity) = _addLiquidityETH(pair, token, amountTokenDesired, amountTokenMin, amountETHMin, to);
    }

    // **** SWAP ****
    // requires the initial amount to have already been sent to the first pair
    function _swap(
        address tokenIn,
        uint256[] memory amounts,
        address[] memory path,
        address _to
    ) internal virtual {
        address input = tokenIn;
        for (uint256 i = 0; i < path.length; i++) {
            IValueLiquidPair pairV2 = IValueLiquidPair(path[i]);
            address token0 = pairV2.token0();
            uint256 amountOut = amounts[i + 1];
            (uint256 amount0Out, uint256 amount1Out, address output) = input == token0 ? (uint256(0), amountOut, pairV2.token1()) : (amountOut, uint256(0), token0);
            address to = i < path.length - 1 ? path[i + 1] : _to;
            pairV2.swap(amount0Out, amount1Out, to, new bytes(0));
            emit Exchange(address(pairV2), amountOut, output);
            input = output;
        }
    }

    function swapExactTokensForTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] memory path,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountOut(tokenIn, tokenOut, amountIn, amountOutMin, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, to);
    }

    function swapTokensForExactTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountIn(tokenIn, tokenOut, amountOut, amountInMax, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, to);
    }

    function swapExactETHForTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountOut(WETH, tokenOut, msg.value, amountOutMin, path);

        transferETHTo(amounts[0], path[0]);
        _swap(WETH, amounts, path, to);
    }

    function swapTokensForExactETH(
        address tokenIn,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountIn(tokenIn, WETH, amountOut, amountInMax, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, address(this));
        transferAll(ETH_ADDRESS, to, amounts[amounts.length - 1]);
    }

    function swapExactTokensForETH(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountOut(tokenIn, WETH, amountIn, amountOutMin, path);

        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amounts[0]);
        _swap(tokenIn, amounts, path, address(this));
        transferAll(ETH_ADDRESS, to, amounts[amounts.length - 1]);
    }

    function swapETHForExactTokens(
        address tokenOut,
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable virtual override ensure(deadline) returns (uint256[] memory amounts) {
        amounts = _validateAmountIn(WETH, tokenOut, amountOut, msg.value, path);

        transferETHTo(amounts[0], path[0]);
        _swap(WETH, amounts, path, to);
        // refund dust eth, if any
        if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]);
    }

    // **** SWAP (supporting fee-on-transfer tokens) ****
    // requires the initial amount to have already been sent to the first pair
    function _swapSupportingFeeOnTransferTokens(
        address tokenIn,
        address[] memory path,
        address _to
    ) internal virtual {
        address input = tokenIn;
        for (uint256 i; i < path.length; i++) {
            IValueLiquidPair pair = IValueLiquidPair(path[i]);

            uint256 amountInput;
            uint256 amountOutput;
            address currentOutput;
            {
                (address output, uint256 reserveInput, uint256 reserveOutput, uint32 tokenWeightInput, uint32 tokenWeightOutput, uint32 swapFee) =
                    IValueLiquidFormula(formula).getFactoryReserveAndWeights(factory, address(pair), input);
                amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput);
                amountOutput = IValueLiquidFormula(formula).getAmountOut(amountInput, reserveInput, reserveOutput, tokenWeightInput, tokenWeightOutput, swapFee);
                currentOutput = output;
            }
            (uint256 amount0Out, uint256 amount1Out) = input == pair.token0() ? (uint256(0), amountOutput) : (amountOutput, uint256(0));
            address to = i < path.length - 1 ? path[i + 1] : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
            emit Exchange(address(pair), amountOutput, currentOutput);
            input = currentOutput;
        }
    }

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) {
        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amountIn);
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(tokenIn, path, to);
        require(IERC20(tokenOut).balanceOf(to).sub(balanceBefore) >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        address tokenOut,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable virtual override ensure(deadline) {
        //            require(path[0] == WETH, 'Router: INVALID_PATH');
        uint256 amountIn = msg.value;
        transferETHTo(amountIn, path[0]);
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(WETH, path, to);
        require(IERC20(tokenOut).balanceOf(to).sub(balanceBefore) >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override ensure(deadline) {
        TransferHelper.safeTransferFrom(tokenIn, msg.sender, path[0], amountIn);
        _swapSupportingFeeOnTransferTokens(tokenIn, path, address(this));
        uint256 amountOut = IERC20(WETH).balanceOf(address(this));
        require(amountOut >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        transferAll(ETH_ADDRESS, to, amountOut);
    }

    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 totalAmountIn,
        uint256 minTotalAmountOut,
        uint256 deadline
    ) public payable virtual override ensure(deadline) returns (uint256 totalAmountOut) {
        transferFromAll(tokenIn, totalAmountIn);
        uint256 balanceBefore;
        if (!isETH(tokenOut)) {
            balanceBefore = IERC20(tokenOut).balanceOf(msg.sender);
        }

        for (uint256 i = 0; i < swapSequences.length; i++) {
            uint256 tokenAmountOut;
            for (uint256 k = 0; k < swapSequences[i].length; k++) {
                Swap memory swap = swapSequences[i][k];
                if (k == 1) {
                    // Makes sure that on the second swap the output of the first was used
                    // so there is not intermediate token leftover
                    swap.swapAmount = tokenAmountOut;
                }
                tokenAmountOut = _swapSingleSupportFeeOnTransferTokens(swap.tokenIn, swap.tokenOut, swap.pool, swap.swapAmount, swap.limitReturnAmount);
            }

            // This takes the amountOut of the last swap
            totalAmountOut = tokenAmountOut.add(totalAmountOut);
        }

        transferAll(tokenOut, msg.sender, totalAmountOut);
        transferAll(tokenIn, msg.sender, getBalance(tokenIn));

        if (isETH(tokenOut)) {
            require(totalAmountOut >= minTotalAmountOut, "ERR_LIMIT_OUT");
        } else {
            require(IERC20(tokenOut).balanceOf(msg.sender).sub(balanceBefore) >= minTotalAmountOut, "<minTotalAmountOut");
        }
    }

    function multihopBatchSwapExactOut(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint256 maxTotalAmountIn,
        uint256 deadline
    ) public payable virtual override ensure(deadline) returns (uint256 totalAmountIn) {
        transferFromAll(tokenIn, maxTotalAmountIn);

        for (uint256 i = 0; i < swapSequences.length; i++) {
            uint256 tokenAmountInFirstSwap;
            // Specific code for a simple swap and a multihop (2 swaps in sequence)
            if (swapSequences[i].length == 1) {
                Swap memory swap = swapSequences[i][0];
                tokenAmountInFirstSwap = _swapSingleMixOut(swap.tokenIn, swap.tokenOut, swap.pool, swap.swapAmount, swap.limitReturnAmount, swap.maxPrice);
            } else {
                // Consider we are swapping A -> B and B -> C. The goal is to buy a given amount
                // of token C. But first we need to buy B with A so we can then buy C with B
                // To get the exact amount of C we then first need to calculate how much B we'll need:
                uint256 intermediateTokenAmount;
                // This would be token B as described above
                Swap memory secondSwap = swapSequences[i][1];
                {
                    address[] memory paths = new address[](1);
                    paths[0] = secondSwap.pool;
                    uint256[] memory amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, secondSwap.tokenIn, secondSwap.tokenOut, secondSwap.swapAmount, paths);
                    intermediateTokenAmount = amounts[0];
                    require(intermediateTokenAmount <= secondSwap.limitReturnAmount, "Router: EXCESSIVE_INPUT_AMOUNT");
                }

                //// Buy intermediateTokenAmount of token B with A in the first pool
                Swap memory firstSwap = swapSequences[i][0];
                tokenAmountInFirstSwap = _swapSingleMixOut(firstSwap.tokenIn, firstSwap.tokenOut, firstSwap.pool, intermediateTokenAmount, firstSwap.limitReturnAmount, firstSwap.maxPrice);

                //// Buy the final amount of token C desired
                _swapSingle(secondSwap.tokenIn, secondSwap.pool, intermediateTokenAmount, secondSwap.swapAmount);
            }

            totalAmountIn = tokenAmountInFirstSwap.add(totalAmountIn);
        }

        require(totalAmountIn <= maxTotalAmountIn, "ERR_LIMIT_IN");

        transferAll(tokenOut, msg.sender, getBalance(tokenOut));
        transferAll(tokenIn, msg.sender, getBalance(tokenIn));
    }

    function transferFromAll(address token, uint256 amount) internal returns (bool) {
        if (isETH(token)) {
            IWETH(WETH).deposit{value: msg.value}();
        } else {
            TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount);
        }
        return true;
    }

    function getBalance(address token) internal view returns (uint256) {
        if (isETH(token)) {
            return IWETH(WETH).balanceOf(address(this));
        } else {
            return IERC20(token).balanceOf(address(this));
        }
    }

    function _swapSingleMixOut(
        address tokenIn,
        address tokenOut,
        address pool,
        uint256 swapAmount,
        uint256 limitReturnAmount,
        uint256
    ) internal returns (uint256 tokenAmountIn) {
        address[] memory paths = new address[](1);
        paths[0] = pool;
        uint256[] memory amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, tokenIn, tokenOut, swapAmount, paths);
        tokenAmountIn = amounts[0];
        require(tokenAmountIn <= limitReturnAmount, "Router: EXCESSIVE_INPUT_AMOUNT");
        _swapSingle(tokenIn, pool, tokenAmountIn, amounts[1]);
    }

    function _swapSingle(
        address tokenIn,
        address pair,
        uint256 targetSwapAmount,
        uint256 targetOutAmount
    ) internal {
        TransferHelper.safeTransfer(tokenIn, pair, targetSwapAmount);
        IValueLiquidPair pairV2 = IValueLiquidPair(pair);
        address token0 = pairV2.token0();

        (uint256 amount0Out, uint256 amount1Out, address output) = tokenIn == token0 ? (uint256(0), targetOutAmount, pairV2.token1()) : (targetOutAmount, uint256(0), token0);
        pairV2.swap(amount0Out, amount1Out, address(this), new bytes(0));

        emit Exchange(pair, targetOutAmount, output);
    }

    function _swapSingleSupportFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        address pool,
        uint256 swapAmount,
        uint256 limitReturnAmount
    ) internal returns (uint256 tokenAmountOut) {
        TransferHelper.safeTransfer(tokenIn, pool, swapAmount);

        uint256 amountOutput;
        {
            (, uint256 reserveInput, uint256 reserveOutput, uint32 tokenWeightInput, uint32 tokenWeightOutput, uint32 swapFee) =
                IValueLiquidFormula(formula).getFactoryReserveAndWeights(factory, pool, tokenIn);
            uint256 amountInput = IERC20(tokenIn).balanceOf(pool).sub(reserveInput);
            amountOutput = IValueLiquidFormula(formula).getAmountOut(amountInput, reserveInput, reserveOutput, tokenWeightInput, tokenWeightOutput, swapFee);
        }
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(address(this));
        (uint256 amount0Out, uint256 amount1Out) = tokenIn == IValueLiquidPair(pool).token0() ? (uint256(0), amountOutput) : (amountOutput, uint256(0));
        IValueLiquidPair(pool).swap(amount0Out, amount1Out, address(this), new bytes(0));
        emit Exchange(pool, amountOutput, tokenOut);

        tokenAmountOut = IERC20(tokenOut).balanceOf(address(this)).sub(balanceBefore);
        require(tokenAmountOut >= limitReturnAmount, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function _validateAmountOut(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] memory path
    ) internal view returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsOut(factory, tokenIn, tokenOut, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    }

    function _validateAmountIn(
        address tokenIn,
        address tokenOut,
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path
    ) internal view returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, tokenIn, tokenOut, amountOut, path);
        require(amounts[0] <= amountInMax, "Router: EXCESSIVE_INPUT_AMOUNT");
    }

    function transferETHTo(uint256 amount, address to) internal {
        IWETH(WETH).deposit{value: amount}();
        assert(IWETH(WETH).transfer(to, amount));
    }

    function transferAll(
        address token,
        address to,
        uint256 amount
    ) internal returns (bool) {
        if (amount == 0) {
            return true;
        }

        if (isETH(token)) {
            IWETH(WETH).withdraw(amount);
            TransferHelper.safeTransferETH(to, amount);
        } else {
            TransferHelper.safeTransfer(token, to, amount);
        }
        return true;
    }

    function isETH(address token) internal pure returns (bool) {
        return (token == ETH_ADDRESS);
    }

    // **** REMOVE LIQUIDITY ****
    function _removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to
    ) internal returns (uint256 amountA, uint256 amountB) {
        require(IValueLiquidFactory(factory).isPair(pair), "Router: Invalid pair");
        IValueLiquidPair(pair).transferFrom(msg.sender, pair, liquidity);
        // send liquidity to pair
        (uint256 amount0, uint256 amount1) = IValueLiquidPair(pair).burn(to);
        (address token0, ) = IValueLiquidFormula(formula).sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, "Router: INSUFFICIENT_A_AMOUNT");
        require(amountB >= amountBMin, "Router: INSUFFICIENT_B_AMOUNT");
    }

    function removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256 amountA, uint256 amountB) {
        (amountA, amountB) = _removeLiquidity(pair, tokenA, tokenB, liquidity, amountAMin, amountBMin, to);
    }

    function removeLiquidityETH(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256 amountToken, uint256 amountETH) {
        (amountToken, amountETH) = _removeLiquidity(pair, token, WETH, liquidity, amountTokenMin, amountETHMin, address(this));
        TransferHelper.safeTransfer(token, to, amountToken);
        transferAll(ETH_ADDRESS, to, amountETH);
    }

    function removeLiquidityWithPermit(
        address pair,
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override ensure(deadline) returns (uint256 amountA, uint256 amountB) {
        {
            uint256 value = approveMax ? uint256(-1) : liquidity;
            IValueLiquidPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        }
        (amountA, amountB) = _removeLiquidity(pair, tokenA, tokenB, liquidity, amountAMin, amountBMin, to);
    }

    function removeLiquidityETHWithPermit(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override returns (uint256 amountToken, uint256 amountETH) {
        uint256 value = approveMax ? uint256(-1) : liquidity;
        IValueLiquidPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        (amountToken, amountETH) = removeLiquidityETH(pair, token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }

    // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) ****
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256 amountETH) {
        (, amountETH) = removeLiquidity(pair, token, WETH, liquidity, amountTokenMin, amountETHMin, address(this), deadline);
        TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this)));
        transferAll(ETH_ADDRESS, to, amountETH);
    }

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override returns (uint256 amountETH) {
        uint256 value = approveMax ? uint256(-1) : liquidity;
        IValueLiquidPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(pair, token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"address","name":"output","type":"address"}],"name":"Exchange","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint32","name":"tokenWeightA","type":"uint32"},{"internalType":"uint32","name":"swapFee","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"createPair","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint32","name":"tokenWeight","type":"uint32"},{"internalType":"uint32","name":"swapFee","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"createPairETH","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"formula","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"swapAmount","type":"uint256"},{"internalType":"uint256","name":"limitReturnAmount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"internalType":"struct IValueLiquidRouter.Swap[][]","name":"swapSequences","type":"tuple[][]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"totalAmountIn","type":"uint256"},{"internalType":"uint256","name":"minTotalAmountOut","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"multihopBatchSwapExactIn","outputs":[{"internalType":"uint256","name":"totalAmountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"swapAmount","type":"uint256"},{"internalType":"uint256","name":"limitReturnAmount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"internalType":"struct IValueLiquidRouter.Swap[][]","name":"swapSequences","type":"tuple[][]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"maxTotalAmountIn","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"multihopBatchSwapExactOut","outputs":[{"internalType":"uint256","name":"totalAmountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101006040523480156200001257600080fd5b50604051620057c8380380620057c883398101604081905262000035916200012f565b6001600160601b0319606084811b821660805283901b1660a05260408051634b75f54f60e01b815290516001600160a01b03851691634b75f54f916004808301926020929190829003018186803b1580156200009057600080fd5b505afa158015620000a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000cb91906200010b565b6001600160601b0319606091821b811660c05291901b1660e05250620001789050565b80516001600160a01b03811681146200010657600080fd5b919050565b6000602082840312156200011d578081fd5b6200012882620000ee565b9392505050565b60008060006060848603121562000144578182fd5b6200014f84620000ee565b92506200015f60208501620000ee565b91506200016f60408501620000ee565b90509250925092565b60805160601c60a05160601c60c05160601c60e05160601c61554662000282600039806101b752806108345280610a315280610ba45280611067528061141b528061147f52806114d452806115bb5280611c1b5280611d7d5280611ef15280611f635280611fca52806129eb5280612a795280612b325280612c1d528061313852508061061b5280610de552806122f352806125c452806127185280612d37528061325b528061366452806139b45280613b095280613f6b5280614077528061418e525080611d18525080610b675280610e2152806116ad528061196552806120d852806126005280612d645280613288528061369152806139f05280613e8952506155466000f3fe60806040526004361061019a5760003560e01c8063b05f579e116100e1578063d59e44ee1161008a578063f77c479111610064578063f77c479114610463578063fa3219d514610478578063fbf4513514610498578063fde1adda146104b8576101e0565b8063d59e44ee14610403578063e1f4a78414610423578063ebb5d2e914610443576101e0565b8063c45a0155116100bb578063c45a0155146103bb578063ce819632146103d0578063d0f2c82a146103e3576101e0565b8063b05f579e14610368578063b56b681d1461037b578063bff51d711461039b576101e0565b80636cb4942811610143578063a4aabb081161011d578063a4aabb0814610313578063a67d0e3c14610333578063ad5c464814610353576101e0565b80636cb49428146102c0578063840c34d0146102d35780639c91fcb5146102e6576101e0565b80634c17fd7c116101745780634c17fd7c1461025f5780635cae03101461028d578063674ee80b146102ad576101e0565b80630e2f024c146101e55780633990ba541461021b5780634b75f54f1461023d576101e0565b366101e0573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101de57fe5b005b600080fd5b3480156101f157600080fd5b50610205610200366004614842565b6104cb565b60405161021291906153bd565b60405180910390f35b61022e6102293660046147d1565b6105ae565b6040516102129392919061540f565b34801561024957600080fd5b50610252610619565b6040516102129190614d76565b34801561026b57600080fd5b5061027f61027a366004614503565b61063d565b6040516102129291906153c6565b34801561029957600080fd5b506101de6102a83660046149e8565b61074d565b6101de6102bb36600461496e565b610920565b6102056102ce366004614ae0565b610b62565b6102056102e1366004614b47565b610c54565b3480156102f257600080fd5b506103066103013660046149e8565b611024565b6040516102129190615005565b34801561031f57600080fd5b5061027f61032e366004614842565b611187565b34801561033f57600080fd5b506101de61034e36600461464c565b611270565b34801561035f57600080fd5b50610252611419565b61030661037636600461496e565b61143d565b34801561038757600080fd5b5061027f6103963660046147d1565b611576565b3480156103a757600080fd5b506103066103b63660046146e3565b611620565b3480156103c757600080fd5b506102526116ab565b6102056103de366004614bb9565b6116cf565b3480156103ef57600080fd5b506102056103fe3660046148eb565b611960565b34801561040f57600080fd5b5061030661041e36600461464c565b611acc565b34801561042f57600080fd5b5061027f61043e36600461447f565b611b78565b34801561044f57600080fd5b5061020561045e3660046147d1565b611bd7565b34801561046f57600080fd5b50610252611d16565b34801561048457600080fd5b506103066104933660046149e8565b611d3a565b3480156104a457600080fd5b5061022e6104b33660046145be565b611da5565b6103066104c636600461496e565b611eaf565b600080856104d9578a6104fb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8e169063d505accf9061055c903390309086908d908c908c908c90600401614d97565b600060405180830381600087803b15801561057657600080fd5b505af115801561058a573d6000803e3d6000fd5b5050505061059d8d8d8d8d8d8d8d611bd7565b9d9c50505050505050505050505050565b600080600083428110156105f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b60405180910390fd5b6106058b8b8b8b8b8b611fbe565b919d909c50909a5098505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600080864281101561067b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b600087610688578c6106aa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508f73ffffffffffffffffffffffffffffffffffffffff1663d505accf3330848d8c8c8c6040518863ffffffff1660e01b81526004016106f19796959493929190614d97565b600060405180830381600087803b15801561070b57600080fd5b505af115801561071f573d6000803e3d6000fd5b50505050506107338f8f8f8f8f8f8f6120d3565b8093508194505050509c509c9a5050505050505050505050565b8042811015610788576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6107b588338787600081811061079a57fe5b90506020020160208101906107af919061440e565b8a612463565b6107f48886868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525030925061258f915050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610869903090600401614d76565b60206040518083038186803b15801561088157600080fd5b505afa158015610895573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b99190614cd5565b9050868110156108f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b61091473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8583612991565b50505050505050505050565b804281101561095b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b3461098581878760008161096b57fe5b9050602002016020810190610980919061440e565b612a77565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8a16906370a08231906109da908890600401614d76565b60206040518083038186803b1580156109f257600080fd5b505afa158015610a06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2a9190614cd5565b9050610a8b7f00000000000000000000000000000000000000000000000000000000000000008888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a925061258f915050565b87610b1f828b73ffffffffffffffffffffffffffffffffffffffff166370a08231896040518263ffffffff1660e01b8152600401610ac99190614d76565b60206040518083038186803b158015610ae157600080fd5b505afa158015610af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b199190614cd5565b90612bc8565b1015610b57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b505050505050505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166314572adb887f000000000000000000000000000000000000000000000000000000000000000088886040518563ffffffff1660e01b8152600401610be49493929190614f71565b602060405180830381600087803b158015610bfe57600080fd5b505af1158015610c12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c36919061442a565b9050610c4781888860008088611fbe565b9998505050505050505050565b60008142811015610c91576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b610c9b8685612c0b565b5060005b8751811015610fbc576000888281518110610cb657fe5b60200260200101515160011415610d21576000898381518110610cd557fe5b6020026020010151600081518110610ce957fe5b60200260200101519050610d19816020015182604001518360000151846060015185608001518660a00151612cb6565b915050610fa7565b6000808a8481518110610d3057fe5b6020026020010151600181518110610d4457fe5b602002602001015190506000600167ffffffffffffffff81118015610d6857600080fd5b50604051908082528060200260200182016040528015610d92578160200160208202803683370190505b509050816000015181600081518110610da757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166367f84adc7f0000000000000000000000000000000000000000000000000000000000000000856020015186604001518760600151876040518663ffffffff1660e01b8152600401610e70959493929190614ef1565b60006040518083038186803b158015610e8857600080fd5b505afa158015610e9c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610ee29190810190614c35565b905080600081518110610ef157fe5b602002602001015193508260800151841115610f39576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150ee565b505060008b8581518110610f4957fe5b6020026020010151600081518110610f5d57fe5b60200260200101519050610f898160200151826040015183600001518685608001518660a00151612cb6565b9350610fa382602001518360000151858560600151612e75565b5050505b610fb181856130ae565b935050600101610c9f565b5083821115610ff7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615201565b61100a8533611005886130eb565b612991565b506110198633611005896130eb565b505095945050505050565b60608142811015611061576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6110c1897f00000000000000000000000000000000000000000000000000000000000000008a8a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061321b92505050565b91506111048933888860008181106110d557fe5b90506020020160208101906110ea919061440e565b856000815181106110f757fe5b6020026020010151612463565b6111448983888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613386915050565b61117a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858460018651038151811061116d57fe5b6020026020010151612991565b5050979650505050505050565b600080600086611197578b6111b9565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8f169063d505accf9061121a903390309086908e908d908d908d90600401614d97565b600060405180830381600087803b15801561123457600080fd5b505af1158015611248573d6000803e3d6000fd5b5050505061125b8e8e8e8e8e8e8e611576565b909f909e509c50505050505050505050505050565b80428110156112ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6112bd89338787600081811061079a57fe5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8a16906370a0823190611312908790600401614d76565b60206040518083038186803b15801561132a57600080fd5b505afa15801561133e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113629190614cd5565b90506113a38a87878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525089925061258f915050565b866113e1828b73ffffffffffffffffffffffffffffffffffffffff166370a08231886040518263ffffffff1660e01b8152600401610ac99190614d76565b1015610914576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b7f000000000000000000000000000000000000000000000000000000000000000081565b6060814281101561147a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6114a87f00000000000000000000000000000000000000000000000000000000000000008989348a8a613624565b91506114cf826000815181106114ba57fe5b60200260200101518787600081811061096b57fe5b61152f7f0000000000000000000000000000000000000000000000000000000000000000838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613386915050565b8160008151811061153c57fe5b602002602001015134111561156b5761156b338360008151811061155c57fe5b6020026020010151340361378f565b509695505050505050565b60008082428110156115b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6115e38a8a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b306120d3565b90935091506115f3898685613848565b61161273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8684612991565b505097509795505050505050565b6060814281101561165d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b61166a898989898961321b565b915061169389338760008151811061167e57fe5b6020026020010151856000815181106110f757fe5b61169f89838787613386565b50979650505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000814281101561170c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6117168786612c0b565b5060006117228761396a565b6117cb576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816906370a0823190611778903390600401614d76565b60206040518083038186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c89190614cd5565b90505b60005b8951811015611875576000805b8b83815181106117e757fe5b60200260200101515181101561185f5760008c848151811061180557fe5b6020026020010151828151811061181857fe5b60200260200101519050816001141561183357606081018390525b6118548160200151826040015183600001518460600151856080015161399c565b9250506001016117db565b5061186a81866130ae565b9450506001016117ce565b50611881873385612991565b5061189088336110058b6130eb565b5061189a8761396a565b156118de57848310156118d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906151ca565b611954565b8461191c828973ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610ac99190614d76565b1015611954576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150b7565b50509695505050505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166314572adb8a8a88886040518563ffffffff1660e01b81526004016119c29493929190614f71565b602060405180830381600087803b1580156119dc57600080fd5b505af11580156119f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a14919061442a565b9050611a26818a8a8a8a600080613e49565b50506040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636a62784290611a7a908690600401614d76565b602060405180830381600087803b158015611a9457600080fd5b505af1158015611aa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c479190614cd5565b60608142811015611b09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611b178a8a8a8a8a8a613624565b9150611b2b8a33888860008181106110d557fe5b611b6b8a838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613386915050565b5098975050505050505050565b6000808242811015611bb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611bc58b8b8b8b8b8b8b6120d3565b909c909b509950505050505050505050565b60008142811015611c14576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611c4489897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a611b78565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152909350611cf791508990869073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190611ca2903090600401614d76565b60206040518083038186803b158015611cba57600080fd5b505afa158015611cce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cf29190614cd5565b613848565b61117a73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8584612991565b7f000000000000000000000000000000000000000000000000000000000000000081565b60608142811015611d77576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b6110c1897f00000000000000000000000000000000000000000000000000000000000000008a8a8a8a613624565b60008060008342811015611de5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611df48d8d8d8d8d8d8d613e49565b6040517f6a627842000000000000000000000000000000000000000000000000000000008152919550935073ffffffffffffffffffffffffffffffffffffffff8e1690636a62784290611e4b908990600401614d76565b602060405180830381600087803b158015611e6557600080fd5b505af1158015611e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9d9190614cd5565b91505099509950999650505050505050565b60608142811015611eec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615238565b611f4c7f000000000000000000000000000000000000000000000000000000000000000089348a8a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061321b92505050565b9150611f5e826000815181106114ba57fe5b61156b7f0000000000000000000000000000000000000000000000000000000000000000838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250613386915050565b6000806000611ff289897f00000000000000000000000000000000000000000000000000000000000000008a348b8b613e84565b909350915061200388338b86612463565b61200d828a612a77565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a1690636a6278429061205f908790600401614d76565b602060405180830381600087803b15801561207957600080fd5b505af115801561208d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120b19190614cd5565b9050813411156120c7576120c73383340361378f565b96509650969350505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e5e31b138a6040518263ffffffff1660e01b815260040161212f9190614d76565b60206040518083038186803b15801561214757600080fd5b505afa15801561215b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217f9190614cb9565b6121b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615386565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16906323b872dd9061220b9033908d908b90600401614de5565b602060405180830381600087803b15801561222557600080fd5b505af1158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190614cb9565b506000808a73ffffffffffffffffffffffffffffffffffffffff166389afcb44866040518263ffffffff1660e01b815260040161229a9190614d76565b6040805180830381600087803b1580156122b357600080fd5b505af11580156122c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122eb9190614ced565b9150915060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663544caa568c8c6040518363ffffffff1660e01b815260040161234c929190614e16565b604080518083038186803b15801561236357600080fd5b505afa158015612377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239b9190614446565b5090508073ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff16146123d85781836123db565b82825b90955093508785101561241a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615193565b86841015612454576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615125565b50505097509795505050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161249793929190614de5565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516124e59190614d5a565b6000604051808303816000865af19150503d8060008114612522576040519150601f19603f3d011682016040523d82523d6000602084013e612527565b606091505b50915091508180156125515750805115806125515750808060200190518101906125519190614cb9565b612587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615329565b505050505050565b8260005b835181101561298a5760008482815181106125aa57fe5b6020026020010151905060008060008060008060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f00000000000000000000000000000000000000000000000000000000000000008c8f6040518463ffffffff1660e01b815260040161263f93929190614e3d565b60c06040518083038186803b15801561265757600080fd5b505afa15801561266b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268f9190614a6d565b9550955095509550955095506126d8858d73ffffffffffffffffffffffffffffffffffffffff166370a082318d6040518263ffffffff1660e01b8152600401610ac99190614d76565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290995073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063671a11b590612757908c9089908990899089908990600401615425565b60206040518083038186803b15801561276f57600080fd5b505afa158015612783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a79190614cd5565b97508596505050505050506000808573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156127fb57600080fd5b505afa15801561280f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612833919061442a565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461286d57836000612871565b6000845b91509150600060018b5103881061288857896128a0565b8a886001018151811061289757fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f9061290890869086908690602481016153d4565b600060405180830381600087803b15801561292257600080fd5b505af1158015612936573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4887868660405161296d93929190614fd5565b60405180910390a150919650506001909401935061259392505050565b5050505050565b6000816129a057506001612a70565b6129a98461396a565b15612a61576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632e1a7d4d90612a209085906004016153bd565b600060405180830381600087803b158015612a3a57600080fd5b505af1158015612a4e573d6000803e3d6000fd5b50505050612a5c838361378f565b612a6c565b612a6c848484613848565b5060015b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015612adf57600080fd5b505af1158015612af3573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb9250612b6c915084908690600401614faf565b602060405180830381600087803b158015612b8657600080fd5b505af1158015612b9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bbe9190614cb9565b612bc457fe5b5050565b80820382811115612c05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615049565b92915050565b6000612c168361396a565b15612ca1577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015612c8357600080fd5b505af1158015612c97573d6000803e3d6000fd5b5050505050612cad565b612cad83333085612463565b50600192915050565b604080516001808252818301909252600091829190602080830190803683370190505090508581600081518110612ce957fe5b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f67f84adc0000000000000000000000000000000000000000000000000000000081526000917f000000000000000000000000000000000000000000000000000000000000000016906367f84adc90612d94907f0000000000000000000000000000000000000000000000000000000000000000908d908d908c908990600401614ef1565b60006040518083038186803b158015612dac57600080fd5b505afa158015612dc0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612e069190810190614c35565b905080600081518110612e1557fe5b6020026020010151925084831115612e59576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150ee565b61195489888584600181518110612e6c57fe5b60200260200101515b612e80848484613848565b600083905060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015612ecd57600080fd5b505afa158015612ee1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f05919061442a565b905060008060008373ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614612f485785600085612fc9565b6000868673ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015612f9157600080fd5b505afa158015612fa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc9919061442a565b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152929550909350915073ffffffffffffffffffffffffffffffffffffffff86169063022c0d9f9061303690869086903090602481016153d4565b600060405180830381600087803b15801561305057600080fd5b505af1158015613064573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4888878360405161309b93929190614fd5565b60405180910390a1505050505050505050565b80820182811015612c05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061515c565b60006130f68261396a565b156131c4576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a082319061316d903090600401614d76565b60206040518083038186803b15801561318557600080fd5b505afa158015613199573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131bd9190614cd5565b9050613216565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906370a082319061316d903090600401614d76565b919050565b6040517f119220a500000000000000000000000000000000000000000000000000000000815260609073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063119220a5906132b8907f0000000000000000000000000000000000000000000000000000000000000000908a908a908a908990600401614ef1565b60006040518083038186803b1580156132d057600080fd5b505afa1580156132e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261332a9190810190614c35565b9050828160018351038151811061333d57fe5b6020026020010151101561337d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b95945050505050565b8360005b83518110156125875760008482815181106133a157fe5b6020026020010151905060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156133f357600080fd5b505afa158015613407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342b919061442a565b9050600087846001018151811061343e57fe5b6020026020010151905060008060008473ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613489578360008661350a565b6000848773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156134d257600080fd5b505afa1580156134e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061350a919061442a565b925092509250600060018b51038810613523578961353b565b8a886001018151811061353257fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f906135a390879087908690602481016153d4565b600060405180830381600087803b1580156135bd57600080fd5b505af11580156135d1573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4887868460405161360893929190614fd5565b60405180910390a1509650506001909401935061338a92505050565b6040517f67f84adc00000000000000000000000000000000000000000000000000000000815260609073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906367f84adc906136c3907f0000000000000000000000000000000000000000000000000000000000000000908b908b908b908a908a90600401614e6d565b60006040518083038186803b1580156136db57600080fd5b505afa1580156136ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526137359190810190614c35565b9050838160008151811061374557fe5b60200260200101511115613785576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906150ee565b9695505050505050565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040516137c69190614d5a565b60006040518083038185875af1925050503d8060008114613803576040519150601f19603f3d011682016040523d82523d6000602084013e613808565b606091505b5050905080613843576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee906152cc565b505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161387a929190614faf565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516138c89190614d5a565b6000604051808303816000865af19150503d8060008114613905576040519150601f19603f3d011682016040523d82523d6000602084013e61390a565b606091505b50915091508180156139345750805115806139345750808060200190518101906139349190614cb9565b61298a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615080565b73ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14919050565b60006139a9868585613848565b6000806000806000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f00000000000000000000000000000000000000000000000000000000000000008c8f6040518463ffffffff1660e01b8152600401613a2f93929190614e3d565b60c06040518083038186803b158015613a4757600080fd5b505afa158015613a5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a7f9190614a6d565b95509550955095509550506000613ac9868e73ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401610ac99190614d76565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063671a11b590613b489084908a908a908a908a908a90600401615425565b60206040518083038186803b158015613b6057600080fd5b505afa158015613b74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b989190614cd5565b965050505050505060008673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401613bdb9190614d76565b60206040518083038186803b158015613bf357600080fd5b505afa158015613c07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c2b9190614cd5565b90506000808773ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015613c7657600080fd5b505afa158015613c8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cae919061442a565b73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614613ce857836000613cec565b6000845b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152919350915073ffffffffffffffffffffffffffffffffffffffff89169063022c0d9f90613d5690859085903090602481016153d4565b600060405180830381600087803b158015613d7057600080fd5b505af1158015613d84573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4888858b604051613dbb93929190614fd5565b60405180910390a1613e00838a73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ac99190614d76565b945085851015613e3c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee9061526f565b5050505095945050505050565b600080613e5b89898989898989613e84565b9092509050613e6c88338b85612463565b613e7887338b84612463565b97509795505050505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e5e31b138a6040518263ffffffff1660e01b8152600401613ee09190614d76565b60206040518083038186803b158015613ef857600080fd5b505afa158015613f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f309190614cb9565b613f66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615386565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663327494618c8c8c6040518463ffffffff1660e01b8152600401613fc693929190614e3d565b604080518083038186803b158015613fdd57600080fd5b505afa158015613ff1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140159190614ced565b91509150816000148015614027575080155b1561403757879350869250611612565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063ad615dec906140b0908c908790879060040161540f565b60206040518083038186803b1580156140c857600080fd5b505afa1580156140dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141009190614cd5565b905087811161414e5785811015614143576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615125565b889450925082612454565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063ad615dec906141c7908c908790899060040161540f565b60206040518083038186803b1580156141df57600080fd5b505afa1580156141f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142179190614cd5565b90508981111561422357fe5b8781101561425d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ee90615193565b9c979b50969950505050505050505050565b8035613216816154cb565b60008083601f84011261428b578182fd5b50813567ffffffffffffffff8111156142a2578182fd5b60208301915083602080830285010111156142bc57600080fd5b9250929050565b600082601f8301126142d3578081fd5b813560206142e86142e38361547d565b615459565b82815281810190858301855b858110156143f0578135880189603f82011261430e578788fd5b8581013561431e6142e38261547d565b808282528882019150604084018d604060c08602870101111561433f578b8cfd5b8b94505b838510156143da5760c0818f03121561435a578b8cfd5b60405160c0810181811067ffffffffffffffff8211171561437757fe5b6040528135614385816154cb565b8152614392828c0161426f565b8b8201526143a26040830161426f565b6040820152606082810135908201526080808301359082015260a080830135908201528352600194909401939189019160c001614343565b50875250505092840192908401906001016142f4565b5090979650505050505050565b803560ff8116811461321657600080fd5b60006020828403121561441f578081fd5b8135612a70816154cb565b60006020828403121561443b578081fd5b8151612a70816154cb565b60008060408385031215614458578081fd5b8251614463816154cb565b6020840151909250614474816154cb565b809150509250929050565b600080600080600080600080610100898b03121561449b578384fd5b88356144a6816154cb565b975060208901356144b6816154cb565b965060408901356144c6816154cb565b9550606089013594506080890135935060a0890135925060c08901356144eb816154cb565b8092505060e089013590509295985092959890939650565b6000806000806000806000806000806000806101808d8f031215614525578586fd5b8c35614530816154cb565b9b5060208d0135614540816154cb565b9a5060408d0135614550816154cb565b995060608d0135985060808d0135975060a08d0135965060c08d0135614575816154cb565b955060e08d013594506101008d013561458d816154f0565b935061459c6101208e016143fd565b92506101408d013591506101608d013590509295989b509295989b509295989b565b60008060008060008060008060006101208a8c0312156145dc578283fd5b89356145e7816154cb565b985060208a01356145f7816154cb565b975060408a0135614607816154cb565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135614633816154cb565b809250506101008a013590509295985092959850929598565b60008060008060008060008060e0898b031215614667578182fd5b8835614672816154cb565b97506020890135614682816154cb565b96506040890135955060608901359450608089013567ffffffffffffffff8111156146ab578283fd5b6146b78b828c0161427a565b90955093505060a08901356146cb816154cb565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a0312156146fd578081fd5b8735614708816154cb565b9650602088810135614719816154cb565b96506040890135955060608901359450608089013567ffffffffffffffff811115614742578283fd5b8901601f81018b13614752578283fd5b80356147606142e38261547d565b81815283810190838501858402850186018f101561477c578687fd5b8694505b838510156147a7578035614793816154cb565b835260019490940193918501918501614780565b5080975050505050506147bc60a0890161426f565b915060c0880135905092959891949750929550565b600080600080600080600060e0888a0312156147eb578081fd5b87356147f6816154cb565b96506020880135614806816154cb565b955060408801359450606088013593506080880135925060a088013561482b816154cb565b8092505060c0880135905092959891949750929550565b60008060008060008060008060008060006101608c8e031215614863578485fd5b8b3561486e816154cb565b9a5060208c013561487e816154cb565b995060408c0135985060608c0135975060808c0135965060a08c01356148a3816154cb565b955060c08c0135945060e08c01356148ba816154f0565b93506148c96101008d016143fd565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600080600080600060e0888a031215614905578081fd5b8735614910816154cb565b96506020880135614920816154cb565b95506040880135945060608801359350608088013561493e816154fe565b925060a088013561494e816154fe565b915060c088013561495e816154cb565b8091505092959891949750929550565b60008060008060008060a08789031215614986578384fd5b8635614991816154cb565b955060208701359450604087013567ffffffffffffffff8111156149b3578485fd5b6149bf89828a0161427a565b90955093505060608701356149d3816154cb565b80925050608087013590509295509295509295565b600080600080600080600060c0888a031215614a02578081fd5b8735614a0d816154cb565b96506020880135955060408801359450606088013567ffffffffffffffff811115614a36578182fd5b614a428a828b0161427a565b9095509350506080880135614a56816154cb565b8092505060a0880135905092959891949750929550565b60008060008060008060c08789031215614a85578384fd5b8651614a90816154cb565b8096505060208701519450604087015193506060870151614ab0816154fe565b6080880151909350614ac1816154fe565b60a0880151909250614ad2816154fe565b809150509295509295509295565b600080600080600060a08688031215614af7578283fd5b8535614b02816154cb565b9450602086013593506040860135614b19816154fe565b92506060860135614b29816154fe565b91506080860135614b39816154cb565b809150509295509295909350565b600080600080600060a08688031215614b5e578283fd5b853567ffffffffffffffff811115614b74578384fd5b614b80888289016142c3565b9550506020860135614b91816154cb565b93506040860135614ba1816154cb565b94979396509394606081013594506080013592915050565b60008060008060008060c08789031215614bd1578384fd5b863567ffffffffffffffff811115614be7578485fd5b614bf389828a016142c3565b9650506020870135614c04816154cb565b94506040870135614c14816154cb565b959894975094956060810135955060808101359460a0909101359350915050565b60006020808385031215614c47578182fd5b825167ffffffffffffffff811115614c5d578283fd5b8301601f81018513614c6d578283fd5b8051614c7b6142e38261547d565b8181528381019083850185840285018601891015614c97578687fd5b8694505b8385101561169f578051835260019490940193918501918501614c9b565b600060208284031215614cca578081fd5b8151612a70816154f0565b600060208284031215614ce6578081fd5b5051919050565b60008060408385031215614cff578182fd5b505080516020909101519092909150565b60008151808452614d2881602086016020860161549b565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251614d6c81846020870161549b565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff97881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b600060a0820173ffffffffffffffffffffffffffffffffffffffff808a1684526020818a1681860152818916604086015287606086015260a060808601528286845260c086019050879350845b87811015614ee1578435614ecd816154cb565b841682529382019390820190600101614eba565b509b9a5050505050505050505050565b600060a0820173ffffffffffffffffffffffffffffffffffffffff8089168452602081891681860152818816604086015286606086015260a0608086015282865180855260c0870191508288019450855b81811015614f60578551851683529483019491830191600101614f42565b50909b9a5050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff948516815292909316602083015263ffffffff9081166040830152909116606082015260800190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff93841681526020810192909252909116604082015260600190565b6020808252825182820181905260009190848201906040850190845b8181101561503d57835183529284019291840191600101615021565b50909695505050505050565b60208082526015908201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604082015260600190565b6020808252601f908201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604082015260600190565b60208082526012908201527f3c6d696e546f74616c416d6f756e744f75740000000000000000000000000000604082015260600190565b6020808252601e908201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604082015260600190565b60208082526014908201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604082015260600190565b6020808252600d908201527f4552525f4c494d49545f4f555400000000000000000000000000000000000000604082015260600190565b6020808252600c908201527f4552525f4c494d49545f494e0000000000000000000000000000000000000000604082015260600190565b6020808252600f908201527f526f757465723a20455850495245440000000000000000000000000000000000604082015260600190565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560408201527f4e54000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201527f4c45440000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160408201527f494c454400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526014908201527f526f757465723a20496e76616c69642070616972000000000000000000000000604082015260600190565b90815260200190565b918252602082015260400190565b600085825284602083015273ffffffffffffffffffffffffffffffffffffffff84166040830152608060608301526137856080830184614d10565b9283526020830191909152604082015260600190565b9586526020860194909452604085019290925263ffffffff908116606085015290811660808401521660a082015260c00190565b60405181810167ffffffffffffffff8111828210171561547557fe5b604052919050565b600067ffffffffffffffff82111561549157fe5b5060209081020190565b60005b838110156154b657818101518382015260200161549e565b838111156154c5576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff811681146154ed57600080fd5b50565b80151581146154ed57600080fd5b63ffffffff811681146154ed57600080fdfea26469706673582212200b64ee0912afd1d68a01be202a9ae707748fbd13a053643a727a00d5ba47782964736f6c634300070600330000000000000000000000001b8e12f839bd4e73a47addf76cf7f0097d74c14c000000000000000000000000be879a1a360e5beeb6abdae6b3d4cda300756a8b000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000001b8e12f839bd4e73a47addf76cf7f0097d74c14c000000000000000000000000be879a1a360e5beeb6abdae6b3d4cda300756a8b000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000001b8e12f839bd4e73a47addf76cf7f0097d74c14c
Arg [1] : 000000000000000000000000be879a1a360e5beeb6abdae6b3d4cda300756a8b
Arg [2] : 000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c


Deployed ByteCode Sourcemap

21708:27604:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22524:10;:18;22538:4;22524:18;;22517:26;;;;21708:27604;;;;;48608:701;;;;;;;;;;-1:-1:-1;48608:701:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26983:594;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;21896:41::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46518:722::-;;;;;;;;;;-1:-1:-1;46518:722:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;34684:642::-;;;;;;;;;;-1:-1:-1;34684:642:0;;;;;:::i;:::-;;:::i;34006:670::-;;;;;;:::i;:::-;;:::i;26567:408::-;;;;;;:::i;:::-;;:::i;37043:2619::-;;;;;;:::i;:::-;;:::i;30643:583::-;;;;;;;;;;-1:-1:-1;30643:583:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;47248:679::-;;;;;;;;;;-1:-1:-1;47248:679:0;;;;;:::i;:::-;;:::i;33350:648::-;;;;;;;;;;-1:-1:-1;33350:648:0;;;;;:::i;:::-;;:::i;21944:38::-;;;;;;;;;;;;;:::i;31234:580::-;;;;;;:::i;:::-;;:::i;45949:561::-;;;;;;;;;;-1:-1:-1;45949:561:0;;;;;:::i;:::-;;:::i;28512:534::-;;;;;;;;;;-1:-1:-1;28512:534:0;;;;;:::i;:::-;;:::i;21797:41::-;;;;;;;;;;;;;:::i;35334:1701::-;;;;;;:::i;:::-;;:::i;24571:498::-;;;;;;;;;;-1:-1:-1;24571:498:0;;;;;:::i;:::-;;:::i;29054:537::-;;;;;;;;;;-1:-1:-1;29054:537:0;;;;;:::i;:::-;;:::i;45501:440::-;;;;;;;;;;-1:-1:-1;45501:440:0;;;;;:::i;:::-;;:::i;48006:594::-;;;;;;;;;;-1:-1:-1;48006:594:0;;;;;:::i;:::-;;:::i;21845:44::-;;;;;;;;;;;;;:::i;30053:582::-;;;;;;;;;;-1:-1:-1;30053:582:0;;;;;:::i;:::-;;:::i;25077:669::-;;;;;;;;;;-1:-1:-1;25077:669:0;;;;;:::i;:::-;;:::i;29599:446::-;;;;;;:::i;:::-;;:::i;48608:701::-;48988:17;49018:13;49034:10;:36;;49061:9;49034:36;;;49055:2;49034:36;49081:82;;;;;49018:52;;-1:-1:-1;49081:29:0;;;;;;:82;;49111:10;;49131:4;;49018:52;;49145:8;;49155:1;;49158;;49161;;49081:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49186:115;49234:4;49240:5;49247:9;49258:14;49274:12;49288:2;49292:8;49186:47;:115::i;:::-;49174:127;48608:701;-1:-1:-1;;;;;;;;;;;;;48608:701:0:o;26983:594::-;27337:19;27371:17;27403;27295:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;27486:83:::1;27503:4;27509:5;27516:18;27536:14;27552:12;27566:2;27486:16;:83::i;:::-;27448:121:::0;;;;-1:-1:-1;27448:121:0;;-1:-1:-1;26983:594:0;-1:-1:-1;;;;;;;;;26983:594:0:o;21896:41::-;;;:::o;46518:722::-;46903:15;46920;46884:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;46963:13:::1;46979:10;:36;;47006:9;46979:36;;;47000:2;46979:36;46963:52;;47047:4;47030:29;;;47060:10;47080:4;47087:5;47094:8;47104:1;47107;47110;47030:82;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;22199:1;47155:77;47172:4;47178:6;47186;47194:9;47205:10;47217;47229:2;47155:16;:77::i;:::-;47134:98;;;;;;;;46518:722:::0;;;;;;;;;;;;;;;;:::o;34684:642::-;34950:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;34971:71:::1;35003:7;35012:10;35024:4;;35029:1;35024:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;35033:8;34971:31;:71::i;:::-;35053:64;35088:7;35097:4;;35053:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;35111:4:0::1;::::0;-1:-1:-1;35053:34:0::1;::::0;-1:-1:-1;;35053:64:0:i:1;:::-;35148:37;::::0;;;;35128:17:::1;::::0;35148:22:::1;35155:4;35148:22;::::0;::::1;::::0;:37:::1;::::0;35179:4:::1;::::0;35148:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35128:57;;35217:12;35204:9;:25;;35196:72;;;;;;;;;;;;:::i;:::-;35279:39;22036:42;35304:2;35308:9;35279:11;:39::i;:::-;;22199:1;34684:642:::0;;;;;;;;:::o;34006:670::-;34254:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;34367:9:::1;34387:32;34367:9:::0;34411:4;;34348:16:::1;34411:7:::0;::::1;;;;;;;;;;;;;;;;;:::i;:::-;34387:13;:32::i;:::-;34454:30;::::0;;;;34430:21:::1;::::0;34454:26:::1;::::0;::::1;::::0;::::1;::::0;:30:::1;::::0;34481:2;;34454:30:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34430:54;;34495:50;34530:4;34536;;34495:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;34542:2:0;;-1:-1:-1;34495:34:0::1;::::0;-1:-1:-1;;34495:50:0:i:1;:::-;34617:12;34564:49;34599:13;34571:8;34564:26;;;34591:2;34564:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:34:::0;::::1;:49::i;:::-;:65;;34556:112;;;;;;;;;;;;:::i;:::-;22199:1;;34006:670:::0;;;;;;;:::o;26567:408::-;26767:17;26797:12;26832:7;26812:39;;;26852:5;26859:4;26865:11;26878:7;26812:74;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26797:89;;26915:52;26932:4;26938:5;26945:11;26958:1;26961;26964:2;26915:16;:52::i;:::-;26897:70;26567:408;-1:-1:-1;;;;;;;;;26567:408:0:o;37043:2619::-;37298:21;37279:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;37332:42:::1;37348:7;37357:16;37332:15;:42::i;:::-;;37392:9;37387:2065;37411:13;:20;37407:1;:24;37387:2065;;;37453:30;37587:13;37601:1;37587:16;;;;;;;;;;;;;;:23;37614:1;37587:28;37583:1784;;;37636:16;37655:13;37669:1;37655:16;;;;;;;;;;;;;;37672:1;37655:19;;;;;;;;;;;;;;37636:38;;37718:113;37736:4;:12;;;37750:4;:13;;;37765:4;:9;;;37776:4;:15;;;37793:4;:22;;;37817:4;:13;;;37718:17;:113::i;:::-;37693:138;;37583:1784;;;;38168:31;38279:22:::0;38304:13:::1;38318:1;38304:16;;;;;;;;;;;;;;38321:1;38304:19;;;;;;;;;;;;;;38279:44;;38365:22;38404:1;38390:16;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;38390:16:0::1;;38365:41;;38440:10;:15;;;38429:5;38435:1;38429:8;;;;;;;;;;;;;:26;;;;;;;;;::::0;::::1;38478:24;38525:7;38505:48;;;38554:7;38563:10;:18;;;38583:10;:19;;;38604:10;:21;;;38627:5;38505:128;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;38478:155;;38682:7;38690:1;38682:10;;;;;;;;;;;;;;38656:36;;38750:10;:28;;;38723:23;:55;;38715:98;;;;;;;;;;;;:::i;:::-;37583:1784;;38939:21;38963:13;38977:1;38963:16;;;;;;;;;;;;;;38980:1;38963:19;;;;;;;;;;;;;;38939:43;;39026:146;39044:9;:17;;;39063:9;:18;;;39083:9;:14;;;39099:23;39124:9;:27;;;39153:9;:18;;;39026:17;:146::i;:::-;39001:171;;39255:96;39267:10;:18;;;39287:10;:15;;;39304:23;39329:10;:21;;;39255:11;:96::i;:::-;37583:1784;;;;39399:41;:22:::0;39426:13;39399:26:::1;:41::i;:::-;39383:57:::0;-1:-1:-1;;37433:3:0::1;;37387:2065;;;;39489:16;39472:13;:33;;39464:58;;;;;;;;;;;;:::i;:::-;39535:55;39547:8;39557:10;39569:20;39580:8;39569:10;:20::i;:::-;39535:11;:55::i;:::-;;39601:53;39613:7;39622:10;39634:19;39645:7;39634:10;:19::i;39601:53::-;;37043:2619:::0;;;;;;;;:::o;30643:583::-;30899:24;30880:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;30946:63:::1;30965:7;30974:4;30980:8;30990:12;31004:4;;30946:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;30946:18:0::1;::::0;-1:-1:-1;;;30946:63:0:i:1;:::-;30936:73;;31022;31054:7;31063:10;31075:4;;31080:1;31075:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;31084;31092:1;31084:10;;;;;;;;;;;;;;31022:31;:73::i;:::-;31106:44;31112:7;31121;31130:4;;31106:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;31144:4:0::1;::::0;-1:-1:-1;31106:5:0::1;::::0;-1:-1:-1;;31106:44:0:i:1;:::-;31161:57;22036:42;31186:2;31190:7;31215:1;31198:7;:14;:18;31190:27;;;;;;;;;;;;;;31161:11;:57::i;:::-;;30643:583:::0;;;;;;;;;;:::o;47248:679::-;47599:19;47620:17;47650:13;47666:10;:36;;47693:9;47666:36;;;47687:2;47666:36;47713:82;;;;;47650:52;;-1:-1:-1;47713:29:0;;;;;;:82;;47743:10;;47763:4;;47650:52;;47777:8;;47787:1;;47790;;47793;;47713:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47833:86;47852:4;47858:5;47865:9;47876:14;47892:12;47906:2;47910:8;47833:18;:86::i;:::-;47806:113;;;;-1:-1:-1;47248:679:0;-1:-1:-1;;;;;;;;;;;;;47248:679:0:o;33350:648::-;33646:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;33667:71:::1;33699:7;33708:10;33720:4;;33725:1;33720:7;;;;;;33667:71;33773:30;::::0;;;;33749:21:::1;::::0;33773:26:::1;::::0;::::1;::::0;::::1;::::0;:30:::1;::::0;33800:2;;33773:30:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33749:54;;33814:53;33849:7;33858:4;;33814:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;33864:2:0;;-1:-1:-1;33814:34:0::1;::::0;-1:-1:-1;;33814:53:0:i:1;:::-;33939:12;33886:49;33921:13;33893:8;33886:26;;;33913:2;33886:30;;;;;;;;;;;;;;;:::i;:49::-;:65;;33878:112;;;;;;;;;;;;:::i;21944:38::-:0;;;:::o;31234:580::-;31469:24;31450:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;31516:61:::1;31534:4;31540:8;31550:9;31561;31572:4;;31516:17;:61::i;:::-;31506:71;;31590:34;31604:7;31612:1;31604:10;;;;;;;;;;;;;;31616:4;;31621:1;31616:7;;;;;;31590:34;31635:30;31641:4;31647:7;31656:4;;31635:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;31662:2:0;;-1:-1:-1;31635:5:0::1;::::0;-1:-1:-1;;31635:30:0:i:1;:::-;31728:7;31736:1;31728:10;;;;;;;;;;;;;;31716:9;:22;31712:94;;;31740:66;31771:10;31795:7;31803:1;31795:10;;;;;;;;;;;;;;31783:9;:22;31740:30;:66::i;:::-;31234:580:::0;;;;;;;;;:::o;45949:561::-;46221:19;46242:17;46202:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;46299:91:::1;46316:4;46322:5;46329:4;46335:9;46346:14;46362:12;46384:4;46299:16;:91::i;:::-;46272:118:::0;;-1:-1:-1;46272:118:0;-1:-1:-1;46401:51:0::1;46429:5:::0;46436:2;46272:118;46401:27:::1;:51::i;:::-;46463:39;22036:42;46488:2;46492:9;46463:11;:39::i;:::-;;45949:561:::0;;;;;;;;;;;:::o;28512:534::-;28794:24;28775:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;28841:67:::1;28860:7;28869:8;28879;28889:12;28903:4;28841:18;:67::i;:::-;28831:77;;28921:73;28953:7;28962:10;28974:4;28979:1;28974:7;;;;;;;;;;;;;;28983;28991:1;28983:10;;;;;;;28921:73;29005:33;29011:7;29020;29029:4;29035:2;29005:5;:33::i;:::-;28512:534:::0;;;;;;;;;;:::o;21797:41::-;;;:::o;35334:1701::-;35621:22;35602:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;35656:39:::1;35672:7;35681:13;35656:15;:39::i;:::-;;35706:21;35743:15;35749:8;35743:5;:15::i;:::-;35738:103;;35791:38;::::0;;;;:26:::1;::::0;::::1;::::0;::::1;::::0;:38:::1;::::0;35818:10:::1;::::0;35791:38:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35775:54;;35738:103;35858:9;35853:786;35877:13;:20;35873:1;:24;35853:786;;;35919:22;::::0;35956:546:::1;35980:13;35994:1;35980:16;;;;;;;;;;;;;;:23;35976:1;:27;35956:546;;;36029:16;36048:13;36062:1;36048:16;;;;;;;;;;;;;;36065:1;36048:19;;;;;;;;;;;;;;36029:38;;36090:1;36095;36090:6;36086:247;;;36281:15;::::0;::::1;:32:::0;;;36086:247:::1;36368:118;36406:4;:12;;;36420:4;:13;;;36435:4;:9;;;36446:4;:15;;;36463:4;:22;;;36368:37;:118::i;:::-;36351:135:::0;-1:-1:-1;;36005:3:0::1;;35956:546;;;-1:-1:-1::0;36593:34:0::1;:14:::0;36612;36593:18:::1;:34::i;:::-;36576:51:::0;-1:-1:-1;;35899:3:0::1;;35853:786;;;;36651:49;36663:8;36673:10;36685:14;36651:11;:49::i;:::-;;36711:53;36723:7;36732:10;36744:19;36755:7;36744:10;:19::i;36711:53::-;;36781:15;36787:8;36781:5;:15::i;:::-;36777:251;;;36839:17;36821:14;:35;;36813:61;;;;;;;;;;;;:::i;:::-;36777:251;;;36976:17;36915:57;36958:13;36922:8;36915:26;;;36942:10;36915:38;;;;;;;;;;;;;;;:::i;:57::-;:78;;36907:109;;;;;;;;;;;;:::i;:::-;22199:1;35334:1701:::0;;;;;;;;;:::o;24571:498::-;24809:17;24839:12;24874:7;24854:39;;;24894:6;24902;24910:12;24924:7;24854:78;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24839:93;;24943:64;24962:4;24968:6;24976;24984:7;24993;25002:1;25005;24943:18;:64::i;:::-;-1:-1:-1;;25030:31:0;;;;;:27;;;;;;:31;;25058:2;;25030:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;29054:537::-;29340:24;29321:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;29387:66:::1;29405:7;29414:8;29424:9;29435:11;29448:4;;29387:17;:66::i;:::-;29377:76;;29466:73;29498:7;29507:10;29519:4;;29524:1;29519:7;;;;;;29466:73;29550:33;29556:7;29565;29574:4;;29550:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;29580:2:0;;-1:-1:-1;29550:5:0::1;::::0;-1:-1:-1;;29550:33:0:i:1;:::-;29054:537:::0;;;;;;;;;;;:::o;45501:440::-;45790:15;45807;45771:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;45856:77:::1;45873:4;45879:6;45887;45895:9;45906:10;45918;45930:2;45856:16;:77::i;:::-;45835:98:::0;;;;-1:-1:-1;45501:440:0;-1:-1:-1;;;;;;;;;;45501:440:0:o;48006:594::-;48307:17;48288:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;48353:100:::1;48369:4;48375:5;48382:4;48388:9;48399:14;48415:12;48437:4;48444:8;48353:15;:100::i;:::-;48503:38;::::0;;;;48337:116;;-1:-1:-1;48464:78:0::1;::::0;-1:-1:-1;48492:5:0;;48499:2;;48503:23:::1;::::0;::::1;::::0;::::1;::::0;:38:::1;::::0;48535:4:::1;::::0;48503:38:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48464:27;:78::i;:::-;48553:39;22036:42;48578:2;48582:9;48553:11;:39::i;21845:44::-:0;;;:::o;30053:582::-;30309:24;30290:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;30356:62:::1;30374:7;30383:4;30389:9;30400:11;30413:4;;30356:17;:62::i;25077:669::-:0;25462:15;25492;25522:17;25420:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;25588:96:::1;25607:4;25613:6;25621;25629:14;25645;25661:10;25673;25588:18;:96::i;:::-;25707:31;::::0;;;;25567:117;;-1:-1:-1;25567:117:0;-1:-1:-1;25707:27:0::1;::::0;::::1;::::0;::::1;::::0;:31:::1;::::0;25735:2;;25707:31:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25695:43;;25077:669:::0;;;;;;;;;;;;;;:::o;29599:446::-;29837:24;29818:8;22153:15;22141:8;:27;;22133:55;;;;;;;;;;;;:::i;:::-;29884:65:::1;29903:4;29909:8;29919:9;29930:12;29944:4;;29884:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;29884:18:0::1;::::0;-1:-1:-1;;;29884:65:0:i:1;:::-;29874:75;;29962:34;29976:7;29984:1;29976:10;;;;;;;29962:34;30007:30;30013:4;30019:7;30028:4;;30007:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;30034:2:0;;-1:-1:-1;30007:5:0::1;::::0;-1:-1:-1;;30007:30:0:i:1;25754:805::-:0;26006:19;26040:17;26072;26144:93;26158:4;26164:5;26171:4;26177:18;26197:9;26208:14;26224:12;26144:13;:93::i;:::-;26117:120;;-1:-1:-1;26117:120:0;-1:-1:-1;26248:69:0;26280:5;26287:10;26299:4;26117:120;26248:31;:69::i;:::-;26328:30;26342:9;26353:4;26328:13;:30::i;:::-;26381:31;;;;;:27;;;;;;:31;;26409:2;;26381:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;26369:43;;26475:9;26463;:21;26459:92;;;26486:65;26517:10;26541:9;26529;:21;26486:30;:65::i;:::-;25754:805;;;;;;;;;;:::o;44621:872::-;44852:15;44869;44925:7;44905:35;;;44941:4;44905:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44897:74;;;;;;;;;;;;:::i;:::-;44982:64;;;;;:35;;;;;;:64;;45018:10;;44999:4;;45036:9;;44982:64;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;45093:15;45110;45146:4;45129:27;;;45157:2;45129:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45092:68;;;;45172:14;45212:7;45192:39;;;45232:6;45240;45192:55;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45171:76;;;45289:6;45279:16;;:6;:16;;;:58;;45320:7;45329;45279:58;;;45299:7;45308;45279:58;45258:79;;-1:-1:-1;45258:79:0;-1:-1:-1;45356:21:0;;;;45348:63;;;;;;;;;;;;:::i;:::-;45441:10;45430:7;:21;;45422:63;;;;;;;;;;;;:::i;:::-;44621:872;;;;;;;;;;;;;:::o;8954:448::-;9179:12;9193:17;9214:5;:10;;9248;9260:4;9266:2;9270:5;9225:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9214:63;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9178:99;;;;9296:7;:57;;;;-1:-1:-1;9308:11:0;;:16;;:44;;;9339:4;9328:24;;;;;;;;;;;;:::i;:::-;9288:106;;;;;;;;;;;;:::i;:::-;8954:448;;;;;;:::o;31961:1381::-;32136:7;32120:13;32154:1181;32174:4;:11;32170:1;:15;32154:1181;;;32207:21;32248:4;32253:1;32248:7;;;;;;;;;;;;;;32207:49;;32273:19;32307:20;32342:21;32398:14;32414:20;32436:21;32459:23;32484:24;32510:14;32569:7;32549:56;;;32606:7;32623:4;32630:5;32549:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32397:239;;;;;;;;;;;;32669:56;32712:12;32676:5;32669:23;;;32701:4;32669:38;;;;;;;;;;;;;;;:::i;:56::-;32759:129;;;;;32655:70;;-1:-1:-1;32759:41:0;32779:7;32759:41;;;;:129;;32655:70;;32814:12;;32828:13;;32843:16;;32861:17;;32880:7;;32759:129;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32744:144;;32923:6;32907:22;;32154:1181;;;;;;32960:18;32980;33011:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33002:22;;:5;:22;;;:80;;33057:12;33079:1;33002:80;;;33036:1;33040:12;33002:80;32959:123;;;;33097:10;33128:1;33114:4;:11;:15;33110:1;:19;:39;;33146:3;33110:39;;;33132:4;33137:1;33141;33137:5;33132:11;;;;;;;;;;;;;;33110:39;33202:12;;;33212:1;33202:12;;;;;;;;;33164:51;;;;33097:52;;-1:-1:-1;33164:9:0;;;;;;:51;;33174:10;;33186;;33097:52;;33164:51;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33235:52;33252:4;33259:12;33273:13;33235:52;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;33310:13:0;;-1:-1:-1;;32187:3:0;;;;;-1:-1:-1;32154:1181:0;;-1:-1:-1;;;32154:1181:0;;;31961:1381;;;;:::o;44025:438::-;44141:4;44162:11;44158:55;;-1:-1:-1;44197:4:0;44190:11;;44158:55;44229:12;44235:5;44229;:12::i;:::-;44225:209;;;44258:28;;;;;:20;44264:4;44258:20;;;;:28;;44279:6;;44258:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44301:42;44332:2;44336:6;44301:30;:42::i;:::-;44225:209;;;44376:46;44404:5;44411:2;44415:6;44376:27;:46::i;:::-;-1:-1:-1;44451:4:0;44025:438;;;;;;:::o;43851:166::-;43928:4;43922:19;;;43949:6;43922:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43976:32:0;;;;;:20;43982:4;43976:20;;-1:-1:-1;43976:20:0;;-1:-1:-1;43976:32:0;;-1:-1:-1;43997:2:0;;44001:6;;43976:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43969:40;;;;43851:166;;:::o;16682:138::-;16775:5;;;16770:16;;;;16762:50;;;;;;;;;;;;:::i;:::-;16682:138;;;;:::o;39670:310::-;39744:4;39765:12;39771:5;39765;:12::i;:::-;39761:190;;;39800:4;39794:19;;;39821:9;39794:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39761:190;;;39866:73;39898:5;39905:10;39925:4;39932:6;39866:31;:73::i;:::-;-1:-1:-1;39968:4:0;39670:310;;;;:::o;40247:642::-;40517:16;;;40531:1;40517:16;;;;;;;;;40458:21;;;;40517:16;;;;;;;;;;;;-1:-1:-1;40517:16:0;40492:41;;40555:4;40544:5;40550:1;40544:8;;;;;;;;:15;;;;:8;;;;;;;;;:15;40597:95;;;;;40570:24;;40617:7;40597:48;;;;:95;;40646:7;;40655;;40664:8;;40674:10;;40686:5;;40597:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40570:122;;40719:7;40727:1;40719:10;;;;;;;;;;;;;;40703:26;;40765:17;40748:13;:34;;40740:77;;;;;;;;;;;;:::i;:::-;40828:53;40840:7;40849:4;40855:13;40870:7;40878:1;40870:10;;;;;;;;;;;;;;40897:646;41063:60;41091:7;41100:4;41106:16;41063:27;:60::i;:::-;41134:23;41177:4;41134:48;;41193:14;41210:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41193:32;;41239:18;41259;41279:14;41308:6;41297:17;;:7;:17;;;:106;;41367:15;41392:1;41396:6;41297:106;;;41326:1;41330:15;41347:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41465:12;;;41475:1;41465:12;;;;;;;;;41414:64;;;;41238:165;;-1:-1:-1;41238:165:0;;-1:-1:-1;41238:165:0;-1:-1:-1;41414:11:0;;;;;;:64;;41238:165;;;;41458:4;;41414:64;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41496:39;41505:4;41511:15;41528:6;41496:39;;;;;;;;:::i;:::-;;;;;;;;40897:646;;;;;;;;;:::o;16537:137::-;16630:5;;;16625:16;;;;16617:49;;;;;;;;;;;;:::i;39988:251::-;40046:7;40070:12;40076:5;40070;:12::i;:::-;40066:166;;;40106:36;;;;;:21;40112:4;40106:21;;;;:36;;40136:4;;40106:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40099:43;;;;40066:166;40182:38;;;;;:23;;;;;;:38;;40214:4;;40182:38;;;:::i;40066:166::-;39988:251;;;:::o;42956:450::-;43204:93;;;;;43157:24;;43204:49;43224:7;43204:49;;;;:93;;43254:7;;43263;;43272:8;;43282;;43292:4;;43204:93;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43194:103;;43347:12;43316:7;43341:1;43324:7;:14;:18;43316:27;;;;;;;;;;;;;;:43;;43308:90;;;;;;;;;;;;:::i;:::-;42956:450;;;;;;;:::o;27688:816::-;27869:7;27853:13;27887:610;27911:4;:11;27907:1;:15;27887:610;;;27944:23;27987:4;27992:1;27987:7;;;;;;;;;;;;;;27944:51;;28010:14;28027:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28010:32;;28057:17;28077:7;28085:1;28089;28085:5;28077:14;;;;;;;;;;;;;;28057:34;;28107:18;28127;28147:14;28174:6;28165:15;;:5;:15;;;:92;;28227:9;28246:1;28250:6;28165:92;;;28192:1;28196:9;28207:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28106:151;;;;;;28272:10;28303:1;28289:4;:11;:15;28285:1;:19;:39;;28321:3;28285:39;;;28307:4;28312:1;28316;28312:5;28307:11;;;;;;;;;;;;;;28285:39;28379:12;;;28389:1;28379:12;;;;;;;;;28339:53;;;;28272:52;;-1:-1:-1;28339:11:0;;;;;;:53;;28351:10;;28363;;28272:52;;28339:53;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28412:44;28429:6;28438:9;28449:6;28412:44;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;28479:6:0;-1:-1:-1;;27924:3:0;;;;;-1:-1:-1;27887:610:0;;-1:-1:-1;;;27887:610:0;43414:429;43663:93;;;;;43616:24;;43663:48;43683:7;43663:48;;;;:93;;43712:7;;43721;;43730:8;;43740:9;;43751:4;;;;43663:93;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43653:103;;43789:11;43775:7;43783:1;43775:10;;;;;;;;;;;;;;:25;;43767:68;;;;;;;;;;;;:::i;:::-;43414:429;;;;;;;;:::o;9410:200::-;9523:12;;;9483;9523;;;;;;;;;9501:7;;;;9516:5;;9501:35;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9482:54;;;9555:7;9547:55;;;;;;;;;;;;:::i;:::-;9410:200;;;:::o;8548:398::-;8734:12;8748:17;8769:5;:10;;8803;8815:2;8819:5;8780:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8769:57;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8733:93;;;;8845:7;:57;;;;-1:-1:-1;8857:11:0;;:16;;:44;;;8888:4;8877:24;;;;;;;;;;;;:::i;:::-;8837:101;;;;;;;;;;;;:::i;44471:107::-;44549:20;;;22036:42;44549:20;44471:107;;;:::o;41551:1397::-;41764:22;41799:54;41827:7;41836:4;41842:10;41799:27;:54::i;:::-;41866:20;41915;41937:21;41960:23;41985:24;42011:14;42066:7;42046:56;;;42103:7;42112:4;42118:7;42046:80;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41912:214;;;;;;;;;;;42141:19;42163:49;42199:12;42170:7;42163:25;;;42189:4;42163:31;;;;;;;;;;;;;;;:::i;:49::-;42242:129;;;;;42141:71;;-1:-1:-1;42242:41:0;42262:7;42242:41;;;;:129;;42141:71;;42297:12;;42311:13;;42326:16;;42344:17;;42363:7;;42242:129;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42227:144;;41551:1397;;;;;;42393:21;42424:8;42417:26;;;42452:4;42417:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42393:65;;42470:18;42490;42540:4;42523:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42512:42;;:7;:42;;;:100;;42587:12;42609:1;42512:100;;;42566:1;42570:12;42512:100;42690:12;;;42700:1;42690:12;;;;;;;;;42623:80;;;;42469:143;;-1:-1:-1;42469:143:0;-1:-1:-1;42623:27:0;;;;;;:80;;42469:143;;;;42683:4;;42623:80;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42719:38;42728:4;42734:12;42748:8;42719:38;;;;;;;;:::i;:::-;;;;;;;;42787:60;42833:13;42794:8;42787:26;;;42822:4;42787:41;;;;;;;;;;;;;;;:::i;:60::-;42770:77;;42884:17;42866:14;:35;;42858:82;;;;;;;;;;;;:::i;:::-;41551:1397;;;;;;;;;;;:::o;23994:569::-;24244:15;24261;24310:91;24324:4;24330:6;24338;24346:14;24362;24378:10;24390;24310:13;:91::i;:::-;24289:112;;-1:-1:-1;24289:112:0;-1:-1:-1;24412:66:0;24444:6;24452:10;24464:4;24289:112;24412:31;:66::i;:::-;24489;24521:6;24529:10;24541:4;24547:7;24489:31;:66::i;:::-;23994:569;;;;;;;;;;:::o;22655:1331::-;22908:15;22925;22981:7;22961:35;;;22997:4;22961:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22953:74;;;;;;;;;;;;:::i;:::-;23039:16;23057;23097:7;23077:40;;;23118:4;23124:6;23132;23077:62;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23038:101;;;;23154:8;23166:1;23154:13;:30;;;;-1:-1:-1;23171:13:0;;23154:30;23150:829;;;23223:14;;-1:-1:-1;23239:14:0;;-1:-1:-1;23150:829:0;;;23312:70;;;;;23287:22;;23312:34;23332:7;23312:34;;;;:70;;23347:14;;23363:8;;23373;;23312:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23287:95;;23419:14;23401;:32;23397:571;;23480:10;23462:14;:28;;23454:70;;;;;;;;;;;;:::i;:::-;23565:14;;-1:-1:-1;23581:14:0;-1:-1:-1;23581:14:0;23397:571;;;23662:70;;;;;23637:22;;23662:34;23682:7;23662:34;;;;:70;;23697:14;;23713:8;;23723;;23662:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23637:95;;23776:14;23758;:32;;23751:40;;;;23836:10;23818:14;:28;;23810:70;;;;;;;;;;;;:::i;:::-;23921:14;23937;;-1:-1:-1;22655:1331:0;;-1:-1:-1;;;;;;;;;;22655:1331:0:o;14:138:1:-;84:20;;113:33;84:20;113:33;:::i;157:404::-;;;290:3;283:4;275:6;271:17;267:27;257:2;;315:8;305;298:26;257:2;-1:-1:-1;345:20:1;;388:18;377:30;;374:2;;;427:8;417;410:26;374:2;471:4;463:6;459:17;447:29;;534:3;527:4;519;511:6;507:17;499:6;495:30;491:41;488:50;485:2;;;551:1;548;541:12;485:2;247:314;;;;;:::o;566:2147::-;;698:3;691:4;683:6;679:17;675:27;665:2;;720:5;713;706:20;665:2;760:6;747:20;786:4;810:65;825:49;871:2;825:49;:::i;:::-;810:65;:::i;:::-;909:15;;;940:12;;;;972:15;;;1005:5;1019:1665;1033:2;1030:1;1027:9;1019:1665;;;1113:3;1100:17;1092:6;1088:30;1158:3;1153:2;1149;1145:11;1141:21;1131:2;;1180:5;1173;1166:20;1131:2;1232;1228;1224:11;1211:25;1262:65;1277:49;1323:2;1277:49;:::i;1262:65::-;1353:5;1385:2;1378:5;1371:17;1421:2;1414:5;1410:14;1401:23;;1458:2;1454;1450:11;1513:3;1508:2;1500:4;1496:2;1492:13;1488:2;1484:22;1480:31;1477:40;1474:2;;;1534:5;1527;1520:20;1474:2;1566:5;1555:16;;1584:995;1600:2;1595:3;1592:11;1584:995;;;1681:4;1673:5;1668:3;1664:15;1660:26;1657:2;;;1703:5;1696;1689:20;1657:2;1748;1742:9;1798:4;1790:6;1786:17;1877:6;1865:10;1862:22;1841:18;1829:10;1826:34;1823:62;1820:2;;;1888:9;1820:2;1923;1916:22;1968:19;;2004:33;1968:19;2004:33;:::i;:::-;2054:21;;2116:36;2137:14;;;2116:36;:::i;:::-;2111:2;2103:6;2099:15;2092:61;2194:36;2226:2;2219:5;2215:14;2194:36;:::i;:::-;2189:2;2177:15;;2170:61;2296:2;2285:14;;;2272:28;2255:15;;;2248:53;2367:3;2356:15;;;2343:29;2325:16;;;2318:55;2439:3;2428:15;;;2415:29;2397:16;;;2390:55;2462:21;;1622:1;1613:11;;;;;2509:14;;;;2560:4;2549:16;1584:995;;;-1:-1:-1;2592:18:1;;-1:-1:-1;;;2630:12:1;;;;2662;;;;1051:1;1044:9;1019:1665;;;-1:-1:-1;2702:5:1;;655:2058;-1:-1:-1;;;;;;;655:2058:1:o;2718:158::-;2786:20;;2846:4;2835:16;;2825:27;;2815:2;;2866:1;2863;2856:12;2881:259;;2993:2;2981:9;2972:7;2968:23;2964:32;2961:2;;;3014:6;3006;2999:22;2961:2;3058:9;3045:23;3077:33;3104:5;3077:33;:::i;3145:263::-;;3268:2;3256:9;3247:7;3243:23;3239:32;3236:2;;;3289:6;3281;3274:22;3236:2;3326:9;3320:16;3345:33;3372:5;3345:33;:::i;3413:399::-;;;3553:2;3541:9;3532:7;3528:23;3524:32;3521:2;;;3574:6;3566;3559:22;3521:2;3611:9;3605:16;3630:33;3657:5;3630:33;:::i;:::-;3732:2;3717:18;;3711:25;3682:5;;-1:-1:-1;3745:35:1;3711:25;3745:35;:::i;:::-;3799:7;3789:17;;;3511:301;;;;;:::o;3817:965::-;;;;;;;;;4048:3;4036:9;4027:7;4023:23;4019:33;4016:2;;;4070:6;4062;4055:22;4016:2;4114:9;4101:23;4133:33;4160:5;4133:33;:::i;:::-;4185:5;-1:-1:-1;4242:2:1;4227:18;;4214:32;4255:35;4214:32;4255:35;:::i;:::-;4309:7;-1:-1:-1;4368:2:1;4353:18;;4340:32;4381:35;4340:32;4381:35;:::i;:::-;4435:7;-1:-1:-1;4489:2:1;4474:18;;4461:32;;-1:-1:-1;4540:3:1;4525:19;;4512:33;;-1:-1:-1;4592:3:1;4577:19;;4564:33;;-1:-1:-1;4649:3:1;4634:19;;4621:33;4663:35;4621:33;4663:35;:::i;:::-;4717:7;4707:17;;;4771:3;4760:9;4756:19;4743:33;4733:43;;4006:776;;;;;;;;;;;:::o;4787:1318::-;;;;;;;;;;;;;5083:3;5071:9;5062:7;5058:23;5054:33;5051:2;;;5105:6;5097;5090:22;5051:2;5149:9;5136:23;5168:33;5195:5;5168:33;:::i;:::-;5220:5;-1:-1:-1;5277:2:1;5262:18;;5249:32;5290:35;5249:32;5290:35;:::i;:::-;5344:7;-1:-1:-1;5403:2:1;5388:18;;5375:32;5416:35;5375:32;5416:35;:::i;:::-;5470:7;-1:-1:-1;5524:2:1;5509:18;;5496:32;;-1:-1:-1;5575:3:1;5560:19;;5547:33;;-1:-1:-1;5627:3:1;5612:19;;5599:33;;-1:-1:-1;5684:3:1;5669:19;;5656:33;5698:35;5656:33;5698:35;:::i;:::-;5752:7;-1:-1:-1;5806:3:1;5791:19;;5778:33;;-1:-1:-1;5863:3:1;5848:19;;5835:33;5877:32;5835:33;5877:32;:::i;:::-;5928:7;-1:-1:-1;5954:39:1;5988:3;5973:19;;5954:39;:::i;:::-;5944:49;;6041:3;6030:9;6026:19;6013:33;6002:44;;6094:3;6083:9;6079:19;6066:33;6055:44;;5041:1064;;;;;;;;;;;;;;:::o;6110:1034::-;;;;;;;;;;6358:3;6346:9;6337:7;6333:23;6329:33;6326:2;;;6380:6;6372;6365:22;6326:2;6424:9;6411:23;6443:33;6470:5;6443:33;:::i;:::-;6495:5;-1:-1:-1;6552:2:1;6537:18;;6524:32;6565:35;6524:32;6565:35;:::i;:::-;6619:7;-1:-1:-1;6678:2:1;6663:18;;6650:32;6691:35;6650:32;6691:35;:::i;:::-;6745:7;-1:-1:-1;6799:2:1;6784:18;;6771:32;;-1:-1:-1;6850:3:1;6835:19;;6822:33;;-1:-1:-1;6902:3:1;6887:19;;6874:33;;-1:-1:-1;6954:3:1;6939:19;;6926:33;;-1:-1:-1;7011:3:1;6996:19;;6983:33;7025:35;6983:33;7025:35;:::i;:::-;7079:7;7069:17;;;7133:3;7122:9;7118:19;7105:33;7095:43;;6316:828;;;;;;;;;;;:::o;7149:1094::-;;;;;;;;;7398:3;7386:9;7377:7;7373:23;7369:33;7366:2;;;7420:6;7412;7405:22;7366:2;7464:9;7451:23;7483:33;7510:5;7483:33;:::i;:::-;7535:5;-1:-1:-1;7592:2:1;7577:18;;7564:32;7605:35;7564:32;7605:35;:::i;:::-;7659:7;-1:-1:-1;7713:2:1;7698:18;;7685:32;;-1:-1:-1;7764:2:1;7749:18;;7736:32;;-1:-1:-1;7819:3:1;7804:19;;7791:33;7847:18;7836:30;;7833:2;;;7884:6;7876;7869:22;7833:2;7928:76;7996:7;7987:6;7976:9;7972:22;7928:76;:::i;:::-;8023:8;;-1:-1:-1;7902:102:1;-1:-1:-1;;8110:3:1;8095:19;;8082:33;8124:35;8082:33;8124:35;:::i;:::-;8178:7;8168:17;;;8232:3;8221:9;8217:19;8204:33;8194:43;;7356:887;;;;;;;;;;;:::o;8248:1600::-;;;;;;;;8487:3;8475:9;8466:7;8462:23;8458:33;8455:2;;;8509:6;8501;8494:22;8455:2;8553:9;8540:23;8572:33;8599:5;8572:33;:::i;:::-;8624:5;-1:-1:-1;8648:2:1;8687:18;;;8674:32;8715:35;8674:32;8715:35;:::i;:::-;8769:7;-1:-1:-1;8823:2:1;8808:18;;8795:32;;-1:-1:-1;8874:2:1;8859:18;;8846:32;;-1:-1:-1;8929:3:1;8914:19;;8901:33;8957:18;8946:30;;8943:2;;;8994:6;8986;8979:22;8943:2;9022:22;;9075:4;9067:13;;9063:27;-1:-1:-1;9053:2:1;;9109:6;9101;9094:22;9053:2;9150;9137:16;9173:65;9188:49;9234:2;9188:49;:::i;9173:65::-;9272:15;;;9303:12;;;;9335:11;;;9373;;;9365:20;;9361:29;;9358:42;-1:-1:-1;9355:2:1;;;9418:6;9410;9403:22;9355:2;9445:6;9436:15;;9460:246;9474:2;9471:1;9468:9;9460:246;;;9547:3;9534:17;9564:35;9591:7;9564:35;:::i;:::-;9612:20;;9492:1;9485:9;;;;;9652:12;;;;9684;;9460:246;;;9464:3;9725:5;9715:15;;;;;;;9749:41;9785:3;9774:9;9770:19;9749:41;:::i;:::-;9739:51;;9837:3;9826:9;9822:19;9809:33;9799:43;;8445:1403;;;;;;;;;;:::o;9853:821::-;;;;;;;;10067:3;10055:9;10046:7;10042:23;10038:33;10035:2;;;10089:6;10081;10074:22;10035:2;10133:9;10120:23;10152:33;10179:5;10152:33;:::i;:::-;10204:5;-1:-1:-1;10261:2:1;10246:18;;10233:32;10274:35;10233:32;10274:35;:::i;:::-;10328:7;-1:-1:-1;10382:2:1;10367:18;;10354:32;;-1:-1:-1;10433:2:1;10418:18;;10405:32;;-1:-1:-1;10484:3:1;10469:19;;10456:33;;-1:-1:-1;10541:3:1;10526:19;;10513:33;10555:35;10513:33;10555:35;:::i;:::-;10609:7;10599:17;;;10663:3;10652:9;10648:19;10635:33;10625:43;;10025:649;;;;;;;;;;:::o;10679:1172::-;;;;;;;;;;;;10957:3;10945:9;10936:7;10932:23;10928:33;10925:2;;;10979:6;10971;10964:22;10925:2;11023:9;11010:23;11042:33;11069:5;11042:33;:::i;:::-;11094:5;-1:-1:-1;11151:2:1;11136:18;;11123:32;11164:35;11123:32;11164:35;:::i;:::-;11218:7;-1:-1:-1;11272:2:1;11257:18;;11244:32;;-1:-1:-1;11323:2:1;11308:18;;11295:32;;-1:-1:-1;11374:3:1;11359:19;;11346:33;;-1:-1:-1;11431:3:1;11416:19;;11403:33;11445:35;11403:33;11445:35;:::i;:::-;11499:7;-1:-1:-1;11553:3:1;11538:19;;11525:33;;-1:-1:-1;11610:3:1;11595:19;;11582:33;11624:32;11582:33;11624:32;:::i;:::-;11675:7;-1:-1:-1;11701:39:1;11735:3;11720:19;;11701:39;:::i;:::-;11691:49;;11787:3;11776:9;11772:19;11759:33;11749:43;;11840:3;11829:9;11825:19;11812:33;11801:44;;10915:936;;;;;;;;;;;;;;:::o;11856:967::-;;;;;;;;12068:3;12056:9;12047:7;12043:23;12039:33;12036:2;;;12090:6;12082;12075:22;12036:2;12134:9;12121:23;12153:33;12180:5;12153:33;:::i;:::-;12205:5;-1:-1:-1;12262:2:1;12247:18;;12234:32;12275:35;12234:32;12275:35;:::i;:::-;12329:7;-1:-1:-1;12383:2:1;12368:18;;12355:32;;-1:-1:-1;12434:2:1;12419:18;;12406:32;;-1:-1:-1;12490:3:1;12475:19;;12462:33;12504:34;12462:33;12504:34;:::i;:::-;12557:7;-1:-1:-1;12616:3:1;12601:19;;12588:33;12630:34;12588:33;12630:34;:::i;:::-;12683:7;-1:-1:-1;12742:3:1;12727:19;;12714:33;12756:35;12714:33;12756:35;:::i;:::-;12810:7;12800:17;;;12026:797;;;;;;;;;;:::o;12828:881::-;;;;;;;13043:3;13031:9;13022:7;13018:23;13014:33;13011:2;;;13065:6;13057;13050:22;13011:2;13109:9;13096:23;13128:33;13155:5;13128:33;:::i;:::-;13180:5;-1:-1:-1;13232:2:1;13217:18;;13204:32;;-1:-1:-1;13287:2:1;13272:18;;13259:32;13314:18;13303:30;;13300:2;;;13351:6;13343;13336:22;13300:2;13395:76;13463:7;13454:6;13443:9;13439:22;13395:76;:::i;:::-;13490:8;;-1:-1:-1;13369:102:1;-1:-1:-1;;13577:2:1;13562:18;;13549:32;13590:35;13549:32;13590:35;:::i;:::-;13644:7;13634:17;;;13698:3;13687:9;13683:19;13670:33;13660:43;;13001:708;;;;;;;;:::o;13714:950::-;;;;;;;;13946:3;13934:9;13925:7;13921:23;13917:33;13914:2;;;13968:6;13960;13953:22;13914:2;14012:9;13999:23;14031:33;14058:5;14031:33;:::i;:::-;14083:5;-1:-1:-1;14135:2:1;14120:18;;14107:32;;-1:-1:-1;14186:2:1;14171:18;;14158:32;;-1:-1:-1;14241:2:1;14226:18;;14213:32;14268:18;14257:30;;14254:2;;;14305:6;14297;14290:22;14254:2;14349:76;14417:7;14408:6;14397:9;14393:22;14349:76;:::i;:::-;14444:8;;-1:-1:-1;14323:102:1;-1:-1:-1;;14531:3:1;14516:19;;14503:33;14545:35;14503:33;14545:35;:::i;:::-;14599:7;14589:17;;;14653:3;14642:9;14638:19;14625:33;14615:43;;13904:760;;;;;;;;;;:::o;14669:790::-;;;;;;;14874:3;14862:9;14853:7;14849:23;14845:33;14842:2;;;14896:6;14888;14881:22;14842:2;14933:9;14927:16;14952:33;14979:5;14952:33;:::i;:::-;15004:5;14994:15;;;15049:2;15038:9;15034:18;15028:25;15018:35;;15093:2;15082:9;15078:18;15072:25;15062:35;;15142:2;15131:9;15127:18;15121:25;15155:34;15181:7;15155:34;:::i;:::-;15260:3;15245:19;;15239:26;15208:7;;-1:-1:-1;15274:34:1;15239:26;15274:34;:::i;:::-;15379:3;15364:19;;15358:26;15327:7;;-1:-1:-1;15393:34:1;15358:26;15393:34;:::i;:::-;15446:7;15436:17;;;14832:627;;;;;;;;:::o;15464:754::-;;;;;;15642:3;15630:9;15621:7;15617:23;15613:33;15610:2;;;15664:6;15656;15649:22;15610:2;15708:9;15695:23;15727:33;15754:5;15727:33;:::i;:::-;15779:5;-1:-1:-1;15831:2:1;15816:18;;15803:32;;-1:-1:-1;15887:2:1;15872:18;;15859:32;15900:34;15859:32;15900:34;:::i;:::-;15953:7;-1:-1:-1;16012:2:1;15997:18;;15984:32;16025:34;15984:32;16025:34;:::i;:::-;16078:7;-1:-1:-1;16137:3:1;16122:19;;16109:33;16151:35;16109:33;16151:35;:::i;:::-;16205:7;16195:17;;;15600:618;;;;;;;;:::o;16223:857::-;;;;;;16474:3;16462:9;16453:7;16449:23;16445:33;16442:2;;;16496:6;16488;16481:22;16442:2;16541:9;16528:23;16574:18;16566:6;16563:30;16560:2;;;16611:6;16603;16596:22;16560:2;16639:86;16717:7;16708:6;16697:9;16693:22;16639:86;:::i;:::-;16629:96;;;16775:2;16764:9;16760:18;16747:32;16788:33;16815:5;16788:33;:::i;:::-;16840:5;-1:-1:-1;16897:2:1;16882:18;;16869:32;16910:35;16869:32;16910:35;:::i;:::-;16432:648;;;;-1:-1:-1;16964:7:1;;17018:2;17003:18;;16990:32;;-1:-1:-1;17069:3:1;17054:19;17041:33;;16432:648;-1:-1:-1;;16432:648:1:o;17085:926::-;;;;;;;17353:3;17341:9;17332:7;17328:23;17324:33;17321:2;;;17375:6;17367;17360:22;17321:2;17420:9;17407:23;17453:18;17445:6;17442:30;17439:2;;;17490:6;17482;17475:22;17439:2;17518:86;17596:7;17587:6;17576:9;17572:22;17518:86;:::i;:::-;17508:96;;;17654:2;17643:9;17639:18;17626:32;17667:33;17694:5;17667:33;:::i;:::-;17719:5;-1:-1:-1;17776:2:1;17761:18;;17748:32;17789:35;17748:32;17789:35;:::i;:::-;17311:700;;;;-1:-1:-1;17843:7:1;;17897:2;17882:18;;17869:32;;-1:-1:-1;17948:3:1;17933:19;;17920:33;;18000:3;17985:19;;;17972:33;;-1:-1:-1;17311:700:1;-1:-1:-1;;17311:700:1:o;18016:943::-;;18142:2;18185;18173:9;18164:7;18160:23;18156:32;18153:2;;;18206:6;18198;18191:22;18153:2;18244:9;18238:16;18277:18;18269:6;18266:30;18263:2;;;18314:6;18306;18299:22;18263:2;18342:22;;18395:4;18387:13;;18383:27;-1:-1:-1;18373:2:1;;18429:6;18421;18414:22;18373:2;18463;18457:9;18486:65;18501:49;18547:2;18501:49;:::i;18486:65::-;18585:15;;;18616:12;;;;18648:11;;;18686;;;18678:20;;18674:29;;18671:42;-1:-1:-1;18668:2:1;;;18731:6;18723;18716:22;18668:2;18758:6;18749:15;;18773:156;18787:2;18784:1;18781:9;18773:156;;;18844:10;;18832:23;;18805:1;18798:9;;;;;18875:12;;;;18907;;18773:156;;18964:257;;19084:2;19072:9;19063:7;19059:23;19055:32;19052:2;;;19105:6;19097;19090:22;19052:2;19142:9;19136:16;19161:30;19185:5;19161:30;:::i;19226:194::-;;19349:2;19337:9;19328:7;19324:23;19320:32;19317:2;;;19370:6;19362;19355:22;19317:2;-1:-1:-1;19398:16:1;;19307:113;-1:-1:-1;19307:113:1:o;19425:255::-;;;19565:2;19553:9;19544:7;19540:23;19536:32;19533:2;;;19586:6;19578;19571:22;19533:2;-1:-1:-1;;19614:16:1;;19670:2;19655:18;;;19649:25;19614:16;;19649:25;;-1:-1:-1;19523:157:1:o;19685:318::-;;19766:5;19760:12;19793:6;19788:3;19781:19;19809:63;19865:6;19858:4;19853:3;19849:14;19842:4;19835:5;19831:16;19809:63;:::i;:::-;19917:2;19905:15;19922:66;19901:88;19892:98;;;;19992:4;19888:109;;19736:267;-1:-1:-1;;19736:267:1:o;20008:274::-;;20175:6;20169:13;20191:53;20237:6;20232:3;20225:4;20217:6;20213:17;20191:53;:::i;:::-;20260:16;;;;;20145:137;-1:-1:-1;;20145:137:1:o;20287:226::-;20463:42;20451:55;;;;20433:74;;20421:2;20406:18;;20388:125::o;20757:709::-;21094:42;21163:15;;;21145:34;;21215:15;;;;21210:2;21195:18;;21188:43;21262:2;21247:18;;21240:34;;;;21305:2;21290:18;;21283:34;;;;21366:4;21354:17;21348:3;21333:19;;21326:46;21403:3;21388:19;;21381:35;21447:3;21432:19;;21425:35;;;;21071:3;21056:19;;21038:428::o;21471:406::-;21691:42;21760:15;;;21742:34;;21812:15;;;;21807:2;21792:18;;21785:43;21859:2;21844:18;;21837:34;;;;21669:2;21654:18;;21636:241::o;21882:327::-;22066:42;22135:15;;;22117:34;;22187:15;;22182:2;22167:18;;22160:43;22044:2;22029:18;;22011:198::o;22214:407::-;22426:42;22495:15;;;22477:34;;22547:15;;;22542:2;22527:18;;22520:43;22599:15;;;22594:2;22579:18;;22572:43;22404:2;22389:18;;22371:250::o;22626:1069::-;;22938:3;22927:9;22923:19;22961:42;23042:2;23034:6;23030:15;23019:9;23012:34;23065:2;23115;23107:6;23103:15;23098:2;23087:9;23083:18;23076:43;23167:2;23159:6;23155:15;23150:2;23139:9;23135:18;23128:43;23207:6;23202:2;23191:9;23187:18;23180:34;23251:3;23245;23234:9;23230:19;23223:32;23275:6;23305;23297;23290:22;23343:3;23332:9;23328:19;23321:26;;23370:6;23356:20;;23394:4;23407:262;23421:6;23418:1;23415:13;23407:262;;;23496:6;23483:20;23516:33;23543:5;23516:33;:::i;:::-;23574:14;;23562:27;;23644:15;;;;23609:12;;;;23443:1;23436:9;23407:262;;;-1:-1:-1;23686:3:1;22899:796;-1:-1:-1;;;;;;;;;;;22899:796:1:o;23700:1020::-;;24002:3;23991:9;23987:19;24025:42;24106:2;24098:6;24094:15;24083:9;24076:34;24129:2;24179;24171:6;24167:15;24162:2;24151:9;24147:18;24140:43;24231:2;24223:6;24219:15;24214:2;24203:9;24199:18;24192:43;24271:6;24266:2;24255:9;24251:18;24244:34;24315:3;24309;24298:9;24294:19;24287:32;24339:6;24374;24368:13;24405:6;24397;24390:22;24443:3;24432:9;24428:19;24421:26;;24482:2;24474:6;24470:15;24456:29;;24503:4;24516:178;24530:6;24527:1;24524:13;24516:178;;;24595:13;;24591:22;;24579:35;;24669:15;;;;24634:12;;;;24552:1;24545:9;24516:178;;;-1:-1:-1;24711:3:1;;23963:757;-1:-1:-1;;;;;;;;;;;23963:757:1:o;25128:513::-;25365:42;25434:15;;;25416:34;;25486:15;;;;25481:2;25466:18;;25459:43;25521:10;25567:15;;;25562:2;25547:18;;25540:43;25619:15;;;25614:2;25599:18;;25592:43;25342:3;25327:19;;25309:332::o;25646:297::-;25850:42;25838:55;;;;25820:74;;25925:2;25910:18;;25903:34;25808:2;25793:18;;25775:168::o;25948:398::-;26160:42;26229:15;;;26211:34;;26276:2;26261:18;;26254:34;;;;26324:15;;;26319:2;26304:18;;26297:43;26138:2;26123:18;;26105:241::o;26351:635::-;26522:2;26574:21;;;26644:13;;26547:18;;;26666:22;;;26351:635;;26522:2;26745:15;;;;26719:2;26704:18;;;26351:635;26791:169;26805:6;26802:1;26799:13;26791:169;;;26866:13;;26854:26;;26935:15;;;;26900:12;;;;26827:1;26820:9;26791:169;;;-1:-1:-1;26977:3:1;;26502:484;-1:-1:-1;;;;;;26502:484:1:o;26991:345::-;27193:2;27175:21;;;27232:2;27212:18;;;27205:30;27271:23;27266:2;27251:18;;27244:51;27327:2;27312:18;;27165:171::o;27341:355::-;27543:2;27525:21;;;27582:2;27562:18;;;27555:30;27621:33;27616:2;27601:18;;27594:61;27687:2;27672:18;;27515:181::o;27701:342::-;27903:2;27885:21;;;27942:2;27922:18;;;27915:30;27981:20;27976:2;27961:18;;27954:48;28034:2;28019:18;;27875:168::o;28048:354::-;28250:2;28232:21;;;28289:2;28269:18;;;28262:30;28328:32;28323:2;28308:18;;28301:60;28393:2;28378:18;;28222:180::o;28407:353::-;28609:2;28591:21;;;28648:2;28628:18;;;28621:30;28687:31;28682:2;28667:18;;28660:59;28751:2;28736:18;;28581:179::o;28765:344::-;28967:2;28949:21;;;29006:2;28986:18;;;28979:30;29045:22;29040:2;29025:18;;29018:50;29100:2;29085:18;;28939:170::o;29114:353::-;29316:2;29298:21;;;29355:2;29335:18;;;29328:30;29394:31;29389:2;29374:18;;29367:59;29458:2;29443:18;;29288:179::o;29472:337::-;29674:2;29656:21;;;29713:2;29693:18;;;29686:30;29752:15;29747:2;29732:18;;29725:43;29800:2;29785:18;;29646:163::o;29814:336::-;30016:2;29998:21;;;30055:2;30035:18;;;30028:30;30094:14;30089:2;30074:18;;30067:42;30141:2;30126:18;;29988:162::o;30155:339::-;30357:2;30339:21;;;30396:2;30376:18;;;30369:30;30435:17;30430:2;30415:18;;30408:45;30485:2;30470:18;;30329:165::o;30499:398::-;30701:2;30683:21;;;30740:2;30720:18;;;30713:30;30779:34;30774:2;30759:18;;30752:62;30850:4;30845:2;30830:18;;30823:32;30887:3;30872:19;;30673:224::o;30902:399::-;31104:2;31086:21;;;31143:2;31123:18;;;31116:30;31182:34;31177:2;31162:18;;31155:62;31253:5;31248:2;31233:18;;31226:33;31291:3;31276:19;;31076:225::o;31306:400::-;31508:2;31490:21;;;31547:2;31527:18;;;31520:30;31586:34;31581:2;31566:18;;31559:62;31657:6;31652:2;31637:18;;31630:34;31696:3;31681:19;;31480:226::o;31711:344::-;31913:2;31895:21;;;31952:2;31932:18;;;31925:30;31991:22;31986:2;31971:18;;31964:50;32046:2;32031:18;;31885:170::o;32060:177::-;32206:25;;;32194:2;32179:18;;32161:76::o;32242:248::-;32416:25;;;32472:2;32457:18;;32450:34;32404:2;32389:18;;32371:119::o;32495:491::-;;32734:6;32723:9;32716:25;32777:6;32772:2;32761:9;32757:18;32750:34;32832:42;32824:6;32820:55;32815:2;32804:9;32800:18;32793:83;32912:3;32907:2;32896:9;32892:18;32885:31;32933:47;32975:3;32964:9;32960:19;32952:6;32933:47;:::i;33479:319::-;33681:25;;;33737:2;33722:18;;33715:34;;;;33780:2;33765:18;;33758:34;33669:2;33654:18;;33636:162::o;33803:585::-;34084:25;;;34140:2;34125:18;;34118:34;;;;34183:2;34168:18;;34161:34;;;;34214:10;34260:15;;;34255:2;34240:18;;34233:43;34313:15;;;34307:3;34292:19;;34285:44;34366:15;34360:3;34345:19;;34338:44;34071:3;34056:19;;34038:350::o;34393:242::-;34463:2;34457:9;34493:17;;;34540:18;34525:34;;34561:22;;;34522:62;34519:2;;;34587:9;34519:2;34614;34607:22;34437:198;;-1:-1:-1;34437:198:1:o;34640:183::-;;34739:18;34731:6;34728:30;34725:2;;;34761:9;34725:2;-1:-1:-1;34812:4:1;34793:17;;;34789:28;;34715:108::o;34828:258::-;34900:1;34910:113;34924:6;34921:1;34918:13;34910:113;;;35000:11;;;34994:18;34981:11;;;34974:39;34946:2;34939:10;34910:113;;;35041:6;35038:1;35035:13;35032:2;;;35076:1;35067:6;35062:3;35058:16;35051:27;35032:2;;34881:205;;;:::o;35091:156::-;35179:42;35172:5;35168:54;35161:5;35158:65;35148:2;;35237:1;35234;35227:12;35148:2;35138:109;:::o;35252:120::-;35340:5;35333:13;35326:21;35319:5;35316:32;35306:2;;35362:1;35359;35352:12;35377:123;35464:10;35457:5;35453:22;35446:5;35443:33;35433:2;;35490:1;35487;35480:12

Swarm Source

ipfs://0b64ee0912afd1d68a01be202a9ae707748fbd13a053643a727a00d5ba477829
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.