Contract 0x45f1a95a4d3f3836523f5c83673c797f4d4d263b 21

 
Txn Hash Method
Block
From
To
Value
0xc68f71c4f7aee539a80bf70b6c12c011e564afd00912e484cae2ade214d2764dAdd Liquidity132306992024-04-16 6:59:054 secs ago0x471891ec5962d4343f203b0ad923cb63211233c6 IN  Stargate: Router0 ETH0.0000039672370.018348254
0x4e727542021df4279cb1d164e5e0fbe543d17b009cfee3f3ade34b3f86b2261bAdd Liquidity132306922024-04-16 6:58:5118 secs ago0x6abb4716ac262d601a8d79cfb4a6b456e2475a88 IN  Stargate: Router0 ETH0.0000039174680.018109093
0x7cbf3b46968cdebd6421c713ad7d880537fbd58328d664e9ee11f70647bf204cAdd Liquidity132306832024-04-16 6:58:3336 secs ago0xb49754f852eb4baa44dbf6346383af1557163b66 IN  Stargate: Router0 ETH0.0000042438350.018181351
0x39493fdab3c31ada0dceaec022cd82cf735f2f43cdbdf840b80f8d430ecfdf82Instant Redeem L...132306772024-04-16 6:58:2148 secs ago0x504327ce5853a01f8db88d5dbb9dcc770d13efab IN  Stargate: Router0 ETH0.0000016606590.018218141
0x30adf6b1cda964f444855f3c80ae96cb250f605adf938df8469b9dc4d02decb1Add Liquidity132306732024-04-16 6:58:1356 secs ago0x2ec75915728238d4506f6fea6b23b543f05ba119 IN  Stargate: Router0 ETH0.0000041694950.016610453
0xd2504f4202a8aab294dc82fe6048c7a51d61d80296197777a4cae2c9b10985e2Add Liquidity132306652024-04-16 6:57:571 min ago0x858ec5f382386a5e99f6d6ce999a44adbd38f8c8 IN  Stargate: Router0 ETH0.0000041276010.018260997
0x66308bdc2370adbc93f985a4370a1626783a4c47126d112527395b81bfc2b995Swap132306622024-04-16 6:57:511 min ago0x92dd7adf4014df2049fa89ade7f2cf8b7d434ca3 IN  Stargate: Router0.000019573587443 ETH0.0000078318230.017606992
0xb611a4f857da2edd3b35b579e9c749d70bab5d97b157b51546bb0d74842b8f79Add Liquidity132306602024-04-16 6:57:471 min ago0x154fcbe302a264750b005217683b092a506c5ac9 IN  Stargate: Router0 ETH0.0000038210710.018287817
0x7c1f021895eaab96b1778735faa6f1705da69d4c6a47e955d99de3de08bde1e7Add Liquidity132306492024-04-16 6:57:251 min ago0x01fa4059786eb3d7c76d1b40cd6fd883e2b3b93f IN  Stargate: Router0 ETH0.0000041417270.018322904
0x344c6fcfd8c1c685e354e579d916238d919f74df042604bdff151f3f3849a35bInstant Redeem L...132306392024-04-16 6:57:052 mins ago0xecedd99f44df6cc72cd5bc2d5301bb35a3e4fd6b IN  Stargate: Router0 ETH0.0000017818590.0196
0x497ad6395527dc9d532423e655382f9ebde358b9fa91b2ed3ce76bf97f91be99Add Liquidity132306302024-04-16 6:56:472 mins ago0x2ad3ee8e12de7517a5dd67c7822661c1f1fdc12e IN  Stargate: Router0 ETH0.0000041154360.01850067
0xe6b029cc18ca9c12cff061e188ba4648cc7cf9353a1f2d11b1e3df91ba416d10Swap132306272024-04-16 6:56:412 mins ago0x4a18454fd4a561b6d9f488195db5c29e74fb3323 IN  Stargate: Router0.000112327298101 ETH0.0000079744150.016974601
0x81583fe06206066dcd3e298aa15864f69c03df20f55d58c10a70165e1ef233adInstant Redeem L...132306222024-04-16 6:56:312 mins ago0xf92c56ca2ddcec205f9cccbee9e3d7efe39b0deb IN  Stargate: Router0 ETH0.0000016951470.018613238
0xc1c4adb4fa1e7605fbf3e124f1c80513398b8637ef0e6f9ddcc54a34a21c4434Instant Redeem L...132306132024-04-16 6:56:132 mins ago0x926d0334139df12368a78883a7b21a8759339872 IN  Stargate: Router0 ETH0.0000019162660.018816704
0x1c46a4a38f937722189ab779d5c653fbfa806c85276c09e5b6c125eec85c9e6eInstant Redeem L...132306052024-04-16 6:55:573 mins ago0x23165f6175d62ef697ea86bf44ae390fa11ea105 IN  Stargate: Router0 ETH0.0000019312680.018952971
0x72bd25bfb0f27f62b66ad609bf861bfaccf731521ed61a6bb7fe8b5ecb613e48Add Liquidity132306052024-04-16 6:55:573 mins ago0x4ca1e7c7f825a1ce905be239fc56cdc49776073c IN  Stargate: Router0 ETH0.0000043798780.018952971
0x750edb7310e2003e541ca5e6d5e2cf06fc165a592f297207ca362d3c118859ebSwap132306012024-04-16 6:55:493 mins ago0x2a0da66fbff0853f3dc878db16f8ad0c3416c12d IN  Stargate: Router0.000176236541642 ETH0.0000102874440.023790332
0x52e8e901b28ae3b186ec3ac4c99abd01121191f8ec5f9ee5564223a098cef7f5Swap132305972024-04-16 6:55:413 mins ago0xa2f501ac3602e272810b902cd374928f5fd082a6 IN  Stargate: Router0.000303971885087 ETH0.0000103247670.024037018
0xca655d87feb63a6244d60521caccea1cee0b7599e45421bca874edd90226de0cAdd Liquidity132305952024-04-16 6:55:373 mins ago0xfa007de84af424c47b8aebfba4cf945242d24f6b IN  Stargate: Router0 ETH0.0000035891670.017382929
0xb7f60fe2cf2527577a8da55d95dc617027d8185489ce187c41fb0d06c0d1a6ffInstant Redeem L...132305902024-04-16 6:55:273 mins ago0xe23e29885d5f10a6eaa522c3b53fe89ce0fb432a IN  Stargate: Router0 ETH0.0000017425890.019119255
0x251c398cb8daa6a5a969dce98d68efd41fce3b1191cff5a1397719f4aea3e0d3Instant Redeem L...132305862024-04-16 6:55:193 mins ago0x5c15c44b1f8d030f581d85ec8cd1de2ce4ec910f IN  Stargate: Router0 ETH0.0000019542280.019206995
0xaa8770f1b8cdbdeb19c824434c2b34dc0baa288fe76f150dc46da7a0f36bf9eeAdd Liquidity132305852024-04-16 6:55:173 mins ago0x90860ebc989179e956cbf932192eaae7b49d419d IN  Stargate: Router0 ETH0.00000387460.019219667
0xad5b0350d75a0cdb0ed9ecd0126adedb8214d4d5d50f58095e20c4bac271f401Add Liquidity132305822024-04-16 6:55:113 mins ago0xfa007de84af424c47b8aebfba4cf945242d24f6b IN  Stargate: Router0 ETH0.0000037933240.017616497
0x087bc0d681ddcdb026c9b53710cea5d1e7a4b0041f54f214f605d31e81677ff4Swap132305712024-04-16 6:54:494 mins ago0x19b1144304c247eac979e67a2caeb9d927205f5d IN  Stargate: Router0.000126195084407 ETH0.000008795270.0205
0x46a65129519350bfd6ef29b747eb96b34c5052679b11279cb8a980b3b4ecf1e2Swap132305672024-04-16 6:54:414 mins ago0x6798bdd59395bbee8ac553c124c4a6d9a2483f2d IN  Stargate: Router0.000019573587443 ETH0.0000081045060.018660698
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x74bd46a16328a6b8b26ec6b5400610b980884d64a169b3bd544ae26ac77d1302132306992024-04-16 6:59:054 secs ago Stargate: Router Stargate: Bridge0.000112327298101279 ETH
0x74bd46a16328a6b8b26ec6b5400610b980884d64a169b3bd544ae26ac77d1302132306992024-04-16 6:59:054 secs ago Stargate: Router ETH Stargate: Router0.000112327298101279 ETH
0xef152642bf9dac6f9e3543f809e3576362e1fb497d4874bd476b37514a94f724132306962024-04-16 6:58:5910 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0xef152642bf9dac6f9e3543f809e3576362e1fb497d4874bd476b37514a94f724132306962024-04-16 6:58:5910 secs ago Stargate Finance: Composer Stargate: Router0.000098508689943792 ETH
0x26075c126a64a74acba715f09aab23cc5531d84237a25171f77bb3f9ccfd73f0132306952024-04-16 6:58:5712 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0x26075c126a64a74acba715f09aab23cc5531d84237a25171f77bb3f9ccfd73f0132306952024-04-16 6:58:5712 secs ago Stargate: Router ETH Stargate: Router0.000098508689943792 ETH
0x61347cca960f8069fae0367c4be300e6ac5551ea8ce341e86d816289016525eb132306952024-04-16 6:58:5712 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0x61347cca960f8069fae0367c4be300e6ac5551ea8ce341e86d816289016525eb132306952024-04-16 6:58:5712 secs ago Stargate: Router ETH Stargate: Router0.000098508689943792 ETH
0x0fcd092002a42887064782264c1fba6988366db3a75b64fd4ba8666e807bfeca132306942024-04-16 6:58:5514 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0x0fcd092002a42887064782264c1fba6988366db3a75b64fd4ba8666e807bfeca132306942024-04-16 6:58:5514 secs ago Stargate Finance: Composer Stargate: Router0.000098508689943792 ETH
0xe542720e1019246f8a57cad16380488d1825d79289883255feee8c545c4e8312132306942024-04-16 6:58:5514 secs ago Stargate: Router Stargate: Bridge0.000112327298101279 ETH
0xe542720e1019246f8a57cad16380488d1825d79289883255feee8c545c4e8312132306942024-04-16 6:58:5514 secs ago Stargate: Router ETH Stargate: Router0.000112327298101279 ETH
0xdd626168c25550fcc48a6f729cbc018a584bfd60bf7a2b79e428590f18b6b890132306942024-04-16 6:58:5514 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0xdd626168c25550fcc48a6f729cbc018a584bfd60bf7a2b79e428590f18b6b890132306942024-04-16 6:58:5514 secs ago Stargate: Router ETH Stargate: Router0.000098508689943792 ETH
0x4725ebbf72f676083dd5475621f47d2e4cda4616b0d6520315373bd4feb3f1f3132306932024-04-16 6:58:5316 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0x4725ebbf72f676083dd5475621f47d2e4cda4616b0d6520315373bd4feb3f1f3132306932024-04-16 6:58:5316 secs ago Stargate: Router ETH Stargate: Router0.000098508689943792 ETH
0xb3bd613a99dd62bd48d3e3939984c7219151e444a7efb08fbd8d75a358a0217d132306932024-04-16 6:58:5316 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0xb3bd613a99dd62bd48d3e3939984c7219151e444a7efb08fbd8d75a358a0217d132306932024-04-16 6:58:5316 secs ago Stargate Finance: Composer Stargate: Router0.000098508689943792 ETH
0xbb0fc28d1042062752875636cf2bbe7d4f353e8341587ae7ad7f8332a86a58e6132306902024-04-16 6:58:4722 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
0xbb0fc28d1042062752875636cf2bbe7d4f353e8341587ae7ad7f8332a86a58e6132306902024-04-16 6:58:4722 secs ago Stargate: Router ETH Stargate: Router0.000098508689943792 ETH
0x99b34108a42b6d69850f280835c23d7e3a8065e6d9649938eb8e0b45cac762be132306902024-04-16 6:58:4722 secs ago Stargate: Router Stargate: Bridge0.000019573587443843 ETH
0x99b34108a42b6d69850f280835c23d7e3a8065e6d9649938eb8e0b45cac762be132306902024-04-16 6:58:4722 secs ago Stargate: Router ETH Stargate: Router0.000019573587443843 ETH
0x42c7b1dd061b71d97bd9f6a0773e1eaa12e4920c7d369083366de9412fc7f832132306892024-04-16 6:58:4524 secs ago Stargate: Router Stargate: Bridge0.000019573587443843 ETH
0x42c7b1dd061b71d97bd9f6a0773e1eaa12e4920c7d369083366de9412fc7f832132306892024-04-16 6:58:4524 secs ago Stargate: Router ETH Stargate: Router0.000019573587443843 ETH
0x7710d11007a7c7d7c1de6dc814e3e922ff0dd84853940c454435beb1d96e2376132306872024-04-16 6:58:4128 secs ago Stargate: Router Stargate: Bridge0.000098508689943792 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Router

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, BSL 1.1 license
File 1 of 17 : Router.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;
pragma abicoder v2;

// imports
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./Factory.sol";
import "./Pool.sol";
import "./Bridge.sol";

// interfaces
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interfaces/IStargateRouter.sol";
import "./interfaces/IStargateReceiver.sol";

// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";

contract Router is IStargateRouter, Ownable, ReentrancyGuard {
    using SafeMath for uint256;

    //---------------------------------------------------------------------------
    // CONSTANTS
    uint8 internal constant TYPE_REDEEM_LOCAL_RESPONSE = 1;
    uint8 internal constant TYPE_REDEEM_LOCAL_CALLBACK_RETRY = 2;
    uint8 internal constant TYPE_SWAP_REMOTE_RETRY = 3;

    //---------------------------------------------------------------------------
    // STRUCTS
    struct CachedSwap {
        address token;
        uint256 amountLD;
        address to;
        bytes payload;
    }

    //---------------------------------------------------------------------------
    // VARIABLES
    Factory public factory; // used for creating pools
    address public protocolFeeOwner; // can call methods to pull Stargate fees collected in pools
    address public mintFeeOwner; // can call methods to pull mint fees collected in pools
    Bridge public bridge;
    mapping(uint16 => mapping(bytes => mapping(uint256 => bytes))) public revertLookup; //[chainId][srcAddress][nonce]
    mapping(uint16 => mapping(bytes => mapping(uint256 => CachedSwap))) public cachedSwapLookup; //[chainId][srcAddress][nonce]

    //---------------------------------------------------------------------------
    // EVENTS
    event Revert(uint8 bridgeFunctionType, uint16 chainId, bytes srcAddress, uint256 nonce);
    event CachedSwapSaved(
        uint16 chainId,
        bytes srcAddress,
        uint256 nonce,
        address token,
        uint256 amountLD,
        address to,
        bytes payload,
        bytes reason
    );
    event RevertRedeemLocal(
        uint16 srcChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        bytes to,
        uint256 redeemAmountSD,
        uint256 mintAmountSD,
        uint256 indexed nonce,
        bytes indexed srcAddress
    );
    event RedeemLocalCallback(
        uint16 srcChainId,
        bytes indexed srcAddress,
        uint256 indexed nonce,
        uint256 srcPoolId,
        uint256 dstPoolId,
        address to,
        uint256 amountSD,
        uint256 mintAmountSD
    );

    //---------------------------------------------------------------------------
    // MODIFIERS
    modifier onlyBridge() {
        require(msg.sender == address(bridge), "Bridge: caller must be Bridge.");
        _;
    }

    constructor() {}

    function setBridgeAndFactory(Bridge _bridge, Factory _factory) external onlyOwner {
        require(address(bridge) == address(0x0) && address(factory) == address(0x0), "Stargate: bridge and factory already initialized"); // 1 time only
        require(address(_bridge) != address(0x0), "Stargate: bridge cant be 0x0");
        require(address(_factory) != address(0x0), "Stargate: factory cant be 0x0");

        bridge = _bridge;
        factory = _factory;
    }

    //---------------------------------------------------------------------------
    // VIEWS
    function _getPool(uint256 _poolId) internal view returns (Pool pool) {
        pool = factory.getPool(_poolId);
        require(address(pool) != address(0x0), "Stargate: Pool does not exist");
    }

    //---------------------------------------------------------------------------
    // INTERNAL
    function _safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) private {
        // 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))), "Stargate: TRANSFER_FROM_FAILED");
    }

    //---------------------------------------------------------------------------
    // LOCAL CHAIN FUNCTIONS
    function addLiquidity(
        uint256 _poolId,
        uint256 _amountLD,
        address _to
    ) external override nonReentrant {
        Pool pool = _getPool(_poolId);
        uint256 convertRate = pool.convertRate();
        _amountLD = _amountLD.div(convertRate).mul(convertRate);
        _safeTransferFrom(pool.token(), msg.sender, address(pool), _amountLD);
        pool.mint(_to, _amountLD);
    }

    function swap(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        uint256 _amountLD,
        uint256 _minAmountLD,
        lzTxObj memory _lzTxParams,
        bytes calldata _to,
        bytes calldata _payload
    ) external payable override nonReentrant {
        require(_amountLD > 0, "Stargate: cannot swap 0");
        require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
        Pool.SwapObj memory s;
        Pool.CreditObj memory c;
        {
            Pool pool = _getPool(_srcPoolId);
            {
                uint256 convertRate = pool.convertRate();
                _amountLD = _amountLD.div(convertRate).mul(convertRate);
            }

            s = pool.swap(_dstChainId, _dstPoolId, msg.sender, _amountLD, _minAmountLD, true);
            _safeTransferFrom(pool.token(), msg.sender, address(pool), _amountLD);
            c = pool.sendCredits(_dstChainId, _dstPoolId);
        }
        bridge.swap{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, s, _lzTxParams, _to, _payload);
    }

    function redeemRemote(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        uint256 _amountLP,
        uint256 _minAmountLD,
        bytes calldata _to,
        lzTxObj memory _lzTxParams
    ) external payable override nonReentrant {
        require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
        require(_amountLP > 0, "Stargate: not enough lp to redeemRemote");
        Pool.SwapObj memory s;
        Pool.CreditObj memory c;
        {
            Pool pool = _getPool(_srcPoolId);
            uint256 amountLD = pool.amountLPtoLD(_amountLP);
            // perform a swap with no liquidity
            s = pool.swap(_dstChainId, _dstPoolId, msg.sender, amountLD, _minAmountLD, false);
            pool.redeemRemote(_dstChainId, _dstPoolId, msg.sender, _amountLP);
            c = pool.sendCredits(_dstChainId, _dstPoolId);
        }
        // equal to a swap, with no payload ("0x") no dstGasForCall 0
        bridge.swap{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, s, _lzTxParams, _to, "");
    }

    function instantRedeemLocal(
        uint16 _srcPoolId,
        uint256 _amountLP,
        address _to
    ) external override nonReentrant returns (uint256 amountSD) {
        require(_amountLP > 0, "Stargate: not enough lp to redeem");
        Pool pool = _getPool(_srcPoolId);
        amountSD = pool.instantRedeemLocal(msg.sender, _amountLP, _to);
    }

    function redeemLocal(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        uint256 _amountLP,
        bytes calldata _to,
        lzTxObj memory _lzTxParams
    ) external payable override nonReentrant {
        require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
        Pool pool = _getPool(_srcPoolId);
        require(_amountLP > 0, "Stargate: not enough lp to redeem");
        uint256 amountSD = pool.redeemLocal(msg.sender, _amountLP, _dstChainId, _dstPoolId, _to);
        require(amountSD > 0, "Stargate: not enough lp to redeem with amountSD");

        Pool.CreditObj memory c = pool.sendCredits(_dstChainId, _dstPoolId);
        bridge.redeemLocal{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c, amountSD, _to, _lzTxParams);
    }

    function sendCredits(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress
    ) external payable override nonReentrant {
        require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
        Pool pool = _getPool(_srcPoolId);
        Pool.CreditObj memory c = pool.sendCredits(_dstChainId, _dstPoolId);
        bridge.sendCredits{value: msg.value}(_dstChainId, _srcPoolId, _dstPoolId, _refundAddress, c);
    }

    function quoteLayerZeroFee(
        uint16 _dstChainId,
        uint8 _functionType,
        bytes calldata _toAddress,
        bytes calldata _transferAndCallPayload,
        Router.lzTxObj memory _lzTxParams
    ) external view override returns (uint256, uint256) {
        return bridge.quoteLayerZeroFee(_dstChainId, _functionType, _toAddress, _transferAndCallPayload, _lzTxParams);
    }

    function revertRedeemLocal(
        uint16 _dstChainId,
        bytes calldata _srcAddress,
        uint256 _nonce,
        address payable _refundAddress,
        lzTxObj memory _lzTxParams
    ) external payable {
        require(_refundAddress != address(0x0), "Stargate: _refundAddress cannot be 0x0");
        bytes memory payload = revertLookup[_dstChainId][_srcAddress][_nonce];
        require(payload.length > 0, "Stargate: no retry revert");
        {
            uint8 functionType;
            assembly {
                functionType := mload(add(payload, 32))
            }
            require(functionType == TYPE_REDEEM_LOCAL_RESPONSE, "Stargate: invalid function type");
        }

        // empty it
        revertLookup[_dstChainId][_srcAddress][_nonce] = "";

        uint256 srcPoolId;
        uint256 dstPoolId;
        assembly {
            srcPoolId := mload(add(payload, 64))
            dstPoolId := mload(add(payload, 96))
        }

        Pool.CreditObj memory c;
        {
            Pool pool = _getPool(dstPoolId);
            c = pool.sendCredits(_dstChainId, srcPoolId);
        }

        bridge.redeemLocalCallback{value: msg.value}(_dstChainId, _refundAddress, c, _lzTxParams, payload);
    }

    function retryRevert(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        uint256 _nonce
    ) external payable {
        bytes memory payload = revertLookup[_srcChainId][_srcAddress][_nonce];
        require(payload.length > 0, "Stargate: no retry revert");

        // empty it
        revertLookup[_srcChainId][_srcAddress][_nonce] = "";

        uint8 functionType;
        assembly {
            functionType := mload(add(payload, 32))
        }

        if (functionType == TYPE_REDEEM_LOCAL_CALLBACK_RETRY) {
            (, uint256 srcPoolId, uint256 dstPoolId, address to, uint256 amountSD, uint256 mintAmountSD) = abi.decode(
                payload,
                (uint8, uint256, uint256, address, uint256, uint256)
            );
            _redeemLocalCallback(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, to, amountSD, mintAmountSD);
        }
        // for retrying the swapRemote. if it fails again, retry
        else if (functionType == TYPE_SWAP_REMOTE_RETRY) {
            (, uint256 srcPoolId, uint256 dstPoolId, uint256 dstGasForCall, address to, Pool.SwapObj memory s, bytes memory p) = abi.decode(
                payload,
                (uint8, uint256, uint256, uint256, address, Pool.SwapObj, bytes)
            );
            _swapRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, dstGasForCall, to, s, p);
        } else {
            revert("Stargate: invalid function type");
        }
    }

    function clearCachedSwap(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        uint256 _nonce
    ) external {
        CachedSwap memory cs = cachedSwapLookup[_srcChainId][_srcAddress][_nonce];
        require(cs.to != address(0x0), "Stargate: cache already cleared");
        // clear the data
        cachedSwapLookup[_srcChainId][_srcAddress][_nonce] = CachedSwap(address(0x0), 0, address(0x0), "");
        IStargateReceiver(cs.to).sgReceive(_srcChainId, _srcAddress, _nonce, cs.token, cs.amountLD, cs.payload);
    }

    function creditChainPath(
        uint16 _dstChainId,
        uint256 _dstPoolId,
        uint256 _srcPoolId,
        Pool.CreditObj memory _c
    ) external onlyBridge {
        Pool pool = _getPool(_srcPoolId);
        pool.creditChainPath(_dstChainId, _dstPoolId, _c);
    }

    //---------------------------------------------------------------------------
    // REMOTE CHAIN FUNCTIONS
    function redeemLocalCheckOnRemote(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint256 _nonce,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        uint256 _amountSD,
        bytes calldata _to
    ) external onlyBridge {
        Pool pool = _getPool(_dstPoolId);
        try pool.redeemLocalCheckOnRemote(_srcChainId, _srcPoolId, _amountSD) returns (uint256 redeemAmountSD, uint256 mintAmountSD) {
            revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(
                TYPE_REDEEM_LOCAL_RESPONSE,
                _srcPoolId,
                _dstPoolId,
                redeemAmountSD,
                mintAmountSD,
                _to
            );
            emit RevertRedeemLocal(_srcChainId, _srcPoolId, _dstPoolId, _to, redeemAmountSD, mintAmountSD, _nonce, _srcAddress);
        } catch {
            // if the func fail, return [swapAmount: 0, mintAMount: _amountSD]
            // swapAmount represents the amount of chainPath balance deducted on the remote side, which because the above tx failed, should be 0
            // mintAmount is the full amount of tokens the user attempted to redeem on the src side, which gets converted back into the lp amount
            revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(TYPE_REDEEM_LOCAL_RESPONSE, _srcPoolId, _dstPoolId, 0, _amountSD, _to);
            emit Revert(TYPE_REDEEM_LOCAL_RESPONSE, _srcChainId, _srcAddress, _nonce);
        }
    }

    function redeemLocalCallback(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint256 _nonce,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address _to,
        uint256 _amountSD,
        uint256 _mintAmountSD
    ) external onlyBridge {
        _redeemLocalCallback(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _to, _amountSD, _mintAmountSD);
    }

    function _redeemLocalCallback(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint256 _nonce,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address _to,
        uint256 _amountSD,
        uint256 _mintAmountSD
    ) internal {
        Pool pool = _getPool(_dstPoolId);
        try pool.redeemLocalCallback(_srcChainId, _srcPoolId, _to, _amountSD, _mintAmountSD) {} catch {
            revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(
                TYPE_REDEEM_LOCAL_CALLBACK_RETRY,
                _srcPoolId,
                _dstPoolId,
                _to,
                _amountSD,
                _mintAmountSD
            );
            emit Revert(TYPE_REDEEM_LOCAL_CALLBACK_RETRY, _srcChainId, _srcAddress, _nonce);
        }
        emit RedeemLocalCallback(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _to, _amountSD, _mintAmountSD);
    }

    function swapRemote(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint256 _nonce,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        uint256 _dstGasForCall,
        address _to,
        Pool.SwapObj memory _s,
        bytes memory _payload
    ) external onlyBridge {
        _swapRemote(_srcChainId, _srcAddress, _nonce, _srcPoolId, _dstPoolId, _dstGasForCall, _to, _s, _payload);
    }

    function _swapRemote(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint256 _nonce,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        uint256 _dstGasForCall,
        address _to,
        Pool.SwapObj memory _s,
        bytes memory _payload
    ) internal {
        Pool pool = _getPool(_dstPoolId);
        // first try catch the swap remote
        try pool.swapRemote(_srcChainId, _srcPoolId, _to, _s) returns (uint256 amountLD) {
            if (Address.isContract(_to) && _payload.length > 0) {
                // then try catch the external contract call
                try IStargateReceiver(_to).sgReceive{gas: _dstGasForCall}(_srcChainId, _srcAddress, _nonce, pool.token(), amountLD, _payload) {
                    // do nothing
                } catch (bytes memory reason) {
                    cachedSwapLookup[_srcChainId][_srcAddress][_nonce] = CachedSwap(pool.token(), amountLD, _to, _payload);
                    emit CachedSwapSaved(_srcChainId, _srcAddress, _nonce, pool.token(), amountLD, _to, _payload, reason);
                }
            }
        } catch {
            revertLookup[_srcChainId][_srcAddress][_nonce] = abi.encode(
                TYPE_SWAP_REMOTE_RETRY,
                _srcPoolId,
                _dstPoolId,
                _dstGasForCall,
                _to,
                _s,
                _payload
            );
            emit Revert(TYPE_SWAP_REMOTE_RETRY, _srcChainId, _srcAddress, _nonce);
        }
    }

    //---------------------------------------------------------------------------
    // DAO Calls
    function createPool(
        uint256 _poolId,
        address _token,
        uint8 _sharedDecimals,
        uint8 _localDecimals,
        string memory _name,
        string memory _symbol
    ) external onlyOwner returns (address) {
        require(_token != address(0x0), "Stargate: _token cannot be 0x0");
        return factory.createPool(_poolId, _token, _sharedDecimals, _localDecimals, _name, _symbol);
    }

    function createChainPath(
        uint256 _poolId,
        uint16 _dstChainId,
        uint256 _dstPoolId,
        uint256 _weight
    ) external onlyOwner {
        Pool pool = _getPool(_poolId);
        pool.createChainPath(_dstChainId, _dstPoolId, _weight);
    }

    function activateChainPath(
        uint256 _poolId,
        uint16 _dstChainId,
        uint256 _dstPoolId
    ) external onlyOwner {
        Pool pool = _getPool(_poolId);
        pool.activateChainPath(_dstChainId, _dstPoolId);
    }

    function setWeightForChainPath(
        uint256 _poolId,
        uint16 _dstChainId,
        uint256 _dstPoolId,
        uint16 _weight
    ) external onlyOwner {
        Pool pool = _getPool(_poolId);
        pool.setWeightForChainPath(_dstChainId, _dstPoolId, _weight);
    }

    function setProtocolFeeOwner(address _owner) external onlyOwner {
        require(_owner != address(0x0), "Stargate: _owner cannot be 0x0");
        protocolFeeOwner = _owner;
    }

    function setMintFeeOwner(address _owner) external onlyOwner {
        require(_owner != address(0x0), "Stargate: _owner cannot be 0x0");
        mintFeeOwner = _owner;
    }

    function setFees(uint256 _poolId, uint256 _mintFeeBP) external onlyOwner {
        Pool pool = _getPool(_poolId);
        pool.setFee(_mintFeeBP);
    }

    function setFeeLibrary(uint256 _poolId, address _feeLibraryAddr) external onlyOwner {
        Pool pool = _getPool(_poolId);
        pool.setFeeLibrary(_feeLibraryAddr);
    }

    function setSwapStop(uint256 _poolId, bool _swapStop) external onlyOwner {
        Pool pool = _getPool(_poolId);
        pool.setSwapStop(_swapStop);
    }

    function setDeltaParam(
        uint256 _poolId,
        bool _batched,
        uint256 _swapDeltaBP,
        uint256 _lpDeltaBP,
        bool _defaultSwapMode,
        bool _defaultLPMode
    ) external onlyOwner {
        Pool pool = _getPool(_poolId);
        pool.setDeltaParam(_batched, _swapDeltaBP, _lpDeltaBP, _defaultSwapMode, _defaultLPMode);
    }

    function callDelta(uint256 _poolId, bool _fullMode) external {
        Pool pool = _getPool(_poolId);
        pool.callDelta(_fullMode);
    }

    function withdrawMintFee(uint256 _poolId, address _to) external {
        require(mintFeeOwner == msg.sender, "Stargate: only mintFeeOwner");
        Pool pool = _getPool(_poolId);
        pool.withdrawMintFeeBalance(_to);
    }

    function withdrawProtocolFee(uint256 _poolId, address _to) external {
        require(protocolFeeOwner == msg.sender, "Stargate: only protocolFeeOwner");
        Pool pool = _getPool(_poolId);
        pool.withdrawProtocolFeeBalance(_to);
    }
}

