ETH Price: $2,934.94 (-2.09%)
Gas: 29 Gwei

Contract

0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913
 

Multichain Info

Transaction Hash
Method
Block
From
To
Value
0xa07d88737cb7b16be40084faf66a5b81d7cc1d90a47710c935246142e7a18dcaMulticall(pending)2024-02-22 4:12:259 mins ago1708575145IN
Maverick Protocol: Router
0.008 ETH(Pending)(Pending)
0x11392677625ea2f360bb9e1525dc806e0a0c7eaf2957fe870a62395616cfb4e9Multicall(pending)2024-02-22 4:08:5312 mins ago1708574933IN
Maverick Protocol: Router
0.0001 ETH(Pending)(Pending)
0xd48b21b2b4c0f497774a48d79494e95c0aaf4d6ea406ea265d578376d14b4e7eMulticall(pending)2024-02-04 8:07:1817 days 20 hrs ago1707034038IN
Maverick Protocol: Router
0.002 ETH(Pending)(Pending)
0x6efe27a013e8d6a1cc2fda096c2ccb2f6989f19b9bdf248c9519a24a44e0e40fMulticall(pending)2024-02-04 5:14:1017 days 23 hrs ago1707023650IN
Maverick Protocol: Router
0.0055291981 ETH(Pending)(Pending)
0x7e48523626549349509c57c4a77c0d71f38c218612d56c0b670764eb883442c9Multicall(pending)2024-02-04 4:05:2018 days 16 mins ago1707019520IN
Maverick Protocol: Router
0.0002 ETH(Pending)(Pending)
0xb171663f14dad7a1862723a31dbe3ff3b0cc3c767aab8ad3c658815b6e84ff47Multicall(pending)2024-02-04 2:28:2218 days 1 hr ago1707013702IN
Maverick Protocol: Router
0.0000124623 ETH(Pending)(Pending)
0xd590d91146fd8cb6aefd3dacfa25a15ff931b593d58e3ac5c6dcd8545ff349f3Multicall(pending)2024-02-04 2:17:4218 days 2 hrs ago1707013062IN
Maverick Protocol: Router
0.0002 ETH(Pending)(Pending)
0x11fe56f9f8f32251782b465780aa6d137d4717977c254587442eb42034ea8aeaMulticall(pending)2024-02-04 1:45:2618 days 2 hrs ago1707011126IN
Maverick Protocol: Router
0.0001 ETH(Pending)(Pending)
0x691ea9b69661eb2df3b86a6c0ad54a7d367e128227b6fc1104183c1a5e5396e0Multicall(pending)2024-02-04 1:31:5118 days 2 hrs ago1707010311IN
Maverick Protocol: Router
0.0087555655 ETH(Pending)(Pending)
Multicall192802922024-02-22 2:49:351 hr 31 mins ago1708570175IN
Maverick Protocol: Router
0 ETH0.0050316431.29930447
Multicall192799122024-02-22 1:32:352 hrs 48 mins ago1708565555IN
Maverick Protocol: Router
0 ETH0.0068129235.8145004
Multicall192791142024-02-21 22:50:475 hrs 30 mins ago1708555847IN
Maverick Protocol: Router
0 ETH0.0056281336.19355559
Multicall192789692024-02-21 22:21:475 hrs 59 mins ago1708554107IN
Maverick Protocol: Router
0.5 ETH0.0053472736.92612286
Multicall192784052024-02-21 20:27:597 hrs 53 mins ago1708547279IN
Maverick Protocol: Router
0 ETH0.0047068232.69833586
Multicall192782482024-02-21 19:55:598 hrs 25 mins ago1708545359IN
Maverick Protocol: Router
0 ETH0.0144251238.23331563
Multicall192782302024-02-21 19:52:238 hrs 29 mins ago1708545143IN
Maverick Protocol: Router
0 ETH0.0067690634.59111936
Multicall192781122024-02-21 19:28:238 hrs 53 mins ago1708543703IN
Maverick Protocol: Router
0 ETH0.0112617641.03499861
Multicall192773762024-02-21 17:00:1111 hrs 21 mins ago1708534811IN
Maverick Protocol: Router
0.14 ETH0.0083340455.56734784
Multicall192769802024-02-21 15:40:1112 hrs 41 mins ago1708530011IN
Maverick Protocol: Router
0 ETH0.0064894143.13449364
Multicall192762412024-02-21 13:10:3515 hrs 10 mins ago1708521035IN
Maverick Protocol: Router
0 ETH0.0056221935.03538366
Multicall192761642024-02-21 12:54:5915 hrs 26 mins ago1708520099IN
Maverick Protocol: Router
0 ETH0.0045722131.56078837
Multicall192759632024-02-21 12:14:2316 hrs 7 mins ago1708517663IN
Maverick Protocol: Router
0.02 ETH0.0114117343.03310011
Multicall192759602024-02-21 12:13:4716 hrs 7 mins ago1708517627IN
Maverick Protocol: Router
0 ETH0.0070926344.15815782
Multicall192759402024-02-21 12:09:4716 hrs 11 mins ago1708517387IN
Maverick Protocol: Router
0 ETH0.0176818450.53674706
Multicall192757792024-02-21 11:37:1116 hrs 44 mins ago1708515431IN
Maverick Protocol: Router
0 ETH0.0062532632.6307626
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
192802922024-02-22 2:49:351 hr 31 mins ago1708570175
Maverick Protocol: Router
0.09779069 ETH
192802922024-02-22 2:49:351 hr 31 mins ago1708570175
Maverick Protocol: Router
0.09779069 ETH
192791142024-02-21 22:50:475 hrs 30 mins ago1708555847
Maverick Protocol: Router
0.79213135 ETH
192791142024-02-21 22:50:475 hrs 30 mins ago1708555847
Maverick Protocol: Router
0.79213135 ETH
192789692024-02-21 22:21:475 hrs 59 mins ago1708554107
Maverick Protocol: Router
0.5 ETH
192782482024-02-21 19:55:598 hrs 25 mins ago1708545359
Maverick Protocol: Router
1.71967457 ETH
192782482024-02-21 19:55:598 hrs 25 mins ago1708545359
Maverick Protocol: Router
1.71967457 ETH
192782302024-02-21 19:52:238 hrs 29 mins ago1708545143
Maverick Protocol: Router
1.30251308 ETH
192782302024-02-21 19:52:238 hrs 29 mins ago1708545143
Maverick Protocol: Router
1.30251308 ETH
192773762024-02-21 17:00:1111 hrs 21 mins ago1708534811
Maverick Protocol: Router
0.14 ETH
192769802024-02-21 15:40:1112 hrs 41 mins ago1708530011
Maverick Protocol: Router
0.10316558 ETH
192769802024-02-21 15:40:1112 hrs 41 mins ago1708530011
Maverick Protocol: Router
0.10316558 ETH
192767622024-02-21 14:55:4713 hrs 25 mins ago1708527347
Maverick Protocol: Router
0.14955 ETH
192767622024-02-21 14:55:4713 hrs 25 mins ago1708527347
Maverick Protocol: Router
0.14955 ETH
192762412024-02-21 13:10:3515 hrs 10 mins ago1708521035
Maverick Protocol: Router
0.52337795 ETH
192762412024-02-21 13:10:3515 hrs 10 mins ago1708521035
Maverick Protocol: Router
0.52337795 ETH
192761642024-02-21 12:54:5915 hrs 26 mins ago1708520099
Maverick Protocol: Router
0.07910741 ETH
192761642024-02-21 12:54:5915 hrs 26 mins ago1708520099
Maverick Protocol: Router
0.07910741 ETH
192759632024-02-21 12:14:2316 hrs 7 mins ago1708517663
Maverick Protocol: Router
0.02 ETH
192759602024-02-21 12:13:4716 hrs 7 mins ago1708517627
Maverick Protocol: Router
0.04866403 ETH
192759602024-02-21 12:13:4716 hrs 7 mins ago1708517627
Maverick Protocol: Router
0.04866403 ETH
192759402024-02-21 12:09:4716 hrs 11 mins ago1708517387
Maverick Protocol: Router
0.11675886 ETH
192759402024-02-21 12:09:4716 hrs 11 mins ago1708517387
Maverick Protocol: Router
0.11675886 ETH
192759372024-02-21 12:09:1116 hrs 12 mins ago1708517351
Maverick Protocol: Router
0.11491415 ETH
192759372024-02-21 12:09:1116 hrs 12 mins ago1708517351
Maverick Protocol: Router
0.11491415 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Router

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
default evmVersion, GNU GPLv2 license
File 11 of 23 : Router.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

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

import "@maverick/contracts/contracts/interfaces/IPool.sol";
import "@maverick/contracts/contracts/interfaces/IFactory.sol";
import "@maverick/contracts/contracts/interfaces/IPosition.sol";

import "./interfaces/IRouter.sol";
import "./interfaces/external/IWETH9.sol";
import "./libraries/TransferHelper.sol";
import "./libraries/Path.sol";
import "./libraries/Deadline.sol";
import "./libraries/Multicall.sol";
import "./libraries/SelfPermit.sol";

contract Router is IRouter, Multicall, SelfPermit, Deadline {
    using Path for bytes;
    /// @dev Used as the placeholder value for amountInCached, because the
    //computed amount in for an exact output swap / can never actually be this
    //value
    uint256 private constant DEFAULT_AMOUNT_IN_CACHED = type(uint256).max;

    /// @dev Transient storage variable used for returning the computed amount in for an exact output swap.
    uint256 private amountInCached = DEFAULT_AMOUNT_IN_CACHED;

    struct AddLiquidityCallbackData {
        IERC20 tokenA;
        IERC20 tokenB;
        IPool pool;
        address payer;
    }

    struct SwapCallbackData {
        bytes path;
        address payer;
        bool exactOutput;
    }

    /// @inheritdoc IRouter
    IFactory public immutable factory;
    /// @inheritdoc IRouter
    IPosition public immutable position;
    /// @inheritdoc ISlimRouter
    IWETH9 public immutable WETH9;

    constructor(IFactory _factory, IWETH9 _WETH9) {
        factory = _factory;
        position = _factory.position();
        WETH9 = _WETH9;
    }

    receive() external payable {
        require(IWETH9(msg.sender) == WETH9, "Not WETH9");
    }

    /// @inheritdoc ISlimRouter
    function unwrapWETH9(uint256 amountMinimum, address recipient) public payable override {
        uint256 balanceWETH9 = WETH9.balanceOf(address(this));
        require(balanceWETH9 >= amountMinimum, "Insufficient WETH9");

        if (balanceWETH9 > 0) {
            WETH9.withdraw(balanceWETH9);
            TransferHelper.safeTransferETH(recipient, balanceWETH9);
        }
    }

    /// @inheritdoc ISlimRouter
    function sweepToken(IERC20 token, uint256 amountMinimum, address recipient) public payable {
        uint256 balanceToken = token.balanceOf(address(this));
        require(balanceToken >= amountMinimum, "Insufficient token");

        if (balanceToken > 0) {
            TransferHelper.safeTransfer(address(token), recipient, balanceToken);
        }
    }

    /// @inheritdoc ISlimRouter
    function refundETH() external payable override {
        if (address(this).balance > 0)
            TransferHelper.safeTransferETH(msg.sender, address(this).balance);
    }

    /// @param token The token to pay
    /// @param payer The entity that must pay
    /// @param recipient The entity that will receive payment
    /// @param value The amount to pay
    function pay(IERC20 token, address payer, address recipient, uint256 value) internal {
        if (IWETH9(address(token)) == WETH9 && address(this).balance >= value) {
            WETH9.deposit{value: value}();
            WETH9.transfer(recipient, value);
        } else if (payer == address(this)) {
            TransferHelper.safeTransfer(address(token), recipient, value);
        } else {
            TransferHelper.safeTransferFrom(address(token), payer, recipient, value);
        }
    }

    function swapCallback(uint256 amountToPay, uint256 amountOut, bytes calldata _data) external {
        require(amountToPay > 0 && amountOut > 0, "In or Out Amount is Zero");
        require(factory.isFactoryPool(IPool(msg.sender)), "Must call from a Factory Pool");

        SwapCallbackData memory data = abi.decode(_data, (SwapCallbackData));
        (IERC20 tokenIn, IERC20 tokenOut, IPool pool) = data.path.decodeFirstPool();

        require(msg.sender == address(pool));

        if (data.exactOutput) {
            if (data.path.hasMultiplePools()) {
                data.path = data.path.skipToken();
                exactOutputInternal(amountToPay, msg.sender, data);
            } else {
                amountInCached = amountToPay;
                pay(tokenOut, data.payer, msg.sender, amountToPay);
            }
        } else {
            pay(tokenIn, data.payer, msg.sender, amountToPay);
        }
    }

    function exactInputInternal(
        uint256 amountIn,
        address recipient,
        uint256 sqrtPriceLimitD18,
        SwapCallbackData memory data
    ) private returns (uint256 amountOut) {
        if (recipient == address(0)) recipient = address(this);

        (IERC20 tokenIn, IERC20 tokenOut, IPool pool) = data.path.decodeFirstPool();

        bool tokenAIn = tokenIn < tokenOut;

        (, amountOut) = pool.swap(
            recipient,
            amountIn,
            tokenAIn,
            false,
            sqrtPriceLimitD18,
            abi.encode(data)
        );
    }

    /// @inheritdoc ISlimRouter
    function exactInputSingle(
        ExactInputSingleParams calldata params
    ) external payable override checkDeadline(params.deadline) returns (uint256 amountOut) {
        bool tokenAIn = params.tokenIn < params.tokenOut;

        (, amountOut) = params.pool.swap(
            (params.recipient == address(0)) ? address(this) : params.recipient,
            params.amountIn,
            tokenAIn,
            false,
            params.sqrtPriceLimitD18,
            abi.encode(
                SwapCallbackData({
                    path: abi.encodePacked(params.tokenIn, params.pool, params.tokenOut),
                    payer: msg.sender,
                    exactOutput: false
                })
            )
        );
        require(amountOut >= params.amountOutMinimum, "Too little received");
    }

    /// @inheritdoc IRouter
    function exactInput(
        ExactInputParams memory params
    ) external payable override checkDeadline(params.deadline) returns (uint256 amountOut) {
        address payer = msg.sender;

        while (true) {
            bool stillMultiPoolSwap = params.path.hasMultiplePools();

            params.amountIn = exactInputInternal(
                params.amountIn,
                stillMultiPoolSwap ? address(this) : params.recipient,
                0,
                SwapCallbackData({
                    path: params.path.getFirstPool(),
                    payer: payer,
                    exactOutput: false
                })
            );

            if (stillMultiPoolSwap) {
                payer = address(this);
                params.path = params.path.skipToken();
            } else {
                amountOut = params.amountIn;
                break;
            }
        }

        require(amountOut >= params.amountOutMinimum, "Too little received");
    }

    /// @dev Performs a single exact output swap
    function exactOutputInternal(
        uint256 amountOut,
        address recipient,
        SwapCallbackData memory data
    ) private returns (uint256 amountIn) {
        if (recipient == address(0)) recipient = address(this);

        (IERC20 tokenOut, IERC20 tokenIn, IPool pool) = data.path.decodeFirstPool();

        bool tokenAIn = tokenIn < tokenOut;
        uint256 amountOutReceived;
        (amountIn, amountOutReceived) = pool.swap(
            recipient,
            amountOut,
            tokenAIn,
            true,
            0,
            abi.encode(data)
        );
        require(amountOutReceived == amountOut, "Requested amount not available");
    }

    /// @inheritdoc ISlimRouter
    function exactOutputSingle(
        ExactOutputSingleParams calldata params
    ) external payable override checkDeadline(params.deadline) returns (uint256 amountIn) {
        bool tokenAIn = params.tokenIn < params.tokenOut;
        uint256 amountOutReceived;
        (amountIn, amountOutReceived) = params.pool.swap(
            (params.recipient == address(0)) ? address(this) : params.recipient,
            params.amountOut,
            tokenAIn,
            true,
            0,
            abi.encode(
                SwapCallbackData({
                    path: abi.encodePacked(params.tokenOut, params.pool, params.tokenIn),
                    payer: msg.sender,
                    exactOutput: true
                })
            )
        );
        require(amountOutReceived == params.amountOut, "Requested amount not available");
        require(amountIn <= params.amountInMaximum, "Too much requested");
        amountInCached = DEFAULT_AMOUNT_IN_CACHED;
    }

    /// @inheritdoc IRouter
    function exactOutput(
        ExactOutputParams calldata params
    ) external payable override checkDeadline(params.deadline) returns (uint256 amountIn) {
        exactOutputInternal(
            params.amountOut,
            params.recipient,
            SwapCallbackData({path: params.path, payer: msg.sender, exactOutput: true})
        );

        amountIn = amountInCached;
        require(amountIn <= params.amountInMaximum, "Too much requested");
        amountInCached = DEFAULT_AMOUNT_IN_CACHED;
    }

    // Liqudity

    function addLiquidityCallback(uint256 amountA, uint256 amountB, bytes calldata _data) external {
        AddLiquidityCallbackData memory data = abi.decode(_data, (AddLiquidityCallbackData));
        require(factory.isFactoryPool(IPool(msg.sender)));
        require(msg.sender == address(data.pool));
        if (amountA != 0) {
            pay(data.tokenA, data.payer, msg.sender, amountA);
        }
        if (amountB != 0) {
            pay(data.tokenB, data.payer, msg.sender, amountB);
        }
    }

    function addLiquidity(
        IPool pool,
        uint256 tokenId,
        IPool.AddLiquidityParams[] calldata params,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount
    )
        private
        returns (
            uint256 receivingTokenId,
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            IPool.BinDelta[] memory binDeltas
        )
    {
        if (tokenId == 0) {
            if (IPosition(position).tokenOfOwnerByIndexExists(msg.sender, 0)) {
                tokenId = IPosition(position).tokenOfOwnerByIndex(msg.sender, 0);
            } else {
                tokenId = IPosition(position).mint(msg.sender);
            }
        }
        receivingTokenId = tokenId;

        AddLiquidityCallbackData memory data = AddLiquidityCallbackData({
            tokenA: pool.tokenA(),
            tokenB: pool.tokenB(),
            pool: pool,
            payer: msg.sender
        });
        (tokenAAmount, tokenBAmount, binDeltas) = pool.addLiquidity(
            tokenId,
            params,
            abi.encode(data)
        );

        require(
            tokenAAmount >= minTokenAAmount && tokenBAmount >= minTokenBAmount,
            "Too little added"
        );
    }

    /// @inheritdoc IRouter
    function addLiquidityToPool(
        IPool pool,
        uint256 tokenId,
        IPool.AddLiquidityParams[] calldata params,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        uint256 deadline
    )
        external
        payable
        checkDeadline(deadline)
        returns (
            uint256 receivingTokenId,
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            IPool.BinDelta[] memory binDeltas
        )
    {
        return addLiquidity(pool, tokenId, params, minTokenAAmount, minTokenBAmount);
    }

    /// @inheritdoc IRouter
    function addLiquidityWTickLimits(
        IPool pool,
        uint256 tokenId,
        IPool.AddLiquidityParams[] calldata params,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        int32 minActiveTick,
        int32 maxActiveTick,
        uint256 deadline
    )
        external
        payable
        checkDeadline(deadline)
        returns (
            uint256 receivingTokenId,
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            IPool.BinDelta[] memory binDeltas
        )
    {
        int32 activeTick = pool.getState().activeTick;

        require(
            activeTick >= minActiveTick && activeTick <= maxActiveTick,
            "activeTick not in range"
        );

        return addLiquidity(pool, tokenId, params, minTokenAAmount, minTokenBAmount);
    }

    function getOrCreatePool(PoolParams calldata poolParams) private returns (IPool pool) {
        {
            pool = IFactory(factory).lookup(
                poolParams.fee,
                poolParams.tickSpacing,
                poolParams.lookback,
                poolParams.tokenA,
                poolParams.tokenB
            );
        }
        if (address(pool) == address(0)) {
            pool = IFactory(factory).create(
                poolParams.fee,
                poolParams.tickSpacing,
                poolParams.lookback,
                poolParams.activeTick,
                poolParams.tokenA,
                poolParams.tokenB
            );
        }
    }

    /// @inheritdoc IRouter
    function getOrCreatePoolAndAddLiquidity(
        PoolParams calldata poolParams,
        uint256 tokenId,
        IPool.AddLiquidityParams[] calldata addParams,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        uint256 deadline
    )
        external
        payable
        checkDeadline(deadline)
        returns (
            uint256 receivingTokenId,
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            IPool.BinDelta[] memory binDeltas
        )
    {
        IPool pool = getOrCreatePool(poolParams);
        return addLiquidity(pool, tokenId, addParams, minTokenAAmount, minTokenBAmount);
    }

    /// @inheritdoc IRouter
    function migrateBinsUpStack(
        IPool pool,
        uint128[] calldata binIds,
        uint32 maxRecursion,
        uint256 deadline
    ) external checkDeadline(deadline) {
        for (uint256 i = 0; i < binIds.length; i++) {
            pool.migrateBinUpStack(binIds[i], maxRecursion);
        }
    }

    /// @inheritdoc IRouter
    function removeLiquidity(
        IPool pool,
        address recipient,
        uint256 tokenId,
        IPool.RemoveLiquidityParams[] calldata params,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        uint256 deadline
    )
        external
        checkDeadline(deadline)
        returns (uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas)
    {
        require(msg.sender == position.ownerOf(tokenId), "P");

        if (recipient == address(0)) recipient = address(this);
        (tokenAAmount, tokenBAmount, binDeltas) = pool.removeLiquidity(recipient, tokenId, params);

        require(
            tokenAAmount >= minTokenAAmount && tokenBAmount >= minTokenBAmount,
            "Too little removed"
        );
    }
}

