ETH Price: $3,086.45 (+0.81%)
Gas: 6 Gwei

Contract

0xeFa14C326424F82503F3120d16898d3084e90942
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
0xc0d9a13883891e1ffdf31046cb9df234ec3381882789a9af1b53cedff57d8789 Multihop Batch S...(pending)2024-07-07 1:29:503 days ago1720315790IN
0xeFa14C32...084e90942
0.000668582 ETH(Pending)(Pending)
Swap Exact Token...183402502023-10-13 8:22:23271 days ago1697185343IN
0xeFa14C32...084e90942
0 ETH0.000263335.49680383
Swap Exact Token...177885542023-07-28 2:24:35348 days ago1690511075IN
0xeFa14C32...084e90942
0 ETH0.0021633415.88570571
Swap Exact Token...174887892023-06-16 0:17:59390 days ago1686874679IN
0xeFa14C32...084e90942
0 ETH0.001739814.60718743
Swap Exact Token...168807222023-03-22 4:21:11476 days ago1679458871IN
0xeFa14C32...084e90942
0 ETH0.0016166213.57576532
Swap Exact Token...168806952023-03-22 4:15:47476 days ago1679458547IN
0xeFa14C32...084e90942
0 ETH0.0014972112.08582312
Swap Exact Token...164911732023-01-26 13:05:11530 days ago1674738311IN
0xeFa14C32...084e90942
0 ETH0.0016671414
Swap Exact Token...163181522023-01-02 9:19:59554 days ago1672651199IN
0xeFa14C32...084e90942
0 ETH0.0015480613
Swap Exact Token...162092852022-12-18 4:47:59570 days ago1671338879IN
0xeFa14C32...084e90942
0 ETH0.001519312.75718915
Swap Exact Token...160375622022-11-24 4:50:11594 days ago1669265411IN
0xeFa14C32...084e90942
0 ETH0.00129810.89897058
Swap Tokens For ...140213962022-01-17 6:27:04905 days ago1642400824IN
0xeFa14C32...084e90942
0 ETH0.0176113293.30157365
Multihop Batch S...139649622022-01-08 13:15:05913 days ago1641647705IN
0xeFa14C32...084e90942
0 ETH0.0203081175.45529685
Swap Tokens For ...139567832022-01-07 6:49:38915 days ago1641538178IN
0xeFa14C32...084e90942
0 ETH0.02460308119.51541074
Swap Tokens For ...138345102021-12-19 8:37:38934 days ago1639903058IN
0xeFa14C32...084e90942
0 ETH0.0080493741.18570745
Multihop Batch S...138164522021-12-16 13:30:03936 days ago1639661403IN
0xeFa14C32...084e90942
0 ETH0.0232986690
Multihop Batch S...138064302021-12-15 0:09:06938 days ago1639526946IN
0xeFa14C32...084e90942
0.1 ETH0.03175872121.9
Multihop Batch S...134939322021-10-26 15:59:49987 days ago1635263989IN
0xeFa14C32...084e90942
0.23660638 ETH0.05904135125.68381299
Multihop Batch S...134935222021-10-26 14:26:57987 days ago1635258417IN
0xeFa14C32...084e90942
0.1 ETH0.02711746115
Multihop Batch S...134929792021-10-26 12:20:39987 days ago1635250839IN
0xeFa14C32...084e90942
0.11419042 ETH0.0254846883.92063578
Multihop Batch S...134654442021-10-22 4:51:45992 days ago1634878305IN
0xeFa14C32...084e90942
0 ETH0.0163358259.19399145
Multihop Batch S...134654442021-10-22 4:51:45992 days ago1634878305IN
0xeFa14C32...084e90942
0 ETH0.0024094959.19399145
Multihop Batch S...134653692021-10-22 4:36:38992 days ago1634877398IN
0xeFa14C32...084e90942
0 ETH0.0223216962.85287068
Multihop Batch S...133573882021-10-05 6:19:041009 days ago1633414744IN
0xeFa14C32...084e90942
0 ETH0.0190920469.22447965
Swap ETH For Exa...133573502021-10-05 6:10:051009 days ago1633414205IN
0xeFa14C32...084e90942
0.26087811 ETH0.0080494958.35420727
Swap Exact Token...133361342021-10-01 22:27:001012 days ago1633127220IN
0xeFa14C32...084e90942
0 ETH0.0184623292.11631463
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
139649622022-01-08 13:15:05913 days ago1641647705
0xeFa14C32...084e90942
0.03096563 ETH
139649622022-01-08 13:15:05913 days ago1641647705
0xeFa14C32...084e90942
0.03096563 ETH
138064302021-12-15 0:09:06938 days ago1639526946
0xeFa14C32...084e90942
0.1 ETH
134939322021-10-26 15:59:49987 days ago1635263989
0xeFa14C32...084e90942
0.00029665 ETH
134939322021-10-26 15:59:49987 days ago1635263989
0xeFa14C32...084e90942
0.00029665 ETH
134939322021-10-26 15:59:49987 days ago1635263989
0xeFa14C32...084e90942
0.23660638 ETH
134935222021-10-26 14:26:57987 days ago1635258417
0xeFa14C32...084e90942
0.1 ETH
134929792021-10-26 12:20:39987 days ago1635250839
0xeFa14C32...084e90942
0.00036328 ETH
134929792021-10-26 12:20:39987 days ago1635250839
0xeFa14C32...084e90942
0.00036328 ETH
134929792021-10-26 12:20:39987 days ago1635250839
0xeFa14C32...084e90942
0.11419042 ETH
133573882021-10-05 6:19:041009 days ago1633414744
0xeFa14C32...084e90942
0.3017956 ETH
133573882021-10-05 6:19:041009 days ago1633414744
0xeFa14C32...084e90942
0.3017956 ETH
133573502021-10-05 6:10:051009 days ago1633414205
0xeFa14C32...084e90942
0.26087811 ETH
133336762021-10-01 13:18:111012 days ago1633094291
0xeFa14C32...084e90942
0.0982858 ETH
133336762021-10-01 13:18:111012 days ago1633094291
0xeFa14C32...084e90942
0.0982858 ETH
133336652021-10-01 13:16:151012 days ago1633094175
0xeFa14C32...084e90942
0.75623421 ETH
133336652021-10-01 13:16:151012 days ago1633094175
0xeFa14C32...084e90942
0.75623421 ETH
133191392021-09-29 6:37:381015 days ago1632897458
0xeFa14C32...084e90942
0.32045582 ETH
133191392021-09-29 6:37:381015 days ago1632897458
0xeFa14C32...084e90942
0.32045582 ETH
133014862021-09-26 12:54:101017 days ago1632660850
0xeFa14C32...084e90942
0.38300232 ETH
133014862021-09-26 12:54:101017 days ago1632660850
0xeFa14C32...084e90942
0.38300232 ETH
133002482021-09-26 8:04:021018 days ago1632643442
0xeFa14C32...084e90942
0.39953968 ETH
133002482021-09-26 8:04:021018 days ago1632643442
0xeFa14C32...084e90942
0.39953968 ETH
132948002021-09-25 11:52:271018 days ago1632570747
0xeFa14C32...084e90942
0.44217188 ETH
132948002021-09-25 11:52:271018 days ago1632570747
0xeFa14C32...084e90942
0.44217188 ETH
View All Internal Transactions
Loading...
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 Etherscan.io on 2021-01-20
*/

// 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;
}

interface IStakePool {
    event Deposit(address indexed account, uint256 amount);
    event AddRewardPool(uint256 indexed poolId);
    event UpdateRewardPool(uint256 indexed poolId, uint256 endRewardBlock, uint256 rewardPerBlock);
    event PayRewardPool(
        uint256 indexed poolId,
        address indexed rewardToken,
        address indexed account,
        uint256 pendingReward,
        uint256 rebaseAmount,
        uint256 paidReward
    );
    event UpdateRewardRebaser(uint256 indexed poolId, address rewardRebaser);
    event UpdateRewardMultiplier(uint256 indexed poolId, address rewardMultiplier);
    event Withdraw(address indexed account, uint256 amount);

    function version() external returns (uint256);

    function pair() external returns (address);

    function initialize(
        address _pair,
        uint256 _unstakingFrozenTime,
        address _rewardFund,
        address _timelock
    ) external;

    function stake(uint256) external;

    function stakeFor(address _account) external;

    function withdraw(uint256) external;

    function getReward(uint8 _pid, address _account) external;

    function getAllRewards(address _account) external;

    function pendingReward(uint8 _pid, address _account) external view returns (uint256);

    function getEndRewardBlock(uint8 _pid) external view returns (address, uint256);

    function getRewardPerBlock(uint8 pid) external view returns (uint256);

    function rewardPoolInfoLength() external view returns (uint256);

    function unfrozenStakeTime(address _account) external view returns (uint256);

    function emergencyWithdraw() external;

    function updateReward() external;

    function updateReward(uint8 _pid) external;

    function updateRewardPool(
        uint8 _pid,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock
    ) external;

    function getRewardMultiplier(
        uint8 _pid,
        uint256 _from,
        uint256 _to,
        uint256 _rewardPerBlock
    ) external view returns (uint256);

    function getRewardRebase(
        uint8 _pid,
        address _rewardToken,
        uint256 _pendingReward
    ) external view returns (uint256);

    function updateRewardRebaser(uint8 _pid, address _rewardRebaser) external;

    function updateRewardMultiplier(uint8 _pid, address _rewardMultiplier) external;

    function getUserInfo(uint8 _pid, address _account)
        external
        view
        returns (
            uint256 amount,
            uint256 rewardDebt,
            uint256 accumulatedEarned,
            uint256 lockReward,
            uint256 lockRewardReleased
        );

    function addRewardPool(
        address _rewardToken,
        address _rewardRebaser,
        address _rewardMultiplier,
        uint256 _startBlock,
        uint256 _endRewardBlock,
        uint256 _rewardPerBlock,
        uint256 _lockRewardPercent,
        uint256 _startVestingBlock,
        uint256 _endVestingBlock
    ) external;

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

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

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

// 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 {
    struct Swap {
        address pool;
        address tokenIn;
        address tokenOut;
        uint256 swapAmount; // tokenInAmount / tokenOutAmount
        uint256 limitReturnAmount; // minAmountOut / maxAmountIn
        uint256 maxPrice;
        bool isBPool;
    }

    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,
        uint8 flag
    ) external returns (uint256[] memory amounts);

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

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

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

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

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

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

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

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

    function addStakeLiquidity(
        address stakePool,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addStakeLiquidityETH(
        address stakePool,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

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

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

// 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);
}

interface IFreeFromUpTo {
    function freeFromUpTo(address from, uint256 value) external returns (uint256 freed);
}

interface IStakePoolController {
    event MasterCreated(address indexed farm, address indexed pair, uint256 version, address timelock, address stakePoolRewardFund, uint256 totalStakePool);
    event SetWhitelistStakingFor(address indexed contractAddress, bool value);
    event SetWhitelistStakePool(address indexed contractAddress, int8 value);
    event SetStakePoolCreator(address indexed contractAddress, uint256 verion);
    event SetWhitelistRewardRebaser(address indexed contractAddress, bool value);
    event SetWhitelistRewardMultiplier(address indexed contractAddress, bool value);
    event SetStakePoolVerifier(address indexed contractAddress, bool value);
    event ChangeGovernance(address indexed governance);
    event SetFeeCollector(address indexed feeCollector);
    event SetFeeToken(address indexed token);
    event SetFeeAmount(uint256 indexed amount);

    struct PoolRewardInfo {
        address rewardToken;
        address rewardRebaser;
        address rewardMultiplier;
        uint256 startBlock;
        uint256 endRewardBlock;
        uint256 rewardPerBlock;
        uint256 lockRewardPercent;
        uint256 startVestingBlock;
        uint256 endVestingBlock;
        uint256 unstakingFrozenTime;
        uint256 rewardFundAmount;
    }

    function allStakePools(uint256) external view returns (address stakePool);

    function isStakePool(address contractAddress) external view returns (bool);

    function isStakePoolVerifier(address contractAddress) external view returns (bool);

    function isWhitelistStakingFor(address contractAddress) external view returns (bool);

    function isWhitelistStakePool(address contractAddress) external view returns (int8);

    function setStakePoolVerifier(address contractAddress, bool state) external;

    function setWhitelistStakingFor(address contractAddress, bool state) external;

    function setWhitelistStakePool(address contractAddress, int8 state) external;

    function addStakePoolCreator(address contractAddress) external;

    function isWhitelistRewardRebaser(address contractAddress) external view returns (bool);

    function setWhitelistRewardRebaser(address contractAddress, bool state) external;

    function isWhitelistRewardMultiplier(address contractAddress) external view returns (bool);

    function setWhitelistRewardMultiplier(address contractAddress, bool state) external;

    function allStakePoolsLength() external view returns (uint256);

    function create(
        uint256 version,
        address pair,
        uint256 delayTimeLock,
        PoolRewardInfo calldata poolRewardInfo,
        uint8 flag
    ) external returns (address);

    function createPair(
        uint256 version,
        address tokenA,
        address tokenB,
        uint32 tokenWeightA,
        uint32 swapFee,
        uint256 delayTimeLock,
        PoolRewardInfo calldata poolRewardInfo,
        uint8 flag
    ) external returns (address);

    function setGovernance(address) external;

    function setFeeCollector(address _address) external;

    function setFeeToken(address _token) external;

    function setFeeAmount(uint256 _token) external;
}

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);

    IFreeFromUpTo public constant chi = IFreeFromUpTo(0x0000000000004946c0e9F43F4Dee607b0eF1fA1c);
    modifier ensure(uint256 deadline) {
        require(deadline >= block.timestamp, "Router: EXPIRED");
        _;
    }
    modifier discountCHI(uint8 flag) {
        uint256 gasStart = gasleft();
        _;
        if ((flag & 0x1) == 1) {
            uint256 gasSpent = 21000 + gasStart - gasleft() + 16 * msg.data.length;
            chi.freeFromUpTo(msg.sender, (gasSpent + 14154) / 41130);
        }
    }

    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 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 addStakeLiquidity(
        address stakePool,
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        uint256 deadline
    )
        external
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        )
    {
        require(IStakePoolController(controller).isStakePool(stakePool), "Router: Invalid stakePool");
        address pair = IStakePool(stakePool).pair();
        (amountA, amountB) = _addLiquidityToken(pair, tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        liquidity = IValueLiquidPair(pair).mint(stakePool);
        IStakePool(stakePool).stakeFor(msg.sender);
    }

    function addStakeLiquidityETH(
        address stakePool,
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        uint256 deadline
    )
        external
        payable
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        )
    {
        require(IStakePoolController(controller).isStakePool(stakePool), "Router: Invalid stakePool");
        (amountToken, amountETH, liquidity) = _addLiquidityETH(
            IStakePool(stakePool).pair(),
            token,
            amountTokenDesired,
            amountTokenMin,
            amountETHMin,
            stakePool
        );
        IStakePool(stakePool).stakeFor(msg.sender);
    }

    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 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));
            input = output;
        }
    }

    function swapExactTokensForTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] memory path,
        address to,
        uint256 deadline,
        uint8 flag
    ) public virtual override discountCHI(flag) ensure(deadline) returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsOut(factory, tokenIn, tokenOut, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");

        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,
        uint8 flag
    ) external virtual override discountCHI(flag) ensure(deadline) returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, tokenIn, tokenOut, amountOut, path);
        require(amounts[0] <= amountInMax, "Router: EXCESSIVE_INPUT_AMOUNT");
        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,
        uint8 flag
    ) external payable virtual override discountCHI(flag) ensure(deadline) returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsOut(factory, WETH, tokenOut, msg.value, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        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,
        uint8 flag
    ) external virtual override discountCHI(flag) ensure(deadline) returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, tokenIn, WETH, amountOut, path);
        require(amounts[0] <= amountInMax, "Router: EXCESSIVE_INPUT_AMOUNT");
        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,
        uint8 flag
    ) external virtual override discountCHI(flag) ensure(deadline) returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsOut(factory, tokenIn, WETH, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        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,
        uint8 flag
    ) external payable virtual override discountCHI(flag) ensure(deadline) returns (uint256[] memory amounts) {
        amounts = IValueLiquidFormula(formula).getFactoryAmountsIn(factory, WETH, tokenOut, amountOut, path);
        require(amounts[0] <= msg.value, "Router: EXCESSIVE_INPUT_AMOUNT");
        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));
            input = currentOutput;
        }
    }

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline,
        uint8 flag
    ) external virtual override discountCHI(flag) 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,
        uint8 flag
    ) external payable virtual override discountCHI(flag) ensure(deadline) {
        //            require(path[0] == WETH, 'Router: INVALID_PATH');
        uint256 amountIn = msg.value;
        IWETH(WETH).deposit{value: amountIn}();
        assert(IWETH(WETH).transfer(path[0], amountIn));
        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,
        uint8 flag
    ) external virtual override discountCHI(flag) 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,
        uint8 flag
    ) public payable virtual override discountCHI(flag) 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;
                }

                if (swap.isBPool) {
                    TransferHelper.safeApprove(swap.tokenIn, swap.pool, swap.swapAmount);

                    (tokenAmountOut, ) = IBPool(swap.pool).swapExactAmountIn(
                        swap.tokenIn,
                        swap.swapAmount,
                        swap.tokenOut,
                        swap.limitReturnAmount,
                        swap.maxPrice
                    );
                } else {
                    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,
        uint8 flag
    ) public payable virtual override discountCHI(flag) 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,
                    swap.isBPool
                );
            } 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];
                if (secondSwap.isBPool) {
                    IBPool poolSecondSwap = IBPool(secondSwap.pool);
                    intermediateTokenAmount = poolSecondSwap.calcInGivenOut(
                        poolSecondSwap.getBalance(secondSwap.tokenIn),
                        poolSecondSwap.getDenormalizedWeight(secondSwap.tokenIn),
                        poolSecondSwap.getBalance(secondSwap.tokenOut),
                        poolSecondSwap.getDenormalizedWeight(secondSwap.tokenOut),
                        secondSwap.swapAmount,
                        poolSecondSwap.swapFee()
                    );
                } else {
                    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,
                    firstSwap.isBPool
                );

                //// Buy the final amount of token C desired
                if (secondSwap.isBPool) {
                    _swapPBoolOut(
                        secondSwap.tokenIn,
                        secondSwap.tokenOut,
                        secondSwap.pool,
                        secondSwap.swapAmount,
                        secondSwap.limitReturnAmount,
                        secondSwap.maxPrice
                    );
                } else {
                    _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 maxPrice,
        bool isBPool
    ) internal returns (uint256 tokenAmountIn) {
        if (isBPool) {
            return _swapPBoolOut(tokenIn, tokenOut, pool, swapAmount, limitReturnAmount, maxPrice);
        } else {
            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 _swapPBoolOut(
        address tokenIn,
        address tokenOut,
        address pool,
        uint256 swapAmount,
        uint256 limitReturnAmount,
        uint256 maxPrice
    ) internal returns (uint256 tokenAmountIn) {
        TransferHelper.safeApprove(tokenIn, pool, limitReturnAmount);

        (tokenAmountIn, ) = IBPool(pool).swapExactAmountOut(tokenIn, limitReturnAmount, tokenOut, swapAmount, maxPrice);
    }

    function _swapSingle(
        address tokenIn,
        address pair,
        uint256 targetSwapAmount,
        uint256 targetOutAmount
    ) internal {
        TransferHelper.safeTransfer(tokenIn, pair, targetSwapAmount);
        (uint256 amount0Out, uint256 amount1Out) = tokenIn == IValueLiquidPair(pair).token0() ? (uint256(0), targetOutAmount) : (targetOutAmount, uint256(0));

        IValueLiquidPair(pair).swap(amount0Out, amount1Out, address(this), new bytes(0));
    }

    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));

        tokenAmountOut = IERC20(tokenOut).balanceOf(address(this)).sub(balanceBefore);
        require(tokenAmountOut >= limitReturnAmount, "Router: INSUFFICIENT_OUTPUT_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);
    }
}