File 2 of 17 : ILayerZeroReceiver.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity >=0.5.0;

interface ILayerZeroReceiver {
    // @notice LayerZero endpoint will invoke this function to deliver the message on the destination
    // @param _srcChainId - the source endpoint identifier
    // @param _srcAddress - the source sending contract address from the source chain
    // @param _nonce - the ordered message nonce
    // @param _payload - the signed payload is the UA bytes has encoded to be sent
    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
}

File 3 of 17 : ILayerZeroEndpoint.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity >=0.5.0;

import "./ILayerZeroUserApplicationConfig.sol";

interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
    // @notice send a LayerZero message to the specified address at a LayerZero endpoint.
    // @param _dstChainId - the destination chain identifier
    // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
    // @param _payload - a custom bytes payload to send to the destination contract
    // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
    // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
    // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
    function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    // @notice used by the messaging library to publish verified payload
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source contract (as bytes) at the source chain
    // @param _dstAddress - the address on destination chain
    // @param _nonce - the unbound message ordering nonce
    // @param _gasLimit - the gas limit for external contract execution
    // @param _payload - verified payload to send to the destination contract
    function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external;

    // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);

    // @notice get the outboundNonce from this source chain which, consequently, is always an EVM
    // @param _srcAddress - the source chain contract address
    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);

    // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
    // @param _dstChainId - the destination chain identifier
    // @param _userApplication - the user app address on this EVM chain
    // @param _payload - the custom message to send over LayerZero
    // @param _payInZRO - if false, user app pays the protocol fee in native token
    // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
    function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee);

    // @notice get this Endpoint's immutable source identifier
    function getChainId() external view returns (uint16);

    // @notice the interface to retry failed message on this Endpoint destination
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    // @param _payload - the payload to be retried
    function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;

    // @notice query if any STORED payload (message blocking) at the endpoint.
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);

    // @notice query if the _libraryAddress is valid for sending msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getSendLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the _libraryAddress is valid for receiving msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getReceiveLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the non-reentrancy guard for send() is on
    // @return true if the guard is on. false otherwise
    function isSendingPayload() external view returns (bool);

    // @notice query if the non-reentrancy guard for receive() is on
    // @return true if the guard is on. false otherwise
    function isReceivingPayload() external view returns (bool);

    // @notice get the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _userApplication - the contract address of the user application
    // @param _configType - type of configuration. every messaging library has its own convention.
    function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory);

    // @notice get the send() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getSendVersion(address _userApplication) external view returns (uint16);

    // @notice get the lzReceive() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getReceiveVersion(address _userApplication) external view returns (uint16);
}

File 4 of 17 : ILayerZeroUserApplicationConfig.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity >=0.5.0;

interface ILayerZeroUserApplicationConfig {
    // @notice set the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _configType - type of configuration. every messaging library has its own convention.
    // @param _config - configuration in the bytes. can encode arbitrary content.
    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;

    // @notice set the send() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setSendVersion(uint16 _version) external;

    // @notice set the lzReceive() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setReceiveVersion(uint16 _version) external;

    // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
    // @param _srcChainId - the chainId of the source chain
    // @param _srcAddress - the contract address of the source contract at the source chain
    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}

File 5 of 17 : LPTokenERC20.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;

// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";

contract LPTokenERC20 {
    using SafeMath for uint256;

    //---------------------------------------------------------------------------
    // CONSTANTS
    string public name;
    string public symbol;
    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
    // set in constructor
    bytes32 public DOMAIN_SEPARATOR;

    //---------------------------------------------------------------------------
    // VARIABLES
    uint256 public decimals;
    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    mapping(address => uint256) public nonces;

    //---------------------------------------------------------------------------
    // EVENTS
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
        uint256 chainId;
        assembly {
            chainId := chainid()
        }
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                keccak256(bytes(name)),
                keccak256(bytes("1")),
                chainId,
                address(this)
            )
        );
    }

    function _mint(address to, uint256 value) internal {
        totalSupply = totalSupply.add(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(address(0), to, value);
    }

    function _burn(address from, uint256 value) internal {
        balanceOf[from] = balanceOf[from].sub(value);
        totalSupply = totalSupply.sub(value);
        emit Transfer(from, address(0), value);
    }

    function _approve(
        address owner,
        address spender,
        uint256 value
    ) private {
        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    function _transfer(
        address from,
        address to,
        uint256 value
    ) private {
        balanceOf[from] = balanceOf[from].sub(value);
        balanceOf[to] = balanceOf[to].add(value);
        emit Transfer(from, to, value);
    }

    function approve(address spender, uint256 value) external returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    function transfer(address to, uint256 value) external returns (bool) {
        _transfer(msg.sender, to, value);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool) {
        if (allowance[from][msg.sender] != uint256(-1)) {
            allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
        }
        _transfer(from, to, value);
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(msg.sender, spender, allowance[msg.sender][spender].add(addedValue));
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(msg.sender, spender, allowance[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        require(deadline >= block.timestamp, "Bridge: EXPIRED");
        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR,
                keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
            )
        );
        address recoveredAddress = ecrecover(digest, v, r, s);
        require(recoveredAddress != address(0) && recoveredAddress == owner, "Bridge: INVALID_SIGNATURE");
        _approve(owner, spender, value);
    }
}

File 6 of 17 : IStargateFeeLibrary.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.7.6;
pragma abicoder v2;
import "../Pool.sol";

interface IStargateFeeLibrary {
    function getFees(
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        uint16 _dstChainId,
        address _from,
        uint256 _amountSD
    ) external returns (Pool.SwapObj memory s);

    function getVersion() external view returns (string memory);
}

File 7 of 17 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 8 of 17 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

import "../utils/Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 9 of 17 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 10 of 17 : Factory.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;
pragma abicoder v2;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./Pool.sol";

contract Factory is Ownable {
    using SafeMath for uint256;

    //---------------------------------------------------------------------------
    // VARIABLES
    mapping(uint256 => Pool) public getPool; // poolId -> PoolInfo
    address[] public allPools;
    address public immutable router;
    address public defaultFeeLibrary; // address for retrieving fee params for swaps

    //---------------------------------------------------------------------------
    // MODIFIERS
    modifier onlyRouter() {
        require(msg.sender == router, "Stargate: caller must be Router.");
        _;
    }

    constructor(address _router) {
        require(_router != address(0x0), "Stargate: _router cant be 0x0"); // 1 time only
        router = _router;
    }

    function setDefaultFeeLibrary(address _defaultFeeLibrary) external onlyOwner {
        require(_defaultFeeLibrary != address(0x0), "Stargate: fee library cant be 0x0");
        defaultFeeLibrary = _defaultFeeLibrary;
    }

    function allPoolsLength() external view returns (uint256) {
        return allPools.length;
    }

    function createPool(
        uint256 _poolId,
        address _token,
        uint8 _sharedDecimals,
        uint8 _localDecimals,
        string memory _name,
        string memory _symbol
    ) public onlyRouter returns (address poolAddress) {
        require(address(getPool[_poolId]) == address(0x0), "Stargate: Pool already created");

        Pool pool = new Pool(_poolId, router, _token, _sharedDecimals, _localDecimals, defaultFeeLibrary, _name, _symbol);
        getPool[_poolId] = pool;
        poolAddress = address(pool);
        allPools.push(poolAddress);
    }

    function renounceOwnership() public override onlyOwner {}
}

File 11 of 17 : Pool.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;
pragma abicoder v2;

// imports
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./LPTokenERC20.sol";
import "./interfaces/IStargateFeeLibrary.sol";

// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";

/// Pool contracts on other chains and managed by the Stargate protocol.
contract Pool is LPTokenERC20, ReentrancyGuard {
    using SafeMath for uint256;

    //---------------------------------------------------------------------------
    // CONSTANTS
    bytes4 private constant SELECTOR = bytes4(keccak256(bytes("transfer(address,uint256)")));
    uint256 public constant BP_DENOMINATOR = 10000;

    //---------------------------------------------------------------------------
    // STRUCTS
    struct ChainPath {
        bool ready; // indicate if the counter chainPath has been created.
        uint16 dstChainId;
        uint256 dstPoolId;
        uint256 weight;
        uint256 balance;
        uint256 lkb;
        uint256 credits;
        uint256 idealBalance;
    }

    struct SwapObj {
        uint256 amount;
        uint256 eqFee;
        uint256 eqReward;
        uint256 lpFee;
        uint256 protocolFee;
        uint256 lkbRemove;
    }

    struct CreditObj {
        uint256 credits;
        uint256 idealBalance;
    }

    //---------------------------------------------------------------------------
    // VARIABLES

    // chainPath
    ChainPath[] public chainPaths; // list of connected chains with shared pools
    mapping(uint16 => mapping(uint256 => uint256)) public chainPathIndexLookup; // lookup for chainPath by chainId => poolId =>index

    // metadata
    uint256 public immutable poolId; // shared id between chains to represent same pool
    uint256 public sharedDecimals; // the shared decimals (lowest common decimals between chains)
    uint256 public localDecimals; // the decimals for the token
    uint256 public immutable convertRate; // the decimals for the token
    address public immutable token; // the token for the pool
    address public immutable router; // the token for the pool

    bool public stopSwap; // flag to stop swapping in extreme cases

    // Fee and Liquidity
    uint256 public totalLiquidity; // the total amount of tokens added on this side of the chain (fees + deposits - withdrawals)
    uint256 public totalWeight; // total weight for pool percentages
    uint256 public mintFeeBP; // fee basis points for the mint/deposit
    uint256 public protocolFeeBalance; // fee balance created from dao fee
    uint256 public mintFeeBalance; // fee balance created from mint fee
    uint256 public eqFeePool; // pool rewards in Shared Decimal format. indicate the total budget for reverse swap incentive
    address public feeLibrary; // address for retrieving fee params for swaps

    // Delta related
    uint256 public deltaCredit; // credits accumulated from txn
    bool public batched; // flag to indicate if we want batch processing.
    bool public defaultSwapMode; // flag for the default mode for swap
    bool public defaultLPMode; // flag for the default mode for lp
    uint256 public swapDeltaBP; // basis points of poolCredits to activate Delta in swap
    uint256 public lpDeltaBP; // basis points of poolCredits to activate Delta in liquidity events

    //---------------------------------------------------------------------------
    // EVENTS
    event Mint(address to, uint256 amountLP, uint256 amountSD, uint256 mintFeeAmountSD);
    event Burn(address from, uint256 amountLP, uint256 amountSD);
    event RedeemLocalCallback(address _to, uint256 _amountSD, uint256 _amountToMintSD);
    event Swap(
        uint16 chainId,
        uint256 dstPoolId,
        address from,
        uint256 amountSD,
        uint256 eqReward,
        uint256 eqFee,
        uint256 protocolFee,
        uint256 lpFee
    );
    event SendCredits(uint16 dstChainId, uint256 dstPoolId, uint256 credits, uint256 idealBalance);
    event RedeemRemote(uint16 chainId, uint256 dstPoolId, address from, uint256 amountLP, uint256 amountSD);
    event RedeemLocal(address from, uint256 amountLP, uint256 amountSD, uint16 chainId, uint256 dstPoolId, bytes to);
    event InstantRedeemLocal(address from, uint256 amountLP, uint256 amountSD, address to);
    event CreditChainPath(uint16 chainId, uint256 srcPoolId, uint256 amountSD, uint256 idealBalance);
    event SwapRemote(address to, uint256 amountSD, uint256 protocolFee, uint256 dstFee);
    event WithdrawRemote(uint16 srcChainId, uint256 srcPoolId, uint256 swapAmount, uint256 mintAmount);
    event ChainPathUpdate(uint16 dstChainId, uint256 dstPoolId, uint256 weight);
    event FeesUpdated(uint256 mintFeeBP);
    event FeeLibraryUpdated(address feeLibraryAddr);
    event StopSwapUpdated(bool swapStop);
    event WithdrawProtocolFeeBalance(address to, uint256 amountSD);
    event WithdrawMintFeeBalance(address to, uint256 amountSD);
    event DeltaParamUpdated(bool batched, uint256 swapDeltaBP, uint256 lpDeltaBP, bool defaultSwapMode, bool defaultLPMode);

    //---------------------------------------------------------------------------
    // MODIFIERS
    modifier onlyRouter() {
        require(msg.sender == router, "Stargate: only the router can call this method");
        _;
    }

    constructor(
        uint256 _poolId,
        address _router,
        address _token,
        uint256 _sharedDecimals,
        uint256 _localDecimals,
        address _feeLibrary,
        string memory _name,
        string memory _symbol
    ) LPTokenERC20(_name, _symbol) {
        require(_token != address(0x0), "Stargate: _token cannot be 0x0");
        require(_router != address(0x0), "Stargate: _router cannot be 0x0");
        poolId = _poolId;
        router = _router;
        token = _token;
        sharedDecimals = _sharedDecimals;
        decimals = uint8(_sharedDecimals);
        localDecimals = _localDecimals;
        convertRate = 10**(uint256(localDecimals).sub(sharedDecimals));
        totalWeight = 0;
        feeLibrary = _feeLibrary;

        //delta algo related
        batched = false;
        defaultSwapMode = true;
        defaultLPMode = true;
    }

    function getChainPathsLength() public view returns (uint256) {
        return chainPaths.length;
    }

    //---------------------------------------------------------------------------
    // LOCAL CHAIN FUNCTIONS

    function mint(address _to, uint256 _amountLD) external nonReentrant onlyRouter returns (uint256) {
        return _mintLocal(_to, _amountLD, true, true);
    }

    // Local                                    Remote
    // -------                                  ---------
    // swap             ->                      swapRemote
    function swap(
        uint16 _dstChainId,
        uint256 _dstPoolId,
        address _from,
        uint256 _amountLD,
        uint256 _minAmountLD,
        bool newLiquidity
    ) external nonReentrant onlyRouter returns (SwapObj memory) {
        require(!stopSwap, "Stargate: swap func stopped");
        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
        require(cp.ready == true, "Stargate: counter chainPath is not ready");

        uint256 amountSD = amountLDtoSD(_amountLD);
        uint256 minAmountSD = amountLDtoSD(_minAmountLD);

        // request fee params from library
        SwapObj memory s = IStargateFeeLibrary(feeLibrary).getFees(poolId, _dstPoolId, _dstChainId, _from, amountSD);

        // equilibrium fee and reward. note eqFee/eqReward are separated from swap liquidity
        eqFeePool = eqFeePool.sub(s.eqReward);
        // update the new amount the user gets minus the fees
        s.amount = amountSD.sub(s.eqFee).sub(s.protocolFee).sub(s.lpFee);
        // users will also get the eqReward
        require(s.amount.add(s.eqReward) >= minAmountSD, "Stargate: slippage too high");

        // behaviours
        //     - protocolFee: booked, stayed and withdrawn at remote.
        //     - eqFee: booked, stayed and withdrawn at remote.
        //     - lpFee: booked and stayed at remote, can be withdrawn anywhere

        s.lkbRemove = amountSD.sub(s.lpFee).add(s.eqReward);
        // check for transfer solvency.
        require(cp.balance >= s.lkbRemove, "Stargate: dst balance too low");
        cp.balance = cp.balance.sub(s.lkbRemove);

        if (newLiquidity) {
            deltaCredit = deltaCredit.add(amountSD).add(s.eqReward);
        } else if (s.eqReward > 0) {
            deltaCredit = deltaCredit.add(s.eqReward);
        }

        // distribute credits on condition.
        if (!batched || deltaCredit >= totalLiquidity.mul(swapDeltaBP).div(BP_DENOMINATOR)) {
            _delta(defaultSwapMode);
        }

        emit Swap(_dstChainId, _dstPoolId, _from, s.amount, s.eqReward, s.eqFee, s.protocolFee, s.lpFee);
        return s;
    }

    // Local                                    Remote
    // -------                                  ---------
    // sendCredits      ->                      creditChainPath
    function sendCredits(uint16 _dstChainId, uint256 _dstPoolId) external nonReentrant onlyRouter returns (CreditObj memory c) {
        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
        require(cp.ready == true, "Stargate: counter chainPath is not ready");
        cp.lkb = cp.lkb.add(cp.credits);
        c.idealBalance = totalLiquidity.mul(cp.weight).div(totalWeight);
        c.credits = cp.credits;
        cp.credits = 0;
        emit SendCredits(_dstChainId, _dstPoolId, c.credits, c.idealBalance);
    }

    // Local                                    Remote
    // -------                                  ---------
    // redeemRemote   ->                        swapRemote
    function redeemRemote(
        uint16 _dstChainId,
        uint256 _dstPoolId,
        address _from,
        uint256 _amountLP
    ) external nonReentrant onlyRouter {
        require(_from != address(0x0), "Stargate: _from cannot be 0x0");
        uint256 amountSD = _burnLocal(_from, _amountLP);
        //run Delta
        if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {
            _delta(defaultLPMode);
        }
        uint256 amountLD = amountSDtoLD(amountSD);
        emit RedeemRemote(_dstChainId, _dstPoolId, _from, _amountLP, amountLD);
    }

    function instantRedeemLocal(
        address _from,
        uint256 _amountLP,
        address _to
    ) external nonReentrant onlyRouter returns (uint256 amountSD) {
        require(_from != address(0x0), "Stargate: _from cannot be 0x0");
        uint256 _deltaCredit = deltaCredit; // sload optimization.
        uint256 _capAmountLP = _amountSDtoLP(_deltaCredit);

        if (_amountLP > _capAmountLP) _amountLP = _capAmountLP;

        amountSD = _burnLocal(_from, _amountLP);
        deltaCredit = _deltaCredit.sub(amountSD);
        uint256 amountLD = amountSDtoLD(amountSD);
        _safeTransfer(token, _to, amountLD);
        emit InstantRedeemLocal(_from, _amountLP, amountSD, _to);
    }

    // Local                                    Remote
    // -------                                  ---------
    // redeemLocal   ->                         redeemLocalCheckOnRemote
    // redeemLocalCallback             <-
    function redeemLocal(
        address _from,
        uint256 _amountLP,
        uint16 _dstChainId,
        uint256 _dstPoolId,
        bytes calldata _to
    ) external nonReentrant onlyRouter returns (uint256 amountSD) {
        require(_from != address(0x0), "Stargate: _from cannot be 0x0");

        // safeguard.
        require(chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]].ready == true, "Stargate: counter chainPath is not ready");
        amountSD = _burnLocal(_from, _amountLP);

        // run Delta
        if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {
            _delta(false);
        }
        emit RedeemLocal(_from, _amountLP, amountSD, _dstChainId, _dstPoolId, _to);
    }

    //---------------------------------------------------------------------------
    // REMOTE CHAIN FUNCTIONS

    // Local                                    Remote
    // -------                                  ---------
    // sendCredits      ->                      creditChainPath
    function creditChainPath(
        uint16 _dstChainId,
        uint256 _dstPoolId,
        CreditObj memory _c
    ) external nonReentrant onlyRouter {
        ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];
        cp.balance = cp.balance.add(_c.credits);
        if (cp.idealBalance != _c.idealBalance) {
            cp.idealBalance = _c.idealBalance;
        }
        emit CreditChainPath(_dstChainId, _dstPoolId, _c.credits, _c.idealBalance);
    }

    // Local                                    Remote
    // -------                                  ---------
    // swap             ->                      swapRemote
    function swapRemote(
        uint16 _srcChainId,
        uint256 _srcPoolId,
        address _to,
        SwapObj memory _s
    ) external nonReentrant onlyRouter returns (uint256 amountLD) {
        // booking lpFee
        totalLiquidity = totalLiquidity.add(_s.lpFee);
        // booking eqFee
        eqFeePool = eqFeePool.add(_s.eqFee);
        // booking stargateFee
        protocolFeeBalance = protocolFeeBalance.add(_s.protocolFee);

        // update LKB
        uint256 chainPathIndex = chainPathIndexLookup[_srcChainId][_srcPoolId];
        chainPaths[chainPathIndex].lkb = chainPaths[chainPathIndex].lkb.sub(_s.lkbRemove);

        // user receives the amount + the srcReward
        amountLD = amountSDtoLD(_s.amount.add(_s.eqReward));
        _safeTransfer(token, _to, amountLD);
        emit SwapRemote(_to, _s.amount.add(_s.eqReward), _s.protocolFee, _s.eqFee);
    }

    // Local                                    Remote
    // -------                                  ---------
    // redeemLocal   ->                         redeemLocalCheckOnRemote
    // redeemLocalCallback             <-
    function redeemLocalCallback(
        uint16 _srcChainId,
        uint256 _srcPoolId,
        address _to,
        uint256 _amountSD,
        uint256 _amountToMintSD
    ) external nonReentrant onlyRouter {
        if (_amountToMintSD > 0) {
            _mintLocal(_to, amountSDtoLD(_amountToMintSD), false, false);
        }

        ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId);
        cp.lkb = cp.lkb.sub(_amountSD);

        uint256 amountLD = amountSDtoLD(_amountSD);
        _safeTransfer(token, _to, amountLD);
        emit RedeemLocalCallback(_to, _amountSD, _amountToMintSD);
    }

    // Local                                    Remote
    // -------                                  ---------
    // redeemLocal(amount)   ->               redeemLocalCheckOnRemote
    // redeemLocalCallback             <-
    function redeemLocalCheckOnRemote(
        uint16 _srcChainId,
        uint256 _srcPoolId,
        uint256 _amountSD
    ) external nonReentrant onlyRouter returns (uint256 swapAmount, uint256 mintAmount) {
        ChainPath storage cp = getAndCheckCP(_srcChainId, _srcPoolId);
        if (_amountSD > cp.balance) {
            mintAmount = _amountSD - cp.balance;
            swapAmount = cp.balance;
            cp.balance = 0;
        } else {
            cp.balance = cp.balance.sub(_amountSD);
            swapAmount = _amountSD;
            mintAmount = 0;
        }
        emit WithdrawRemote(_srcChainId, _srcPoolId, swapAmount, mintAmount);
    }

    //---------------------------------------------------------------------------
    // DAO Calls
    function createChainPath(
        uint16 _dstChainId,
        uint256 _dstPoolId,
        uint256 _weight
    ) external onlyRouter {
        for (uint256 i = 0; i < chainPaths.length; ++i) {
            ChainPath memory cp = chainPaths[i];
            bool exists = cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId;
            require(!exists, "Stargate: cant createChainPath of existing dstChainId and _dstPoolId");
        }
        totalWeight = totalWeight.add(_weight);
        chainPathIndexLookup[_dstChainId][_dstPoolId] = chainPaths.length;
        chainPaths.push(ChainPath(false, _dstChainId, _dstPoolId, _weight, 0, 0, 0, 0));
        emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight);
    }

    function setWeightForChainPath(
        uint16 _dstChainId,
        uint256 _dstPoolId,
        uint16 _weight
    ) external onlyRouter {
        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
        totalWeight = totalWeight.sub(cp.weight).add(_weight);
        cp.weight = _weight;
        emit ChainPathUpdate(_dstChainId, _dstPoolId, _weight);
    }

    function setFee(uint256 _mintFeeBP) external onlyRouter {
        require(_mintFeeBP <= BP_DENOMINATOR, "Bridge: cum fees > 100%");
        mintFeeBP = _mintFeeBP;
        emit FeesUpdated(mintFeeBP);
    }

    function setFeeLibrary(address _feeLibraryAddr) external onlyRouter {
        require(_feeLibraryAddr != address(0x0), "Stargate: fee library cant be 0x0");
        feeLibrary = _feeLibraryAddr;
        emit FeeLibraryUpdated(_feeLibraryAddr);
    }

    function setSwapStop(bool _swapStop) external onlyRouter {
        stopSwap = _swapStop;
        emit StopSwapUpdated(_swapStop);
    }

    function setDeltaParam(
        bool _batched,
        uint256 _swapDeltaBP,
        uint256 _lpDeltaBP,
        bool _defaultSwapMode,
        bool _defaultLPMode
    ) external onlyRouter {
        require(_swapDeltaBP <= BP_DENOMINATOR && _lpDeltaBP <= BP_DENOMINATOR, "Stargate: wrong Delta param");
        batched = _batched;
        swapDeltaBP = _swapDeltaBP;
        lpDeltaBP = _lpDeltaBP;
        defaultSwapMode = _defaultSwapMode;
        defaultLPMode = _defaultLPMode;
        emit DeltaParamUpdated(_batched, _swapDeltaBP, _lpDeltaBP, _defaultSwapMode, _defaultLPMode);
    }

    function callDelta(bool _fullMode) external onlyRouter {
        _delta(_fullMode);
    }

    function activateChainPath(uint16 _dstChainId, uint256 _dstPoolId) external onlyRouter {
        ChainPath storage cp = getAndCheckCP(_dstChainId, _dstPoolId);
        require(cp.ready == false, "Stargate: chainPath is already active");
        // this func will only be called once
        cp.ready = true;
    }

    function withdrawProtocolFeeBalance(address _to) external onlyRouter {
        if (protocolFeeBalance > 0) {
            uint256 amountOfLD = amountSDtoLD(protocolFeeBalance);
            protocolFeeBalance = 0;
            _safeTransfer(token, _to, amountOfLD);
            emit WithdrawProtocolFeeBalance(_to, amountOfLD);
        }
    }

    function withdrawMintFeeBalance(address _to) external onlyRouter {
        if (mintFeeBalance > 0) {
            uint256 amountOfLD = amountSDtoLD(mintFeeBalance);
            mintFeeBalance = 0;
            _safeTransfer(token, _to, amountOfLD);
            emit WithdrawMintFeeBalance(_to, amountOfLD);
        }
    }

    //---------------------------------------------------------------------------
    // INTERNAL
    // Conversion Helpers
    //---------------------------------------------------------------------------
    function amountLPtoLD(uint256 _amountLP) external view returns (uint256) {
        return amountSDtoLD(_amountLPtoSD(_amountLP));
    }

    function _amountLPtoSD(uint256 _amountLP) internal view returns (uint256) {
        require(totalSupply > 0, "Stargate: cant convert LPtoSD when totalSupply == 0");
        return _amountLP.mul(totalLiquidity).div(totalSupply);
    }

    function _amountSDtoLP(uint256 _amountSD) internal view returns (uint256) {
        require(totalLiquidity > 0, "Stargate: cant convert SDtoLP when totalLiq == 0");
        return _amountSD.mul(totalSupply).div(totalLiquidity);
    }

    function amountSDtoLD(uint256 _amount) internal view returns (uint256) {
        return _amount.mul(convertRate);
    }

    function amountLDtoSD(uint256 _amount) internal view returns (uint256) {
        return _amount.div(convertRate);
    }

    function getAndCheckCP(uint16 _dstChainId, uint256 _dstPoolId) internal view returns (ChainPath storage) {
        require(chainPaths.length > 0, "Stargate: no chainpaths exist");
        ChainPath storage cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];
        require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, "Stargate: local chainPath does not exist");
        return cp;
    }

    function getChainPath(uint16 _dstChainId, uint256 _dstPoolId) external view returns (ChainPath memory) {
        ChainPath memory cp = chainPaths[chainPathIndexLookup[_dstChainId][_dstPoolId]];
        require(cp.dstChainId == _dstChainId && cp.dstPoolId == _dstPoolId, "Stargate: local chainPath does not exist");
        return cp;
    }

    function _burnLocal(address _from, uint256 _amountLP) internal returns (uint256) {
        require(totalSupply > 0, "Stargate: cant burn when totalSupply == 0");
        uint256 amountOfLPTokens = balanceOf[_from];
        require(amountOfLPTokens >= _amountLP, "Stargate: not enough LP tokens to burn");

        uint256 amountSD = _amountLP.mul(totalLiquidity).div(totalSupply);
        //subtract totalLiquidity accordingly
        totalLiquidity = totalLiquidity.sub(amountSD);

        _burn(_from, _amountLP);
        emit Burn(_from, _amountLP, amountSD);
        return amountSD;
    }

    function _delta(bool fullMode) internal {
        if (deltaCredit > 0 && totalWeight > 0) {
            uint256 cpLength = chainPaths.length;
            uint256[] memory deficit = new uint256[](cpLength);
            uint256 totalDeficit = 0;

            // algorithm steps 6-9: calculate the total and the amounts required to get to balance state
            for (uint256 i = 0; i < cpLength; ++i) {
                ChainPath storage cp = chainPaths[i];
                // (liquidity * (weight/totalWeight)) - (lkb+credits)
                uint256 balLiq = totalLiquidity.mul(cp.weight).div(totalWeight);
                uint256 currLiq = cp.lkb.add(cp.credits);
                if (balLiq > currLiq) {
                    // save gas since we know balLiq > currLiq and we know deficit[i] > 0
                    deficit[i] = balLiq - currLiq;
                    totalDeficit = totalDeficit.add(deficit[i]);
                }
            }

            // indicates how much delta credit is distributed
            uint256 spent;

            // handle credits with 2 tranches. the [ < totalDeficit] [excessCredit]
            // run full Delta, allocate all credits
            if (totalDeficit == 0) {
                // only fullMode delta will allocate excess credits
                if (fullMode && deltaCredit > 0) {
                    // credit ChainPath by weights
                    for (uint256 i = 0; i < cpLength; ++i) {
                        ChainPath storage cp = chainPaths[i];
                        // credits = credits + toBalanceChange + remaining allocation based on weight
                        uint256 amtToCredit = deltaCredit.mul(cp.weight).div(totalWeight);
                        spent = spent.add(amtToCredit);
                        cp.credits = cp.credits.add(amtToCredit);
                    }
                } // else do nth
            } else if (totalDeficit <= deltaCredit) {
                if (fullMode) {
                    // algorithm step 13: calculate amount to disperse to bring to balance state or as close as possible
                    uint256 excessCredit = deltaCredit - totalDeficit;
                    // algorithm steps 14-16: calculate credits
                    for (uint256 i = 0; i < cpLength; ++i) {
                        if (deficit[i] > 0) {
                            ChainPath storage cp = chainPaths[i];
                            // credits = credits + deficit + remaining allocation based on weight
                            uint256 amtToCredit = deficit[i].add(excessCredit.mul(cp.weight).div(totalWeight));
                            spent = spent.add(amtToCredit);
                            cp.credits = cp.credits.add(amtToCredit);
                        }
                    }
                } else {
                    // totalDeficit <= deltaCredit but not running fullMode
                    // credit chainPaths as is if any deficit, not using all deltaCredit
                    for (uint256 i = 0; i < cpLength; ++i) {
                        if (deficit[i] > 0) {
                            ChainPath storage cp = chainPaths[i];
                            uint256 amtToCredit = deficit[i];
                            spent = spent.add(amtToCredit);
                            cp.credits = cp.credits.add(amtToCredit);
                        }
                    }
                }
            } else {
                // totalDeficit > deltaCredit, fullMode or not, normalize the deficit by deltaCredit
                for (uint256 i = 0; i < cpLength; ++i) {
                    if (deficit[i] > 0) {
                        ChainPath storage cp = chainPaths[i];
                        uint256 proportionalDeficit = deficit[i].mul(deltaCredit).div(totalDeficit);
                        spent = spent.add(proportionalDeficit);
                        cp.credits = cp.credits.add(proportionalDeficit);
                    }
                }
            }

            // deduct the amount of credit sent
            deltaCredit = deltaCredit.sub(spent);
        }
    }

    function _mintLocal(
        address _to,
        uint256 _amountLD,
        bool _feesEnabled,
        bool _creditDelta
    ) internal returns (uint256 amountSD) {
        require(totalWeight > 0, "Stargate: No ChainPaths exist");
        amountSD = amountLDtoSD(_amountLD);

        uint256 mintFeeSD = 0;
        if (_feesEnabled) {
            mintFeeSD = amountSD.mul(mintFeeBP).div(BP_DENOMINATOR);
            amountSD = amountSD.sub(mintFeeSD);
            mintFeeBalance = mintFeeBalance.add(mintFeeSD);
        }

        if (_creditDelta) {
            deltaCredit = deltaCredit.add(amountSD);
        }

        uint256 amountLPTokens = amountSD;
        if (totalSupply != 0) {
            amountLPTokens = amountSD.mul(totalSupply).div(totalLiquidity);
        }
        totalLiquidity = totalLiquidity.add(amountSD);

        _mint(_to, amountLPTokens);
        emit Mint(_to, amountLPTokens, amountSD, mintFeeSD);

        // add to credits and call delta. short circuit to save gas
        if (!batched || deltaCredit > totalLiquidity.mul(lpDeltaBP).div(BP_DENOMINATOR)) {
            _delta(defaultLPMode);
        }
    }

    function _safeTransfer(
        address _token,
        address _to,
        uint256 _value
    ) private {
        (bool success, bytes memory data) = _token.call(abi.encodeWithSelector(SELECTOR, _to, _value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "Stargate: TRANSFER_FAILED");
    }
}