File 2 of 23 : IFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "../interfaces/IPool.sol";
import "../interfaces/IPosition.sol";

interface IFactory {
    event PoolCreated(
        address poolAddress,
        uint256 fee,
        uint256 tickSpacing,
        int32 activeTick,
        int256 lookback,
        uint64 protocolFeeRatio,
        IERC20 tokenA,
        IERC20 tokenB
    );
    event SetFactoryProtocolFeeRatio(uint64 protocolFeeRatio);
    event SetFactoryOwner(address owner);

    /// @notice creates new pool
    /// @param _fee is a rate in prbmath 60x18 decimal format
    /// @param _tickSpacing  1.0001^tickSpacing is the bin width
    /// @param _activeTick initial activeTick of the pool
    /// @param _lookback TWAP lookback in whole seconds
    /// @param _tokenA ERC20 token
    /// @param _tokenB ERC20 token
    function create(
        uint256 _fee,
        uint256 _tickSpacing,
        int256 _lookback,
        int32 _activeTick,
        IERC20 _tokenA,
        IERC20 _tokenB
    ) external returns (IPool);

    function lookup(
        uint256 fee,
        uint256 tickSpacing,
        int256 lookback,
        IERC20 tokenA,
        IERC20 tokenB
    ) external view returns (IPool);

    function owner() external view returns (address);

    function position() external view returns (IPosition);

    /// @notice protocolFeeRatio ratio of the swap fee that is kept for the
    //protocol
    function protocolFeeRatio() external view returns (uint64);

    /// @notice lookup table for whether a pool is owned by the factory
    function isFactoryPool(IPool pool) external view returns (bool);
}

File 3 of 23 : IPool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IFactory.sol";

interface IPool {
    event Swap(
        address sender,
        address recipient,
        bool tokenAIn,
        bool exactOutput,
        uint256 amountIn,
        uint256 amountOut,
        int32 activeTick
    );

    event AddLiquidity(address indexed sender, uint256 indexed tokenId, BinDelta[] binDeltas);

    event MigrateBinsUpStack(address indexed sender, uint128 binId, uint32 maxRecursion);

    event TransferLiquidity(uint256 fromTokenId, uint256 toTokenId, RemoveLiquidityParams[] params);

    event RemoveLiquidity(
        address indexed sender,
        address indexed recipient,
        uint256 indexed tokenId,
        BinDelta[] binDeltas
    );

    event BinMerged(uint128 indexed binId, uint128 reserveA, uint128 reserveB, uint128 mergeId);

    event BinMoved(uint128 indexed binId, int128 previousTick, int128 newTick);

    event ProtocolFeeCollected(uint256 protocolFee, bool isTokenA);

    event SetProtocolFeeRatio(uint256 protocolFee);

    /// @notice return parameters for Add/Remove liquidity
    /// @param binId of the bin that changed
    /// @param kind one of the 4 Kinds (0=static, 1=right, 2=left, 3=both)
    /// @param isActive bool to indicate whether the bin is still active
    /// @param lowerTick is the lower price tick of the bin in its current state
    /// @param deltaA amount of A token that has been added or removed
    /// @param deltaB amount of B token that has been added or removed
    /// @param deltaLpToken amount of LP balance that has increase (add) or decreased (remove)
    struct BinDelta {
        uint128 deltaA;
        uint128 deltaB;
        uint256 deltaLpBalance;
        uint128 binId;
        uint8 kind;
        int32 lowerTick;
        bool isActive;
    }

    /// @notice time weighted average state
    /// @param twa the twa at the last update instant
    /// @param value the new value that was passed in at the last update
    /// @param lastTimestamp timestamp of the last update in seconds
    /// @param lookback time in seconds
    struct TwaState {
        int96 twa;
        int96 value;
        uint64 lastTimestamp;
    }

    /// @notice bin state parameters
    /// @param kind one of the 4 Kinds (0=static, 1=right, 2=left, 3=both)
    /// @param lowerTick is the lower price tick of the bin in its current state
    /// @param mergeId binId of the bin that this bin has merged in to
    /// @param reserveA amount of A token in bin
    /// @param reserveB amount of B token in bin
    /// @param totalSupply total amount of LP tokens in this bin
    /// @param mergeBinBalance LP token balance that this bin posseses of the merge bin
    struct BinState {
        uint128 reserveA;
        uint128 reserveB;
        uint128 mergeBinBalance;
        uint128 mergeId;
        uint128 totalSupply;
        uint8 kind;
        int32 lowerTick;
    }

    /// @notice Parameters for each bin that will get new liquidity
    /// @param kind one of the 4 Kinds (0=static, 1=right, 2=left, 3=both)
    /// @param pos bin position
    /// @param isDelta bool that indicates whether the bin position is relative
    //to the current bin or an absolute position
    /// @param deltaA amount of A token to add
    /// @param deltaB amount of B token to add
    struct AddLiquidityParams {
        uint8 kind;
        int32 pos;
        bool isDelta;
        uint128 deltaA;
        uint128 deltaB;
    }

    /// @notice Parameters for each bin that will have liquidity removed
    /// @param binId index of the bin losing liquidity
    /// @param amount LP balance amount to remove
    struct RemoveLiquidityParams {
        uint128 binId;
        uint128 amount;
    }

    /// @notice State of the pool
    /// @param activeTick  current bin position that contains the active bins
    /// @param status pool status.  e.g. locked or unlocked; status values
    //defined in Pool.sol
    /// @param binCounter index of the last bin created
    /// @param protocolFeeRatio ratio of the swap fee that is kept for the
    //protocol
    struct State {
        int32 activeTick;
        uint8 status;
        uint128 binCounter;
        uint64 protocolFeeRatio;
    }

    /// @notice fee for pool in 18 decimal format
    function fee() external view returns (uint256);

    /// @notice tickSpacing of pool where 1.0001^tickSpacing is the bin width
    function tickSpacing() external view returns (uint256);

    /// @notice address of token A
    function tokenA() external view returns (IERC20);

    /// @notice address of token B
    function tokenB() external view returns (IERC20);

    /// @notice address of Factory
    function factory() external view returns (IFactory);

    /// @notice bitmap of active bins
    function binMap(int32 tick) external view returns (uint256);

    /// @notice mapping of tick/kind to binId
    function binPositions(int32 tick, uint256 kind) external view returns (uint128);

    /// @notice internal accounting of the sum tokenA balance across bins
    function binBalanceA() external view returns (uint128);

    /// @notice internal accounting of the sum tokenB balance across bins
    function binBalanceB() external view returns (uint128);

    /// @notice log_binWidth of the time weighted average price
    function getTwa() external view returns (TwaState memory);

    /// @notice pool state
    function getState() external view returns (State memory);

    /// @notice Add liquidity to a pool.
    /// @param tokenId NFT token ID that will hold the position
    /// @param params array of AddLiquidityParams that specify the mode and
    //position of the liquidity
    /// @param data callback function that addLiquidity will call so that the
    //caller can transfer tokens
    function addLiquidity(
        uint256 tokenId,
        AddLiquidityParams[] calldata params,
        bytes calldata data
    )
        external
        returns (
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            BinDelta[] memory binDeltas
        );

    /// @notice Transfer liquidity in an array of bins from one nft tokenId
    //to another
    /// @param fromTokenId NFT token ID that holds the position being transferred
    /// @param toTokenId NFT token ID that is receiving liquidity
    /// @param params array of binIds and amounts to transfer
    function transferLiquidity(
        uint256 fromTokenId,
        uint256 toTokenId,
        RemoveLiquidityParams[] calldata params
    ) external;

    /// @notice Remove liquidity from a pool.
    /// @param recipient address that will receive the removed tokens
    /// @param tokenId NFT token ID that holds the position being removed
    /// @param params array of RemoveLiquidityParams that specify the bins,
    //and amounts
    function removeLiquidity(
        address recipient,
        uint256 tokenId,
        RemoveLiquidityParams[] calldata params
    )
        external
        returns (
            uint256 tokenAOut,
            uint256 tokenBOut,
            BinDelta[] memory binDeltas
        );

    /// @notice Migrate bins up the linked list of merged bins so that its
    //mergeId is the currrent active bin.
    /// @param binId is an array of the binIds to be migrated
    /// @param maxRecursion is the maximum recursion depth of the migration. set to
    //zero to recurse until the active bin is found.
    function migrateBinUpStack(uint128 binId, uint32 maxRecursion) external;

    /// @notice swap tokens
    /// @param recipient address that will receive the output tokens
    /// @param amount amount of token that is either the input if exactOutput
    //is false or the output if exactOutput is true
    /// @param tokenAIn bool indicating whether tokenA is the input
    /// @param exactOutput bool indicating whether the amount specified is the
    //exact output amount (true)
    /// @param sqrtPriceLimit limiting sqrt price of the swap.  A value of 0
    //indicates no limit.  Limit is only engaged for exactOutput=false.  If the
    //limit is reached only part of the input amount will be swapped and the
    //callback will only require that amount of the swap to be paid.
    /// @param data callback function that swap will call so that the
    //caller can transfer tokens
    function swap(
        address recipient,
        uint256 amount,
        bool tokenAIn,
        bool exactOutput,
        uint256 sqrtPriceLimit,
        bytes calldata data
    ) external returns (uint256 amountIn, uint256 amountOut);

    /// @notice bin information for a given binId
    function getBin(uint128 binId) external view returns (BinState memory bin);

    /// @notice LP token balance for a given tokenId at a given binId
    function balanceOf(uint256 tokenId, uint128 binId) external view returns (uint256 lpToken);

    /// @notice tokenA scale value
    /// @dev msb is a flag to indicate whether tokenA has more or less than 18
    //decimals.  Scale is used in conjuction with Math.toScale/Math.fromScale
    //functions to convert from token amounts to D18 scale internal pool
    //accounting.
    function tokenAScale() external view returns (uint256);

    /// @notice tokenB scale value
    /// @dev msb is a flag to indicate whether tokenA has more or less than 18
    //decimals.  Scale is used in conjuction with Math.toScale/Math.fromScale
    //functions to convert from token amounts to D18 scale internal pool
    //accounting.
    function tokenBScale() external view returns (uint256);
}

File 4 of 23 : IPosition.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "../interfaces/IPositionMetadata.sol";

interface IPosition is IERC721Enumerable {
    event SetMetadata(IPositionMetadata metadata);

    /// @notice mint new position NFT
    function mint(address to) external returns (uint256 tokenId);

    /// @notice mint new position NFT
    function tokenOfOwnerByIndexExists(address owner, uint256 index) external view returns (bool);
}

File 5 of 23 : IPositionMetadata.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IPositionMetadata {
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 6 of 23 : ISwapCallback.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ISwapCallback {
    function swapCallback(
        uint256 amountIn,
        uint256 amountOut,
        bytes calldata data
    ) external;
}

File 7 of 23 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 8 of 23 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 9 of 23 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 10 of 23 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 11 of 23 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 12 of 23 : IMulticall.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

/// @title Multicall interface
/// @notice Enables calling multiple methods in a single call to the contract
interface IMulticall {
    /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed
    /// @dev The `msg.value` should not be trusted for any method callable from multicall.
    /// @param data The encoded function data for each of the calls to make to this contract
    /// @return results The results from each of the calls passed in via data
    function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
}

File 13 of 23 : IRouter.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "@maverick/contracts/contracts/interfaces/IFactory.sol";
import "@maverick/contracts/contracts/interfaces/IPool.sol";
import "@maverick/contracts/contracts/interfaces/IPosition.sol";
import "@maverick/contracts/contracts/interfaces/ISwapCallback.sol";
import "./external/IWETH9.sol";
import "./ISlimRouter.sol";

interface IRouter is ISlimRouter {
    /// @return Returns the address of the factory
    function factory() external view returns (IFactory);

    /// @return Returns the address of the Position NFT
    function position() external view returns (IPosition);

    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of
    //another along the specified path
    /// @param params The parameters necessary for the multi-hop swap, encoded
    //as `ExactInputParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInput(
        ExactInputParams calldata params
    ) external payable returns (uint256 amountOut);

    struct ExactOutputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of
    //another along the specified path (reversed)
    /// @param params The parameters necessary for the multi-hop swap, encoded
    //as `ExactOutputParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutput(
        ExactOutputParams calldata params
    ) external payable returns (uint256 amountIn);

    struct PoolParams {
        uint256 fee;
        uint256 tickSpacing;
        int256 lookback;
        int32 activeTick;
        IERC20 tokenA;
        IERC20 tokenB;
    }

    /// @notice create a pool and add liquidity to it
    /// @param poolParams paramters of a pool
    /// @param tokenId nft id of token that will hold lp balance, use 0 to mint a new token
    /// @param addParams paramters of liquidity addition
    /// @param minTokenAAmount minimum amount of token A to add, revert if not met
    /// @param minTokenBAmount minimum amount of token B to add, revert if not met
    /// @param deadline epoch timestamp in seconds
    function getOrCreatePoolAndAddLiquidity(
        PoolParams calldata poolParams,
        uint256 tokenId,
        IPool.AddLiquidityParams[] calldata addParams,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 receivingTokenId,
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            IPool.BinDelta[] memory binDeltas
        );

    /// @notice add liquidity to a pool
    /// @param pool pool to add liquidity to
    /// @param tokenId nft id of token that will hold lp balance, use 0 to mint a new token
    /// @param params paramters of liquidity addition
    /// @param minTokenAAmount minimum amount of token A to add, revert if not met
    /// @param minTokenBAmount minimum amount of token B to add, revert if not met
    /// @param deadline epoch timestamp in seconds
    function addLiquidityToPool(
        IPool pool,
        uint256 tokenId,
        IPool.AddLiquidityParams[] calldata params,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 receivingTokenId,
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            IPool.BinDelta[] memory binDeltas
        );

    /// @notice add liquidity to a pool with active tick limits
    /// @param pool pool to add liquidity to
    /// @param tokenId nft id of token that will hold lp balance, use 0 to mint a new token
    /// @param params paramters of liquidity addition
    /// @param minTokenAAmount minimum amount of token A to add, revert if not met
    /// @param minTokenBAmount minimum amount of token B to add, revert if not met
    /// @param minActiveTick lowest activeTick (inclusive) of pool that will permit transaction to pass
    /// @param maxActiveTick highest activeTick (inclusive) of pool that will permit transaction to pass
    /// @param deadline epoch timestamp in seconds
    function addLiquidityWTickLimits(
        IPool pool,
        uint256 tokenId,
        IPool.AddLiquidityParams[] calldata params,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        int32 minActiveTick,
        int32 maxActiveTick,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 receivingTokenId,
            uint256 tokenAAmount,
            uint256 tokenBAmount,
            IPool.BinDelta[] memory binDeltas
        );

    /// @notice moves the head of input merged bins to the active bin
    /// @param pool to remove from
    /// @param binIds array of bin Ids to migrate
    /// @param maxRecursion maximum recursion depth before returning; 0=no max
    /// @param deadline epoch timestamp in seconds
    function migrateBinsUpStack(
        IPool pool,
        uint128[] calldata binIds,
        uint32 maxRecursion,
        uint256 deadline
    ) external;

    /// @notice remove liquidity from pool and receive WETH if one of the tokens is WETH
    /// @dev router must be approved for the withdrawing tokenId: Position.approve(router, tokenId)
    /// @param pool pool to remove from
    /// @param recipient address where proceeds are sent; use zero or router address to leave tokens in router
    /// @param tokenId ID of position NFT that holds liquidity
    /// @param params paramters of liquidity removal
    /// @param minTokenAAmount minimum amount of token A to receive, revert if not met
    /// @param minTokenBAmount minimum amount of token B to receive, revert if not met
    /// @param deadline epoch timestamp in seconds
    function removeLiquidity(
        IPool pool,
        address recipient,
        uint256 tokenId,
        IPool.RemoveLiquidityParams[] calldata params,
        uint256 minTokenAAmount,
        uint256 minTokenBAmount,
        uint256 deadline
    )
        external
        returns (uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
}

File 14 of 23 : ISelfPermit.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;

