Contract 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c

 

Contract Overview

Balance:
0 BNB

BNB Value:
$0.00

Token:
Ad
Ad
Txn Hash
Block
From
To
Value [Txn Fee]
0x771f0dd4945cb1694382e7b1de50cb8ba60687cd20ce398eeb34285d38f29a4565938092021-04-15 18:00:496 secs ago0xc932db2a3bad21fddf62aa70c66bfb71c2875d19 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000818345
0x263457b843319beb29d85df26b9405aff8fc4dc72e4c506ad37a7ab9e77ea36965938062021-04-15 18:00:4015 secs ago0x42cca31fce5c299f49f13abde67e108c8496f452 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00096164
0xb6f0d76aa77c128ea22a6a913894553e882c114c0e534b9b853aba9eb32e504e65938042021-04-15 18:00:3421 secs ago0x111fa0293c78ea77c6250d38f4ac447e196358dd IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00103785
0x28c5607e0572e20cf012ef5cf2c6184474975bf7408874cc9fd1bf5b560a966a65938042021-04-15 18:00:3421 secs ago0x321aee90cbbe22325658f83fad136dc0b4920492 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000654795
0xd306a5008d5cc522262681896a5fe974728414ec15dc3eda2f067c7e0934741765938022021-04-15 18:00:2827 secs ago0x5921ebcd810f0d283320bb95b77f7c06b9f9977a IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.0006873
0xe96ee0b37afcea12ff49b1ad0dc2d4cc598dd4a678ab60f8a57a97b997edfee465938002021-04-15 18:00:2233 secs ago0x187bdd49c94e5802055d3aa8825577971432aa80 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000835225
0x711b88c2a4fb54bcac1fc79d3fd18e4adc16e777db9e628a23d21aaa1660826965937972021-04-15 18:00:1342 secs ago0x42cca31fce5c299f49f13abde67e108c8496f452 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00025781
0xcfa9a5bf11840a55ca10c2bd5ae273b74177ec2eafa48a32703c9fdc198ef7e365937902021-04-15 17:59:521 min ago0x505f72f17d84060076ebf2a204e03b0125236dcd IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000903405
0x077fba91c95883077084eb3eb145a5b94f95f8822513463c17c6dadefd05dbb065937872021-04-15 17:59:431 min ago0x84f3872705c91e5e272875be0e2749be7e705c11 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000948365
0xeac17f2e5a2c5825469567853b9308e271bc0649f29f6b39a6411b07b42b2b5c65937852021-04-15 17:59:371 min ago0x7428a136a88711b076da35b6fc2991d82959ed5e IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000695245
0xea8368aa72351ab6a4450596bb6a99e7e537be5e0b900b5857fdfb5a9f1793e965937762021-04-15 17:59:101 min ago0x9a7d98e0a7ae22889006c1d622d971c6ffa7ac75 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00063775
0xbb58524d7e1975424c6365a06a097b24857ee2b0f2d38612f416bb932d08ca3665937762021-04-15 17:59:101 min ago0xf19f4c6427b154f766f114b45fd2e3b461e06764 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.2429839 BNB0.000895585
0xd94ba891000e6b766fce104e9cc0d8a9db26d8babfb5273ba638d8bafc2cd50665937722021-04-15 17:58:581 min ago0xf19f4c6427b154f766f114b45fd2e3b461e06764 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000773095
0xc250e4a3dace5ed3cf8cb02d4ded80e7ebc418c7eec58d9d14c0a88b808b393165937672021-04-15 17:58:432 mins ago0x72ac0dac4784d1b0f6f15ceb4ee918c40aada55b IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.001647205
0xc1ee9879f3dffdefc0277ccc78ac9ab8bf252ad3b22c1e727b8a156abff9acf865937602021-04-15 17:58:222 mins ago0xb69357a0358d46ed8fccce403313269d9e1173c5 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000948305
0xd4087b59a944e33f29b2a3df6570b7d362983e44a7ea6c869755541a6dc8902c65937592021-04-15 17:58:192 mins ago0x743409f937c02819ac689897833bd00e5fb559f7 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00064062
0x23f4bd5725d9a85565ae7e6d649830724c0221a57a8f3a2a8b6cf80762470ac665937532021-04-15 17:58:012 mins ago0x4869e35cd6802850c6984e25e516ee04e9a8a2be IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.001769295
0x01c9a091cc902aa016ff8413ff10158a218487ec3f7b6ed9976a70d51b313b2765937522021-04-15 17:57:582 mins ago0x80f900994d69b9012ce551543d26ebb5a8add14c IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.085921715431536 BNB0.000800835
0x811a38cbe36296912112ee35f686fb4c5744b50821e94f7e5e155f3b3af3f00265937522021-04-15 17:57:582 mins ago0x0814e01f9832c6bdc6603002b180e8ea984feab7 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00113571
0x2ef151c199fc37a19cbff081a6894da709ec7ab1e09dd4c8a390fe8e8e591c0b65937482021-04-15 17:57:463 mins ago0xadf2122d590b3a2f449035f2f573685c66dd46bb IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000992355
0x5f27f0ff4ca3f63792ddf7a7b7234b38e97190b86d9c611201364085f77693d265937412021-04-15 17:57:253 mins ago0x4d655e3e4e63208dd1021a03af617db0284d79f6 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00054675
0xd550e1b2f659874edc4ccce5e6a69421e8498d6e38a46d9e5f74c25284b1a02365937402021-04-15 17:57:223 mins ago0x743409f937c02819ac689897833bd00e5fb559f7 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.00064062
0x0704719a2397e78963f735e0ce2e8101bd014d7ad6448028b05ed55cacaec8e365937392021-04-15 17:57:193 mins ago0xee7f31a28e3e776219c81e12382384cbe55e07f3 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000976355
0xf8bc9b86cf988747d149b0b893b91a6982b846aa4ba3a92b957bf3aa286c709165937372021-04-15 17:57:133 mins ago0x6e873918cfecc6156806753dedef212dcb3f5b0d IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0 BNB0.000948245
0x6dde4c2d72cada7dd8f48e1738f8810773298c44a6d27a70aea658cd3d593dfc65937342021-04-15 17:57:043 mins ago0x1466c2869278e7b1daca2ee60dd62af3f5fba605 IN  0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.099710991072371 BNB0.00092041
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xb6f0d76aa77c128ea22a6a913894553e882c114c0e534b9b853aba9eb32e504e65938042021-04-15 18:00:3421 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x111fa0293c78ea77c6250d38f4ac447e196358dd0.006412998750881885 BNB
0xb6f0d76aa77c128ea22a6a913894553e882c114c0e534b9b853aba9eb32e504e65938042021-04-15 18:00:3421 secs ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.006412998750881885 BNB
0x28c5607e0572e20cf012ef5cf2c6184474975bf7408874cc9fd1bf5b560a966a65938042021-04-15 18:00:3421 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x321aee90cbbe22325658f83fad136dc0b49204920.140761495562812138 BNB
0x28c5607e0572e20cf012ef5cf2c6184474975bf7408874cc9fd1bf5b560a966a65938042021-04-15 18:00:3421 secs ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.140761495562812138 BNB
0x61f10953d110ae4d4d6a548961a0ee91daaeaa1acbf9d7efe64240147595fe5f65937972021-04-15 18:00:1342 secs ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c 0x1d954998067db0074e810a85fd43e4e44a65515387.56113621288378326 BNB
0x61f10953d110ae4d4d6a548961a0ee91daaeaa1acbf9d7efe64240147595fe5f65937972021-04-15 18:00:1342 secs ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c87.56113621288378326 BNB
0xeac17f2e5a2c5825469567853b9308e271bc0649f29f6b39a6411b07b42b2b5c65937852021-04-15 17:59:371 min ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x7428a136a88711b076da35b6fc2991d82959ed5e0.053740782872211282 BNB
0xeac17f2e5a2c5825469567853b9308e271bc0649f29f6b39a6411b07b42b2b5c65937852021-04-15 17:59:371 min ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.053740782872211282 BNB
0xea8368aa72351ab6a4450596bb6a99e7e537be5e0b900b5857fdfb5a9f1793e965937762021-04-15 17:59:101 min ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x9a7d98e0a7ae22889006c1d622d971c6ffa7ac750.001543439209948254 BNB
0xea8368aa72351ab6a4450596bb6a99e7e537be5e0b900b5857fdfb5a9f1793e965937762021-04-15 17:59:101 min ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.001543439209948254 BNB
0xbb58524d7e1975424c6365a06a097b24857ee2b0f2d38612f416bb932d08ca3665937762021-04-15 17:59:101 min ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0xf19f4c6427b154f766f114b45fd2e3b461e067640.000000007683484264 BNB
0xbb58524d7e1975424c6365a06a097b24857ee2b0f2d38612f416bb932d08ca3665937762021-04-15 17:59:101 min ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.242983892316515736 BNB
0xd94ba891000e6b766fce104e9cc0d8a9db26d8babfb5273ba638d8bafc2cd50665937722021-04-15 17:58:581 min ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0xf19f4c6427b154f766f114b45fd2e3b461e067640.241072253523680388 BNB
0xd94ba891000e6b766fce104e9cc0d8a9db26d8babfb5273ba638d8bafc2cd50665937722021-04-15 17:58:581 min ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.241072253523680388 BNB
0xc250e4a3dace5ed3cf8cb02d4ded80e7ebc418c7eec58d9d14c0a88b808b393165937672021-04-15 17:58:432 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x72ac0dac4784d1b0f6f15ceb4ee918c40aada55b0.231909118946930907 BNB
0xc250e4a3dace5ed3cf8cb02d4ded80e7ebc418c7eec58d9d14c0a88b808b393165937672021-04-15 17:58:432 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.231909118946930907 BNB
0x01c9a091cc902aa016ff8413ff10158a218487ec3f7b6ed9976a70d51b313b2765937522021-04-15 17:57:582 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.085921715431536208 BNB
0x6dde4c2d72cada7dd8f48e1738f8810773298c44a6d27a70aea658cd3d593dfc65937342021-04-15 17:57:043 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.099710991072371369 BNB
0xb5b6e641387c170dba75397f3e6d56702dcc4a19f94e51bd22d79c6fa4ca627665937232021-04-15 17:56:314 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.1 BNB
0xa1e5c9493ccb56a3017145db3349c7aa1e8bb22546396705015b0c48e28aa58765937052021-04-15 17:55:375 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0x5c6de252152a17becdc89277791a472fd8a5bc940.010312849808084699 BNB
0xa1e5c9493ccb56a3017145db3349c7aa1e8bb22546396705015b0c48e28aa58765937052021-04-15 17:55:375 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0.010312849808084699 BNB
0x6a5f70838692d08aea8b28e415fe7541cea1bc256883cbe0cadf637f4252412365937042021-04-15 17:55:345 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0xe23fc0f0b28f5b5fe068490e9e469575517f93961.996296321643423557 BNB
0x6a5f70838692d08aea8b28e415fe7541cea1bc256883cbe0cadf637f4252412365937042021-04-15 17:55:345 mins ago Binance: WBNB Token 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c1.996296321643423557 BNB
0xbbbbaecd1558664aa6b84b041547025dc945ca3dc9fa7ef1e4ce3639838366db65936982021-04-15 17:55:165 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c Binance: WBNB Token0.299282466984004475 BNB
0xdd2da0bb7cfbb57c0127fde291b08cedec08ee86060d0a1041abc8c6aaa6cb9265936922021-04-15 17:54:585 mins ago 0xb7e19a1188776f32e8c2b790d9ca578f2896da7c0xe23fc0f0b28f5b5fe068490e9e469575517f93960.829741084412472149 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.