Contract Security Audit

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"},{"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":[{"internalType":"address","name":"stakePool","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":"uint256","name":"deadline","type":"uint256"}],"name":"addStakeLiquidity","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":"stakePool","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":"uint256","name":"deadline","type":"uint256"}],"name":"addStakeLiquidityETH","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":"chi","outputs":[{"internalType":"contract IFreeFromUpTo","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"bool","name":"isBPool","type":"bool"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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":"bool","name":"isBPool","type":"bool"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"name":"multihopBatchSwapExactOut","outputs":[{"internalType":"uint256","name":"totalAmountIn","type":"uint256"}],"stateMutability":"payable","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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"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"},{"internalType":"uint8","name":"flag","type":"uint8"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101006040523480156200001257600080fd5b50604051620060293803806200602983398101604081905262000035916200012f565b6001600160601b0319606084811b821660805283901b1660a05260408051634b75f54f60e01b815290516001600160a01b03851691634b75f54f916004808301926020929190829003018186803b1580156200009057600080fd5b505afa158015620000a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000cb91906200010b565b6001600160601b0319606091821b811660c05291901b1660e05250620001789050565b80516001600160a01b03811681146200010657600080fd5b919050565b6000602082840312156200011d578081fd5b6200012882620000ee565b9392505050565b60008060006060848603121562000144578182fd5b6200014f84620000ee565b92506200015f60208501620000ee565b91506200016f60408501620000ee565b90509250925092565b60805160601c60a05160601c60c05160601c60e05160601c615d8e6200029b60003980610180528061068a528061070b52806108895280610b725280611147528061148052806115cd52806119125280611d925280612221528061233c5280612ff2528061368b52806139b85280613a715280613b195280614203525080610d8d52806110e9528061142352806117435280611d345280611f1252806121c452806128f2528061313052806132845280613d1f5280613e745280614435528061488f528061499b5280614ab25250806104615280610e2c5280612eba525080611125528061145f528061177f5280611d705280611e995280611f4e5280612200528061292e528061316c5280613d5b528061446252806147ad5250615d8e6000f3fe6080604052600436106101635760003560e01c8063c0b2b9bc116100c0578063e0ea880511610074578063f7639be311610059578063f7639be314610386578063f77c4791146103a6578063fbf45135146103bb576101a9565b8063e0ea880514610360578063e78d866d14610373576101a9565b8063c45a0155116100a5578063c45a015514610316578063c92aecc41461032b578063df10967014610340576101a9565b8063c0b2b9bc146102d6578063c1f25c61146102f6576101a9565b80634e01dbf0116101175780639aef6d5b116100fc5780639aef6d5b1461028e5780639d5f8665146102a1578063ad5c4648146102c1576101a9565b80634e01dbf0146102415780637beffcf514610261576101a9565b806333fe77511161014857806333fe7751146101ec5780633990ba541461020c5780634b75f54f1461021f576101a9565b806317529294146101ae578063225c823d146101d9576101a9565b366101a9573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101a757fe5b005b600080fd5b6101c16101bc3660046151da565b6103db565b6040516101d093929190615c41565b60405180910390f35b6101a76101e7366004615232565b610642565b3480156101f857600080fd5b506101a76102073660046152bc565b610a85565b6101c161021a366004615169565b610d29565b34801561022b57600080fd5b50610234610d8b565b6040516101d091906155e0565b34801561024d57600080fd5b506101c161025c366004614f4c565b610daf565b34801561026d57600080fd5b5061028161027c3660046152bc565b6110a4565b6040516101d091906157cd565b61028161029c366004615232565b6113de565b3480156102ad57600080fd5b506102816102bc366004615068565b6116fe565b3480156102cd57600080fd5b50610234611910565b6102e96102e43660046153a8565b611934565b6040516101d09190615bf3565b34801561030257600080fd5b506102816103113660046152bc565b611cef565b34801561032257600080fd5b50610234611e97565b34801561033757600080fd5b50610234611ebb565b34801561034c57600080fd5b5061028161035b366004614fc2565b611ecd565b61028161036e366004615232565b61217f565b6102e9610381366004615428565b6123d3565b34801561039257600080fd5b506101a76103a1366004614fc2565b612c33565b3480156103b257600080fd5b50610234612eb8565b3480156103c757600080fd5b506101c16103d6366004614ebe565b612edc565b60008060008342811015610424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b60405180910390fd5b6040517f1047a85700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690631047a85790610496908d906004016155e0565b60206040518083038186803b1580156104ae57600080fd5b505afa1580156104c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e69190615523565b61051c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615b28565b6105a98a73ffffffffffffffffffffffffffffffffffffffff1663a8aa1b316040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561056757600080fd5b505af115801561057b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059f9190614ea2565b8a8a8a8a8f612fe6565b6040517f4bf69206000000000000000000000000000000000000000000000000000000008152929650909450925073ffffffffffffffffffffffffffffffffffffffff8b1690634bf69206906106039033906004016155e0565b600060405180830381600087803b15801561061d57600080fd5b505af1158015610631573d6000803e3d6000fd5b505050505096509650969350505050565b8060005a90508342811015610683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b60003490507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156106f057600080fd5b505af1158015610704573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8a8a600081811061075257fe5b90506020020160208101906107679190614e86565b836040518363ffffffff1660e01b8152600401610785929190615601565b602060405180830381600087803b15801561079f57600080fd5b505af11580156107b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d79190615523565b6107dd57fe5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8d16906370a0823190610832908b906004016155e0565b60206040518083038186803b15801561084a57600080fd5b505afa15801561085e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610882919061553f565b90506108e37f00000000000000000000000000000000000000000000000000000000000000008b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d92506130fb915050565b8a610977828e73ffffffffffffffffffffffffffffffffffffffff166370a082318c6040518263ffffffff1660e01b815260040161092191906155e0565b60206040518083038186803b15801561093957600080fd5b505afa15801561094d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610971919061553f565b906134c2565b10156109af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b50505060018083161415610a7a576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181610a0757fe5b046040518363ffffffff1660e01b8152600401610a25929190615601565b602060405180830381600087803b158015610a3f57600080fd5b505af1158015610a53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a77919061553f565b50505b505050505050505050565b8060005a90508342811015610ac6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b610af38b338a8a6000818110610ad857fe5b9050602002016020810190610aed9190614e86565b8d613505565b610b328b8989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152503092506130fb915050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610ba79030906004016155e0565b60206040518083038186803b158015610bbf57600080fd5b505afa158015610bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf7919061553f565b905089811015610c33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b610c5273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8883613631565b50505060018083161415610d1d576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181610caa57fe5b046040518363ffffffff1660e01b8152600401610cc8929190615601565b602060405180830381600087803b158015610ce257600080fd5b505af1158015610cf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1a919061553f565b50505b50505050505050505050565b60008060008342811015610d69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b610d778b8b8b8b8b8b612fe6565b919d909c50909a5098505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060008342811015610def576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b6040517f1047a85700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690631047a85790610e61908f906004016155e0565b60206040518083038186803b158015610e7957600080fd5b505afa158015610e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb19190615523565b610ee7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615b28565b60008c73ffffffffffffffffffffffffffffffffffffffff1663a8aa1b316040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610f3157600080fd5b505af1158015610f45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f699190614ea2565b9050610f7a818d8d8d8d8d8d613717565b80955081965050508073ffffffffffffffffffffffffffffffffffffffff16636a6278428e6040518263ffffffff1660e01b8152600401610fbb91906155e0565b602060405180830381600087803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d919061553f565b6040517f4bf6920600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8e1690634bf69206906110629033906004016155e0565b600060405180830381600087803b15801561107c57600080fd5b505af1158015611090573d6000803e3d6000fd5b505050505050985098509895505050505050565b60608160005a905084428110156110e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663119220a57f00000000000000000000000000000000000000000000000000000000000000008e7f00000000000000000000000000000000000000000000000000000000000000008f8e8e6040518763ffffffff1660e01b815260040161118a96959493929190615657565b60006040518083038186803b1580156111a257600080fd5b505afa1580156111b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111fc919081019061549f565b9350898460018651038151811061120f57fe5b6020026020010151101561124f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b6112908c338b8b600081811061126157fe5b90506020020160208101906112769190614e86565b8760008151811061128357fe5b6020026020010151613505565b6112d08c858b8b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613752915050565b61130673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee88866001885103815181106112f957fe5b6020026020010151613631565b5050600180831614156113d0576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161135d57fe5b046040518363ffffffff1660e01b815260040161137b929190615601565b602060405180830381600087803b15801561139557600080fd5b505af11580156113a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cd919061553f565b50505b505098975050505050505050565b60608160005a90508442811015611421576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663119220a57f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008e348e8e6040518763ffffffff1660e01b81526004016114c496959493929190615657565b60006040518083038186803b1580156114dc57600080fd5b505afa1580156114f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611536919081019061549f565b9350898460018651038151811061154957fe5b60200260200101511015611589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b6115c88460008151811061159957fe5b60200260200101518a8a60008181106115ae57fe5b90506020020160208101906115c39190614e86565b6139b6565b6116287f0000000000000000000000000000000000000000000000000000000000000000858b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d9250613752915050565b50600180831614156116f1576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161167e57fe5b046040518363ffffffff1660e01b815260040161169c929190615601565b602060405180830381600087803b1580156116b657600080fd5b505af11580156116ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ee919061553f565b50505b5050979650505050505050565b60608160005a90508442811015611741576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663119220a57f00000000000000000000000000000000000000000000000000000000000000008e8e8e8d6040518663ffffffff1660e01b81526004016117c29594939291906156db565b60006040518083038186803b1580156117da57600080fd5b505afa1580156117ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611834919081019061549f565b9350888460018651038151811061184757fe5b60200260200101511015611887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b6118ae8c338a60008151811061189957fe5b60200260200101518760008151811061128357fe5b6118ba8c858a8a613752565b50600180831614156113d0576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161135d57fe5b7f000000000000000000000000000000000000000000000000000000000000000081565b60008160005a90508442811015611977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b6119818a89613b07565b50600061198d8a613bb2565b611a36576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b16906370a08231906119e39033906004016155e0565b60206040518083038186803b1580156119fb57600080fd5b505afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a33919061553f565b90505b60005b8c51811015611bb4576000805b8e8381518110611a5257fe5b602002602001015151811015611b9e5760008f8481518110611a7057fe5b60200260200101518281518110611a8357fe5b602002602001015190508160011415611a9e57606081018390525b8060c0015115611b7157611abf816020015182600001518360600151613be5565b806000015173ffffffffffffffffffffffffffffffffffffffff16638201aa3f82602001518360600151846040015185608001518660a001516040518663ffffffff1660e01b8152600401611b1895949392919061578c565b6040805180830381600087803b158015611b3157600080fd5b505af1158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190615557565b509250611b95565b611b9281602001518260400151836000015184606001518560800151613d07565b92505b50600101611a46565b50611ba98188614179565b965050600101611a39565b50611bc08a3387613631565b50611bd48b33611bcf8e6141b6565b613631565b50611bde8a613bb2565b15611c225787851015611c1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906159c9565b611c98565b87611c60828c73ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161092191906155e0565b1015611c98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b9061587f565b5050600180831614156116f1576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161167e57fe5b60608160005a90508442811015611d32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166367f84adc7f00000000000000000000000000000000000000000000000000000000000000008e7f00000000000000000000000000000000000000000000000000000000000000008f8e8e6040518763ffffffff1660e01b8152600401611dd596959493929190615657565b60006040518083038186803b158015611ded57600080fd5b505afa158015611e01573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e47919081019061549f565b93508984600081518110611e5757fe5b6020026020010151111561124f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b7f000000000000000000000000000000000000000000000000000000000000000081565b6d4946c0e9f43f4dee607b0ef1fa1c81565b60608160005a90508442811015611f10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166367f84adc7f00000000000000000000000000000000000000000000000000000000000000008f8f8f8e8e6040518763ffffffff1660e01b8152600401611f9396959493929190615657565b60006040518083038186803b158015611fab57600080fd5b505afa158015611fbf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612005919081019061549f565b9350898460008151811061201557fe5b60200260200101511115612055576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b6120678d338b8b600081811061126157fe5b6120a78d858b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d9250613752915050565b5060018083161415612170576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a01816120fd57fe5b046040518363ffffffff1660e01b815260040161211b929190615601565b602060405180830381600087803b15801561213557600080fd5b505af1158015612149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216d919061553f565b50505b50509998505050505050505050565b60608160005a905084428110156121c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166367f84adc7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008e8e8e8e6040518763ffffffff1660e01b815260040161226596959493929190615657565b60006040518083038186803b15801561227d57600080fd5b505afa158015612291573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526122d7919081019061549f565b935034846000815181106122e757fe5b60200260200101511115612327576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b6123378460008151811061159957fe5b6123977f0000000000000000000000000000000000000000000000000000000000000000858b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d9250613752915050565b836000815181106123a457fe5b60200260200101513411156116285761162833856000815181106123c457fe5b602002602001015134036142e1565b60008160005a90508442811015612416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b6124208988613b07565b5060005b8a51811015612b055760008b828151811061243b57fe5b602002602001015151600114156124ab5760008c838151811061245a57fe5b602002602001015160008151811061246e57fe5b602002602001015190506124a3816020015182604001518360000151846060015185608001518660a001518760c0015161439a565b915050612af0565b6000808d84815181106124ba57fe5b60200260200101516001815181106124ce57fe5b602002602001015190508060c001511561288057805160208201516040517ff8b2cb4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169163f8d6aed491839163f8b2cb4f9161254291906004016155e0565b60206040518083038186803b15801561255a57600080fd5b505afa15801561256e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612592919061553f565b60208501516040517f948d8ce600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86169163948d8ce6916125e891906004016155e0565b60206040518083038186803b15801561260057600080fd5b505afa158015612614573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612638919061553f565b60408087015190517ff8b2cb4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87169163f8b2cb4f9161268e91906004016155e0565b60206040518083038186803b1580156126a657600080fd5b505afa1580156126ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126de919061553f565b60408088015190517f948d8ce600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88169163948d8ce69161273491906004016155e0565b60206040518083038186803b15801561274c57600080fd5b505afa158015612760573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612784919061553f565b87606001518773ffffffffffffffffffffffffffffffffffffffff166354cf2aeb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156127cf57600080fd5b505afa1580156127e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612807919061553f565b6040518763ffffffff1660e01b815260040161282896959493929190615c57565b60206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612878919061553f565b925050612a49565b604080516001808252818301909252600091602080830190803683370190505090508160000151816000815181106128b457fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166367f84adc7f0000000000000000000000000000000000000000000000000000000000000000856020015186604001518760600151876040518663ffffffff1660e01b815260040161297d9594939291906156db565b60006040518083038186803b15801561299557600080fd5b505afa1580156129a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526129ef919081019061549f565b9050806000815181106129fe57fe5b602002602001015193508260800151841115612a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b50505b60008e8581518110612a5757fe5b6020026020010151600081518110612a6b57fe5b60200260200101519050612a9c8160200151826040015183600001518685608001518660a001518760c0015161439a565b93508160c0015115612ad457612ace826020015183604001518460000151856060015186608001518760a00151614582565b50612aec565b612aec82602001518360000151858560600151614646565b5050505b612afa8187614179565b955050600101612424565b5086841115612b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a00565b612b4e8833611bcf8b6141b6565b50612b5d8933611bcf8c6141b6565b505060018083161415612c27576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181612bb457fe5b046040518363ffffffff1660e01b8152600401612bd2929190615601565b602060405180830381600087803b158015612bec57600080fd5b505af1158015612c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c24919061553f565b50505b50509695505050505050565b8060005a90508342811015612c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b612c868c338a8a6000818110610ad857fe5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8d16906370a0823190612cdb908a906004016155e0565b60206040518083038186803b158015612cf357600080fd5b505afa158015612d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2b919061553f565b9050612d6c8d8a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c92506130fb915050565b89612daa828e73ffffffffffffffffffffffffffffffffffffffff166370a082318b6040518263ffffffff1660e01b815260040161092191906155e0565b1015612de2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b505060018083161415610a77576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181612e3957fe5b046040518363ffffffff1660e01b8152600401612e57929190615601565b602060405180830381600087803b158015612e7157600080fd5b505af1158015612e85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ea9919061553f565b50505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060008342811015612f1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b612f2b8d8d8d8d8d8d8d613717565b6040517f6a627842000000000000000000000000000000000000000000000000000000008152919550935073ffffffffffffffffffffffffffffffffffffffff8e1690636a62784290612f829089906004016155e0565b602060405180830381600087803b158015612f9c57600080fd5b505af1158015612fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd4919061553f565b91505099509950999650505050505050565b600080600061301a89897f00000000000000000000000000000000000000000000000000000000000000008a348b8b6147a8565b909350915061302b88338b86613505565b613035828a6139b6565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a1690636a627842906130879087906004016155e0565b602060405180830381600087803b1580156130a157600080fd5b505af11580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d9919061553f565b9050813411156130ef576130ef338334036142e1565b96509650969350505050565b8260005b83518110156134bb57600084828151811061311657fe5b6020026020010151905060008060008060008060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f00000000000000000000000000000000000000000000000000000000000000008c8f6040518463ffffffff1660e01b81526004016131ab93929190615627565b60c06040518083038186803b1580156131c357600080fd5b505afa1580156131d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131fb9190615340565b955095509550955095509550613244858d73ffffffffffffffffffffffffffffffffffffffff166370a082318d6040518263ffffffff1660e01b815260040161092191906155e0565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290995073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063671a11b5906132c3908c9089908990899089908990600401615c7f565b60206040518083038186803b1580156132db57600080fd5b505afa1580156132ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613313919061553f565b97508596505050505050506000808573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561336757600080fd5b505afa15801561337b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061339f9190614ea2565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146133d9578360006133dd565b6000845b91509150600060018b510388106133f4578961340c565b8a886001018151811061340357fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f906134749086908690869060248101615bfc565b600060405180830381600087803b15801561348e57600080fd5b505af11580156134a2573d6000803e3d6000fd5b50959a5050600190980197506130ff9650505050505050565b5050505050565b808203828111156134ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615811565b92915050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016135399392919061575b565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161358791906155c4565b6000604051808303816000865af19150503d80600081146135c4576040519150601f19603f3d011682016040523d82523d6000602084013e6135c9565b606091505b50915091508180156135f35750805115806135f35750808060200190518101906135f39190615523565b613629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615b5f565b505050505050565b60008161364057506001613710565b61364984613bb2565b15613701576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632e1a7d4d906136c0908590600401615bf3565b600060405180830381600087803b1580156136da57600080fd5b505af11580156136ee573d6000803e3d6000fd5b505050506136fc83836142e1565b61370c565b61370c848484614b97565b5060015b9392505050565b600080613729898989898989896147a8565b909250905061373a88338b85613505565b61374687338b84613505565b97509795505050505050565b8360005b835181101561362957600084828151811061376d57fe5b6020026020010151905060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156137bf57600080fd5b505afa1580156137d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137f79190614ea2565b9050600087846001018151811061380a57fe5b6020026020010151905060008060008473ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461385557836000866138d6565b6000848773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561389e57600080fd5b505afa1580156138b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138d69190614ea2565b925092509250600060018b510388106138ef5789613907565b8a88600101815181106138fe57fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f9061396f9087908790869060248101615bfc565b600060405180830381600087803b15801561398957600080fd5b505af115801561399d573d6000803e3d6000fd5b50939a5050600190980197506137569650505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015613a1e57600080fd5b505af1158015613a32573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb9250613aab915084908690600401615601565b602060405180830381600087803b158015613ac557600080fd5b505af1158015613ad9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613afd9190615523565b613b0357fe5b5050565b6000613b1283613bb2565b15613b9d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015613b7f57600080fd5b505af1158015613b93573d6000803e3d6000fd5b5050505050613ba9565b613ba983333085613505565b50600192915050565b73ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b919050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663095ea7b38585604051602401613c17929190615601565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051613c6591906155c4565b6000604051808303816000865af19150503d8060008114613ca2576040519150601f19603f3d011682016040523d82523d6000602084013e613ca7565b606091505b5091509150818015613cd1575080511580613cd1575080806020019051810190613cd19190615523565b6134bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b9061595b565b6000613d14868585614b97565b6000806000806000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f00000000000000000000000000000000000000000000000000000000000000008c8f6040518463ffffffff1660e01b8152600401613d9a93929190615627565b60c06040518083038186803b158015613db257600080fd5b505afa158015613dc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dea9190615340565b95509550955095509550506000613e34868e73ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b815260040161092191906155e0565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063671a11b590613eb39084908a908a908a908a908a90600401615c7f565b60206040518083038186803b158015613ecb57600080fd5b505afa158015613edf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f03919061553f565b965050505050505060008673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401613f4691906155e0565b60206040518083038186803b158015613f5e57600080fd5b505afa158015613f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f96919061553f565b90506000808773ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015613fe157600080fd5b505afa158015613ff5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140199190614ea2565b73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161461405357836000614057565b6000845b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152919350915073ffffffffffffffffffffffffffffffffffffffff89169063022c0d9f906140c19085908590309060248101615bfc565b600060405180830381600087803b1580156140db57600080fd5b505af11580156140ef573d6000803e3d6000fd5b50505050614130838a73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161092191906155e0565b94508585101561416c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b5050505095945050505050565b808201828110156134ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615924565b60006141c182613bb2565b1561428f576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a08231906142389030906004016155e0565b60206040518083038186803b15801561425057600080fd5b505afa158015614264573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614288919061553f565b9050613be0565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906370a08231906142389030906004016155e0565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161431891906155c4565b60006040518083038185875af1925050503d8060008114614355576040519150601f19603f3d011682016040523d82523d6000602084013e61435a565b606091505b5050905080614395576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615acb565b505050565b600081156143b7576143b0888888888888614582565b9050614577565b6040805160018082528183019092526000916020808301908036833701905050905086816000815181106143e757fe5b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f67f84adc0000000000000000000000000000000000000000000000000000000081526000917f000000000000000000000000000000000000000000000000000000000000000016906367f84adc90614492907f0000000000000000000000000000000000000000000000000000000000000000908e908e908d9089906004016156db565b60006040518083038186803b1580156144aa57600080fd5b505afa1580156144be573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052614504919081019061549f565b90508060008151811061451357fe5b6020026020010151925085831115614557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b6116f18a89858460018151811061456a57fe5b6020026020010151614646565b979650505050505050565b600061458f878685613be5565b6040517f7c5e9ea400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861690637c5e9ea4906145e9908a9087908b908a90899060040161578c565b6040805180830381600087803b15801561460257600080fd5b505af1158015614616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061463a9190615557565b50979650505050505050565b614651848484614b97565b6000808473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561469a57600080fd5b505afa1580156146ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146d29190614ea2565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161461470c57826000614710565b6000835b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152919350915073ffffffffffffffffffffffffffffffffffffffff86169063022c0d9f9061477a9085908590309060248101615bfc565b600060405180830381600087803b15801561479457600080fd5b505af1158015610d1d573d6000803e3d6000fd5b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e5e31b138a6040518263ffffffff1660e01b815260040161480491906155e0565b60206040518083038186803b15801561481c57600080fd5b505afa158015614830573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148549190615523565b61488a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615bbc565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663327494618c8c8c6040518463ffffffff1660e01b81526004016148ea93929190615627565b604080518083038186803b15801561490157600080fd5b505afa158015614915573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149399190615557565b9150915081600014801561494b575080155b1561495b57879350869250614b89565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063ad615dec906149d4908c9087908790600401615c41565b60206040518083038186803b1580156149ec57600080fd5b505afa158015614a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a24919061553f565b9050878111614a725785811015614a67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158ed565b889450925082614b87565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063ad615dec90614aeb908c9087908990600401615c41565b60206040518083038186803b158015614b0357600080fd5b505afa158015614b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b3b919061553f565b905089811115614b4757fe5b87811015614b81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615992565b94508793505b505b505097509795505050505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401614bc9929190615601565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051614c1791906155c4565b6000604051808303816000865af19150503d8060008114614c54576040519150601f19603f3d011682016040523d82523d6000602084013e614c59565b606091505b5091509150818015614c83575080511580614c83575080806020019051810190614c839190615523565b6134bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615848565b8035613be081615d25565b60008083601f840112614cd5578182fd5b50813567ffffffffffffffff811115614cec578182fd5b6020830191508360208083028501011115614d0657600080fd5b9250929050565b600082601f830112614d1d578081fd5b81356020614d32614d2d83615cd7565b615cb3565b82815281810190858301855b85811015614e49578135880189603f820112614d58578788fd5b85810135614d68614d2d82615cd7565b808282528882019150604084018d604060e086028701011115614d89578b8cfd5b8b94505b83851015614e335760e0818f031215614da4578b8cfd5b60405160e0810181811067ffffffffffffffff82111715614dc157fe5b604052614dcd82614cb9565b8152614dda8b8301614cb9565b8b820152614dea60408301614cb9565b6040820152606082013560608201526080820135608082015260a082013560a0820152614e1960c08301614e56565b60c08201528352600194909401939189019160e001614d8d565b5087525050509284019290840190600101614d3e565b5090979650505050505050565b8035613be081615d4a565b805163ffffffff81168114613be057600080fd5b803560ff81168114613be057600080fd5b600060208284031215614e97578081fd5b813561371081615d25565b600060208284031215614eb3578081fd5b815161371081615d25565b60008060008060008060008060006101208a8c031215614edc578485fd5b8935614ee781615d25565b985060208a0135614ef781615d25565b975060408a0135614f0781615d25565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135614f3381615d25565b809250506101008a013590509295985092959850929598565b600080600080600080600080610100898b031215614f68578182fd5b8835614f7381615d25565b97506020890135614f8381615d25565b96506040890135614f9381615d25565b979a96995096976060810135975060808101359660a0820135965060c0820135955060e0909101359350915050565b60008060008060008060008060006101008a8c031215614fe0578283fd5b8935614feb81615d25565b985060208a0135614ffb81615d25565b975060408a0135965060608a0135955060808a013567ffffffffffffffff811115615024578384fd5b6150308c828d01614cc4565b90965094505060a08a013561504481615d25565b925060c08a0135915061505960e08b01614e75565b90509295985092959850929598565b600080600080600080600080610100898b031215615084578182fd5b883561508f81615d25565b97506020898101356150a081615d25565b975060408a0135965060608a0135955060808a013567ffffffffffffffff8111156150c9578384fd5b8a01601f81018c136150d9578384fd5b80356150e7614d2d82615cd7565b8082825284820191508484018f868786028701011115615105578788fd5b8794505b8385101561513057803561511c81615d25565b835260019490940193918501918501615109565b50809850505050505061514560a08a01614cb9565b925060c0890135915061515a60e08a01614e75565b90509295985092959890939650565b600080600080600080600060e0888a031215615183578081fd5b873561518e81615d25565b9650602088013561519e81615d25565b955060408801359450606088013593506080880135925060a08801356151c381615d25565b8092505060c0880135905092959891949750929550565b60008060008060008060c087890312156151f2578384fd5b86356151fd81615d25565b9550602087013561520d81615d25565b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600060c0888a03121561524c578081fd5b873561525781615d25565b965060208801359550604088013567ffffffffffffffff811115615279578182fd5b6152858a828b01614cc4565b909650945050606088013561529981615d25565b9250608088013591506152ae60a08901614e75565b905092959891949750929550565b60008060008060008060008060e0898b0312156152d7578182fd5b88356152e281615d25565b97506020890135965060408901359550606089013567ffffffffffffffff81111561530b578283fd5b6153178b828c01614cc4565b909650945050608089013561532b81615d25565b925060a0890135915061515a60c08a01614e75565b60008060008060008060c08789031215615358578384fd5b865161536381615d25565b602088015160408901519197509550935061538060608801614e61565b925061538e60808801614e61565b915061539c60a08801614e61565b90509295509295509295565b600080600080600080600060e0888a0312156153c2578081fd5b873567ffffffffffffffff8111156153d8578182fd5b6153e48a828b01614d0d565b97505060208801356153f581615d25565b9550604088013561540581615d25565b9450606088013593506080880135925060a088013591506152ae60c08901614e75565b60008060008060008060c08789031215615440578384fd5b863567ffffffffffffffff811115615456578485fd5b61546289828a01614d0d565b965050602087013561547381615d25565b9450604087013561548381615d25565b9350606087013592506080870135915061539c60a08801614e75565b600060208083850312156154b1578182fd5b825167ffffffffffffffff8111156154c7578283fd5b8301601f810185136154d7578283fd5b80516154e5614d2d82615cd7565b8181528381019083850185840285018601891015615501578687fd5b8694505b8385101561463a578051835260019490940193918501918501615505565b600060208284031215615534578081fd5b815161371081615d4a565b600060208284031215615550578081fd5b5051919050565b60008060408385031215615569578182fd5b505080516020909101519092909150565b60008151808452615592816020860160208601615cf5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516155d6818460208701615cf5565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b600060a0820173ffffffffffffffffffffffffffffffffffffffff808a1684526020818a1681860152818916604086015287606086015260a060808601528286845260c086019050879350845b878110156156cb5784356156b781615d25565b8416825293820193908201906001016156a4565b509b9a5050505050505050505050565b600060a0820173ffffffffffffffffffffffffffffffffffffffff8089168452602081891681860152818816604086015286606086015260a0608086015282865180855260c0870191508288019450855b8181101561574a57855185168352948301949183019160010161572c565b50909b9a5050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff958616815260208101949094529190931660408301526060820192909252608081019190915260a00190565b6020808252825182820181905260009190848201906040850190845b81811015615805578351835292840192918401916001016157e9565b50909695505050505050565b60208082526015908201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604082015260600190565b6020808252601f908201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604082015260600190565b60208082526012908201527f3c6d696e546f74616c416d6f756e744f75740000000000000000000000000000604082015260600190565b6020808252601e908201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604082015260600190565b60208082526014908201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604082015260600190565b6020808252601e908201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604082015260600190565b6020808252600d908201527f4552525f4c494d49545f4f555400000000000000000000000000000000000000604082015260600190565b6020808252600c908201527f4552525f4c494d49545f494e0000000000000000000000000000000000000000604082015260600190565b6020808252600f908201527f526f757465723a20455850495245440000000000000000000000000000000000604082015260600190565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560408201527f4e54000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201527f4c45440000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f526f757465723a20496e76616c6964207374616b65506f6f6c00000000000000604082015260600190565b60208082526024908201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160408201527f494c454400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526014908201527f526f757465723a20496e76616c69642070616972000000000000000000000000604082015260600190565b90815260200190565b600085825284602083015273ffffffffffffffffffffffffffffffffffffffff8416604083015260806060830152615c37608083018461557a565b9695505050505050565b9283526020830191909152604082015260600190565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b9586526020860194909452604085019290925263ffffffff908116606085015290811660808401521660a082015260c00190565b60405181810167ffffffffffffffff81118282101715615ccf57fe5b604052919050565b600067ffffffffffffffff821115615ceb57fe5b5060209081020190565b60005b83811015615d10578181015183820152602001615cf8565b83811115615d1f576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff81168114615d4757600080fd5b50565b8015158114615d4757600080fdfea264697066735822122063d97bcbfaaf0b3f28485c166961e5d48832981a9591fbce7cd716e6298301b364736f6c634300070600330000000000000000000000005021470fc598373fba4fe3384745940eab3e653d000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed Bytecode

0x6080604052600436106101635760003560e01c8063c0b2b9bc116100c0578063e0ea880511610074578063f7639be311610059578063f7639be314610386578063f77c4791146103a6578063fbf45135146103bb576101a9565b8063e0ea880514610360578063e78d866d14610373576101a9565b8063c45a0155116100a5578063c45a015514610316578063c92aecc41461032b578063df10967014610340576101a9565b8063c0b2b9bc146102d6578063c1f25c61146102f6576101a9565b80634e01dbf0116101175780639aef6d5b116100fc5780639aef6d5b1461028e5780639d5f8665146102a1578063ad5c4648146102c1576101a9565b80634e01dbf0146102415780637beffcf514610261576101a9565b806333fe77511161014857806333fe7751146101ec5780633990ba541461020c5780634b75f54f1461021f576101a9565b806317529294146101ae578063225c823d146101d9576101a9565b366101a9573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216146101a757fe5b005b600080fd5b6101c16101bc3660046151da565b6103db565b6040516101d093929190615c41565b60405180910390f35b6101a76101e7366004615232565b610642565b3480156101f857600080fd5b506101a76102073660046152bc565b610a85565b6101c161021a366004615169565b610d29565b34801561022b57600080fd5b50610234610d8b565b6040516101d091906155e0565b34801561024d57600080fd5b506101c161025c366004614f4c565b610daf565b34801561026d57600080fd5b5061028161027c3660046152bc565b6110a4565b6040516101d091906157cd565b61028161029c366004615232565b6113de565b3480156102ad57600080fd5b506102816102bc366004615068565b6116fe565b3480156102cd57600080fd5b50610234611910565b6102e96102e43660046153a8565b611934565b6040516101d09190615bf3565b34801561030257600080fd5b506102816103113660046152bc565b611cef565b34801561032257600080fd5b50610234611e97565b34801561033757600080fd5b50610234611ebb565b34801561034c57600080fd5b5061028161035b366004614fc2565b611ecd565b61028161036e366004615232565b61217f565b6102e9610381366004615428565b6123d3565b34801561039257600080fd5b506101a76103a1366004614fc2565b612c33565b3480156103b257600080fd5b50610234612eb8565b3480156103c757600080fd5b506101c16103d6366004614ebe565b612edc565b60008060008342811015610424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b60405180910390fd5b6040517f1047a85700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b1690631047a85790610496908d906004016155e0565b60206040518083038186803b1580156104ae57600080fd5b505afa1580156104c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e69190615523565b61051c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615b28565b6105a98a73ffffffffffffffffffffffffffffffffffffffff1663a8aa1b316040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561056757600080fd5b505af115801561057b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059f9190614ea2565b8a8a8a8a8f612fe6565b6040517f4bf69206000000000000000000000000000000000000000000000000000000008152929650909450925073ffffffffffffffffffffffffffffffffffffffff8b1690634bf69206906106039033906004016155e0565b600060405180830381600087803b15801561061d57600080fd5b505af1158015610631573d6000803e3d6000fd5b505050505096509650969350505050565b8060005a90508342811015610683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b60003490507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156106f057600080fd5b505af1158015610704573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8a8a600081811061075257fe5b90506020020160208101906107679190614e86565b836040518363ffffffff1660e01b8152600401610785929190615601565b602060405180830381600087803b15801561079f57600080fd5b505af11580156107b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d79190615523565b6107dd57fe5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8d16906370a0823190610832908b906004016155e0565b60206040518083038186803b15801561084a57600080fd5b505afa15801561085e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610882919061553f565b90506108e37f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d92506130fb915050565b8a610977828e73ffffffffffffffffffffffffffffffffffffffff166370a082318c6040518263ffffffff1660e01b815260040161092191906155e0565b60206040518083038186803b15801561093957600080fd5b505afa15801561094d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610971919061553f565b906134c2565b10156109af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b50505060018083161415610a7a576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181610a0757fe5b046040518363ffffffff1660e01b8152600401610a25929190615601565b602060405180830381600087803b158015610a3f57600080fd5b505af1158015610a53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a77919061553f565b50505b505050505050505050565b8060005a90508342811015610ac6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b610af38b338a8a6000818110610ad857fe5b9050602002016020810190610aed9190614e86565b8d613505565b610b328b8989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152503092506130fb915050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a0823190610ba79030906004016155e0565b60206040518083038186803b158015610bbf57600080fd5b505afa158015610bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf7919061553f565b905089811015610c33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b610c5273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8883613631565b50505060018083161415610d1d576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181610caa57fe5b046040518363ffffffff1660e01b8152600401610cc8929190615601565b602060405180830381600087803b158015610ce257600080fd5b505af1158015610cf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1a919061553f565b50505b50505050505050505050565b60008060008342811015610d69576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b610d778b8b8b8b8b8b612fe6565b919d909c50909a5098505050505050505050565b7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41581565b60008060008342811015610def576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b6040517f1047a85700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b1690631047a85790610e61908f906004016155e0565b60206040518083038186803b158015610e7957600080fd5b505afa158015610e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb19190615523565b610ee7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615b28565b60008c73ffffffffffffffffffffffffffffffffffffffff1663a8aa1b316040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610f3157600080fd5b505af1158015610f45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f699190614ea2565b9050610f7a818d8d8d8d8d8d613717565b80955081965050508073ffffffffffffffffffffffffffffffffffffffff16636a6278428e6040518263ffffffff1660e01b8152600401610fbb91906155e0565b602060405180830381600087803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061100d919061553f565b6040517f4bf6920600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8e1690634bf69206906110629033906004016155e0565b600060405180830381600087803b15801561107c57600080fd5b505af1158015611090573d6000803e3d6000fd5b505050505050985098509895505050505050565b60608160005a905084428110156110e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff1663119220a57f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d8e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28f8e8e6040518763ffffffff1660e01b815260040161118a96959493929190615657565b60006040518083038186803b1580156111a257600080fd5b505afa1580156111b6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111fc919081019061549f565b9350898460018651038151811061120f57fe5b6020026020010151101561124f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b6112908c338b8b600081811061126157fe5b90506020020160208101906112769190614e86565b8760008151811061128357fe5b6020026020010151613505565b6112d08c858b8b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613752915050565b61130673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee88866001885103815181106112f957fe5b6020026020010151613631565b5050600180831614156113d0576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161135d57fe5b046040518363ffffffff1660e01b815260040161137b929190615601565b602060405180830381600087803b15801561139557600080fd5b505af11580156113a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113cd919061553f565b50505b505098975050505050505050565b60608160005a90508442811015611421576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff1663119220a57f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28e348e8e6040518763ffffffff1660e01b81526004016114c496959493929190615657565b60006040518083038186803b1580156114dc57600080fd5b505afa1580156114f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611536919081019061549f565b9350898460018651038151811061154957fe5b60200260200101511015611589576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b6115c88460008151811061159957fe5b60200260200101518a8a60008181106115ae57fe5b90506020020160208101906115c39190614e86565b6139b6565b6116287f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2858b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d9250613752915050565b50600180831614156116f1576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161167e57fe5b046040518363ffffffff1660e01b815260040161169c929190615601565b602060405180830381600087803b1580156116b657600080fd5b505af11580156116ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ee919061553f565b50505b5050979650505050505050565b60608160005a90508442811015611741576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff1663119220a57f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d8e8e8e8d6040518663ffffffff1660e01b81526004016117c29594939291906156db565b60006040518083038186803b1580156117da57600080fd5b505afa1580156117ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611834919081019061549f565b9350888460018651038151811061184757fe5b60200260200101511015611887576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b6118ae8c338a60008151811061189957fe5b60200260200101518760008151811061128357fe5b6118ba8c858a8a613752565b50600180831614156113d0576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161135d57fe5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b60008160005a90508442811015611977576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b6119818a89613b07565b50600061198d8a613bb2565b611a36576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b16906370a08231906119e39033906004016155e0565b60206040518083038186803b1580156119fb57600080fd5b505afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a33919061553f565b90505b60005b8c51811015611bb4576000805b8e8381518110611a5257fe5b602002602001015151811015611b9e5760008f8481518110611a7057fe5b60200260200101518281518110611a8357fe5b602002602001015190508160011415611a9e57606081018390525b8060c0015115611b7157611abf816020015182600001518360600151613be5565b806000015173ffffffffffffffffffffffffffffffffffffffff16638201aa3f82602001518360600151846040015185608001518660a001516040518663ffffffff1660e01b8152600401611b1895949392919061578c565b6040805180830381600087803b158015611b3157600080fd5b505af1158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190615557565b509250611b95565b611b9281602001518260400151836000015184606001518560800151613d07565b92505b50600101611a46565b50611ba98188614179565b965050600101611a39565b50611bc08a3387613631565b50611bd48b33611bcf8e6141b6565b613631565b50611bde8a613bb2565b15611c225787851015611c1d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906159c9565b611c98565b87611c60828c73ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b815260040161092191906155e0565b1015611c98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b9061587f565b5050600180831614156116f1576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a018161167e57fe5b60608160005a90508442811015611d32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff166367f84adc7f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d8e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28f8e8e6040518763ffffffff1660e01b8152600401611dd596959493929190615657565b60006040518083038186803b158015611ded57600080fd5b505afa158015611e01573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e47919081019061549f565b93508984600081518110611e5757fe5b6020026020010151111561124f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b7f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d81565b6d4946c0e9f43f4dee607b0ef1fa1c81565b60608160005a90508442811015611f10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff166367f84adc7f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d8f8f8f8e8e6040518763ffffffff1660e01b8152600401611f9396959493929190615657565b60006040518083038186803b158015611fab57600080fd5b505afa158015611fbf573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612005919081019061549f565b9350898460008151811061201557fe5b60200260200101511115612055576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b6120678d338b8b600081811061126157fe5b6120a78d858b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d9250613752915050565b5060018083161415612170576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a01816120fd57fe5b046040518363ffffffff1660e01b815260040161211b929190615601565b602060405180830381600087803b15801561213557600080fd5b505af1158015612149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216d919061553f565b50505b50509998505050505050505050565b60608160005a905084428110156121c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff166367f84adc7f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28e8e8e8e6040518763ffffffff1660e01b815260040161226596959493929190615657565b60006040518083038186803b15801561227d57600080fd5b505afa158015612291573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526122d7919081019061549f565b935034846000815181106122e757fe5b60200260200101511115612327576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b6123378460008151811061159957fe5b6123977f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2858b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508d9250613752915050565b836000815181106123a457fe5b60200260200101513411156116285761162833856000815181106123c457fe5b602002602001015134036142e1565b60008160005a90508442811015612416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b6124208988613b07565b5060005b8a51811015612b055760008b828151811061243b57fe5b602002602001015151600114156124ab5760008c838151811061245a57fe5b602002602001015160008151811061246e57fe5b602002602001015190506124a3816020015182604001518360000151846060015185608001518660a001518760c0015161439a565b915050612af0565b6000808d84815181106124ba57fe5b60200260200101516001815181106124ce57fe5b602002602001015190508060c001511561288057805160208201516040517ff8b2cb4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169163f8d6aed491839163f8b2cb4f9161254291906004016155e0565b60206040518083038186803b15801561255a57600080fd5b505afa15801561256e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612592919061553f565b60208501516040517f948d8ce600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86169163948d8ce6916125e891906004016155e0565b60206040518083038186803b15801561260057600080fd5b505afa158015612614573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612638919061553f565b60408087015190517ff8b2cb4f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87169163f8b2cb4f9161268e91906004016155e0565b60206040518083038186803b1580156126a657600080fd5b505afa1580156126ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126de919061553f565b60408088015190517f948d8ce600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88169163948d8ce69161273491906004016155e0565b60206040518083038186803b15801561274c57600080fd5b505afa158015612760573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612784919061553f565b87606001518773ffffffffffffffffffffffffffffffffffffffff166354cf2aeb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156127cf57600080fd5b505afa1580156127e3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612807919061553f565b6040518763ffffffff1660e01b815260040161282896959493929190615c57565b60206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612878919061553f565b925050612a49565b604080516001808252818301909252600091602080830190803683370190505090508160000151816000815181106128b457fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060007f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff166367f84adc7f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d856020015186604001518760600151876040518663ffffffff1660e01b815260040161297d9594939291906156db565b60006040518083038186803b15801561299557600080fd5b505afa1580156129a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526129ef919081019061549f565b9050806000815181106129fe57fe5b602002602001015193508260800151841115612a46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b50505b60008e8581518110612a5757fe5b6020026020010151600081518110612a6b57fe5b60200260200101519050612a9c8160200151826040015183600001518685608001518660a001518760c0015161439a565b93508160c0015115612ad457612ace826020015183604001518460000151856060015186608001518760a00151614582565b50612aec565b612aec82602001518360000151858560600151614646565b5050505b612afa8187614179565b955050600101612424565b5086841115612b40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a00565b612b4e8833611bcf8b6141b6565b50612b5d8933611bcf8c6141b6565b505060018083161415612c27576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181612bb457fe5b046040518363ffffffff1660e01b8152600401612bd2929190615601565b602060405180830381600087803b158015612bec57600080fd5b505af1158015612c00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c24919061553f565b50505b50509695505050505050565b8060005a90508342811015612c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b612c868c338a8a6000818110610ad857fe5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff8d16906370a0823190612cdb908a906004016155e0565b60206040518083038186803b158015612cf357600080fd5b505afa158015612d07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d2b919061553f565b9050612d6c8d8a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508c92506130fb915050565b89612daa828e73ffffffffffffffffffffffffffffffffffffffff166370a082318b6040518263ffffffff1660e01b815260040161092191906155e0565b1015612de2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b505060018083161415610a77576000601036025a8361520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff1663079d229f3361a0aa8461374a0181612e3957fe5b046040518363ffffffff1660e01b8152600401612e57929190615601565b602060405180830381600087803b158015612e7157600080fd5b505af1158015612e85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ea9919061553f565b50505050505050505050505050565b7f000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b81565b60008060008342811015612f1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a37565b612f2b8d8d8d8d8d8d8d613717565b6040517f6a627842000000000000000000000000000000000000000000000000000000008152919550935073ffffffffffffffffffffffffffffffffffffffff8e1690636a62784290612f829089906004016155e0565b602060405180830381600087803b158015612f9c57600080fd5b505af1158015612fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd4919061553f565b91505099509950999650505050505050565b600080600061301a89897f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28a348b8b6147a8565b909350915061302b88338b86613505565b613035828a6139b6565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a1690636a627842906130879087906004016155e0565b602060405180830381600087803b1580156130a157600080fd5b505af11580156130b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d9919061553f565b9050813411156130ef576130ef338334036142e1565b96509650969350505050565b8260005b83518110156134bb57600084828151811061311657fe5b6020026020010151905060008060008060008060008060007f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d8c8f6040518463ffffffff1660e01b81526004016131ab93929190615627565b60c06040518083038186803b1580156131c357600080fd5b505afa1580156131d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131fb9190615340565b955095509550955095509550613244858d73ffffffffffffffffffffffffffffffffffffffff166370a082318d6040518263ffffffff1660e01b815260040161092191906155e0565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290995073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc415169063671a11b5906132c3908c9089908990899089908990600401615c7f565b60206040518083038186803b1580156132db57600080fd5b505afa1580156132ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613313919061553f565b97508596505050505050506000808573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561336757600080fd5b505afa15801561337b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061339f9190614ea2565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146133d9578360006133dd565b6000845b91509150600060018b510388106133f4578961340c565b8a886001018151811061340357fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f906134749086908690869060248101615bfc565b600060405180830381600087803b15801561348e57600080fd5b505af11580156134a2573d6000803e3d6000fd5b50959a5050600190980197506130ff9650505050505050565b5050505050565b808203828111156134ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615811565b92915050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd8686866040516024016135399392919061575b565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161358791906155c4565b6000604051808303816000865af19150503d80600081146135c4576040519150601f19603f3d011682016040523d82523d6000602084013e6135c9565b606091505b50915091508180156135f35750805115806135f35750808060200190518101906135f39190615523565b613629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615b5f565b505050505050565b60008161364057506001613710565b61364984613bb2565b15613701576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21690632e1a7d4d906136c0908590600401615bf3565b600060405180830381600087803b1580156136da57600080fd5b505af11580156136ee573d6000803e3d6000fd5b505050506136fc83836142e1565b61370c565b61370c848484614b97565b5060015b9392505050565b600080613729898989898989896147a8565b909250905061373a88338b85613505565b61374687338b84613505565b97509795505050505050565b8360005b835181101561362957600084828151811061376d57fe5b6020026020010151905060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156137bf57600080fd5b505afa1580156137d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137f79190614ea2565b9050600087846001018151811061380a57fe5b6020026020010151905060008060008473ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461385557836000866138d6565b6000848773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561389e57600080fd5b505afa1580156138b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138d69190614ea2565b925092509250600060018b510388106138ef5789613907565b8a88600101815181106138fe57fe5b60200260200101515b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915290915073ffffffffffffffffffffffffffffffffffffffff88169063022c0d9f9061396f9087908790869060248101615bfc565b600060405180830381600087803b15801561398957600080fd5b505af115801561399d573d6000803e3d6000fd5b50939a5050600190980197506137569650505050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015613a1e57600080fd5b505af1158015613a32573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216935063a9059cbb9250613aab915084908690600401615601565b602060405180830381600087803b158015613ac557600080fd5b505af1158015613ad9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613afd9190615523565b613b0357fe5b5050565b6000613b1283613bb2565b15613b9d577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015613b7f57600080fd5b505af1158015613b93573d6000803e3d6000fd5b5050505050613ba9565b613ba983333085613505565b50600192915050565b73ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b919050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663095ea7b38585604051602401613c17929190615601565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051613c6591906155c4565b6000604051808303816000865af19150503d8060008114613ca2576040519150601f19603f3d011682016040523d82523d6000602084013e613ca7565b606091505b5091509150818015613cd1575080511580613cd1575080806020019051810190613cd19190615523565b6134bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b9061595b565b6000613d14868585614b97565b6000806000806000807f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff1663b33d96b07f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d8c8f6040518463ffffffff1660e01b8152600401613d9a93929190615627565b60c06040518083038186803b158015613db257600080fd5b505afa158015613dc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dea9190615340565b95509550955095509550506000613e34868e73ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b815260040161092191906155e0565b6040517f671a11b500000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc415169063671a11b590613eb39084908a908a908a908a908a90600401615c7f565b60206040518083038186803b158015613ecb57600080fd5b505afa158015613edf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f03919061553f565b965050505050505060008673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401613f4691906155e0565b60206040518083038186803b158015613f5e57600080fd5b505afa158015613f72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f96919061553f565b90506000808773ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015613fe157600080fd5b505afa158015613ff5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140199190614ea2565b73ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff161461405357836000614057565b6000845b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152919350915073ffffffffffffffffffffffffffffffffffffffff89169063022c0d9f906140c19085908590309060248101615bfc565b600060405180830381600087803b1580156140db57600080fd5b505af11580156140ef573d6000803e3d6000fd5b50505050614130838a73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161092191906155e0565b94508585101561416c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615a6e565b5050505095945050505050565b808201828110156134ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615924565b60006141c182613bb2565b1561428f576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a08231906142389030906004016155e0565b60206040518083038186803b15801561425057600080fd5b505afa158015614264573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614288919061553f565b9050613be0565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316906370a08231906142389030906004016155e0565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161431891906155c4565b60006040518083038185875af1925050503d8060008114614355576040519150601f19603f3d011682016040523d82523d6000602084013e61435a565b606091505b5050905080614395576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615acb565b505050565b600081156143b7576143b0888888888888614582565b9050614577565b6040805160018082528183019092526000916020808301908036833701905050905086816000815181106143e757fe5b73ffffffffffffffffffffffffffffffffffffffff92831660209182029290920101526040517f67f84adc0000000000000000000000000000000000000000000000000000000081526000917f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41516906367f84adc90614492907f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d908e908e908d9089906004016156db565b60006040518083038186803b1580156144aa57600080fd5b505afa1580156144be573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052614504919081019061549f565b90508060008151811061451357fe5b6020026020010151925085831115614557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158b6565b6116f18a89858460018151811061456a57fe5b6020026020010151614646565b979650505050505050565b600061458f878685613be5565b6040517f7c5e9ea400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861690637c5e9ea4906145e9908a9087908b908a90899060040161578c565b6040805180830381600087803b15801561460257600080fd5b505af1158015614616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061463a9190615557565b50979650505050505050565b614651848484614b97565b6000808473ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561469a57600080fd5b505afa1580156146ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146d29190614ea2565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161461470c57826000614710565b6000835b604080516000815260208101918290527f022c0d9f00000000000000000000000000000000000000000000000000000000909152919350915073ffffffffffffffffffffffffffffffffffffffff86169063022c0d9f9061477a9085908590309060248101615bfc565b600060405180830381600087803b15801561479457600080fd5b505af1158015610d1d573d6000803e3d6000fd5b6000807f0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d73ffffffffffffffffffffffffffffffffffffffff1663e5e31b138a6040518263ffffffff1660e01b815260040161480491906155e0565b60206040518083038186803b15801561481c57600080fd5b505afa158015614830573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148549190615523565b61488a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615bbc565b6000807f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc41573ffffffffffffffffffffffffffffffffffffffff1663327494618c8c8c6040518463ffffffff1660e01b81526004016148ea93929190615627565b604080518083038186803b15801561490157600080fd5b505afa158015614915573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149399190615557565b9150915081600014801561494b575080155b1561495b57879350869250614b89565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc415169063ad615dec906149d4908c9087908790600401615c41565b60206040518083038186803b1580156149ec57600080fd5b505afa158015614a00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a24919061553f565b9050878111614a725785811015614a67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b906158ed565b889450925082614b87565b6040517fad615dec00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d989212c51ba850a1787ce4c666eb44a170cc415169063ad615dec90614aeb908c9087908990600401615c41565b60206040518083038186803b158015614b0357600080fd5b505afa158015614b17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b3b919061553f565b905089811115614b4757fe5b87811015614b81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615992565b94508793505b505b505097509795505050505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401614bc9929190615601565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051614c1791906155c4565b6000604051808303816000865af19150503d8060008114614c54576040519150601f19603f3d011682016040523d82523d6000602084013e614c59565b606091505b5091509150818015614c83575080511580614c83575080806020019051810190614c839190615523565b6134bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041b90615848565b8035613be081615d25565b60008083601f840112614cd5578182fd5b50813567ffffffffffffffff811115614cec578182fd5b6020830191508360208083028501011115614d0657600080fd5b9250929050565b600082601f830112614d1d578081fd5b81356020614d32614d2d83615cd7565b615cb3565b82815281810190858301855b85811015614e49578135880189603f820112614d58578788fd5b85810135614d68614d2d82615cd7565b808282528882019150604084018d604060e086028701011115614d89578b8cfd5b8b94505b83851015614e335760e0818f031215614da4578b8cfd5b60405160e0810181811067ffffffffffffffff82111715614dc157fe5b604052614dcd82614cb9565b8152614dda8b8301614cb9565b8b820152614dea60408301614cb9565b6040820152606082013560608201526080820135608082015260a082013560a0820152614e1960c08301614e56565b60c08201528352600194909401939189019160e001614d8d565b5087525050509284019290840190600101614d3e565b5090979650505050505050565b8035613be081615d4a565b805163ffffffff81168114613be057600080fd5b803560ff81168114613be057600080fd5b600060208284031215614e97578081fd5b813561371081615d25565b600060208284031215614eb3578081fd5b815161371081615d25565b60008060008060008060008060006101208a8c031215614edc578485fd5b8935614ee781615d25565b985060208a0135614ef781615d25565b975060408a0135614f0781615d25565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135614f3381615d25565b809250506101008a013590509295985092959850929598565b600080600080600080600080610100898b031215614f68578182fd5b8835614f7381615d25565b97506020890135614f8381615d25565b96506040890135614f9381615d25565b979a96995096976060810135975060808101359660a0820135965060c0820135955060e0909101359350915050565b60008060008060008060008060006101008a8c031215614fe0578283fd5b8935614feb81615d25565b985060208a0135614ffb81615d25565b975060408a0135965060608a0135955060808a013567ffffffffffffffff811115615024578384fd5b6150308c828d01614cc4565b90965094505060a08a013561504481615d25565b925060c08a0135915061505960e08b01614e75565b90509295985092959850929598565b600080600080600080600080610100898b031215615084578182fd5b883561508f81615d25565b97506020898101356150a081615d25565b975060408a0135965060608a0135955060808a013567ffffffffffffffff8111156150c9578384fd5b8a01601f81018c136150d9578384fd5b80356150e7614d2d82615cd7565b8082825284820191508484018f868786028701011115615105578788fd5b8794505b8385101561513057803561511c81615d25565b835260019490940193918501918501615109565b50809850505050505061514560a08a01614cb9565b925060c0890135915061515a60e08a01614e75565b90509295985092959890939650565b600080600080600080600060e0888a031215615183578081fd5b873561518e81615d25565b9650602088013561519e81615d25565b955060408801359450606088013593506080880135925060a08801356151c381615d25565b8092505060c0880135905092959891949750929550565b60008060008060008060c087890312156151f2578384fd5b86356151fd81615d25565b9550602087013561520d81615d25565b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600060c0888a03121561524c578081fd5b873561525781615d25565b965060208801359550604088013567ffffffffffffffff811115615279578182fd5b6152858a828b01614cc4565b909650945050606088013561529981615d25565b9250608088013591506152ae60a08901614e75565b905092959891949750929550565b60008060008060008060008060e0898b0312156152d7578182fd5b88356152e281615d25565b97506020890135965060408901359550606089013567ffffffffffffffff81111561530b578283fd5b6153178b828c01614cc4565b909650945050608089013561532b81615d25565b925060a0890135915061515a60c08a01614e75565b60008060008060008060c08789031215615358578384fd5b865161536381615d25565b602088015160408901519197509550935061538060608801614e61565b925061538e60808801614e61565b915061539c60a08801614e61565b90509295509295509295565b600080600080600080600060e0888a0312156153c2578081fd5b873567ffffffffffffffff8111156153d8578182fd5b6153e48a828b01614d0d565b97505060208801356153f581615d25565b9550604088013561540581615d25565b9450606088013593506080880135925060a088013591506152ae60c08901614e75565b60008060008060008060c08789031215615440578384fd5b863567ffffffffffffffff811115615456578485fd5b61546289828a01614d0d565b965050602087013561547381615d25565b9450604087013561548381615d25565b9350606087013592506080870135915061539c60a08801614e75565b600060208083850312156154b1578182fd5b825167ffffffffffffffff8111156154c7578283fd5b8301601f810185136154d7578283fd5b80516154e5614d2d82615cd7565b8181528381019083850185840285018601891015615501578687fd5b8694505b8385101561463a578051835260019490940193918501918501615505565b600060208284031215615534578081fd5b815161371081615d4a565b600060208284031215615550578081fd5b5051919050565b60008060408385031215615569578182fd5b505080516020909101519092909150565b60008151808452615592816020860160208601615cf5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516155d6818460208701615cf5565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff93841681529183166020830152909116604082015260600190565b600060a0820173ffffffffffffffffffffffffffffffffffffffff808a1684526020818a1681860152818916604086015287606086015260a060808601528286845260c086019050879350845b878110156156cb5784356156b781615d25565b8416825293820193908201906001016156a4565b509b9a5050505050505050505050565b600060a0820173ffffffffffffffffffffffffffffffffffffffff8089168452602081891681860152818816604086015286606086015260a0608086015282865180855260c0870191508288019450855b8181101561574a57855185168352948301949183019160010161572c565b50909b9a5050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff958616815260208101949094529190931660408301526060820192909252608081019190915260a00190565b6020808252825182820181905260009190848201906040850190845b81811015615805578351835292840192918401916001016157e9565b50909695505050505050565b60208082526015908201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604082015260600190565b6020808252601f908201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604082015260600190565b60208082526012908201527f3c6d696e546f74616c416d6f756e744f75740000000000000000000000000000604082015260600190565b6020808252601e908201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604082015260600190565b60208082526014908201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604082015260600190565b6020808252601e908201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604082015260600190565b6020808252600d908201527f4552525f4c494d49545f4f555400000000000000000000000000000000000000604082015260600190565b6020808252600c908201527f4552525f4c494d49545f494e0000000000000000000000000000000000000000604082015260600190565b6020808252600f908201527f526f757465723a20455850495245440000000000000000000000000000000000604082015260600190565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560408201527f4e54000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201527f4c45440000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f526f757465723a20496e76616c6964207374616b65506f6f6c00000000000000604082015260600190565b60208082526024908201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160408201527f494c454400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526014908201527f526f757465723a20496e76616c69642070616972000000000000000000000000604082015260600190565b90815260200190565b600085825284602083015273ffffffffffffffffffffffffffffffffffffffff8416604083015260806060830152615c37608083018461557a565b9695505050505050565b9283526020830191909152604082015260600190565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b9586526020860194909452604085019290925263ffffffff908116606085015290811660808401521660a082015260c00190565b60405181810167ffffffffffffffff81118282101715615ccf57fe5b604052919050565b600067ffffffffffffffff821115615ceb57fe5b5060209081020190565b60005b83811015615d10578181015183820152602001615cf8565b83811115615d1f576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff81168114615d4757600080fd5b50565b8015158114615d4757600080fdfea264697066735822122063d97bcbfaaf0b3f28485c166961e5d48832981a9591fbce7cd716e6298301b364736f6c63430007060033

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

0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

-----Decoded View---------------
Arg [0] : _factory (address): 0x5021470FC598373fBA4fE3384745940eaB3E653d
Arg [1] : _controller (address): 0xf0159d041DB29029cCF285A1043DcAAc7088030b
Arg [2] : _WETH (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000005021470fc598373fba4fe3384745940eab3e653d
Arg [1] : 000000000000000000000000f0159d041db29029ccf285a1043dcaac7088030b
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2


Deployed Bytecode Sourcemap

27512:26814:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28727:10;:18;28741:4;28727:18;;28720:26;;;;27512:26814;;;;;32335:862;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;42029:773;;;;;;:::i;:::-;;:::i;42810:681::-;;;;;;;;;;-1:-1:-1;42810:681:0;;;;;:::i;:::-;;:::i;34018:594::-;;;;;;:::i;:::-;;:::i;27700:41::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;31451:876::-;;;;;;;;;;-1:-1:-1;31451:876:0;;;;;:::i;:::-;;:::i;38247:747::-;;;;;;;;;;-1:-1:-1;38247:747:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;36896:610::-;;;;;;:::i;:::-;;:::i;35500:700::-;;;;;;;;;;-1:-1:-1;35500:700:0;;;;;:::i;:::-;;:::i;27748:38::-;;;;;;;;;;;;;:::i;43499:2233::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;37514:725::-;;;;;;;;;;-1:-1:-1;37514:725:0;;;;;:::i;:::-;;:::i;27601:41::-;;;;;;;;;;;;;:::i;27892:93::-;;;;;;;;;;;;;:::i;36208:680::-;;;;;;;;;;-1:-1:-1;36208:680:0;;;;;:::i;:::-;;:::i;39002:723::-;;;;;;:::i;:::-;;:::i;45740:4113::-;;;;;;:::i;:::-;;:::i;41334:687::-;;;;;;;;;;-1:-1:-1;41334:687:0;;;;;:::i;:::-;;:::i;27649:44::-;;;;;;;;;;;;;:::i;30774:669::-;;;;;;;;;;-1:-1:-1;30774:669:0;;;;;:::i;:::-;;:::i;32335:862::-;32680:19;32714:17;32746;32638:8;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;32799::::1;::::0;;;;:44:::1;32820:10;32799:44;::::0;::::1;::::0;:55:::1;::::0;32844:9;;32799:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32791:93;;;;;;;;;;;;:::i;:::-;32933:203;32975:9;32964:26;;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33007:5;33027:18;33060:14;33089:12;33116:9;32933:16;:203::i;:::-;33147:42;::::0;;;;32895:241;;-1:-1:-1;32895:241:0;;-1:-1:-1;32895:241:0;-1:-1:-1;33147:30:0::1;::::0;::::1;::::0;::::1;::::0;:42:::1;::::0;33178:10:::1;::::0;33147:42:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;32335:862:::0;;;;;;;;;;;:::o;42029:773::-;42303:4;28162:16;28181:9;28162:28;;42316:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;42410:16:::2;42429:9;42410:28;;42455:4;42449:19;;;42476:8;42449:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;42511:4;42505:20;;;42526:4;;42531:1;42526:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;42535:8;42505:39;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42498:47;;;;42580:30;::::0;;;;42556:21:::2;::::0;42580:26:::2;::::0;::::2;::::0;::::2;::::0;:30:::2;::::0;42607:2;;42580:30:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;42556:54;;42621:50;42656:4;42662;;42621:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;42668:2:0;;-1:-1:-1;42621:34:0::2;::::0;-1:-1:-1;;42621:50:0:i:2;:::-;42743:12;42690:49;42725:13;42697:8;42690:26;;;42717:2;42690:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:34:::0;::::2;:49::i;:::-;:65;;42682:112;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;;;28336:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28213:191;;42029:773;;;;;;;;;:::o;42810:681::-;43102:4;28162:16;28181:9;28162:28;;43115:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;43136:71:::2;43168:7;43177:10;43189:4;;43194:1;43189:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;43198:8;43136:31;:71::i;:::-;43218:64;43253:7;43262:4;;43218:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;43276:4:0::2;::::0;-1:-1:-1;43218:34:0::2;::::0;-1:-1:-1;;43218:64:0:i:2;:::-;43313:37;::::0;;;;43293:17:::2;::::0;43313:22:::2;43320:4;43313:22;::::0;::::2;::::0;:37:::2;::::0;43344:4:::2;::::0;43313:37:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43293:57;;43382:12;43369:9;:25;;43361:72;;;;;;;;;;;;:::i;:::-;43444:39;27840:42;43469:2;43473:9;43444:11;:39::i;:::-;-1:-1:-1::0;;;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;;;28336:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28213:191;;42810:681;;;;;;;;;;:::o;34018:594::-;34372:19;34406:17;34438;34330:8;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;34521:83:::1;34538:4;34544:5;34551:18;34571:14;34587:12;34601:2;34521:16;:83::i;:::-;34483:121:::0;;;;-1:-1:-1;34483:121:0;;-1:-1:-1;34018:594:0;-1:-1:-1;;;;;;;;;34018:594:0:o;27700:41::-;;;:::o;31451:876::-;31825:15;31855;31885:17;31783:8;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;31938::::1;::::0;;;;:44:::1;31959:10;31938:44;::::0;::::1;::::0;:55:::1;::::0;31983:9;;31938:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31930:93;;;;;;;;;;;;:::i;:::-;32034:12;32060:9;32049:26;;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32034:43;;32109:96;32128:4;32134:6;32142;32150:14;32166;32182:10;32194;32109:18;:96::i;:::-;32088:117;;;;;;;;32245:4;32228:27;;;32256:9;32228:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32277:42;::::0;;;;32216:50;;-1:-1:-1;32277:30:0::1;::::0;::::1;::::0;::::1;::::0;:42:::1;::::0;32308:10:::1;::::0;32277:42:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;28103:1;31451:876:::0;;;;;;;;;;;;;:::o;38247:747::-;38542:24;38510:4;28162:16;28181:9;28162:28;;38523:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;38609:7:::2;38589:49;;;38639:7;38648;38657:4;38663:8;38673:4;;38589:89;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;38579:99;;38728:12;38697:7;38722:1;38705:7;:14;:18;38697:27;;;;;;;;;;;;;;:43;;38689:90;;;;;;;;;;;;:::i;:::-;38790:73;38822:7;38831:10;38843:4;;38848:1;38843:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;38852;38860:1;38852:10;;;;;;;;;;;;;;38790:31;:73::i;:::-;38874:44;38880:7;38889;38898:4;;38874:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;38912:4:0::2;::::0;-1:-1:-1;38874:5:0::2;::::0;-1:-1:-1;;38874:44:0:i:2;:::-;38929:57;27840:42;38954:2;38958:7;38983:1;38966:7;:14;:18;38958:27;;;;;;;;;;;;;;38929:11;:57::i;:::-;-1:-1:-1::0;;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;;;28336:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28213:191;;38247:747;;;;;;;;;;;;:::o;36896:610::-;37173:24;37141:4;28162:16;28181:9;28162:28;;37154:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;37240:7:::2;37220:49;;;37270:7;37279:4;37285:8;37295:9;37306:4;;37220:91;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;37210:101;;37361:12;37330:7;37355:1;37338:7;:14;:18;37330:27;;;;;;;;;;;;;;:43;;37322:90;;;;;;;;;;;;:::i;:::-;37423:34;37437:7;37445:1;37437:10;;;;;;;;;;;;;;37449:4;;37454:1;37449:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;37423:13;:34::i;:::-;37468:30;37474:4;37480:7;37489:4;;37468:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;37495:2:0;;-1:-1:-1;37468:5:0::2;::::0;-1:-1:-1;;37468:30:0:i:2;:::-;-1:-1:-1::0;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;;;28336:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28213:191;;36896:610;;;;;;;;;;;:::o;35500:700::-;35821:24;35789:4;28162:16;28181:9;28162:28;;35802:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;35888:7:::2;35868:49;;;35918:7;35927;35936:8;35946;35956:4;35868:93;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;35858:103;;36011:12;35980:7;36005:1;35988:7;:14;:18;35980:27;;;;;;;;;;;;;;:43;;35972:90;;;;;;;;;;;;:::i;:::-;36075:73;36107:7;36116:10;36128:4;36133:1;36128:7;;;;;;;;;;;;;;36137;36145:1;36137:10;;;;;;;36075:73;36159:33;36165:7;36174;36183:4;36189:2;36159:5;:33::i;:::-;-1:-1:-1::0;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;27748:38;;;:::o;43499:2233::-;43825:22;43793:4;28162:16;28181:9;28162:28;;43806:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;43860:39:::2;43876:7;43885:13;43860:15;:39::i;:::-;;43910:21;43947:15;43953:8;43947:5;:15::i;:::-;43942:103;;43995:38;::::0;;;;:26:::2;::::0;::::2;::::0;::::2;::::0;:38:::2;::::0;44022:10:::2;::::0;43995:38:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43979:54;;43942:103;44062:9;44057:1279;44081:13;:20;44077:1;:24;44057:1279;;;44123:22;::::0;44160:1039:::2;44184:13;44198:1;44184:16;;;;;;;;;;;;;;:23;44180:1;:27;44160:1039;;;44233:16;44252:13;44266:1;44252:16;;;;;;;;;;;;;;44269:1;44252:19;;;;;;;;;;;;;;44233:38;;44294:1;44299;44294:6;44290:247;;;44485:15;::::0;::::2;:32:::0;;;44290:247:::2;44561:4;:12;;;44557:627;;;44598:68;44625:4;:12;;;44639:4;:9;;;44650:4;:15;;;44598:26;:68::i;:::-;44719:4;:9;;;44712:35;;;44774:4;:12;;;44813:4;:15;;;44855:4;:13;;;44895:4;:22;;;44944:4;:13;;;44712:268;;;;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::2;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;44691:289:0;-1:-1:-1;44557:627:0::2;;;45046:118;45084:4;:12;;;45098:4;:13;;;45113:4;:9;;;45124:4;:15;;;45141:4;:22;;;45046:37;:118::i;:::-;45029:135;;44557:627;-1:-1:-1::0;44209:3:0::2;;44160:1039;;;-1:-1:-1::0;45290:34:0::2;:14:::0;45309;45290:18:::2;:34::i;:::-;45273:51:::0;-1:-1:-1;;44103:3:0::2;;44057:1279;;;;45348:49;45360:8;45370:10;45382:14;45348:11;:49::i;:::-;;45408:53;45420:7;45429:10;45441:19;45452:7;45441:10;:19::i;:::-;45408:11;:53::i;:::-;;45478:15;45484:8;45478:5;:15::i;:::-;45474:251;;;45536:17;45518:14;:35;;45510:61;;;;;;;;;;;;:::i;:::-;45474:251;;;45673:17;45612:57;45655:13;45619:8;45612:26;;;45639:10;45612:38;;;;;;;;;;;;;;;:::i;:57::-;:78;;45604:109;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;37514:725;37809:24;37777:4;28162:16;28181:9;28162:28;;37790:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;37876:7:::2;37856:48;;;37905:7;37914;37923:4;37929:9;37940:4;;37856:89;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;37846:99;;37978:11;37964:7;37972:1;37964:10;;;;;;;;;;;;;;:25;;37956:68;;;;;;;;;;;;:::i;27601:41::-:0;;;:::o;27892:93::-;27942:42;27892:93;:::o;36208:680::-;36533:24;36501:4;28162:16;28181:9;28162:28;;36514:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;36600:7:::2;36580:48;;;36629:7;36638;36647:8;36657:9;36668:4;;36580:93;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;36570:103;;36706:11;36692:7;36700:1;36692:10;;;;;;;;;;;;;;:25;;36684:68;;;;;;;;;;;;:::i;:::-;36763:73;36795:7;36804:10;36816:4;;36821:1;36816:7;;;;;;36763:73;36847:33;36853:7;36862;36871:4;;36847:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;36877:2:0;;-1:-1:-1;36847:5:0::2;::::0;-1:-1:-1;;36847:33:0:i:2;:::-;-1:-1:-1::0;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;;;28336:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28213:191;;36208:680;;;;;;;;;;;;;:::o;39002:723::-;39276:24;39244:4;28162:16;28181:9;28162:28;;39257:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;39343:7:::2;39323:48;;;39372:7;39381:4;39387:8;39397:9;39408:4;;39323:90;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;39313:100;;39446:9;39432:7;39440:1;39432:10;;;;;;;;;;;;;;:23;;39424:66;;;;;;;;;;;;:::i;:::-;39501:34;39515:7;39523:1;39515:10;;;;;;;39501:34;39546:30;39552:4;39558:7;39567:4;;39546:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;39573:2:0;;-1:-1:-1;39546:5:0::2;::::0;-1:-1:-1;;39546:30:0:i:2;:::-;39639:7;39647:1;39639:10;;;;;;;;;;;;;;39627:9;:22;39623:94;;;39651:66;39682:10;39706:7;39714:1;39706:10;;;;;;;;;;;;;;39694:9;:22;39651:30;:66::i;45740:4113::-:0;46034:21;46002:4;28162:16;28181:9;28162:28;;46015:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;46068:42:::2;46084:7;46093:16;46068:15;:42::i;:::-;;46128:9;46123:3520;46147:13;:20;46143:1;:24;46123:3520;;;46189:30;46323:13;46337:1;46323:16;;;;;;;;;;;;;;:23;46350:1;46323:28;46319:3239;;;46372:16;46391:13;46405:1;46391:16;;;;;;;;;;;;;;46408:1;46391:19;;;;;;;;;;;;;;46372:38;;46454:293;46494:4;:12;;;46529:4;:13;;;46565:4;:9;;;46597:4;:15;;;46635:4;:22;;;46680:4;:13;;;46716:4;:12;;;46454:17;:293::i;:::-;46429:318;;46319:3239;;;;47084:31;47195:22:::0;47220:13:::2;47234:1;47220:16;;;;;;;;;;;;;;47237:1;47220:19;;;;;;;;;;;;;;47195:44;;47262:10;:18;;;47258:1148;;;47336:15:::0;;47483:18:::2;::::0;::::2;::::0;47457:45:::2;::::0;;;;47401:29:::2;::::0;::::2;::::0;::::2;::::0;;;47457:25:::2;::::0;:45:::2;::::0;47483:18;47457:45:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47566:18;::::0;::::2;::::0;47529:56:::2;::::0;;;;:36:::2;::::0;::::2;::::0;::::2;::::0;:56:::2;::::0;47566:18;47529:56:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47638:19;::::0;;::::2;::::0;47612:46;;;;;:25:::2;::::0;::::2;::::0;::::2;::::0;:46:::2;::::0;47638:19;47612:46:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47722:19;::::0;;::::2;::::0;47685:57;;;;;:36:::2;::::0;::::2;::::0;::::2;::::0;:57:::2;::::0;47722:19;47685:57:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47769:10;:21;;;47817:14;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47401:463;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47375:489;;47258:1148;;;;47938:16;::::0;;47952:1:::2;47938:16:::0;;;;;::::2;::::0;;;47913:22:::2;::::0;47938:16:::2;::::0;;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;47938:16:0::2;47913:41;;47988:10;:15;;;47977:5;47983:1;47977:8;;;;;;;;;;;;;:26;;;;;;;;;::::0;::::2;48026:24;48098:7;48078:48;;;48127:7;48136:10;:18;;;48156:10;:19;;;48177:10;:21;;;48200:5;48078:128;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;48026:180;;48255:7;48263:1;48255:10;;;;;;;;;;;;;;48229:36;;48323:10;:28;;;48296:23;:55;;48288:98;;;;;;;;;;;;:::i;:::-;47258:1148;;;48512:21;48536:13;48550:1;48536:16;;;;;;;;;;;;;;48553:1;48536:19;;;;;;;;;;;;;;48512:43;;48599:331;48639:9;:17;;;48679:9;:18;;;48720:9;:14;;;48757:23;48803:9;:27;;;48853:9;:18;;;48894:9;:17;;;48599;:331::i;:::-;48574:356;;49017:10;:18;;;49013:530;;;49060:318;49100:10;:18;;;49145:10;:19;;;49191:10;:15;;;49233:10;:21;;;49281:10;:28;;;49336:10;:19;;;49060:13;:318::i;:::-;;49013:530;;;49427:96;49439:10;:18;;;49459:10;:15;;;49476:23;49501:10;:21;;;49427:11;:96::i;:::-;46319:3239;;;;49590:41;:22:::0;49617:13;49590:26:::2;:41::i;:::-;49574:57:::0;-1:-1:-1;;46169:3:0::2;;46123:3520;;;;49680:16;49663:13;:33;;49655:58;;;;;;;;;;;;:::i;:::-;49726:55;49738:8;49748:10;49760:20;49771:8;49760:10;:20::i;49726:55::-;;49792:53;49804:7;49813:10;49825:19;49836:7;49825:10;:19::i;49792:53::-;-1:-1:-1::0;;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;;;28336:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28213:191;;45740:4113;;;;;;;;;;:::o;41334:687::-;41656:4;28162:16;28181:9;28162:28;;41669:8:::1;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;41690:71:::2;41722:7;41731:10;41743:4;;41748:1;41743:7;;;;;;41690:71;41796:30;::::0;;;;41772:21:::2;::::0;41796:26:::2;::::0;::::2;::::0;::::2;::::0;:30:::2;::::0;41823:2;;41796:30:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41772:54;;41837:53;41872:7;41881:4;;41837:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;41887:2:0;;-1:-1:-1;41837:34:0::2;::::0;-1:-1:-1;;41837:53:0:i:2;:::-;41962:12;41909:49;41944:13;41916:8;41909:26;;;41936:2;41909:30;;;;;;;;;;;;;;;:::i;:49::-;:65;;41901:112;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;28225:3:0;28218:10;;;28217:17;28213:191;;;28251:16;28301:2;28306:8;28301:20;28289:9;28278:8;28270:5;:16;:28;:51;28251:70;;27942:42;28336:16;;;28353:10;28386:5;28366:8;28377:5;28366:16;28365:26;;;;;;28336:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28213:191;41334:687;;;;;;;;;;;:::o;27649:44::-;;;:::o;30774:669::-;31159:15;31189;31219:17;31117:8;28057:15;28045:8;:27;;28037:55;;;;;;;;;;;;:::i;:::-;31285:96:::1;31304:4;31310:6;31318;31326:14;31342;31358:10;31370;31285:18;:96::i;:::-;31404:31;::::0;;;;31264:117;;-1:-1:-1;31264:117:0;-1:-1:-1;31404:27:0::1;::::0;::::1;::::0;::::1;::::0;:31:::1;::::0;31432:2;;31404:31:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;31392:43;;30774:669:::0;;;;;;;;;;;;;;:::o;33205:805::-;33457:19;33491:17;33523;33595:93;33609:4;33615:5;33622:4;33628:18;33648:9;33659:14;33675:12;33595:13;:93::i;:::-;33568:120;;-1:-1:-1;33568:120:0;-1:-1:-1;33699:69:0;33731:5;33738:10;33750:4;33568:120;33699:31;:69::i;:::-;33779:30;33793:9;33804:4;33779:13;:30::i;:::-;33832:31;;;;;:27;;;;;;:31;;33860:2;;33832:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33820:43;;33926:9;33914;:21;33910:92;;;33937:65;33968:10;33992:9;33980;:21;33937:30;:65::i;:::-;33205:805;;;;;;;;;;:::o;39872:1454::-;40047:7;40031:13;40065:1254;40085:4;:11;40081:1;:15;40065:1254;;;40118:21;40159:4;40164:1;40159:7;;;;;;;;;;;;;;40118:49;;40184:19;40218:20;40253:21;40309:14;40325:20;40347:21;40370:23;40395:24;40421:14;40480:7;40460:56;;;40517:7;40534:4;40541:5;40460:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40308:239;;;;;;;;;;;;40580:56;40623:12;40587:5;40580:23;;;40612:4;40580:38;;;;;;;;;;;;;;;:::i;:56::-;40670:274;;;;;40566:70;;-1:-1:-1;40670:41:0;40690:7;40670:41;;;;:274;;40566:70;;40768:12;;40803:13;;40839:16;;40878:17;;40918:7;;40670:274;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40655:289;;40979:6;40963:22;;40065:1254;;;;;;41016:18;41036;41067:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41058:22;;:5;:22;;;:80;;41113:12;41135:1;41058:80;;;41092:1;41096:12;41058:80;41015:123;;;;41153:10;41184:1;41170:4;:11;:15;41166:1;:19;:39;;41202:3;41166:39;;;41188:4;41193:1;41197;41193:5;41188:11;;;;;;;;;;;;;;41166:39;41258:12;;;41268:1;41258:12;;;;;;;;;41220:51;;;;41153:52;;-1:-1:-1;41220:9:0;;;;;;:51;;41230:10;;41242;;41153:52;;41220:51;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41294:13:0;;-1:-1:-1;;40098:3:0;;;;;-1:-1:-1;40065:1254:0;;-1:-1:-1;;;;;;;40065:1254:0;;;39872:1454;;;;:::o;19124:138::-;19217:5;;;19212:16;;;;19204:50;;;;;;;;;;;;:::i;:::-;19124:138;;;;:::o;12925:448::-;13150:12;13164:17;13185:5;:10;;13219;13231:4;13237:2;13241:5;13196:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13185:63;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13149:99;;;;13267:7;:57;;;;-1:-1:-1;13279:11:0;;:16;;:44;;;13310:4;13299:24;;;;;;;;;;;;:::i;:::-;13259:106;;;;;;;;;;;;:::i;:::-;12925:448;;;;;;:::o;53770:438::-;53886:4;53907:11;53903:55;;-1:-1:-1;53942:4:0;53935:11;;53903:55;53974:12;53980:5;53974;:12::i;:::-;53970:209;;;54003:28;;;;;:20;54009:4;54003:20;;;;:28;;54024:6;;54003:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54046:42;54077:2;54081:6;54046:30;:42::i;:::-;53970:209;;;54121:46;54149:5;54156:2;54160:6;54121:27;:46::i;:::-;-1:-1:-1;54196:4:0;53770:438;;;;;;:::o;30197:569::-;30447:15;30464;30513:91;30527:4;30533:6;30541;30549:14;30565;30581:10;30593;30513:13;:91::i;:::-;30492:112;;-1:-1:-1;30492:112:0;-1:-1:-1;30615:66:0;30647:6;30655:10;30667:4;30492:112;30615:31;:66::i;:::-;30692;30724:6;30732:10;30744:4;30750:7;30692:31;:66::i;:::-;30197:569;;;;;;;;;;:::o;34723:769::-;34904:7;34888:13;34922:563;34946:4;:11;34942:1;:15;34922:563;;;34979:23;35022:4;35027:1;35022:7;;;;;;;;;;;;;;34979:51;;35045:14;35062:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35045:32;;35092:17;35112:7;35120:1;35124;35120:5;35112:14;;;;;;;;;;;;;;35092:34;;35142:18;35162;35182:14;35226:6;35217:15;;:5;:15;;;:92;;35279:9;35298:1;35302:6;35217:92;;;35244:1;35248:9;35259:6;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35141:168;;;;;;35324:10;35355:1;35341:4;:11;:15;35337:1;:19;:39;;35373:3;35337:39;;;35359:4;35364:1;35368;35364:5;35359:11;;;;;;;;;;;;;;35337:39;35431:12;;;35441:1;35431:12;;;;;;;;;35391:53;;;;35324:52;;-1:-1:-1;35391:11:0;;;;;;:53;;35403:10;;35415;;35324:52;;35391:53;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35467:6:0;;-1:-1:-1;;34959:3:0;;;;;-1:-1:-1;34922:563:0;;-1:-1:-1;;;;;;;34922:563:0;53596:166;53673:4;53667:19;;;53694:6;53667:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53721:32:0;;;;;:20;53727:4;53721:20;;-1:-1:-1;53721:20:0;;-1:-1:-1;53721:32:0;;-1:-1:-1;53742:2:0;;53746:6;;53721:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53714:40;;;;53596:166;;:::o;49861:310::-;49935:4;49956:12;49962:5;49956;:12::i;:::-;49952:190;;;49991:4;49985:19;;;50012:9;49985:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49952:190;;;50057:73;50089:5;50096:10;50116:4;50123:6;50057:31;:73::i;:::-;-1:-1:-1;50159:4:0;49861:310;;;;:::o;54216:107::-;54294:20;;;27840:42;54294:20;54216:107;;;;:::o;12116:395::-;12300:12;12314:17;12335:5;:10;;12369;12381:2;12385:5;12346:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12335:57;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12299:93;;;;12411:7;:57;;;;-1:-1:-1;12423:11:0;;:16;;:44;;;12454:4;12443:24;;;;;;;;;;;;:::i;:::-;12403:100;;;;;;;;;;;;:::i;52245:1343::-;52458:22;52493:54;52521:7;52530:4;52536:10;52493:27;:54::i;:::-;52560:20;52609;52631:21;52654:23;52679:24;52705:14;52760:7;52740:56;;;52797:7;52806:4;52812:7;52740:80;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52606:214;;;;;;;;;;;52835:19;52857:49;52893:12;52864:7;52857:25;;;52883:4;52857:31;;;;;;;;;;;;;;;:::i;:49::-;52936:129;;;;;52835:71;;-1:-1:-1;52936:41:0;52956:7;52936:41;;;;:129;;52835:71;;52991:12;;53005:13;;53020:16;;53038:17;;53057:7;;52936:129;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52921:144;;52245:1343;;;;;;53087:21;53118:8;53111:26;;;53146:4;53111:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53087:65;;53164:18;53184;53234:4;53217:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53206:42;;:7;:42;;;:100;;53281:12;53303:1;53206:100;;;53260:1;53264:12;53206:100;53384:12;;;53394:1;53384:12;;;;;;;;;53317:80;;;;53163:143;;-1:-1:-1;53163:143:0;-1:-1:-1;53317:27:0;;;;;;:80;;53163:143;;;;53377:4;;53317:80;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53427:60;53473:13;53434:8;53427:26;;;53462:4;53427:41;;;;;;;;;;;;;;;:::i;:60::-;53410:77;;53524:17;53506:14;:35;;53498:82;;;;;;;;;;;;:::i;:::-;52245:1343;;;;;;;;;;;:::o;18979:137::-;19072:5;;;19067:16;;;;19059:49;;;;;;;;;;;;:::i;50179:251::-;50237:7;50261:12;50267:5;50261;:12::i;:::-;50257:166;;;50297:36;;;;;:21;50303:4;50297:21;;;;:36;;50327:4;;50297:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50290:43;;;;50257:166;50373:38;;;;;:23;;;;;;:38;;50405:4;;50373:38;;;:::i;13381:200::-;13494:12;;;13454;13494;;;;;;;;;13472:7;;;;13487:5;;13472:35;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13453:54;;;13526:7;13518:55;;;;;;;;;;;;:::i;:::-;13381:200;;;:::o;50438:854::-;50681:21;50719:7;50715:570;;;50750:79;50764:7;50773:8;50783:4;50789:10;50801:17;50820:8;50750:13;:79::i;:::-;50743:86;;;;50715:570;50887:16;;;50901:1;50887:16;;;;;;;;;50862:22;;50887:16;;;;;;;;;;;-1:-1:-1;50887:16:0;50862:41;;50929:4;50918:5;50924:1;50918:8;;;;;;;;:15;;;;:8;;;;;;;;;:15;50975:95;;;;;50948:24;;50995:7;50975:48;;;;:95;;51024:7;;51033;;51042:8;;51052:10;;51064:5;;50975:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50948:122;;51101:7;51109:1;51101:10;;;;;;;;;;;;;;51085:26;;51151:17;51134:13;:34;;51126:77;;;;;;;;;;;;:::i;:::-;51220:53;51232:7;51241:4;51247:13;51262:7;51270:1;51262:10;;;;;;;;;;;;;;51220:11;:53::i;50715:570::-;50438:854;;;;;;;;;:::o;51300:442::-;51516:21;51550:60;51577:7;51586:4;51592:17;51550:26;:60::i;:::-;51643:91;;;;;:31;;;;;;:91;;51675:7;;51684:17;;51703:8;;51713:10;;51725:8;;51643:91;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;51623:111:0;51300:442;-1:-1:-1;;;;;;;51300:442:0:o;51750:487::-;51916:60;51944:7;51953:4;51959:16;51916:27;:60::i;:::-;51988:18;52008;52058:4;52041:29;;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52030:42;;:7;:42;;;:106;;52108:15;52133:1;52030:106;;;52084:1;52088:15;52030:106;52216:12;;;52226:1;52216:12;;;;;;;;;52149:80;;;;51987:149;;-1:-1:-1;51987:149:0;-1:-1:-1;52149:27:0;;;;;;:80;;51987:149;;;;52209:4;;52149:80;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28858:1331;29111:15;29128;29184:7;29164:35;;;29200:4;29164:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29156:74;;;;;;;;;;;;:::i;:::-;29242:16;29260;29300:7;29280:40;;;29321:4;29327:6;29335;29280:62;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29241:101;;;;29357:8;29369:1;29357:13;:30;;;;-1:-1:-1;29374:13:0;;29357:30;29353:829;;;29426:14;;-1:-1:-1;29442:14:0;;-1:-1:-1;29353:829:0;;;29515:70;;;;;29490:22;;29515:34;29535:7;29515:34;;;;:70;;29550:14;;29566:8;;29576;;29515:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29490:95;;29622:14;29604;:32;29600:571;;29683:10;29665:14;:28;;29657:70;;;;;;;;;;;;:::i;:::-;29768:14;;-1:-1:-1;29784:14:0;-1:-1:-1;29784:14:0;29600:571;;;29865:70;;;;;29840:22;;29865:34;29885:7;29865:34;;;;:70;;29900:14;;29916:8;;29926;;29865:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29840:95;;29979:14;29961;:32;;29954:40;;;;30039:10;30021:14;:28;;30013:70;;;;;;;;;;;;:::i;:::-;30124:14;-1:-1:-1;30140:14:0;;-1:-1:-1;29600:571:0;29353:829;;28858:1331;;;;;;;;;;;;:::o;12519:398::-;12705:12;12719:17;12740:5;:10;;12774;12786:2;12790:5;12751:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12740:57;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12704:93;;;;12816:7;:57;;;;-1:-1:-1;12828:11:0;;:16;;:44;;;12859:4;12848:24;;;;;;;;;;;;:::i;:::-;12808:101;;;;;;;;;;;;:::i;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;1970:27;1991:5;1970:27;:::i;:::-;1962:6;1955:43;2039:36;2071:2;2064:5;2060:14;2039:36;:::i;:::-;2034:2;2026:6;2022:15;2015:61;2117:36;2149:2;2142:5;2138:14;2117:36;:::i;:::-;2112:2;2104:6;2100:15;2093:61;2219:2;2212:5;2208:14;2195:28;2190:2;2182:6;2178:15;2171:53;2290:3;2283:5;2279:15;2266:29;2260:3;2252:6;2248:16;2241:55;2362:3;2355:5;2351:15;2338:29;2332:3;2324:6;2320:16;2313:55;2410:34;2439:3;2432:5;2428:15;2410:34;:::i;:::-;2404:3;2392:16;;2385:60;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:132::-;2785:20;;2814:30;2785:20;2814:30;:::i;2855:169::-;2935:13;;2988:10;2977:22;;2967:33;;2957:2;;3014:1;3011;3004:12;3029:158;3097:20;;3157:4;3146:16;;3136:27;;3126:2;;3177:1;3174;3167:12;3192:259;;3304:2;3292:9;3283:7;3279:23;3275:32;3272:2;;;3325:6;3317;3310:22;3272:2;3369:9;3356:23;3388:33;3415:5;3388:33;:::i;3456:263::-;;3579:2;3567:9;3558:7;3554:23;3550:32;3547:2;;;3600:6;3592;3585:22;3547:2;3637:9;3631:16;3656:33;3683:5;3656:33;:::i;3724:1034::-;;;;;;;;;;3972:3;3960:9;3951:7;3947:23;3943:33;3940:2;;;3994:6;3986;3979:22;3940:2;4038:9;4025:23;4057:33;4084:5;4057:33;:::i;:::-;4109:5;-1:-1:-1;4166:2:1;4151:18;;4138:32;4179:35;4138:32;4179:35;:::i;:::-;4233:7;-1:-1:-1;4292:2:1;4277:18;;4264:32;4305:35;4264:32;4305:35;:::i;:::-;4359:7;-1:-1:-1;4413:2:1;4398:18;;4385:32;;-1:-1:-1;4464:3:1;4449:19;;4436:33;;-1:-1:-1;4516:3:1;4501:19;;4488:33;;-1:-1:-1;4568:3:1;4553:19;;4540:33;;-1:-1:-1;4625:3:1;4610:19;;4597:33;4639:35;4597:33;4639:35;:::i;:::-;4693:7;4683:17;;;4747:3;4736:9;4732:19;4719:33;4709:43;;3930:828;;;;;;;;;;;:::o;4763:890::-;;;;;;;;;4994:3;4982:9;4973:7;4969:23;4965:33;4962:2;;;5016:6;5008;5001:22;4962:2;5060:9;5047:23;5079:33;5106:5;5079:33;:::i;:::-;5131:5;-1:-1:-1;5188:2:1;5173:18;;5160:32;5201:35;5160:32;5201:35;:::i;:::-;5255:7;-1:-1:-1;5314:2:1;5299:18;;5286:32;5327:35;5286:32;5327:35;:::i;:::-;4952:701;;;;-1:-1:-1;5381:7:1;;5435:2;5420:18;;5407:32;;-1:-1:-1;5486:3:1;5471:19;;5458:33;;5538:3;5523:19;;5510:33;;-1:-1:-1;5590:3:1;5575:19;;5562:33;;-1:-1:-1;5642:3:1;5627:19;;;5614:33;;-1:-1:-1;4952:701:1;-1:-1:-1;;4952:701:1:o;5658:1167::-;;;;;;;;;;5922:3;5910:9;5901:7;5897:23;5893:33;5890:2;;;5944:6;5936;5929:22;5890:2;5988:9;5975:23;6007:33;6034:5;6007:33;:::i;:::-;6059:5;-1:-1:-1;6116:2:1;6101:18;;6088:32;6129:35;6088:32;6129:35;:::i;:::-;6183:7;-1:-1:-1;6237:2:1;6222:18;;6209:32;;-1:-1:-1;6288:2:1;6273:18;;6260:32;;-1:-1:-1;6343:3:1;6328:19;;6315:33;6371:18;6360:30;;6357:2;;;6408:6;6400;6393:22;6357:2;6452:76;6520:7;6511:6;6500:9;6496:22;6452:76;:::i;:::-;6547:8;;-1:-1:-1;6426:102:1;-1:-1:-1;;6634:3:1;6619:19;;6606:33;6648:35;6606:33;6648:35;:::i;:::-;6702:7;-1:-1:-1;6756:3:1;6741:19;;6728:33;;-1:-1:-1;6780:39:1;6814:3;6799:19;;6780:39;:::i;:::-;6770:49;;5880:945;;;;;;;;;;;:::o;6830:1673::-;;;;;;;;;7084:3;7072:9;7063:7;7059:23;7055:33;7052:2;;;7106:6;7098;7091:22;7052:2;7150:9;7137:23;7169:33;7196:5;7169:33;:::i;:::-;7221:5;-1:-1:-1;7245:2:1;7284:18;;;7271:32;7312:35;7271:32;7312:35;:::i;:::-;7366:7;-1:-1:-1;7420:2:1;7405:18;;7392:32;;-1:-1:-1;7471:2:1;7456:18;;7443:32;;-1:-1:-1;7526:3:1;7511:19;;7498:33;7554:18;7543:30;;7540:2;;;7591:6;7583;7576:22;7540:2;7619:22;;7672:4;7664:13;;7660:27;-1:-1:-1;7650:2:1;;7706:6;7698;7691:22;7650:2;7747;7734:16;7770:65;7785:49;7831:2;7785:49;:::i;7770:65::-;7857:3;7881:2;7876:3;7869:15;7909:2;7904:3;7900:12;7893:19;;7940:2;7936;7932:11;7989:7;7984:2;7978;7974;7970:11;7966:2;7962:20;7958:29;7955:42;7952:2;;;8015:6;8007;8000:22;7952:2;8042:6;8033:15;;8057:246;8071:2;8068:1;8065:9;8057:246;;;8144:3;8131:17;8161:35;8188:7;8161:35;:::i;:::-;8209:20;;8089:1;8082:9;;;;;8249:12;;;;8281;;8057:246;;;8061:3;8322:5;8312:15;;;;;;;8346:41;8382:3;8371:9;8367:19;8346:41;:::i;:::-;8336:51;;8434:3;8423:9;8419:19;8406:33;8396:43;;8458:39;8492:3;8481:9;8477:19;8458:39;:::i;:::-;8448:49;;7042:1461;;;;;;;;;;;:::o;8508:821::-;;;;;;;;8722:3;8710:9;8701:7;8697:23;8693:33;8690:2;;;8744:6;8736;8729:22;8690:2;8788:9;8775:23;8807:33;8834:5;8807:33;:::i;:::-;8859:5;-1:-1:-1;8916:2:1;8901:18;;8888:32;8929:35;8888:32;8929:35;:::i;:::-;8983:7;-1:-1:-1;9037:2:1;9022:18;;9009:32;;-1:-1:-1;9088:2:1;9073:18;;9060:32;;-1:-1:-1;9139:3:1;9124:19;;9111:33;;-1:-1:-1;9196:3:1;9181:19;;9168:33;9210:35;9168:33;9210:35;:::i;:::-;9264:7;9254:17;;;9318:3;9307:9;9303:19;9290:33;9280:43;;8680:649;;;;;;;;;;:::o;9334:677::-;;;;;;;9531:3;9519:9;9510:7;9506:23;9502:33;9499:2;;;9553:6;9545;9538:22;9499:2;9597:9;9584:23;9616:33;9643:5;9616:33;:::i;:::-;9668:5;-1:-1:-1;9725:2:1;9710:18;;9697:32;9738:35;9697:32;9738:35;:::i;:::-;9489:522;;9792:7;;-1:-1:-1;;;;9846:2:1;9831:18;;9818:32;;9897:2;9882:18;;9869:32;;9948:3;9933:19;;9920:33;;-1:-1:-1;10000:3:1;9985:19;;;9972:33;;-1:-1:-1;9489:522:1:o;10016:954::-;;;;;;;;10246:3;10234:9;10225:7;10221:23;10217:33;10214:2;;;10268:6;10260;10253:22;10214:2;10312:9;10299:23;10331:33;10358:5;10331:33;:::i;:::-;10383:5;-1:-1:-1;10435:2:1;10420:18;;10407:32;;-1:-1:-1;10490:2:1;10475:18;;10462:32;10517:18;10506:30;;10503:2;;;10554:6;10546;10539:22;10503:2;10598:76;10666:7;10657:6;10646:9;10642:22;10598:76;:::i;:::-;10693:8;;-1:-1:-1;10572:102:1;-1:-1:-1;;10780:2:1;10765:18;;10752:32;10793:35;10752:32;10793:35;:::i;:::-;10847:7;-1:-1:-1;10901:3:1;10886:19;;10873:33;;-1:-1:-1;10925:39:1;10959:3;10944:19;;10925:39;:::i;:::-;10915:49;;10204:766;;;;;;;;;;:::o;10975:1023::-;;;;;;;;;11222:3;11210:9;11201:7;11197:23;11193:33;11190:2;;;11244:6;11236;11229:22;11190:2;11288:9;11275:23;11307:33;11334:5;11307:33;:::i;:::-;11359:5;-1:-1:-1;11411:2:1;11396:18;;11383:32;;-1:-1:-1;11462:2:1;11447:18;;11434:32;;-1:-1:-1;11517:2:1;11502:18;;11489:32;11544:18;11533:30;;11530:2;;;11581:6;11573;11566:22;11530:2;11625:76;11693:7;11684:6;11673:9;11669:22;11625:76;:::i;:::-;11720:8;;-1:-1:-1;11599:102:1;-1:-1:-1;;11807:3:1;11792:19;;11779:33;11821:35;11779:33;11821:35;:::i;:::-;11875:7;-1:-1:-1;11929:3:1;11914:19;;11901:33;;-1:-1:-1;11953:39:1;11987:3;11972:19;;11953:39;:::i;12003:643::-;;;;;;;12208:3;12196:9;12187:7;12183:23;12179:33;12176:2;;;12230:6;12222;12215:22;12176:2;12267:9;12261:16;12286:33;12313:5;12286:33;:::i;:::-;12383:2;12368:18;;12362:25;12427:2;12412:18;;12406:25;12338:5;;-1:-1:-1;12362:25:1;-1:-1:-1;12406:25:1;-1:-1:-1;12450:50:1;12496:2;12481:18;;12450:50;:::i;:::-;12440:60;;12519:51;12565:3;12554:9;12550:19;12519:51;:::i;:::-;12509:61;;12589:51;12635:3;12624:9;12620:19;12589:51;:::i;:::-;12579:61;;12166:480;;;;;;;;:::o;12651:1000::-;;;;;;;;12935:3;12923:9;12914:7;12910:23;12906:33;12903:2;;;12957:6;12949;12942:22;12903:2;13002:9;12989:23;13035:18;13027:6;13024:30;13021:2;;;13072:6;13064;13057:22;13021:2;13100:86;13178:7;13169:6;13158:9;13154:22;13100:86;:::i;:::-;13090:96;;;13236:2;13225:9;13221:18;13208:32;13249:33;13276:5;13249:33;:::i;:::-;13301:5;-1:-1:-1;13358:2:1;13343:18;;13330:32;13371:35;13330:32;13371:35;:::i;:::-;13425:7;-1:-1:-1;13479:2:1;13464:18;;13451:32;;-1:-1:-1;13530:3:1;13515:19;;13502:33;;-1:-1:-1;13582:3:1;13567:19;;13554:33;;-1:-1:-1;13606:39:1;13640:3;13625:19;;13606:39;:::i;13656:931::-;;;;;;;13923:3;13911:9;13902:7;13898:23;13894:33;13891:2;;;13945:6;13937;13930:22;13891:2;13990:9;13977:23;14023:18;14015:6;14012:30;14009:2;;;14060:6;14052;14045:22;14009:2;14088:86;14166:7;14157:6;14146:9;14142:22;14088:86;:::i;:::-;14078:96;;;14224:2;14213:9;14209:18;14196:32;14237:33;14264:5;14237:33;:::i;:::-;14289:5;-1:-1:-1;14346:2:1;14331:18;;14318:32;14359:35;14318:32;14359:35;:::i;:::-;14413:7;-1:-1:-1;14467:2:1;14452:18;;14439:32;;-1:-1:-1;14518:3:1;14503:19;;14490:33;;-1:-1:-1;14542:39:1;14576:3;14561:19;;14542:39;:::i;14592:943::-;;14718:2;14761;14749:9;14740:7;14736:23;14732:32;14729:2;;;14782:6;14774;14767:22;14729:2;14820:9;14814:16;14853:18;14845:6;14842:30;14839:2;;;14890:6;14882;14875:22;14839:2;14918:22;;14971:4;14963:13;;14959:27;-1:-1:-1;14949:2:1;;15005:6;14997;14990:22;14949:2;15039;15033:9;15062:65;15077:49;15123:2;15077:49;:::i;15062:65::-;15161:15;;;15192:12;;;;15224:11;;;15262;;;15254:20;;15250:29;;15247:42;-1:-1:-1;15244:2:1;;;15307:6;15299;15292:22;15244:2;15334:6;15325:15;;15349:156;15363:2;15360:1;15357:9;15349:156;;;15420:10;;15408:23;;15381:1;15374:9;;;;;15451:12;;;;15483;;15349:156;;15540:257;;15660:2;15648:9;15639:7;15635:23;15631:32;15628:2;;;15681:6;15673;15666:22;15628:2;15718:9;15712:16;15737:30;15761:5;15737:30;:::i;15802:194::-;;15925:2;15913:9;15904:7;15900:23;15896:32;15893:2;;;15946:6;15938;15931:22;15893:2;-1:-1:-1;15974:16:1;;15883:113;-1:-1:-1;15883:113:1:o;16001:255::-;;;16141:2;16129:9;16120:7;16116:23;16112:32;16109:2;;;16162:6;16154;16147:22;16109:2;-1:-1:-1;;16190:16:1;;16246:2;16231:18;;;16225:25;16190:16;;16225:25;;-1:-1:-1;16099:157:1:o;16261:318::-;;16342:5;16336:12;16369:6;16364:3;16357:19;16385:63;16441:6;16434:4;16429:3;16425:14;16418:4;16411:5;16407:16;16385:63;:::i;:::-;16493:2;16481:15;16498:66;16477:88;16468:98;;;;16568:4;16464:109;;16312:267;-1:-1:-1;;16312:267:1:o;16584:274::-;;16751:6;16745:13;16767:53;16813:6;16808:3;16801:4;16793:6;16789:17;16767:53;:::i;:::-;16836:16;;;;;16721:137;-1:-1:-1;;16721:137:1:o;16863:226::-;17039:42;17027:55;;;;17009:74;;16997:2;16982:18;;16964:125::o;17333:305::-;17545:42;17533:55;;;;17515:74;;17620:2;17605:18;;17598:34;17503:2;17488:18;;17470:168::o;17643:407::-;17855:42;17924:15;;;17906:34;;17976:15;;;17971:2;17956:18;;17949:43;18028:15;;;18023:2;18008:18;;18001:43;17833:2;17818:18;;17800:250::o;18055:1069::-;;18367:3;18356:9;18352:19;18390:42;18471:2;18463:6;18459:15;18448:9;18441:34;18494:2;18544;18536:6;18532:15;18527:2;18516:9;18512:18;18505:43;18596:2;18588:6;18584:15;18579:2;18568:9;18564:18;18557:43;18636:6;18631:2;18620:9;18616:18;18609:34;18680:3;18674;18663:9;18659:19;18652:32;18704:6;18734;18726;18719:22;18772:3;18761:9;18757:19;18750:26;;18799:6;18785:20;;18823:4;18836:262;18850:6;18847:1;18844:13;18836:262;;;18925:6;18912:20;18945:33;18972:5;18945:33;:::i;:::-;19003:14;;18991:27;;19073:15;;;;19038:12;;;;18872:1;18865:9;18836:262;;;-1:-1:-1;19115:3:1;18328:796;-1:-1:-1;;;;;;;;;;;18328:796:1:o;19129:1020::-;;19431:3;19420:9;19416:19;19454:42;19535:2;19527:6;19523:15;19512:9;19505:34;19558:2;19608;19600:6;19596:15;19591:2;19580:9;19576:18;19569:43;19660:2;19652:6;19648:15;19643:2;19632:9;19628:18;19621:43;19700:6;19695:2;19684:9;19680:18;19673:34;19744:3;19738;19727:9;19723:19;19716:32;19768:6;19803;19797:13;19834:6;19826;19819:22;19872:3;19861:9;19857:19;19850:26;;19911:2;19903:6;19899:15;19885:29;;19932:4;19945:178;19959:6;19956:1;19953:13;19945:178;;;20024:13;;20020:22;;20008:35;;20098:15;;;;20063:12;;;;19981:1;19974:9;19945:178;;;-1:-1:-1;20140:3:1;;19392:757;-1:-1:-1;;;;;;;;;;;19392:757:1:o;20154:398::-;20366:42;20435:15;;;20417:34;;20487:15;;;;20482:2;20467:18;;20460:43;20534:2;20519:18;;20512:34;;;;20344:2;20329:18;;20311:241::o;20859:542::-;21128:42;21197:15;;;21179:34;;21244:2;21229:18;;21222:34;;;;21292:15;;;;21287:2;21272:18;;21265:43;21339:2;21324:18;;21317:34;;;;21382:3;21367:19;;21360:35;;;;21105:3;21090:19;;21072:329::o;21406:635::-;21577:2;21629:21;;;21699:13;;21602:18;;;21721:22;;;21406:635;;21577:2;21800:15;;;;21774:2;21759:18;;;21406:635;21846:169;21860:6;21857:1;21854:13;21846:169;;;21921:13;;21909:26;;21990:15;;;;21955:12;;;;21882:1;21875:9;21846:169;;;-1:-1:-1;22032:3:1;;21557:484;-1:-1:-1;;;;;;21557:484:1:o;22299:345::-;22501:2;22483:21;;;22540:2;22520:18;;;22513:30;22579:23;22574:2;22559:18;;22552:51;22635:2;22620:18;;22473:171::o;22649:355::-;22851:2;22833:21;;;22890:2;22870:18;;;22863:30;22929:33;22924:2;22909:18;;22902:61;22995:2;22980:18;;22823:181::o;23009:342::-;23211:2;23193:21;;;23250:2;23230:18;;;23223:30;23289:20;23284:2;23269:18;;23262:48;23342:2;23327:18;;23183:168::o;23356:354::-;23558:2;23540:21;;;23597:2;23577:18;;;23570:30;23636:32;23631:2;23616:18;;23609:60;23701:2;23686:18;;23530:180::o;23715:353::-;23917:2;23899:21;;;23956:2;23936:18;;;23929:30;23995:31;23990:2;23975:18;;23968:59;24059:2;24044:18;;23889:179::o;24073:344::-;24275:2;24257:21;;;24314:2;24294:18;;;24287:30;24353:22;24348:2;24333:18;;24326:50;24408:2;24393:18;;24247:170::o;24422:354::-;24624:2;24606:21;;;24663:2;24643:18;;;24636:30;24702:32;24697:2;24682:18;;24675:60;24767:2;24752:18;;24596:180::o;24781:353::-;24983:2;24965:21;;;25022:2;25002:18;;;24995:30;25061:31;25056:2;25041:18;;25034:59;25125:2;25110:18;;24955:179::o;25139:337::-;25341:2;25323:21;;;25380:2;25360:18;;;25353:30;25419:15;25414:2;25399:18;;25392:43;25467:2;25452:18;;25313:163::o;25481:336::-;25683:2;25665:21;;;25722:2;25702:18;;;25695:30;25761:14;25756:2;25741:18;;25734:42;25808:2;25793:18;;25655:162::o;25822:339::-;26024:2;26006:21;;;26063:2;26043:18;;;26036:30;26102:17;26097:2;26082:18;;26075:45;26152:2;26137:18;;25996:165::o;26166:398::-;26368:2;26350:21;;;26407:2;26387:18;;;26380:30;26446:34;26441:2;26426:18;;26419:62;26517:4;26512:2;26497:18;;26490:32;26554:3;26539:19;;26340:224::o;26569:399::-;26771:2;26753:21;;;26810:2;26790:18;;;26783:30;26849:34;26844:2;26829:18;;26822:62;26920:5;26915:2;26900:18;;26893:33;26958:3;26943:19;;26743:225::o;26973:349::-;27175:2;27157:21;;;27214:2;27194:18;;;27187:30;27253:27;27248:2;27233:18;;27226:55;27313:2;27298:18;;27147:175::o;27327:400::-;27529:2;27511:21;;;27568:2;27548:18;;;27541:30;27607:34;27602:2;27587:18;;27580:62;27678:6;27673:2;27658:18;;27651:34;27717:3;27702:19;;27501:226::o;27732:344::-;27934:2;27916:21;;;27973:2;27953:18;;;27946:30;28012:22;28007:2;27992:18;;27985:50;28067:2;28052:18;;27906:170::o;28081:177::-;28227:25;;;28215:2;28200:18;;28182:76::o;28263:491::-;;28502:6;28491:9;28484:25;28545:6;28540:2;28529:9;28525:18;28518:34;28600:42;28592:6;28588:55;28583:2;28572:9;28568:18;28561:83;28680:3;28675:2;28664:9;28660:18;28653:31;28701:47;28743:3;28732:9;28728:19;28720:6;28701:47;:::i;:::-;28693:55;28474:280;-1:-1:-1;;;;;;28474:280:1:o;29247:319::-;29449:25;;;29505:2;29490:18;;29483:34;;;;29548:2;29533:18;;29526:34;29437:2;29422:18;;29404:162::o;29571:535::-;29858:25;;;29914:2;29899:18;;29892:34;;;;29957:2;29942:18;;29935:34;;;;30000:2;29985:18;;29978:34;30043:3;30028:19;;30021:35;30087:3;30072:19;;30065:35;29845:3;29830:19;;29812:294::o;30111:585::-;30392:25;;;30448:2;30433:18;;30426:34;;;;30491:2;30476:18;;30469:34;;;;30522:10;30568:15;;;30563:2;30548:18;;30541:43;30621:15;;;30615:3;30600:19;;30593:44;30674:15;30668:3;30653:19;;30646:44;30379:3;30364:19;;30346:350::o;30701:242::-;30771:2;30765:9;30801:17;;;30848:18;30833:34;;30869:22;;;30830:62;30827:2;;;30895:9;30827:2;30922;30915:22;30745:198;;-1:-1:-1;30745:198:1:o;30948:183::-;;31047:18;31039:6;31036:30;31033:2;;;31069:9;31033:2;-1:-1:-1;31120:4:1;31101:17;;;31097:28;;31023:108::o;31136:258::-;31208:1;31218:113;31232:6;31229:1;31226:13;31218:113;;;31308:11;;;31302:18;31289:11;;;31282:39;31254:2;31247:10;31218:113;;;31349:6;31346:1;31343:13;31340:2;;;31384:1;31375:6;31370:3;31366:16;31359:27;31340:2;;31189:205;;;:::o;31399:156::-;31487:42;31480:5;31476:54;31469:5;31466:65;31456:2;;31545:1;31542;31535:12;31456:2;31446:109;:::o;31560:120::-;31648:5;31641:13;31634:21;31627:5;31624:32;31614:2;;31670:1;31667;31660:12

Swarm Source

ipfs://63d97bcbfaaf0b3f28485c166961e5d48832981a9591fbce7cd716e6298301b3

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.