File 12 of 17 : Bridge.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;
pragma abicoder v2;

// imports
import "@openzeppelin/contracts/access/Ownable.sol";

import "./Pool.sol";
import "./Router.sol";
// interfaces
import "@layerzerolabs/layerzero-core/contracts/interfaces/ILayerZeroReceiver.sol";
import "@layerzerolabs/layerzero-core/contracts/interfaces/ILayerZeroEndpoint.sol";
import "@layerzerolabs/layerzero-core/contracts/interfaces/ILayerZeroUserApplicationConfig.sol";

// libraries
import "@openzeppelin/contracts/math/SafeMath.sol";

contract Bridge is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
    using SafeMath for uint256;

    //---------------------------------------------------------------------------
    // CONSTANTS
    uint8 internal constant TYPE_SWAP_REMOTE = 1;
    uint8 internal constant TYPE_ADD_LIQUIDITY = 2;
    uint8 internal constant TYPE_REDEEM_LOCAL_CALL_BACK = 3;
    uint8 internal constant TYPE_WITHDRAW_REMOTE = 4;

    //---------------------------------------------------------------------------
    // VARIABLES
    ILayerZeroEndpoint public immutable layerZeroEndpoint;
    mapping(uint16 => bytes) public bridgeLookup;
    mapping(uint16 => mapping(uint8 => uint256)) public gasLookup;
    Router public immutable router;
    bool public useLayerZeroToken;

    //---------------------------------------------------------------------------
    // EVENTS
    event SendMsg(uint8 msgType, uint64 nonce);

    //---------------------------------------------------------------------------
    // MODIFIERS
    modifier onlyRouter() {
        require(msg.sender == address(router), "Stargate: caller must be Router.");
        _;
    }

    constructor(address _layerZeroEndpoint, address _router) {
        require(_layerZeroEndpoint != address(0x0), "Stargate: _layerZeroEndpoint cannot be 0x0");
        require(_router != address(0x0), "Stargate: _router cannot be 0x0");
        layerZeroEndpoint = ILayerZeroEndpoint(_layerZeroEndpoint);
        router = Router(_router);
    }

    //---------------------------------------------------------------------------
    // EXTERNAL functions

    function lzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload
    ) external override {
        require(msg.sender == address(layerZeroEndpoint), "Stargate: only LayerZero endpoint can call lzReceive");
        require(
            _srcAddress.length == bridgeLookup[_srcChainId].length && keccak256(_srcAddress) == keccak256(bridgeLookup[_srcChainId]),
            "Stargate: bridge does not match"
        );

        uint8 functionType;
        assembly {
            functionType := mload(add(_payload, 32))
        }

        if (functionType == TYPE_SWAP_REMOTE) {
            (
                ,
                uint256 srcPoolId,
                uint256 dstPoolId,
                uint256 dstGasForCall,
                Pool.CreditObj memory c,
                Pool.SwapObj memory s,
                bytes memory to,
                bytes memory payload
            ) = abi.decode(_payload, (uint8, uint256, uint256, uint256, Pool.CreditObj, Pool.SwapObj, bytes, bytes));
            address toAddress;
            assembly {
                toAddress := mload(add(to, 20))
            }
            router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
            router.swapRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, dstGasForCall, toAddress, s, payload);
        } else if (functionType == TYPE_ADD_LIQUIDITY) {
            (, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c) = abi.decode(_payload, (uint8, uint256, uint256, Pool.CreditObj));
            router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
        } else if (functionType == TYPE_REDEEM_LOCAL_CALL_BACK) {
            (, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c, uint256 amountSD, uint256 mintAmountSD, bytes memory to) = abi
                .decode(_payload, (uint8, uint256, uint256, Pool.CreditObj, uint256, uint256, bytes));
            address toAddress;
            assembly {
                toAddress := mload(add(to, 20))
            }
            router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
            router.redeemLocalCallback(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, toAddress, amountSD, mintAmountSD);
        } else if (functionType == TYPE_WITHDRAW_REMOTE) {
            (, uint256 srcPoolId, uint256 dstPoolId, Pool.CreditObj memory c, uint256 amountSD, bytes memory to) = abi.decode(
                _payload,
                (uint8, uint256, uint256, Pool.CreditObj, uint256, bytes)
            );
            router.creditChainPath(_srcChainId, srcPoolId, dstPoolId, c);
            router.redeemLocalCheckOnRemote(_srcChainId, _srcAddress, _nonce, srcPoolId, dstPoolId, amountSD, to);
        }
    }

    //---------------------------------------------------------------------------
    // LOCAL CHAIN FUNCTIONS
    function swap(
        uint16 _chainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        Pool.CreditObj memory _c,
        Pool.SwapObj memory _s,
        IStargateRouter.lzTxObj memory _lzTxParams,
        bytes calldata _to,
        bytes calldata _payload
    ) external payable onlyRouter {
        bytes memory payload = abi.encode(TYPE_SWAP_REMOTE, _srcPoolId, _dstPoolId, _lzTxParams.dstGasForCall, _c, _s, _to, _payload);
        _call(_chainId, TYPE_SWAP_REMOTE, _refundAddress, _lzTxParams, payload);
    }

    function redeemLocalCallback(
        uint16 _chainId,
        address payable _refundAddress,
        Pool.CreditObj memory _c,
        IStargateRouter.lzTxObj memory _lzTxParams,
        bytes memory _payload
    ) external payable onlyRouter {
        bytes memory payload;

        {
            (, uint256 srcPoolId, uint256 dstPoolId, uint256 amountSD, uint256 mintAmountSD, bytes memory to) = abi.decode(
                _payload,
                (uint8, uint256, uint256, uint256, uint256, bytes)
            );

            // swap dst and src because we are headed back
            payload = abi.encode(TYPE_REDEEM_LOCAL_CALL_BACK, dstPoolId, srcPoolId, _c, amountSD, mintAmountSD, to);
        }

        _call(_chainId, TYPE_REDEEM_LOCAL_CALL_BACK, _refundAddress, _lzTxParams, payload);
    }

    function redeemLocal(
        uint16 _chainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        Pool.CreditObj memory _c,
        uint256 _amountSD,
        bytes calldata _to,
        IStargateRouter.lzTxObj memory _lzTxParams
    ) external payable onlyRouter {
        bytes memory payload = abi.encode(TYPE_WITHDRAW_REMOTE, _srcPoolId, _dstPoolId, _c, _amountSD, _to);
        _call(_chainId, TYPE_WITHDRAW_REMOTE, _refundAddress, _lzTxParams, payload);
    }

    function sendCredits(
        uint16 _chainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        Pool.CreditObj memory _c
    ) external payable onlyRouter {
        bytes memory payload = abi.encode(TYPE_ADD_LIQUIDITY, _srcPoolId, _dstPoolId, _c);
        IStargateRouter.lzTxObj memory lzTxObj = IStargateRouter.lzTxObj(0, 0, "0x");
        _call(_chainId, TYPE_ADD_LIQUIDITY, _refundAddress, lzTxObj, payload);
    }

    function quoteLayerZeroFee(
        uint16 _chainId,
        uint8 _functionType,
        bytes calldata _toAddress,
        bytes calldata _transferAndCallPayload,
        IStargateRouter.lzTxObj memory _lzTxParams
    ) external view returns (uint256, uint256) {
        bytes memory payload = "";
        Pool.CreditObj memory c = Pool.CreditObj(1, 1);
        if (_functionType == TYPE_SWAP_REMOTE) {
            Pool.SwapObj memory s = Pool.SwapObj(1, 1, 1, 1, 1, 1);
            payload = abi.encode(TYPE_SWAP_REMOTE, 0, 0, 0, c, s, _toAddress, _transferAndCallPayload);
        } else if (_functionType == TYPE_ADD_LIQUIDITY) {
            payload = abi.encode(TYPE_ADD_LIQUIDITY, 0, 0, c);
        } else if (_functionType == TYPE_REDEEM_LOCAL_CALL_BACK) {
            payload = abi.encode(TYPE_REDEEM_LOCAL_CALL_BACK, 0, 0, c, 0, 0, _toAddress);
        } else if (_functionType == TYPE_WITHDRAW_REMOTE) {
            payload = abi.encode(TYPE_WITHDRAW_REMOTE, 0, 0, c, 0, _toAddress);
        } else {
            revert("Stargate: unsupported function type");
        }

        bytes memory lzTxParamBuilt = _txParamBuilder(_chainId, _functionType, _lzTxParams);
        return layerZeroEndpoint.estimateFees(_chainId, address(this), payload, useLayerZeroToken, lzTxParamBuilt);
    }

    //---------------------------------------------------------------------------
    // dao functions
    function setBridge(uint16 _chainId, bytes calldata _bridgeAddress) external onlyOwner {
        require(bridgeLookup[_chainId].length == 0, "Stargate: Bridge already set!");
        bridgeLookup[_chainId] = _bridgeAddress;
    }

    function setGasAmount(
        uint16 _chainId,
        uint8 _functionType,
        uint256 _gasAmount
    ) external onlyOwner {
        require(_functionType >= 1 && _functionType <= 4, "Stargate: invalid _functionType");
        gasLookup[_chainId][_functionType] = _gasAmount;
    }

    function approveTokenSpender(
        address token,
        address spender,
        uint256 amount
    ) external onlyOwner {
        IERC20(token).approve(spender, amount);
    }

    function setUseLayerZeroToken(bool enable) external onlyOwner {
        useLayerZeroToken = enable;
    }

    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
        layerZeroEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
    }

    //---------------------------------------------------------------------------
    // generic config for user Application
    function setConfig(
        uint16 _version,
        uint16 _chainId,
        uint256 _configType,
        bytes calldata _config
    ) external override onlyOwner {
        layerZeroEndpoint.setConfig(_version, _chainId, _configType, _config);
    }

    function setSendVersion(uint16 version) external override onlyOwner {
        layerZeroEndpoint.setSendVersion(version);
    }

    function setReceiveVersion(uint16 version) external override onlyOwner {
        layerZeroEndpoint.setReceiveVersion(version);
    }

    //---------------------------------------------------------------------------
    // INTERNAL functions
    function txParamBuilderType1(uint256 _gasAmount) internal pure returns (bytes memory) {
        uint16 txType = 1;
        return abi.encodePacked(txType, _gasAmount);
    }

    function txParamBuilderType2(
        uint256 _gasAmount,
        uint256 _dstNativeAmount,
        bytes memory _dstNativeAddr
    ) internal pure returns (bytes memory) {
        uint16 txType = 2;
        return abi.encodePacked(txType, _gasAmount, _dstNativeAmount, _dstNativeAddr);
    }

    function _txParamBuilder(
        uint16 _chainId,
        uint8 _type,
        IStargateRouter.lzTxObj memory _lzTxParams
    ) internal view returns (bytes memory) {
        bytes memory lzTxParam;
        address dstNativeAddr;
        {
            bytes memory dstNativeAddrBytes = _lzTxParams.dstNativeAddr;
            assembly {
                dstNativeAddr := mload(add(dstNativeAddrBytes, 20))
            }
        }

        uint256 totalGas = gasLookup[_chainId][_type].add(_lzTxParams.dstGasForCall);
        if (_lzTxParams.dstNativeAmount > 0 && dstNativeAddr != address(0x0)) {
            lzTxParam = txParamBuilderType2(totalGas, _lzTxParams.dstNativeAmount, _lzTxParams.dstNativeAddr);
        } else {
            lzTxParam = txParamBuilderType1(totalGas);
        }

        return lzTxParam;
    }

    function _call(
        uint16 _chainId,
        uint8 _type,
        address payable _refundAddress,
        IStargateRouter.lzTxObj memory _lzTxParams,
        bytes memory _payload
    ) internal {
        bytes memory lzTxParamBuilt = _txParamBuilder(_chainId, _type, _lzTxParams);
        uint64 nextNonce = layerZeroEndpoint.getOutboundNonce(_chainId, address(this)) + 1;
        layerZeroEndpoint.send{value: msg.value}(_chainId, bridgeLookup[_chainId], _payload, _refundAddress, address(this), lzTxParamBuilt);
        emit SendMsg(_type, nextNonce);
    }

    function renounceOwnership() public override onlyOwner {}
}