/// @title Self Permit
/// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route
interface ISelfPermit {
    /// @notice Permits this contract to spend a given token from `msg.sender`
    /// @dev The `owner` is always msg.sender and the `spender` is always address(this).
    /// @param token The address of the token spent
    /// @param value The amount that can be spent of token
    /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp
    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
    function selfPermit(
        address token,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable;

    /// @notice Permits this contract to spend a given token from `msg.sender`
    /// @dev The `owner` is always msg.sender and the `spender` is always address(this).
    /// Can be used instead of #selfPermit to prevent calls from failing due to a frontrun of a call to #selfPermit
    /// @param token The address of the token spent
    /// @param value The amount that can be spent of token
    /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp
    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
    function selfPermitIfNecessary(
        address token,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable;

    /// @notice Permits this contract to spend the sender's tokens for permit signatures that have the `allowed` parameter
    /// @dev The `owner` is always msg.sender and the `spender` is always address(this)
    /// @param token The address of the token spent
    /// @param nonce The current nonce of the owner
    /// @param expiry The timestamp at which the permit is no longer valid
    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
    function selfPermitAllowed(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable;

    /// @notice Permits this contract to spend the sender's tokens for permit signatures that have the `allowed` parameter
    /// @dev The `owner` is always msg.sender and the `spender` is always address(this)
    /// Can be used instead of #selfPermitAllowed to prevent calls from failing due to a frontrun of a call to #selfPermitAllowed.
    /// @param token The address of the token spent
    /// @param nonce The current nonce of the owner
    /// @param expiry The timestamp at which the permit is no longer valid
    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
    function selfPermitAllowedIfNecessary(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable;
}

File 15 of 23 : ISlimRouter.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "@maverick/contracts/contracts/interfaces/IFactory.sol";
import "@maverick/contracts/contracts/interfaces/IPool.sol";
import "@maverick/contracts/contracts/interfaces/IPosition.sol";
import "@maverick/contracts/contracts/interfaces/ISwapCallback.sol";
import "./external/IWETH9.sol";

interface ISlimRouter is ISwapCallback {
    /// @return Returns the address of WETH9
    function WETH9() external view returns (IWETH9);

    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        IPool pool;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint256 sqrtPriceLimitD18;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of
    //another token
    /// @param params The parameters necessary for the swap, encoded as
    //`ExactInputSingleParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInputSingle(
        ExactInputSingleParams calldata params
    ) external payable returns (uint256 amountOut);

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        IPool pool;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of
    //another token
    /// @param params The parameters necessary for the swap, encoded as
    //`ExactOutputSingleParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutputSingle(
        ExactOutputSingleParams calldata params
    ) external payable returns (uint256 amountIn);

    /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH.
    /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users.
    /// @param amountMinimum The minimum amount of WETH9 to unwrap
    /// @param recipient The address receiving ETH
    function unwrapWETH9(uint256 amountMinimum, address recipient) external payable;

    /// @notice Refunds any ETH balance held by this contract to the `msg.sender`
    /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps
    /// that use ether for the input amount
    function refundETH() external payable;

    /// @notice Transfers the full amount of a token held by this contract to recipient
    /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users
    /// @param token The contract address of the token which will be transferred to `recipient`
    /// @param amountMinimum The minimum amount of token required for a transfer
    /// @param recipient The destination address of the token
    function sweepToken(IERC20 token, uint256 amountMinimum, address recipient) external payable;
}

File 16 of 23 : IERC20PermitAllowed.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title Interface for permit
/// @notice Interface used by DAI/CHAI for permit
interface IERC20PermitAllowed {
    /// @notice Approve the spender to spend some tokens via the holder signature
    /// @dev This is the permit interface used by DAI and CHAI
    /// @param holder The address of the token holder, the token owner
    /// @param spender The address of the token spender
    /// @param nonce The holder's nonce, increases at each call to permit
    /// @param expiry The timestamp at which the permit is no longer valid
    /// @param allowed Boolean that sets approval amount, true for type(uint256).max and false for 0
    /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
    /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
    /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
    function permit(
        address holder,
        address spender,
        uint256 nonce,
        uint256 expiry,
        bool allowed,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

File 17 of 23 : IWETH9.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

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

/// @title Interface for WETH9
interface IWETH9 is IERC20 {
    /// @notice Deposit ether to get wrapped ether
    function deposit() external payable;

    /// @notice Withdraw wrapped ether to get ether
    function withdraw(uint256) external;
}

File 18 of 23 : BytesLib.sol
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity ^0.8.0;

library BytesLib {
    function slice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    ) internal pure returns (bytes memory) {
        require(_length + 31 >= _length, "slice_overflow");
        require(_start + _length >= _start, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_start + 20 >= _start, "toAddress_overflow");
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {
        require(_start + 3 >= _start, "toUint24_overflow");
        require(_bytes.length >= _start + 3, "toUint24_outOfBounds");
        uint24 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x3), _start))
        }

        return tempUint;
    }
}

File 19 of 23 : Deadline.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

abstract contract Deadline {
    modifier checkDeadline(uint256 deadline) {
        require(block.timestamp <= deadline, "Transaction too old");
        _;
    }
}

File 20 of 23 : Multicall.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
pragma abicoder v2;

import "../interfaces/IMulticall.sol";

/// @title Multicall
/// @notice Enables calling multiple methods in a single call to the contract
abstract contract Multicall is IMulticall {
    /// @inheritdoc IMulticall
    function multicall(
        bytes[] calldata data
    ) public payable override returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            (bool success, bytes memory result) = address(this).delegatecall(data[i]);

            if (!success) {
                // Next 5 lines from https://ethereum.stackexchange.com/a/83577
                if (result.length < 68) revert();
                assembly {
                    result := add(result, 0x04)
                }
                revert(abi.decode(result, (string)));
            }

            results[i] = result;
        }
    }
}

File 21 of 23 : Path.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

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

import "@maverick/contracts/contracts/interfaces/IPool.sol";

import "./BytesLib.sol";

/// @title Functions for manipulating path data for multihop swaps
library Path {
    using BytesLib for bytes;

    /// @dev The length of the bytes encoded address
    uint256 private constant ADDR_SIZE = 20;

    /// @dev The offset of a single token address and pool address
    uint256 private constant NEXT_OFFSET = ADDR_SIZE + ADDR_SIZE;
    /// @dev The offset of an encoded pool key
    uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE;
    /// @dev The minimum length of an encoding that contains 2 or more pools
    uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET;

    /// @notice Returns true iff the path contains two or more pools
    /// @param path The encoded swap path
    /// @return True if path contains two or more pools, otherwise false
    function hasMultiplePools(bytes memory path) internal pure returns (bool) {
        return path.length >= MULTIPLE_POOLS_MIN_LENGTH;
    }

    /// @notice Returns the number of pools in the path
    /// @param path The encoded swap path
    /// @return The number of pools in the path
    function numPools(bytes memory path) internal pure returns (uint256) {
        // Ignore the first token address. From then on every fee and token offset indicates a pool.
        return ((path.length - ADDR_SIZE) / NEXT_OFFSET);
    }

    /// @notice Decodes the first pool in path
    /// @param path The bytes encoded swap path
    /// @return tokenIn The input in a path
    /// @return tokenOut The output in a path
    /// @return pool The pool
    function decodeFirstPool(
        bytes memory path
    ) internal pure returns (IERC20 tokenIn, IERC20 tokenOut, IPool pool) {
        tokenIn = IERC20(path.toAddress(0));
        pool = IPool(path.toAddress(ADDR_SIZE));
        tokenOut = IERC20(path.toAddress(NEXT_OFFSET));
    }

    /// @notice Gets the segment corresponding to the first pool in the path
    /// @param path The bytes encoded swap path
    /// @return The segment containing all data necessary to target the first pool in the path
    function getFirstPool(bytes memory path) internal pure returns (bytes memory) {
        return path.slice(0, POP_OFFSET);
    }

    /// @notice Skips a token + pool element from the buffer and returns the remainder
    /// @param path The swap path
    /// @return The remaining token + pool elements in the path
    function skipToken(bytes memory path) internal pure returns (bytes memory) {
        return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET);
    }
}

File 22 of 23 : SelfPermit.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol";

import "../interfaces/ISelfPermit.sol";
import "../interfaces/external/IERC20PermitAllowed.sol";