File 13 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 14 of 17 : IStargateRouter.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;
pragma abicoder v2;

interface IStargateRouter {
    struct lzTxObj {
        uint256 dstGasForCall;
        uint256 dstNativeAmount;
        bytes dstNativeAddr;
    }

    function addLiquidity(
        uint256 _poolId,
        uint256 _amountLD,
        address _to
    ) external;

    function swap(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        uint256 _amountLD,
        uint256 _minAmountLD,
        lzTxObj memory _lzTxParams,
        bytes calldata _to,
        bytes calldata _payload
    ) external payable;

    function redeemRemote(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        uint256 _amountLP,
        uint256 _minAmountLD,
        bytes calldata _to,
        lzTxObj memory _lzTxParams
    ) external payable;

    function instantRedeemLocal(
        uint16 _srcPoolId,
        uint256 _amountLP,
        address _to
    ) external returns (uint256);

    function redeemLocal(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress,
        uint256 _amountLP,
        bytes calldata _to,
        lzTxObj memory _lzTxParams
    ) external payable;

    function sendCredits(
        uint16 _dstChainId,
        uint256 _srcPoolId,
        uint256 _dstPoolId,
        address payable _refundAddress
    ) external payable;

    function quoteLayerZeroFee(
        uint16 _dstChainId,
        uint8 _functionType,
        bytes calldata _toAddress,
        bytes calldata _transferAndCallPayload,
        lzTxObj memory _lzTxParams
    ) external view returns (uint256, uint256);
}

File 15 of 17 : IStargateReceiver.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;

interface IStargateReceiver {
    function sgReceive(
        uint16 _chainId,
        bytes memory _srcAddress,
        uint256 _nonce,
        address _token,
        uint256 amountLD,
        bytes memory payload
    ) external;
}