/// @title Self Permit
/// @notice Functionality to call permit on any EIP-2612-compliant token for use in the route
/// @dev These functions are expected to be embedded in multicalls to allow EOAs to approve a contract and call a function
/// that requires an approval in a single transaction.
abstract contract SelfPermit is ISelfPermit {
    /// @inheritdoc ISelfPermit
    function selfPermit(
        address token,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable override {
        IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s);
    }

    /// @inheritdoc ISelfPermit
    function selfPermitIfNecessary(
        address token,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable override {
        if (IERC20(token).allowance(msg.sender, address(this)) < value)
            selfPermit(token, value, deadline, v, r, s);
    }

    /// @inheritdoc ISelfPermit
    function selfPermitAllowed(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public payable override {
        IERC20PermitAllowed(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s);
    }

    /// @inheritdoc ISelfPermit
    function selfPermitAllowedIfNecessary(
        address token,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable override {
        if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max)
            selfPermitAllowed(token, nonce, expiry, v, r, s);
    }
}

File 23 of 23 : TransferHelper.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;

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

library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(address token, address from, address to, uint256 value) internal {
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)
        );
        require(success && (data.length == 0 || abi.decode(data, (bool))), "STF");
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(IERC20.transfer.selector, to, value)
        );
        require(success && (data.length == 0 || abi.decode(data, (bool))), "ST");
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev Errors with 'SA' if transfer fails
    /// @param token The contract address of the token to be approved
    /// @param to The target of the approval
    /// @param value The amount of the given token the target will be allowed to spend
    function safeApprove(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(IERC20.approve.selector, to, value)
        );
        require(success && (data.length == 0 || abi.decode(data, (bool))), "SA");
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "STE");
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IFactory","name":"_factory","type":"address"},{"internalType":"contract IWETH9","name":"_WETH9","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH9","outputs":[{"internalType":"contract IWETH9","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"addLiquidityCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"pool","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"int32","name":"pos","type":"int32"},{"internalType":"bool","name":"isDelta","type":"bool"},{"internalType":"uint128","name":"deltaA","type":"uint128"},{"internalType":"uint128","name":"deltaB","type":"uint128"}],"internalType":"struct IPool.AddLiquidityParams[]","name":"params","type":"tuple[]"},{"internalType":"uint256","name":"minTokenAAmount","type":"uint256"},{"internalType":"uint256","name":"minTokenBAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityToPool","outputs":[{"internalType":"uint256","name":"receivingTokenId","type":"uint256"},{"internalType":"uint256","name":"tokenAAmount","type":"uint256"},{"internalType":"uint256","name":"tokenBAmount","type":"uint256"},{"components":[{"internalType":"uint128","name":"deltaA","type":"uint128"},{"internalType":"uint128","name":"deltaB","type":"uint128"},{"internalType":"uint256","name":"deltaLpBalance","type":"uint256"},{"internalType":"uint128","name":"binId","type":"uint128"},{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"int32","name":"lowerTick","type":"int32"},{"internalType":"bool","name":"isActive","type":"bool"}],"internalType":"struct IPool.BinDelta[]","name":"binDeltas","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"pool","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"int32","name":"pos","type":"int32"},{"internalType":"bool","name":"isDelta","type":"bool"},{"internalType":"uint128","name":"deltaA","type":"uint128"},{"internalType":"uint128","name":"deltaB","type":"uint128"}],"internalType":"struct IPool.AddLiquidityParams[]","name":"params","type":"tuple[]"},{"internalType":"uint256","name":"minTokenAAmount","type":"uint256"},{"internalType":"uint256","name":"minTokenBAmount","type":"uint256"},{"internalType":"int32","name":"minActiveTick","type":"int32"},{"internalType":"int32","name":"maxActiveTick","type":"int32"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityWTickLimits","outputs":[{"internalType":"uint256","name":"receivingTokenId","type":"uint256"},{"internalType":"uint256","name":"tokenAAmount","type":"uint256"},{"internalType":"uint256","name":"tokenBAmount","type":"uint256"},{"components":[{"internalType":"uint128","name":"deltaA","type":"uint128"},{"internalType":"uint128","name":"deltaB","type":"uint128"},{"internalType":"uint256","name":"deltaLpBalance","type":"uint256"},{"internalType":"uint128","name":"binId","type":"uint128"},{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"int32","name":"lowerTick","type":"int32"},{"internalType":"bool","name":"isActive","type":"bool"}],"internalType":"struct IPool.BinDelta[]","name":"binDeltas","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"internalType":"struct IRouter.ExactInputParams","name":"params","type":"tuple"}],"name":"exactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"contract IPool","name":"pool","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"internalType":"uint256","name":"sqrtPriceLimitD18","type":"uint256"}],"internalType":"struct ISlimRouter.ExactInputSingleParams","name":"params","type":"tuple"}],"name":"exactInputSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"contract IPool","name":"pool","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct ISlimRouter.ExactOutputSingleParams","name":"params","type":"tuple"}],"name":"exactOutputSingle","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract IFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"tickSpacing","type":"uint256"},{"internalType":"int256","name":"lookback","type":"int256"},{"internalType":"int32","name":"activeTick","type":"int32"},{"internalType":"contract IERC20","name":"tokenA","type":"address"},{"internalType":"contract IERC20","name":"tokenB","type":"address"}],"internalType":"struct IRouter.PoolParams","name":"poolParams","type":"tuple"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"int32","name":"pos","type":"int32"},{"internalType":"bool","name":"isDelta","type":"bool"},{"internalType":"uint128","name":"deltaA","type":"uint128"},{"internalType":"uint128","name":"deltaB","type":"uint128"}],"internalType":"struct IPool.AddLiquidityParams[]","name":"addParams","type":"tuple[]"},{"internalType":"uint256","name":"minTokenAAmount","type":"uint256"},{"internalType":"uint256","name":"minTokenBAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"getOrCreatePoolAndAddLiquidity","outputs":[{"internalType":"uint256","name":"receivingTokenId","type":"uint256"},{"internalType":"uint256","name":"tokenAAmount","type":"uint256"},{"internalType":"uint256","name":"tokenBAmount","type":"uint256"},{"components":[{"internalType":"uint128","name":"deltaA","type":"uint128"},{"internalType":"uint128","name":"deltaB","type":"uint128"},{"internalType":"uint256","name":"deltaLpBalance","type":"uint256"},{"internalType":"uint128","name":"binId","type":"uint128"},{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"int32","name":"lowerTick","type":"int32"},{"internalType":"bool","name":"isActive","type":"bool"}],"internalType":"struct IPool.BinDelta[]","name":"binDeltas","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"pool","type":"address"},{"internalType":"uint128[]","name":"binIds","type":"uint128[]"},{"internalType":"uint32","name":"maxRecursion","type":"uint32"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"migrateBinsUpStack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"position","outputs":[{"internalType":"contract IPosition","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refundETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IPool","name":"pool","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint128","name":"binId","type":"uint128"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct IPool.RemoveLiquidityParams[]","name":"params","type":"tuple[]"},{"internalType":"uint256","name":"minTokenAAmount","type":"uint256"},{"internalType":"uint256","name":"minTokenBAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"tokenAAmount","type":"uint256"},{"internalType":"uint256","name":"tokenBAmount","type":"uint256"},{"components":[{"internalType":"uint128","name":"deltaA","type":"uint128"},{"internalType":"uint128","name":"deltaB","type":"uint128"},{"internalType":"uint256","name":"deltaLpBalance","type":"uint256"},{"internalType":"uint128","name":"binId","type":"uint128"},{"internalType":"uint8","name":"kind","type":"uint8"},{"internalType":"int32","name":"lowerTick","type":"int32"},{"internalType":"bool","name":"isActive","type":"bool"}],"internalType":"struct IPool.BinDelta[]","name":"binDeltas","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowed","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitAllowedIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToPay","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"swapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"sweepToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"unwrapWETH9","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040526000196000553480156200001757600080fd5b50604051620046c3380380620046c38339810160408190526200003a91620000dd565b6001600160a01b0382166080819052604080516309218e9160e01b815290516309218e91916004808201926020929091908290030181865afa15801562000085573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ab91906200011c565b6001600160a01b0390811660a0521660c0525062000143565b6001600160a01b0381168114620000da57600080fd5b50565b60008060408385031215620000f157600080fd5b8251620000fe81620000c4565b60208401519092506200011181620000c4565b809150509250929050565b6000602082840312156200012f57600080fd5b81516200013c81620000c4565b9392505050565b60805160a05160c0516144ee620001d5600039600081816101960152818161035a01528181610f4a0152818161106b0152818161282301528181612883015261294b01526000818161023b01528181610a870152818161214e0152818161220801526122bd01526000818161042d0152818161122501528181611c0e01528181612b500152612c8001526144ee6000f3fe6080604052600436106101795760003560e01c8063a4a78f0c116100cb578063c45a01551161007f578063df2ab5bb11610059578063df2ab5bb14610482578063f28c049814610495578063f3995c67146104a857600080fd5b8063c45a01551461041b578063cc1695c91461044f578063dc8fd1821461046257600080fd5b8063ac9650d8116100b0578063ac9650d8146103d5578063c04b8d59146103f5578063c2e3140a1461040857600080fd5b8063a4a78f0c146103af578063a5dcbcdf146103c257600080fd5b80633339aad11161012d5780634aa4a4fc116101075780634aa4a4fc1461034857806379b28ef31461037c578063923b8a2a1461038f57600080fd5b80633339aad1146103025780634659a4941461032257806349404b7c1461033557600080fd5b806326b3e1cc1161015e57806326b3e1cc1461028f57806327dbbf70146102b257806329ffb48c146102d357600080fd5b806309218e911461022957806312210e8a1461028757600080fd5b36610224573373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610222576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f74205745544839000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561023557600080fd5b5061025d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6102226104bb565b6102a261029d3660046133e6565b6104cd565b60405161027e9493929190613523565b6102c56102c0366004613552565b610660565b60405190815260200161027e565b3480156102df57600080fd5b506102f36102ee36600461356a565b6109e8565b60405161027e93929190613628565b34801561030e57600080fd5b5061022261031d366004613695565b610d03565b61022261033036600461371d565b610e5e565b610222610343366004613779565b610f19565b34801561035457600080fd5b5061025d7f000000000000000000000000000000000000000000000000000000000000000081565b6102a261038a3660046137a9565b6110eb565b34801561039b57600080fd5b506102226103aa366004613820565b611181565b6102226103bd36600461371d565b6113c4565b6102c56103d03660046138a0565b611496565b6103e86103e33660046138b3565b61178b565b60405161027e9190613963565b6102c5610403366004613b6c565b6118fd565b61022261041636600461371d565b611a80565b34801561042757600080fd5b5061025d7f000000000000000000000000000000000000000000000000000000000000000081565b6102a261045d366004613c10565b611b2a565b34801561046e57600080fd5b5061022261047d366004613820565b611bcf565b610222610490366004613c91565b611d0e565b6102c56104a3366004613cd3565b611e22565b6102226104b636600461371d565b611fa9565b47156104cb576104cb3347612026565b565b60008060006060848042111561053f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60008e73ffffffffffffffffffffffffffffffffffffffff16631865c57d6040518163ffffffff1660e01b8152600401608060405180830381865afa15801561058c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b09190613d3e565b6000015190508860030b8160030b121580156105d257508760030b8160030b13155b610638576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6163746976655469636b206e6f7420696e2072616e67650000000000000000006044820152606401610219565b6106468f8f8f8f8f8f61210a565b955095509550955050509950995099509995505050505050565b60008160800135804211156106d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60006106e36040850160208601613db2565b73ffffffffffffffffffffffffffffffffffffffff166107066020860186613db2565b73ffffffffffffffffffffffffffffffffffffffff1610905060006107316060860160408701613db2565b73ffffffffffffffffffffffffffffffffffffffff1663c51c9029600061075e6080890160608a01613db2565b73ffffffffffffffffffffffffffffffffffffffff161461078e576107896080880160608901613db2565b610790565b305b8760a00135856001600060405180606001604052808d60200160208101906107b89190613db2565b8e60400160208101906107cb9190613db2565b8f60000160208101906107de9190613db2565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606094851b8116602083015292841b83166034820152921b166048820152605c0160405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525060405160200161086a9190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b815260040161089a96959493929190613e23565b60408051808303816000875af11580156108b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dc9190613e7a565b909450905060a0850135811461094e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f52657175657374656420616d6f756e74206e6f7420617661696c61626c6500006044820152606401610219565b8460c001358411156109bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f546f6f206d7563682072657175657374656400000000000000000000000000006044820152606401610219565b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005550919050565b60008060608380421115610a58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b6040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018b90527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690636352211e90602401602060405180830381865afa158015610ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b079190613e9e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f50000000000000000000000000000000000000000000000000000000000000006044820152606401610219565b73ffffffffffffffffffffffffffffffffffffffff8b16610bba57309a505b6040517f57c8c7b000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d16906357c8c7b090610c12908e908e908e908e90600401613ebb565b6000604051808303816000875af1158015610c31573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c779190810190613f6c565b91955093509150868410801590610c8e5750858310155b610cf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f546f6f206c6974746c652072656d6f76656400000000000000000000000000006044820152606401610219565b50985098509895505050505050565b8080421115610d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60005b84811015610e55578673ffffffffffffffffffffffffffffffffffffffff1663c0c5d7fb878784818110610da757610da76140af565b9050602002016020810190610dbc91906140de565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526fffffffffffffffffffffffffffffffff909116600482015263ffffffff87166024820152604401600060405180830381600087803b158015610e2a57600080fd5b505af1158015610e3e573d6000803e3d6000fd5b505050508080610e4d9061412a565b915050610d71565b50505050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b600060405180830381600087803b158015610ef957600080fd5b505af1158015610f0d573d6000803e3d6000fd5b50505050505050505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fca9190614162565b905082811015611036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420574554483900000000000000000000000000006044820152606401610219565b80156110e6576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156110c457600080fd5b505af11580156110d8573d6000803e3d6000fd5b505050506110e68282612026565b505050565b60008060006060848042111561115d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b61116b8c8c8c8c8c8c61210a565b929f919e509c50909a5098505050505050505050565b6000841180156111915750600083115b6111f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e206f72204f757420416d6f756e74206973205a65726f00000000000000006044820152606401610219565b6040517f578eaca40000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063578eaca490602401602060405180830381865afa158015611281573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a5919061417b565b61130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d7573742063616c6c2066726f6d206120466163746f727920506f6f6c0000006044820152606401610219565b600061131982840184614198565b9050600080600061132d84600001516125eb565b919450925090503373ffffffffffffffffffffffffffffffffffffffff82161461135657600080fd5b8360400151156113aa57835161136b90612626565b1561138e57835161137b9061265e565b8452611388883386612693565b506113ba565b876000819055506113a5828560200151338b612821565b6113ba565b6113ba838560200151338b612821565b5050505050505050565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147a9190614162565b101561148e5761148e868686868686610e5e565b505050505050565b6000816080013580421115611507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60006115196040850160208601613db2565b73ffffffffffffffffffffffffffffffffffffffff1661153c6020860186613db2565b73ffffffffffffffffffffffffffffffffffffffff161090506115656060850160408601613db2565b73ffffffffffffffffffffffffffffffffffffffff1663c51c902960006115926080880160608901613db2565b73ffffffffffffffffffffffffffffffffffffffff16146115c2576115bd6080870160608801613db2565b6115c4565b305b8660a001358460008960e0013560405180606001604052808c60000160208101906115ef9190613db2565b8d60400160208101906116029190613db2565b8e60200160208101906116159190613db2565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606094851b8116602083015292841b83166034820152921b166048820152605c0160405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152506040516020016116a19190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b81526004016116d196959493929190613e23565b60408051808303816000875af11580156116ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117139190613e7a565b93505060c0840135831015611784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f546f6f206c6974746c65207265636569766564000000000000000000000000006044820152606401610219565b5050919050565b60608167ffffffffffffffff8111156117a6576117a66139e3565b6040519080825280602002602001820160405280156117d957816020015b60608152602001906001900390816117c45790505b50905060005b828110156118f657600080308686858181106117fd576117fd6140af565b905060200281019061180f9190614248565b60405161181d9291906142ad565b600060405180830381855af49150503d8060008114611858576040519150601f19603f3d011682016040523d82523d6000602084013e61185d565b606091505b5091509150816118c35760448151101561187657600080fd5b6004810190508080602001905181019061189091906142bd565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610219919061432b565b808484815181106118d6576118d66140af565b6020026020010181905250505080806118ee9061412a565b9150506117df565b5092915050565b600081604001518042111561196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b335b600061197f8560000151612626565b90506119df85606001518261199857866020015161199a565b305b600060405180606001604052806119b48b600001516129fb565b815273ffffffffffffffffffffffffffffffffffffffff881660208201526000604090910152612a18565b606086015280156119ff5784513092506119f89061265e565b8552611a0c565b8460600151935050611a12565b50611970565b8360800151831015611784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f546f6f206c6974746c65207265636569766564000000000000000000000000006044820152606401610219565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190614162565b101561148e5761148e868686868686611fa9565b600080600060608480421115611b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b6000611ba78d612b37565b9050611bb7818d8d8d8d8d61210a565b95509550955095505050975097509750979350505050565b6000611bdd8284018461433e565b6040517f578eaca40000000000000000000000000000000000000000000000000000000081523360048201529091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063578eaca490602401602060405180830381865afa158015611c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8e919061417b565b611c9757600080fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cd357600080fd5b8415611ced57611ced816000015182606001513388612821565b8315611d0757611d07816020015182606001513387612821565b5050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015611d7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9f9190614162565b905082811015611e0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e00000000000000000000000000006044820152606401610219565b8015611e1c57611e1c848383612d9b565b50505050565b6000816040013580421115611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b611f0b6060840135611eab6040860160208701613db2565b604080516060810190915280611ec18880614248565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252503360208201526001604090910152612693565b5060005491508260800135821115611f7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f546f6f206d7563682072657175657374656400000000000000000000000000006044820152606401610219565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055919050565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e401610edf565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161205d9190614399565b60006040518083038185875af1925050503d806000811461209a576040519150601f19603f3d011682016040523d82523d6000602084013e61209f565b606091505b50509050806110e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53544500000000000000000000000000000000000000000000000000000000006044820152606401610219565b6000806000606088600003612342576040517f48fd65fe000000000000000000000000000000000000000000000000000000008152336004820152600060248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906348fd65fe90604401602060405180830381865afa1580156121aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ce919061417b565b1561228f576040517f2f745c59000000000000000000000000000000000000000000000000000000008152336004820152600060248201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632f745c5990604401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122889190614162565b9850612342565b6040517f6a6278420000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690636a627842906024016020604051808303816000875af115801561231b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233f9190614162565b98505b889350600060405180608001604052808c73ffffffffffffffffffffffffffffffffffffffff16630fc63d106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561239d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c19190613e9e565b73ffffffffffffffffffffffffffffffffffffffff1681526020018c73ffffffffffffffffffffffffffffffffffffffff16635f64b55b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244b9190613e9e565b73ffffffffffffffffffffffffffffffffffffffff90811682528d811660208084018290523360409485015283518551841681830152908501518316818501528484015183166060808301919091528501519092166080808401919091528351808403909101815260a08301938490527f9d5f20bb00000000000000000000000000000000000000000000000000000000909352929350639d5f20bb916124fb918e918e918e919060a4016143b5565b6000604051808303816000875af115801561251a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526125609190810190613f6c565b919550935091508684108015906125775750858310155b6125dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f546f6f206c6974746c65206164646564000000000000000000000000000000006044820152606401610219565b509650965096509692505050565b600080806125f98482612f04565b9250612606846014612f04565b905061261d612616601480614475565b8590612f04565b91509193909250565b6000612633601480614475565b601461263f8180614475565b6126499190614475565b6126539190614475565b825110159050919050565b606061268d61266e601480614475565b612679601480614475565b84516126859190614488565b849190613008565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff83166126b4573092505b60008060006126c685600001516125eb565b92509250925060008373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1610905060008273ffffffffffffffffffffffffffffffffffffffff1663c51c9029898b85600160008d6040516020016127359190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b815260040161276596959493929190613e23565b60408051808303816000875af1158015612783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a79190613e7a565b9096509050888114612815576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f52657175657374656420616d6f756e74206e6f7420617661696c61626c6500006044820152606401610219565b50505050509392505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614801561287c5750804710155b156129c2577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156128e957600080fd5b505af11580156128fd573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015612998573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129bc919061417b565b50611e1c565b3073ffffffffffffffffffffffffffffffffffffffff8416036129ef576129ea848383612d9b565b611e1c565b611e1c848484846131f5565b606061268d60006014612a0e8180614475565b6126859190614475565b600073ffffffffffffffffffffffffffffffffffffffff8416612a39573093505b6000806000612a4b85600001516125eb565b92509250925060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161090508173ffffffffffffffffffffffffffffffffffffffff1663c51c9029898b8460008c8c604051602001612ab79190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b8152600401612ae796959493929190613e23565b60408051808303816000875af1158015612b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b299190613e7a565b9a9950505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663c697217a833560208501356040860135612b9160a0880160808901613db2565b612ba160c0890160a08a01613db2565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815260048101959095526024850193909352604484019190915273ffffffffffffffffffffffffffffffffffffffff908116606484015216608482015260a401602060405180830381865afa158015612c28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4c9190613e9e565b905073ffffffffffffffffffffffffffffffffffffffff8116612d965773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166371861ede833560208501356040860135612cc1608088016060890161449b565b612cd160a0890160808a01613db2565b612ce160c08a0160a08b01613db2565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b16815260048101969096526024860194909452604485019290925260030b606484015273ffffffffffffffffffffffffffffffffffffffff90811660848401521660a482015260c4016020604051808303816000875af1158015612d72573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268d9190613e9e565b919050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691612e329190614399565b6000604051808303816000865af19150503d8060008114612e6f576040519150601f19603f3d011682016040523d82523d6000602084013e612e74565b606091505b5091509150818015612e9e575080511580612e9e575080806020019051810190612e9e919061417b565b611d07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f53540000000000000000000000000000000000000000000000000000000000006044820152606401610219565b600081612f12816014614475565b1015612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f7700000000000000000000000000006044820152606401610219565b612f85826014614475565b83511015612fef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e647300000000000000000000006044820152606401610219565b5001602001516c01000000000000000000000000900490565b60608161301681601f614475565b101561307e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610219565b826130898382614475565b10156130f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610219565b6130fb8284614475565b84511015613165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610219565b60608215801561318457604051915060008252602082016040526131ec565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156131bd5780518352602092830192016131a5565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916132949190614399565b6000604051808303816000865af19150503d80600081146132d1576040519150601f19603f3d011682016040523d82523d6000602084013e6132d6565b606091505b5091509150818015613300575080511580613300575080806020019051810190613300919061417b565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53544600000000000000000000000000000000000000000000000000000000006044820152606401610219565b73ffffffffffffffffffffffffffffffffffffffff8116811461338857600080fd5b50565b60008083601f84011261339d57600080fd5b50813567ffffffffffffffff8111156133b557600080fd5b60208301915083602060a0830285010111156133d057600080fd5b9250929050565b8060030b811461338857600080fd5b60008060008060008060008060006101008a8c03121561340557600080fd5b893561341081613366565b985060208a0135975060408a013567ffffffffffffffff81111561343357600080fd5b61343f8c828d0161338b565b90985096505060608a0135945060808a0135935060a08a0135613461816133d7565b925060c08a0135613471816133d7565b8092505060e08a013590509295985092959850929598565b600081518084526020808501945080840160005b8381101561351857815180516fffffffffffffffffffffffffffffffff9081168952848201518116858a0152604080830151908a01526060808301519091169089015260808082015160ff169089015260a08082015160030b9089015260c09081015115159088015260e0909601959082019060010161349d565b509495945050505050565b8481528360208201528260408201526080606082015260006135486080830184613489565b9695505050505050565b600060e0828403121561356457600080fd5b50919050565b60008060008060008060008060e0898b03121561358657600080fd5b883561359181613366565b975060208901356135a181613366565b965060408901359550606089013567ffffffffffffffff808211156135c557600080fd5b818b0191508b601f8301126135d957600080fd5b8135818111156135e857600080fd5b8c60208260061b85010111156135fd57600080fd5b999c989b50969960209190910198976080820135975060a0820135965060c090910135945092505050565b8381528260208201526060604082015260006136476060830184613489565b95945050505050565b60008083601f84011261366257600080fd5b50813567ffffffffffffffff81111561367a57600080fd5b6020830191508360208260051b85010111156133d057600080fd5b6000806000806000608086880312156136ad57600080fd5b85356136b881613366565b9450602086013567ffffffffffffffff8111156136d457600080fd5b6136e088828901613650565b909550935050604086013563ffffffff811681146136fd57600080fd5b949793965091946060013592915050565b60ff8116811461338857600080fd5b60008060008060008060c0878903121561373657600080fd5b863561374181613366565b95506020870135945060408701359350606087013561375f8161370e565b9598949750929560808101359460a0909101359350915050565b6000806040838503121561378c57600080fd5b82359150602083013561379e81613366565b809150509250929050565b600080600080600080600060c0888a0312156137c457600080fd5b87356137cf81613366565b965060208801359550604088013567ffffffffffffffff8111156137f257600080fd5b6137fe8a828b0161338b565b989b979a50986060810135976080820135975060a09091013595509350505050565b6000806000806060858703121561383657600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561385c57600080fd5b818701915087601f83011261387057600080fd5b81358181111561387f57600080fd5b88602082850101111561389157600080fd5b95989497505060200194505050565b6000610100828403121561356457600080fd5b600080602083850312156138c657600080fd5b823567ffffffffffffffff8111156138dd57600080fd5b6138e985828601613650565b90969095509350505050565b60005b838110156139105781810151838201526020016138f8565b50506000910152565b600081518084526139318160208601602086016138f5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156139d6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526139c4858351613919565b9450928501929085019060010161398a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613a3557613a356139e3565b60405290565b6040516080810167ffffffffffffffff81118282101715613a3557613a356139e3565b60405160e0810167ffffffffffffffff81118282101715613a3557613a356139e3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ac857613ac86139e3565b604052919050565b600067ffffffffffffffff821115613aea57613aea6139e3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613b2757600080fd5b8135613b3a613b3582613ad0565b613a81565b818152846020838601011115613b4f57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613b7e57600080fd5b813567ffffffffffffffff80821115613b9657600080fd5b9083019060a08286031215613baa57600080fd5b613bb2613a12565b823582811115613bc157600080fd5b613bcd87828601613b16565b82525060208301359150613be082613366565b81602082015260408301356040820152606083013560608201526080830135608082015280935050505092915050565b6000806000806000806000878903610160811215613c2d57600080fd5b60c0811215613c3b57600080fd5b5087965060c0880135955060e088013567ffffffffffffffff811115613c6057600080fd5b613c6c8a828b0161338b565b989b979a50986101008101359761012082013597506101409091013595509350505050565b600080600060608486031215613ca657600080fd5b8335613cb181613366565b9250602084013591506040840135613cc881613366565b809150509250925092565b600060208284031215613ce557600080fd5b813567ffffffffffffffff811115613cfc57600080fd5b820160a08185031215613d0e57600080fd5b9392505050565b8051612d96816133d7565b6fffffffffffffffffffffffffffffffff8116811461338857600080fd5b600060808284031215613d5057600080fd5b613d58613a3b565b8251613d63816133d7565b81526020830151613d738161370e565b60208201526040830151613d8681613d20565b6040820152606083015167ffffffffffffffff81168114613da657600080fd5b60608201529392505050565b600060208284031215613dc457600080fd5b8135613d0e81613366565b602081526000825160606020840152613deb6080840182613919565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151151560608401528091505092915050565b73ffffffffffffffffffffffffffffffffffffffff871681528560208201528415156040820152831515606082015282608082015260c060a08201526000613e6e60c0830184613919565b98975050505050505050565b60008060408385031215613e8d57600080fd5b505080516020909101519092909150565b600060208284031215613eb057600080fd5b8151613d0e81613366565b60006060820173ffffffffffffffffffffffffffffffffffffffff871683526020868185015260406060818601528286845260808601905087935060005b87811015613f45578435613f0c81613d20565b6fffffffffffffffffffffffffffffffff90811683528585013590613f3082613d20565b16828501529382019390820190600101613ef9565b509998505050505050505050565b801515811461338857600080fd5b8051612d9681613f53565b60008060006060808587031215613f8257600080fd5b84519350602080860151935060408087015167ffffffffffffffff80821115613faa57600080fd5b818901915089601f830112613fbe57600080fd5b815181811115613fd057613fd06139e3565b613fde858260051b01613a81565b818152858101925060e091820284018601918c831115613ffd57600080fd5b938601935b8285101561409d5780858e03121561401a5760008081fd5b614022613a5e565b855161402d81613d20565b81528588015161403c81613d20565b8189015285870151878201528886015161405581613d20565b818a01526080868101516140688161370e565b9082015260a0614079878201613d15565b9082015260c061408a878201613f61565b9082015284529384019392860192614002565b50809750505050505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156140f057600080fd5b8135613d0e81613d20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361415b5761415b6140fb565b5060010190565b60006020828403121561417457600080fd5b5051919050565b60006020828403121561418d57600080fd5b8151613d0e81613f53565b6000602082840312156141aa57600080fd5b813567ffffffffffffffff808211156141c257600080fd5b90830190606082860312156141d657600080fd5b6040516060810181811083821117156141f1576141f16139e3565b60405282358281111561420357600080fd5b61420f87828601613b16565b8252506020830135915061422282613366565b8160208201526040830135925061423883613f53565b6040810192909252509392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261427d57600080fd5b83018035915067ffffffffffffffff82111561429857600080fd5b6020019150368190038213156133d057600080fd5b8183823760009101908152919050565b6000602082840312156142cf57600080fd5b815167ffffffffffffffff8111156142e657600080fd5b8201601f810184136142f757600080fd5b8051614305613b3582613ad0565b81815285602083850101111561431a57600080fd5b6136478260208301602086016138f5565b602081526000613d0e6020830184613919565b60006080828403121561435057600080fd5b614358613a3b565b823561436381613366565b8152602083013561437381613366565b6020820152604083013561438681613366565b60408201526060830135613da681613366565b600082516143ab8184602087016138f5565b9190910192915050565b848152606060208083018290528282018590526000919060809081850188855b898110156144615781356143e88161370e565b60ff168352818401356143fa816133d7565b60030b8385015260408281013561441081613f53565b1515908401528186013561442381613d20565b6fffffffffffffffffffffffffffffffff90811684880152828601359061444982613d20565b168386015260a09283019291909101906001016143d5565b50508581036040870152612b298188613919565b8082018082111561268d5761268d6140fb565b8181038181111561268d5761268d6140fb565b6000602082840312156144ad57600080fd5b8135613d0e816133d756fea2646970667358221220b8014cef1c16d677a941a1f5dcbdb3c48ff496222bea57353bdc03ce08e2ea7b64736f6c63430008110033000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed Bytecode

0x6080604052600436106101795760003560e01c8063a4a78f0c116100cb578063c45a01551161007f578063df2ab5bb11610059578063df2ab5bb14610482578063f28c049814610495578063f3995c67146104a857600080fd5b8063c45a01551461041b578063cc1695c91461044f578063dc8fd1821461046257600080fd5b8063ac9650d8116100b0578063ac9650d8146103d5578063c04b8d59146103f5578063c2e3140a1461040857600080fd5b8063a4a78f0c146103af578063a5dcbcdf146103c257600080fd5b80633339aad11161012d5780634aa4a4fc116101075780634aa4a4fc1461034857806379b28ef31461037c578063923b8a2a1461038f57600080fd5b80633339aad1146103025780634659a4941461032257806349404b7c1461033557600080fd5b806326b3e1cc1161015e57806326b3e1cc1461028f57806327dbbf70146102b257806329ffb48c146102d357600080fd5b806309218e911461022957806312210e8a1461028757600080fd5b36610224573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21614610222576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f74205745544839000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b005b600080fd5b34801561023557600080fd5b5061025d7f0000000000000000000000004a3e49f77a2a5b60682a2d6b8899c7c5211eb64681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6102226104bb565b6102a261029d3660046133e6565b6104cd565b60405161027e9493929190613523565b6102c56102c0366004613552565b610660565b60405190815260200161027e565b3480156102df57600080fd5b506102f36102ee36600461356a565b6109e8565b60405161027e93929190613628565b34801561030e57600080fd5b5061022261031d366004613695565b610d03565b61022261033036600461371d565b610e5e565b610222610343366004613779565b610f19565b34801561035457600080fd5b5061025d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6102a261038a3660046137a9565b6110eb565b34801561039b57600080fd5b506102226103aa366004613820565b611181565b6102226103bd36600461371d565b6113c4565b6102c56103d03660046138a0565b611496565b6103e86103e33660046138b3565b61178b565b60405161027e9190613963565b6102c5610403366004613b6c565b6118fd565b61022261041636600461371d565b611a80565b34801561042757600080fd5b5061025d7f000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b81565b6102a261045d366004613c10565b611b2a565b34801561046e57600080fd5b5061022261047d366004613820565b611bcf565b610222610490366004613c91565b611d0e565b6102c56104a3366004613cd3565b611e22565b6102226104b636600461371d565b611fa9565b47156104cb576104cb3347612026565b565b60008060006060848042111561053f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60008e73ffffffffffffffffffffffffffffffffffffffff16631865c57d6040518163ffffffff1660e01b8152600401608060405180830381865afa15801561058c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b09190613d3e565b6000015190508860030b8160030b121580156105d257508760030b8160030b13155b610638576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6163746976655469636b206e6f7420696e2072616e67650000000000000000006044820152606401610219565b6106468f8f8f8f8f8f61210a565b955095509550955050509950995099509995505050505050565b60008160800135804211156106d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60006106e36040850160208601613db2565b73ffffffffffffffffffffffffffffffffffffffff166107066020860186613db2565b73ffffffffffffffffffffffffffffffffffffffff1610905060006107316060860160408701613db2565b73ffffffffffffffffffffffffffffffffffffffff1663c51c9029600061075e6080890160608a01613db2565b73ffffffffffffffffffffffffffffffffffffffff161461078e576107896080880160608901613db2565b610790565b305b8760a00135856001600060405180606001604052808d60200160208101906107b89190613db2565b8e60400160208101906107cb9190613db2565b8f60000160208101906107de9190613db2565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606094851b8116602083015292841b83166034820152921b166048820152605c0160405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525060405160200161086a9190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b815260040161089a96959493929190613e23565b60408051808303816000875af11580156108b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dc9190613e7a565b909450905060a0850135811461094e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f52657175657374656420616d6f756e74206e6f7420617661696c61626c6500006044820152606401610219565b8460c001358411156109bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f546f6f206d7563682072657175657374656400000000000000000000000000006044820152606401610219565b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60005550919050565b60008060608380421115610a58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b6040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018b90527f0000000000000000000000004a3e49f77a2a5b60682a2d6b8899c7c5211eb64673ffffffffffffffffffffffffffffffffffffffff1690636352211e90602401602060405180830381865afa158015610ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b079190613e9e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f50000000000000000000000000000000000000000000000000000000000000006044820152606401610219565b73ffffffffffffffffffffffffffffffffffffffff8b16610bba57309a505b6040517f57c8c7b000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d16906357c8c7b090610c12908e908e908e908e90600401613ebb565b6000604051808303816000875af1158015610c31573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c779190810190613f6c565b91955093509150868410801590610c8e5750858310155b610cf4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f546f6f206c6974746c652072656d6f76656400000000000000000000000000006044820152606401610219565b50985098509895505050505050565b8080421115610d6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60005b84811015610e55578673ffffffffffffffffffffffffffffffffffffffff1663c0c5d7fb878784818110610da757610da76140af565b9050602002016020810190610dbc91906140de565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526fffffffffffffffffffffffffffffffff909116600482015263ffffffff87166024820152604401600060405180830381600087803b158015610e2a57600080fd5b505af1158015610e3e573d6000803e3d6000fd5b505050508080610e4d9061412a565b915050610d71565b50505050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b600060405180830381600087803b158015610ef957600080fd5b505af1158015610f0d573d6000803e3d6000fd5b50505050505050505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fca9190614162565b905082811015611036576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420574554483900000000000000000000000000006044820152606401610219565b80156110e6576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156110c457600080fd5b505af11580156110d8573d6000803e3d6000fd5b505050506110e68282612026565b505050565b60008060006060848042111561115d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b61116b8c8c8c8c8c8c61210a565b929f919e509c50909a5098505050505050505050565b6000841180156111915750600083115b6111f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e206f72204f757420416d6f756e74206973205a65726f00000000000000006044820152606401610219565b6040517f578eaca40000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b73ffffffffffffffffffffffffffffffffffffffff169063578eaca490602401602060405180830381865afa158015611281573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a5919061417b565b61130b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d7573742063616c6c2066726f6d206120466163746f727920506f6f6c0000006044820152606401610219565b600061131982840184614198565b9050600080600061132d84600001516125eb565b919450925090503373ffffffffffffffffffffffffffffffffffffffff82161461135657600080fd5b8360400151156113aa57835161136b90612626565b1561138e57835161137b9061265e565b8452611388883386612693565b506113ba565b876000819055506113a5828560200151338b612821565b6113ba565b6113ba838560200151338b612821565b5050505050505050565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611456573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147a9190614162565b101561148e5761148e868686868686610e5e565b505050505050565b6000816080013580421115611507576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b60006115196040850160208601613db2565b73ffffffffffffffffffffffffffffffffffffffff1661153c6020860186613db2565b73ffffffffffffffffffffffffffffffffffffffff161090506115656060850160408601613db2565b73ffffffffffffffffffffffffffffffffffffffff1663c51c902960006115926080880160608901613db2565b73ffffffffffffffffffffffffffffffffffffffff16146115c2576115bd6080870160608801613db2565b6115c4565b305b8660a001358460008960e0013560405180606001604052808c60000160208101906115ef9190613db2565b8d60400160208101906116029190613db2565b8e60200160208101906116159190613db2565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606094851b8116602083015292841b83166034820152921b166048820152605c0160405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff168152602001600015158152506040516020016116a19190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b81526004016116d196959493929190613e23565b60408051808303816000875af11580156116ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117139190613e7a565b93505060c0840135831015611784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f546f6f206c6974746c65207265636569766564000000000000000000000000006044820152606401610219565b5050919050565b60608167ffffffffffffffff8111156117a6576117a66139e3565b6040519080825280602002602001820160405280156117d957816020015b60608152602001906001900390816117c45790505b50905060005b828110156118f657600080308686858181106117fd576117fd6140af565b905060200281019061180f9190614248565b60405161181d9291906142ad565b600060405180830381855af49150503d8060008114611858576040519150601f19603f3d011682016040523d82523d6000602084013e61185d565b606091505b5091509150816118c35760448151101561187657600080fd5b6004810190508080602001905181019061189091906142bd565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610219919061432b565b808484815181106118d6576118d66140af565b6020026020010181905250505080806118ee9061412a565b9150506117df565b5092915050565b600081604001518042111561196e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b335b600061197f8560000151612626565b90506119df85606001518261199857866020015161199a565b305b600060405180606001604052806119b48b600001516129fb565b815273ffffffffffffffffffffffffffffffffffffffff881660208201526000604090910152612a18565b606086015280156119ff5784513092506119f89061265e565b8552611a0c565b8460600151935050611a12565b50611970565b8360800151831015611784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f546f6f206c6974746c65207265636569766564000000000000000000000000006044820152606401610219565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e90604401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190614162565b101561148e5761148e868686868686611fa9565b600080600060608480421115611b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b6000611ba78d612b37565b9050611bb7818d8d8d8d8d61210a565b95509550955095505050975097509750979350505050565b6000611bdd8284018461433e565b6040517f578eaca40000000000000000000000000000000000000000000000000000000081523360048201529091507f000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b73ffffffffffffffffffffffffffffffffffffffff169063578eaca490602401602060405180830381865afa158015611c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8e919061417b565b611c9757600080fd5b806040015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cd357600080fd5b8415611ced57611ced816000015182606001513388612821565b8315611d0757611d07816020015182606001513387612821565b5050505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015611d7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9f9190614162565b905082811015611e0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e00000000000000000000000000006044820152606401610219565b8015611e1c57611e1c848383612d9b565b50505050565b6000816040013580421115611e93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c64000000000000000000000000006044820152606401610219565b611f0b6060840135611eab6040860160208701613db2565b604080516060810190915280611ec18880614248565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050908252503360208201526001604090910152612693565b5060005491508260800135821115611f7f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f546f6f206d7563682072657175657374656400000000000000000000000000006044820152606401610219565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055919050565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e401610edf565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff841690839060405161205d9190614399565b60006040518083038185875af1925050503d806000811461209a576040519150601f19603f3d011682016040523d82523d6000602084013e61209f565b606091505b50509050806110e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53544500000000000000000000000000000000000000000000000000000000006044820152606401610219565b6000806000606088600003612342576040517f48fd65fe000000000000000000000000000000000000000000000000000000008152336004820152600060248201527f0000000000000000000000004a3e49f77a2a5b60682a2d6b8899c7c5211eb64673ffffffffffffffffffffffffffffffffffffffff16906348fd65fe90604401602060405180830381865afa1580156121aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ce919061417b565b1561228f576040517f2f745c59000000000000000000000000000000000000000000000000000000008152336004820152600060248201527f0000000000000000000000004a3e49f77a2a5b60682a2d6b8899c7c5211eb64673ffffffffffffffffffffffffffffffffffffffff1690632f745c5990604401602060405180830381865afa158015612264573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122889190614162565b9850612342565b6040517f6a6278420000000000000000000000000000000000000000000000000000000081523360048201527f0000000000000000000000004a3e49f77a2a5b60682a2d6b8899c7c5211eb64673ffffffffffffffffffffffffffffffffffffffff1690636a627842906024016020604051808303816000875af115801561231b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233f9190614162565b98505b889350600060405180608001604052808c73ffffffffffffffffffffffffffffffffffffffff16630fc63d106040518163ffffffff1660e01b8152600401602060405180830381865afa15801561239d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c19190613e9e565b73ffffffffffffffffffffffffffffffffffffffff1681526020018c73ffffffffffffffffffffffffffffffffffffffff16635f64b55b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612427573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061244b9190613e9e565b73ffffffffffffffffffffffffffffffffffffffff90811682528d811660208084018290523360409485015283518551841681830152908501518316818501528484015183166060808301919091528501519092166080808401919091528351808403909101815260a08301938490527f9d5f20bb00000000000000000000000000000000000000000000000000000000909352929350639d5f20bb916124fb918e918e918e919060a4016143b5565b6000604051808303816000875af115801561251a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526125609190810190613f6c565b919550935091508684108015906125775750858310155b6125dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f546f6f206c6974746c65206164646564000000000000000000000000000000006044820152606401610219565b509650965096509692505050565b600080806125f98482612f04565b9250612606846014612f04565b905061261d612616601480614475565b8590612f04565b91509193909250565b6000612633601480614475565b601461263f8180614475565b6126499190614475565b6126539190614475565b825110159050919050565b606061268d61266e601480614475565b612679601480614475565b84516126859190614488565b849190613008565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff83166126b4573092505b60008060006126c685600001516125eb565b92509250925060008373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1610905060008273ffffffffffffffffffffffffffffffffffffffff1663c51c9029898b85600160008d6040516020016127359190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b815260040161276596959493929190613e23565b60408051808303816000875af1158015612783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a79190613e7a565b9096509050888114612815576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f52657175657374656420616d6f756e74206e6f7420617661696c61626c6500006044820152606401610219565b50505050509392505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614801561287c5750804710155b156129c2577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156128e957600080fd5b505af11580156128fd573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216935063a9059cbb925060440190506020604051808303816000875af1158015612998573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129bc919061417b565b50611e1c565b3073ffffffffffffffffffffffffffffffffffffffff8416036129ef576129ea848383612d9b565b611e1c565b611e1c848484846131f5565b606061268d60006014612a0e8180614475565b6126859190614475565b600073ffffffffffffffffffffffffffffffffffffffff8416612a39573093505b6000806000612a4b85600001516125eb565b92509250925060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161090508173ffffffffffffffffffffffffffffffffffffffff1663c51c9029898b8460008c8c604051602001612ab79190613dcf565b6040516020818303038152906040526040518763ffffffff1660e01b8152600401612ae796959493929190613e23565b60408051808303816000875af1158015612b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b299190613e7a565b9a9950505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b1663c697217a833560208501356040860135612b9160a0880160808901613db2565b612ba160c0890160a08a01613db2565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b16815260048101959095526024850193909352604484019190915273ffffffffffffffffffffffffffffffffffffffff908116606484015216608482015260a401602060405180830381865afa158015612c28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c4c9190613e9e565b905073ffffffffffffffffffffffffffffffffffffffff8116612d965773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b166371861ede833560208501356040860135612cc1608088016060890161449b565b612cd160a0890160808a01613db2565b612ce160c08a0160a08b01613db2565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e089901b16815260048101969096526024860194909452604485019290925260030b606484015273ffffffffffffffffffffffffffffffffffffffff90811660848401521660a482015260c4016020604051808303816000875af1158015612d72573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268d9190613e9e565b919050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790529151600092839290871691612e329190614399565b6000604051808303816000865af19150503d8060008114612e6f576040519150601f19603f3d011682016040523d82523d6000602084013e612e74565b606091505b5091509150818015612e9e575080511580612e9e575080806020019051810190612e9e919061417b565b611d07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f53540000000000000000000000000000000000000000000000000000000000006044820152606401610219565b600081612f12816014614475565b1015612f7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f7700000000000000000000000000006044820152606401610219565b612f85826014614475565b83511015612fef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e647300000000000000000000006044820152606401610219565b5001602001516c01000000000000000000000000900490565b60608161301681601f614475565b101561307e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610219565b826130898382614475565b10156130f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610219565b6130fb8284614475565b84511015613165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610219565b60608215801561318457604051915060008252602082016040526131ec565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156131bd5780518352602092830192016131a5565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291516000928392908816916132949190614399565b6000604051808303816000865af19150503d80600081146132d1576040519150601f19603f3d011682016040523d82523d6000602084013e6132d6565b606091505b5091509150818015613300575080511580613300575080806020019051810190613300919061417b565b61148e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f53544600000000000000000000000000000000000000000000000000000000006044820152606401610219565b73ffffffffffffffffffffffffffffffffffffffff8116811461338857600080fd5b50565b60008083601f84011261339d57600080fd5b50813567ffffffffffffffff8111156133b557600080fd5b60208301915083602060a0830285010111156133d057600080fd5b9250929050565b8060030b811461338857600080fd5b60008060008060008060008060006101008a8c03121561340557600080fd5b893561341081613366565b985060208a0135975060408a013567ffffffffffffffff81111561343357600080fd5b61343f8c828d0161338b565b90985096505060608a0135945060808a0135935060a08a0135613461816133d7565b925060c08a0135613471816133d7565b8092505060e08a013590509295985092959850929598565b600081518084526020808501945080840160005b8381101561351857815180516fffffffffffffffffffffffffffffffff9081168952848201518116858a0152604080830151908a01526060808301519091169089015260808082015160ff169089015260a08082015160030b9089015260c09081015115159088015260e0909601959082019060010161349d565b509495945050505050565b8481528360208201528260408201526080606082015260006135486080830184613489565b9695505050505050565b600060e0828403121561356457600080fd5b50919050565b60008060008060008060008060e0898b03121561358657600080fd5b883561359181613366565b975060208901356135a181613366565b965060408901359550606089013567ffffffffffffffff808211156135c557600080fd5b818b0191508b601f8301126135d957600080fd5b8135818111156135e857600080fd5b8c60208260061b85010111156135fd57600080fd5b999c989b50969960209190910198976080820135975060a0820135965060c090910135945092505050565b8381528260208201526060604082015260006136476060830184613489565b95945050505050565b60008083601f84011261366257600080fd5b50813567ffffffffffffffff81111561367a57600080fd5b6020830191508360208260051b85010111156133d057600080fd5b6000806000806000608086880312156136ad57600080fd5b85356136b881613366565b9450602086013567ffffffffffffffff8111156136d457600080fd5b6136e088828901613650565b909550935050604086013563ffffffff811681146136fd57600080fd5b949793965091946060013592915050565b60ff8116811461338857600080fd5b60008060008060008060c0878903121561373657600080fd5b863561374181613366565b95506020870135945060408701359350606087013561375f8161370e565b9598949750929560808101359460a0909101359350915050565b6000806040838503121561378c57600080fd5b82359150602083013561379e81613366565b809150509250929050565b600080600080600080600060c0888a0312156137c457600080fd5b87356137cf81613366565b965060208801359550604088013567ffffffffffffffff8111156137f257600080fd5b6137fe8a828b0161338b565b989b979a50986060810135976080820135975060a09091013595509350505050565b6000806000806060858703121561383657600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561385c57600080fd5b818701915087601f83011261387057600080fd5b81358181111561387f57600080fd5b88602082850101111561389157600080fd5b95989497505060200194505050565b6000610100828403121561356457600080fd5b600080602083850312156138c657600080fd5b823567ffffffffffffffff8111156138dd57600080fd5b6138e985828601613650565b90969095509350505050565b60005b838110156139105781810151838201526020016138f8565b50506000910152565b600081518084526139318160208601602086016138f5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156139d6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526139c4858351613919565b9450928501929085019060010161398a565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613a3557613a356139e3565b60405290565b6040516080810167ffffffffffffffff81118282101715613a3557613a356139e3565b60405160e0810167ffffffffffffffff81118282101715613a3557613a356139e3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613ac857613ac86139e3565b604052919050565b600067ffffffffffffffff821115613aea57613aea6139e3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613b2757600080fd5b8135613b3a613b3582613ad0565b613a81565b818152846020838601011115613b4f57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613b7e57600080fd5b813567ffffffffffffffff80821115613b9657600080fd5b9083019060a08286031215613baa57600080fd5b613bb2613a12565b823582811115613bc157600080fd5b613bcd87828601613b16565b82525060208301359150613be082613366565b81602082015260408301356040820152606083013560608201526080830135608082015280935050505092915050565b6000806000806000806000878903610160811215613c2d57600080fd5b60c0811215613c3b57600080fd5b5087965060c0880135955060e088013567ffffffffffffffff811115613c6057600080fd5b613c6c8a828b0161338b565b989b979a50986101008101359761012082013597506101409091013595509350505050565b600080600060608486031215613ca657600080fd5b8335613cb181613366565b9250602084013591506040840135613cc881613366565b809150509250925092565b600060208284031215613ce557600080fd5b813567ffffffffffffffff811115613cfc57600080fd5b820160a08185031215613d0e57600080fd5b9392505050565b8051612d96816133d7565b6fffffffffffffffffffffffffffffffff8116811461338857600080fd5b600060808284031215613d5057600080fd5b613d58613a3b565b8251613d63816133d7565b81526020830151613d738161370e565b60208201526040830151613d8681613d20565b6040820152606083015167ffffffffffffffff81168114613da657600080fd5b60608201529392505050565b600060208284031215613dc457600080fd5b8135613d0e81613366565b602081526000825160606020840152613deb6080840182613919565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151151560608401528091505092915050565b73ffffffffffffffffffffffffffffffffffffffff871681528560208201528415156040820152831515606082015282608082015260c060a08201526000613e6e60c0830184613919565b98975050505050505050565b60008060408385031215613e8d57600080fd5b505080516020909101519092909150565b600060208284031215613eb057600080fd5b8151613d0e81613366565b60006060820173ffffffffffffffffffffffffffffffffffffffff871683526020868185015260406060818601528286845260808601905087935060005b87811015613f45578435613f0c81613d20565b6fffffffffffffffffffffffffffffffff90811683528585013590613f3082613d20565b16828501529382019390820190600101613ef9565b509998505050505050505050565b801515811461338857600080fd5b8051612d9681613f53565b60008060006060808587031215613f8257600080fd5b84519350602080860151935060408087015167ffffffffffffffff80821115613faa57600080fd5b818901915089601f830112613fbe57600080fd5b815181811115613fd057613fd06139e3565b613fde858260051b01613a81565b818152858101925060e091820284018601918c831115613ffd57600080fd5b938601935b8285101561409d5780858e03121561401a5760008081fd5b614022613a5e565b855161402d81613d20565b81528588015161403c81613d20565b8189015285870151878201528886015161405581613d20565b818a01526080868101516140688161370e565b9082015260a0614079878201613d15565b9082015260c061408a878201613f61565b9082015284529384019392860192614002565b50809750505050505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156140f057600080fd5b8135613d0e81613d20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361415b5761415b6140fb565b5060010190565b60006020828403121561417457600080fd5b5051919050565b60006020828403121561418d57600080fd5b8151613d0e81613f53565b6000602082840312156141aa57600080fd5b813567ffffffffffffffff808211156141c257600080fd5b90830190606082860312156141d657600080fd5b6040516060810181811083821117156141f1576141f16139e3565b60405282358281111561420357600080fd5b61420f87828601613b16565b8252506020830135915061422282613366565b8160208201526040830135925061423883613f53565b6040810192909252509392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261427d57600080fd5b83018035915067ffffffffffffffff82111561429857600080fd5b6020019150368190038213156133d057600080fd5b8183823760009101908152919050565b6000602082840312156142cf57600080fd5b815167ffffffffffffffff8111156142e657600080fd5b8201601f810184136142f757600080fd5b8051614305613b3582613ad0565b81815285602083850101111561431a57600080fd5b6136478260208301602086016138f5565b602081526000613d0e6020830184613919565b60006080828403121561435057600080fd5b614358613a3b565b823561436381613366565b8152602083013561437381613366565b6020820152604083013561438681613366565b60408201526060830135613da681613366565b600082516143ab8184602087016138f5565b9190910192915050565b848152606060208083018290528282018590526000919060809081850188855b898110156144615781356143e88161370e565b60ff168352818401356143fa816133d7565b60030b8385015260408281013561441081613f53565b1515908401528186013561442381613d20565b6fffffffffffffffffffffffffffffffff90811684880152828601359061444982613d20565b168386015260a09283019291909101906001016143d5565b50508581036040870152612b298188613919565b8082018082111561268d5761268d6140fb565b8181038181111561268d5761268d6140fb565b6000602082840312156144ad57600080fd5b8135613d0e816133d756fea2646970667358221220b8014cef1c16d677a941a1f5dcbdb3c48ff496222bea57353bdc03ce08e2ea7b64736f6c63430008110033

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

000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

-----Decoded View---------------
Arg [0] : _factory (address): 0xEb6625D65a0553c9dBc64449e56abFe519bd9c9B
Arg [1] : _WETH9 (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000eb6625d65a0553c9dbc64449e56abfe519bd9c9b
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2


Deployed Bytecode Sourcemap

578:14337:10:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1731:10;1724:27;1746:5;1724:27;;1716:49;;;;;;;216:2:23;1716:49:10;;;198:21:23;255:1;235:18;;;228:29;293:11;273:18;;;266:39;322:18;;1716:49:10;;;;;;;;;578:14337;;;;;1419:35;;;;;;;;;;;;;;;;;;544:42:23;532:55;;;514:74;;502:2;487:18;1419:35:10;;;;;;;;2623:172;;;:::i;11563:823::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;7638:976::-;;;;;;:::i;:::-;;:::i;:::-;;;4597:25:23;;;4585:2;4570:18;7638:976:10;4451:177:23;14137:776:10;;;;;;;;;;-1:-1:-1;14137:776:10;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;13794:309::-;;;;;;;;;;-1:-1:-1;13794:309:10;;;;;:::i;:::-;;:::i;1359:289:21:-;;;;;;:::i;:::-;;:::i;1810:381:10:-;;;;;;:::i;:::-;;:::i;1492:29::-;;;;;;;;;;;;;;;10964:565;;;;;;:::i;:::-;;:::i;3487:921::-;;;;;;;;;;-1:-1:-1;3487:921:10;;;;;:::i;:::-;;:::i;1686:348:21:-;;;;;;:::i;:::-;;:::i;5043:811:10:-;;;;;;:::i;:::-;;:::i;308:667:19:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5888:983:10:-;;;;;;:::i;:::-;;:::i;995:326:21:-;;;;;;:::i;:::-;;:::i;1352:33:10:-;;;;;;;;;;;;;;;13107:653;;;;;;:::i;:::-;;:::i;9182:508::-;;;;;;;;;;-1:-1:-1;9182:508:10;;;;;:::i;:::-;;:::i;2229:356::-;;;;;;:::i;:::-;;:::i;8648:511::-;;;;;;:::i;:::-;;:::i;684:273:21:-;;;;;;:::i;:::-;;:::i;2623:172:10:-;2684:21;:25;2680:108;;2723:65;2754:10;2766:21;2723:30;:65::i;:::-;2623:172::o;11563:823::-;11944:24;11982:20;12016;12050:33;11904:8;181::18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;12108:16:10::1;12127:4;:13;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:26;;;12108:45;;12199:13;12185:27;;:10;:27;;;;:58;;;;;12230:13;12216:27;;:10;:27;;;;12185:58;12164:128;;;::::0;::::1;::::0;;19347:2:23;12164:128:10::1;::::0;::::1;19329:21:23::0;19386:2;19366:18;;;19359:30;19425:25;19405:18;;;19398:53;19468:18;;12164:128:10::1;19145:347:23::0;12164:128:10::1;12310:69;12323:4;12329:7;12338:6;;12346:15;12363;12310:12;:69::i;:::-;12303:76;;;;;;;;;11563:823:::0;;;;;;;;;;;;;;;:::o;7638:976::-;7786:16;7760:6;:15;;;181:8:18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;7814:13:10::1;7847:15;::::0;;;::::1;::::0;::::1;;:::i;:::-;7830:32;;:14;;::::0;::::1;:6:::0;:14:::1;:::i;:::-;:32;;;::::0;-1:-1:-1;7872:25:10::1;7939:11;::::0;;;::::1;::::0;::::1;;:::i;:::-;:16;;;7998:1;7970:16;::::0;;;::::1;::::0;::::1;;:::i;:::-;:30;;;7969:67;;8020:16;::::0;;;::::1;::::0;::::1;;:::i;:::-;7969:67;;;8012:4;7969:67;8050:6;:16;;;8080:8;8102:4;8120:1;8163:204;;;;;;;;8225:6;:15;;;;;;;;;;:::i;:::-;8242:6;:11;;;;;;;;;;:::i;:::-;8255:6;:14;;;;;;;;;;:::i;:::-;8208:62;::::0;20236:66:23;20331:2;20327:15;;;20323:24;;8208:62:10::1;::::0;::::1;20311:37:23::0;20382:15;;;20378:24;;20364:12;;;20357:46;20437:15;;20433:24;20419:12;;;20412:46;20474:12;;8208:62:10::1;;;;;;;;;;;;8163:204;;;;8299:10;8163:204;;;;;;8344:4;8163:204;;;;::::0;8135:246:::1;;;;;;;;:::i;:::-;;;;;;;;;;;;;7939:452;;;;;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7907:484:::0;;-1:-1:-1;7907:484:10;-1:-1:-1;8430:16:10::1;::::0;::::1;;8409:37:::0;::::1;8401:80;;;::::0;::::1;::::0;;22181:2:23;8401:80:10::1;::::0;::::1;22163:21:23::0;22220:2;22200:18;;;22193:30;22259:32;22239:18;;;22232:60;22309:18;;8401:80:10::1;21979:354:23::0;8401:80:10::1;8511:6;:22;;;8499:8;:34;;8491:65;;;::::0;::::1;::::0;;22540:2:23;8491:65:10::1;::::0;::::1;22522:21:23::0;22579:2;22559:18;;;22552:30;22618:20;22598:18;;;22591:48;22656:18;;8491:65:10::1;22338:342:23::0;8491:65:10::1;-1:-1:-1::0;;888:17:10::1;8566:14;:41:::0;-1:-1:-1;7638:976:10;;-1:-1:-1;7638:976:10:o;14137:776::-;14453:20;14475;14497:33;14426:8;181::18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;14568:25:10::1;::::0;;;;::::1;::::0;::::1;4597::23::0;;;14568:8:10::1;:16;;::::0;::::1;::::0;4570:18:23;;14568:25:10::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14554:39;;:10;:39;;;14546:53;;;::::0;::::1;::::0;;23150:2:23;14546:53:10::1;::::0;::::1;23132:21:23::0;23189:1;23169:18;;;23162:29;23227:3;23207:18;;;23200:31;23248:18;;14546:53:10::1;22948:324:23::0;14546:53:10::1;14614:23;::::0;::::1;14610:54;;14659:4;14639:25;;14610:54;14716:48;::::0;;;;:20:::1;::::0;::::1;::::0;::::1;::::0;:48:::1;::::0;14737:9;;14748:7;;14757:6;;;;14716:48:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;::::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;14674:90:::0;;-1:-1:-1;14674:90:10;-1:-1:-1;14674:90:10;-1:-1:-1;14796:31:10;;::::1;::::0;::::1;::::0;:66:::1;;;14847:15;14831:12;:31;;14796:66;14775:131;;;::::0;::::1;::::0;;27070:2:23;14775:131:10::1;::::0;::::1;27052:21:23::0;27109:2;27089:18;;;27082:30;27148:20;27128:18;;;27121:48;27186:18;;14775:131:10::1;26868:342:23::0;14775:131:10::1;14137:776:::0;;;;;;;;;;;;;:::o;13794:309::-;13961:8;181::18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;13986:9:10::1;13981:116;14001:17:::0;;::::1;13981:116;;;14039:4;:22;;;14062:6;;14069:1;14062:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;14039:47;::::0;;::::1;::::0;;;;;;27858:34:23;27846:47;;;14039::10::1;::::0;::::1;27828:66:23::0;14039:47:10::1;27930:23:23::0;;27910:18;;;27903:51;27801:18;;14039:47:10::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;14020:3;;;;;:::i;:::-;;;;13981:116;;;;13794:309:::0;;;;;;:::o;1359:289:21:-;1551:90;;;;;1585:10;1551:90;;;28748:34:23;1605:4:21;28798:18:23;;;28791:43;28850:18;;;28843:34;;;28893:18;;;28886:34;;;1627:4:21;28936:19:23;;;28929:51;29029:4;29017:17;;28996:19;;;28989:46;29051:19;;;29044:35;;;29095:19;;;29088:35;;;1551:33:21;;;;;;28659:19:23;;1551:90:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1359:289;;;;;;:::o;1810:381:10:-;1930:30;;;;;1954:4;1930:30;;;514:74:23;1907:20:10;;1930:5;:15;;;;;487:18:23;;1930:30:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1907:53;;1994:13;1978:12;:29;;1970:60;;;;;;;29756:2:23;1970:60:10;;;29738:21:23;29795:2;29775:18;;;29768:30;29834:20;29814:18;;;29807:48;29872:18;;1970:60:10;29554:342:23;1970:60:10;2045:16;;2041:144;;2077:28;;;;;;;;4597:25:23;;;2077:5:10;:14;;;;;4570:18:23;;2077:28:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2119:55;2150:9;2161:12;2119:30;:55::i;:::-;1897:294;1810:381;;:::o;10964:565::-;11282:24;11320:20;11354;11388:33;11242:8;181::18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;11453:69:10::1;11466:4;11472:7;11481:6;;11489:15;11506;11453:12;:69::i;:::-;11446:76:::0;;;;-1:-1:-1;11446:76:10;-1:-1:-1;11446:76:10;;-1:-1:-1;10964:565:10;-1:-1:-1;;;;;;;;;10964:565:10:o;3487:921::-;3612:1;3598:11;:15;:32;;;;;3629:1;3617:9;:13;3598:32;3590:69;;;;;;;30103:2:23;3590:69:10;;;30085:21:23;30142:2;30122:18;;;30115:30;30181:26;30161:18;;;30154:54;30225:18;;3590:69:10;29901:348:23;3590:69:10;3677:40;;;;;3705:10;3677:40;;;514:74:23;3677:7:10;:21;;;;;487:18:23;;3677:40:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3669:82;;;;;;;30950:2:23;3669:82:10;;;30932:21:23;30989:2;30969:18;;;30962:30;31028:31;31008:18;;;31001:59;31077:18;;3669:82:10;30748:353:23;3669:82:10;3762:28;3793:37;;;;3804:5;3793:37;:::i;:::-;3762:68;;3841:14;3857:15;3874:10;3888:27;:4;:9;;;:25;:27::i;:::-;3840:75;;-1:-1:-1;3840:75:10;-1:-1:-1;3840:75:10;-1:-1:-1;3934:10:10;:27;;;;3926:36;;;;;;3977:4;:16;;;3973:429;;;4013:9;;:28;;:26;:28::i;:::-;4009:303;;;4073:9;;:21;;:19;:21::i;:::-;4061:33;;4112:50;4132:11;4145:10;4061:4;4112:19;:50::i;:::-;;3973:429;;4009:303;4218:11;4201:14;:28;;;;4247:50;4251:8;4261:4;:10;;;4273;4285:11;4247:3;:50::i;:::-;3973:429;;;4342:49;4346:7;4355:4;:10;;;4367;4379:11;4342:3;:49::i;:::-;3580:828;;;;3487:921;;;;:::o;1686:348:21:-;1895:50;;;;;1919:10;1895:50;;;32370:34:23;1939:4:21;32420:18:23;;;32413:43;1948:17:21;;1895:23;;;;;;32282:18:23;;1895:50:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:70;1891:136;;;1979:48;1997:5;2004;2011:6;2019:1;2022;2025;1979:17;:48::i;:::-;1686:348;;;;;;:::o;5043:811:10:-;5189:17;5163:6;:15;;;181:8:18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;5218:13:10::1;5251:15;::::0;;;::::1;::::0;::::1;;:::i;:::-;5234:32;;:14;;::::0;::::1;:6:::0;:14:::1;:::i;:::-;:32;;;::::0;-1:-1:-1;5293:11:10::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;:16;;;5352:1;5324:16;::::0;;;::::1;::::0;::::1;;:::i;:::-;:30;;;5323:67;;5374:16;::::0;;;::::1;::::0;::::1;;:::i;:::-;5323:67;;;5366:4;5323:67;5404:6;:15;;;5433:8;5455:5;5474:6;:24;;;5540:205;;;;;;;;5602:6;:14;;;;;;;;;;:::i;:::-;5618:6;:11;;;;;;;;;;:::i;:::-;5631:6;:15;;;;;;;;;;:::i;:::-;5585:62;::::0;20236:66:23;20331:2;20327:15;;;20323:24;;5585:62:10::1;::::0;::::1;20311:37:23::0;20382:15;;;20378:24;;20364:12;;;20357:46;20437:15;;20433:24;20419:12;;;20412:46;20474:12;;5585:62:10::1;;;;;;;;;;;;5540:205;;;;5676:10;5540:205;;;;;;5721:5;5540:205;;;;::::0;5512:247:::1;;;;;;;;:::i;:::-;;;;;;;;;;;;;5293:476;;;;;;;;;;;;;;;;;;;;:::i;:::-;;::::0;::::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5277:492:::0;-1:-1:-1;;5800:23:10::1;::::0;::::1;;5787:36:::0;::::1;;5779:68;;;::::0;::::1;::::0;;33319:2:23;5779:68:10::1;::::0;::::1;33301:21:23::0;33358:2;33338:18;;;33331:30;33397:21;33377:18;;;33370:49;33436:18;;5779:68:10::1;33117:343:23::0;5779:68:10::1;5208:646;5043:811:::0;;;;:::o;308:667:19:-;397:22;453:4;441:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;431:34;;480:9;475:494;495:15;;;475:494;;;532:12;;577:4;596;;601:1;596:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;569:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;531:73;;;;624:7;619:306;;751:2;735:6;:13;:18;731:32;;;755:8;;;731:32;834:4;826:6;822:17;812:27;;892:6;881:28;;;;;;;;;;;;:::i;:::-;874:36;;;;;;;;;;;:::i;619:306::-;952:6;939:7;947:1;939:10;;;;;;;;:::i;:::-;;;;;;:19;;;;517:452;;512:3;;;;;:::i;:::-;;;;475:494;;;;308:667;;;;:::o;5888:983:10:-;6020:17;5994:6;:15;;;181:8:18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;6065:10:10::1;6086:700;6113:23;6139:30;:6;:11;;;:28;:30::i;:::-;6113:56;;6202:337;6238:6;:15;;;6271:18;:53;;6308:6;:16;;;6271:53;;;6300:4;6271:53;6342:1;6361:164;;;;;;;;6406:26;:6;:11;;;:24;:26::i;:::-;6361:164:::0;;::::1;::::0;::::1;;::::0;::::1;::::0;-1:-1:-1;6361:164:10;;;;;6202:18:::1;:337::i;:::-;6184:15;::::0;::::1;:355:::0;6554:222;::::1;;;6649:11:::0;;6612:4:::1;::::0;-1:-1:-1;6649:23:10::1;::::0;:21:::1;:23::i;:::-;6635:37:::0;;6554:222:::1;;;6723:6;:15;;;6711:27;;6756:5;;;6554:222;6099:687;6086:700;;;6817:6;:23;;;6804:9;:36;;6796:68;;;::::0;::::1;::::0;;33319:2:23;6796:68:10::1;::::0;::::1;33301:21:23::0;33358:2;33338:18;;;33331:30;33397:21;33377:18;;;33370:49;33436:18;;6796:68:10::1;33117:343:23::0;995:326:21;1199:50;;;;;1223:10;1199:50;;;32370:34:23;1243:4:21;32420:18:23;;;32413:43;1252:5:21;;1199:23;;;;;;32282:18:23;;1199:50:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;1195:119;;;1271:43;1282:5;1289;1296:8;1306:1;1309;1312;1271:10;:43::i;13107:653:10:-;13460:24;13498:20;13532;13566:33;13420:8;181::18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;13624:10:10::1;13637:27;13653:10;13637:15;:27::i;:::-;13624:40;;13681:72;13694:4;13700:7;13709:9;;13720:15;13737;13681:12;:72::i;:::-;13674:79;;;;;;;;;13107:653:::0;;;;;;;;;;;;;:::o;9182:508::-;9287:36;9326:45;;;;9337:5;9326:45;:::i;:::-;9389:40;;;;;9417:10;9389:40;;;514:74:23;9287:84:10;;-1:-1:-1;9389:7:10;:21;;;;;487:18:23;;9389:40:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9381:49;;;;;;9470:4;:9;;;9448:32;;:10;:32;;;9440:41;;;;;;9495:12;;9491:92;;9523:49;9527:4;:11;;;9540:4;:10;;;9552;9564:7;9523:3;:49::i;:::-;9596:12;;9592:92;;9624:49;9628:4;:11;;;9641:4;:10;;;9653;9665:7;9624:3;:49::i;:::-;9277:413;9182:508;;;;:::o;2229:356::-;2353:30;;;;;2377:4;2353:30;;;514:74:23;2330:20:10;;2353:15;;;;;;487:18:23;;2353:30:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2330:53;;2417:13;2401:12;:29;;2393:60;;;;;;;36220:2:23;2393:60:10;;;36202:21:23;36259:2;36239:18;;;36232:30;36298:20;36278:18;;;36271:48;36336:18;;2393:60:10;36018:342:23;2393:60:10;2468:16;;2464:115;;2500:68;2536:5;2544:9;2555:12;2500:27;:68::i;:::-;2320:265;2229:356;;;:::o;8648:511::-;8784:16;8758:6;:15;;;181:8:18;162:15;:27;;154:59;;;;;;;17922:2:23;154:59:18;;;17904:21:23;17961:2;17941:18;;;17934:30;18000:21;17980:18;;;17973:49;18039:18;;154:59:18;17720:343:23;154:59:18;8812:178:10::1;8845:16;::::0;::::1;;8875;::::0;;;::::1;::::0;::::1;;:::i;:::-;8905:75;::::0;;::::1;::::0;::::1;::::0;;;;8929:11:::1;:6:::0;;:11:::1;:::i;:::-;8905:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;;8905:75:10;;;-1:-1:-1;8949:10:10::1;8905:75;::::0;::::1;::::0;8974:4:::1;8905:75:::0;;;;;8812:19:::1;:178::i;:::-;;9012:14;;9001:25;;9056:6;:22;;;9044:8;:34;;9036:65;;;::::0;::::1;::::0;;22540:2:23;9036:65:10::1;::::0;::::1;22522:21:23::0;22579:2;22559:18;;;22552:30;22618:20;22598:18;;;22591:48;22656:18;;9036:65:10::1;22338:342:23::0;9036:65:10::1;-1:-1:-1::0;888:17:10::1;9111:14;:41:::0;8648:511;;-1:-1:-1;8648:511:10:o;684:273:21:-;871:79;;;;;898:10;871:79;;;36737:34:23;918:4:21;36787:18:23;;;36780:43;36839:18;;;36832:34;;;36882:18;;;36875:34;;;36958:4;36946:17;;36925:19;;;36918:46;36980:19;;;36973:35;;;37024:19;;;37017:35;;;871:26:21;;;;;;36648:19:23;;871:79:21;36365:693:23;2326:165:22;2438:12;;;2398;2438;;;;;;;;;2416:7;;;;2431:5;;2416:35;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2397:54;;;2469:7;2461:23;;;;;;;37557:2:23;2461:23:22;;;37539:21:23;37596:1;37576:18;;;37569:29;37634:5;37614:18;;;37607:33;37657:18;;2461:23:22;37355:326:23;9696:1234:10;9933:24;9971:20;10005;10039:33;10101:7;10112:1;10101:12;10097:290;;10133:60;;;;;10179:10;10133:60;;;37868:74:23;10191:1:10;37958:18:23;;;37951:34;10143:8:10;10133:45;;;;;37841:18:23;;10133:60:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10129:248;;;10223:54;;;;;10263:10;10223:54;;;37868:74:23;10275:1:10;37958:18:23;;;37951:34;10233:8:10;10223:39;;;;;37841:18:23;;10223:54:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10213:64;;10129:248;;;10326:36;;;;;10351:10;10326:36;;;514:74:23;10336:8:10;10326:24;;;;;487:18:23;;10326:36:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10316:46;;10129:248;10415:7;10396:26;;10433:36;10472:161;;;;;;;;10519:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10472:161;;;;;;10554:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10472:161;;;;;;;;;;;;;;;;10612:10;10472:161;;;;;10757:16;;38585:13:23;;38581:22;;10757:16:10;;;38563:41:23;38652:17;;;38646:24;38642:33;;38620:20;;;38613:63;38724:17;;;38718:24;38714:33;;38692:20;;;;38685:63;;;;38796:17;;38790:24;38786:33;;;38764:20;;;;38757:63;;;;10757:16:10;;;;;;;;;;38474:19:23;;;10757:16:10;;;;10685:98;;;;38585:13:23;;-1:-1:-1;10685:17:10;;:98;;10716:7;;10737:6;;;;10757:16;10685:98;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10643:140;;-1:-1:-1;10643:140:10;-1:-1:-1;10643:140:10;-1:-1:-1;10815:31:10;;;;;;:66;;;10866:15;10850:12;:31;;10815:66;10794:129;;;;;;;40777:2:23;10794:129:10;;;40759:21:23;40816:2;40796:18;;;40789:30;40855:18;40835;;;40828:46;40891:18;;10794:129:10;40575:340:23;10794:129:10;10087:843;9696:1234;;;;;;;;;;;:::o;1770:283:20:-;1851:14;;;1923:17;:4;1851:14;1923;:17::i;:::-;1906:35;-1:-1:-1;1964:25:20;:4;423:2;1964:14;:25::i;:::-;1951:39;-1:-1:-1;2018:27:20;538:21;423:2;;538:21;:::i;:::-;2018:4;;:14;:27::i;:::-;2000:46;;1770:283;;;;;:::o;1024:138::-;1092:4;538:21;423:2;;538:21;:::i;:::-;423:2;538:21;423:2;;538:21;:::i;:::-;650:23;;;;:::i;:::-;809:24;;;;:::i;:::-;1115:4;:11;:40;;1108:47;;1024:138;;;:::o;2597:149::-;2658:12;2689:50;538:21;423:2;;538:21;:::i;:::-;;423:2;;538:21;:::i;:::-;2713:4;:11;:25;;;;:::i;:::-;2689:4;;:50;:10;:50::i;:::-;2682:57;2597:149;-1:-1:-1;;2597:149:20:o;6926:674:10:-;7070:16;7102:23;;;7098:54;;7147:4;7127:25;;7098:54;7164:15;7181:14;7197:10;7211:27;:4;:9;;;:25;:27::i;:::-;7163:75;;;;;;7249:13;7275:8;7265:18;;:7;:18;;;7249:34;;7293:25;7360:4;:9;;;7383;7406;7429:8;7451:4;7469:1;7495:4;7484:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;7360:150;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7328:182;;-1:-1:-1;7328:182:10;-1:-1:-1;7528:30:10;;;7520:73;;;;;;;22181:2:23;7520:73:10;;;22163:21:23;22220:2;22200:18;;;22193:30;22259:32;22239:18;;;22232:60;22309:18;;7520:73:10;21979:354:23;7520:73:10;7088:512;;;;;6926:674;;;;;:::o;2986:495::-;3111:5;3085:31;;3100:5;3085:31;;;:65;;;;;3145:5;3120:21;:30;;3085:65;3081:394;;;3166:5;:13;;;3187:5;3166:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3209:32:10;;;;;:14;37886:55:23;;;3209:32:10;;;37868:74:23;37958:18;;;37951:34;;;3209:5:10;:14;;-1:-1:-1;3209:14:10;;-1:-1:-1;37841:18:23;;;-1:-1:-1;3209:32:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3081:394;;;3279:4;3262:22;;;;3258:217;;3300:61;3336:5;3344:9;3355:5;3300:27;:61::i;:::-;3258:217;;;3392:72;3432:5;3440;3447:9;3458:5;3392:31;:72::i;2279:127:20:-;2343:12;2374:25;2385:1;423:2;538:21;423:2;;538:21;:::i;:::-;650:23;;;;:::i;4414:591:10:-;4591:17;4624:23;;;4620:54;;4669:4;4649:25;;4620:54;4686:14;4702:15;4719:10;4733:27;:4;:9;;;:25;:27::i;:::-;4685:75;;;;;;4771:13;4797:8;4787:18;;:7;:18;;;4771:34;;4832:4;:9;;;4855;4878:8;4900;4922:5;4941:17;4983:4;4972:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;4832:166;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4816:182;4414:591;-1:-1:-1;;;;;;;;;;4414:591:10:o;12392:681::-;12466:10;12509:24;12518:7;12509:24;;12551:14;;12583:22;;;;12623:19;;;;12660:17;;;;;;;;:::i;:::-;12695;;;;;;;;:::i;:::-;12509:217;;;;;;;;;;;;;42043:25:23;;;;42084:18;;;42077:34;;;;42127:18;;;42120:34;;;;42173:42;42251:15;;;42231:18;;;42224:43;42304:15;42283:19;;;42276:44;42015:19;;12509:217:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12502:224;-1:-1:-1;12750:27:10;;;12746:321;;12800:24;12809:7;12800:24;;12842:14;;12874:22;;;;12914:19;;;;12951:21;;;;;;;;:::i;:::-;12990:17;;;;;;;;:::i;:::-;13025;;;;;;;;:::i;:::-;12800:256;;;;;;;;;;;;;43164:25:23;;;;43205:18;;;43198:34;;;;43248:18;;;43241:34;;;;43322:1;43311:21;43291:18;;;43284:49;43352:42;43431:15;;;43410:19;;;43403:44;43484:15;43463:19;;;43456:44;43136:19;;12800:256:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;12746:321::-;12392:681;;;:::o;1183:301:22:-;1326:59;;;1302:10;37886:55:23;;;1326:59:22;;;37868:74:23;37958:18;;;;37951:34;;;1326:59:22;;;;;;;;;;37841:18:23;;;;1326:59:22;;;;;;;;;1349:24;1326:59;;;1302:93;;-1:-1:-1;;;;1302:10:22;;;;:93;;1326:59;1302:93;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1266:129;;;;1413:7;:57;;;;-1:-1:-1;1425:11:22;;:16;;:44;;;1456:4;1445:24;;;;;;;;;;;;:::i;:::-;1405:72;;;;;;;43713:2:23;1405:72:22;;;43695:21:23;43752:1;43732:18;;;43725:29;43790:4;43770:18;;;43763:32;43812:18;;1405:72:22;43511:325:23;3236:416:17;3315:7;3357:6;3342:11;3357:6;3351:2;3342:11;:::i;:::-;:21;;3334:52;;;;;;;44043:2:23;3334:52:17;;;44025:21:23;44082:2;44062:18;;;44055:30;44121:20;44101:18;;;44094:48;44159:18;;3334:52:17;43841:342:23;3334:52:17;3421:11;:6;3430:2;3421:11;:::i;:::-;3404:6;:13;:28;;3396:62;;;;;;;44390:2:23;3396:62:17;;;44372:21:23;44429:2;44409:18;;;44402:30;44468:23;44448:18;;;44441:51;44509:18;;3396:62:17;44188:345:23;3396:62:17;-1:-1:-1;3546:30:17;3562:4;3546:30;3540:37;3579:27;3536:71;;;3236:416::o;391:2839::-;513:12;561:7;545:12;561:7;555:2;545:12;:::i;:::-;:23;;537:50;;;;;;;44740:2:23;537:50:17;;;44722:21:23;44779:2;44759:18;;;44752:30;44818:16;44798:18;;;44791:44;44852:18;;537:50:17;44538:338:23;537:50:17;625:6;605:16;614:7;625:6;605:16;:::i;:::-;:26;;597:53;;;;;;;44740:2:23;597:53:17;;;44722:21:23;44779:2;44759:18;;;44752:30;44818:16;44798:18;;;44791:44;44852:18;;597:53:17;44538:338:23;597:53:17;685:16;694:7;685:6;:16;:::i;:::-;668:6;:13;:33;;660:63;;;;;;;45083:2:23;660:63:17;;;45065:21:23;45122:2;45102:18;;;45095:30;45161:19;45141:18;;;45134:47;45198:18;;660:63:17;44881:341:23;660:63:17;734:22;797:15;;825:1967;;;;2933:4;2927:11;2914:24;;3119:1;3108:9;3101:20;3167:4;3156:9;3152:20;3146:4;3139:34;790:2397;;825:1967;1007:4;1001:11;988:24;;1666:2;1657:7;1653:16;2048:9;2041:17;2035:4;2031:28;2019:9;2008;2004:25;2000:60;2096:7;2092:2;2088:16;2348:6;2334:9;2327:17;2321:4;2317:28;2305:9;2297:6;2293:22;2289:57;2285:70;2122:425;2381:3;2377:2;2374:11;2122:425;;;2519:9;;2508:21;;2422:4;2414:13;;;;2454;2122:425;;;-1:-1:-1;;2565:26:17;;;2773:2;2756:11;2769:7;2752:25;2746:4;2739:39;-1:-1:-1;790:2397:17;-1:-1:-1;3214:9:17;391:2839;-1:-1:-1;;;;391:2839:17:o;561:330:22:-;722:69;;;698:10;45508:15:23;;;722:69:22;;;45490:34:23;45560:15;;;45540:18;;;45533:43;45592:18;;;;45585:34;;;722:69:22;;;;;;;;;;45402:18:23;;;;722:69:22;;;;;;;;;745:28;722:69;;;698:103;;-1:-1:-1;;;;698:10:22;;;;:103;;722:69;698:103;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;662:139;;;;819:7;:57;;;;-1:-1:-1;831:11:22;;:16;;:44;;;862:4;851:24;;;;;;;;;;;;:::i;:::-;811:73;;;;;;;45832:2:23;811:73:22;;;45814:21:23;45871:1;45851:18;;;45844:29;45909:5;45889:18;;;45882:33;45932:18;;811:73:22;45630:326:23;599:161;692:42;685:5;681:54;674:5;671:65;661:93;;750:1;747;740:12;661:93;599:161;:::o;765:397::-;855:8;865:6;919:3;912:4;904:6;900:17;896:27;886:55;;937:1;934;927:12;886:55;-1:-1:-1;960:20:23;;1003:18;992:30;;989:50;;;1035:1;1032;1025:12;989:50;1072:4;1064:6;1060:17;1048:29;;1135:3;1128:4;1120;1112:6;1108:17;1100:6;1096:30;1092:41;1089:50;1086:70;;;1152:1;1149;1142:12;1086:70;765:397;;;;;:::o;1167:118::-;1254:5;1251:1;1240:20;1233:5;1230:31;1220:59;;1275:1;1272;1265:12;1290:1207;1485:6;1493;1501;1509;1517;1525;1533;1541;1549;1602:3;1590:9;1581:7;1577:23;1573:33;1570:53;;;1619:1;1616;1609:12;1570:53;1658:9;1645:23;1677:38;1709:5;1677:38;:::i;:::-;1734:5;-1:-1:-1;1786:2:23;1771:18;;1758:32;;-1:-1:-1;1841:2:23;1826:18;;1813:32;1868:18;1857:30;;1854:50;;;1900:1;1897;1890:12;1854:50;1939:97;2028:7;2019:6;2008:9;2004:22;1939:97;:::i;:::-;2055:8;;-1:-1:-1;1913:123:23;-1:-1:-1;;2137:2:23;2122:18;;2109:32;;-1:-1:-1;2188:3:23;2173:19;;2160:33;;-1:-1:-1;2245:3:23;2230:19;;2217:33;2259:31;2217:33;2259:31;:::i;:::-;2309:7;-1:-1:-1;2368:3:23;2353:19;;2340:33;2382:31;2340:33;2382:31;:::i;:::-;2432:7;2422:17;;;2486:3;2475:9;2471:19;2458:33;2448:43;;1290:1207;;;;;;;;;;;:::o;2598:1094::-;2659:3;2697:5;2691:12;2724:6;2719:3;2712:19;2750:4;2779:2;2774:3;2770:12;2763:19;;2816:2;2809:5;2805:14;2837:1;2847:820;2861:6;2858:1;2855:13;2847:820;;;2920:13;;3019:9;;2956:34;3015:18;;;3003:31;;3078:11;;;3072:18;3068:27;;3054:12;;;3047:49;3119:4;3163:11;;;3157:18;3143:12;;;3136:40;3199:4;3247:11;;;3241:18;3237:27;;;3223:12;;;3216:49;3288:4;3336:11;;;3330:18;3350:4;3326:29;3312:12;;;3305:51;3379:4;3437:11;;;3431:18;3428:1;3417:33;3403:12;;;3396:55;3474:4;3517:11;;;3511:18;2572:13;2565:21;3572:12;;;2553:34;3614:4;3605:14;;;;3642:15;;;;2883:1;2876:9;2847:820;;;-1:-1:-1;3683:3:23;;2598:1094;-1:-1:-1;;;;;2598:1094:23:o;3697:534::-;4010:6;3999:9;3992:25;4053:6;4048:2;4037:9;4033:18;4026:34;4096:6;4091:2;4080:9;4076:18;4069:34;4139:3;4134:2;4123:9;4119:18;4112:31;3973:4;4160:65;4220:3;4209:9;4205:19;4197:6;4160:65;:::i;:::-;4152:73;3697:534;-1:-1:-1;;;;;;3697:534:23:o;4236:210::-;4338:6;4391:3;4379:9;4370:7;4366:23;4362:33;4359:53;;;4408:1;4405;4398:12;4359:53;-1:-1:-1;4431:9:23;4236:210;-1:-1:-1;4236:210:23:o;4633:1234::-;4826:6;4834;4842;4850;4858;4866;4874;4882;4935:3;4923:9;4914:7;4910:23;4906:33;4903:53;;;4952:1;4949;4942:12;4903:53;4991:9;4978:23;5010:38;5042:5;5010:38;:::i;:::-;5067:5;-1:-1:-1;5124:2:23;5109:18;;5096:32;5137:40;5096:32;5137:40;:::i;:::-;5196:7;-1:-1:-1;5250:2:23;5235:18;;5222:32;;-1:-1:-1;5305:2:23;5290:18;;5277:32;5328:18;5358:14;;;5355:34;;;5385:1;5382;5375:12;5355:34;5423:6;5412:9;5408:22;5398:32;;5468:7;5461:4;5457:2;5453:13;5449:27;5439:55;;5490:1;5487;5480:12;5439:55;5530:2;5517:16;5556:2;5548:6;5545:14;5542:34;;;5572:1;5569;5562:12;5542:34;5625:7;5620:2;5610:6;5607:1;5603:14;5599:2;5595:23;5591:32;5588:45;5585:65;;;5646:1;5643;5636:12;5585:65;4633:1234;;;;-1:-1:-1;4633:1234:23;;5677:2;5669:11;;;;;5699:6;5752:3;5737:19;;5724:33;;-1:-1:-1;5804:3:23;5789:19;;5776:33;;-1:-1:-1;5856:3:23;5841:19;;;5828:33;;-1:-1:-1;4633:1234:23;-1:-1:-1;;;4633:1234:23:o;5872:461::-;6157:6;6146:9;6139:25;6200:6;6195:2;6184:9;6180:18;6173:34;6243:2;6238;6227:9;6223:18;6216:30;6120:4;6263:64;6323:2;6312:9;6308:18;6300:6;6263:64;:::i;:::-;6255:72;5872:461;-1:-1:-1;;;;;5872:461:23:o;6338:367::-;6401:8;6411:6;6465:3;6458:4;6450:6;6446:17;6442:27;6432:55;;6483:1;6480;6473:12;6432:55;-1:-1:-1;6506:20:23;;6549:18;6538:30;;6535:50;;;6581:1;6578;6571:12;6535:50;6618:4;6610:6;6606:17;6594:29;;6678:3;6671:4;6661:6;6658:1;6654:14;6646:6;6642:27;6638:38;6635:47;6632:67;;;6695:1;6692;6685:12;6710:833;6835:6;6843;6851;6859;6867;6920:3;6908:9;6899:7;6895:23;6891:33;6888:53;;;6937:1;6934;6927:12;6888:53;6976:9;6963:23;6995:38;7027:5;6995:38;:::i;:::-;7052:5;-1:-1:-1;7108:2:23;7093:18;;7080:32;7135:18;7124:30;;7121:50;;;7167:1;7164;7157:12;7121:50;7206:70;7268:7;7259:6;7248:9;7244:22;7206:70;:::i;:::-;7295:8;;-1:-1:-1;7180:96:23;-1:-1:-1;;7382:2:23;7367:18;;7354:32;7430:10;7417:24;;7405:37;;7395:65;;7456:1;7453;7446:12;7395:65;6710:833;;;;-1:-1:-1;6710:833:23;;7533:2;7518:18;7505:32;;6710:833;-1:-1:-1;;6710:833:23:o;7548:114::-;7632:4;7625:5;7621:16;7614:5;7611:27;7601:55;;7652:1;7649;7642:12;7667:666;7769:6;7777;7785;7793;7801;7809;7862:3;7850:9;7841:7;7837:23;7833:33;7830:53;;;7879:1;7876;7869:12;7830:53;7918:9;7905:23;7937:38;7969:5;7937:38;:::i;:::-;7994:5;-1:-1:-1;8046:2:23;8031:18;;8018:32;;-1:-1:-1;8097:2:23;8082:18;;8069:32;;-1:-1:-1;8153:2:23;8138:18;;8125:32;8166:31;8125:32;8166:31;:::i;:::-;7667:666;;;;-1:-1:-1;7667:666:23;;8270:3;8255:19;;8242:33;;8322:3;8307:19;;;8294:33;;-1:-1:-1;7667:666:23;-1:-1:-1;;7667:666:23:o;8338:322::-;8406:6;8414;8467:2;8455:9;8446:7;8442:23;8438:32;8435:52;;;8483:1;8480;8473:12;8435:52;8519:9;8506:23;8496:33;;8579:2;8568:9;8564:18;8551:32;8592:38;8624:5;8592:38;:::i;:::-;8649:5;8639:15;;;8338:322;;;;;:::o;8911:931::-;9092:6;9100;9108;9116;9124;9132;9140;9193:3;9181:9;9172:7;9168:23;9164:33;9161:53;;;9210:1;9207;9200:12;9161:53;9249:9;9236:23;9268:38;9300:5;9268:38;:::i;:::-;9325:5;-1:-1:-1;9377:2:23;9362:18;;9349:32;;-1:-1:-1;9432:2:23;9417:18;;9404:32;9459:18;9448:30;;9445:50;;;9491:1;9488;9481:12;9445:50;9530:97;9619:7;9610:6;9599:9;9595:22;9530:97;:::i;:::-;8911:931;;;;-1:-1:-1;9646:8:23;9728:2;9713:18;;9700:32;;9779:3;9764:19;;9751:33;;-1:-1:-1;9831:3:23;9816:19;;;9803:33;;-1:-1:-1;8911:931:23;-1:-1:-1;;;;8911:931:23:o;9847:727::-;9935:6;9943;9951;9959;10012:2;10000:9;9991:7;9987:23;9983:32;9980:52;;;10028:1;10025;10018:12;9980:52;10064:9;10051:23;10041:33;;10121:2;10110:9;10106:18;10093:32;10083:42;;10176:2;10165:9;10161:18;10148:32;10199:18;10240:2;10232:6;10229:14;10226:34;;;10256:1;10253;10246:12;10226:34;10294:6;10283:9;10279:22;10269:32;;10339:7;10332:4;10328:2;10324:13;10320:27;10310:55;;10361:1;10358;10351:12;10310:55;10401:2;10388:16;10427:2;10419:6;10416:14;10413:34;;;10443:1;10440;10433:12;10413:34;10488:7;10483:2;10474:6;10470:2;10466:15;10462:24;10459:37;10456:57;;;10509:1;10506;10499:12;10456:57;9847:727;;;;-1:-1:-1;;10540:2:23;10532:11;;-1:-1:-1;;;9847:727:23:o;10579:209::-;10680:6;10733:3;10721:9;10712:7;10708:23;10704:33;10701:53;;;10750:1;10747;10740:12;10793:448;10890:6;10898;10951:2;10939:9;10930:7;10926:23;10922:32;10919:52;;;10967:1;10964;10957:12;10919:52;11007:9;10994:23;11040:18;11032:6;11029:30;11026:50;;;11072:1;11069;11062:12;11026:50;11111:70;11173:7;11164:6;11153:9;11149:22;11111:70;:::i;:::-;11200:8;;11085:96;;-1:-1:-1;10793:448:23;-1:-1:-1;;;;10793:448:23:o;11246:250::-;11331:1;11341:113;11355:6;11352:1;11349:13;11341:113;;;11431:11;;;11425:18;11412:11;;;11405:39;11377:2;11370:10;11341:113;;;-1:-1:-1;;11488:1:23;11470:16;;11463:27;11246:250::o;11501:329::-;11542:3;11580:5;11574:12;11607:6;11602:3;11595:19;11623:76;11692:6;11685:4;11680:3;11676:14;11669:4;11662:5;11658:16;11623:76;:::i;:::-;11744:2;11732:15;11749:66;11728:88;11719:98;;;;11819:4;11715:109;;11501:329;-1:-1:-1;;11501:329:23:o;11835:859::-;11995:4;12024:2;12064;12053:9;12049:18;12094:2;12083:9;12076:21;12117:6;12152;12146:13;12183:6;12175;12168:22;12221:2;12210:9;12206:18;12199:25;;12283:2;12273:6;12270:1;12266:14;12255:9;12251:30;12247:39;12233:53;;12321:2;12313:6;12309:15;12342:1;12352:313;12366:6;12363:1;12360:13;12352:313;;;12455:66;12443:9;12435:6;12431:22;12427:95;12422:3;12415:108;12546:39;12578:6;12569;12563:13;12546:39;:::i;:::-;12536:49;-1:-1:-1;12643:12:23;;;;12608:15;;;;12388:1;12381:9;12352:313;;;-1:-1:-1;12682:6:23;;11835:859;-1:-1:-1;;;;;;;11835:859:23:o;12699:184::-;12751:77;12748:1;12741:88;12848:4;12845:1;12838:15;12872:4;12869:1;12862:15;12888:253;12960:2;12954:9;13002:4;12990:17;;13037:18;13022:34;;13058:22;;;13019:62;13016:88;;;13084:18;;:::i;:::-;13120:2;13113:22;12888:253;:::o;13146:252::-;13218:2;13212:9;13260:3;13248:16;;13294:18;13279:34;;13315:22;;;13276:62;13273:88;;;13341:18;;:::i;13403:253::-;13475:2;13469:9;13517:4;13505:17;;13552:18;13537:34;;13573:22;;;13534:62;13531:88;;;13599:18;;:::i;13661:334::-;13732:2;13726:9;13788:2;13778:13;;13793:66;13774:86;13762:99;;13891:18;13876:34;;13912:22;;;13873:62;13870:88;;;13938:18;;:::i;:::-;13974:2;13967:22;13661:334;;-1:-1:-1;13661:334:23:o;14000:245::-;14048:4;14081:18;14073:6;14070:30;14067:56;;;14103:18;;:::i;:::-;-1:-1:-1;14160:2:23;14148:15;14165:66;14144:88;14234:4;14140:99;;14000:245::o;14250:462::-;14292:5;14345:3;14338:4;14330:6;14326:17;14322:27;14312:55;;14363:1;14360;14353:12;14312:55;14399:6;14386:20;14430:48;14446:31;14474:2;14446:31;:::i;:::-;14430:48;:::i;:::-;14503:2;14494:7;14487:19;14549:3;14542:4;14537:2;14529:6;14525:15;14521:26;14518:35;14515:55;;;14566:1;14563;14556:12;14515:55;14631:2;14624:4;14616:6;14612:17;14605:4;14596:7;14592:18;14579:55;14679:1;14654:16;;;14672:4;14650:27;14643:38;;;;14658:7;14250:462;-1:-1:-1;;;14250:462:23:o;14717:931::-;14810:6;14863:2;14851:9;14842:7;14838:23;14834:32;14831:52;;;14879:1;14876;14869:12;14831:52;14919:9;14906:23;14948:18;14989:2;14981:6;14978:14;14975:34;;;15005:1;15002;14995:12;14975:34;15028:22;;;;15084:4;15066:16;;;15062:27;15059:47;;;15102:1;15099;15092:12;15059:47;15128:22;;:::i;:::-;15188:2;15175:16;15216:2;15206:8;15203:16;15200:36;;;15232:1;15229;15222:12;15200:36;15259:44;15295:7;15284:8;15280:2;15276:17;15259:44;:::i;:::-;15252:5;15245:59;;15349:2;15345;15341:11;15328:25;15313:40;;15362;15394:7;15362:40;:::i;:::-;15434:7;15429:2;15422:5;15418:14;15411:31;15495:2;15491;15487:11;15474:25;15469:2;15462:5;15458:14;15451:49;15553:2;15549;15545:11;15532:25;15527:2;15520:5;15516:14;15509:49;15612:3;15608:2;15604:12;15591:26;15585:3;15578:5;15574:15;15567:51;15637:5;15627:15;;;;;14717:931;;;;:::o;15899:925::-;16097:6;16105;16113;16121;16129;16137;16145;16189:9;16180:7;16176:23;16219:3;16215:2;16211:12;16208:32;;;16236:1;16233;16226:12;16208:32;16260:3;16256:2;16252:12;16249:32;;;16277:1;16274;16267:12;16249:32;;16300:9;16290:19;;16356:3;16345:9;16341:19;16328:33;16318:43;;16412:3;16401:9;16397:19;16384:33;16440:18;16432:6;16429:30;16426:50;;;16472:1;16469;16462:12;16426:50;16511:97;16600:7;16591:6;16580:9;16576:22;16511:97;:::i;:::-;15899:925;;;;-1:-1:-1;16627:8:23;16709:3;16694:19;;16681:33;;16761:3;16746:19;;16733:33;;-1:-1:-1;16813:3:23;16798:19;;;16785:33;;-1:-1:-1;15899:925:23;-1:-1:-1;;;;15899:925:23:o;16829:484::-;16920:6;16928;16936;16989:2;16977:9;16968:7;16964:23;16960:32;16957:52;;;17005:1;17002;16995:12;16957:52;17044:9;17031:23;17063:38;17095:5;17063:38;:::i;:::-;17120:5;-1:-1:-1;17172:2:23;17157:18;;17144:32;;-1:-1:-1;17228:2:23;17213:18;;17200:32;17241:40;17200:32;17241:40;:::i;:::-;17300:7;17290:17;;;16829:484;;;;;:::o;17318:397::-;17414:6;17467:2;17455:9;17446:7;17442:23;17438:32;17435:52;;;17483:1;17480;17473:12;17435:52;17523:9;17510:23;17556:18;17548:6;17545:30;17542:50;;;17588:1;17585;17578:12;17542:50;17611:22;;17667:3;17649:16;;;17645:26;17642:46;;;17684:1;17681;17674:12;17642:46;17707:2;17318:397;-1:-1:-1;;;17318:397:23:o;18068:134::-;18145:13;;18167:29;18145:13;18167:29;:::i;18207:146::-;18293:34;18286:5;18282:46;18275:5;18272:57;18262:85;;18343:1;18340;18333:12;18358:782;18450:6;18503:3;18491:9;18482:7;18478:23;18474:33;18471:53;;;18520:1;18517;18510:12;18471:53;18546:22;;:::i;:::-;18598:9;18592:16;18617:31;18640:7;18617:31;:::i;:::-;18657:22;;18724:2;18709:18;;18703:25;18737:31;18703:25;18737:31;:::i;:::-;18795:2;18784:14;;18777:31;18853:2;18838:18;;18832:25;18866:33;18832:25;18866:33;:::i;:::-;18926:2;18915:14;;18908:31;18984:2;18969:18;;18963:25;19032:18;19019:32;;19007:45;;18997:73;;19066:1;19063;19056:12;18997:73;19097:2;19086:14;;19079:31;19090:5;18358:782;-1:-1:-1;;;18358:782:23:o;19497:254::-;19556:6;19609:2;19597:9;19588:7;19584:23;19580:32;19577:52;;;19625:1;19622;19615:12;19577:52;19664:9;19651:23;19683:38;19715:5;19683:38;:::i;20497:569::-;20692:2;20681:9;20674:21;20655:4;20730:6;20724:13;20773:4;20768:2;20757:9;20753:18;20746:32;20801:51;20847:3;20836:9;20832:19;20818:12;20801:51;:::i;:::-;20787:65;;20916:42;20910:2;20902:6;20898:15;20892:22;20888:71;20883:2;20872:9;20868:18;20861:99;21030:2;21022:6;21018:15;21012:22;21005:30;20998:38;20991:4;20980:9;20976:20;20969:68;21054:6;21046:14;;;20497:569;;;;:::o;21071:653::-;21366:42;21358:6;21354:55;21343:9;21336:74;21446:6;21441:2;21430:9;21426:18;21419:34;21503:6;21496:14;21489:22;21484:2;21473:9;21469:18;21462:50;21562:6;21555:14;21548:22;21543:2;21532:9;21528:18;21521:50;21608:6;21602:3;21591:9;21587:19;21580:35;21652:3;21646;21635:9;21631:19;21624:32;21317:4;21673:45;21713:3;21702:9;21698:19;21690:6;21673:45;:::i;:::-;21665:53;21071:653;-1:-1:-1;;;;;;;;21071:653:23:o;21729:245::-;21808:6;21816;21869:2;21857:9;21848:7;21844:23;21840:32;21837:52;;;21885:1;21882;21875:12;21837:52;-1:-1:-1;;21908:16:23;;21964:2;21949:18;;;21943:25;21908:16;;21943:25;;-1:-1:-1;21729:245:23:o;22685:258::-;22755:6;22808:2;22796:9;22787:7;22783:23;22779:32;22776:52;;;22824:1;22821;22814:12;22776:52;22856:9;22850:16;22875:38;22907:5;22875:38;:::i;23277:1190::-;23563:4;23611:2;23600:9;23596:18;23653:42;23645:6;23641:55;23630:9;23623:74;23716:2;23754:6;23749:2;23738:9;23734:18;23727:34;23780:2;23818;23813;23802:9;23798:18;23791:30;23841:6;23871;23863;23856:22;23909:3;23898:9;23894:19;23887:26;;23936:6;23922:20;;23960:1;23970:471;23984:6;23981:1;23978:13;23970:471;;;24059:6;24046:20;24079:31;24104:5;24079:31;:::i;:::-;24133:34;24192:14;;;24180:27;;24248:15;;;24235:29;;24277:33;24235:29;24277:33;:::i;:::-;24344:16;24330:12;;;24323:38;24416:15;;;;24381:12;;;;24006:1;23999:9;23970:471;;;-1:-1:-1;24458:3:23;23277:1190;-1:-1:-1;;;;;;;;;23277:1190:23:o;24472:118::-;24558:5;24551:13;24544:21;24537:5;24534:32;24524:60;;24580:1;24577;24570:12;24595:132;24671:13;;24693:28;24671:13;24693:28;:::i;24732:2131::-;24870:6;24878;24886;24917:2;24960;24948:9;24939:7;24935:23;24931:32;24928:52;;;24976:1;24973;24966:12;24928:52;25005:9;24999:16;24989:26;;25034:2;25076;25065:9;25061:18;25055:25;25045:35;;25099:2;25145;25134:9;25130:18;25124:25;25168:18;25209:2;25201:6;25198:14;25195:34;;;25225:1;25222;25215:12;25195:34;25263:6;25252:9;25248:22;25238:32;;25308:7;25301:4;25297:2;25293:13;25289:27;25279:55;;25330:1;25327;25320:12;25279:55;25359:2;25353:9;25381:2;25377;25374:10;25371:36;;;25387:18;;:::i;:::-;25427:36;25459:2;25454;25451:1;25447:10;25443:19;25427:36;:::i;:::-;25497:15;;;25528:12;;;;-1:-1:-1;25559:4:23;25598:11;;;25590:20;;25586:29;;;25627:19;;;25624:39;;;25659:1;25656;25649:12;25624:39;25683:11;;;;25703:1130;25719:6;25714:3;25711:15;25703:1130;;;25799:2;25793:3;25784:7;25780:17;25776:26;25773:116;;;25843:1;25872:2;25868;25861:14;25773:116;25915:22;;:::i;:::-;25971:3;25965:10;25988:33;26013:7;25988:33;:::i;:::-;26034:22;;26090:12;;;26084:19;26116:33;26084:19;26116:33;:::i;:::-;26169:14;;;26162:31;26235:12;;;26229:19;26213:14;;;26206:43;26283:12;;;26277:19;26309:33;26277:19;26309:33;:::i;:::-;26362:14;;;26355:31;26409:3;26446:12;;;26440:19;26472:31;26440:19;26472:31;:::i;:::-;26523:14;;;26516:31;26571:3;26611:42;26639:13;;;26611:42;:::i;:::-;26594:15;;;26587:67;26678:3;26718:41;26745:13;;;26718:41;:::i;:::-;26701:15;;;26694:66;26773:18;;25736:12;;;;26811;;;;25703:1130;;;25707:3;26852:5;26842:15;;;;;;;;;24732:2131;;;;;:::o;27215:184::-;27267:77;27264:1;27257:88;27364:4;27361:1;27354:15;27388:4;27385:1;27378:15;27404:247;27463:6;27516:2;27504:9;27495:7;27491:23;27487:32;27484:52;;;27532:1;27529;27522:12;27484:52;27571:9;27558:23;27590:31;27615:5;27590:31;:::i;27965:184::-;28017:77;28014:1;28007:88;28114:4;28111:1;28104:15;28138:4;28135:1;28128:15;28154:195;28193:3;28224:66;28217:5;28214:77;28211:103;;28294:18;;:::i;:::-;-1:-1:-1;28341:1:23;28330:13;;28154:195::o;29365:184::-;29435:6;29488:2;29476:9;29467:7;29463:23;29459:32;29456:52;;;29504:1;29501;29494:12;29456:52;-1:-1:-1;29527:16:23;;29365:184;-1:-1:-1;29365:184:23:o;30498:245::-;30565:6;30618:2;30606:9;30597:7;30593:23;30589:32;30586:52;;;30634:1;30631;30624:12;30586:52;30666:9;30660:16;30685:28;30707:5;30685:28;:::i;31106:1024::-;31198:6;31251:2;31239:9;31230:7;31226:23;31222:32;31219:52;;;31267:1;31264;31257:12;31219:52;31307:9;31294:23;31336:18;31377:2;31369:6;31366:14;31363:34;;;31393:1;31390;31383:12;31363:34;31416:22;;;;31472:4;31454:16;;;31450:27;31447:47;;;31490:1;31487;31480:12;31447:47;31523:2;31517:9;31565:4;31557:6;31553:17;31620:6;31608:10;31605:22;31600:2;31588:10;31585:18;31582:46;31579:72;;;31631:18;;:::i;:::-;31667:2;31660:22;31707:16;;31735;;;31732:36;;;31764:1;31761;31754:12;31732:36;31792:44;31828:7;31817:8;31813:2;31809:17;31792:44;:::i;:::-;31784:6;31777:60;;31880:2;31876;31872:11;31859:25;31846:38;;31893;31925:5;31893:38;:::i;:::-;31964:5;31959:2;31951:6;31947:15;31940:30;32015:2;32011;32007:11;31994:25;31979:40;;32028:30;32050:7;32028:30;:::i;:::-;32086:2;32074:15;;32067:32;;;;-1:-1:-1;32078:6:23;31106:1024;-1:-1:-1;;;31106:1024:23:o;33465:580::-;33542:4;33548:6;33608:11;33595:25;33698:66;33687:8;33671:14;33667:29;33663:102;33643:18;33639:127;33629:155;;33780:1;33777;33770:12;33629:155;33807:33;;33859:20;;;-1:-1:-1;33902:18:23;33891:30;;33888:50;;;33934:1;33931;33924:12;33888:50;33967:4;33955:17;;-1:-1:-1;33998:14:23;33994:27;;;33984:38;;33981:58;;;34035:1;34032;34025:12;34050:271;34233:6;34225;34220:3;34207:33;34189:3;34259:16;;34284:13;;;34259:16;34050:271;-1:-1:-1;34050:271:23:o;34326:648::-;34406:6;34459:2;34447:9;34438:7;34434:23;34430:32;34427:52;;;34475:1;34472;34465:12;34427:52;34508:9;34502:16;34541:18;34533:6;34530:30;34527:50;;;34573:1;34570;34563:12;34527:50;34596:22;;34649:4;34641:13;;34637:27;-1:-1:-1;34627:55:23;;34678:1;34675;34668:12;34627:55;34707:2;34701:9;34732:48;34748:31;34776:2;34748:31;:::i;34732:48::-;34803:2;34796:5;34789:17;34843:7;34838:2;34833;34829;34825:11;34821:20;34818:33;34815:53;;;34864:1;34861;34854:12;34815:53;34877:67;34941:2;34936;34929:5;34925:14;34920:2;34916;34912:11;34877:67;:::i;34979:219::-;35128:2;35117:9;35110:21;35091:4;35148:44;35188:2;35177:9;35173:18;35165:6;35148:44;:::i;35203:810::-;35303:6;35356:3;35344:9;35335:7;35331:23;35327:33;35324:53;;;35373:1;35370;35363:12;35324:53;35399:22;;:::i;:::-;35458:9;35445:23;35477:40;35509:7;35477:40;:::i;:::-;35526:22;;35600:2;35585:18;;35572:32;35613:40;35572:32;35613:40;:::i;:::-;35680:2;35669:14;;35662:31;35745:2;35730:18;;35717:32;35758:40;35717:32;35758:40;:::i;:::-;35825:2;35814:14;;35807:31;35890:2;35875:18;;35862:32;35903:40;35862:32;35903:40;:::i;37063:287::-;37192:3;37230:6;37224:13;37246:66;37305:6;37300:3;37293:4;37285:6;37281:17;37246:66;:::i;:::-;37328:16;;;;;37063:287;-1:-1:-1;;37063:287:23:o;38831:1739::-;39210:25;;;39158:2;39254;39272:18;;;39265:30;;;39183:18;;;39330:22;;;39129:4;;39158:2;39371:3;;39390:18;;;39431:6;39129:4;39465:995;39479:6;39476:1;39473:13;39465:995;;;39554:6;39541:20;39574:29;39597:5;39574:29;:::i;:::-;39639:4;39628:16;39616:29;;39686:15;;;39673:29;39715:31;39673:29;39715:31;:::i;:::-;39791:1;39780:22;39766:12;;;39759:44;39826:4;39871:15;;;39858:29;39900:30;39858:29;39900:30;:::i;:::-;39971:15;39964:23;39950:12;;;39943:45;40029:15;;;40016:29;40058:33;40016:29;40058:33;:::i;:::-;40114:34;40182:16;;;40168:12;;;40161:38;40240:15;;;40227:29;;40269:33;40227:29;40269:33;:::i;:::-;40336:16;40322:12;;;40315:38;40376:4;40400:12;;;;40435:15;;;;;39501:1;39494:9;39465:995;;;39469:3;;40507:9;40502:3;40498:19;40491:4;40480:9;40476:20;40469:49;40535:29;40560:3;40552:6;40535:29;:::i;40920:125::-;40985:9;;;41006:10;;;41003:36;;;41019:18;;:::i;41050:128::-;41117:9;;;41138:11;;;41135:37;;;41152:18;;:::i;42607:243::-;42664:6;42717:2;42705:9;42696:7;42692:23;42688:32;42685:52;;;42733:1;42730;42723:12;42685:52;42772:9;42759:23;42791:29;42814:5;42791:29;:::i

Swarm Source

ipfs://b8014cef1c16d677a941a1f5dcbdb3c48ff496222bea57353bdc03ce08e2ea7b

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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