File 16 of 17 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 17 of 17 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountLD","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"CachedSwapSaved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"srcPoolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dstPoolId","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmountSD","type":"uint256"}],"name":"RedeemLocalCallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"bridgeFunctionType","type":"uint8"},{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Revert","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"srcChainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"to","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"redeemAmountSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintAmountSD","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"srcAddress","type":"bytes"}],"name":"RevertRedeemLocal","type":"event"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"}],"name":"activateChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256","name":"_amountLD","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract Bridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"cachedSwapLookup","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountLD","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"payload","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_fullMode","type":"bool"}],"name":"callDelta","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"clearCachedSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_weight","type":"uint256"}],"name":"createChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint8","name":"_sharedDecimals","type":"uint8"},{"internalType":"uint8","name":"_localDecimals","type":"uint8"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"createPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"components":[{"internalType":"uint256","name":"credits","type":"uint256"},{"internalType":"uint256","name":"idealBalance","type":"uint256"}],"internalType":"struct Pool.CreditObj","name":"_c","type":"tuple"}],"name":"creditChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcPoolId","type":"uint16"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"instantRedeemLocal","outputs":[{"internalType":"uint256","name":"amountSD","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintFeeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint8","name":"_functionType","type":"uint8"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"bytes","name":"_transferAndCallPayload","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"quoteLayerZeroFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"redeemLocal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amountSD","type":"uint256"},{"internalType":"uint256","name":"_mintAmountSD","type":"uint256"}],"name":"redeemLocalCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_amountSD","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"}],"name":"redeemLocalCheckOnRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLP","type":"uint256"},{"internalType":"uint256","name":"_minAmountLD","type":"uint256"},{"internalType":"bytes","name":"_to","type":"bytes"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"redeemRemote","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"retryRevert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"revertLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"}],"name":"revertRedeemLocal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"}],"name":"sendCredits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract Bridge","name":"_bridge","type":"address"},{"internalType":"contract Factory","name":"_factory","type":"address"}],"name":"setBridgeAndFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_batched","type":"bool"},{"internalType":"uint256","name":"_swapDeltaBP","type":"uint256"},{"internalType":"uint256","name":"_lpDeltaBP","type":"uint256"},{"internalType":"bool","name":"_defaultSwapMode","type":"bool"},{"internalType":"bool","name":"_defaultLPMode","type":"bool"}],"name":"setDeltaParam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_feeLibraryAddr","type":"address"}],"name":"setFeeLibrary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint256","name":"_mintFeeBP","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setMintFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setProtocolFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"bool","name":"_swapStop","type":"bool"}],"name":"setSwapStop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint16","name":"_weight","type":"uint16"}],"name":"setWeightForChainPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"uint256","name":"_amountLD","type":"uint256"},{"internalType":"uint256","name":"_minAmountLD","type":"uint256"},{"components":[{"internalType":"uint256","name":"dstGasForCall","type":"uint256"},{"internalType":"uint256","name":"dstNativeAmount","type":"uint256"},{"internalType":"bytes","name":"dstNativeAddr","type":"bytes"}],"internalType":"struct IStargateRouter.lzTxObj","name":"_lzTxParams","type":"tuple"},{"internalType":"bytes","name":"_to","type":"bytes"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_srcPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstPoolId","type":"uint256"},{"internalType":"uint256","name":"_dstGasForCall","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"eqFee","type":"uint256"},{"internalType":"uint256","name":"eqReward","type":"uint256"},{"internalType":"uint256","name":"lpFee","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"uint256","name":"lkbRemove","type":"uint256"}],"internalType":"struct Pool.SwapObj","name":"_s","type":"tuple"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"swapRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060006200001e62000072565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001805562000076565b3390565b6151c980620000866000396000f3fe60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece64736f6c63430007060033

Deployed Bytecode

0x60806040526004361061021a5760003560e01c806387b21efc11610123578063c45a0155116100ab578063cefbdde21161006f578063cefbdde2146105dd578063da133a06146105fd578063e78cea921461062a578063f2fde38b1461063f578063fba6e2801461065f5761021a565b8063c45a01551461053b578063c4de93a514610550578063c6a276241461057d578063c7d968e31461059d578063c8adf12d146105bd5761021a565b80639ba3aa74116100f25780639ba3aa74146104cb5780639fbf10fc146104de578063a18fa804146104f1578063a96fbed414610511578063af640d82146105265761021a565b806387b21efc146104635780638da5cb5b146104835780638f2e1d181461049857806398e391a1146104ab5761021a565b806343a30630116101a6578063715018a611610175578063715018a6146103ce5780637af935a1146103e35780637b84d287146104105780637f7212981461043057806384d0dba3146104505761021a565b806343a30630146103685780635500585c1461038857806360a3b95c146103a85780636a7982da146103bb5761021a565b806323fd4647116101ed57806323fd4647146102b85780632f925555146102e857806334aba41014610308578063403a9f7a14610328578063424c9119146103485761021a565b80630403bce51461021f5780630a512369146102415780630b78f9c01461027857806316fb60f514610298575b600080fd5b34801561022b57600080fd5b5061023f61023a366004613b12565b61067f565b005b34801561024d57600080fd5b5061026161025c366004613ed5565b6108eb565b60405161026f929190614f2c565b60405180910390f35b34801561028457600080fd5b5061023f610293366004614193565b61098b565b3480156102a457600080fd5b5061023f6102b3366004614159565b610a5e565b3480156102c457600080fd5b506102d86102d336600461390f565b610b2c565b60405161026f94939291906144e3565b3480156102f457600080fd5b5061023f6103033660046139f1565b610c0b565b34801561031457600080fd5b5061023f610323366004613737565b610c46565b34801561033457600080fd5b5061023f610343366004613825565b610cf0565b34801561035457600080fd5b5061023f61036336600461378b565b610f23565b34801561037457600080fd5b5061023f61038336600461407a565b61103d565b34801561039457600080fd5b5061023f6103a3366004613f9f565b61111c565b61023f6103b6366004613825565b611180565b61023f6103c936600461387c565b6113fd565b3480156103da57600080fd5b5061023f6116ae565b3480156103ef57600080fd5b506104036103fe366004613fc3565b61175a565b60405161026f919061442b565b34801561041c57600080fd5b5061023f61042b366004614114565b61187d565b34801561043c57600080fd5b5061023f61044b366004613963565b61191d565b61023f61045e366004613cda565b611961565b34801561046f57600080fd5b5061023f61047e3660046141d7565b611c96565b34801561048f57600080fd5b50610403611e81565b61023f6104a6366004613c35565b611e90565b3480156104b757600080fd5b5061023f6104c6366004614056565b6120b1565b61023f6104d9366004613bee565b61214d565b61023f6104ec366004613d79565b6122c5565b3480156104fd57600080fd5b5061023f61050c366004613e59565b61261a565b34801561051d57600080fd5b50610403612682565b34801561053257600080fd5b50610403612691565b34801561054757600080fd5b506104036126a0565b34801561055c57600080fd5b5061057061056b366004613baf565b6126af565b60405161026f9190614ed6565b34801561058957600080fd5b5061023f610598366004613f9f565b6127ba565b3480156105a957600080fd5b5061023f6105b83660046140e0565b612856565b3480156105c957600080fd5b5061023f6105d8366004613f9f565b612922565b3480156105e957600080fd5b5061023f6105f8366004613737565b612986565b34801561060957600080fd5b5061061d61061836600461390f565b612a30565b60405161026f919061454a565b34801561063657600080fd5b50610403612aed565b34801561064b57600080fd5b5061023f61065a366004613737565b612afc565b34801561066b57600080fd5b5061023f61067a366004614056565b612bfe565b6005546001600160a01b031633146106b25760405162461bcd60e51b81526004016106a99061462b565b60405180910390fd5b60006106bd85612c38565b604051637544f15560e11b81529091506001600160a01b0382169063ea89e2aa906106f0908c908a908990600401614c2c565b6040805180830381600087803b15801561070957600080fd5b505af1925050508015610739575060408051601f3d908101601f19168201909252610736918101906141b4565b60015b6108025760018686600087878760405160200161075c9796959493929190614fa7565b60408051601f1981840301815282825261ffff8c166000908152600660205291909120909161078c908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906107be9291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60018a8a8a6040516107f59493929190614f3a565b60405180910390a16108e0565b6001888884848989604051602001610820979695949392919061502e565b60408051601f1981840301815282825261ffff8e1660009081526006602052919091209091610850908d9061440f565b908152602001604051809103902060008b815260200190815260200160002090805190602001906108829291906134af565b5089604051610891919061440f565b6040518091039020897f6ace246fa15cf1d5decabf654b1e8581a4422e0fcf4c1ed4bf83f41687caec198d8b8b8a8a89896040516108d59796959493929190614e48565b60405180910390a350505b505050505050505050565b600554604051630a51236960e01b815260009182916001600160a01b0390911690630a5123699061092c908c908c908c908c908c908c908c90600401614e88565b604080518083038186803b15801561094357600080fd5b505afa158015610957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097b91906141b4565b9150915097509795505050505050565b610993612ce6565b6001600160a01b03166109a4611e81565b6001600160a01b0316146109ed576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006109f883612c38565b6040516369fe0e2d60e01b81529091506001600160a01b038216906369fe0e2d90610a27908590600401614ed6565b600060405180830381600087803b158015610a4157600080fd5b505af1158015610a55573d6000803e3d6000fd5b50505050505050565b610a66612ce6565b6001600160a01b0316610a77611e81565b6001600160a01b031614610ac0576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6000610acb85612c38565b6040516320d6bc7560e01b81529091506001600160a01b038216906320d6bc7590610afe90879087908790600401614c2c565b600060405180830381600087803b158015610b1857600080fd5b505af11580156108e0573d6000803e3d6000fd5b600760209081526000938452604080852084518086018401805192815290840195840195909520945292815290835291819020805460018083015460028085015460038601805488516101009682161596909602600019011692909204601f81018990048902850189019097528684526001600160a01b03948516979296941694939091830182828015610c015780601f10610bd657610100808354040283529160200191610c01565b820191906000526020600020905b815481529060010190602001808311610be457829003601f168201915b5050505050905084565b6005546001600160a01b03163314610c355760405162461bcd60e51b81526004016106a99061462b565b6108e0898989898989898989612cea565b610c4e612ce6565b6001600160a01b0316610c5f611e81565b6001600160a01b031614610ca8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116610cce5760405162461bcd60e51b81526004016106a99061483c565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b61ffff84166000908152600760205260408082209051610d1390869086906143ff565b9081526040805160209281900383018120600086815290845282902060808201835280546001600160a01b039081168352600180830154868501526002808401549092168486015260038301805486516101009382161593909302600019011692909204601f810187900487028201870190955284815292949193606086019392830182828015610de55780601f10610dba57610100808354040283529160200191610de5565b820191906000526020600020905b815481529060010190602001808311610dc857829003601f168201915b5050509190925250505060408101519091506001600160a01b0316610e1c5760405162461bcd60e51b81526004016106a990614873565b604080516080810182526000808252602080830182905282840182905283518082018552828152606084015261ffff89168252600790528290209151909190610e6890879087906143ff565b90815260408051602092819003830190206000868152908352819020835181546001600160a01b03199081166001600160a01b0392831617835585850151600184015592850151600283018054909416911617909155606083015180519192610ed9926003850192909101906134af565b505050604080820151825160208401516060850151935163ab8236f360e01b81526001600160a01b039093169363ab8236f393610afe938b938b938b938b939291906004016149e0565b610f2b612ce6565b6001600160a01b0316610f3c611e81565b6001600160a01b031614610f85576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6005546001600160a01b0316158015610fa757506002546001600160a01b0316155b610fc35760405162461bcd60e51b81526004016106a99061455d565b6001600160a01b038216610fe95760405162461bcd60e51b81526004016106a990614775565b6001600160a01b03811661100f5760405162461bcd60e51b81526004016106a990614707565b600580546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055565b611045612ce6565b6001600160a01b0316611056611e81565b6001600160a01b03161461109f576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006110aa87612c38565b60405163e065608b60e01b81529091506001600160a01b0382169063e065608b906110e19089908990899089908990600401614521565b600060405180830381600087803b1580156110fb57600080fd5b505af115801561110f573d6000803e3d6000fd5b5050505050505050505050565b6004546001600160a01b031633146111465760405162461bcd60e51b81526004016106a990614662565b600061115183612c38565b60405163011dbbf960e61b81529091506001600160a01b0382169063476efe4090610a2790859060040161442b565b61ffff841660009081526006602052604080822090516111a390869086906143ff565b90815260408051602092819003830181206000868152908452829020805460026001821615610100026000190190911604601f8101859004850283018501909352828252909290919083018282801561123d5780601f106112125761010080835404028352916020019161123d565b820191906000526020600020905b81548152906001019060200180831161122057829003601f168201915b5050505050905060008151116112655760405162461bcd60e51b81526004016106a990614699565b6040805160208082018352600080835261ffff891681526006909152829020915190919061129690879087906143ff565b9081526020016040518091039020600084815260200190815260200160002090805190602001906112c89291906134af565b50602081015160ff811660021415611353576000806000806000868060200190518101906112f69190614204565b95509550955095509550506113498b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92508a9150899050888888613166565b50505050506113f5565b60ff8116600314156113dd576000806000806000808780602001905181019061137c9190614263565b965096509650965096509650506113d28c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508b91508a905089898989612cea565b5050505050506113f5565b60405162461bcd60e51b81526004016106a9906148e1565b505050505050565b6001600160a01b0382166114235760405162461bcd60e51b81526004016106a99061494f565b61ffff8616600090815260066020526040808220905161144690889088906143ff565b90815260408051602092819003830181206000888152908452829020805460026001821615610100026000190190911604601f810185900485028301850190935282825290929091908301828280156114e05780601f106114b5576101008083540402835291602001916114e0565b820191906000526020600020905b8154815290600101906020018083116114c357829003601f168201915b5050505050905060008151116115085760405162461bcd60e51b81526004016106a990614699565b602081015160ff81166001146115305760405162461bcd60e51b81526004016106a9906148e1565b506040805160208082018352600080835261ffff8b1681526006909152829020915190919061156290899089906143ff565b9081526020016040518091039020600086815260200190815260200160002090805190602001906115949291906134af565b50604081015160608201516115a761353b565b60006115b283612c38565b604051630474ec6160e11b81529091506001600160a01b038216906308e9d8c2906115e3908e908890600401614b0e565b6040805180830381600087803b1580156115fc57600080fd5b505af1158015611610573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163491906137c3565b6005546040516396aae4af60e01b81529193506001600160a01b031691506396aae4af903490611670908e908b9087908c908c90600401614995565b6000604051808303818588803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050505050505050505050505050565b6116b6612ce6565b6001600160a01b03166116c7611e81565b6001600160a01b031614611710576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611764612ce6565b6001600160a01b0316611775611e81565b6001600160a01b0316146117be576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b0386166117e45760405162461bcd60e51b81526004016106a9906145ad565b600254604051637af935a160e01b81526001600160a01b0390911690637af935a19061181e908a908a908a908a908a908a90600401614edf565b602060405180830381600087803b15801561183857600080fd5b505af115801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613753565b90505b9695505050505050565b611885612ce6565b6001600160a01b0316611896611e81565b6001600160a01b0316146118df576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006118ea85612c38565b60405163a985565f60e01b81529091506001600160a01b0382169063a985565f90610afe90879087908790600401614c0e565b6005546001600160a01b031633146119475760405162461bcd60e51b81526004016106a99061462b565b6119578888888888888888613166565b5050505050505050565b600260015414156119a7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0386166119d25760405162461bcd60e51b81526004016106a99061494f565b600085116119f25760405162461bcd60e51b81526004016106a9906145e4565b6119fa613555565b611a0261353b565b6000611a0d8b612c38565b90506000816001600160a01b031663f6cd35ee8a6040518263ffffffff1660e01b8152600401611a3d9190614ed6565b60206040518083038186803b158015611a5557600080fd5b505afa158015611a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8d9190613f87565b9050816001600160a01b0316631b7319b68e8d33858d60006040518763ffffffff1660e01b8152600401611ac696959493929190614b4c565b60c060405180830381600087803b158015611ae057600080fd5b505af1158015611af4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b18919061380a565b9350816001600160a01b0316637298a5dc8e8d338d6040518563ffffffff1660e01b8152600401611b4c9493929190614b22565b600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050816001600160a01b03166308e9d8c28e8d6040518363ffffffff1660e01b8152600401611bac929190614b0e565b6040805180830381600087803b158015611bc557600080fd5b505af1158015611bd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfd91906137c3565b92505050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348d8d8d8d87898b8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d11565b6000604051808303818588803b158015611c6c57600080fd5b505af1158015611c80573d6000803e3d6000fd5b5050600180555050505050505050505050505050565b60026001541415611cdc576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556000611cec84612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613f87565b9050611d7781611d7186826132f8565b90613361565b9350611df5826001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015611db557600080fd5b505afa158015611dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ded9190613753565b3384876133c1565b6040516340c10f1960e01b81526001600160a01b038316906340c10f1990611e2390869088906004016144ca565b602060405180830381600087803b158015611e3d57600080fd5b505af1158015611e51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e759190613f87565b50506001805550505050565b6000546001600160a01b031690565b60026001541415611ed6576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b038516611f015760405162461bcd60e51b81526004016106a99061494f565b6000611f0c88612c38565b905060008511611f2e5760405162461bcd60e51b81526004016106a9906147ac565b604051632c3eac2f60e21b81526000906001600160a01b0383169063b0fab0bc90611f679033908a908f908e908c908c90600401614462565b602060405180830381600087803b158015611f8157600080fd5b505af1158015611f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb99190613f87565b905060008111611fdb5760405162461bcd60e51b81526004016106a9906147ed565b604051630474ec6160e11b81526000906001600160a01b038416906308e9d8c29061200c908e908d90600401614b0e565b6040805180830381600087803b15801561202557600080fd5b505af1158015612039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205d91906137c3565b9050600560009054906101000a90046001600160a01b03166001600160a01b0316633cef94b9348d8d8d8d87898e8e8e6040518b63ffffffff1660e01b8152600401611c5399989796959493929190614d9d565b6120b9612ce6565b6001600160a01b03166120ca611e81565b6001600160a01b031614612113576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061211e83612c38565b60405163ac2cc36b60e01b81529091506001600160a01b0382169063ac2cc36b90610a27908590600401614516565b60026001541415612193576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001556001600160a01b0381166121be5760405162461bcd60e51b81526004016106a99061494f565b60006121c984612c38565b90506000816001600160a01b03166308e9d8c287866040518363ffffffff1660e01b81526004016121fb929190614b0e565b6040805180830381600087803b15801561221457600080fd5b505af1158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c91906137c3565b600554604051632fa7502b60e21b81529192506001600160a01b03169063be9d40ac903490612287908a908a908a908a908990600401614c48565b6000604051808303818588803b1580156122a057600080fd5b505af11580156122b4573d6000803e3d6000fd5b505060018055505050505050505050565b6002600154141561230b576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b60026001558661232d5760405162461bcd60e51b81526004016106a9906148aa565b6001600160a01b0388166123535760405162461bcd60e51b81526004016106a99061494f565b61235b613555565b61236361353b565b600061236e8d612c38565b90506000816001600160a01b031663feb56b156040518163ffffffff1660e01b815260040160206040518083038186803b1580156123ab57600080fd5b505afa1580156123bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e39190613f87565b90506123f381611d718d826132f8565b9a5050806001600160a01b0316631b7319b68f8e338e8e60016040518763ffffffff1660e01b815260040161242d96959493929190614b4c565b60c060405180830381600087803b15801561244757600080fd5b505af115801561245b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247f919061380a565b92506124fd816001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156124bd57600080fd5b505afa1580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190613753565b33838d6133c1565b806001600160a01b03166308e9d8c28f8e6040518363ffffffff1660e01b815260040161252b929190614b0e565b6040805180830381600087803b15801561254457600080fd5b505af1158015612558573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061257c91906137c3565b915050600560009054906101000a90046001600160a01b03166001600160a01b03166351156e73348f8f8f8f87898f8f8f8f8f6040518d63ffffffff1660e01b81526004016125d59b9a99989796959493929190614c7d565b6000604051808303818588803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b50506001805550505050505050505050505050505050565b6005546001600160a01b031633146126445760405162461bcd60e51b81526004016106a99061462b565b600061264f83612c38565b60405163b6addec760e01b81529091506001600160a01b0382169063b6addec790610afe90889088908790600401614bef565b6003546001600160a01b031681565b6004546001600160a01b031681565b6002546001600160a01b031681565b6000600260015414156126f7576040805162461bcd60e51b815260206004820152601f602482015260008051602061510d833981519152604482015290519081900360640190fd5b6002600155826127195760405162461bcd60e51b81526004016106a9906147ac565b60006127288561ffff16612c38565b6040516304c35b0d60e11b81529091506001600160a01b03821690630986b61a9061275b9033908890889060040161443f565b602060405180830381600087803b15801561277557600080fd5b505af1158015612789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ad9190613f87565b6001805595945050505050565b6127c2612ce6565b6001600160a01b03166127d3611e81565b6001600160a01b03161461281c576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b600061282783612c38565b6040516312d72b2f60e21b81529091506001600160a01b03821690634b5cacbc90610a2790859060040161442b565b61285e612ce6565b6001600160a01b031661286f611e81565b6001600160a01b0316146128b8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b60006128c384612c38565b6040516345ec368560e11b81529091506001600160a01b03821690638bd86d0a906128f49086908690600401614b0e565b600060405180830381600087803b15801561290e57600080fd5b505af1158015611957573d6000803e3d6000fd5b6003546001600160a01b0316331461294c5760405162461bcd60e51b81526004016106a99061473e565b600061295783612c38565b604051632f8c40a560e21b81529091506001600160a01b0382169063be31029490610a2790859060040161442b565b61298e612ce6565b6001600160a01b031661299f611e81565b6001600160a01b0316146129e8576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612a0e5760405162461bcd60e51b81526004016106a99061483c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6006602090815260009384526040808520845180860184018051928152908401958401959095209452928152908352918190208054825160026001831615610100026000190190921691909104601f810185900485028201850190935282815292909190830182828015612ae55780601f10612aba57610100808354040283529160200191612ae5565b820191906000526020600020905b815481529060010190602001808311612ac857829003601f168201915b505050505081565b6005546001600160a01b031681565b612b04612ce6565b6001600160a01b0316612b15611e81565b6001600160a01b031614612b5e576040805162461bcd60e51b81526020600482018190526024820152600080516020615174833981519152604482015290519081900360640190fd5b6001600160a01b038116612ba35760405162461bcd60e51b815260040180806020018281038252602681526020018061512d6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000612c0983612c38565b604051637fb6526560e01b81529091506001600160a01b03821690637fb6526590610a27908590600401614516565b60025460405163068bcd8d60e01b81526000916001600160a01b03169063068bcd8d90612c69908590600401614ed6565b60206040518083038186803b158015612c8157600080fd5b505afa158015612c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb99190613753565b90506001600160a01b038116612ce15760405162461bcd60e51b81526004016106a990614918565b919050565b3390565b6000612cf586612c38565b60405163902b8ab760e01b81529091506001600160a01b0382169063902b8ab790612d2a908d908b9089908990600401614b85565b602060405180830381600087803b158015612d4457600080fd5b505af1925050508015612d74575060408051601f3d908101601f19168201909252612d7191810190613f87565b60015b612e3c576003878787878787604051602001612d969796959493929190614fdf565b60408051601f1981840301815282825261ffff8d1660009081526006602052919091209091612dc6908c9061440f565b908152602001604051809103902060008a81526020019081526020016000209080519060200190612df89291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60038b8b8b604051612e2f9493929190614f3a565b60405180910390a161315a565b612e45856134a9565b8015612e52575060008351115b1561110f57846001600160a01b031663ab8236f3878d8d8d876001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612ea357600080fd5b505afa158015612eb7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612edb9190613753565b878a6040518863ffffffff1660e01b8152600401612efe96959493929190614ab5565b600060405180830381600088803b158015612f1857600080fd5b5087f193505050508015612f2a575060015b61110f573d808015612f58576040519150601f19603f3d011682016040523d82523d6000602084013e612f5d565b606091505b506040518060800160405280846001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b158015612fa257600080fd5b505afa158015612fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fda9190613753565b6001600160a01b03168152602001838152602001876001600160a01b0316815260200185815250600760008e61ffff1661ffff1681526020019081526020016000208c60405161302a919061440f565b908152604080516020928190038301902060008e8152908352819020835181546001600160a01b03199081166001600160a01b039283161783558585015160018401559285015160028301805490941691161790915560608301518051919261309b926003850192909101906134af565b509050507f8186389e97ff190cd5e17304ed8188a4a98a6c8add46e6df94462ac7f7e8dd348c8c8c866001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156130fc57600080fd5b505afa158015613110573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131349190613753565b868b8a8860405161314c989796959493929190614a3b565b60405180910390a15061110f565b50505050505050505050565b600061317185612c38565b604051632cc36bab60e21b81529091506001600160a01b0382169063b30daeac906131a8908c908a90899089908990600401614bbd565b600060405180830381600087803b1580156131c257600080fd5b505af19250505080156131d3575060015b61329557600286868686866040516020016131f396959493929190614f71565b60408051601f1981840301815282825261ffff8c1660009081526006602052919091209091613223908b9061440f565b9081526020016040518091039020600089815260200190815260200160002090805190602001906132559291906134af565b507fa5d2ba6de30cc2f2e91c5a29ba66b148c27826954217e2f67cb8983541da21cf60028a8a8a60405161328c9493929190614f3a565b60405180910390a15b86886040516132a4919061440f565b60405180910390207fc7379a02e530fbd0a46ea1ce6fd91987e96535798231a796bdc0e1a688a508738b89898989896040516132e596959493929190614e11565b60405180910390a3505050505050505050565b600080821161334e576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161335757fe5b0490505b92915050565b6000826133705750600061335b565b8282028284828161337d57fe5b04146133ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806151536021913960400191505060405180910390fd5b9392505050565b600080856001600160a01b03166323b872dd8686866040516024016133e8939291906144a6565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613421919061440f565b6000604051808303816000865af19150503d806000811461345e576040519150601f19603f3d011682016040523d82523d6000602084013e613463565b606091505b509150915081801561348d57508051158061348d57508080602001905181019061348d919061376f565b6113f55760405162461bcd60e51b81526004016106a9906146d0565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826134e5576000855561352b565b82601f106134fe57805160ff191683800117855561352b565b8280016001018555821561352b579182015b8281111561352b578251825591602001919060010190613510565b5061353792915061358b565b5090565b604051806040016040528060008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b80821115613537576000815560010161358c565b8035612ce1816150d7565b60008083601f8401126135bc578182fd5b5081356001600160401b038111156135d2578182fd5b6020830191508360208285010111156135ea57600080fd5b9250929050565b600082601f830112613601578081fd5b813561361461360f82615086565b615063565b818152846020838601011115613628578283fd5b816020850160208301379081016020019190915292915050565b600060c08284031215613653578081fd5b60405160c081018181106001600160401b038211171561366f57fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201525092915050565b6000606082840312156136c5578081fd5b604051606081016001600160401b0382821081831117156136e257fe5b816040528293508435835260208501356020840152604085013591508082111561370b57600080fd5b50613718858286016135f1565b6040830152505092915050565b803561ffff81168114612ce157600080fd5b600060208284031215613748578081fd5b81356133ba816150d7565b600060208284031215613764578081fd5b81516133ba816150d7565b600060208284031215613780578081fd5b81516133ba816150ef565b6000806040838503121561379d578081fd5b82356137a8816150d7565b915060208301356137b8816150d7565b809150509250929050565b6000604082840312156137d4578081fd5b604051604081018181106001600160401b03821117156137f057fe5b604052825181526020928301519281019290925250919050565b600060c0828403121561381b578081fd5b6133ba8383613642565b6000806000806060858703121561383a578182fd5b61384385613725565b935060208501356001600160401b0381111561385d578283fd5b613869878288016135ab565b9598909750949560400135949350505050565b60008060008060008060a08789031215613894578384fd5b61389d87613725565b955060208701356001600160401b03808211156138b8578586fd5b6138c48a838b016135ab565b909750955060408901359450606089013591506138e0826150d7565b909250608088013590808211156138f5578283fd5b5061390289828a016136b4565b9150509295509295509295565b600080600060608486031215613923578081fd5b61392c84613725565b925060208401356001600160401b03811115613946578182fd5b613952868287016135f1565b925050604084013590509250925092565b600080600080600080600080610100898b03121561397f578586fd5b61398889613725565b975060208901356001600160401b038111156139a2578687fd5b6139ae8b828c016135f1565b97505060408901359550606089013594506080890135935060a08901356139d4816150d7565b979a969950949793969295929450505060c08201359160e0013590565b6000806000806000806000806000898b036101c0811215613a10578384fd5b613a198b613725565b995060208b01356001600160401b0380821115613a34578586fd5b613a408e838f016135f1565b9a5060408d0135995060608d0135985060808d0135975060a08d0135965060c08d01359150613a6e826150d7565b81955060c060df1984011215613a82578384fd5b604051925060c0830191508282108183111715613a9b57fe5b8160405260e08d013583526101008d013560208401526101208d013560408401526101408d013560608401526101608d013560808401526101808d013560a08401528294506101a08d0135925080831115613af4578384fd5b5050613b028c828d016135f1565b9150509295985092959850929598565b60008060008060008060008060e0898b031215613b2d578182fd5b613b3689613725565b975060208901356001600160401b0380821115613b51578384fd5b613b5d8c838d016135f1565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135915080821115613b8e578384fd5b50613b9b8b828c016135ab565b999c989b5096995094979396929594505050565b600080600060608486031215613bc3578081fd5b613bcc84613725565b9250602084013591506040840135613be3816150d7565b809150509250925092565b60008060008060808587031215613c03578182fd5b613c0c85613725565b935060208501359250604085013591506060850135613c2a816150d7565b939692955090935050565b60008060008060008060008060e0898b031215613c50578182fd5b613c5989613725565b975060208901359650604089013595506060890135613c77816150d7565b94506080890135935060a08901356001600160401b0380821115613c99578384fd5b613ca58c838d016135ab565b909550935060c08b0135915080821115613cbd578283fd5b50613cca8b828c016136b4565b9150509295985092959890939650565b60008060008060008060008060006101008a8c031215613cf8578283fd5b613d018a613725565b985060208a0135975060408a0135965060608a0135613d1f816150d7565b955060808a0135945060a08a0135935060c08a01356001600160401b0380821115613d48578485fd5b613d548d838e016135ab565b909550935060e08c0135915080821115613d6c578283fd5b50613b028c828d016136b4565b60008060008060008060008060008060006101208c8e031215613d9a578485fd5b613da38c613725565b9a5060208c0135995060408c01359850613dbf60608d016135a0565b975060808c0135965060a08c013595506001600160401b038060c08e01351115613de7578586fd5b613df78e60c08f01358f016136b4565b95508060e08e01351115613e09578283fd5b613e198e60e08f01358f016135ab565b90955093506101008d0135811015613e2f578283fd5b50613e418d6101008e01358e016135ab565b81935080925050509295989b509295989b9093969950565b60008060008084860360a0811215613e6f578283fd5b613e7886613725565b9450602086013593506040808701359350605f1982011215613e98578182fd5b50604051604081018181106001600160401b0382111715613eb557fe5b604052606086013581526080909501356020860152509194909350909190565b600080600080600080600060a0888a031215613eef578081fd5b613ef888613725565b96506020880135613f08816150fd565b955060408801356001600160401b0380821115613f23578283fd5b613f2f8b838c016135ab565b909750955060608a0135915080821115613f47578283fd5b613f538b838c016135ab565b909550935060808a0135915080821115613f6b578283fd5b50613f788a828b016136b4565b91505092959891949750929550565b600060208284031215613f98578081fd5b5051919050565b60008060408385031215613fb1578182fd5b8235915060208301356137b8816150d7565b60008060008060008060c08789031215613fdb578384fd5b863595506020870135613fed816150d7565b94506040870135613ffd816150fd565b9350606087013561400d816150fd565b925060808701356001600160401b0380821115614028578384fd5b6140348a838b016135f1565b935060a0890135915080821115614049578283fd5b5061390289828a016135f1565b60008060408385031215614068578182fd5b8235915060208301356137b8816150ef565b60008060008060008060c08789031215614092578384fd5b8635955060208701356140a4816150ef565b9450604087013593506060870135925060808701356140c2816150ef565b915060a08701356140d2816150ef565b809150509295509295509295565b6000806000606084860312156140f4578081fd5b8335925061410460208501613725565b9150604084013590509250925092565b60008060008060808587031215614129578182fd5b8435935061413960208601613725565b92506040850135915061414e60608601613725565b905092959194509250565b6000806000806080858703121561416e578182fd5b8435935061417e60208601613725565b93969395505050506040820135916060013590565b600080604083850312156141a5578182fd5b50508035926020909101359150565b600080604083850312156141c6578182fd5b505080516020909101519092909150565b6000806000606084860312156141eb578081fd5b83359250602084013591506040840135613be3816150d7565b60008060008060008060c0878903121561421c578384fd5b8651614227816150fd565b8096505060208701519450604087015193506060870151614247816150d7565b809350506080870151915060a087015190509295509295509295565b6000806000806000806000610180888a03121561427e578081fd5b8751614289816150fd565b8097505060208801519550604088015194506060880151935060808801516142b0816150d7565b92506142bf8960a08a01613642565b91506101608801516001600160401b038111156142da578182fd5b8801601f81018a136142ea578182fd5b80516142f861360f82615086565b8181528b602083850101111561430c578384fd5b61431d8260208301602086016150a7565b80935050505092959891949750929550565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526143718160208601602086016150a7565b601f01601f19169290920160200192915050565b80518252602090810151910152565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a08301525050565b600081518352602082015160208401526040820151606060408501526143f76060850182614359565b949350505050565b6000828483379101908152919050565b600082516144218184602087016150a7565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b600060018060a01b038816825286602083015261ffff8616604083015284606083015260a0608083015261449a60a08301848661432f565b98975050505050505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038581168252602082018590528316604082015260806060820181905260009061187390830184614359565b901515815260200190565b941515855260208501939093526040840191909152151560608301521515608082015260a00190565b6000602082526133ba6020830184614359565b60208082526030908201527f53746172676174653a2062726964676520616e6420666163746f727920616c7260408201526f1958591e481a5b9a5d1a585b1a5e995960821b606082015260800190565b6020808252601e908201527f53746172676174653a205f746f6b656e2063616e6e6f74206265203078300000604082015260600190565b60208082526027908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152666d52656d6f746560c81b606082015260800190565b6020808252601e908201527f4272696467653a2063616c6c6572206d757374206265204272696467652e0000604082015260600190565b6020808252601b908201527f53746172676174653a206f6e6c79206d696e744665654f776e65720000000000604082015260600190565b60208082526019908201527f53746172676174653a206e6f2072657472792072657665727400000000000000604082015260600190565b6020808252601e908201527f53746172676174653a205452414e534645525f46524f4d5f4641494c45440000604082015260600190565b6020808252601d908201527f53746172676174653a20666163746f72792063616e7420626520307830000000604082015260600190565b6020808252601f908201527f53746172676174653a206f6e6c792070726f746f636f6c4665654f776e657200604082015260600190565b6020808252601c908201527f53746172676174653a206272696467652063616e742062652030783000000000604082015260600190565b60208082526021908201527f53746172676174653a206e6f7420656e6f756768206c7020746f2072656465656040820152606d60f81b606082015260800190565b6020808252602f908201527f53746172676174653a206e6f7420656e6f756768206c7020746f20726564656560408201526e1b481dda5d1a08185b5bdd5b9d14d1608a1b606082015260800190565b6020808252601e908201527f53746172676174653a205f6f776e65722063616e6e6f74206265203078300000604082015260600190565b6020808252601f908201527f53746172676174653a20636163686520616c726561647920636c656172656400604082015260600190565b60208082526017908201527f53746172676174653a2063616e6e6f7420737761702030000000000000000000604082015260600190565b6020808252601f908201527f53746172676174653a20696e76616c69642066756e6374696f6e207479706500604082015260600190565b6020808252601d908201527f53746172676174653a20506f6f6c20646f6573206e6f74206578697374000000604082015260600190565b60208082526026908201527f53746172676174653a205f726566756e64416464726573732063616e6e6f742060408201526506265203078360d41b606082015260800190565b61ffff861681526001600160a01b038516602082015260006149ba6040830186614385565b60c060808301526149ce60c08301856143ce565b82810360a084015261449a8185614359565b600061ffff8916825260c060208301526149fe60c08301888a61432f565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614a2d8185614359565b9a9950505050505050505050565b600061010061ffff8b168352806020840152614a598184018b614359565b604084018a90526001600160a01b03898116606086015260808501899052871660a085015283810360c08501529050614a928186614359565b905082810360e0840152614aa68185614359565b9b9a5050505050505050505050565b600061ffff8816825260c06020830152614ad260c0830188614359565b604083018790526001600160a01b03861660608401526080830185905282810360a0840152614b018185614359565b9998505050505050505050565b61ffff929092168252602082015260400190565b61ffff94909416845260208401929092526001600160a01b03166040830152606082015260800190565b61ffff96909616865260208601949094526001600160a01b0392909216604085015260608401526080830152151560a082015260c00190565b61ffff85168152602081018490526001600160a01b03831660408201526101208101614bb46060830184614394565b95945050505050565b61ffff95909516855260208501939093526001600160a01b039190911660408401526060830152608082015260a00190565b61ffff8416815260208101839052608081016143f76040830184614385565b61ffff93841681526020810192909252909116604082015260600190565b61ffff9390931683526020830191909152604082015260600190565b61ffff8616815260208101859052604081018490526001600160a01b038316606082015260c081016118736080830184614385565b61ffff8c168152602081018b9052604081018a90526001600160a01b038916606082015260006101e0614cb3608084018b614385565b614cc060c084018a614394565b80610180840152614cd3818401896143ce565b90508281036101a0840152614ce981878961432f565b90508281036101c0840152614cff81858761432f565b9e9d5050505050505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b038716606082015260006101e0614d476080840189614385565b614d5460c0840188614394565b80610180840152614d67818401876143ce565b90508281036101a0840152614d7d81858761432f565b8381036101c0909401939093525081526020019998505050505050505050565b61ffff8a16815260208101899052604081018890526001600160a01b03871660608201526000610120614dd36080840189614385565b8660c08401528060e0840152614dec818401868861432f565b9050828103610100840152614e0181856143ce565b9c9b505050505050505050505050565b61ffff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600061ffff8916825287602083015286604083015260c06060830152614e7260c08301868861432f565b60808301949094525060a0015295945050505050565b600061ffff8916825260ff8816602083015260a06040830152614eaf60a08301878961432f565b8281036060840152614ec281868861432f565b90508281036080840152614a2d81856143ce565b90815260200190565b8681526001600160a01b038616602082015260ff85811660408301528416606082015260c060808201819052600090614f1a90830185614359565b82810360a0840152614b018185614359565b918252602082015260400190565b600060ff8616825261ffff8516602083015260806040830152614f606080830185614359565b905082606083015295945050505050565b60ff969096168652602086019490945260408501929092526001600160a01b03166060840152608083015260a082015260c00190565b600060ff8916825287602083015286604083015260ff8616606083015284608083015260c060a0830152614b0160c08301848661432f565b60ff881681526020810187905260408101869052606081018590526001600160a01b0384166080820152600061018061501b60a0840186614394565b80610160840152614a2d81840185614359565b600060ff8916825287602083015286604083015285606083015284608083015260c060a0830152614b0160c08301848661432f565b6040518181016001600160401b038111828210171561507e57fe5b604052919050565b60006001600160401b0382111561509957fe5b50601f01601f191660200190565b60005b838110156150c25781810151838201526020016150aa565b838111156150d1576000848401525b50505050565b6001600160a01b03811681146150ec57600080fd5b50565b80151581146150ec57600080fd5b60ff811681146150ec57600080fdfe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece64736f6c63430007060033

Deployed ByteCode Sourcemap

553:20274:13:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12905:1469;;;;;;;;;;-1:-1:-1;12905:1469:13;;;;;:::i;:::-;;:::i;:::-;;8851:392;;;;;;;;;;-1:-1:-1;8851:392:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;19334:152;;;;;;;;;;-1:-1:-1;19334:152:13;;;;;:::i;:::-;;:::i;18171:266::-;;;;;;;;;;-1:-1:-1;18171:266:13;;;;;:::i;:::-;;:::i;1642:91::-;;;;;;;;;;-1:-1:-1;1642:91:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;15711:425::-;;;;;;;;;;-1:-1:-1;15711:425:13;;;;;:::i;:::-;;:::i;18968:181::-;;;;;;;;;;-1:-1:-1;18968:181:13;;;;;:::i;:::-;;:::i;11964:540::-;;;;;;;;;;-1:-1:-1;11964:540:13;;;;;:::i;:::-;;:::i;2952:465::-;;;;;;;;;;-1:-1:-1;2952:465:13;;;;;:::i;:::-;;:::i;19835:358::-;;;;;;;;;;-1:-1:-1;19835:358:13;;;;;:::i;:::-;;:::i;20347:228::-;;;;;;;;;;-1:-1:-1;20347:228:13;;;;;:::i;:::-;;:::i;10487:1471::-;;;;;;:::i;:::-;;:::i;9249:1232::-;;;;;;:::i;:::-;;:::i;1700:145:3:-;;;;;;;;;;;;;:::i;17749:416:13:-;;;;;;;;;;-1:-1:-1;17749:416:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;18685:277::-;;;;;;;;;;-1:-1:-1;18685:277:13;;;;;:::i;:::-;;:::i;14380:402::-;;;;;;;;;;-1:-1:-1;14380:402:13;;;;;:::i;:::-;;:::i;5936:1147::-;;;;;;:::i;:::-;;:::i;4370:407::-;;;;;;;;;;-1:-1:-1;4370:407:13;;;;;:::i;:::-;;:::i;1068:85:3:-;;;;;;;;;;;;;:::i;7452:878:13:-;;;;;;:::i;:::-;;:::i;19673:156::-;;;;;;;;;;-1:-1:-1;19673:156:13;;;;;:::i;:::-;;:::i;8336:509::-;;;;;;:::i;:::-;;:::i;4783:1147::-;;;;;;:::i;:::-;;:::i;12510:277::-;;;;;;;;;;-1:-1:-1;12510:277:13;;;;;:::i;:::-;;:::i;1309:31::-;;;;;;;;;;;;;:::i;1407:27::-;;;;;;;;;;;;;:::i;1254:22::-;;;;;;;;;;;;;:::i;7089:357::-;;;;;;;;;;-1:-1:-1;7089:357:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;19492:175::-;;;;;;;;;;-1:-1:-1;19492:175:13;;;;;:::i;:::-;;:::i;18443:236::-;;;;;;;;;;-1:-1:-1;18443:236:13;;;;;:::i;:::-;;:::i;20581:244::-;;;;;;;;;;-1:-1:-1;20581:244:13;;;;;:::i;:::-;;:::i;19155:173::-;;;;;;;;;;-1:-1:-1;19155:173:13;;;;;:::i;:::-;;:::i;1523:82::-;;;;;;;;;;-1:-1:-1;1523:82:13;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1497:20::-;;;;;;;;;;;;;:::i;1994:240:3:-;;;;;;;;;;-1:-1:-1;1994:240:3;;;;;:::i;:::-;;:::i;20199:142:13:-;;;;;;;;;;-1:-1:-1;20199:142:13;;;;;:::i;:::-;;:::i;12905:1469::-;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;;;;;;;;;13172:9:::1;13184:20;13193:10;13184:8;:20::i;:::-;13218:65;::::0;-1:-1:-1;;;13218:65:13;;13172:32;;-1:-1:-1;;;;;;13218:29:13;::::1;::::0;::::1;::::0;:65:::1;::::0;13248:11;;13261:10;;13273:9;;13218:65:::1;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;-1:-1:-1::0;13218:65:13::1;::::0;;::::1;;::::0;;::::1;-1:-1:-1::0;;13218:65:13::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;;13214:1154;;805:1;14228:10;14240;14252:1;14255:9;14266:3;;14189:81;;;;;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;14189:81:13;;::::1;::::0;;;;;;14140:25:::1;::::0;::::1;;::::0;;;:12:::1;14189:81;14140:25:::0;;;;;14189:81;;14140:38:::1;::::0;14166:11;;14140:38:::1;:::i;:::-;;;;;;;;;;;;;:46;14179:6;14140:46;;;;;;;;;;;:130;;;;;;;;;;;;:::i;:::-;;14289:68;805:1;14324:11;14337;14350:6;14289:68;;;;;;;;;:::i;:::-;;;;;;;;13214:1154;;;805:1;13474:10;13502;13530:14;13562:12;13592:3;;13402:207;;;;;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;13402:207:13;;::::1;::::0;;;;;;13353:25:::1;::::0;::::1;;::::0;;;:12:::1;13402:207;13353:25:::0;;;;;13402:207;;13353:38:::1;::::0;13379:11;;13353:38:::1;:::i;:::-;;;;;;;;;;;;;:46;13392:6;13353:46;;;;;;;;;;;:256;;;;;;;;;;;;:::i;:::-;;13726:11;13628:110;;;;;;:::i;:::-;;;;;;;;13718:6;13628:110;13646:11;13659:10;13671;13683:3;;13688:14;13704:12;13628:110;;;;;;;;;;;;:::i;:::-;;;;;;;;13284:465;;13214:1154;2916:1;12905:1469:::0;;;;;;;;:::o;8851:392::-;9134:6;;:102;;-1:-1:-1;;;9134:102:13;;9099:7;;;;-1:-1:-1;;;;;9134:6:13;;;;:24;;:102;;9159:11;;9172:13;;9187:10;;;;9199:23;;;;9224:11;;9134:102;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9127:109;;;;8851:392;;;;;;;;;;:::o;19334:152::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;19417:9:13::1;19429:17;19438:7;19429:8;:17::i;:::-;19456:23;::::0;-1:-1:-1;;;19456:23:13;;19417:29;;-1:-1:-1;;;;;;19456:11:13;::::1;::::0;::::1;::::0;:23:::1;::::0;19468:10;;19456:23:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1350:1:3;19334:152:13::0;;:::o;18171:266::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;18337:9:13::1;18349:17;18358:7;18349:8;:17::i;:::-;18376:54;::::0;-1:-1:-1;;;18376:54:13;;18337:29;;-1:-1:-1;;;;;;18376:20:13;::::1;::::0;::::1;::::0;:54:::1;::::0;18397:11;;18410:10;;18422:7;;18376:54:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;1642:91:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1642:91:13;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1642:91:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;15711:425::-;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;16025:104:::1;16037:11;16050;16063:6;16071:10;16083;16095:14;16111:3;16116:2;16120:8;16025:11;:104::i;18968:181::-:0;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;19050:22:13;::::1;19042:65;;;;-1:-1:-1::0;;;19042:65:13::1;;;;;;;:::i;:::-;19117:16;:25:::0;;-1:-1:-1;;;;;;19117:25:13::1;-1:-1:-1::0;;;;;19117:25:13;;;::::1;::::0;;;::::1;::::0;;18968:181::o;11964:540::-;12125:29;;;12102:20;12125:29;;;:16;:29;;;;;;:42;;;;12155:11;;;;12125:42;:::i;:::-;;;;;;;;;;;;;;;;:50;;;;;;;;;;12102:73;;;;;;;-1:-1:-1;;;;;12102:73:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12102:73:13;;;;;;;;;;;;;;;;;;;;;;;;12125:42;;:50;;12102:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;12102:73:13;;;;-1:-1:-1;;;12193:5:13;;;;12102:73;;-1:-1:-1;;;;;;12193:21:13;12185:65;;;;-1:-1:-1;;;12185:65:13;;;;;;;:::i;:::-;12339:45;;;;;;;;-1:-1:-1;12339:45:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12286:29;;;;;:16;:29;;;;;:42;;12339:45;;12286:29;:42;;12316:11;;;;12286:42;:::i;:::-;;;;;;;;;;;;;;;;:50;;;;;;;;;;:98;;;;-1:-1:-1;;;;;;12286:98:13;;;-1:-1:-1;;;;;12286:98:13;;;;;;;;;;-1:-1:-1;12286:98:13;;;;;;;;;;;;;;;;;;;;;;;;;;;:50;;:98;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;12412:5:13;;;;;12463:8;;12473:11;;;;12486:10;;;;12394:103;;-1:-1:-1;;;12394:103:13;;-1:-1:-1;;;;;12394:34:13;;;;;;:103;;12429:11;;12442;;;;12455:6;;12463:8;12473:11;12486:10;12394:103;;;:::i;2952:465::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;3060:6:13::1;::::0;-1:-1:-1;;;;;3060:6:13::1;3052:31:::0;:67;::::1;;;-1:-1:-1::0;3095:7:13::1;::::0;-1:-1:-1;;;;;3095:7:13::1;3087:32:::0;3052:67:::1;3044:128;;;;-1:-1:-1::0;;;3044:128:13::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;3205:32:13;::::1;3197:73;;;;-1:-1:-1::0;;;3197:73:13::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;3288:33:13;::::1;3280:75;;;;-1:-1:-1::0;;;3280:75:13::1;;;;;;;:::i;:::-;3366:6;:16:::0;;-1:-1:-1;;;;;3366:16:13;;::::1;-1:-1:-1::0;;;;;;3366:16:13;;::::1;;::::0;;;3392:7:::1;:18:::0;;;;;::::1;::::0;::::1;;::::0;;2952:465::o;19835:358::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;20059:9:13::1;20071:17;20080:7;20071:8;:17::i;:::-;20098:88;::::0;-1:-1:-1;;;20098:88:13;;20059:29;;-1:-1:-1;;;;;;20098:18:13;::::1;::::0;::::1;::::0;:88:::1;::::0;20117:8;;20127:12;;20141:10;;20153:16;;20171:14;;20098:88:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;1350:1:3;19835:358:13::0;;;;;;:::o;20347:228::-;20429:12;;-1:-1:-1;;;;;20429:12:13;20445:10;20429:26;20421:66;;;;-1:-1:-1;;;20421:66:13;;;;;;;:::i;:::-;20497:9;20509:17;20518:7;20509:8;:17::i;:::-;20536:32;;-1:-1:-1;;;20536:32:13;;20497:29;;-1:-1:-1;;;;;;20536:27:13;;;;;:32;;20564:3;;20536:32;;;:::i;10487:1471::-;10652:25;;;10629:20;10652:25;;;:12;:25;;;;;;:38;;;;10678:11;;;;10652:38;:::i;:::-;;;;;;;;;;;;;;;;:46;;;;;;;;;;10629:69;;;;;;;;;-1:-1:-1;;10629:69:13;;;;;;;;;;;;;;;;;;;;;;;10652:38;;:46;;10629:69;;;10652:46;10629:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10733:1;10716:7;:14;:18;10708:56;;;;-1:-1:-1;;;10708:56:13;;;;;;;:::i;:::-;10795:51;;;;;;;;;-1:-1:-1;10795:51:13;;;:25;;;;;:12;:25;;;;;;:38;;:51;;:25;:38;;10821:11;;;;10795:38;:::i;:::-;;;;;;;;;;;;;:46;10834:6;10795:46;;;;;;;;;;;:51;;;;;;;;;;;;:::i;:::-;-1:-1:-1;10943:2:13;10930:16;;10924:23;10971:48;;;871:1;10971:48;10967:985;;;11038:17;11057;11076:10;11088:16;11106:20;11158:7;11130:119;;;;;;;;;;;;:::i;:::-;11035:214;;;;;;;;;;;11263:104;11284:11;11297;;11263:104;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11310:6:13;;-1:-1:-1;11318:9:13;;-1:-1:-1;11329:9:13;;-1:-1:-1;11340:2:13;11344:8;11354:12;11263:20;:104::i;:::-;10967:985;;;;;;;;11461:38;;;927:1;11461:38;11457:495;;;11518:17;11537;11556:21;11579:10;11591:21;11614:14;11660:7;11632:131;;;;;;;;;;;;:::i;:::-;11515:248;;;;;;;;;;;;;11777:92;11789:11;11802;;11777:92;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11815:6:13;;-1:-1:-1;11823:9:13;;-1:-1:-1;11834:9:13;;-1:-1:-1;11845:13:13;11860:2;11864:1;11867;11777:11;:92::i;:::-;11457:495;;;;;;;;;11900:41;;-1:-1:-1;;;11900:41:13;;;;;;;:::i;11457:495::-;10487:1471;;;;;;:::o;9249:1232::-;-1:-1:-1;;;;;9481:30:13;;9473:81;;;;-1:-1:-1;;;9473:81:13;;;;;;;:::i;:::-;9587:25;;;9564:20;9587:25;;;:12;:25;;;;;;:38;;;;9613:11;;;;9587:38;:::i;:::-;;;;;;;;;;;;;;;;:46;;;;;;;;;;9564:69;;;;;;;;;-1:-1:-1;;9564:69:13;;;;;;;;;;;;;;;;;;;;;;;9587:38;;:46;;9564:69;;;9587:46;9564:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9668:1;9651:7;:14;:18;9643:56;;;;-1:-1:-1;;;9643:56:13;;;;;;;:::i;:::-;9817:2;9804:16;;9798:23;9856:42;;;805:1;9856:42;9848:86;;;;-1:-1:-1;;;9848:86:13;;;;;;;:::i;:::-;-1:-1:-1;9975:51:13;;;;;;;;;-1:-1:-1;9975:51:13;;;:25;;;;;:12;:25;;;;;;:38;;:51;;:25;:38;;10001:11;;;;9975:38;:::i;:::-;;;;;;;;;;;;;:46;10014:6;9975:46;;;;;;;;;;;:51;;;;;;;;;;;;:::i;:::-;-1:-1:-1;10146:2:13;10133:16;;10127:23;10195:2;10182:16;;10176:23;10219;;:::i;:::-;10266:9;10278:19;10287:9;10278:8;:19::i;:::-;10315:40;;-1:-1:-1;;;10315:40:13;;10266:31;;-1:-1:-1;;;;;;10315:16:13;;;;;:40;;10332:11;;10345:9;;10315:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10376:6;;:98;;-1:-1:-1;;;10376:98:13;;10311:44;;-1:-1:-1;;;;;;10376:6:13;;-1:-1:-1;10376:26:13;;10410:9;;10376:98;;10421:11;;10434:14;;10311:44;;10453:11;;10466:7;;10376:98;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9249:1232;;;;;;;;;;:::o;1700:145:3:-;1291:12;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;1806:1:::1;1790:6:::0;;1769:40:::1;::::0;-1:-1:-1;;;;;1790:6:3;;::::1;::::0;1769:40:::1;::::0;1806:1;;1769:40:::1;1836:1;1819:19:::0;;-1:-1:-1;;;;;;1819:19:3::1;::::0;;1700:145::o;17749:416:13:-;17973:7;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;18000:22:13;::::1;17992:65;;;;-1:-1:-1::0;;;17992:65:13::1;;;;;;;:::i;:::-;18074:7;::::0;:84:::1;::::0;-1:-1:-1;;;18074:84:13;;-1:-1:-1;;;;;18074:7:13;;::::1;::::0;:18:::1;::::0;:84:::1;::::0;18093:7;;18102:6;;18110:15;;18127:14;;18143:5;;18150:7;;18074:84:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18067:91;;1350:1:3;17749:416:13::0;;;;;;;;:::o;18685:277::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;18856:9:13::1;18868:17;18877:7;18868:8;:17::i;:::-;18895:60;::::0;-1:-1:-1;;;18895:60:13;;18856:29;;-1:-1:-1;;;;;;18895:26:13;::::1;::::0;::::1;::::0;:60:::1;::::0;18922:11;;18935:10;;18947:7;;18895:60:::1;;;:::i;14380:402::-:0;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;14666:109:::1;14687:11;14700;14713:6;14721:10;14733;14745:3;14750:9;14761:13;14666:20;:109::i;:::-;14380:402:::0;;;;;;;;:::o;5936:1147::-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;-1:-1:-1;;;;;6266:30:13;::::1;6258:81;;;;-1:-1:-1::0;;;6258:81:13::1;;;;;;;:::i;:::-;6369:1;6357:9;:13;6349:65;;;;-1:-1:-1::0;;;6349:65:13::1;;;;;;;:::i;:::-;6424:21;;:::i;:::-;6455:23;;:::i;:::-;6502:9;6514:20;6523:10;6514:8;:20::i;:::-;6502:32;;6548:16;6567:4;-1:-1:-1::0;;;;;6567:17:13::1;;6585:9;6567:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6548:47;;6661:4;-1:-1:-1::0;;;;;6661:9:13::1;;6671:11;6684:10;6696;6708:8;6718:12;6732:5;6661:77;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6657:81;;6752:4;-1:-1:-1::0;;;;;6752:17:13::1;;6770:11;6783:10;6795;6807:9;6752:65;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;6835:4;-1:-1:-1::0;;;;;6835:16:13::1;;6852:11;6865:10;6835:41;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6831:45;;2419:1:8;;6966:6:13;;;;;;;;;-1:-1:-1::0;;;;;6966:6:13::1;-1:-1:-1::0;;;;;6966:11:13::1;;6985:9;6996:11;7009:10;7021;7033:14;7049:1;7052;7055:11;7068:3;;6966:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;;;;;;;;;;;5936:1147:13:o;4370:407::-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;4512:9:13::1;4524:17;4533:7:::0;4524:8:::1;:17::i;:::-;4512:29;;4551:19;4573:4;-1:-1:-1::0;;;;;4573:16:13::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4551:40:::0;-1:-1:-1;4613:43:13::1;4551:40:::0;4613:26:::1;:9:::0;4551:40;4613:13:::1;:26::i;:::-;:30:::0;::::1;:43::i;:::-;4601:55;;4666:69;4684:4;-1:-1:-1::0;;;;;4684:10:13::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4698:10;4718:4;4725:9;4666:17;:69::i;:::-;4745:25;::::0;-1:-1:-1;;;4745:25:13;;-1:-1:-1;;;;;4745:9:13;::::1;::::0;::::1;::::0;:25:::1;::::0;4755:3;;4760:9;;4745:25:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;4370:407:13:o;1068:85:3:-;1114:7;1140:6;-1:-1:-1;;;;;1140:6:3;1068:85;:::o;7452:878:13:-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;-1:-1:-1;;;;;7751:30:13;::::1;7743:81;;;;-1:-1:-1::0;;;7743:81:13::1;;;;;;;:::i;:::-;7834:9;7846:20;7855:10;7846:8;:20::i;:::-;7834:32;;7896:1;7884:9;:13;7876:59;;;;-1:-1:-1::0;;;7876:59:13::1;;;;;;;:::i;:::-;7964:69;::::0;-1:-1:-1;;;7964:69:13;;7945:16:::1;::::0;-1:-1:-1;;;;;7964:16:13;::::1;::::0;::::1;::::0;:69:::1;::::0;7981:10:::1;::::0;7993:9;;8004:11;;8017:10;;8029:3;;;;7964:69:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7945:88;;8062:1;8051:8;:12;8043:72;;;;-1:-1:-1::0;;;8043:72:13::1;;;;;;;:::i;:::-;8152:41;::::0;-1:-1:-1;;;8152:41:13;;8126:23:::1;::::0;-1:-1:-1;;;;;8152:16:13;::::1;::::0;::::1;::::0;:41:::1;::::0;8169:11;;8182:10;;8152:41:::1;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8126:67;;8203:6;;;;;;;;;-1:-1:-1::0;;;;;8203:6:13::1;-1:-1:-1::0;;;;;8203:18:13::1;;8229:9;8240:11;8253:10;8265;8277:14;8293:1;8296:8;8306:3;;8311:11;8203:120;;;;;;;;;;;;;;;;;;;;;;;:::i;19673:156::-:0;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;19756:9:13::1;19768:17;19777:7;19768:8;:17::i;:::-;19795:27;::::0;-1:-1:-1;;;19795:27:13;;19756:29;;-1:-1:-1;;;;;;19795:16:13;::::1;::::0;::::1;::::0;:27:::1;::::0;19812:9;;19795:27:::1;;;:::i;8336:509::-:0;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;-1:-1:-1;;;;;8544:30:13;::::1;8536:81;;;;-1:-1:-1::0;;;8536:81:13::1;;;;;;;:::i;:::-;8627:9;8639:20;8648:10;8639:8;:20::i;:::-;8627:32;;8669:23;8695:4;-1:-1:-1::0;;;;;8695:16:13::1;;8712:11;8725:10;8695:41;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8746:6;::::0;:92:::1;::::0;-1:-1:-1;;;8746:92:13;;8669:67;;-1:-1:-1;;;;;;8746:6:13::1;::::0;:18:::1;::::0;8772:9:::1;::::0;8746:92:::1;::::0;8783:11;;8796:10;;8808;;8820:14;;8669:67;;8746:92:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;;;;;;8336:509:13:o;4783:1147::-;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;5138:13:13;5130:49:::1;;;;-1:-1:-1::0;;;5130:49:13::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5197:30:13;::::1;5189:81;;;;-1:-1:-1::0;;;5189:81:13::1;;;;;;;:::i;:::-;5280:21;;:::i;:::-;5311:23;;:::i;:::-;5358:9;5370:20;5379:10;5370:8;:20::i;:::-;5358:32;;5422:19;5444:4;-1:-1:-1::0;;;;;5444:16:13::1;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5422:40:::0;-1:-1:-1;5492:43:13::1;5422:40:::0;5492:26:::1;:9:::0;5422:40;5492:13:::1;:26::i;:43::-;5480:55;;2419:1:8;5568:4:13;-1:-1:-1::0;;;;;5568:9:13::1;;5578:11;5591:10;5603;5615:9;5626:12;5640:4;5568:77;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5564:81;;5659:69;5677:4;-1:-1:-1::0;;;;;5677:10:13::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5691:10;5711:4;5718:9;5659:17;:69::i;:::-;5746:4;-1:-1:-1::0;;;;;5746:16:13::1;;5763:11;5776:10;5746:41;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5742:45;;2419:1:8;5807:6:13;;;;;;;;;-1:-1:-1::0;;;;;5807:6:13::1;-1:-1:-1::0;;;;;5807:11:13::1;;5826:9;5837:11;5850:10;5862;5874:14;5890:1;5893;5896:11;5909:3;;5914:8;;5807:116;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;1637:1:8;2563:22;;-1:-1:-1;;;;;;;;;;;;;;;;4783:1147:13:o;12510:277::-;2864:6;;-1:-1:-1;;;;;2864:6:13;2842:10;:29;2834:72;;;;-1:-1:-1;;;2834:72:13;;;;;;;:::i;:::-;12689:9:::1;12701:20;12710:10;12701:8;:20::i;:::-;12731:49;::::0;-1:-1:-1;;;12731:49:13;;12689:32;;-1:-1:-1;;;;;;12731:20:13;::::1;::::0;::::1;::::0;:49:::1;::::0;12752:11;;12765:10;;12777:2;;12731:49:::1;;;:::i;1309:31::-:0;;;-1:-1:-1;;;;;1309:31:13;;:::o;1407:27::-;;;-1:-1:-1;;;;;1407:27:13;;:::o;1254:22::-;;;-1:-1:-1;;;;;1254:22:13;;:::o;7089:357::-;7238:16;1680:1:8;2260:7;;:19;;2252:63;;;;;-1:-1:-1;;;2252:63:8;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:63:8;;;;;;;;;;;;;;;1680:1;2390:7;:18;7274:13:13;7266:59:::1;;;;-1:-1:-1::0;;;7266:59:13::1;;;;;;;:::i;:::-;7335:9;7347:20;7356:10;7347:20;;:8;:20::i;:::-;7388:51;::::0;-1:-1:-1;;;7388:51:13;;7335:32;;-1:-1:-1;;;;;;7388:23:13;::::1;::::0;::::1;::::0;:51:::1;::::0;7412:10:::1;::::0;7424:9;;7435:3;;7388:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1637:1:8::0;2563:22;;7377:62:13;7089:357;-1:-1:-1;;;;;7089:357:13:o;19492:175::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;19586:9:13::1;19598:17;19607:7;19598:8;:17::i;:::-;19625:35;::::0;-1:-1:-1;;;19625:35:13;;19586:29;;-1:-1:-1;;;;;;19625:18:13;::::1;::::0;::::1;::::0;:35:::1;::::0;19644:15;;19625:35:::1;;;:::i;18443:236::-:0;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;18586:9:13::1;18598:17;18607:7;18598:8;:17::i;:::-;18625:47;::::0;-1:-1:-1;;;18625:47:13;;18586:29;;-1:-1:-1;;;;;;18625:22:13;::::1;::::0;::::1;::::0;:47:::1;::::0;18648:11;;18661:10;;18625:47:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;20581:244:::0;20667:16;;-1:-1:-1;;;;;20667:16:13;20687:10;20667:30;20659:74;;;;-1:-1:-1;;;20659:74:13;;;;;;;:::i;:::-;20743:9;20755:17;20764:7;20755:8;:17::i;:::-;20782:36;;-1:-1:-1;;;20782:36:13;;20743:29;;-1:-1:-1;;;;;;20782:31:13;;;;;:36;;20814:3;;20782:36;;;:::i;19155:173::-;1291:12:3;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;19233:22:13;::::1;19225:65;;;;-1:-1:-1::0;;;19225:65:13::1;;;;;;;:::i;:::-;19300:12;:21:::0;;-1:-1:-1;;;;;;19300:21:13::1;-1:-1:-1::0;;;;;19300:21:13;;;::::1;::::0;;;::::1;::::0;;19155:173::o;1523:82::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1523:82:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1497:20::-;;;-1:-1:-1;;;;;1497:20:13;;:::o;1994:240:3:-;1291:12;:10;:12::i;:::-;-1:-1:-1;;;;;1280:23:3;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1280:23:3;;1272:68;;;;;-1:-1:-1;;;1272:68:3;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1272:68:3;;;;;;;;;;;;;;;-1:-1:-1;;;;;2082:22:3;::::1;2074:73;;;;-1:-1:-1::0;;;2074:73:3::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2183:6;::::0;;2162:38:::1;::::0;-1:-1:-1;;;;;2162:38:3;;::::1;::::0;2183:6;::::1;::::0;2162:38:::1;::::0;::::1;2210:6;:17:::0;;-1:-1:-1;;;;;;2210:17:3::1;-1:-1:-1::0;;;;;2210:17:3;;;::::1;::::0;;;::::1;::::0;;1994:240::o;20199:142:13:-;20270:9;20282:17;20291:7;20282:8;:17::i;:::-;20309:25;;-1:-1:-1;;;20309:25:13;;20270:29;;-1:-1:-1;;;;;;20309:14:13;;;;;:25;;20324:9;;20309:25;;;:::i;3518:198::-;3604:7;;:24;;-1:-1:-1;;;3604:24:13;;3576:9;;-1:-1:-1;;;;;3604:7:13;;:15;;:24;;3620:7;;3604:24;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3597:31;-1:-1:-1;;;;;;3646:29:13;;3638:71;;;;-1:-1:-1;;;3638:71:13;;;;;;;:::i;:::-;3518:198;;;:::o;598:104:7:-;685:10;598:104;:::o;16142:1502:13:-;16446:9;16458:20;16467:10;16458:8;:20::i;:::-;16535:49;;-1:-1:-1;;;16535:49:13;;16446:32;;-1:-1:-1;;;;;;16535:15:13;;;;;:49;;16551:11;;16564:10;;16576:3;;16581:2;;16535:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16535:49:13;;;;;;;;-1:-1:-1;;16535:49:13;;;;;;;;;;;;:::i;:::-;;;16531:1107;;927:1;17393:10;17421;17449:14;17481:3;17502:2;17522:8;17325:219;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;17325:219:13;;;;;;;;;17276:25;;;;;;;:12;17325:219;17276:25;;;;;17325:219;;17276:38;;17302:11;;17276:38;:::i;:::-;;;;;;;;;;;;;:46;17315:6;17276:46;;;;;;;;;;;:268;;;;;;;;;;;;:::i;:::-;;17563:64;927:1;17594:11;17607;17620:6;17563:64;;;;;;;;;:::i;:::-;;;;;;;;16531:1107;;;16630:23;16649:3;16630:18;:23::i;:::-;:46;;;;;16675:1;16657:8;:15;:19;16630:46;16626:619;;;16779:3;-1:-1:-1;;;;;16761:32:13;;16799:14;16815:11;16828;16841:6;16849:4;-1:-1:-1;;;;;16849:10:13;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16863:8;16873;16761:121;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16757:474;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17040:49;;;;;;;;17051:4;-1:-1:-1;;;;;17051:10:13;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;17040:49:13;;;;;17065:8;17040:49;;;;17075:3;-1:-1:-1;;;;;17040:49:13;;;;;17080:8;17040:49;;;16987:16;:29;17004:11;16987:29;;;;;;;;;;;;;;;17017:11;16987:42;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:50;;;;;;;;;;:102;;;;-1:-1:-1;;;;;;16987:102:13;;;-1:-1:-1;;;;;16987:102:13;;;;;;;;;;-1:-1:-1;16987:102:13;;;;;;;;;;;;;;;;;;;;;;;;;;;:50;;:102;;;;;;;;;;;:::i;:::-;;;;;17116:96;17132:11;17145;17158:6;17166:4;-1:-1:-1;;;;;17166:10:13;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17180:8;17190:3;17195:8;17205:6;17116:96;;;;;;;;;;;;;:::i;:::-;;;;;;;;16937:294;16757:474;;16531:1107;16142:1502;;;;;;;;;;:::o;14788:917::-;15064:9;15076:20;15085:10;15076:8;:20::i;:::-;15110:80;;-1:-1:-1;;;15110:80:13;;15064:32;;-1:-1:-1;;;;;;15110:24:13;;;;;:80;;15135:11;;15148:10;;15160:3;;15165:9;;15176:13;;15110:80;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15106:470;;871:1;15341:10;15369;15397:3;15418:9;15445:13;15263:209;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;15263:209:13;;;;;;;;;15214:25;;;;;;;:12;15263:209;15214:25;;;;;15263:209;;15214:38;;15240:11;;15214:38;:::i;:::-;;;;;;;;;;;;;:46;15253:6;15214:46;;;;;;;;;;;:258;;;;;;;;;;;;:::i;:::-;;15491:74;871:1;15532:11;15545;15558:6;15491:74;;;;;;;;;:::i;:::-;;;;;;;;15106:470;15636:6;15623:11;15590:108;;;;;;:::i;:::-;;;;;;;;;15610:11;15644:10;15656;15668:3;15673:9;15684:13;15590:108;;;;;;;;;;;:::i;:::-;;;;;;;;14788:917;;;;;;;;;:::o;4209:150:4:-;4267:7;4298:1;4294;:5;4286:44;;;;;-1:-1:-1;;;4286:44:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;4351:1;4347;:5;;;;;;4340:12;;4209:150;;;;;:::o;3530:215::-;3588:7;3611:6;3607:20;;-1:-1:-1;3626:1:4;3619:8;;3607:20;3649:5;;;3653:1;3649;:5;:1;3672:5;;;;;:10;3664:56;;;;-1:-1:-1;;;3664:56:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3737:1;3530:215;-1:-1:-1;;;3530:215:4:o;3820:433:13:-;4038:12;4052:17;4073:5;-1:-1:-1;;;;;4073:10:13;4107;4119:4;4125:2;4129:5;4084:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4084:51:13;;;;;;;;;;;4073:63;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4037:99;;;;4154:7;:57;;;;-1:-1:-1;4166:11:13;;:16;;:44;;;4197:4;4186:24;;;;;;;;;;;;:::i;:::-;4146:100;;;;-1:-1:-1;;;4146:100:13;;;;;;;:::i;718:413:6:-;1078:20;1116:8;;;718:413::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:138:17;84:20;;113:33;84:20;113:33;:::i;157:377::-;;;274:3;267:4;259:6;255:17;251:27;241:2;;299:8;289;282:26;241:2;-1:-1:-1;329:20:17;;-1:-1:-1;;;;;361:30:17;;358:2;;;411:8;401;394:26;358:2;455:4;447:6;443:17;431:29;;507:3;500:4;491:6;483;479:19;475:30;472:39;469:2;;;524:1;521;514:12;469:2;231:303;;;;;:::o;539:485::-;;636:3;629:4;621:6;617:17;613:27;603:2;;658:5;651;644:20;603:2;698:6;685:20;729:49;744:33;774:2;744:33;:::i;:::-;729:49;:::i;:::-;803:2;794:7;787:19;849:3;842:4;837:2;829:6;825:15;821:26;818:35;815:2;;;870:5;863;856:20;815:2;939;932:4;924:6;920:17;913:4;904:7;900:18;887:55;962:16;;;980:4;958:27;951:42;;;;966:7;593:431;-1:-1:-1;;593:431:17:o;1029:711::-;;1145:4;1133:9;1128:3;1124:19;1120:30;1117:2;;;1167:5;1160;1153:20;1117:2;1204;1198:9;1246:4;1238:6;1234:17;1317:6;1305:10;1302:22;-1:-1:-1;;;;;1269:10:17;1266:34;1263:62;1260:2;;;1328:9;1260:2;1359:10;1355:2;1348:22;;1388:6;1379:15;;1424:9;1418:16;1410:6;1403:32;1489:2;1478:9;1474:18;1468:25;1463:2;1455:6;1451:15;1444:50;1548:2;1537:9;1533:18;1527:25;1522:2;1514:6;1510:15;1503:50;1607:2;1596:9;1592:18;1586:25;1581:2;1573:6;1569:15;1562:50;1667:3;1656:9;1652:19;1646:26;1640:3;1632:6;1628:16;1621:52;1728:3;1717:9;1713:19;1707:26;1701:3;1693:6;1689:16;1682:52;;1107:633;;;;:::o;1745:674::-;;1850:4;1838:9;1833:3;1829:19;1825:30;1822:2;;;1872:5;1865;1858:20;1822:2;1909;1903:9;1951:4;1943:6;1939:17;-1:-1:-1;;;;;2043:6:17;2031:10;2028:22;2023:2;2011:10;2008:18;2005:46;2002:2;;;2054:9;2002:2;2085:10;2081:2;2074:22;2114:6;2105:15;;2157:9;2144:23;2136:6;2129:39;2229:2;2218:9;2214:18;2201:32;2196:2;2188:6;2184:15;2177:57;2285:2;2274:9;2270:18;2257:32;2243:46;;2312:2;2304:6;2301:14;2298:2;;;2328:1;2325;2318:12;2298:2;;2365:47;2408:3;2399:6;2388:9;2384:22;2365:47;:::i;:::-;2360:2;2352:6;2348:15;2341:72;;;1812:607;;;;:::o;2424:161::-;2493:20;;2553:6;2542:18;;2532:29;;2522:2;;2575:1;2572;2565:12;2590:259;;2702:2;2690:9;2681:7;2677:23;2673:32;2670:2;;;2723:6;2715;2708:22;2670:2;2767:9;2754:23;2786:33;2813:5;2786:33;:::i;2854:263::-;;2977:2;2965:9;2956:7;2952:23;2948:32;2945:2;;;2998:6;2990;2983:22;2945:2;3035:9;3029:16;3054:33;3081:5;3054:33;:::i;3122:257::-;;3242:2;3230:9;3221:7;3217:23;3213:32;3210:2;;;3263:6;3255;3248:22;3210:2;3300:9;3294:16;3319:30;3343:5;3319:30;:::i;3384:433::-;;;3544:2;3532:9;3523:7;3519:23;3515:32;3512:2;;;3565:6;3557;3550:22;3512:2;3609:9;3596:23;3628:33;3655:5;3628:33;:::i;:::-;3680:5;-1:-1:-1;3737:2:17;3722:18;;3709:32;3750:35;3709:32;3750:35;:::i;:::-;3804:7;3794:17;;;3502:315;;;;;:::o;4103:504::-;;4253:2;4241:9;4232:7;4228:23;4224:32;4221:2;;;4274:6;4266;4259:22;4221:2;4312;4306:9;4354:2;4346:6;4342:15;4423:6;4411:10;4408:22;-1:-1:-1;;;;;4375:10:17;4372:34;4369:62;4366:2;;;4434:9;4366:2;4461;4454:22;4500:16;;4485:32;;4571:2;4556:18;;;4550:25;4533:15;;;4526:50;;;;-1:-1:-1;4492:6:17;4211:396;-1:-1:-1;4211:396:17:o;4612:263::-;;4760:3;4748:9;4739:7;4735:23;4731:33;4728:2;;;4782:6;4774;4767:22;4728:2;4810:59;4861:7;4850:9;4810:59;:::i;4880:573::-;;;;;5044:2;5032:9;5023:7;5019:23;5015:32;5012:2;;;5065:6;5057;5050:22;5012:2;5093:30;5113:9;5093:30;:::i;:::-;5083:40;;5174:2;5163:9;5159:18;5146:32;-1:-1:-1;;;;;5193:6:17;5190:30;5187:2;;;5238:6;5230;5223:22;5187:2;5282:60;5334:7;5325:6;5314:9;5310:22;5282:60;:::i;:::-;5002:451;;5361:8;;-1:-1:-1;5256:86:17;;5443:2;5428:18;5415:32;;5002:451;-1:-1:-1;;;;5002:451:17:o;5458:977::-;;;;;;;5689:3;5677:9;5668:7;5664:23;5660:33;5657:2;;;5711:6;5703;5696:22;5657:2;5739:30;5759:9;5739:30;:::i;:::-;5729:40;;5820:2;5809:9;5805:18;5792:32;-1:-1:-1;;;;;5884:2:17;5876:6;5873:14;5870:2;;;5905:6;5897;5890:22;5870:2;5949:60;6001:7;5992:6;5981:9;5977:22;5949:60;:::i;:::-;6028:8;;-1:-1:-1;5923:86:17;-1:-1:-1;6110:2:17;6095:18;;6082:32;;-1:-1:-1;6164:2:17;6149:18;;6136:32;;-1:-1:-1;6177:33:17;6136:32;6177:33;:::i;:::-;6229:5;;-1:-1:-1;6287:3:17;6272:19;;6259:33;;6304:16;;;6301:2;;;6338:6;6330;6323:22;6301:2;;6366:63;6421:7;6410:8;6399:9;6395:24;6366:63;:::i;:::-;6356:73;;;5647:788;;;;;;;;:::o;6440:484::-;;;;6594:2;6582:9;6573:7;6569:23;6565:32;6562:2;;;6615:6;6607;6600:22;6562:2;6643:30;6663:9;6643:30;:::i;:::-;6633:40;;6724:2;6713:9;6709:18;6696:32;-1:-1:-1;;;;;6743:6:17;6740:30;6737:2;;;6788:6;6780;6773:22;6737:2;6816:51;6859:7;6850:6;6839:9;6835:22;6816:51;:::i;:::-;6806:61;;;6914:2;6903:9;6899:18;6886:32;6876:42;;6552:372;;;;;:::o;6929:898::-;;;;;;;;;7168:3;7156:9;7147:7;7143:23;7139:33;7136:2;;;7190:6;7182;7175:22;7136:2;7218:30;7238:9;7218:30;:::i;:::-;7208:40;;7299:2;7288:9;7284:18;7271:32;-1:-1:-1;;;;;7318:6:17;7315:30;7312:2;;;7363:6;7355;7348:22;7312:2;7391:51;7434:7;7425:6;7414:9;7410:22;7391:51;:::i;:::-;7381:61;;;7489:2;7478:9;7474:18;7461:32;7451:42;;7540:2;7529:9;7525:18;7512:32;7502:42;;7591:3;7580:9;7576:19;7563:33;7553:43;;7646:3;7635:9;7631:19;7618:33;7660;7687:5;7660:33;:::i;:::-;7126:701;;;;-1:-1:-1;7126:701:17;;;;;;7712:5;;-1:-1:-1;;;7764:3:17;7749:19;;7736:33;;7816:3;7801:19;7788:33;;7126:701::o;7832:1788::-;;;;;;;;;;8113:9;8104:7;8100:23;8143:3;8139:2;8135:12;8132:2;;;8165:6;8157;8150:22;8132:2;8193:30;8213:9;8193:30;:::i;:::-;8183:40;;8274:2;8263:9;8259:18;8246:32;-1:-1:-1;;;;;8338:2:17;8330:6;8327:14;8324:2;;;8359:6;8351;8344:22;8324:2;8387:51;8430:7;8421:6;8410:9;8406:22;8387:51;:::i;:::-;8377:61;;8485:2;8474:9;8470:18;8457:32;8447:42;;8536:2;8525:9;8521:18;8508:32;8498:42;;8587:3;8576:9;8572:19;8559:33;8549:43;;8639:3;8628:9;8624:19;8611:33;8601:43;;8694:3;8683:9;8679:19;8666:33;8653:46;;8708:33;8735:5;8708:33;:::i;:::-;8760:5;8750:15;;8800:3;8793;8789:8;8785:2;8781:17;8777:27;8774:2;;;8822:6;8814;8807:22;8774:2;8860;8854:9;8840:23;;8902:3;8894:6;8890:16;8872:34;;8956:6;8944:10;8941:22;8936:2;8924:10;8921:18;8918:46;8915:2;;;8967:9;8915:2;8998:10;8994:2;8987:22;9061:3;9050:9;9046:19;9033:33;9025:6;9018:49;9128:3;9117:9;9113:19;9100:33;9095:2;9087:6;9083:15;9076:58;9195:3;9184:9;9180:19;9167:33;9162:2;9154:6;9150:15;9143:58;9262:3;9251:9;9247:19;9234:33;9229:2;9221:6;9217:15;9210:58;9330:3;9319:9;9315:19;9302:33;9296:3;9288:6;9284:16;9277:59;9398:3;9387:9;9383:19;9370:33;9364:3;9356:6;9352:16;9345:59;9423:6;9413:16;;9482:3;9471:9;9467:19;9454:33;9438:49;;9512:2;9502:8;9499:16;9496:2;;;9533:6;9525;9518:22;9496:2;;;9561:53;9606:7;9595:8;9584:9;9580:24;9561:53;:::i;:::-;9551:63;;;8080:1540;;;;;;;;;;;:::o;9625:1012::-;;;;;;;;;9866:3;9854:9;9845:7;9841:23;9837:33;9834:2;;;9888:6;9880;9873:22;9834:2;9916:30;9936:9;9916:30;:::i;:::-;9906:40;;9997:2;9986:9;9982:18;9969:32;-1:-1:-1;;;;;10061:2:17;10053:6;10050:14;10047:2;;;10082:6;10074;10067:22;10047:2;10110:51;10153:7;10144:6;10133:9;10129:22;10110:51;:::i;:::-;10100:61;;10208:2;10197:9;10193:18;10180:32;10170:42;;10259:2;10248:9;10244:18;10231:32;10221:42;;10310:3;10299:9;10295:19;10282:33;10272:43;;10362:3;10351:9;10347:19;10334:33;10324:43;;10420:3;10409:9;10405:19;10392:33;10376:49;;10450:2;10440:8;10437:16;10434:2;;;10471:6;10463;10456:22;10434:2;;10515:62;10569:7;10558:8;10547:9;10543:24;10515:62;:::i;:::-;9824:813;;;;-1:-1:-1;9824:813:17;;-1:-1:-1;9824:813:17;;;;;;10596:8;-1:-1:-1;;;9824:813:17:o;10642:401::-;;;;10787:2;10775:9;10766:7;10762:23;10758:32;10755:2;;;10808:6;10800;10793:22;10755:2;10836:30;10856:9;10836:30;:::i;:::-;10826:40;;10913:2;10902:9;10898:18;10885:32;10875:42;;10967:2;10956:9;10952:18;10939:32;10980:33;11007:5;10980:33;:::i;:::-;11032:5;11022:15;;;10745:298;;;;;:::o;11048:478::-;;;;;11218:3;11206:9;11197:7;11193:23;11189:33;11186:2;;;11240:6;11232;11225:22;11186:2;11268:30;11288:9;11268:30;:::i;:::-;11258:40;;11345:2;11334:9;11330:18;11317:32;11307:42;;11396:2;11385:9;11381:18;11368:32;11358:42;;11450:2;11439:9;11435:18;11422:32;11463:33;11490:5;11463:33;:::i;:::-;11176:350;;;;-1:-1:-1;11176:350:17;;-1:-1:-1;;11176:350:17:o;11531:1115::-;;;;;;;;;11796:3;11784:9;11775:7;11771:23;11767:33;11764:2;;;11818:6;11810;11803:22;11764:2;11846:30;11866:9;11846:30;:::i;:::-;11836:40;;11923:2;11912:9;11908:18;11895:32;11885:42;;11974:2;11963:9;11959:18;11946:32;11936:42;;12028:2;12017:9;12013:18;12000:32;12041:33;12068:5;12041:33;:::i;:::-;12093:5;-1:-1:-1;12145:3:17;12130:19;;12117:33;;-1:-1:-1;12201:3:17;12186:19;;12173:33;-1:-1:-1;;;;;12255:14:17;;;12252:2;;;12287:6;12279;12272:22;12252:2;12331:60;12383:7;12374:6;12363:9;12359:22;12331:60;:::i;:::-;12410:8;;-1:-1:-1;12305:86:17;-1:-1:-1;12498:3:17;12483:19;;12470:33;;-1:-1:-1;12515:16:17;;;12512:2;;;12549:6;12541;12534:22;12512:2;;12577:63;12632:7;12621:8;12610:9;12606:24;12577:63;:::i;:::-;12567:73;;;11754:892;;;;;;;;;;;:::o;12651:1184::-;;;;;;;;;;12933:3;12921:9;12912:7;12908:23;12904:33;12901:2;;;12955:6;12947;12940:22;12901:2;12983:30;13003:9;12983:30;:::i;:::-;12973:40;;13060:2;13049:9;13045:18;13032:32;13022:42;;13111:2;13100:9;13096:18;13083:32;13073:42;;13165:2;13154:9;13150:18;13137:32;13178:33;13205:5;13178:33;:::i;:::-;13230:5;-1:-1:-1;13282:3:17;13267:19;;13254:33;;-1:-1:-1;13334:3:17;13319:19;;13306:33;;-1:-1:-1;13390:3:17;13375:19;;13362:33;-1:-1:-1;;;;;13444:14:17;;;13441:2;;;13476:6;13468;13461:22;13441:2;13520:60;13572:7;13563:6;13552:9;13548:22;13520:60;:::i;:::-;13599:8;;-1:-1:-1;13494:86:17;-1:-1:-1;13687:3:17;13672:19;;13659:33;;-1:-1:-1;13704:16:17;;;13701:2;;;13738:6;13730;13723:22;13701:2;;13766:63;13821:7;13810:8;13799:9;13795:24;13766:63;:::i;13840:1409::-;;;;;;;;;;;;14159:3;14147:9;14138:7;14134:23;14130:33;14127:2;;;14181:6;14173;14166:22;14127:2;14209:30;14229:9;14209:30;:::i;:::-;14199:40;;14286:2;14275:9;14271:18;14258:32;14248:42;;14337:2;14326:9;14322:18;14309:32;14299:42;;14360:40;14396:2;14385:9;14381:18;14360:40;:::i;:::-;14350:50;;14447:3;14436:9;14432:19;14419:33;14409:43;;14499:3;14488:9;14484:19;14471:33;14461:43;;-1:-1:-1;;;;;14591:2:17;14584:3;14573:9;14569:19;14556:33;14553:41;14550:2;;;14612:6;14604;14597:22;14550:2;14640:88;14720:7;14712:3;14701:9;14697:19;14684:33;14673:9;14669:49;14640:88;:::i;:::-;14630:98;;14778:2;14771:3;14760:9;14756:19;14743:33;14740:41;14737:2;;;14799:6;14791;14784:22;14737:2;14843:87;14922:7;14914:3;14903:9;14899:19;14886:33;14875:9;14871:49;14843:87;:::i;:::-;14949:8;;-1:-1:-1;14976:8:17;-1:-1:-1;15027:3:17;15012:19;;14999:33;14996:41;-1:-1:-1;14993:2:17;;;15055:6;15047;15040:22;14993:2;;15100:87;15179:7;15171:3;15160:9;15156:19;15143:33;15132:9;15128:49;15100:87;:::i;:::-;15206:8;15196:18;;15234:9;15223:20;;;;14117:1132;;;;;;;;;;;;;;:::o;15254:804::-;;;;;15434:9;15425:7;15421:23;15464:3;15460:2;15456:12;15453:2;;;15486:6;15478;15471:22;15453:2;15514:30;15534:9;15514:30;:::i;:::-;15504:40;-1:-1:-1;15591:2:17;15576:18;;15563:32;;-1:-1:-1;15642:2:17;15627:18;;;15614:32;;-1:-1:-1;;;15662:16:17;;15658:25;15655:2;;;15701:6;15693;15686:22;15655:2;;15739;15733:9;15781:2;15773:6;15769:15;15850:6;15838:10;15835:22;-1:-1:-1;;;;;15802:10:17;15799:34;15796:62;15793:2;;;15861:9;15793:2;15888;15881:22;15955:2;15940:18;;15927:32;15912:48;;16021:3;16006:19;;;15993:33;15988:2;15976:15;;15969:58;-1:-1:-1;15401:657:17;;;;-1:-1:-1;15401:657:17;;15919:6;15401:657::o;16063:1196::-;;;;;;;;16303:3;16291:9;16282:7;16278:23;16274:33;16271:2;;;16325:6;16317;16310:22;16271:2;16353:30;16373:9;16353:30;:::i;:::-;16343:40;;16433:2;16422:9;16418:18;16405:32;16446:31;16471:5;16446:31;:::i;:::-;16496:5;-1:-1:-1;16552:2:17;16537:18;;16524:32;-1:-1:-1;;;;;16605:14:17;;;16602:2;;;16637:6;16629;16622:22;16602:2;16681:60;16733:7;16724:6;16713:9;16709:22;16681:60;:::i;:::-;16760:8;;-1:-1:-1;16655:86:17;-1:-1:-1;16848:2:17;16833:18;;16820:32;;-1:-1:-1;16864:16:17;;;16861:2;;;16898:6;16890;16883:22;16861:2;16942:62;16996:7;16985:8;16974:9;16970:24;16942:62;:::i;:::-;17023:8;;-1:-1:-1;16916:88:17;-1:-1:-1;17111:3:17;17096:19;;17083:33;;-1:-1:-1;17128:16:17;;;17125:2;;;17162:6;17154;17147:22;17125:2;;17190:63;17245:7;17234:8;17223:9;17219:24;17190:63;:::i;:::-;17180:73;;;16261:998;;;;;;;;;;:::o;17264:194::-;;17387:2;17375:9;17366:7;17362:23;17358:32;17355:2;;;17408:6;17400;17393:22;17355:2;-1:-1:-1;17436:16:17;;17345:113;-1:-1:-1;17345:113:17:o;17463:327::-;;;17592:2;17580:9;17571:7;17567:23;17563:32;17560:2;;;17613:6;17605;17598:22;17560:2;17654:9;17641:23;17631:33;;17714:2;17703:9;17699:18;17686:32;17727:33;17754:5;17727:33;:::i;17795:1061::-;;;;;;;18008:3;17996:9;17987:7;17983:23;17979:33;17976:2;;;18030:6;18022;18015:22;17976:2;18071:9;18058:23;18048:33;;18131:2;18120:9;18116:18;18103:32;18144:33;18171:5;18144:33;:::i;:::-;18196:5;-1:-1:-1;18253:2:17;18238:18;;18225:32;18266:33;18225:32;18266:33;:::i;:::-;18318:7;-1:-1:-1;18377:2:17;18362:18;;18349:32;18390:33;18349:32;18390:33;:::i;:::-;18442:7;-1:-1:-1;18500:3:17;18485:19;;18472:33;-1:-1:-1;;;;;18554:14:17;;;18551:2;;;18586:6;18578;18571:22;18551:2;18614:51;18657:7;18648:6;18637:9;18633:22;18614:51;:::i;:::-;18604:61;;18718:3;18707:9;18703:19;18690:33;18674:49;;18748:2;18738:8;18735:16;18732:2;;;18769:6;18761;18754:22;18732:2;;18797:53;18842:7;18831:8;18820:9;18816:24;18797:53;:::i;18861:321::-;;;18987:2;18975:9;18966:7;18962:23;18958:32;18955:2;;;19008:6;19000;18993:22;18955:2;19049:9;19036:23;19026:33;;19109:2;19098:9;19094:18;19081:32;19122:30;19146:5;19122:30;:::i;19187:734::-;;;;;;;19375:3;19363:9;19354:7;19350:23;19346:33;19343:2;;;19397:6;19389;19382:22;19343:2;19438:9;19425:23;19415:33;;19498:2;19487:9;19483:18;19470:32;19511:30;19535:5;19511:30;:::i;:::-;19560:5;-1:-1:-1;19612:2:17;19597:18;;19584:32;;-1:-1:-1;19663:2:17;19648:18;;19635:32;;-1:-1:-1;19719:3:17;19704:19;;19691:33;19733:32;19691:33;19733:32;:::i;:::-;19784:7;-1:-1:-1;19843:3:17;19828:19;;19815:33;19857:32;19815:33;19857:32;:::i;:::-;19908:7;19898:17;;;19333:588;;;;;;;;:::o;19926:332::-;;;;20071:2;20059:9;20050:7;20046:23;20042:32;20039:2;;;20092:6;20084;20077:22;20039:2;20133:9;20120:23;20110:33;;20162:39;20197:2;20186:9;20182:18;20162:39;:::i;:::-;20152:49;;20248:2;20237:9;20233:18;20220:32;20210:42;;20029:229;;;;;:::o;20263:407::-;;;;;20424:3;20412:9;20403:7;20399:23;20395:33;20392:2;;;20446:6;20438;20431:22;20392:2;20487:9;20474:23;20464:33;;20516:39;20551:2;20540:9;20536:18;20516:39;:::i;:::-;20506:49;;20602:2;20591:9;20587:18;20574:32;20564:42;;20625:39;20660:2;20649:9;20645:18;20625:39;:::i;:::-;20615:49;;20382:288;;;;;;;:::o;20675:401::-;;;;;20837:3;20825:9;20816:7;20812:23;20808:33;20805:2;;;20859:6;20851;20844:22;20805:2;20900:9;20887:23;20877:33;;20929:39;20964:2;20953:9;20949:18;20929:39;:::i;:::-;20795:281;;20919:49;;-1:-1:-1;;;;21015:2:17;21000:18;;20987:32;;21066:2;21051:18;21038:32;;20795:281::o;21081:258::-;;;21210:2;21198:9;21189:7;21185:23;21181:32;21178:2;;;21231:6;21223;21216:22;21178:2;-1:-1:-1;;21259:23:17;;;21329:2;21314:18;;;21301:32;;-1:-1:-1;21168:171:17:o;21344:255::-;;;21484:2;21472:9;21463:7;21459:23;21455:32;21452:2;;;21505:6;21497;21490:22;21452:2;-1:-1:-1;;21533:16:17;;21589:2;21574:18;;;21568:25;21533:16;;21568:25;;-1:-1:-1;21442:157:17:o;21604:395::-;;;;21750:2;21738:9;21729:7;21725:23;21721:32;21718:2;;;21771:6;21763;21756:22;21718:2;21812:9;21799:23;21789:33;;21869:2;21858:9;21854:18;21841:32;21831:42;;21923:2;21912:9;21908:18;21895:32;21936:33;21963:5;21936:33;:::i;22004:650::-;;;;;;;22218:3;22206:9;22197:7;22193:23;22189:33;22186:2;;;22240:6;22232;22225:22;22186:2;22277:9;22271:16;22296:31;22321:5;22296:31;:::i;:::-;22346:5;22336:15;;;22391:2;22380:9;22376:18;22370:25;22360:35;;22435:2;22424:9;22420:18;22414:25;22404:35;;22484:2;22473:9;22469:18;22463:25;22497:35;22524:7;22497:35;:::i;:::-;22551:7;22541:17;;;22598:3;22587:9;22583:19;22577:26;22567:36;;22643:3;22632:9;22628:19;22622:26;22612:36;;22176:478;;;;;;;;:::o;22659:1261::-;;;;;;;;22924:3;22912:9;22903:7;22899:23;22895:33;22892:2;;;22946:6;22938;22931:22;22892:2;22983:9;22977:16;23002:31;23027:5;23002:31;:::i;:::-;23052:5;23042:15;;;23097:2;23086:9;23082:18;23076:25;23066:35;;23141:2;23130:9;23126:18;23120:25;23110:35;;23185:2;23174:9;23170:18;23164:25;23154:35;;23234:3;23223:9;23219:19;23213:26;23248:35;23275:7;23248:35;:::i;:::-;23302:7;-1:-1:-1;23328:69:17;23389:7;23383:3;23368:19;;23328:69;:::i;:::-;23318:79;;23441:3;23430:9;23426:19;23420:26;-1:-1:-1;;;;;23461:6:17;23458:30;23455:2;;;23506:6;23498;23491:22;23455:2;23534:22;;23587:4;23579:13;;23575:27;-1:-1:-1;23565:2:17;;23621:6;23613;23606:22;23565:2;23655;23649:9;23680:49;23695:33;23725:2;23695:33;:::i;23680:49::-;23752:2;23745:5;23738:17;23792:7;23787:2;23782;23778;23774:11;23770:20;23767:33;23764:2;;;23818:6;23810;23803:22;23764:2;23836:54;23887:2;23882;23875:5;23871:14;23866:2;23862;23858:11;23836:54;:::i;:::-;23909:5;23899:15;;;;;22882:1038;;;;;;;;;;:::o;23925:270::-;;24015:6;24010:3;24003:19;24067:6;24060:5;24053:4;24048:3;24044:14;24031:43;24119:3;24112:4;24103:6;24098:3;24094:16;24090:27;24083:40;24184:4;24177:2;24173:7;24168:2;24160:6;24156:15;24152:29;24147:3;24143:39;24139:50;24132:57;;23993:202;;;;;:::o;24200:259::-;;24281:5;24275:12;24308:6;24303:3;24296:19;24324:63;24380:6;24373:4;24368:3;24364:14;24357:4;24350:5;24346:16;24324:63;:::i;:::-;24441:2;24420:15;-1:-1:-1;;24416:29:17;24407:39;;;;24448:4;24403:50;;24251:208;-1:-1:-1;;24251:208:17:o;24464:153::-;24542:12;;24530:25;;24604:4;24593:16;;;24587:23;24571:14;;24564:47;24520:97::o;24622:375::-;24704:5;24698:12;24693:3;24686:25;24760:4;24753:5;24749:16;24743:23;24736:4;24731:3;24727:14;24720:47;24816:4;24809:5;24805:16;24799:23;24792:4;24787:3;24783:14;24776:47;24872:4;24865:5;24861:16;24855:23;24848:4;24843:3;24839:14;24832:47;24928:4;24921:5;24917:16;24911:23;24904:4;24899:3;24895:14;24888:47;24984:4;24977:5;24973:16;24967:23;24960:4;24955:3;24951:14;24944:47;24676:321;;:::o;25002:311::-;;25091:5;25085:12;25080:3;25073:25;25147:4;25140:5;25136:16;25130:23;25123:4;25118:3;25114:14;25107:47;25200:4;25193:5;25189:16;25183:23;25238:4;25231;25226:3;25222:14;25215:28;25259:48;25301:4;25296:3;25292:14;25278:12;25259:48;:::i;:::-;25252:55;25063:250;-1:-1:-1;;;;25063:250:17:o;25318:273::-;;25501:6;25493;25488:3;25475:33;25527:16;;25552:15;;;25527:16;25465:126;-1:-1:-1;25465:126:17:o;25596:274::-;;25763:6;25757:13;25779:53;25825:6;25820:3;25813:4;25805:6;25801:17;25779:53;:::i;:::-;25848:16;;;;;25733:137;-1:-1:-1;;25733:137:17:o;25875:203::-;-1:-1:-1;;;;;26039:32:17;;;;26021:51;;26009:2;25994:18;;25976:102::o;26083:383::-;-1:-1:-1;;;;;26349:15:17;;;26331:34;;26396:2;26381:18;;26374:34;;;;26444:15;;;26439:2;26424:18;;26417:43;26281:2;26266:18;;26248:218::o;26471:578::-;;26775:1;26771;26766:3;26762:11;26758:19;26750:6;26746:32;26735:9;26728:51;26815:6;26810:2;26799:9;26795:18;26788:34;26870:6;26862;26858:19;26853:2;26842:9;26838:18;26831:47;26914:6;26909:2;26898:9;26894:18;26887:34;26958:3;26952;26941:9;26937:19;26930:32;26979:64;27038:3;27027:9;27023:19;27015:6;27007;26979:64;:::i;:::-;26971:72;26718:331;-1:-1:-1;;;;;;;;26718:331:17:o;27054:375::-;-1:-1:-1;;;;;27312:15:17;;;27294:34;;27364:15;;;;27359:2;27344:18;;27337:43;27411:2;27396:18;;27389:34;;;;27244:2;27229:18;;27211:218::o;27434:274::-;-1:-1:-1;;;;;27626:32:17;;;;27608:51;;27690:2;27675:18;;27668:34;27596:2;27581:18;;27563:145::o;27713:490::-;-1:-1:-1;;;;;27982:15:17;;;27964:34;;28029:2;28014:18;;28007:34;;;28077:15;;28072:2;28057:18;;28050:43;28129:3;28124:2;28109:18;;28102:31;;;27713:490;;28150:47;;28177:19;;28169:6;28150:47;:::i;28208:187::-;28373:14;;28366:22;28348:41;;28336:2;28321:18;;28303:92::o;28400:493::-;28666:14;;28659:22;28641:41;;28713:2;28698:18;;28691:34;;;;28756:2;28741:18;;28734:34;;;;28811:14;28804:22;28799:2;28784:18;;28777:50;28871:14;28864:22;28858:3;28843:19;;28836:51;28628:3;28613:19;;28595:298::o;28898:219::-;;29045:2;29034:9;29027:21;29065:46;29107:2;29096:9;29092:18;29084:6;29065:46;:::i;29569:412::-;29771:2;29753:21;;;29810:2;29790:18;;;29783:30;29849:34;29844:2;29829:18;;29822:62;-1:-1:-1;;;29915:2:17;29900:18;;29893:46;29971:3;29956:19;;29743:238::o;29986:354::-;30188:2;30170:21;;;30227:2;30207:18;;;30200:30;30266:32;30261:2;30246:18;;30239:60;30331:2;30316:18;;30160:180::o;30345:403::-;30547:2;30529:21;;;30586:2;30566:18;;;30559:30;30625:34;30620:2;30605:18;;30598:62;-1:-1:-1;;;30691:2:17;30676:18;;30669:37;30738:3;30723:19;;30519:229::o;30753:354::-;30955:2;30937:21;;;30994:2;30974:18;;;30967:30;31033:32;31028:2;31013:18;;31006:60;31098:2;31083:18;;30927:180::o;31112:351::-;31314:2;31296:21;;;31353:2;31333:18;;;31326:30;31392:29;31387:2;31372:18;;31365:57;31454:2;31439:18;;31286:177::o;31468:349::-;31670:2;31652:21;;;31709:2;31689:18;;;31682:30;31748:27;31743:2;31728:18;;31721:55;31808:2;31793:18;;31642:175::o;31822:354::-;32024:2;32006:21;;;32063:2;32043:18;;;32036:30;32102:32;32097:2;32082:18;;32075:60;32167:2;32152:18;;31996:180::o;32181:353::-;32383:2;32365:21;;;32422:2;32402:18;;;32395:30;32461:31;32456:2;32441:18;;32434:59;32525:2;32510:18;;32355:179::o;32539:355::-;32741:2;32723:21;;;32780:2;32760:18;;;32753:30;32819:33;32814:2;32799:18;;32792:61;32885:2;32870:18;;32713:181::o;32899:352::-;33101:2;33083:21;;;33140:2;33120:18;;;33113:30;33179;33174:2;33159:18;;33152:58;33242:2;33227:18;;33073:178::o;33256:397::-;33458:2;33440:21;;;33497:2;33477:18;;;33470:30;33536:34;33531:2;33516:18;;33509:62;-1:-1:-1;;;33602:2:17;33587:18;;33580:31;33643:3;33628:19;;33430:223::o;33658:411::-;33860:2;33842:21;;;33899:2;33879:18;;;33872:30;33938:34;33933:2;33918:18;;33911:62;-1:-1:-1;;;34004:2:17;33989:18;;33982:45;34059:3;34044:19;;33832:237::o;34074:354::-;34276:2;34258:21;;;34315:2;34295:18;;;34288:30;34354:32;34349:2;34334:18;;34327:60;34419:2;34404:18;;34248:180::o;34433:355::-;34635:2;34617:21;;;34674:2;34654:18;;;34647:30;34713:33;34708:2;34693:18;;34686:61;34779:2;34764:18;;34607:181::o;34793:347::-;34995:2;34977:21;;;35034:2;35014:18;;;35007:30;35073:25;35068:2;35053:18;;35046:53;35131:2;35116:18;;34967:173::o;35145:355::-;35347:2;35329:21;;;35386:2;35366:18;;;35359:30;35425:33;35420:2;35405:18;;35398:61;35491:2;35476:18;;35319:181::o;35505:353::-;35707:2;35689:21;;;35746:2;35726:18;;;35719:30;35785:31;35780:2;35765:18;;35758:59;35849:2;35834:18;;35679:179::o;35863:402::-;36065:2;36047:21;;;36104:2;36084:18;;;36077:30;36143:34;36138:2;36123:18;;36116:62;-1:-1:-1;;;36209:2:17;36194:18;;36187:36;36255:3;36240:19;;36037:228::o;36270:771::-;36659:6;36647:19;;36629:38;;-1:-1:-1;;;;;36703:32:17;;36698:2;36683:18;;36676:60;36270:771;36745:58;36799:2;36784:18;;36776:6;36745:58;:::i;:::-;36840:3;36834;36823:9;36819:19;36812:32;36867:57;36919:3;36908:9;36904:19;36896:6;36867:57;:::i;:::-;36973:9;36965:6;36961:22;36955:3;36944:9;36940:19;36933:51;37001:34;37028:6;37020;37001:34;:::i;37046:733::-;;37371:6;37363;37359:19;37348:9;37341:38;37415:3;37410:2;37399:9;37395:18;37388:31;37442:64;37501:3;37490:9;37486:19;37478:6;37470;37442:64;:::i;:::-;37537:2;37522:18;;37515:34;;;-1:-1:-1;;;;;37585:32:17;;37580:2;37565:18;;37558:60;37649:3;37634:19;;37627:35;;;37699:22;;;37605:3;37678:19;;37671:51;37739:34;37703:6;37758;37739:34;:::i;:::-;37731:42;37331:448;-1:-1:-1;;;;;;;;;;37331:448:17:o;37784:991::-;;38153:3;38195:6;38187;38183:19;38172:9;38165:38;38239:2;38234;38223:9;38219:18;38212:30;38265:46;38307:2;38296:9;38292:18;38284:6;38265:46;:::i;:::-;38342:2;38327:18;;38320:34;;;-1:-1:-1;;;;;38428:15:17;;;38423:2;38408:18;;38401:43;38475:3;38460:19;;38453:35;;;38525:15;;38381:3;38504:19;;38497:44;38578:22;;;38572:3;38557:19;;38550:51;38251:60;-1:-1:-1;38624:34:17;38251:60;38643:6;38624:34;:::i;:::-;38610:48;;38707:9;38699:6;38695:22;38689:3;38678:9;38674:19;38667:51;38735:34;38762:6;38754;38735:34;:::i;:::-;38727:42;38133:642;-1:-1:-1;;;;;;;;;;;38133:642:17:o;38780:706::-;;39095:6;39087;39083:19;39072:9;39065:38;39139:3;39134:2;39123:9;39119:18;39112:31;39166:47;39208:3;39197:9;39193:19;39185:6;39166:47;:::i;:::-;39244:2;39229:18;;39222:34;;;-1:-1:-1;;;;;39292:32:17;;39287:2;39272:18;;39265:60;39356:3;39341:19;;39334:35;;;39406:22;;;39312:3;39385:19;;39378:51;39446:34;39410:6;39465;39446:34;:::i;:::-;39438:42;39055:431;-1:-1:-1;;;;;;;;;39055:431:17:o;39491:259::-;39693:6;39681:19;;;;39663:38;;39732:2;39717:18;;39710:34;39651:2;39636:18;;39618:132::o;39755:436::-;40022:6;40010:19;;;;39992:38;;40061:2;40046:18;;40039:34;;;;-1:-1:-1;;;;;40109:32:17;40104:2;40089:18;;40082:60;40173:2;40158:18;;40151:34;39979:3;39964:19;;39946:245::o;40196:590::-;40513:6;40501:19;;;;40483:38;;40552:2;40537:18;;40530:34;;;;-1:-1:-1;;;;;40600:32:17;;;;40595:2;40580:18;;40573:60;40664:2;40649:18;;40642:34;40707:3;40692:19;;40685:35;40764:14;40757:22;40620:3;40736:19;;40729:51;40470:3;40455:19;;40437:349::o;40791:500::-;41100:6;41088:19;;41070:38;;41139:2;41124:18;;41117:34;;;-1:-1:-1;;;;;41187:32:17;;41182:2;41167:18;;41160:60;41057:3;41042:19;;41229:56;41281:2;41266:18;;41258:6;41229:56;:::i;:::-;41024:267;;;;;;;:::o;41296:500::-;41583:6;41571:19;;;;41553:38;;41622:2;41607:18;;41600:34;;;;-1:-1:-1;;;;;41670:32:17;;;;41665:2;41650:18;;41643:60;41734:2;41719:18;;41712:34;41777:3;41762:19;;41755:35;41540:3;41525:19;;41507:289::o;41801:409::-;42086:6;42074:19;;42056:38;;42125:2;42110:18;;42103:34;;;42043:3;42028:19;;42146:58;42200:2;42185:18;;42177:6;42146:58;:::i;42215:358::-;42423:6;42456:15;;;42438:34;;42503:2;42488:18;;42481:34;;;;42551:15;;;42546:2;42531:18;;42524:43;42401:2;42386:18;;42368:205::o;42578:330::-;42808:6;42796:19;;;;42778:38;;42847:2;42832:18;;42825:34;;;;42890:2;42875:18;;42868:34;42766:2;42751:18;;42733:175::o;42913:594::-;43270:6;43258:19;;43240:38;;43309:2;43294:18;;43287:34;;;43352:2;43337:18;;43330:34;;;-1:-1:-1;;;;;43400:32:17;;43395:2;43380:18;;43373:60;43227:3;43212:19;;43442:59;43496:3;43481:19;;43473:6;43442:59;:::i;43512:1297::-;44124:6;44112:19;;44094:38;;44163:2;44148:18;;44141:34;;;44206:2;44191:18;;44184:34;;;-1:-1:-1;;;;;44254:32:17;;44249:2;44234:18;;44227:60;43512:1297;44082:3;44296:59;44350:3;44335:19;;44327:6;44296:59;:::i;:::-;44364:57;44416:3;44405:9;44401:19;44393:6;44364:57;:::i;:::-;44458:2;44452:3;44441:9;44437:19;44430:31;44484:56;44536:2;44525:9;44521:18;44513:6;44484:56;:::i;:::-;44470:70;;44589:9;44581:6;44577:22;44571:3;44560:9;44556:19;44549:51;44623;44667:6;44659;44651;44623:51;:::i;:::-;44609:65;;44723:9;44715:6;44711:22;44705:3;44694:9;44690:19;44683:51;44751:52;44796:6;44787:7;44779:6;44751:52;:::i;:::-;44743:60;44062:747;-1:-1:-1;;;;;;;;;;;;;;44062:747:17:o;44814:1332::-;45469:6;45457:19;;45439:38;;45508:2;45493:18;;45486:34;;;45551:2;45536:18;;45529:34;;;-1:-1:-1;;;;;45599:32:17;;45594:2;45579:18;;45572:60;44814:1332;45427:3;45641:59;45695:3;45680:19;;45672:6;45641:59;:::i;:::-;45709:57;45761:3;45750:9;45746:19;45738:6;45709:57;:::i;:::-;45803:2;45797:3;45786:9;45782:19;45775:31;45829:56;45881:2;45870:9;45866:18;45858:6;45829:56;:::i;:::-;45815:70;;45934:9;45926:6;45922:22;45916:3;45905:9;45901:19;45894:51;45968;46012:6;46004;45996;45968:51;:::i;:::-;46056:22;;;46050:3;46035:19;;;46028:51;;;;-1:-1:-1;46088:20:17;;46137:2;46125:15;;45407:739;-1:-1:-1;;;;;;;;;45407:739:17:o;46151:1033::-;46656:6;46644:19;;46626:38;;46695:2;46680:18;;46673:34;;;46738:2;46723:18;;46716:34;;;-1:-1:-1;;;;;46786:32:17;;46781:2;46766:18;;46759:60;46151:1033;46614:3;46828:59;46882:3;46867:19;;46859:6;46828:59;:::i;:::-;46924:6;46918:3;46907:9;46903:19;46896:35;46968:2;46962:3;46951:9;46947:19;46940:31;46994:63;47053:2;47042:9;47038:18;47030:6;47022;46994:63;:::i;:::-;46980:77;;47106:9;47098:6;47094:22;47088:3;47077:9;47073:19;47066:51;47134:44;47171:6;47163;47134:44;:::i;:::-;47126:52;46594:590;-1:-1:-1;;;;;;;;;;;;46594:590:17:o;47189:572::-;47504:6;47492:19;;;;47474:38;;47543:2;47528:18;;47521:34;;;;47586:2;47571:18;;47564:34;;;;-1:-1:-1;;;;;47634:32:17;47629:2;47614:18;;47607:60;47698:3;47683:19;;47676:35;47654:3;47727:19;;47720:35;47461:3;47446:19;;47428:333::o;47766:616::-;;48073:6;48065;48061:19;48050:9;48043:38;48117:6;48112:2;48101:9;48097:18;48090:34;48160:6;48155:2;48144:9;48140:18;48133:34;48203:3;48198:2;48187:9;48183:18;48176:31;48224:64;48283:3;48272:9;48268:19;48260:6;48252;48224:64;:::i;:::-;48319:3;48304:19;;48297:35;;;;-1:-1:-1;48363:3:17;48348:19;48341:35;48216:72;48033:349;-1:-1:-1;;;;;48033:349:17:o;48387:802::-;;48740:6;48732;48728:19;48717:9;48710:38;48796:4;48788:6;48784:17;48779:2;48768:9;48764:18;48757:45;48838:3;48833:2;48822:9;48818:18;48811:31;48865:64;48924:3;48913:9;48909:19;48901:6;48893;48865:64;:::i;:::-;48977:9;48969:6;48965:22;48960:2;48949:9;48945:18;48938:50;49011:51;49055:6;49047;49039;49011:51;:::i;:::-;48997:65;;49111:9;49103:6;49099:22;49093:3;49082:9;49078:19;49071:51;49139:44;49176:6;49168;49139:44;:::i;49194:177::-;49340:25;;;49328:2;49313:18;;49295:76::o;49376:713::-;49659:25;;;-1:-1:-1;;;;;49720:32:17;;49715:2;49700:18;;49693:60;49801:4;49789:17;;;49784:2;49769:18;;49762:45;49843:17;;49838:2;49823:18;;49816:45;49898:3;49892;49877:19;;49870:32;;;49376:713;;49925:47;;49952:19;;49944:6;49925:47;:::i;:::-;50021:9;50013:6;50009:22;50003:3;49992:9;49988:19;49981:51;50049:34;50076:6;50068;50049:34;:::i;50094:248::-;50268:25;;;50324:2;50309:18;;50302:34;50256:2;50241:18;;50223:119::o;50347:452::-;;50584:4;50576:6;50572:17;50561:9;50554:36;50638:6;50630;50626:19;50621:2;50610:9;50606:18;50599:47;50682:3;50677:2;50666:9;50662:18;50655:31;50703:47;50745:3;50734:9;50730:19;50722:6;50703:47;:::i;:::-;50695:55;;50786:6;50781:2;50770:9;50766:18;50759:34;50544:255;;;;;;;:::o;50804:568::-;51117:4;51105:17;;;;51087:36;;51154:2;51139:18;;51132:34;;;;51197:2;51182:18;;51175:34;;;;-1:-1:-1;;;;;51245:32:17;51240:2;51225:18;;51218:60;51309:3;51294:19;;51287:35;51265:3;51338:19;;51331:35;51074:3;51059:19;;51041:331::o;51377:629::-;;51688:4;51680:6;51676:17;51665:9;51658:36;51730:6;51725:2;51714:9;51710:18;51703:34;51773:6;51768:2;51757:9;51753:18;51746:34;51828:4;51820:6;51816:17;51811:2;51800:9;51796:18;51789:45;51871:6;51865:3;51854:9;51850:19;51843:35;51915:3;51909;51898:9;51894:19;51887:32;51936:64;51995:3;51984:9;51980:19;51972:6;51964;51936:64;:::i;52011:775::-;52406:4;52394:17;;52376:36;;52443:2;52428:18;;52421:34;;;52486:2;52471:18;;52464:34;;;52529:2;52514:18;;52507:34;;;-1:-1:-1;;;;;52578:32:17;;52572:3;52557:19;;52550:61;52011:775;52364:3;52620:57;52598:3;52657:19;;52649:6;52620:57;:::i;:::-;52714:2;52708:3;52697:9;52693:19;52686:31;52734:46;52776:2;52765:9;52761:18;52753:6;52734:46;:::i;52791:612::-;;53096:4;53088:6;53084:17;53073:9;53066:36;53138:6;53133:2;53122:9;53118:18;53111:34;53181:6;53176:2;53165:9;53161:18;53154:34;53224:6;53219:2;53208:9;53204:18;53197:34;53268:6;53262:3;53251:9;53247:19;53240:35;53312:3;53306;53295:9;53291:19;53284:32;53333:64;53392:3;53381:9;53377:19;53369:6;53361;53333:64;:::i;53408:242::-;53478:2;53472:9;53508:17;;;-1:-1:-1;;;;;53540:34:17;;53576:22;;;53537:62;53534:2;;;53602:9;53534:2;53629;53622:22;53452:198;;-1:-1:-1;53452:198:17:o;53655:181::-;;-1:-1:-1;;;;;53730:6:17;53727:30;53724:2;;;53760:9;53724:2;-1:-1:-1;53819:2:17;53796:17;-1:-1:-1;;53792:31:17;53825:4;53788:42;;53714:122::o;53841:258::-;53913:1;53923:113;53937:6;53934:1;53931:13;53923:113;;;54013:11;;;54007:18;53994:11;;;53987:39;53959:2;53952:10;53923:113;;;54054:6;54051:1;54048:13;54045:2;;;54089:1;54080:6;54075:3;54071:16;54064:27;54045:2;;53894:205;;;:::o;54104:133::-;-1:-1:-1;;;;;54181:31:17;;54171:42;;54161:2;;54227:1;54224;54217:12;54161:2;54151:86;:::o;54242:120::-;54330:5;54323:13;54316:21;54309:5;54306:32;54296:2;;54352:1;54349;54342:12;54367:116;54453:4;54446:5;54442:16;54435:5;54432:27;54422:2;;54473:1;54470;54463:12

Swarm Source

ipfs://d86582ffb411c85869be51806318cb203c2835996c58fcb8521dd7b53c5baece
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.