ETH Price: $2,638.83 (-0.77%)
Gas: 3 Gwei

Contract

0xF5117b5117E49080a5cad6e53A754d49cdCcda7F
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040123757412021-05-05 18:03:581192 days ago1620237838IN
 Create: StakingV1
0 ETH0.3645354268

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StakingV1

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-05-05
*/

/**
 * Copyright 2017-2021, bZeroX, LLC <https://bzx.network/>. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0.
 */

pragma solidity 0.5.17;
pragma experimental ABIEncoderV2;


contract IERC20 {
    string public name;
    uint8 public decimals;
    string public symbol;
    function totalSupply() public view returns (uint256);
    function balanceOf(address _who) public view returns (uint256);
    function allowance(address _owner, address _spender) public view returns (uint256);
    function approve(address _spender, uint256 _value) public returns (bool);
    function transfer(address _to, uint256 _value) public returns (bool);
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

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

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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "unauthorized");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _owner;
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following 
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

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

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

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

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

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b != 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Integer division of two numbers, rounding up and truncating the quotient
    */
    function divCeil(uint256 a, uint256 b) internal pure returns (uint256) {
        return divCeil(a, b, "SafeMath: division by zero");
    }

    /**
    * @dev Integer division of two numbers, rounding up and truncating the quotient
    */
    function divCeil(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b != 0, errorMessage);

        if (a == 0) {
            return 0;
        }
        uint256 c = ((a - 1) / b) + 1;

        return c;
    }

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

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }

    function min256(uint256 _a, uint256 _b) internal pure returns (uint256) {
        return _a < _b ? _a : _b;
    }
}

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

/**
 * @dev Library for managing loan sets
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * Include with `using EnumerableBytes32Set for EnumerableBytes32Set.Bytes32Set;`.
 *
 */
library EnumerableBytes32Set {

    struct Bytes32Set {
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) index;
        bytes32[] values;
    }

    /**
     * @dev Add an address value to a set. O(1).
     * Returns false if the value was already in the set.
     */
    function addAddress(Bytes32Set storage set, address addrvalue)
        internal
        returns (bool)
    {
        bytes32 value;
        assembly {
            value := addrvalue
        }
        return addBytes32(set, value);
    }

    /**
     * @dev Add a value to a set. O(1).
     * Returns false if the value was already in the set.
     */
    function addBytes32(Bytes32Set storage set, bytes32 value)
        internal
        returns (bool)
    {
        if (!contains(set, value)){
            set.index[value] = set.values.push(value);
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes an address value from a set. O(1).
     * Returns false if the value was not present in the set.
     */
    function removeAddress(Bytes32Set storage set, address addrvalue)
        internal
        returns (bool)
    {
        bytes32 value;
        assembly {
            value := addrvalue
        }
        return removeBytes32(set, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     * Returns false if the value was not present in the set.
     */
    function removeBytes32(Bytes32Set storage set, bytes32 value)
        internal
        returns (bool)
    {
        if (contains(set, value)){
            uint256 toDeleteIndex = set.index[value] - 1;
            uint256 lastIndex = set.values.length - 1;

            // If the element we're deleting is the last one, we can just remove it without doing a swap
            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set.values[lastIndex];

                // Move the last value to the index where the deleted value is
                set.values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set.index[lastValue] = toDeleteIndex + 1; // All indexes are 1-based
            }

            // Delete the index entry for the deleted value
            delete set.index[value];

            // Delete the old entry for the moved value
            set.values.pop();

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value)
        internal
        view
        returns (bool)
    {
        return set.index[value] != 0;
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function containsAddress(Bytes32Set storage set, address addrvalue)
        internal
        view
        returns (bool)
    {
        bytes32 value;
        assembly {
            value := addrvalue
        }
        return set.index[value] != 0;
    }

    /**
     * @dev Returns an array with all values in the set. O(N).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.

     * WARNING: This function may run out of gas on large sets: use {length} and
     * {get} instead in these cases.
     */
    function enumerate(Bytes32Set storage set, uint256 start, uint256 count)
        internal
        view
        returns (bytes32[] memory output)
    {
        uint256 end = start + count;
        require(end >= start, "addition overflow");
        end = set.values.length < end ? set.values.length : end;
        if (end == 0 || start >= end) {
            return output;
        }

        output = new bytes32[](end-start);
        for (uint256 i = start; i < end; i++) {
            output[i-start] = set.values[i];
        }
        return output;
    }

    /**
     * @dev Returns the number of elements on the set. O(1).
     */
    function length(Bytes32Set storage set)
        internal
        view
        returns (uint256)
    {
        return set.values.length;
    }

   /** @dev Returns the element stored at position `index` in the set. O(1).
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function get(Bytes32Set storage set, uint256 index)
        internal
        view
        returns (bytes32)
    {
        return set.values[index];
    }

   /** @dev Returns the element stored at position `index` in the set. O(1).
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function getAddress(Bytes32Set storage set, uint256 index)
        internal
        view
        returns (address)
    {
        bytes32 value = set.values[index];
        address addrvalue;
        assembly {
            addrvalue := value
        }
        return addrvalue;
    }
}

contract StakingUpgradeable is Ownable {
    address public implementation;
}

contract StakingState is StakingUpgradeable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using EnumerableBytes32Set for EnumerableBytes32Set.Bytes32Set;

    uint256 public constant initialCirculatingSupply = 1030000000e18 - 889389933e18;
    address internal constant ZERO_ADDRESS = address(0);

    bool public isPaused;

    address public fundsWallet;

    mapping(address => uint256) internal _totalSupplyPerToken;                      // token => value
    mapping(address => mapping(address => uint256)) internal _balancesPerToken;     // token => account => value

    mapping(address => address) public delegate;                                    // user => delegate
    mapping(address => mapping(address => uint256)) public delegatedPerToken;       // token => user => value

    uint256 public bzrxPerTokenStored;
    mapping(address => uint256) public bzrxRewardsPerTokenPaid;                     // user => value
    mapping(address => uint256) public bzrxRewards;                                 // user => value
    mapping(address => uint256) public bzrxVesting;                                 // user => value

    uint256 public stableCoinPerTokenStored;
    mapping(address => uint256) public stableCoinRewardsPerTokenPaid;               // user => value
    mapping(address => uint256) public stableCoinRewards;                           // user => value
    mapping(address => uint256) public stableCoinVesting;                           // user => value

    uint256 public vBZRXWeightStored;
    uint256 public iBZRXWeightStored;
    uint256 public LPTokenWeightStored;

    EnumerableBytes32Set.Bytes32Set internal _delegatedSet;

    uint256 public lastRewardsAddTime;

    mapping(address => uint256) public vestingLastSync;

    mapping(address => address[]) public swapPaths;
    mapping(address => uint256) public stakingRewards;
    uint256 public rewardPercent = 50e18;
    uint256 public maxUniswapDisagreement = 3e18;
    uint256 public maxCurveDisagreement = 3e18;
    uint256 public callerRewardDivisor = 100;

    address[] public currentFeeTokens;
}

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

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

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

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

interface ICurve3Pool {
    function add_liquidity(
        uint256[3] calldata amounts,
        uint256 min_mint_amount)
        external;

    function get_virtual_price()
        external
        view
        returns (uint256);
}

interface IBZxPartial {
    enum FeeClaimType {
        All,
        Lending,
        Trading,
        Borrowing
    }
    
    function withdrawFees(
        address[] calldata tokens,
        address receiver,
        FeeClaimType feeType)
        external
        returns (uint256[] memory amounts);

    function queryFees(
        address[] calldata tokens,
        FeeClaimType feeType)
        external
        view
        returns (uint256[] memory amountsHeld, uint256[] memory amountsPaid);

    function priceFeeds()
        external
        view
        returns (address);
}

contract StakingConstants {

    address public constant BZRX = 0x56d811088235F11C8920698a204A5010a788f4b3;
    address public constant vBZRX = 0xB72B31907C1C95F3650b64b2469e08EdACeE5e8F;
    address public constant iBZRX = 0x18240BD9C07fA6156Ce3F3f61921cC82b2619157;
    address public constant LPToken = 0xe26A220a341EAca116bDa64cF9D5638A935ae629;
    IERC20 public constant curve3Crv = IERC20(0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490);

    address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address public constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
    address public constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
    address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;

    IUniswapV2Router public constant uniswapRouter = IUniswapV2Router(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
    ICurve3Pool public constant curve3pool = ICurve3Pool(0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7);
    IBZxPartial public constant bZx = IBZxPartial(0xD8Ee69652E4e4838f2531732a46d1f7F584F0b7f);

    uint256 public constant cliffDuration =                15768000; // 86400 * 365 * 0.5
    uint256 public constant vestingDuration =              126144000; // 86400 * 365 * 4
    uint256 internal constant vestingDurationAfterCliff =  110376000; // 86400 * 365 * 3.5
    uint256 internal constant vestingStartTimestamp =      1594648800; // start_time
    uint256 internal constant vestingCliffTimestamp =      vestingStartTimestamp + cliffDuration;
    uint256 internal constant vestingEndTimestamp =        vestingStartTimestamp + vestingDuration;
    uint256 internal constant _startingVBZRXBalance =      889389933e18; // 889,389,933 BZRX

    uint256 public constant BZRXWeightStored = 1e18;

    struct DelegatedTokens {
        address user;
        uint256 BZRX;
        uint256 vBZRX;
        uint256 iBZRX;
        uint256 LPToken;
        uint256 totalVotes;
    }

    event Stake(
        address indexed user,
        address indexed token,
        address indexed delegate,
        uint256 amount
    );

    event Unstake(
        address indexed user,
        address indexed token,
        address indexed delegate,
        uint256 amount
    );

    event AddRewards(
        address indexed sender,
        uint256 bzrxAmount,
        uint256 stableCoinAmount
    );

    event Claim(
        address indexed user,
        uint256 bzrxAmount,
        uint256 stableCoinAmount
    );

    event ChangeDelegate(
        address indexed user,
        address indexed oldDelegate,
        address indexed newDelegate
    );

    event WithdrawFees(
        address indexed sender
    );

    event ConvertFees(
        address indexed sender,
        uint256 bzrxOutput,
        uint256 stableCoinOutput
    );

    event DistributeFees(
        address indexed sender,
        uint256 bzrxRewards,
        uint256 stableCoinRewards
    );
}

contract IVestingToken is IERC20 {
    function claim()
        external;

    function vestedBalanceOf(
        address _owner)
        external
        view
        returns (uint256);

    function claimedBalanceOf(
        address _owner)
        external
        view
        returns (uint256);

    function totalVested()
        external
        view
        returns (uint256);
}

interface ILoanPool {
    function tokenPrice()
        external
        view
        returns (uint256 price);

    function borrowInterestRate()
        external
        view
        returns (uint256);

    function totalAssetSupply()
        external
        view
        returns (uint256);

    function assetBalanceOf(
        address _owner)
        external
        view
        returns (uint256);
}

interface IPriceFeeds {
    function queryRate(
        address sourceToken,
        address destToken)
        external
        view
        returns (uint256 rate, uint256 precision);

    function queryPrecision(
        address sourceToken,
        address destToken)
        external
        view
        returns (uint256 precision);

    function queryReturn(
        address sourceToken,
        address destToken,
        uint256 sourceAmount)
        external
        view
        returns (uint256 destAmount);

    function checkPriceDisagreement(
        address sourceToken,
        address destToken,
        uint256 sourceAmount,
        uint256 destAmount,
        uint256 maxSlippage)
        external
        view
        returns (uint256 sourceToDestSwapRate);

    function amountInEth(
        address Token,
        uint256 amount)
        external
        view
        returns (uint256 ethAmount);

    function getMaxDrawdown(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount,
        uint256 maintenanceMargin)
        external
        view
        returns (uint256);

    function getCurrentMarginAndCollateralSize(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount)
        external
        view
        returns (uint256 currentMargin, uint256 collateralInEthAmount);

    function getCurrentMargin(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount)
        external
        view
        returns (uint256 currentMargin, uint256 collateralToLoanRate);

    function shouldLiquidate(
        address loanToken,
        address collateralToken,
        uint256 loanAmount,
        uint256 collateralAmount,
        uint256 maintenanceMargin)
        external
        view
        returns (bool);

    function getFastGasPrice(
        address payToken)
        external
        view
        returns (uint256);
}

contract StakingV1 is StakingState, StakingConstants {

    modifier onlyEOA() {
        require(msg.sender == tx.origin, "unauthorized");
        _;
    }

    modifier checkPause() {
        require(!isPaused, "paused");
        _;
    }

    function stake(
        address[] calldata tokens,
        uint256[] calldata values)
        external
        checkPause
        updateRewards(msg.sender)
    {
        require(tokens.length == values.length, "count mismatch");

        address currentDelegate = delegate[msg.sender];
        if (currentDelegate == address(0)) {
            currentDelegate = msg.sender;
            delegate[msg.sender] = currentDelegate;
            _delegatedSet.addAddress(msg.sender);
        }

        address token;
        uint256 stakeAmount;

        for (uint256 i = 0; i < tokens.length; i++) {
            token = tokens[i];
            require(token == BZRX || token == vBZRX || token == iBZRX || token == LPToken, "invalid token");

            stakeAmount = values[i];
            if (stakeAmount == 0) {
                continue;
            }

            _balancesPerToken[token][msg.sender] = _balancesPerToken[token][msg.sender].add(stakeAmount);
            _totalSupplyPerToken[token] = _totalSupplyPerToken[token].add(stakeAmount);

            delegatedPerToken[currentDelegate][token] = delegatedPerToken[currentDelegate][token]
                .add(stakeAmount);

            IERC20(token).safeTransferFrom(msg.sender, address(this), stakeAmount);

            emit Stake(
                msg.sender,
                token,
                currentDelegate,
                stakeAmount
            );
        }
    }

    function unstake(
        address[] memory tokens,
        uint256[] memory values)
        public
        checkPause
        updateRewards(msg.sender)
    {
        require(tokens.length == values.length, "count mismatch");

        address currentDelegate = delegate[msg.sender];

        address token;
        uint256 unstakeAmount;
        uint256 stakedAmount;
        for (uint256 i = 0; i < tokens.length; i++) {
            token = tokens[i];
            require(token == BZRX || token == vBZRX || token == iBZRX || token == LPToken, "invalid token");

            unstakeAmount = values[i];
            stakedAmount = _balancesPerToken[token][msg.sender];
            if (unstakeAmount == 0 || stakedAmount == 0) {
                continue;
            }
            if (unstakeAmount > stakedAmount) {
                unstakeAmount = stakedAmount;
            }

            _balancesPerToken[token][msg.sender] = stakedAmount - unstakeAmount; // will not overflow
            _totalSupplyPerToken[token] = _totalSupplyPerToken[token] - unstakeAmount; // will not overflow

            uint256 delegatedAmount = delegatedPerToken[currentDelegate][token];
            if (delegatedAmount > unstakeAmount) {
                delegatedPerToken[currentDelegate][token] = delegatedAmount - unstakeAmount;
            } else {
                delegatedPerToken[currentDelegate][token] = 0;
            }

            if (token == BZRX && IERC20(BZRX).balanceOf(address(this)) < unstakeAmount) {
                // settle vested BZRX only if needed
                IVestingToken(vBZRX).claim();
            }

            IERC20(token).safeTransfer(msg.sender, unstakeAmount);

            emit Unstake(
                msg.sender,
                token,
                currentDelegate,
                unstakeAmount
            );
        }
    }

    /*function changeDelegate(
        address delegateToSet)
        external
        checkPause
    {
        if (delegateToSet == ZERO_ADDRESS) {
            delegateToSet = msg.sender;
        }

        address currentDelegate = delegate[msg.sender];
        if (delegateToSet != currentDelegate) {
            if (currentDelegate != ZERO_ADDRESS) {
                uint256 balance = _balancesPerToken[BZRX][msg.sender];
                if (balance != 0) {
                    delegatedPerToken[currentDelegate][BZRX] = delegatedPerToken[currentDelegate][BZRX]
                        .sub(balance);
                    delegatedPerToken[delegateToSet][BZRX] = delegatedPerToken[delegateToSet][BZRX]
                        .add(balance);
                }

                balance = _balancesPerToken[vBZRX][msg.sender];
                if (balance != 0) {
                    delegatedPerToken[currentDelegate][vBZRX] = delegatedPerToken[currentDelegate][vBZRX]
                        .sub(balance);
                    delegatedPerToken[delegateToSet][vBZRX] = delegatedPerToken[delegateToSet][vBZRX]
                        .add(balance);
                }

                balance = _balancesPerToken[iBZRX][msg.sender];
                if (balance != 0) {
                    delegatedPerToken[currentDelegate][iBZRX] = delegatedPerToken[currentDelegate][iBZRX]
                        .sub(balance);
                    delegatedPerToken[delegateToSet][iBZRX] = delegatedPerToken[delegateToSet][iBZRX]
                        .add(balance);
                }

                balance = _balancesPerToken[LPToken][msg.sender];
                if (balance != 0) {
                    delegatedPerToken[currentDelegate][LPToken] = delegatedPerToken[currentDelegate][LPToken]
                        .sub(balance);
                    delegatedPerToken[delegateToSet][LPToken] = delegatedPerToken[delegateToSet][LPToken]
                        .add(balance);
                }
            }

            delegate[msg.sender] = delegateToSet;
            _delegatedSet.addAddress(delegateToSet);

            emit ChangeDelegate(
                msg.sender,
                currentDelegate,
                delegateToSet
            );

            currentDelegate = delegateToSet;
        }
    }*/

    function claim(
        bool restake)
        external
        checkPause
        updateRewards(msg.sender)
        returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned)
    {
        return _claim(restake);
    }

    function claimBzrx()
        external
        checkPause
        updateRewards(msg.sender)
        returns (uint256 bzrxRewardsEarned)
    {
        bzrxRewardsEarned = _claimBzrx(false);

        emit Claim(
            msg.sender,
            bzrxRewardsEarned,
            0
        );
    }

    function claim3Crv()
        external
        checkPause
        updateRewards(msg.sender)
        returns (uint256 stableCoinRewardsEarned)
    {
        stableCoinRewardsEarned = _claim3Crv();

        emit Claim(
            msg.sender,
            0,
            stableCoinRewardsEarned
        );
    }

    function _claim(
        bool restake)
        internal
        returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned)
    {
        bzrxRewardsEarned = _claimBzrx(restake);
        stableCoinRewardsEarned = _claim3Crv();

        emit Claim(
            msg.sender,
            bzrxRewardsEarned,
            stableCoinRewardsEarned
        );
    }

    function _claimBzrx(
        bool restake)
        internal
        returns (uint256 bzrxRewardsEarned)
    {
        bzrxRewardsEarned = bzrxRewards[msg.sender];
        if (bzrxRewardsEarned != 0) {
            bzrxRewards[msg.sender] = 0;
            if (restake) {
                _restakeBZRX(
                    msg.sender,
                    bzrxRewardsEarned
                );
            } else {
                if (IERC20(BZRX).balanceOf(address(this)) < bzrxRewardsEarned) {
                    // settle vested BZRX only if needed
                    IVestingToken(vBZRX).claim();
                }

                IERC20(BZRX).transfer(msg.sender, bzrxRewardsEarned);
            }
        }
    }

    function _claim3Crv()
        internal 
        returns (uint256 stableCoinRewardsEarned)
    {
        stableCoinRewardsEarned = stableCoinRewards[msg.sender];
        if (stableCoinRewardsEarned != 0) {
            stableCoinRewards[msg.sender] = 0;
            curve3Crv.transfer(msg.sender, stableCoinRewardsEarned);
        }
    }

    function _restakeBZRX(
        address account,
        uint256 amount)
        internal
    {
        address currentDelegate = delegate[account];
        _balancesPerToken[BZRX][account] = _balancesPerToken[BZRX][account]
            .add(amount);

        _totalSupplyPerToken[BZRX] = _totalSupplyPerToken[BZRX]
            .add(amount);

        delegatedPerToken[currentDelegate][BZRX] = delegatedPerToken[currentDelegate][BZRX]
            .add(amount);

        emit Stake(
            account,
            BZRX,
            currentDelegate,
            amount
        );
    }

    function exit()
        public
        // unstake() does a checkPause
    {
        address[] memory tokens = new address[](4);
        uint256[] memory values = new uint256[](4);
        tokens[0] = iBZRX;
        tokens[1] = LPToken;
        tokens[2] = vBZRX;
        tokens[3] = BZRX;
        values[0] = uint256(-1);
        values[1] = uint256(-1);
        values[2] = uint256(-1);
        values[3] = uint256(-1);
        
        unstake(tokens, values); // calls updateRewards
        _claim(false);
    }

    /*function getDelegateVotes(
        uint256 start,
        uint256 count)
        external
        view
        returns (DelegatedTokens[] memory delegateArr)
    {
        uint256 end = start.add(count).min256(_delegatedSet.length());
        if (start >= end) {
            return delegateArr;
        }
        count = end-start;

        uint256 idx = count;
        address user;
        delegateArr = new DelegatedTokens[](idx);
        for (uint256 i = --end; i >= start; i--) {
            user = _delegatedSet.getAddress(i);
            delegateArr[count-(idx--)] = DelegatedTokens({
                user: user,
                BZRX: delegatedPerToken[user][BZRX],
                vBZRX: delegatedPerToken[user][vBZRX],
                iBZRX: delegatedPerToken[user][iBZRX],
                LPToken: delegatedPerToken[user][LPToken],
                totalVotes: delegateBalanceOf(user)
            });

            if (i == 0) {
                break;
            }
        }

        if (idx != 0) {
            count -= idx;
            assembly {
                mstore(delegateArr, count)
            }
        }
    }*/

    modifier updateRewards(address account) {
        uint256 _bzrxPerTokenStored = bzrxPerTokenStored;
        uint256 _stableCoinPerTokenStored = stableCoinPerTokenStored;

        (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting) = _earned(
            account,
            _bzrxPerTokenStored,
            _stableCoinPerTokenStored
        );
        bzrxRewardsPerTokenPaid[account] = _bzrxPerTokenStored;
        stableCoinRewardsPerTokenPaid[account] = _stableCoinPerTokenStored;

        // vesting amounts get updated before sync
        bzrxVesting[account] = bzrxRewardsVesting;
        stableCoinVesting[account] = stableCoinRewardsVesting;

        (bzrxRewards[account], stableCoinRewards[account]) = _syncVesting(
            account,
            bzrxRewardsEarned,
            stableCoinRewardsEarned,
            bzrxRewardsVesting,
            stableCoinRewardsVesting
        );
        vestingLastSync[account] = block.timestamp;

        _;
    }

    function earned(
        address account)
        external
        view
        returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting)
    {
        (bzrxRewardsEarned, stableCoinRewardsEarned, bzrxRewardsVesting, stableCoinRewardsVesting) = _earned(
            account,
            bzrxPerTokenStored,
            stableCoinPerTokenStored
        );

        (bzrxRewardsEarned, stableCoinRewardsEarned) = _syncVesting(
            account,
            bzrxRewardsEarned,
            stableCoinRewardsEarned,
            bzrxRewardsVesting,
            stableCoinRewardsVesting
        );

        // discount vesting amounts for vesting time
        uint256 multiplier = vestedBalanceForAmount(
            1e36,
            0,
            block.timestamp
        );
        bzrxRewardsVesting = bzrxRewardsVesting
            .sub(bzrxRewardsVesting
                .mul(multiplier)
                .div(1e36)
            );
        stableCoinRewardsVesting = stableCoinRewardsVesting
            .sub(stableCoinRewardsVesting
                .mul(multiplier)
                .div(1e36)
            );
    }

    function _earned(
        address account,
        uint256 _bzrxPerToken,
        uint256 _stableCoinPerToken)
        internal
        view
        returns (uint256 bzrxRewardsEarned, uint256 stableCoinRewardsEarned, uint256 bzrxRewardsVesting, uint256 stableCoinRewardsVesting)
    {
        uint256 bzrxPerTokenUnpaid = _bzrxPerToken.sub(bzrxRewardsPerTokenPaid[account]);
        uint256 stableCoinPerTokenUnpaid = _stableCoinPerToken.sub(stableCoinRewardsPerTokenPaid[account]);

        bzrxRewardsEarned = bzrxRewards[account];
        stableCoinRewardsEarned = stableCoinRewards[account];
        bzrxRewardsVesting = bzrxVesting[account];
        stableCoinRewardsVesting = stableCoinVesting[account];

        if (bzrxPerTokenUnpaid != 0 || stableCoinPerTokenUnpaid != 0) {
            uint256 value;
            uint256 multiplier;
            uint256 lastSync;

            (uint256 vestedBalance, uint256 vestingBalance) = balanceOfStored(account);

            value = vestedBalance
                .mul(bzrxPerTokenUnpaid);
            value /= 1e36;
            bzrxRewardsEarned = value
                .add(bzrxRewardsEarned);

            value = vestedBalance
                .mul(stableCoinPerTokenUnpaid);
            value /= 1e36;
            stableCoinRewardsEarned = value
                .add(stableCoinRewardsEarned);

            if (vestingBalance != 0 && bzrxPerTokenUnpaid != 0) {
                // add new vesting amount for BZRX
                value = vestingBalance
                    .mul(bzrxPerTokenUnpaid);
                value /= 1e36;
                bzrxRewardsVesting = bzrxRewardsVesting
                    .add(value);

                // true up earned amount to vBZRX vesting schedule
                lastSync = vestingLastSync[account];
                multiplier = vestedBalanceForAmount(
                    1e36,
                    0,
                    lastSync
                );
                value = value
                    .mul(multiplier);
                value /= 1e36;
                bzrxRewardsEarned = bzrxRewardsEarned
                    .add(value);
            }
            if (vestingBalance != 0 && stableCoinPerTokenUnpaid != 0) {
                // add new vesting amount for 3crv
                value = vestingBalance
                    .mul(stableCoinPerTokenUnpaid);
                value /= 1e36;
                stableCoinRewardsVesting = stableCoinRewardsVesting
                    .add(value);

                // true up earned amount to vBZRX vesting schedule
                if (lastSync == 0) {
                    lastSync = vestingLastSync[account];
                    multiplier = vestedBalanceForAmount(
                        1e36,
                        0,
                        lastSync
                    );
                }
                value = value
                    .mul(multiplier);
                value /= 1e36;
                stableCoinRewardsEarned = stableCoinRewardsEarned
                    .add(value);
            }
        }
    }

    function _syncVesting(
        address account,
        uint256 bzrxRewardsEarned,
        uint256 stableCoinRewardsEarned,
        uint256 bzrxRewardsVesting,
        uint256 stableCoinRewardsVesting)
        internal
        view
        returns (uint256, uint256)
    {
        uint256 lastVestingSync = vestingLastSync[account];

        if (lastVestingSync != block.timestamp) {
            uint256 rewardsVested;
            uint256 multiplier = vestedBalanceForAmount(
                1e36,
                lastVestingSync,
                block.timestamp
            );

            if (bzrxRewardsVesting != 0) {
                rewardsVested = bzrxRewardsVesting
                    .mul(multiplier)
                    .div(1e36);
                bzrxRewardsEarned += rewardsVested;
            }

            if (stableCoinRewardsVesting != 0) {
                rewardsVested = stableCoinRewardsVesting
                    .mul(multiplier)
                    .div(1e36);
                stableCoinRewardsEarned += rewardsVested;
            }

            uint256 vBZRXBalance = _balancesPerToken[vBZRX][account];
            if (vBZRXBalance != 0) {
                // add vested BZRX to rewards balance
                rewardsVested = vBZRXBalance
                    .mul(multiplier)
                    .div(1e36);
                bzrxRewardsEarned += rewardsVested;
            }
        }

        return (bzrxRewardsEarned, stableCoinRewardsEarned);
    }

    // note: anyone can contribute rewards to the contract
    function addDirectRewards(
        address[] calldata accounts,
        uint256[] calldata bzrxAmounts,
        uint256[] calldata stableCoinAmounts)
        external
        checkPause
        returns (uint256 bzrxTotal, uint256 stableCoinTotal)
    {
        require(accounts.length == bzrxAmounts.length && accounts.length == stableCoinAmounts.length, "count mismatch");

        for (uint256 i = 0; i < accounts.length; i++) {
            bzrxRewards[accounts[i]] = bzrxRewards[accounts[i]].add(bzrxAmounts[i]);
            bzrxTotal = bzrxTotal.add(bzrxAmounts[i]);
            stableCoinRewards[accounts[i]] = stableCoinRewards[accounts[i]].add(stableCoinAmounts[i]);
            stableCoinTotal = stableCoinTotal.add(stableCoinAmounts[i]);
        }
        if (bzrxTotal != 0) {
            IERC20(BZRX).transferFrom(msg.sender, address(this), bzrxTotal);
        }
        if (stableCoinTotal != 0) {
            curve3Crv.transferFrom(msg.sender, address(this), stableCoinTotal);
        }
    }

    // note: anyone can contribute rewards to the contract
    function addRewards(
        uint256 newBZRX,
        uint256 newStableCoin)
        external
        checkPause
    {
        if (newBZRX != 0 || newStableCoin != 0) {
            _addRewards(newBZRX, newStableCoin);
            if (newBZRX != 0) {
                IERC20(BZRX).transferFrom(msg.sender, address(this), newBZRX);
            }
            if (newStableCoin != 0) {
                curve3Crv.transferFrom(msg.sender, address(this), newStableCoin);
            }
        }
    }

    function _addRewards(
        uint256 newBZRX,
        uint256 newStableCoin)
        internal
    {
        (vBZRXWeightStored, iBZRXWeightStored, LPTokenWeightStored) = getVariableWeights();

        uint256 totalTokens = totalSupplyStored();
        require(totalTokens != 0, "nothing staked");

        bzrxPerTokenStored = newBZRX
            .mul(1e36)
            .div(totalTokens)
            .add(bzrxPerTokenStored);

        stableCoinPerTokenStored = newStableCoin
            .mul(1e36)
            .div(totalTokens)
            .add(stableCoinPerTokenStored);

        lastRewardsAddTime = block.timestamp;

        emit AddRewards(
            msg.sender,
            newBZRX,
            newStableCoin
        );
    }

    function getVariableWeights()
        public
        view
        returns (uint256 vBZRXWeight, uint256 iBZRXWeight, uint256 LPTokenWeight)
    {
        uint256 totalVested = vestedBalanceForAmount(
            _startingVBZRXBalance,
            0,
            block.timestamp
        );

        vBZRXWeight = SafeMath.mul(_startingVBZRXBalance - totalVested, 1e18) // overflow not possible
            .div(_startingVBZRXBalance);

        iBZRXWeight = ILoanPool(iBZRX).tokenPrice();

        uint256 lpTokenSupply = _totalSupplyPerToken[LPToken];
        if (lpTokenSupply != 0) {
            // staked LP tokens are assumed to represent the total unstaked supply (circulated supply - staked BZRX)
            uint256 normalizedLPTokenSupply = initialCirculatingSupply +
                totalVested -
                _totalSupplyPerToken[BZRX];

            LPTokenWeight = normalizedLPTokenSupply
                .mul(1e18)
                .div(lpTokenSupply);
        }
    }

    function balanceOfByAsset(
        address token,
        address account)
        public
        view
        returns (uint256 balance)
    {
        balance = _balancesPerToken[token][account];
    }

    function balanceOfByAssets(
        address account)
        external
        view
        returns (
            uint256 bzrxBalance,
            uint256 iBZRXBalance,
            uint256 vBZRXBalance,
            uint256 LPTokenBalance
        )
    {
        return (
            balanceOfByAsset(BZRX, account),
            balanceOfByAsset(iBZRX, account),
            balanceOfByAsset(vBZRX, account),
            balanceOfByAsset(LPToken, account)
        );
    }

    function balanceOfStored(
        address account)
        public
        view
        returns (uint256 vestedBalance, uint256 vestingBalance)
    {
        uint256 balance = _balancesPerToken[vBZRX][account];
        if (balance != 0) {
            vestingBalance = _balancesPerToken[vBZRX][account]
                    .mul(vBZRXWeightStored)
                    .div(1e18);
        }

        vestedBalance = _balancesPerToken[BZRX][account];

        balance = _balancesPerToken[iBZRX][account];
        if (balance != 0) {
            vestedBalance = balance
                .mul(iBZRXWeightStored)
                .div(1e18)
                .add(vestedBalance);
        }

        balance = _balancesPerToken[LPToken][account];
        if (balance != 0) {
            vestedBalance = balance
                .mul(LPTokenWeightStored)
                .div(1e18)
                .add(vestedBalance);
        }
    }

    function delegateBalanceOf(
        address account)
        public
        view
        returns (uint256 totalVotes)
    {
        uint256 vBZRXBalance = _balancesPerToken[vBZRX][account];
        if (vBZRXBalance != 0) {
            // staked vBZRX counts has 1/2 a vote, that's prorated based on total vested
            totalVotes = vBZRXBalance
                .mul(_startingVBZRXBalance -
                    vestedBalanceForAmount( // overflow not possible
                        _startingVBZRXBalance,
                        0,
                        block.timestamp
                    )
                ).div(_startingVBZRXBalance) / 2;

            // user is attributed a staked balance of vested BZRX, from their last update to the present
            totalVotes = vestedBalanceForAmount(
                vBZRXBalance,
                vestingLastSync[account],
                block.timestamp
            ).add(totalVotes);
        }

        totalVotes = _balancesPerToken[BZRX][account]
            .add(bzrxRewards[account]) // unclaimed BZRX rewards count as votes
            .add(totalVotes);

        totalVotes = _balancesPerToken[iBZRX][account]
            .mul(ILoanPool(iBZRX).tokenPrice())
            .div(1e18)
            .add(totalVotes);

        // LPToken votes are measured based on amount of underlying BZRX staked
        totalVotes = IERC20(BZRX).balanceOf(LPToken)
            .mul(_balancesPerToken[LPToken][account])
            .div(IERC20(LPToken).totalSupply())
            .add(totalVotes);
    }

    function totalSupplyByAsset(
        address token)
        external
        view
        returns (uint256)
    {
        return _totalSupplyPerToken[token];
    }

    function totalSupplyStored()
        public
        view
        returns (uint256 supply)
    {
        supply = _totalSupplyPerToken[vBZRX]
            .mul(vBZRXWeightStored)
            .div(1e18);

        supply = _totalSupplyPerToken[BZRX]
            .add(supply);

        supply = _totalSupplyPerToken[iBZRX]
            .mul(iBZRXWeightStored)
            .div(1e18)
            .add(supply);

        supply = _totalSupplyPerToken[LPToken]
            .mul(LPTokenWeightStored)
            .div(1e18)
            .add(supply);
    }

    function vestedBalanceForAmount(
        uint256 tokenBalance,
        uint256 lastUpdate,
        uint256 vestingEndTime)
        public
        view
        returns (uint256 vested)
    {
        vestingEndTime = vestingEndTime.min256(block.timestamp);
        if (vestingEndTime > lastUpdate) {
            if (vestingEndTime <= vestingCliffTimestamp ||
                lastUpdate >= vestingEndTimestamp) {
                // time cannot be before vesting starts
                // OR all vested token has already been claimed
                return 0;
            }
            if (lastUpdate < vestingCliffTimestamp) {
                // vesting starts at the cliff timestamp
                lastUpdate = vestingCliffTimestamp;
            }
            if (vestingEndTime > vestingEndTimestamp) {
                // vesting ends at the end timestamp
                vestingEndTime = vestingEndTimestamp;
            }

            uint256 timeSinceClaim = vestingEndTime.sub(lastUpdate);
            vested = tokenBalance.mul(timeSinceClaim) / vestingDurationAfterCliff; // will never divide by 0
        }
    }


    // Fee Conversion Logic //

    function sweepFees()
        public
        // sweepFeesByAsset() does checkPause
        returns (uint256 bzrxRewards, uint256 crv3Rewards)
    {
        return sweepFeesByAsset(currentFeeTokens);
    }

    function sweepFeesByAsset(
        address[] memory assets)
        public
        checkPause
        onlyEOA
        returns (uint256 bzrxRewards, uint256 crv3Rewards)
    {
        uint256[] memory amounts = _withdrawFees(assets);
        _convertFees(assets, amounts);
        (bzrxRewards, crv3Rewards) = _distributeFees();
    }

    function _withdrawFees(
        address[] memory assets)
        internal
        returns (uint256[] memory)
    {
        uint256[] memory amounts = bZx.withdrawFees(assets, address(this), IBZxPartial.FeeClaimType.All);

        for (uint256 i = 0; i < assets.length; i++) {
            stakingRewards[assets[i]] = stakingRewards[assets[i]]
                .add(amounts[i]);
        }

        emit WithdrawFees(
            msg.sender
        );

        return amounts;
    }

    function _convertFees(
        address[] memory assets,
        uint256[] memory amounts)
        internal
        returns (uint256 bzrxOutput, uint256 crv3Output)
    {
        require(assets.length == amounts.length, "count mismatch");
 
        IPriceFeeds priceFeeds = IPriceFeeds(bZx.priceFeeds());
        (uint256 bzrxRate,) = priceFeeds.queryRate(
            BZRX,
            WETH
        );
        uint256 maxDisagreement = maxUniswapDisagreement;

        address asset;
        uint256 daiAmount;
        uint256 usdcAmount;
        uint256 usdtAmount;
        for (uint256 i = 0; i < assets.length; i++) {
            asset = assets[i];
            if (asset == BZRX) {
                continue;
            } else if (asset == DAI) {
                daiAmount = daiAmount.add(amounts[i]);
                continue;
            } else if (asset == USDC) {
                usdcAmount = usdcAmount.add(amounts[i]);
                continue;
            } else if (asset == USDT) {
                usdtAmount = usdtAmount.add(amounts[i]);
                continue;
            }

            if (amounts[i] != 0) {
                bzrxOutput += _convertFeeWithUniswap(asset, amounts[i], priceFeeds, bzrxRate, maxDisagreement);
            }
        }
        if (bzrxOutput != 0) {
            stakingRewards[BZRX] += bzrxOutput;
        }

        if (daiAmount != 0 || usdcAmount != 0 || usdtAmount != 0) {
            crv3Output = _convertFeesWithCurve(
                daiAmount,
                usdcAmount,
                usdtAmount
            );
            stakingRewards[address(curve3Crv)] += crv3Output;
        }

        emit ConvertFees(
            msg.sender,
            bzrxOutput,
            crv3Output
        );
    }

    function _distributeFees()
        internal
        returns (uint256 bzrxRewards, uint256 crv3Rewards)
    {
        bzrxRewards = stakingRewards[BZRX];
        crv3Rewards = stakingRewards[address(curve3Crv)];
        if (bzrxRewards != 0 || crv3Rewards != 0) {
            address _fundsWallet = fundsWallet;
            uint256 rewardAmount;
            uint256 callerReward;
            if (bzrxRewards != 0) {
                stakingRewards[BZRX] = 0;

                rewardAmount = bzrxRewards
                    .mul(rewardPercent)
                    .div(1e20);
                IERC20(BZRX).transfer(
                    _fundsWallet,
                    bzrxRewards - rewardAmount
                );
                bzrxRewards = rewardAmount;

                callerReward = bzrxRewards / callerRewardDivisor;
                IERC20(BZRX).transfer(
                    msg.sender,
                    callerReward
                );
                bzrxRewards = bzrxRewards
                    .sub(callerReward);
            }
            if (crv3Rewards != 0) {
                stakingRewards[address(curve3Crv)] = 0;

                rewardAmount = crv3Rewards
                    .mul(rewardPercent)
                    .div(1e20);
                curve3Crv.transfer(
                    _fundsWallet,
                    crv3Rewards - rewardAmount
                );
                crv3Rewards = rewardAmount;

                callerReward = crv3Rewards / callerRewardDivisor;
                curve3Crv.transfer(
                    msg.sender,
                    callerReward
                );
                crv3Rewards = crv3Rewards
                    .sub(callerReward);
            }

            _addRewards(bzrxRewards, crv3Rewards);
        }

        emit DistributeFees(
            msg.sender,
            bzrxRewards,
            crv3Rewards
        );
    }

    function _convertFeeWithUniswap(
        address asset,
        uint256 amount,
        IPriceFeeds priceFeeds,
        uint256 bzrxRate,
        uint256 maxDisagreement)
        internal
        returns (uint256 returnAmount)
    {
        uint256 stakingReward = stakingRewards[asset];
        if (stakingReward != 0) {
            if (amount > stakingReward) {
                amount = stakingReward;
            }
            stakingRewards[asset] = stakingReward
                .sub(amount);

            uint256[] memory amounts = uniswapRouter.swapExactTokensForTokens(
                amount,
                1, // amountOutMin
                swapPaths[asset],
                address(this),
                block.timestamp
            );

            returnAmount = amounts[amounts.length - 1];

            // will revert if disagreement found
            _checkUniDisagreement(
                asset,
                amount,
                returnAmount,
                priceFeeds,
                bzrxRate,
                maxDisagreement
            );
        }
    }

    function _convertFeesWithCurve(
        uint256 daiAmount,
        uint256 usdcAmount,
        uint256 usdtAmount)
        internal
        returns (uint256 returnAmount)
    {
        uint256[3] memory curveAmounts;
        uint256 curveTotal;
        uint256 stakingReward;

        if (daiAmount != 0) {
            stakingReward = stakingRewards[DAI];
            if (stakingReward != 0) {
                if (daiAmount > stakingReward) {
                    daiAmount = stakingReward;
                }
                stakingRewards[DAI] = stakingReward
                    .sub(daiAmount);
                curveAmounts[0] = daiAmount;
                curveTotal = daiAmount;
            }
        }
        if (usdcAmount != 0) {
            stakingReward = stakingRewards[USDC];
            if (stakingReward != 0) {
                if (usdcAmount > stakingReward) {
                    usdcAmount = stakingReward;
                }
                stakingRewards[USDC] = stakingReward
                    .sub(usdcAmount);
                curveAmounts[1] = usdcAmount;
                curveTotal = curveTotal.add(usdcAmount.mul(1e12)); // normalize to 18 decimals
            }
        }
        if (usdtAmount != 0) {
            stakingReward = stakingRewards[USDT];
            if (stakingReward != 0) {
                if (usdtAmount > stakingReward) {
                    usdtAmount = stakingReward;
                }
                stakingRewards[USDT] = stakingReward
                    .sub(usdtAmount);
                curveAmounts[2] = usdtAmount;
                curveTotal = curveTotal.add(usdtAmount.mul(1e12)); // normalize to 18 decimals
            }
        }

        uint256 beforeBalance = curve3Crv.balanceOf(address(this));
        curve3pool.add_liquidity(curveAmounts, 0);

        returnAmount = curve3Crv.balanceOf(address(this)) - beforeBalance;

        // will revert if disagreement found
        _checkCurveDisagreement(
            curveTotal,
            returnAmount,
            maxCurveDisagreement
        );
    }    

    function _checkUniDisagreement(
        address asset,
        uint256 assetAmount,
        uint256 bzrxAmount,
        IPriceFeeds priceFeeds,
        uint256 bzrxRate,
        uint256 maxDisagreement)
        internal
        view
    {
        (uint256 rate, uint256 precision) = priceFeeds.queryRate(
            asset,
            WETH
        );

        rate = rate
            .mul(1e36)
            .div(precision)
            .div(bzrxRate);

        uint256 sourceToDestSwapRate = bzrxAmount
            .mul(1e18)
            .div(assetAmount);

        uint256 spreadValue = sourceToDestSwapRate > rate ?
            sourceToDestSwapRate - rate :
            rate - sourceToDestSwapRate;

        if (spreadValue != 0) {
            spreadValue = spreadValue
                .mul(1e20)
                .div(sourceToDestSwapRate);

            require(
                spreadValue <= maxDisagreement,
                "uniswap price disagreement"
            );
        }
    }

    function _checkCurveDisagreement(
        uint256 sendAmount, // deposit tokens
        uint256 actualReturn, // returned lp token
        uint256 maxDisagreement)
        internal
        view
    {
        uint256 expectedReturn = sendAmount
            .mul(1e18)
            .div(curve3pool.get_virtual_price());

        uint256 spreadValue = actualReturn > expectedReturn ?
            actualReturn - expectedReturn :
            expectedReturn - actualReturn;

        if (spreadValue != 0) {
            spreadValue = spreadValue
                .mul(1e20)
                .div(actualReturn);

            require(
                spreadValue <= maxDisagreement,
                "curve price disagreement"
            );
        }
    }

    // OnlyOwner functions

    function togglePause(
        bool _isPaused)
        external
        onlyOwner
    {
        isPaused = _isPaused;
    }

    function setFundsWallet(
        address _fundsWallet)
        external
        onlyOwner
    {
        fundsWallet = _fundsWallet;
    }

    function setFeeTokens(
        address[] calldata tokens)
        external
        onlyOwner
    {
        currentFeeTokens = tokens;
    }

    // path should start with the asset to swap and end with BZRX
    // only one path allowed per asset
    // ex: asset -> WETH -> BZRX
    function setPaths(
        address[][] calldata paths)
        external
        onlyOwner
    {
        address[] memory path;
        for (uint256 i = 0; i < paths.length; i++) {
            path = paths[i];
            require(path.length >= 2 &&
                path[0] != path[path.length - 1] &&
                path[path.length - 1] == BZRX,
                "invalid path"
            );
            
            // check that the path exists
            uint256[] memory amountsOut = uniswapRouter.getAmountsOut(1e10, path);
            require(amountsOut[amountsOut.length - 1] != 0, "path does not exist");
            
            swapPaths[path[0]] = path;
            IERC20(path[0]).safeApprove(address(uniswapRouter), 0);
            IERC20(path[0]).safeApprove(address(uniswapRouter), uint256(-1));
        }
    }

    function setCurveApproval()
        external
        onlyOwner
    {
        IERC20(DAI).safeApprove(address(curve3pool), 0);
        IERC20(DAI).safeApprove(address(curve3pool), uint256(-1));
        IERC20(USDC).safeApprove(address(curve3pool), 0);
        IERC20(USDC).safeApprove(address(curve3pool), uint256(-1));
        IERC20(USDT).safeApprove(address(curve3pool), 0);
        IERC20(USDT).safeApprove(address(curve3pool), uint256(-1));
    }

    function setRewardPercent(
        uint256 _rewardPercent)
        external
        onlyOwner
    {
        require(_rewardPercent <= 1e20, "value too high");
        rewardPercent = _rewardPercent;
    }

    function setMaxUniswapDisagreement(
        uint256 _maxUniswapDisagreement)
        external
        onlyOwner
    {
        require(_maxUniswapDisagreement != 0, "invalid param");
        maxUniswapDisagreement = _maxUniswapDisagreement;
    }

    function setMaxCurveDisagreement(
        uint256 _maxCurveDisagreement)
        external
        onlyOwner
    {
        require(_maxCurveDisagreement != 0, "invalid param");
        maxCurveDisagreement = _maxCurveDisagreement;
    }

    function setCallerRewardDivisor(
        uint256 _callerRewardDivisor)
        external
        onlyOwner
    {
        require(_callerRewardDivisor != 0, "invalid param");
        callerRewardDivisor = _callerRewardDivisor;
    }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinAmount","type":"uint256"}],"name":"AddRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"oldDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"newDelegate","type":"address"}],"name":"ChangeDelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinAmount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxOutput","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinOutput","type":"uint256"}],"name":"ConvertFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stableCoinRewards","type":"uint256"}],"name":"DistributeFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unstake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"WithdrawFees","type":"event"},{"constant":true,"inputs":[],"name":"BZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DAI","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"LPTokenWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"USDT","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"bzrxAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"stableCoinAmounts","type":"uint256[]"}],"name":"addDirectRewards","outputs":[{"internalType":"uint256","name":"bzrxTotal","type":"uint256"},{"internalType":"uint256","name":"stableCoinTotal","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newBZRX","type":"uint256"},{"internalType":"uint256","name":"newStableCoin","type":"uint256"}],"name":"addRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bZx","outputs":[{"internalType":"contract IBZxPartial","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfByAsset","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfByAssets","outputs":[{"internalType":"uint256","name":"bzrxBalance","type":"uint256"},{"internalType":"uint256","name":"iBZRXBalance","type":"uint256"},{"internalType":"uint256","name":"vBZRXBalance","type":"uint256"},{"internalType":"uint256","name":"LPTokenBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOfStored","outputs":[{"internalType":"uint256","name":"vestedBalance","type":"uint256"},{"internalType":"uint256","name":"vestingBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bzrxPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxRewardsPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bzrxVesting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"callerRewardDivisor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"restake","type":"bool"}],"name":"claim","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claim3Crv","outputs":[{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimBzrx","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cliffDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"currentFeeTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curve3Crv","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"curve3pool","outputs":[{"internalType":"contract ICurve3Pool","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegate","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegateBalanceOf","outputs":[{"internalType":"uint256","name":"totalVotes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"delegatedPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"bzrxRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsEarned","type":"uint256"},{"internalType":"uint256","name":"bzrxRewardsVesting","type":"uint256"},{"internalType":"uint256","name":"stableCoinRewardsVesting","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"exit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fundsWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getVariableWeights","outputs":[{"internalType":"uint256","name":"vBZRXWeight","type":"uint256"},{"internalType":"uint256","name":"iBZRXWeight","type":"uint256"},{"internalType":"uint256","name":"LPTokenWeight","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"iBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"iBZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"initialCirculatingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRewardsAddTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxCurveDisagreement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxUniswapDisagreement","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_callerRewardDivisor","type":"uint256"}],"name":"setCallerRewardDivisor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"setCurveApproval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"setFeeTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_fundsWallet","type":"address"}],"name":"setFundsWallet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxCurveDisagreement","type":"uint256"}],"name":"setMaxCurveDisagreement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxUniswapDisagreement","type":"uint256"}],"name":"setMaxUniswapDisagreement","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[][]","name":"paths","type":"address[][]"}],"name":"setPaths","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_rewardPercent","type":"uint256"}],"name":"setRewardPercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stableCoinPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinRewardsPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinVesting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"stake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapPaths","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"sweepFees","outputs":[{"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"internalType":"uint256","name":"crv3Rewards","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"}],"name":"sweepFeesByAsset","outputs":[{"internalType":"uint256","name":"bzrxRewards","type":"uint256"},{"internalType":"uint256","name":"crv3Rewards","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"_isPaused","type":"bool"}],"name":"togglePause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"totalSupplyByAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupplyStored","outputs":[{"internalType":"uint256","name":"supply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract IUniswapV2Router","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"unstake","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vBZRX","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vBZRXWeightStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenBalance","type":"uint256"},{"internalType":"uint256","name":"lastUpdate","type":"uint256"},{"internalType":"uint256","name":"vestingEndTime","type":"uint256"}],"name":"vestedBalanceForAmount","outputs":[{"internalType":"uint256","name":"vested","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vestingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vestingLastSync","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

60806040526802b5e3af16b18800006018556729a2241af62c00006019819055601a556064601b5560006200003c6001600160e01b036200008c16565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35062000090565b3390565b615df180620000a06000396000f3fe608060405234801561001057600080fd5b50600436106104275760003560e01c806366067a951161022b578063b6d6d88d11610130578063db8bb3a1116100b8578063eb0e8d1a11610087578063eb0e8d1a14610810578063ef1c243a14610818578063f2fde38b14610820578063f30127a514610833578063fc41aa091461083b57610427565b8063db8bb3a1146107e5578063e0bab4c4146107f8578063e53b958d14610800578063e9fad8ee1461080857610427565b8063cf86add5116100ff578063cf86add5146107b2578063d0302051146107c5578063d113b95c146107cd578063d85349f7146107d5578063dae607db146107dd57610427565b8063b6d6d88d14610771578063bcca1e0414610784578063c1c5dd2714610797578063c54e44eb146107aa57610427565b80638caaf9e6116101b3578063a5795eba11610182578063a5795eba14610728578063ad5c46481461073b578063b02eba0514610743578063b187bd2614610756578063b293fdc51461075e57610427565b80638caaf9e6146106e55780638da5cb5b146106f85780638f32d59b146107005780639674a9311461071557610427565b806382a8af15116101fa57806382a8af151461069857806383e02cd8146106ab57806387359ebe146106c257806389a30271146106d557806389ffc781146106dd57610427565b806366067a951461066d578063735de9f7146106755780637f3fd8ba1461067d578063802971a61461069057610427565b80633e9a990a1161033157806357d159c6116102b95780635c19a95c116102885780635c19a95c146106245780635c60da1b146106375780635d727d041461063f578063633e94701461065257806364e39b871461065a57610427565b806357d159c6146105e35780635877b3dd146105f657806359d998051461060957806359dcf5221461061157610427565b8063481153851161030057806348115385146105b0578063499d7f96146105b857806352fb1c9d146105cb57806353a8f1ec146105d3578063547d0738146105db57610427565b80633e9a990a1461056f57806341adca42146105775780634330c2631461058a57806343a468c81461059d57610427565b80631c9c4408116103b45780632d06e5bf116103835780632d06e5bf146105185780632d81a78e146105205780632ee1a86e14610541578063307e85a4146105545780633bb20ece1461056757610427565b80631c9c4408146104e05780631ca97a2d146104e85780631d3e3955146104fb5780632194f3a21461051057610427565b806302dd19d9116103fb57806302dd19d9146104a05780630da47e0a146104a85780631514617e146104bb57806317a1d012146104c357806319e772c2146104d857610427565b80628cc2621461042c5780630114a05e14610458578063011cee361461047857806302baf1b01461048d575b600080fd5b61043f61043a366004614f55565b61084e565b60405161044f9493929190615ba8565b60405180910390f35b61046b610466366004614f55565b610918565b60405161044f9190615b03565b61048061092a565b60405161044f91906158b8565b61046b61049b366004614f55565b610942565b61046b610961565b61046b6104b6366004614f55565b610967565b61046b610979565b6104cb610981565b60405161044f9190615996565b61046b610999565b61046b61099f565b61046b6104f6366004614f55565b6109a5565b61050e610509366004615249565b6109b7565b005b610480610a06565b61046b610a15565b61053361052e36600461520d565b610a24565b60405161044f929190615b7f565b61043f61054f366004614f55565b610b0b565b61050e610562366004615249565b610b92565b61046b610bd8565b61050e610bde565b61046b610585366004614f55565b610d63565b61046b610598366004614f55565b610d75565b61046b6105ab366004614f55565b610d87565b61046b6110db565b61046b6105c6366004614f55565b611202565b61046b611214565b61046b61121a565b610480611220565b61050e6105f136600461520d565b611238565b61050e610604366004614ffb565b61127a565b61046b61157f565b61053361061f366004614f55565b611585565b610480610632366004614f55565b6116ec565b610480611707565b61053361064d366004615148565b611716565b6104cb611790565b61050e610668366004614f55565b6117a8565b61046b6117ee565b6104cb6117f4565b61046b61068b3660046152d4565b61180c565b6104806118ae565b6104806106a6366004615249565b6118c6565b6106b36118ed565b60405161044f93929190615b8d565b61046b6106d0366004614f91565b611a69565b610480611a94565b6104cb611aac565b61050e6106f3366004615249565b611ac4565b610480611b0a565b610708611b1a565b60405161044f9190615988565b61046b610723366004614f55565b611b3e565b6105336107363660046150aa565b611b50565b610480611e3f565b61046b610751366004614f55565b611e57565b610708611e69565b61050e61076c366004614ffb565b611e79565b61046b61077f366004614f91565b611eae565b61050e61079236600461517c565b611ecb565b61050e6107a5366004615249565b612352565b6104806123a4565b61050e6107c036600461503c565b6123bc565b61046b612758565b61053361275e565b61046b6127cc565b61046b6127d3565b6104806107f3366004614fcb565b6127df565b610480612814565b61046b61282c565b61050e61293e565b61046b612b0b565b61046b612b11565b61050e61082e366004614f55565b612c86565b610480612cb6565b61050e610849366004615285565b612cc8565b60008060008061086385600754600b54612e34565b9296509094509250905061087a85858585856130c6565b9094509250600061089a6a0c097ce7bc90715b34b9f160241b824261180c565b90506108da6108cd6a0c097ce7bc90715b34b9f160241b6108c1868563ffffffff6131cb16565b9063ffffffff61320e16565b849063ffffffff61325016565b925061090e6109016a0c097ce7bc90715b34b9f160241b6108c1858563ffffffff6131cb16565b839063ffffffff61325016565b9150509193509193565b60086020526000908152604090205481565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b6001600160a01b0381166000908152600360205260409020545b919050565b601b5481565b600d6020526000908152604090205481565b630784ce0081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b600f5481565b60105481565b60096020526000908152604090205481565b6109bf611b1a565b6109e45760405162461bcd60e51b81526004016109db90615a73565b60405180910390fd5b80610a015760405162461bcd60e51b81526004016109db90615a83565b601a55565b6002546001600160a01b031681565b6a744f570177f475546c000081565b6001546000908190600160a01b900460ff1615610a535760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080610a6c878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610abf87858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055610afb8a613292565b9850985050505050505050915091565b600080600080610b29600080516020615d2f83398151915286611a69565b610b477318240bd9c07fa6156ce3f3f61921cc82b261915787611a69565b610b6573b72b31907c1c95f3650b64b2469e08edacee5e8f88611a69565b610b8373e26a220a341eaca116bda64cf9d5638a935ae62989611a69565b93509350935093509193509193565b610b9a611b1a565b610bb65760405162461bcd60e51b81526004016109db90615a73565b80610bd35760405162461bcd60e51b81526004016109db90615a83565b601b55565b600b5481565b610be6611b1a565b610c025760405162461bcd60e51b81526004016109db90615a73565b610c3c736b175474e89094c44da98b954eedeac495271d0f73bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600063ffffffff6132f216565b610c77736b175474e89094c44da98b954eedeac495271d0f73bebc44782c7db0a1a60cb6fe97d0b483032ff1c760001963ffffffff6132f216565b610cb173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600063ffffffff6132f216565b610cec73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873bebc44782c7db0a1a60cb6fe97d0b483032ff1c760001963ffffffff6132f216565b610d2673dac17f958d2ee523a2206206994597c13d831ec773bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600063ffffffff6132f216565b610d6173dac17f958d2ee523a2206206994597c13d831ec773bebc44782c7db0a1a60cb6fe97d0b483032ff1c760001963ffffffff6132f216565b565b600e6020526000908152604090205481565b600a6020526000908152604090205481565b6001600160a01b0381166000908152600080516020615d6f83398151915260205260408120548015610e48576002610dfb6b02dfafa4e0948fa0719400006108c1610de06b02dfafa4e0948fa07194000060004261180c565b85906b02dfafa4e0948fa0719400000363ffffffff6131cb16565b81610e0257fe5b049150610e4582610e398360156000886001600160a01b03166001600160a01b03168152602001908152602001600020544261180c565b9063ffffffff6133ef16565b91505b6001600160a01b038316600090815260096020908152604080832054600080516020615d4f83398151915290925290912054610e89918491610e39916133ef565b9150610f6782610e39670de0b6b3a76400006108c17318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b0316637ff9b5966040518163ffffffff1660e01b815260040160206040518083038186803b158015610eeb57600080fd5b505afa158015610eff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f239190810190615267565b6001600160a01b03891660009081527fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c760205260409020549063ffffffff6131cb16565b91506110d482610e3973e26a220a341eaca116bda64cf9d5638a935ae6296001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fbd57600080fd5b505afa158015610fd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ff59190810190615267565b6001600160a01b03871660009081527f2b99f9ddbab8aac550ca8d7e4f266bf08c26f285c5c72de065cbb397b67b82486020526040908190205490516370a0823160e01b81526108c19190600080516020615d2f833981519152906370a08231906110789073e26a220a341eaca116bda64cf9d5638a935ae629906004016158b8565b60206040518083038186803b15801561109057600080fd5b505afa1580156110a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110c89190810190615267565b9063ffffffff6131cb16565b9392505050565b600154600090600160a01b900460ff16156111085760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080611121878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061117487858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091529081204290556111b290613414565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf78960006040516111f0929190615b11565b60405180910390a25050505050505090565b60176020526000908152604090205481565b60115481565b601a5481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b611240611b1a565b61125c5760405162461bcd60e51b81526004016109db90615a73565b60018054911515600160a01b0260ff60a01b19909216919091179055565b611282611b1a565b61129e5760405162461bcd60e51b81526004016109db90615a73565b606060005b82811015611579578383828181106112b757fe5b602002820190508035601e19368490030181126112d357600080fd5b909101602081019150356001600160401b038111156112f157600080fd5b60208102360382131561130357600080fd5b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508251929450505060021180159061138657508160018351038151811061135457fe5b60200260200101516001600160a01b03168260008151811061137257fe5b60200260200101516001600160a01b031614155b80156113c85750600080516020615d2f8339815191526001600160a01b0316826001845103815181106113b557fe5b60200260200101516001600160a01b0316145b6113e45760405162461bcd60e51b81526004016109db90615a33565b60405163d06ca61f60e01b8152606090737a250d5630b4cf539739df2c5dacb4c659f2488d9063d06ca61f90611425906402540be4009087906004016159b2565b60006040518083038186803b15801561143d57600080fd5b505afa158015611451573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261147991908101906151d9565b90508060018251038151811061148b57fe5b6020026020010151600014156114b35760405162461bcd60e51b81526004016109db90615aa3565b8260166000856000815181106114c557fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000209080519060200190611500929190614c76565b50611548737a250d5630b4cf539739df2c5dacb4c659f2488d60008560008151811061152857fe5b60200260200101516001600160a01b03166132f29092919063ffffffff16565b611570737a250d5630b4cf539739df2c5dacb4c659f2488d6000198560008151811061152857fe5b506001016112a3565b50505050565b60195481565b6001600160a01b0381166000908152600080516020615d6f8339815191526020526040812054819080156115fc57600f546001600160a01b0385166000908152600080516020615d6f83398151915260205260409020546115f991670de0b6b3a7640000916108c19163ffffffff6131cb16565b91505b506001600160a01b0383166000908152600080516020615d4f83398151915260209081526040808320547fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c790925290912054909250801561167f5761167c83610e39670de0b6b3a76400006108c1601054866131cb90919063ffffffff16565b92505b506001600160a01b03831660009081527f2b99f9ddbab8aac550ca8d7e4f266bf08c26f285c5c72de065cbb397b67b8248602052604090205480156116e6576116e383610e39670de0b6b3a76400006108c1601154866131cb90919063ffffffff16565b92505b50915091565b6005602052600090815260409020546001600160a01b031681565b6001546001600160a01b031681565b6001546000908190600160a01b900460ff16156117455760405162461bcd60e51b81526004016109db90615ab3565b3332146117645760405162461bcd60e51b81526004016109db90615a73565b606061176f846135cb565b905061177b848261373c565b5050611785613b27565b909590945092505050565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b6117b0611b1a565b6117cc5760405162461bcd60e51b81526004016109db90615a73565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60145481565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b600061181e824263ffffffff613f4616565b9150828211156110d457635ffd02a08211158061183f575063669136e08310155b1561184c575060006110d4565b635ffd02a083101561186057635ffd02a092505b63669136e08211156118745763669136e091505b6000611886838563ffffffff61325016565b9050630694344061189d868363ffffffff6131cb16565b816118a457fe5b0495945050505050565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b601c81815481106118d357fe5b6000918252602090912001546001600160a01b0316905081565b60008060008061190b6b02dfafa4e0948fa07194000060004261180c565b905061193d6b02dfafa4e0948fa0719400006108c1836b02dfafa4e0948fa07194000003670de0b6b3a76400006131cb565b93507318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b0316637ff9b5966040518163ffffffff1660e01b815260040160206040518083038186803b15801561198c57600080fd5b505afa1580156119a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119c49190810190615267565b73e26a220a341eaca116bda64cf9d5638a935ae62960005260036020527f8341f36a1c413f2034fb483b56344c972362456414155a77c5d31e601f1c02a4549093508015611a6257600080516020615d2f8339815191526000526003602052600080516020615d8f8339815191525482036a744f570177f475546c000001611a5e826108c183670de0b6b3a764000063ffffffff6131cb16565b9350505b5050909192565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b611acc611b1a565b611ae85760405162461bcd60e51b81526004016109db90615a73565b80611b055760405162461bcd60e51b81526004016109db90615a83565b601955565b6000546001600160a01b03165b90565b600080546001600160a01b0316611b2f613f5c565b6001600160a01b031614905090565b60156020526000908152604090205481565b6001546000908190600160a01b900460ff1615611b7f5760405162461bcd60e51b81526004016109db90615ab3565b8685148015611b8d57508683145b611ba95760405162461bcd60e51b81526004016109db90615a23565b60005b87811015611d0f57611c15878783818110611bc357fe5b90506020020135600960008c8c86818110611bda57fe5b9050602002016020611bef9190810190614f55565b6001600160a01b031681526020810191909152604001600020549063ffffffff6133ef16565b600960008b8b85818110611c2557fe5b9050602002016020611c3a9190810190614f55565b6001600160a01b03168152602081019190915260400160002055611c79878783818110611c6357fe5b90506020020135846133ef90919063ffffffff16565b9250611ca1858583818110611c8a57fe5b90506020020135600d60008c8c86818110611bda57fe5b600d60008b8b85818110611cb157fe5b9050602002016020611cc69190810190614f55565b6001600160a01b03168152602081019190915260400160002055611d05858583818110611cef57fe5b90506020020135836133ef90919063ffffffff16565b9150600101611bac565b508115611d9f576040516323b872dd60e01b8152600080516020615d2f833981519152906323b872dd90611d4b903390309087906004016158c6565b602060405180830381600087803b158015611d6557600080fd5b505af1158015611d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d9d919081019061522b565b505b8015611e34576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90611de0903390309086906004016158c6565b602060405180830381600087803b158015611dfa57600080fd5b505af1158015611e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e32919081019061522b565b505b965096945050505050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c6020526000908152604090205481565b600154600160a01b900460ff1681565b611e81611b1a565b611e9d5760405162461bcd60e51b81526004016109db90615a73565b611ea9601c8383614cd7565b505050565b600660209081526000928352604080842090915290825290205481565b600154600160a01b900460ff1615611ef55760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080611f0e878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050611f6187858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152204290558751895114611fb55760405162461bcd60e51b81526004016109db90615a23565b336000908152600560205260408120546001600160a01b0316908080805b8d51811015612342578d8181518110611fe857fe5b60200260200101519350600080516020615d2f8339815191526001600160a01b0316846001600160a01b0316148061203c57506001600160a01b03841673b72b31907c1c95f3650b64b2469e08edacee5e8f145b8061206357506001600160a01b0384167318240bd9c07fa6156ce3f3f61921cc82b2619157145b8061208a57506001600160a01b03841673e26a220a341eaca116bda64cf9d5638a935ae629145b6120a65760405162461bcd60e51b81526004016109db90615a63565b8c81815181106120b257fe5b6020908102919091018101516001600160a01b0386166000908152600483526040808220338352909352919091205490935091508215806120f1575081155b156120fb5761233a565b81831115612107578192505b6001600160a01b0380851660008181526004602090815260408083203384528252808320888803905583835260038252808320805489900390559389168252600681528382209282529190915220548381111561218d576001600160a01b03808716600090815260066020908152604080832093891683529290522084820390556121b6565b6001600160a01b0380871660009081526006602090815260408083209389168352929052908120555b6001600160a01b038516600080516020615d2f83398151915214801561225c57506040516370a0823160e01b81528490600080516020615d2f833981519152906370a082319061220a9030906004016158b8565b60206040518083038186803b15801561222257600080fd5b505afa158015612236573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061225a9190810190615267565b105b156122c95773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156122b057600080fd5b505af11580156122c4573d6000803e3d6000fd5b505050505b6122e36001600160a01b038616338663ffffffff613f6016565b856001600160a01b0316856001600160a01b0316336001600160a01b03167f2cbcd809a4c90d11f8d12c4b6d09986b255ae1e68f54f076c145fbb2185904e1876040516123309190615b03565b60405180910390a4505b600101611fd3565b5050505050505050505050505050565b61235a611b1a565b6123765760405162461bcd60e51b81526004016109db90615a73565b68056bc75e2d6310000081111561239f5760405162461bcd60e51b81526004016109db90615a43565b601855565b73dac17f958d2ee523a2206206994597c13d831ec781565b600154600160a01b900460ff16156123e65760405162461bcd60e51b81526004016109db90615ab3565b600754600b5433919060008080806123ff878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061245287858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152204290558988146124a45760405162461bcd60e51b81526004016109db90615a23565b336000908152600560205260409020546001600160a01b0316806124f5575033600081815260056020526040902080546001600160a01b031916821790556124f360128263ffffffff613f8216565b505b600080805b8d811015612747578e8e8281811061250e57fe5b90506020020160206125239190810190614f55565b92506001600160a01b038316600080516020615d2f833981519152148061256657506001600160a01b03831673b72b31907c1c95f3650b64b2469e08edacee5e8f145b8061258d57506001600160a01b0383167318240bd9c07fa6156ce3f3f61921cc82b2619157145b806125b457506001600160a01b03831673e26a220a341eaca116bda64cf9d5638a935ae629145b6125d05760405162461bcd60e51b81526004016109db90615a63565b8c8c828181106125dc57fe5b90506020020135915081600014156125f35761273f565b6001600160a01b0383166000908152600460209081526040808320338452909152902054612627908363ffffffff6133ef16565b6001600160a01b038416600081815260046020908152604080832033845282528083209490945591815260039091522054612668908363ffffffff6133ef16565b6001600160a01b03808516600081815260036020908152604080832095909555928816815260068352838120918152915220546126ab908363ffffffff6133ef16565b6001600160a01b038086166000908152600660209081526040808320938816808452939091529020919091556126e99033308563ffffffff613f9716565b836001600160a01b0316836001600160a01b0316336001600160a01b03167fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd7856040516127369190615b03565b60405180910390a45b6001016124fa565b505050505050505050505050505050565b60185481565b6000806127c4601c8054806020026020016040519081016040528092919081815260200182805480156127ba57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161279c575b5050505050611716565b915091509091565b62f099c081565b670de0b6b3a764000081565b601660205281600052604060002081815481106127f857fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b600154600090600160a01b900460ff16156128595760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080612872878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e9091529020819055929650909450925090506128c587858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055612900613fbb565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf760008a6040516111f09291906159a4565b60408051600480825260a0820190925260609160208201608080388339505060408051600480825260a082019092529293506060929150602082016080803883390190505090507318240bd9c07fa6156ce3f3f61921cc82b2619157826000815181106129a757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073e26a220a341eaca116bda64cf9d5638a935ae629826001815181106129e957fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073b72b31907c1c95f3650b64b2469e08edacee5e8f82600281518110612a2b57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600080516020615d2f83398151915282600381518110612a6757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060001981600081518110612a9757fe5b60200260200101818152505060001981600181518110612ab357fe5b60200260200101818152505060001981600281518110612acf57fe5b60200260200101818152505060001981600381518110612aeb57fe5b602002602001018181525050612b018282611ecb565b6115796000613292565b60075481565b600f5473b72b31907c1c95f3650b64b2469e08edacee5e8f600090815260036020527ffcfc5d57a009157202436965eb7c01b14f1b51f705a3b4f08296120160c5e109549091612b7591670de0b6b3a7640000916108c1919063ffffffff6131cb16565b600080516020615d2f8339815191526000526003602052600080516020615d8f83398151915254909150612baf908263ffffffff6133ef16565b6010547318240bd9c07fa6156ce3f3f61921cc82b261915760005260036020527f91de0462b01273d0819ee89d2f822b745d4b4dcc3d05d8e0d13f841abd34e4a254919250612c18918391610e3991670de0b6b3a7640000916108c1919063ffffffff6131cb16565b60115473e26a220a341eaca116bda64cf9d5638a935ae62960005260036020527f8341f36a1c413f2034fb483b56344c972362456414155a77c5d31e601f1c02a454919250612c81918391610e3991670de0b6b3a7640000916108c1919063ffffffff6131cb16565b905090565b612c8e611b1a565b612caa5760405162461bcd60e51b81526004016109db90615a73565b612cb381614071565b50565b600080516020615d2f83398151915281565b600154600160a01b900460ff1615612cf25760405162461bcd60e51b81526004016109db90615ab3565b81151580612cff57508015155b15612e3057612d0e82826140f2565b8115612d9d576040516323b872dd60e01b8152600080516020615d2f833981519152906323b872dd90612d49903390309087906004016158c6565b602060405180830381600087803b158015612d6357600080fd5b505af1158015612d77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d9b919081019061522b565b505b8015612e30576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90612dde903390309086906004016158c6565b602060405180830381600087803b158015612df857600080fd5b505af1158015612e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ea9919081019061522b565b5050565b6001600160a01b0383166000908152600860205260408120548190819081908190612e6690889063ffffffff61325016565b6001600160a01b0389166000908152600c602052604081205491925090612e9490889063ffffffff61325016565b6001600160a01b038a16600090815260096020908152604080832054600d835281842054600a845282852054600e9094529190932054929950975095509350905081151580612ee257508015155b156130bb576000806000806000612ef88e611585565b9092509050612f0d828863ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b90049450612f2a858c6133ef565b9a50612f3c828763ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b90049450612f59858b6133ef565b99508015801590612f6957508615155b1561300657612f7e818863ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b90049450612f9b89866133ef565b6001600160a01b038f16600090815260156020526040812054919a50909350612fd4906a0c097ce7bc90715b34b9f160241b908561180c565b9350612fe6858563ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b900494506130038b866133ef565b9a505b801580159061301457508515155b156130b557613029818763ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b9004945061304688866133ef565b975082613085576001600160a01b038e166000908152601560205260408120549350613082906a0c097ce7bc90715b34b9f160241b908561180c565b93505b613095858563ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b900494506130b28a866133ef565b99505b50505050505b505093509350935093565b6001600160a01b03851660009081526015602052604081205481904281146131bd576000806131046a0c097ce7bc90715b34b9f160241b844261180c565b905086156131355761312e6a0c097ce7bc90715b34b9f160241b6108c1898463ffffffff6131cb16565b9889019891505b85156131645761315d6a0c097ce7bc90715b34b9f160241b6108c1888463ffffffff6131cb16565b9788019791505b6001600160a01b038a166000908152600080516020615d6f833981519152602052604090205480156131b9576131b26a0c097ce7bc90715b34b9f160241b6108c1838563ffffffff6131cb16565b998a019992505b5050505b509496939550929350505050565b6000826131da57506000613208565b828202828482816131e757fe5b04146132055760405162461bcd60e51b81526004016109db90615a53565b90505b92915050565b600061320583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506141c9565b600061320583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506141f6565b60008061329e83613414565b91506132a8613fbb565b9050336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf783836040516132e5929190615b7f565b60405180910390a2915091565b80158061337a5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906133289030908690600401615909565b60206040518083038186803b15801561334057600080fd5b505afa158015613354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506133789190810190615267565b155b6133965760405162461bcd60e51b81526004016109db90615ac3565b604051611ea990849063095ea7b360e01b906133b89086908690602401615932565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614222565b6000828201838110156132055760405162461bcd60e51b81526004016109db90615a03565b33600090815260096020526040902054801561095c5733600090815260096020526040812055811561344f5761344a3382614307565b61095c565b6040516370a0823160e01b81528190600080516020615d2f833981519152906370a08231906134829030906004016158b8565b60206040518083038186803b15801561349a57600080fd5b505afa1580156134ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506134d29190810190615267565b10156135405773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561352757600080fd5b505af115801561353b573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b8152600080516020615d2f8339815191529063a9059cbb9061357390339085906004016158ee565b602060405180830381600087803b15801561358d57600080fd5b505af11580156135a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506135c5919081019061522b565b50919050565b604051633360d3df60e01b8152606090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f90633360d3df9061360c9086903090600090600401615940565b600060405180830381600087803b15801561362657600080fd5b505af115801561363a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261366291908101906151d9565b905060005b835181101561370a576136ce82828151811061367f57fe5b60200260200101516017600087858151811061369757fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546133ef90919063ffffffff16565b601760008684815181106136de57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101613667565b5060405133907fd3719f04262b628e1d01a6ed24707f542cda51f144b5271149c7d0419436d00c90600090a292915050565b60008082518451146137605760405162461bcd60e51b81526004016109db90615a23565b600073d8ee69652e4e4838f2531732a46d1f7f584f0b7f6001600160a01b03166378d849ed6040518163ffffffff1660e01b815260040160206040518083038186803b1580156137af57600080fd5b505afa1580156137c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506137e79190810190614f73565b90506000816001600160a01b03166329d5277c600080516020615d2f83398151915273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b815260040161383b929190615909565b604080518083038186803b15801561385257600080fd5b505afa158015613866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061388a91908101906152a4565b506019549091506000808080805b8b51811015613a22578b81815181106138ad57fe5b60200260200101519450600080516020615d2f8339815191526001600160a01b0316856001600160a01b031614156138e457613a1a565b6001600160a01b038516736b175474e89094c44da98b954eedeac495271d0f14156139365761392f8b828151811061391857fe5b6020026020010151856133ef90919063ffffffff16565b9350613a1a565b6001600160a01b03851673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481415613988576139818b828151811061396a57fe5b6020026020010151846133ef90919063ffffffff16565b9250613a1a565b6001600160a01b03851673dac17f958d2ee523a2206206994597c13d831ec714156139da576139d38b82815181106139bc57fe5b6020026020010151836133ef90919063ffffffff16565b9150613a1a565b8a81815181106139e657fe5b6020026020010151600014613a1a57613a15858c8381518110613a0557fe5b60200260200101518a8a8a614472565b8a0199505b600101613898565b508815613a6857600080516020615d2f83398151915260005260176020527fcf37870b726aadbba698d60193b30d07c7c9b39dc1bdaf83e993b9a0358a185680548a0190555b82151580613a7557508115155b80613a7f57508015155b15613ad657613a8f83838361459f565b736c3f90f043a72fa612cbac8115ee7e52bde6e49060005260176020527f407fe9863bf74082c6026154acd61fbcd964905841c0baf42e63cbc49aec164e80548201905597505b336001600160a01b03167f4532d391b3bfa0cfb0b4e8b6d8c2c972a12ddb43658ed59378f340da2082ee5e8a8a604051613b11929190615b7f565b60405180910390a2505050505050509250929050565b60176020527fcf37870b726aadbba698d60193b30d07c7c9b39dc1bdaf83e993b9a0358a185654736c3f90f043a72fa612cbac8115ee7e52bde6e4906000527f407fe9863bf74082c6026154acd61fbcd964905841c0baf42e63cbc49aec164e5481151580613b9557508015155b15613eff576002546001600160a01b03166000808415613d4457600080516020615d2f833981519152600090815260176020527fcf37870b726aadbba698d60193b30d07c7c9b39dc1bdaf83e993b9a0358a185655601854613c0d9068056bc75e2d63100000906108c190889063ffffffff6131cb16565b60405163a9059cbb60e01b8152909250600080516020615d2f8339815191529063a9059cbb90613c45908690868a0390600401615932565b602060405180830381600087803b158015613c5f57600080fd5b505af1158015613c73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613c97919081019061522b565b50819450601b548581613ca657fe5b60405163a9059cbb60e01b81529190049150600080516020615d2f8339815191529063a9059cbb90613cde90339085906004016158ee565b602060405180830381600087803b158015613cf857600080fd5b505af1158015613d0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613d30919081019061522b565b50613d41858263ffffffff61325016565b94505b8315613ef157736c3f90f043a72fa612cbac8115ee7e52bde6e490600090815260176020527f407fe9863bf74082c6026154acd61fbcd964905841c0baf42e63cbc49aec164e55601854613dae9068056bc75e2d63100000906108c190879063ffffffff6131cb16565b60405163a9059cbb60e01b8152909250736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb90613dec90869086890390600401615932565b602060405180830381600087803b158015613e0657600080fd5b505af1158015613e1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e3e919081019061522b565b50819350601b548481613e4d57fe5b60405163a9059cbb60e01b81529190049150736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb90613e8b90339085906004016158ee565b602060405180830381600087803b158015613ea557600080fd5b505af1158015613eb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613edd919081019061522b565b50613eee848263ffffffff61325016565b93505b613efb85856140f2565b5050505b336001600160a01b03167f0d01c94d0df28276fb43f8bfa77a79b387742823fa1189417aca8b82afff77018383604051613f3a929190615b7f565b60405180910390a29091565b6000818310613f555781613205565b5090919050565b3390565b604051611ea990849063a9059cbb60e01b906133b89086908690602401615932565b600081613f8f8482614992565b949350505050565b6040516115799085906323b872dd60e01b906133b890879087908790602401615924565b336000908152600d60205260409020548015611b1757336000818152600d6020526040808220919091555163a9059cbb60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e4909163a9059cbb9161401b919085906004016158ee565b602060405180830381600087803b15801561403557600080fd5b505af1158015614049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061406d919081019061522b565b5090565b6001600160a01b0381166140975760405162461bcd60e51b81526004016109db906159e3565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6140fa6118ed565b601155601055600f55600061410d612b11565b90508061412c5760405162461bcd60e51b81526004016109db90615ae3565b60075461415590610e39836108c1876a0c097ce7bc90715b34b9f160241b63ffffffff6131cb16565b600755600b5461418190610e39836108c1866a0c097ce7bc90715b34b9f160241b63ffffffff6131cb16565b600b554260145560405133907fc88fd69bfa06d2cb1591f4ddd5ebede37737856a00d499e4f51e60984dc13d36906141bc9086908690615b7f565b60405180910390a2505050565b600081836141ea5760405162461bcd60e51b81526004016109db91906159d2565b5060008385816118a457fe5b6000818484111561421a5760405162461bcd60e51b81526004016109db91906159d2565b505050900390565b614234826001600160a01b03166149da565b6142505760405162461bcd60e51b81526004016109db90615ad3565b60006060836001600160a01b03168360405161426c91906158ac565b6000604051808303816000865af19150503d80600081146142a9576040519150601f19603f3d011682016040523d82523d6000602084013e6142ae565b606091505b5091509150816142d05760405162461bcd60e51b81526004016109db90615a13565b80511561157957808060200190516142eb919081019061522b565b6115795760405162461bcd60e51b81526004016109db90615a93565b6001600160a01b03828116600090815260056020908152604080832054600080516020615d4f8339815191529092529091205491169061434790836133ef565b6001600160a01b0384166000908152600080516020615d4f83398151915260209081526040822092909255600080516020615d2f833981519152905260039052600080516020615d8f833981519152546143a7908363ffffffff6133ef16565b600080516020615d8f833981519152556001600160a01b0381166000908152600660209081526040808320600080516020615d2f83398151915284529091529020546143f9908363ffffffff6133ef16565b6001600160a01b038083166000818152600660209081526040808320600080516020615d2f83398151915280855292529182902094909455519092918616907fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd790614465908790615b03565b60405180910390a4505050565b6001600160a01b0385166000908152601760205260408120548015614595578086111561449d578095505b6144ad818763ffffffff61325016565b6001600160a01b0388166000908152601760209081526040808320939093556016905281902090516338ed173960e01b8152606091737a250d5630b4cf539739df2c5dacb4c659f2488d916338ed173991614513918b9160019130904290600401615b2c565b600060405180830381600087803b15801561452d57600080fd5b505af1158015614541573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261456991908101906151d9565b90508060018251038151811061457b57fe5b60200260200101519250614593888885898989614a13565b505b5095945050505050565b60006145a9614d2a565b600080861561465a5750736b175474e89094c44da98b954eedeac495271d0f60005260176020527f8a7776df4a477673730b069fb077ae9d41f7bea257426d6b72fb302b3979395754801561465a5780871115614604578096505b614614818863ffffffff61325016565b736b175474e89094c44da98b954eedeac495271d0f60005260176020527f8a7776df4a477673730b069fb077ae9d41f7bea257426d6b72fb302b39793957558683528691505b8515614732575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260176020527f4b6771a61dd4db37ea6cdd97ea00e948fd53713047d03a3f5e754778f387848c54801561473257808611156146b2578095505b6146c2818763ffffffff61325016565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260176020527f4b6771a61dd4db37ea6cdd97ea00e948fd53713047d03a3f5e754778f387848c5585836001602002015261472f6147228764e8d4a5100063ffffffff6131cb16565b839063ffffffff6133ef16565b91505b84156147f5575073dac17f958d2ee523a2206206994597c13d831ec760005260176020527ff446947c7ecc245e49a695979bfdbedf62c5b3f50cecc135097a55d829f984f55480156147f5578085111561478a578094505b61479a818663ffffffff61325016565b73dac17f958d2ee523a2206206994597c13d831ec760005260176020527ff446947c7ecc245e49a695979bfdbedf62c5b3f50cecc135097a55d829f984f555604083018590526147f26147228664e8d4a510006131cb565b91505b6040516370a0823160e01b8152600090736c3f90f043a72fa612cbac8115ee7e52bde6e490906370a082319061482f9030906004016158b8565b60206040518083038186803b15801561484757600080fd5b505afa15801561485b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061487f9190810190615267565b604051634515cef360e01b815290915073bebc44782c7db0a1a60cb6fe97d0b483032ff1c790634515cef3906148bc90879060009060040161596d565b600060405180830381600087803b1580156148d657600080fd5b505af11580156148ea573d6000803e3d6000fd5b50506040516370a0823160e01b8152839250736c3f90f043a72fa612cbac8115ee7e52bde6e49091506370a08231906149279030906004016158b8565b60206040518083038186803b15801561493f57600080fd5b505afa158015614953573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506149779190810190615267565b0394506149878386601a54614b5a565b505050509392505050565b600061499e8383614c61565b6149d25750600180830180548083018083556000928352602080842090920185905584835290859052604090912055613208565b506000613208565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613f8f575050151592915050565b600080846001600160a01b03166329d5277c8973c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b8152600401614a58929190615909565b604080518083038186803b158015614a6f57600080fd5b505afa158015614a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250614aa791908101906152a4565b9092509050614ad0846108c18381866a0c097ce7bc90715b34b9f160241b63ffffffff6131cb16565b91506000614af0886108c189670de0b6b3a764000063ffffffff6131cb16565b90506000838211614b0357818403614b07565b8382035b90508015614b4e57614b2c826108c18368056bc75e2d6310000063ffffffff6131cb16565b905084811115614b4e5760405162461bcd60e51b81526004016109db90615af3565b50505050505050505050565b6000614bfc73bebc44782c7db0a1a60cb6fe97d0b483032ff1c76001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b158015614bac57600080fd5b505afa158015614bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250614be49190810190615267565b6108c186670de0b6b3a764000063ffffffff6131cb16565b90506000818411614c0f57838203614c13565b8184035b90508015614c5a57614c38846108c18368056bc75e2d6310000063ffffffff6131cb16565b905082811115614c5a5760405162461bcd60e51b81526004016109db906159f3565b5050505050565b60009081526020919091526040902054151590565b828054828255906000526020600020908101928215614ccb579160200282015b82811115614ccb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614c96565b5061406d929150614d48565b828054828255906000526020600020908101928215614ccb579160200282015b82811115614ccb5781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614cf7565b60405180606001604052806003906020820280388339509192915050565b611b1791905b8082111561406d5780546001600160a01b0319168155600101614d4e565b803561320881615d08565b805161320881615d08565b60008083601f840112614d9457600080fd5b5081356001600160401b03811115614dab57600080fd5b602083019150836020820283011115614dc357600080fd5b9250929050565b600082601f830112614ddb57600080fd5b8135614dee614de982615c0c565b615be6565b91508181835260208401935060208101905083856020840282011115614e1357600080fd5b60005b83811015614e3f5781614e298882614d6c565b8452506020928301929190910190600101614e16565b5050505092915050565b600082601f830112614e5a57600080fd5b8135614e68614de982615c0c565b91508181835260208401935060208101905083856020840282011115614e8d57600080fd5b60005b83811015614e3f5781614ea38882614f3f565b8452506020928301929190910190600101614e90565b600082601f830112614eca57600080fd5b8151614ed8614de982615c0c565b91508181835260208401935060208101905083856020840282011115614efd57600080fd5b60005b83811015614e3f5781614f138882614f4a565b8452506020928301929190910190600101614f00565b803561320881615d1c565b805161320881615d1c565b803561320881615d25565b805161320881615d25565b600060208284031215614f6757600080fd5b6000613f8f8484614d6c565b600060208284031215614f8557600080fd5b6000613f8f8484614d77565b60008060408385031215614fa457600080fd5b6000614fb08585614d6c565b9250506020614fc185828601614d6c565b9150509250929050565b60008060408385031215614fde57600080fd5b6000614fea8585614d6c565b9250506020614fc185828601614f3f565b6000806020838503121561500e57600080fd5b82356001600160401b0381111561502457600080fd5b61503085828601614d82565b92509250509250929050565b6000806000806040858703121561505257600080fd5b84356001600160401b0381111561506857600080fd5b61507487828801614d82565b945094505060208501356001600160401b0381111561509257600080fd5b61509e87828801614d82565b95989497509550505050565b600080600080600080606087890312156150c357600080fd5b86356001600160401b038111156150d957600080fd5b6150e589828a01614d82565b965096505060208701356001600160401b0381111561510357600080fd5b61510f89828a01614d82565b945094505060408701356001600160401b0381111561512d57600080fd5b61513989828a01614d82565b92509250509295509295509295565b60006020828403121561515a57600080fd5b81356001600160401b0381111561517057600080fd5b613f8f84828501614dca565b6000806040838503121561518f57600080fd5b82356001600160401b038111156151a557600080fd5b6151b185828601614dca565b92505060208301356001600160401b038111156151cd57600080fd5b614fc185828601614e49565b6000602082840312156151eb57600080fd5b81516001600160401b0381111561520157600080fd5b613f8f84828501614eb9565b60006020828403121561521f57600080fd5b6000613f8f8484614f29565b60006020828403121561523d57600080fd5b6000613f8f8484614f34565b60006020828403121561525b57600080fd5b6000613f8f8484614f3f565b60006020828403121561527957600080fd5b6000613f8f8484614f4a565b6000806040838503121561529857600080fd5b6000614fea8585614f3f565b600080604083850312156152b757600080fd5b60006152c38585614f4a565b9250506020614fc185828601614f4a565b6000806000606084860312156152e957600080fd5b60006152f58686614f3f565b935050602061530686828701614f3f565b925050604061531786828701614f3f565b9150509250925092565b600061532d8383615350565b505060200190565b600061532d83836158a3565b61534a81615c81565b82525050565b61534a81615c67565b600061536482615c3e565b61536e8185615c52565b935061537983615c2c565b8060005b838110156153a75781516153918882615321565b975061539c83615c2c565b92505060010161537d565b509495945050505050565b60006153bd82615c42565b6153c78185615c52565b93506153d283615c32565b8060005b838110156153a7576153e782615ce8565b6153f18882615321565b97506153fc83615c4c565b9250506001016153d6565b61541081615c46565b61541a818461095c565b925061542582611b17565b8060005b8381101561545357815161543d8782615335565b965061544883615c2c565b925050600101615429565b505050505050565b61534a81615c72565b600061546f82615c3e565b615479818561095c565b9350615489818560208601615ca9565b9290920192915050565b61534a81615c88565b61534a81615c93565b61534a81615c9e565b60006154b982615c3e565b6154c38185615c52565b93506154d3818560208601615ca9565b6154dc81615cf4565b9093019392505050565b60006154f3602683615c52565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b600061553b601883615c52565b7f63757276652070726963652064697361677265656d656e740000000000000000815260200192915050565b6000615574601b83615c52565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b60006155ad602083615c52565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b60006155e6600e83615c52565b6d0c6deeadce840dad2e6dac2e8c6d60931b815260200192915050565b6000615610600c83615c52565b6b0d2dcecc2d8d2c840e0c2e8d60a31b815260200192915050565b6000615638600e83615c52565b6d0ecc2d8eaca40e8dede40d0d2ced60931b815260200192915050565b6000615662602183615c52565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006156a5600d83615c52565b6c34b73b30b634b2103a37b5b2b760991b815260200192915050565b60006156ce600c83615c52565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b60006156f6600d83615c52565b6c696e76616c696420706172616d60981b815260200192915050565b600061571f602a83615c52565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b600061576b601383615c52565b721c185d1a08191bd95cc81b9bdd08195e1a5cdd606a1b815260200192915050565b600061579a600683615c52565b651c185d5cd95960d21b815260200192915050565b60006157bc603683615c52565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f81527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b602082015260400192915050565b6000615814601f83615c52565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b600061584d600e83615c52565b6d1b9bdd1a1a5b99c81cdd185ad95960921b815260200192915050565b6000615877601a83615c52565b7f756e69737761702070726963652064697361677265656d656e74000000000000815260200192915050565b61534a81611b17565b60006110d48284615464565b602081016132088284615350565b606081016158d48286615341565b6158e16020830185615350565b613f8f60408301846158a3565b604081016158fc8285615341565b6110d460208301846158a3565b604081016159178285615350565b6110d46020830184615350565b606081016158d48286615350565b604081016158fc8285615350565b606080825281016159518186615359565b90506159606020830185615350565b613f8f604083018461549c565b6080810161597b8285615407565b6110d460608301846154a5565b60208101613208828461545b565b602081016132088284615493565b604081016158fc82856154a5565b604081016159c082856154a5565b8181036020830152613f8f8184615359565b6020808252810161320581846154ae565b60208082528101613208816154e6565b602080825281016132088161552e565b6020808252810161320881615567565b60208082528101613208816155a0565b60208082528101613208816155d9565b6020808252810161320881615603565b602080825281016132088161562b565b6020808252810161320881615655565b6020808252810161320881615698565b60208082528101613208816156c1565b60208082528101613208816156e9565b6020808252810161320881615712565b602080825281016132088161575e565b602080825281016132088161578d565b60208082528101613208816157af565b6020808252810161320881615807565b6020808252810161320881615840565b602080825281016132088161586a565b6020810161320882846158a3565b60408101615b1f82856158a3565b6110d460208301846154a5565b60a08101615b3a82886158a3565b615b4760208301876154a5565b8181036040830152615b5981866153b2565b9050615b686060830185615350565b615b7560808301846158a3565b9695505050505050565b604081016158fc82856158a3565b60608101615b9b82866158a3565b6158e160208301856158a3565b60808101615bb682876158a3565b615bc360208301866158a3565b615bd060408301856158a3565b615bdd60608301846158a3565b95945050505050565b6040518181016001600160401b0381118282101715615c0457600080fd5b604052919050565b60006001600160401b03821115615c2257600080fd5b5060209081020190565b60200190565b60009081526020902090565b5190565b5490565b50600390565b60010190565b90815260200190565b6001600160a01b031690565b600061320882615c5b565b151590565b8061095c81615cfe565b6000613208825b600061320882615c67565b600061320882615c77565b600061320882611b17565b60005b83811015615cc4578181015183820152602001615cac565b838111156115795750506000910152565b6000613208615ce383611b17565b615c5b565b60006132088254615cd5565b601f01601f191690565b60048110612cb357fe5b615d1181615c67565b8114612cb357600080fd5b615d1181615c72565b615d1181611b1756fe00000000000000000000000056d811088235f11c8920698a204a5010a788f4b31e38d77566003d7f728cfa677ad07e8283e5607bd89a929ee98c93eba12048732ce56405c0c0b7d532a6d76ebaf14a8d190d60f3be61dae6890d68141a9cc6f826822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc389411621671a365627a7a7231582087df8006a8f10f4032ff4d4bb599504cbb6e2164ae637a956d0b9080e73b88606c6578706572696d656e74616cf564736f6c63430005110040

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106104275760003560e01c806366067a951161022b578063b6d6d88d11610130578063db8bb3a1116100b8578063eb0e8d1a11610087578063eb0e8d1a14610810578063ef1c243a14610818578063f2fde38b14610820578063f30127a514610833578063fc41aa091461083b57610427565b8063db8bb3a1146107e5578063e0bab4c4146107f8578063e53b958d14610800578063e9fad8ee1461080857610427565b8063cf86add5116100ff578063cf86add5146107b2578063d0302051146107c5578063d113b95c146107cd578063d85349f7146107d5578063dae607db146107dd57610427565b8063b6d6d88d14610771578063bcca1e0414610784578063c1c5dd2714610797578063c54e44eb146107aa57610427565b80638caaf9e6116101b3578063a5795eba11610182578063a5795eba14610728578063ad5c46481461073b578063b02eba0514610743578063b187bd2614610756578063b293fdc51461075e57610427565b80638caaf9e6146106e55780638da5cb5b146106f85780638f32d59b146107005780639674a9311461071557610427565b806382a8af15116101fa57806382a8af151461069857806383e02cd8146106ab57806387359ebe146106c257806389a30271146106d557806389ffc781146106dd57610427565b806366067a951461066d578063735de9f7146106755780637f3fd8ba1461067d578063802971a61461069057610427565b80633e9a990a1161033157806357d159c6116102b95780635c19a95c116102885780635c19a95c146106245780635c60da1b146106375780635d727d041461063f578063633e94701461065257806364e39b871461065a57610427565b806357d159c6146105e35780635877b3dd146105f657806359d998051461060957806359dcf5221461061157610427565b8063481153851161030057806348115385146105b0578063499d7f96146105b857806352fb1c9d146105cb57806353a8f1ec146105d3578063547d0738146105db57610427565b80633e9a990a1461056f57806341adca42146105775780634330c2631461058a57806343a468c81461059d57610427565b80631c9c4408116103b45780632d06e5bf116103835780632d06e5bf146105185780632d81a78e146105205780632ee1a86e14610541578063307e85a4146105545780633bb20ece1461056757610427565b80631c9c4408146104e05780631ca97a2d146104e85780631d3e3955146104fb5780632194f3a21461051057610427565b806302dd19d9116103fb57806302dd19d9146104a05780630da47e0a146104a85780631514617e146104bb57806317a1d012146104c357806319e772c2146104d857610427565b80628cc2621461042c5780630114a05e14610458578063011cee361461047857806302baf1b01461048d575b600080fd5b61043f61043a366004614f55565b61084e565b60405161044f9493929190615ba8565b60405180910390f35b61046b610466366004614f55565b610918565b60405161044f9190615b03565b61048061092a565b60405161044f91906158b8565b61046b61049b366004614f55565b610942565b61046b610961565b61046b6104b6366004614f55565b610967565b61046b610979565b6104cb610981565b60405161044f9190615996565b61046b610999565b61046b61099f565b61046b6104f6366004614f55565b6109a5565b61050e610509366004615249565b6109b7565b005b610480610a06565b61046b610a15565b61053361052e36600461520d565b610a24565b60405161044f929190615b7f565b61043f61054f366004614f55565b610b0b565b61050e610562366004615249565b610b92565b61046b610bd8565b61050e610bde565b61046b610585366004614f55565b610d63565b61046b610598366004614f55565b610d75565b61046b6105ab366004614f55565b610d87565b61046b6110db565b61046b6105c6366004614f55565b611202565b61046b611214565b61046b61121a565b610480611220565b61050e6105f136600461520d565b611238565b61050e610604366004614ffb565b61127a565b61046b61157f565b61053361061f366004614f55565b611585565b610480610632366004614f55565b6116ec565b610480611707565b61053361064d366004615148565b611716565b6104cb611790565b61050e610668366004614f55565b6117a8565b61046b6117ee565b6104cb6117f4565b61046b61068b3660046152d4565b61180c565b6104806118ae565b6104806106a6366004615249565b6118c6565b6106b36118ed565b60405161044f93929190615b8d565b61046b6106d0366004614f91565b611a69565b610480611a94565b6104cb611aac565b61050e6106f3366004615249565b611ac4565b610480611b0a565b610708611b1a565b60405161044f9190615988565b61046b610723366004614f55565b611b3e565b6105336107363660046150aa565b611b50565b610480611e3f565b61046b610751366004614f55565b611e57565b610708611e69565b61050e61076c366004614ffb565b611e79565b61046b61077f366004614f91565b611eae565b61050e61079236600461517c565b611ecb565b61050e6107a5366004615249565b612352565b6104806123a4565b61050e6107c036600461503c565b6123bc565b61046b612758565b61053361275e565b61046b6127cc565b61046b6127d3565b6104806107f3366004614fcb565b6127df565b610480612814565b61046b61282c565b61050e61293e565b61046b612b0b565b61046b612b11565b61050e61082e366004614f55565b612c86565b610480612cb6565b61050e610849366004615285565b612cc8565b60008060008061086385600754600b54612e34565b9296509094509250905061087a85858585856130c6565b9094509250600061089a6a0c097ce7bc90715b34b9f160241b824261180c565b90506108da6108cd6a0c097ce7bc90715b34b9f160241b6108c1868563ffffffff6131cb16565b9063ffffffff61320e16565b849063ffffffff61325016565b925061090e6109016a0c097ce7bc90715b34b9f160241b6108c1858563ffffffff6131cb16565b839063ffffffff61325016565b9150509193509193565b60086020526000908152604090205481565b73e26a220a341eaca116bda64cf9d5638a935ae62981565b6001600160a01b0381166000908152600360205260409020545b919050565b601b5481565b600d6020526000908152604090205481565b630784ce0081565b73bebc44782c7db0a1a60cb6fe97d0b483032ff1c781565b600f5481565b60105481565b60096020526000908152604090205481565b6109bf611b1a565b6109e45760405162461bcd60e51b81526004016109db90615a73565b60405180910390fd5b80610a015760405162461bcd60e51b81526004016109db90615a83565b601a55565b6002546001600160a01b031681565b6a744f570177f475546c000081565b6001546000908190600160a01b900460ff1615610a535760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080610a6c878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050610abf87858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055610afb8a613292565b9850985050505050505050915091565b600080600080610b29600080516020615d2f83398151915286611a69565b610b477318240bd9c07fa6156ce3f3f61921cc82b261915787611a69565b610b6573b72b31907c1c95f3650b64b2469e08edacee5e8f88611a69565b610b8373e26a220a341eaca116bda64cf9d5638a935ae62989611a69565b93509350935093509193509193565b610b9a611b1a565b610bb65760405162461bcd60e51b81526004016109db90615a73565b80610bd35760405162461bcd60e51b81526004016109db90615a83565b601b55565b600b5481565b610be6611b1a565b610c025760405162461bcd60e51b81526004016109db90615a73565b610c3c736b175474e89094c44da98b954eedeac495271d0f73bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600063ffffffff6132f216565b610c77736b175474e89094c44da98b954eedeac495271d0f73bebc44782c7db0a1a60cb6fe97d0b483032ff1c760001963ffffffff6132f216565b610cb173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600063ffffffff6132f216565b610cec73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4873bebc44782c7db0a1a60cb6fe97d0b483032ff1c760001963ffffffff6132f216565b610d2673dac17f958d2ee523a2206206994597c13d831ec773bebc44782c7db0a1a60cb6fe97d0b483032ff1c7600063ffffffff6132f216565b610d6173dac17f958d2ee523a2206206994597c13d831ec773bebc44782c7db0a1a60cb6fe97d0b483032ff1c760001963ffffffff6132f216565b565b600e6020526000908152604090205481565b600a6020526000908152604090205481565b6001600160a01b0381166000908152600080516020615d6f83398151915260205260408120548015610e48576002610dfb6b02dfafa4e0948fa0719400006108c1610de06b02dfafa4e0948fa07194000060004261180c565b85906b02dfafa4e0948fa0719400000363ffffffff6131cb16565b81610e0257fe5b049150610e4582610e398360156000886001600160a01b03166001600160a01b03168152602001908152602001600020544261180c565b9063ffffffff6133ef16565b91505b6001600160a01b038316600090815260096020908152604080832054600080516020615d4f83398151915290925290912054610e89918491610e39916133ef565b9150610f6782610e39670de0b6b3a76400006108c17318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b0316637ff9b5966040518163ffffffff1660e01b815260040160206040518083038186803b158015610eeb57600080fd5b505afa158015610eff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f239190810190615267565b6001600160a01b03891660009081527fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c760205260409020549063ffffffff6131cb16565b91506110d482610e3973e26a220a341eaca116bda64cf9d5638a935ae6296001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fbd57600080fd5b505afa158015610fd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ff59190810190615267565b6001600160a01b03871660009081527f2b99f9ddbab8aac550ca8d7e4f266bf08c26f285c5c72de065cbb397b67b82486020526040908190205490516370a0823160e01b81526108c19190600080516020615d2f833981519152906370a08231906110789073e26a220a341eaca116bda64cf9d5638a935ae629906004016158b8565b60206040518083038186803b15801561109057600080fd5b505afa1580156110a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506110c89190810190615267565b9063ffffffff6131cb16565b9392505050565b600154600090600160a01b900460ff16156111085760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080611121878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061117487858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d8352818420949094559390925560159091529081204290556111b290613414565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf78960006040516111f0929190615b11565b60405180910390a25050505050505090565b60176020526000908152604090205481565b60115481565b601a5481565b73b72b31907c1c95f3650b64b2469e08edacee5e8f81565b611240611b1a565b61125c5760405162461bcd60e51b81526004016109db90615a73565b60018054911515600160a01b0260ff60a01b19909216919091179055565b611282611b1a565b61129e5760405162461bcd60e51b81526004016109db90615a73565b606060005b82811015611579578383828181106112b757fe5b602002820190508035601e19368490030181126112d357600080fd5b909101602081019150356001600160401b038111156112f157600080fd5b60208102360382131561130357600080fd5b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250508251929450505060021180159061138657508160018351038151811061135457fe5b60200260200101516001600160a01b03168260008151811061137257fe5b60200260200101516001600160a01b031614155b80156113c85750600080516020615d2f8339815191526001600160a01b0316826001845103815181106113b557fe5b60200260200101516001600160a01b0316145b6113e45760405162461bcd60e51b81526004016109db90615a33565b60405163d06ca61f60e01b8152606090737a250d5630b4cf539739df2c5dacb4c659f2488d9063d06ca61f90611425906402540be4009087906004016159b2565b60006040518083038186803b15801561143d57600080fd5b505afa158015611451573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261147991908101906151d9565b90508060018251038151811061148b57fe5b6020026020010151600014156114b35760405162461bcd60e51b81526004016109db90615aa3565b8260166000856000815181106114c557fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000209080519060200190611500929190614c76565b50611548737a250d5630b4cf539739df2c5dacb4c659f2488d60008560008151811061152857fe5b60200260200101516001600160a01b03166132f29092919063ffffffff16565b611570737a250d5630b4cf539739df2c5dacb4c659f2488d6000198560008151811061152857fe5b506001016112a3565b50505050565b60195481565b6001600160a01b0381166000908152600080516020615d6f8339815191526020526040812054819080156115fc57600f546001600160a01b0385166000908152600080516020615d6f83398151915260205260409020546115f991670de0b6b3a7640000916108c19163ffffffff6131cb16565b91505b506001600160a01b0383166000908152600080516020615d4f83398151915260209081526040808320547fe09f1b989ce5e55474fdfb6ab6036e5e02e6f44d8729816a39308c55c71b13c790925290912054909250801561167f5761167c83610e39670de0b6b3a76400006108c1601054866131cb90919063ffffffff16565b92505b506001600160a01b03831660009081527f2b99f9ddbab8aac550ca8d7e4f266bf08c26f285c5c72de065cbb397b67b8248602052604090205480156116e6576116e383610e39670de0b6b3a76400006108c1601154866131cb90919063ffffffff16565b92505b50915091565b6005602052600090815260409020546001600160a01b031681565b6001546001600160a01b031681565b6001546000908190600160a01b900460ff16156117455760405162461bcd60e51b81526004016109db90615ab3565b3332146117645760405162461bcd60e51b81526004016109db90615a73565b606061176f846135cb565b905061177b848261373c565b5050611785613b27565b909590945092505050565b73d8ee69652e4e4838f2531732a46d1f7f584f0b7f81565b6117b0611b1a565b6117cc5760405162461bcd60e51b81526004016109db90615a73565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60145481565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b600061181e824263ffffffff613f4616565b9150828211156110d457635ffd02a08211158061183f575063669136e08310155b1561184c575060006110d4565b635ffd02a083101561186057635ffd02a092505b63669136e08211156118745763669136e091505b6000611886838563ffffffff61325016565b9050630694344061189d868363ffffffff6131cb16565b816118a457fe5b0495945050505050565b7318240bd9c07fa6156ce3f3f61921cc82b261915781565b601c81815481106118d357fe5b6000918252602090912001546001600160a01b0316905081565b60008060008061190b6b02dfafa4e0948fa07194000060004261180c565b905061193d6b02dfafa4e0948fa0719400006108c1836b02dfafa4e0948fa07194000003670de0b6b3a76400006131cb565b93507318240bd9c07fa6156ce3f3f61921cc82b26191576001600160a01b0316637ff9b5966040518163ffffffff1660e01b815260040160206040518083038186803b15801561198c57600080fd5b505afa1580156119a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506119c49190810190615267565b73e26a220a341eaca116bda64cf9d5638a935ae62960005260036020527f8341f36a1c413f2034fb483b56344c972362456414155a77c5d31e601f1c02a4549093508015611a6257600080516020615d2f8339815191526000526003602052600080516020615d8f8339815191525482036a744f570177f475546c000001611a5e826108c183670de0b6b3a764000063ffffffff6131cb16565b9350505b5050909192565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205490565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b736c3f90f043a72fa612cbac8115ee7e52bde6e49081565b611acc611b1a565b611ae85760405162461bcd60e51b81526004016109db90615a73565b80611b055760405162461bcd60e51b81526004016109db90615a83565b601955565b6000546001600160a01b03165b90565b600080546001600160a01b0316611b2f613f5c565b6001600160a01b031614905090565b60156020526000908152604090205481565b6001546000908190600160a01b900460ff1615611b7f5760405162461bcd60e51b81526004016109db90615ab3565b8685148015611b8d57508683145b611ba95760405162461bcd60e51b81526004016109db90615a23565b60005b87811015611d0f57611c15878783818110611bc357fe5b90506020020135600960008c8c86818110611bda57fe5b9050602002016020611bef9190810190614f55565b6001600160a01b031681526020810191909152604001600020549063ffffffff6133ef16565b600960008b8b85818110611c2557fe5b9050602002016020611c3a9190810190614f55565b6001600160a01b03168152602081019190915260400160002055611c79878783818110611c6357fe5b90506020020135846133ef90919063ffffffff16565b9250611ca1858583818110611c8a57fe5b90506020020135600d60008c8c86818110611bda57fe5b600d60008b8b85818110611cb157fe5b9050602002016020611cc69190810190614f55565b6001600160a01b03168152602081019190915260400160002055611d05858583818110611cef57fe5b90506020020135836133ef90919063ffffffff16565b9150600101611bac565b508115611d9f576040516323b872dd60e01b8152600080516020615d2f833981519152906323b872dd90611d4b903390309087906004016158c6565b602060405180830381600087803b158015611d6557600080fd5b505af1158015611d79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d9d919081019061522b565b505b8015611e34576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90611de0903390309086906004016158c6565b602060405180830381600087803b158015611dfa57600080fd5b505af1158015611e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611e32919081019061522b565b505b965096945050505050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600c6020526000908152604090205481565b600154600160a01b900460ff1681565b611e81611b1a565b611e9d5760405162461bcd60e51b81526004016109db90615a73565b611ea9601c8383614cd7565b505050565b600660209081526000928352604080842090915290825290205481565b600154600160a01b900460ff1615611ef55760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080611f0e878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e909152902081905592965090945092509050611f6187858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152204290558751895114611fb55760405162461bcd60e51b81526004016109db90615a23565b336000908152600560205260408120546001600160a01b0316908080805b8d51811015612342578d8181518110611fe857fe5b60200260200101519350600080516020615d2f8339815191526001600160a01b0316846001600160a01b0316148061203c57506001600160a01b03841673b72b31907c1c95f3650b64b2469e08edacee5e8f145b8061206357506001600160a01b0384167318240bd9c07fa6156ce3f3f61921cc82b2619157145b8061208a57506001600160a01b03841673e26a220a341eaca116bda64cf9d5638a935ae629145b6120a65760405162461bcd60e51b81526004016109db90615a63565b8c81815181106120b257fe5b6020908102919091018101516001600160a01b0386166000908152600483526040808220338352909352919091205490935091508215806120f1575081155b156120fb5761233a565b81831115612107578192505b6001600160a01b0380851660008181526004602090815260408083203384528252808320888803905583835260038252808320805489900390559389168252600681528382209282529190915220548381111561218d576001600160a01b03808716600090815260066020908152604080832093891683529290522084820390556121b6565b6001600160a01b0380871660009081526006602090815260408083209389168352929052908120555b6001600160a01b038516600080516020615d2f83398151915214801561225c57506040516370a0823160e01b81528490600080516020615d2f833981519152906370a082319061220a9030906004016158b8565b60206040518083038186803b15801561222257600080fd5b505afa158015612236573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061225a9190810190615267565b105b156122c95773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156122b057600080fd5b505af11580156122c4573d6000803e3d6000fd5b505050505b6122e36001600160a01b038616338663ffffffff613f6016565b856001600160a01b0316856001600160a01b0316336001600160a01b03167f2cbcd809a4c90d11f8d12c4b6d09986b255ae1e68f54f076c145fbb2185904e1876040516123309190615b03565b60405180910390a4505b600101611fd3565b5050505050505050505050505050565b61235a611b1a565b6123765760405162461bcd60e51b81526004016109db90615a73565b68056bc75e2d6310000081111561239f5760405162461bcd60e51b81526004016109db90615a43565b601855565b73dac17f958d2ee523a2206206994597c13d831ec781565b600154600160a01b900460ff16156123e65760405162461bcd60e51b81526004016109db90615ab3565b600754600b5433919060008080806123ff878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e90915290208190559296509094509250905061245287858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d835281842094909455939092556015909152204290558988146124a45760405162461bcd60e51b81526004016109db90615a23565b336000908152600560205260409020546001600160a01b0316806124f5575033600081815260056020526040902080546001600160a01b031916821790556124f360128263ffffffff613f8216565b505b600080805b8d811015612747578e8e8281811061250e57fe5b90506020020160206125239190810190614f55565b92506001600160a01b038316600080516020615d2f833981519152148061256657506001600160a01b03831673b72b31907c1c95f3650b64b2469e08edacee5e8f145b8061258d57506001600160a01b0383167318240bd9c07fa6156ce3f3f61921cc82b2619157145b806125b457506001600160a01b03831673e26a220a341eaca116bda64cf9d5638a935ae629145b6125d05760405162461bcd60e51b81526004016109db90615a63565b8c8c828181106125dc57fe5b90506020020135915081600014156125f35761273f565b6001600160a01b0383166000908152600460209081526040808320338452909152902054612627908363ffffffff6133ef16565b6001600160a01b038416600081815260046020908152604080832033845282528083209490945591815260039091522054612668908363ffffffff6133ef16565b6001600160a01b03808516600081815260036020908152604080832095909555928816815260068352838120918152915220546126ab908363ffffffff6133ef16565b6001600160a01b038086166000908152600660209081526040808320938816808452939091529020919091556126e99033308563ffffffff613f9716565b836001600160a01b0316836001600160a01b0316336001600160a01b03167fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd7856040516127369190615b03565b60405180910390a45b6001016124fa565b505050505050505050505050505050565b60185481565b6000806127c4601c8054806020026020016040519081016040528092919081815260200182805480156127ba57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161279c575b5050505050611716565b915091509091565b62f099c081565b670de0b6b3a764000081565b601660205281600052604060002081815481106127f857fe5b6000918252602090912001546001600160a01b03169150829050565b736b175474e89094c44da98b954eedeac495271d0f81565b600154600090600160a01b900460ff16156128595760405162461bcd60e51b81526004016109db90615ab3565b600754600b543391906000808080612872878787612e34565b6001600160a01b038b1660009081526008602090815260408083208d9055600c82528083208c9055600a8252808320859055600e9091529020819055929650909450925090506128c587858585856130c6565b6001600160a01b0389166000908152600960209081526040808320600d83528184209490945593909255601590915220429055612900613fbb565b9750336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf760008a6040516111f09291906159a4565b60408051600480825260a0820190925260609160208201608080388339505060408051600480825260a082019092529293506060929150602082016080803883390190505090507318240bd9c07fa6156ce3f3f61921cc82b2619157826000815181106129a757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073e26a220a341eaca116bda64cf9d5638a935ae629826001815181106129e957fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073b72b31907c1c95f3650b64b2469e08edacee5e8f82600281518110612a2b57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600080516020615d2f83398151915282600381518110612a6757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060001981600081518110612a9757fe5b60200260200101818152505060001981600181518110612ab357fe5b60200260200101818152505060001981600281518110612acf57fe5b60200260200101818152505060001981600381518110612aeb57fe5b602002602001018181525050612b018282611ecb565b6115796000613292565b60075481565b600f5473b72b31907c1c95f3650b64b2469e08edacee5e8f600090815260036020527ffcfc5d57a009157202436965eb7c01b14f1b51f705a3b4f08296120160c5e109549091612b7591670de0b6b3a7640000916108c1919063ffffffff6131cb16565b600080516020615d2f8339815191526000526003602052600080516020615d8f83398151915254909150612baf908263ffffffff6133ef16565b6010547318240bd9c07fa6156ce3f3f61921cc82b261915760005260036020527f91de0462b01273d0819ee89d2f822b745d4b4dcc3d05d8e0d13f841abd34e4a254919250612c18918391610e3991670de0b6b3a7640000916108c1919063ffffffff6131cb16565b60115473e26a220a341eaca116bda64cf9d5638a935ae62960005260036020527f8341f36a1c413f2034fb483b56344c972362456414155a77c5d31e601f1c02a454919250612c81918391610e3991670de0b6b3a7640000916108c1919063ffffffff6131cb16565b905090565b612c8e611b1a565b612caa5760405162461bcd60e51b81526004016109db90615a73565b612cb381614071565b50565b600080516020615d2f83398151915281565b600154600160a01b900460ff1615612cf25760405162461bcd60e51b81526004016109db90615ab3565b81151580612cff57508015155b15612e3057612d0e82826140f2565b8115612d9d576040516323b872dd60e01b8152600080516020615d2f833981519152906323b872dd90612d49903390309087906004016158c6565b602060405180830381600087803b158015612d6357600080fd5b505af1158015612d77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612d9b919081019061522b565b505b8015612e30576040516323b872dd60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e490906323b872dd90612dde903390309086906004016158c6565b602060405180830381600087803b158015612df857600080fd5b505af1158015612e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ea9919081019061522b565b5050565b6001600160a01b0383166000908152600860205260408120548190819081908190612e6690889063ffffffff61325016565b6001600160a01b0389166000908152600c602052604081205491925090612e9490889063ffffffff61325016565b6001600160a01b038a16600090815260096020908152604080832054600d835281842054600a845282852054600e9094529190932054929950975095509350905081151580612ee257508015155b156130bb576000806000806000612ef88e611585565b9092509050612f0d828863ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b90049450612f2a858c6133ef565b9a50612f3c828763ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b90049450612f59858b6133ef565b99508015801590612f6957508615155b1561300657612f7e818863ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b90049450612f9b89866133ef565b6001600160a01b038f16600090815260156020526040812054919a50909350612fd4906a0c097ce7bc90715b34b9f160241b908561180c565b9350612fe6858563ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b900494506130038b866133ef565b9a505b801580159061301457508515155b156130b557613029818763ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b9004945061304688866133ef565b975082613085576001600160a01b038e166000908152601560205260408120549350613082906a0c097ce7bc90715b34b9f160241b908561180c565b93505b613095858563ffffffff6131cb16565b6a0c097ce7bc90715b34b9f160241b900494506130b28a866133ef565b99505b50505050505b505093509350935093565b6001600160a01b03851660009081526015602052604081205481904281146131bd576000806131046a0c097ce7bc90715b34b9f160241b844261180c565b905086156131355761312e6a0c097ce7bc90715b34b9f160241b6108c1898463ffffffff6131cb16565b9889019891505b85156131645761315d6a0c097ce7bc90715b34b9f160241b6108c1888463ffffffff6131cb16565b9788019791505b6001600160a01b038a166000908152600080516020615d6f833981519152602052604090205480156131b9576131b26a0c097ce7bc90715b34b9f160241b6108c1838563ffffffff6131cb16565b998a019992505b5050505b509496939550929350505050565b6000826131da57506000613208565b828202828482816131e757fe5b04146132055760405162461bcd60e51b81526004016109db90615a53565b90505b92915050565b600061320583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506141c9565b600061320583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506141f6565b60008061329e83613414565b91506132a8613fbb565b9050336001600160a01b03167f34fcbac0073d7c3d388e51312faf357774904998eeb8fca628b9e6f65ee1cbf783836040516132e5929190615b7f565b60405180910390a2915091565b80158061337a5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906133289030908690600401615909565b60206040518083038186803b15801561334057600080fd5b505afa158015613354573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506133789190810190615267565b155b6133965760405162461bcd60e51b81526004016109db90615ac3565b604051611ea990849063095ea7b360e01b906133b89086908690602401615932565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614222565b6000828201838110156132055760405162461bcd60e51b81526004016109db90615a03565b33600090815260096020526040902054801561095c5733600090815260096020526040812055811561344f5761344a3382614307565b61095c565b6040516370a0823160e01b81528190600080516020615d2f833981519152906370a08231906134829030906004016158b8565b60206040518083038186803b15801561349a57600080fd5b505afa1580156134ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506134d29190810190615267565b10156135405773b72b31907c1c95f3650b64b2469e08edacee5e8f6001600160a01b0316634e71d92d6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561352757600080fd5b505af115801561353b573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b8152600080516020615d2f8339815191529063a9059cbb9061357390339085906004016158ee565b602060405180830381600087803b15801561358d57600080fd5b505af11580156135a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506135c5919081019061522b565b50919050565b604051633360d3df60e01b8152606090819073d8ee69652e4e4838f2531732a46d1f7f584f0b7f90633360d3df9061360c9086903090600090600401615940565b600060405180830381600087803b15801561362657600080fd5b505af115801561363a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261366291908101906151d9565b905060005b835181101561370a576136ce82828151811061367f57fe5b60200260200101516017600087858151811061369757fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546133ef90919063ffffffff16565b601760008684815181106136de57fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101613667565b5060405133907fd3719f04262b628e1d01a6ed24707f542cda51f144b5271149c7d0419436d00c90600090a292915050565b60008082518451146137605760405162461bcd60e51b81526004016109db90615a23565b600073d8ee69652e4e4838f2531732a46d1f7f584f0b7f6001600160a01b03166378d849ed6040518163ffffffff1660e01b815260040160206040518083038186803b1580156137af57600080fd5b505afa1580156137c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506137e79190810190614f73565b90506000816001600160a01b03166329d5277c600080516020615d2f83398151915273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b815260040161383b929190615909565b604080518083038186803b15801561385257600080fd5b505afa158015613866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061388a91908101906152a4565b506019549091506000808080805b8b51811015613a22578b81815181106138ad57fe5b60200260200101519450600080516020615d2f8339815191526001600160a01b0316856001600160a01b031614156138e457613a1a565b6001600160a01b038516736b175474e89094c44da98b954eedeac495271d0f14156139365761392f8b828151811061391857fe5b6020026020010151856133ef90919063ffffffff16565b9350613a1a565b6001600160a01b03851673a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481415613988576139818b828151811061396a57fe5b6020026020010151846133ef90919063ffffffff16565b9250613a1a565b6001600160a01b03851673dac17f958d2ee523a2206206994597c13d831ec714156139da576139d38b82815181106139bc57fe5b6020026020010151836133ef90919063ffffffff16565b9150613a1a565b8a81815181106139e657fe5b6020026020010151600014613a1a57613a15858c8381518110613a0557fe5b60200260200101518a8a8a614472565b8a0199505b600101613898565b508815613a6857600080516020615d2f83398151915260005260176020527fcf37870b726aadbba698d60193b30d07c7c9b39dc1bdaf83e993b9a0358a185680548a0190555b82151580613a7557508115155b80613a7f57508015155b15613ad657613a8f83838361459f565b736c3f90f043a72fa612cbac8115ee7e52bde6e49060005260176020527f407fe9863bf74082c6026154acd61fbcd964905841c0baf42e63cbc49aec164e80548201905597505b336001600160a01b03167f4532d391b3bfa0cfb0b4e8b6d8c2c972a12ddb43658ed59378f340da2082ee5e8a8a604051613b11929190615b7f565b60405180910390a2505050505050509250929050565b60176020527fcf37870b726aadbba698d60193b30d07c7c9b39dc1bdaf83e993b9a0358a185654736c3f90f043a72fa612cbac8115ee7e52bde6e4906000527f407fe9863bf74082c6026154acd61fbcd964905841c0baf42e63cbc49aec164e5481151580613b9557508015155b15613eff576002546001600160a01b03166000808415613d4457600080516020615d2f833981519152600090815260176020527fcf37870b726aadbba698d60193b30d07c7c9b39dc1bdaf83e993b9a0358a185655601854613c0d9068056bc75e2d63100000906108c190889063ffffffff6131cb16565b60405163a9059cbb60e01b8152909250600080516020615d2f8339815191529063a9059cbb90613c45908690868a0390600401615932565b602060405180830381600087803b158015613c5f57600080fd5b505af1158015613c73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613c97919081019061522b565b50819450601b548581613ca657fe5b60405163a9059cbb60e01b81529190049150600080516020615d2f8339815191529063a9059cbb90613cde90339085906004016158ee565b602060405180830381600087803b158015613cf857600080fd5b505af1158015613d0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613d30919081019061522b565b50613d41858263ffffffff61325016565b94505b8315613ef157736c3f90f043a72fa612cbac8115ee7e52bde6e490600090815260176020527f407fe9863bf74082c6026154acd61fbcd964905841c0baf42e63cbc49aec164e55601854613dae9068056bc75e2d63100000906108c190879063ffffffff6131cb16565b60405163a9059cbb60e01b8152909250736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb90613dec90869086890390600401615932565b602060405180830381600087803b158015613e0657600080fd5b505af1158015613e1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613e3e919081019061522b565b50819350601b548481613e4d57fe5b60405163a9059cbb60e01b81529190049150736c3f90f043a72fa612cbac8115ee7e52bde6e4909063a9059cbb90613e8b90339085906004016158ee565b602060405180830381600087803b158015613ea557600080fd5b505af1158015613eb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613edd919081019061522b565b50613eee848263ffffffff61325016565b93505b613efb85856140f2565b5050505b336001600160a01b03167f0d01c94d0df28276fb43f8bfa77a79b387742823fa1189417aca8b82afff77018383604051613f3a929190615b7f565b60405180910390a29091565b6000818310613f555781613205565b5090919050565b3390565b604051611ea990849063a9059cbb60e01b906133b89086908690602401615932565b600081613f8f8482614992565b949350505050565b6040516115799085906323b872dd60e01b906133b890879087908790602401615924565b336000908152600d60205260409020548015611b1757336000818152600d6020526040808220919091555163a9059cbb60e01b8152736c3f90f043a72fa612cbac8115ee7e52bde6e4909163a9059cbb9161401b919085906004016158ee565b602060405180830381600087803b15801561403557600080fd5b505af1158015614049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061406d919081019061522b565b5090565b6001600160a01b0381166140975760405162461bcd60e51b81526004016109db906159e3565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6140fa6118ed565b601155601055600f55600061410d612b11565b90508061412c5760405162461bcd60e51b81526004016109db90615ae3565b60075461415590610e39836108c1876a0c097ce7bc90715b34b9f160241b63ffffffff6131cb16565b600755600b5461418190610e39836108c1866a0c097ce7bc90715b34b9f160241b63ffffffff6131cb16565b600b554260145560405133907fc88fd69bfa06d2cb1591f4ddd5ebede37737856a00d499e4f51e60984dc13d36906141bc9086908690615b7f565b60405180910390a2505050565b600081836141ea5760405162461bcd60e51b81526004016109db91906159d2565b5060008385816118a457fe5b6000818484111561421a5760405162461bcd60e51b81526004016109db91906159d2565b505050900390565b614234826001600160a01b03166149da565b6142505760405162461bcd60e51b81526004016109db90615ad3565b60006060836001600160a01b03168360405161426c91906158ac565b6000604051808303816000865af19150503d80600081146142a9576040519150601f19603f3d011682016040523d82523d6000602084013e6142ae565b606091505b5091509150816142d05760405162461bcd60e51b81526004016109db90615a13565b80511561157957808060200190516142eb919081019061522b565b6115795760405162461bcd60e51b81526004016109db90615a93565b6001600160a01b03828116600090815260056020908152604080832054600080516020615d4f8339815191529092529091205491169061434790836133ef565b6001600160a01b0384166000908152600080516020615d4f83398151915260209081526040822092909255600080516020615d2f833981519152905260039052600080516020615d8f833981519152546143a7908363ffffffff6133ef16565b600080516020615d8f833981519152556001600160a01b0381166000908152600660209081526040808320600080516020615d2f83398151915284529091529020546143f9908363ffffffff6133ef16565b6001600160a01b038083166000818152600660209081526040808320600080516020615d2f83398151915280855292529182902094909455519092918616907fc5017594d2723c038bb216e5bcef3ac65910ade839c0e63253bf5b59efbf0fd790614465908790615b03565b60405180910390a4505050565b6001600160a01b0385166000908152601760205260408120548015614595578086111561449d578095505b6144ad818763ffffffff61325016565b6001600160a01b0388166000908152601760209081526040808320939093556016905281902090516338ed173960e01b8152606091737a250d5630b4cf539739df2c5dacb4c659f2488d916338ed173991614513918b9160019130904290600401615b2c565b600060405180830381600087803b15801561452d57600080fd5b505af1158015614541573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261456991908101906151d9565b90508060018251038151811061457b57fe5b60200260200101519250614593888885898989614a13565b505b5095945050505050565b60006145a9614d2a565b600080861561465a5750736b175474e89094c44da98b954eedeac495271d0f60005260176020527f8a7776df4a477673730b069fb077ae9d41f7bea257426d6b72fb302b3979395754801561465a5780871115614604578096505b614614818863ffffffff61325016565b736b175474e89094c44da98b954eedeac495271d0f60005260176020527f8a7776df4a477673730b069fb077ae9d41f7bea257426d6b72fb302b39793957558683528691505b8515614732575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260176020527f4b6771a61dd4db37ea6cdd97ea00e948fd53713047d03a3f5e754778f387848c54801561473257808611156146b2578095505b6146c2818763ffffffff61325016565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4860005260176020527f4b6771a61dd4db37ea6cdd97ea00e948fd53713047d03a3f5e754778f387848c5585836001602002015261472f6147228764e8d4a5100063ffffffff6131cb16565b839063ffffffff6133ef16565b91505b84156147f5575073dac17f958d2ee523a2206206994597c13d831ec760005260176020527ff446947c7ecc245e49a695979bfdbedf62c5b3f50cecc135097a55d829f984f55480156147f5578085111561478a578094505b61479a818663ffffffff61325016565b73dac17f958d2ee523a2206206994597c13d831ec760005260176020527ff446947c7ecc245e49a695979bfdbedf62c5b3f50cecc135097a55d829f984f555604083018590526147f26147228664e8d4a510006131cb565b91505b6040516370a0823160e01b8152600090736c3f90f043a72fa612cbac8115ee7e52bde6e490906370a082319061482f9030906004016158b8565b60206040518083038186803b15801561484757600080fd5b505afa15801561485b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061487f9190810190615267565b604051634515cef360e01b815290915073bebc44782c7db0a1a60cb6fe97d0b483032ff1c790634515cef3906148bc90879060009060040161596d565b600060405180830381600087803b1580156148d657600080fd5b505af11580156148ea573d6000803e3d6000fd5b50506040516370a0823160e01b8152839250736c3f90f043a72fa612cbac8115ee7e52bde6e49091506370a08231906149279030906004016158b8565b60206040518083038186803b15801561493f57600080fd5b505afa158015614953573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506149779190810190615267565b0394506149878386601a54614b5a565b505050509392505050565b600061499e8383614c61565b6149d25750600180830180548083018083556000928352602080842090920185905584835290859052604090912055613208565b506000613208565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590613f8f575050151592915050565b600080846001600160a01b03166329d5277c8973c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26040518363ffffffff1660e01b8152600401614a58929190615909565b604080518083038186803b158015614a6f57600080fd5b505afa158015614a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250614aa791908101906152a4565b9092509050614ad0846108c18381866a0c097ce7bc90715b34b9f160241b63ffffffff6131cb16565b91506000614af0886108c189670de0b6b3a764000063ffffffff6131cb16565b90506000838211614b0357818403614b07565b8382035b90508015614b4e57614b2c826108c18368056bc75e2d6310000063ffffffff6131cb16565b905084811115614b4e5760405162461bcd60e51b81526004016109db90615af3565b50505050505050505050565b6000614bfc73bebc44782c7db0a1a60cb6fe97d0b483032ff1c76001600160a01b031663bb7b8b806040518163ffffffff1660e01b815260040160206040518083038186803b158015614bac57600080fd5b505afa158015614bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250614be49190810190615267565b6108c186670de0b6b3a764000063ffffffff6131cb16565b90506000818411614c0f57838203614c13565b8184035b90508015614c5a57614c38846108c18368056bc75e2d6310000063ffffffff6131cb16565b905082811115614c5a5760405162461bcd60e51b81526004016109db906159f3565b5050505050565b60009081526020919091526040902054151590565b828054828255906000526020600020908101928215614ccb579160200282015b82811115614ccb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614c96565b5061406d929150614d48565b828054828255906000526020600020908101928215614ccb579160200282015b82811115614ccb5781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614cf7565b60405180606001604052806003906020820280388339509192915050565b611b1791905b8082111561406d5780546001600160a01b0319168155600101614d4e565b803561320881615d08565b805161320881615d08565b60008083601f840112614d9457600080fd5b5081356001600160401b03811115614dab57600080fd5b602083019150836020820283011115614dc357600080fd5b9250929050565b600082601f830112614ddb57600080fd5b8135614dee614de982615c0c565b615be6565b91508181835260208401935060208101905083856020840282011115614e1357600080fd5b60005b83811015614e3f5781614e298882614d6c565b8452506020928301929190910190600101614e16565b5050505092915050565b600082601f830112614e5a57600080fd5b8135614e68614de982615c0c565b91508181835260208401935060208101905083856020840282011115614e8d57600080fd5b60005b83811015614e3f5781614ea38882614f3f565b8452506020928301929190910190600101614e90565b600082601f830112614eca57600080fd5b8151614ed8614de982615c0c565b91508181835260208401935060208101905083856020840282011115614efd57600080fd5b60005b83811015614e3f5781614f138882614f4a565b8452506020928301929190910190600101614f00565b803561320881615d1c565b805161320881615d1c565b803561320881615d25565b805161320881615d25565b600060208284031215614f6757600080fd5b6000613f8f8484614d6c565b600060208284031215614f8557600080fd5b6000613f8f8484614d77565b60008060408385031215614fa457600080fd5b6000614fb08585614d6c565b9250506020614fc185828601614d6c565b9150509250929050565b60008060408385031215614fde57600080fd5b6000614fea8585614d6c565b9250506020614fc185828601614f3f565b6000806020838503121561500e57600080fd5b82356001600160401b0381111561502457600080fd5b61503085828601614d82565b92509250509250929050565b6000806000806040858703121561505257600080fd5b84356001600160401b0381111561506857600080fd5b61507487828801614d82565b945094505060208501356001600160401b0381111561509257600080fd5b61509e87828801614d82565b95989497509550505050565b600080600080600080606087890312156150c357600080fd5b86356001600160401b038111156150d957600080fd5b6150e589828a01614d82565b965096505060208701356001600160401b0381111561510357600080fd5b61510f89828a01614d82565b945094505060408701356001600160401b0381111561512d57600080fd5b61513989828a01614d82565b92509250509295509295509295565b60006020828403121561515a57600080fd5b81356001600160401b0381111561517057600080fd5b613f8f84828501614dca565b6000806040838503121561518f57600080fd5b82356001600160401b038111156151a557600080fd5b6151b185828601614dca565b92505060208301356001600160401b038111156151cd57600080fd5b614fc185828601614e49565b6000602082840312156151eb57600080fd5b81516001600160401b0381111561520157600080fd5b613f8f84828501614eb9565b60006020828403121561521f57600080fd5b6000613f8f8484614f29565b60006020828403121561523d57600080fd5b6000613f8f8484614f34565b60006020828403121561525b57600080fd5b6000613f8f8484614f3f565b60006020828403121561527957600080fd5b6000613f8f8484614f4a565b6000806040838503121561529857600080fd5b6000614fea8585614f3f565b600080604083850312156152b757600080fd5b60006152c38585614f4a565b9250506020614fc185828601614f4a565b6000806000606084860312156152e957600080fd5b60006152f58686614f3f565b935050602061530686828701614f3f565b925050604061531786828701614f3f565b9150509250925092565b600061532d8383615350565b505060200190565b600061532d83836158a3565b61534a81615c81565b82525050565b61534a81615c67565b600061536482615c3e565b61536e8185615c52565b935061537983615c2c565b8060005b838110156153a75781516153918882615321565b975061539c83615c2c565b92505060010161537d565b509495945050505050565b60006153bd82615c42565b6153c78185615c52565b93506153d283615c32565b8060005b838110156153a7576153e782615ce8565b6153f18882615321565b97506153fc83615c4c565b9250506001016153d6565b61541081615c46565b61541a818461095c565b925061542582611b17565b8060005b8381101561545357815161543d8782615335565b965061544883615c2c565b925050600101615429565b505050505050565b61534a81615c72565b600061546f82615c3e565b615479818561095c565b9350615489818560208601615ca9565b9290920192915050565b61534a81615c88565b61534a81615c93565b61534a81615c9e565b60006154b982615c3e565b6154c38185615c52565b93506154d3818560208601615ca9565b6154dc81615cf4565b9093019392505050565b60006154f3602683615c52565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b600061553b601883615c52565b7f63757276652070726963652064697361677265656d656e740000000000000000815260200192915050565b6000615574601b83615c52565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b60006155ad602083615c52565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815260200192915050565b60006155e6600e83615c52565b6d0c6deeadce840dad2e6dac2e8c6d60931b815260200192915050565b6000615610600c83615c52565b6b0d2dcecc2d8d2c840e0c2e8d60a31b815260200192915050565b6000615638600e83615c52565b6d0ecc2d8eaca40e8dede40d0d2ced60931b815260200192915050565b6000615662602183615c52565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006156a5600d83615c52565b6c34b73b30b634b2103a37b5b2b760991b815260200192915050565b60006156ce600c83615c52565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b60006156f6600d83615c52565b6c696e76616c696420706172616d60981b815260200192915050565b600061571f602a83615c52565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e8152691bdd081cdd58d8d9595960b21b602082015260400192915050565b600061576b601383615c52565b721c185d1a08191bd95cc81b9bdd08195e1a5cdd606a1b815260200192915050565b600061579a600683615c52565b651c185d5cd95960d21b815260200192915050565b60006157bc603683615c52565b7f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f81527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b602082015260400192915050565b6000615814601f83615c52565b7f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400815260200192915050565b600061584d600e83615c52565b6d1b9bdd1a1a5b99c81cdd185ad95960921b815260200192915050565b6000615877601a83615c52565b7f756e69737761702070726963652064697361677265656d656e74000000000000815260200192915050565b61534a81611b17565b60006110d48284615464565b602081016132088284615350565b606081016158d48286615341565b6158e16020830185615350565b613f8f60408301846158a3565b604081016158fc8285615341565b6110d460208301846158a3565b604081016159178285615350565b6110d46020830184615350565b606081016158d48286615350565b604081016158fc8285615350565b606080825281016159518186615359565b90506159606020830185615350565b613f8f604083018461549c565b6080810161597b8285615407565b6110d460608301846154a5565b60208101613208828461545b565b602081016132088284615493565b604081016158fc82856154a5565b604081016159c082856154a5565b8181036020830152613f8f8184615359565b6020808252810161320581846154ae565b60208082528101613208816154e6565b602080825281016132088161552e565b6020808252810161320881615567565b60208082528101613208816155a0565b60208082528101613208816155d9565b6020808252810161320881615603565b602080825281016132088161562b565b6020808252810161320881615655565b6020808252810161320881615698565b60208082528101613208816156c1565b60208082528101613208816156e9565b6020808252810161320881615712565b602080825281016132088161575e565b602080825281016132088161578d565b60208082528101613208816157af565b6020808252810161320881615807565b6020808252810161320881615840565b602080825281016132088161586a565b6020810161320882846158a3565b60408101615b1f82856158a3565b6110d460208301846154a5565b60a08101615b3a82886158a3565b615b4760208301876154a5565b8181036040830152615b5981866153b2565b9050615b686060830185615350565b615b7560808301846158a3565b9695505050505050565b604081016158fc82856158a3565b60608101615b9b82866158a3565b6158e160208301856158a3565b60808101615bb682876158a3565b615bc360208301866158a3565b615bd060408301856158a3565b615bdd60608301846158a3565b95945050505050565b6040518181016001600160401b0381118282101715615c0457600080fd5b604052919050565b60006001600160401b03821115615c2257600080fd5b5060209081020190565b60200190565b60009081526020902090565b5190565b5490565b50600390565b60010190565b90815260200190565b6001600160a01b031690565b600061320882615c5b565b151590565b8061095c81615cfe565b6000613208825b600061320882615c67565b600061320882615c77565b600061320882611b17565b60005b83811015615cc4578181015183820152602001615cac565b838111156115795750506000910152565b6000613208615ce383611b17565b615c5b565b60006132088254615cd5565b601f01601f191690565b60048110612cb357fe5b615d1181615c67565b8114612cb357600080fd5b615d1181615c72565b615d1181611b1756fe00000000000000000000000056d811088235f11c8920698a204a5010a788f4b31e38d77566003d7f728cfa677ad07e8283e5607bd89a929ee98c93eba12048732ce56405c0c0b7d532a6d76ebaf14a8d190d60f3be61dae6890d68141a9cc6f826822d1429e81ba812c5218f96710c8923c00dbf3bebc27a2dcc389411621671a365627a7a7231582087df8006a8f10f4032ff4d4bb599504cbb6e2164ae637a956d0b9080e73b88606c6578706572696d656e74616cf564736f6c63430005110040

Deployed Bytecode Sourcemap

33006:39180:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33006:39180:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44792:1223;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;23786:58;;;;;;;;;:::i;:::-;;;;;;;;27291:76;;;:::i;:::-;;;;;;;;57418:170;;;;;;;;;:::i;24985:40::-;;;:::i;24242:52::-;;;;;;;;;:::i;28197:64::-;;;:::i;27905:96::-;;;:::i;:::-;;;;;;;;24448:32;;;:::i;24487:::-;;;:::i;23888:46::-;;;;;;;;;:::i;71696:242::-;;;;;;;;;:::i;:::-;;23274:26;;;:::i;23099:79::-;;;:::i;39020:236::-;;;;;;;;;:::i;:::-;;;;;;;;;54375:487;;;;;;;;;:::i;71946:237::-;;;;;;;;;:::i;24094:39::-;;;:::i;70749:460::-;;;:::i;24344:52::-;;;;;;;;;:::i;23990:46::-;;;;;;;;;:::i;55827:1583::-;;;;;;;;;:::i;39264:307::-;;;:::i;24786:49::-;;;;;;;;;:::i;24526:34::-;;;:::i;24936:42::-;;;:::i;27129:74::-;;;:::i;69309:128::-;;;;;;;;;:::i;69890:851::-;;;;;;;;;:::i;24885:44::-;;;:::i;54870:949::-;;;;;;;;;:::i;23528:43::-;;;;;;;;;:::i;22874:29::-;;;:::i;59575:343::-;;;;;;;;;:::i;28008:89::-;;;:::i;69445:143::-;;;;;;;;;:::i;24632:33::-;;;:::i;27789:109::-;;;:::i;58168:1146::-;;;;;;;;;:::i;27210:74::-;;;:::i;25034:33::-;;;;;;;;;:::i;53141:1009::-;;;:::i;:::-;;;;;;;;;;54158:209;;;;;;;;;:::i;27627:73::-;;;:::i;27374:85::-;;;:::i;71436:252::-;;;;;;;;;:::i;2929:79::-;;;:::i;3275:94::-;;;:::i;:::-;;;;;;;;24674:50;;;;;;;;;:::i;50762:1027::-;;;;;;;;;:::i;27468:73::-;;;:::i;24140:64::-;;;;;;;;;:::i;23245:20::-;;;:::i;69596:145::-;;;;;;;;;:::i;23633:72::-;;;;;;;;;:::i;34742:1902::-;;;;;;;;;:::i;71217:211::-;;;;;;;;;:::i;27707:73::-;;;:::i;33263:1471::-;;;;;;;;;:::i;24842:36::-;;;:::i;59358:209::-;;;:::i;28106:63::-;;;:::i;28761:47::-;;;:::i;24733:46::-;;;;;;;;;:::i;27548:72::-;;;:::i;39579:320::-;;;:::i;42003:531::-;;;:::i;23746:33::-;;;:::i;57596:564::-;;;:::i;3524:109::-;;;;;;;;;:::i;27049:73::-;;;:::i;51857:507::-;;;;;;;;;:::i;44792:1223::-;44885:25;44912:31;44945:26;44973:32;45116:112;45138:7;45160:18;;45193:24;;45116:7;:112::i;:::-;45023:205;;-1:-1:-1;45023:205:0;;-1:-1:-1;45023:205:0;-1:-1:-1;45023:205:0;-1:-1:-1;45288:187:0;45315:7;45023:205;;;;45288:12;:187::i;:::-;45241:234;;-1:-1:-1;45241:234:0;-1:-1:-1;45542:18:0;45563:98;-1:-1:-1;;;45542:18:0;45635:15;45563:22;:98::i;:::-;45542:119;-1:-1:-1;45693:132:0;45730:80;-1:-1:-1;;;45730:52:0;:18;45542:119;45730:52;:40;:52;:::i;:::-;:74;:80;:74;:80;:::i;:::-;45693:18;;:132;:36;:132;:::i;:::-;45672:153;-1:-1:-1;45863:144:0;45906:86;-1:-1:-1;;;45906:58:0;:24;45953:10;45906:58;:46;:58;:::i;:86::-;45863:24;;:144;:42;:144;:::i;:::-;45836:171;;44792:1223;;;;;;:::o;23786:58::-;;;;;;;;;;;;;:::o;27291:76::-;27325:42;27291:76;:::o;57418:170::-;-1:-1:-1;;;;;57553:27:0;;57521:7;57553:27;;;:20;:27;;;;;;57418:170;;;;:::o;24985:40::-;;;;:::o;24242:52::-;;;;;;;;;;;;;:::o;28197:64::-;28252:9;28197:64;:::o;27905:96::-;27958:42;27905:96;:::o;24448:32::-;;;;:::o;24487:::-;;;;:::o;23888:46::-;;;;;;;;;;;;;:::o;71696:242::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;;;;;;;;;71831:26;71823:52;;;;-1:-1:-1;;;71823:52:0;;;;;;;;;71886:20;:44;71696:242::o;23274:26::-;;;-1:-1:-1;;;;;23274:26:0;;:::o;23099:79::-;23150:28;23099:79;:::o;39020:236::-;33216:8;;39150:25;;;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;43803:18;;43868:24;;39120:10;;43803:18;43773:27;;;;44030:114;39120:10;43803:18;43868:24;44030:7;:114::i;:::-;-1:-1:-1;;;;;44155:32:0;;;;;;:23;:32;;;;;;;;:54;;;44220:29;:38;;;;;:66;;;44351:11;:20;;;;;:41;;;44403:17;:26;;;;;:53;;;43905:239;;-1:-1:-1;43905:239:0;;-1:-1:-1;43905:239:0;-1:-1:-1;43905:239:0;-1:-1:-1;44522:187:0;44179:7;43905:239;;;;44522:12;:187::i;:::-;-1:-1:-1;;;;;44470:20:0;;;;;;:11;:20;;;;;;;;44492:17;:26;;;;;44469:240;;;;;;;;44720:15;:24;;;;44747:15;44720:42;;39233:15;39240:7;39233:6;:15::i;:::-;39226:22;;;;33246:1;;;;;;;39020:236;;;:::o;54375:487::-;54493:19;54527:20;54562;54597:22;54669:31;-1:-1:-1;;;;;;;;;;;54692:7:0;54669:16;:31::i;:::-;54715:32;27242:42;54739:7;54715:16;:32::i;:::-;54762;27161:42;54786:7;54762:16;:32::i;:::-;54809:34;27325:42;54835:7;54809:16;:34::i;:::-;54647:207;;;;;;;;54375:487;;;;;:::o;71946:237::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;72079:25;72071:51;;;;-1:-1:-1;;;72071:51:0;;;;;;;;;72133:19;:42;71946:237::o;24094:39::-;;;;:::o;70749:460::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;70830:47;27578:42;27958;70875:1;70830:47;:23;:47;:::i;:::-;70888:57;27578:42;27958;-1:-1:-1;;70888:57:0;:23;:57;:::i;:::-;70956:48;27658:42;27958;71002:1;70956:48;:24;:48;:::i;:::-;71015:58;27658:42;27958;-1:-1:-1;;71015:58:0;:24;:58;:::i;:::-;71084:48;27738:42;27958;71130:1;71084:48;:24;:48;:::i;:::-;71143:58;27738:42;27958;-1:-1:-1;;71143:58:0;:24;:58;:::i;:::-;70749:460::o;24344:52::-;;;;;;;;;;;;;:::o;23990:46::-;;;;;;;;;;;;;:::o;55827:1583::-;-1:-1:-1;;;;;55988:33:0;;55929:18;55988:33;;;-1:-1:-1;;;;;;;;;;;55988:24:0;:33;:24;:33;;;56036:17;;56032:768;;56490:1;56173:314;28720:12;56173:287;56253:188;28720:12;56375:1;56403:15;56253:22;:188::i;:::-;56173:12;;28720;56208:233;56173:287;:34;:287;:::i;:314::-;:318;;;;;;56160:331;;56627:161;56777:10;56627:145;56668:12;56699:15;:24;56715:7;-1:-1:-1;;;;;56699:24:0;-1:-1:-1;;;;;56699:24:0;;;;;;;;;;;;;56742:15;56627:22;:145::i;:::-;:149;:161;:149;:161;:::i;:::-;56614:174;;56032:768;-1:-1:-1;;;;;56876:20:0;;;;;;:11;:20;;;;;;;;;-1:-1:-1;;;;;;;;;;;56825:32:0;;;;;;;:143;;56957:10;;56825:72;;:50;:72::i;:143::-;56812:156;;56994:136;57119:10;56994:106;57095:4;56994:82;27242:42;-1:-1:-1;;;;;57046:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57046:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57046:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;57046:29:0;;;;;;;;;-1:-1:-1;;;;;56994:33:0;;:24;:33;;;:24;;:33;:24;:33;;;;:82;:51;:82;:::i;:136::-;56981:149;;57237:165;57391:10;57237:135;27325:42;-1:-1:-1;;;;;57342:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57342:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57342:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;57342:29:0;;;;;;;;;-1:-1:-1;;;;;57287:35:0;;:26;:35;;;:26;;:35;:26;:35;;;;;57237:31;;-1:-1:-1;;;57237:31:0;;:86;;57287:35;-1:-1:-1;;;;;;;;;;;27080:42:0;57237:22;;:31;;27325:42;;57287:17;57237:31;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57237:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57237:31:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;57237:31:0;;;;;;;;;:49;:86;:49;:86;:::i;:165::-;57224:178;55827:1583;-1:-1:-1;;;55827:1583:0:o;39264:307::-;33216:8;;39376:25;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;43803:18;;43868:24;;39346:10;;43803:18;43773:27;;;;44030:114;39346:10;43803:18;43868:24;44030:7;:114::i;:::-;-1:-1:-1;;;;;44155:32:0;;;;;;:23;:32;;;;;;;;:54;;;44220:29;:38;;;;;:66;;;44351:11;:20;;;;;:41;;;44403:17;:26;;;;;:53;;;43905:239;;-1:-1:-1;43905:239:0;;-1:-1:-1;43905:239:0;-1:-1:-1;43905:239:0;-1:-1:-1;44522:187:0;44179:7;43905:239;;;;44522:12;:187::i;:::-;-1:-1:-1;;;;;44470:20:0;;;;;;:11;:20;;;;;;;;44492:17;:26;;;;;44469:240;;;;;;;;44720:15;:24;;;;;;44747:15;44720:42;;39439:17;;:10;:17::i;:::-;39419:37;;39494:10;-1:-1:-1;;;;;39474:89:0;;39519:17;39551:1;39474:89;;;;;;;;;;;;;;;;33246:1;;;;;;;39264:307;:::o;24786:49::-;;;;;;;;;;;;;:::o;24526:34::-;;;;:::o;24936:42::-;;;;:::o;27129:74::-;27161:42;27129:74;:::o;69309:128::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;69409:8;:20;;;;;-1:-1:-1;;;69409:20:0;-1:-1:-1;;;;69409:20:0;;;;;;;;;69309:128::o;69890:851::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;69999:21;70036:9;70031:703;70051:16;;;70031:703;;;70096:5;;70102:1;70096:8;;;;;;;;;;;;-1:-1:-1;30:25;;-1:-1;;100:14;96:29;;;92:48;68:73;;58:2;;155:1;152;145:12;58:2;174:33;;;69:4;55:19;;;-1:-1;16:22;-1:-1;;;;;82:30;;79:2;;;125:1;122;115:12;79:2;183:4;175:6;171:17;155:14;151:38;141:8;137:53;134:2;;;203:1;200;193:12;134:2;70089:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;70127:11:0;;70089:15;;-1:-1:-1;;;70142:1:0;-1:-1:-1;70127:16:0;;;:69;;;70175:4;70194:1;70180:4;:11;:15;70175:21;;;;;;;;;;;;;;-1:-1:-1;;;;;70164:32:0;:4;70169:1;70164:7;;;;;;;;;;;;;;-1:-1:-1;;;;;70164:32:0;;;70127:69;:119;;;;;-1:-1:-1;;;;;;;;;;;;;;;;70217:29:0;:4;70236:1;70222:4;:11;:15;70217:21;;;;;;;;;;;;;;-1:-1:-1;;;;;70217:29:0;;70127:119;70119:175;;;;-1:-1:-1;;;70119:175:0;;;;;;;;;70396:39;;-1:-1:-1;;;70396:39:0;;70366:27;;27855:42;;70396:27;;:39;;70424:4;;70430;;70396:39;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70396:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70396:39:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;70396:39:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;70396:39:0;;;;;;;;;70366:69;;70458:10;70489:1;70469:10;:17;:21;70458:33;;;;;;;;;;;;;;70495:1;70458:38;;70450:70;;;;-1:-1:-1;;;70450:70:0;;;;;;;;;70570:4;70549:9;:18;70559:4;70564:1;70559:7;;;;;;;;;;;;;;-1:-1:-1;;;;;70549:18:0;-1:-1:-1;;;;;70549:18:0;;;;;;;;;;;;:25;;;;;;;;;;;;:::i;:::-;;70589:54;27855:42;70641:1;70596:4;70601:1;70596:7;;;;;;;;;;;;;;-1:-1:-1;;;;;70589:27:0;;;:54;;;;;:::i;:::-;70658:64;27855:42;-1:-1:-1;;70665:4:0;70670:1;70665:7;;;;;;;70658:64;-1:-1:-1;70069:3:0;;70031:703;;;;3178:1;69890:851;;:::o;24885:44::-;;;;:::o;54870:949::-;-1:-1:-1;;;;;55051:33:0;;54970:21;55051:33;;;-1:-1:-1;;;;;;;;;;;55051:24:0;:33;:24;:33;;;54970:21;;55099:12;;55095:172;;55205:17;;-1:-1:-1;;;;;55145:33:0;;:24;:33;;;-1:-1:-1;;;;;;;;;;;55145:24:0;:33;:24;:33;;;:110;;55250:4;;55145:78;;;:59;:78;:::i;:110::-;55128:127;;55095:172;-1:-1:-1;;;;;;55295:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;55295:23:0;:32;;;:23;:32;;;;55350:24;:33;;;;;;;55295:32;;-1:-1:-1;55398:12:0;;55394:174;;55443:113;55542:13;55443:76;55514:4;55443:48;55473:17;;55443:7;:29;;:48;;;;:::i;:113::-;55427:129;;55394:174;-1:-1:-1;;;;;;55590:35:0;;:26;:35;;;:26;;:35;:26;:35;;;55640:12;;55636:176;;55685:115;55786:13;55685:78;55758:4;55685:50;55715:19;;55685:7;:29;;:50;;;;:::i;:115::-;55669:131;;55636:176;54870:949;;;;:::o;23528:43::-;;;;;;;;;;;;-1:-1:-1;;;;;23528:43:0;;:::o;22874:29::-;;;-1:-1:-1;;;;;22874:29:0;;:::o;59575:343::-;33216:8;;59707:19;;;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;33106:10;33120:9;33106:23;33098:48;;;;-1:-1:-1;;;33098:48:0;;;;;;;;;59765:24;59792:21;59806:6;59792:13;:21::i;:::-;59765:48;;59824:29;59837:6;59845:7;59824:12;:29::i;:::-;;;59893:17;:15;:17::i;:::-;59864:46;;;;-1:-1:-1;59575:343:0;-1:-1:-1;;;59575:343:0:o;28008:89::-;28054:42;28008:89;:::o;69445:143::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;69554:11;:26;;-1:-1:-1;;;;;;69554:26:0;-1:-1:-1;;;;;69554:26:0;;;;;;;;;;69445:143::o;24632:33::-;;;;:::o;27789:109::-;27855:42;27789:109;:::o;58168:1146::-;58342:14;58391:38;:14;58413:15;58391:38;:21;:38;:::i;:::-;58374:55;;58461:10;58444:14;:27;58440:867;;;28520:37;58492:39;;;;:93;;-1:-1:-1;28619:39:0;58552:33;;;58492:93;58488:264;;;-1:-1:-1;58735:1:0;58728:8;;58488:264;28520:37;58770:34;;58766:167;;;28520:37;;-1:-1:-1;58766:167:0;28619:39;58951:36;;58947:167;;;28619:39;;-1:-1:-1;58947:167:0;59130:22;59155:30;:14;59174:10;59155:30;:18;:30;:::i;:::-;59130:55;-1:-1:-1;28342:9:0;59209:32;:12;59130:55;59209:32;:16;:32;:::i;:::-;:60;;;;;;;58168:1146;-1:-1:-1;;;;;58168:1146:0:o;27210:74::-;27242:42;27210:74;:::o;25034:33::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;25034:33:0;;-1:-1:-1;25034:33:0;:::o;53141:1009::-;53219:19;53240;53261:21;53300:19;53322:115;28720:12;53395:1;53411:15;53322:22;:115::i;:::-;53300:137;;53464:121;28720:12;53464:55;53501:11;28720:12;53477:35;53514:4;53464:12;:55::i;:121::-;53450:135;;27242:42;-1:-1:-1;;;;;53612:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53612:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53612:29:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53612:29:0;;;;;;;;;27325:42;53654:21;53678:29;:20;:29;;;;53598:43;;-1:-1:-1;53722:18:0;;53718:425;;-1:-1:-1;;;;;;;;;;;53875:31:0;53984:26;:20;:26;;-1:-1:-1;;;;;;;;;;;53984:26:0;53909:101;;23150:28;53909:101;54043:88;54117:13;54043:51;53909:101;54089:4;54043:51;:45;:51;:::i;:88::-;54027:104;;53718:425;;53141:1009;;;;;:::o;54158:209::-;-1:-1:-1;;;;;54326:24:0;;;54283:15;54326:24;;;:17;:24;;;;;;;;:33;;;;;;;;;;;;;54158:209::o;27627:73::-;27658:42;27627:73;:::o;27374:85::-;27416:42;27374:85;:::o;71436:252::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;71575:28;71567:54;;;;-1:-1:-1;;;71567:54:0;;;;;;;;;71632:22;:48;71436:252::o;2929:79::-;2967:7;2994:6;-1:-1:-1;;;;;2994:6:0;2929:79;;:::o;3275:94::-;3315:4;3355:6;;-1:-1:-1;;;;;3355:6:0;3339:12;:10;:12::i;:::-;-1:-1:-1;;;;;3339:22:0;;3332:29;;3275:94;:::o;24674:50::-;;;;;;;;;;;;;:::o;50762:1027::-;33216:8;;50971:17;;;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;51039:37;;;:84;;;;-1:-1:-1;51080:43:0;;;51039:84;51031:111;;;;-1:-1:-1;;;51031:111:0;;;;;;;;;51160:9;51155:378;51175:19;;;51155:378;;;51243:44;51272:11;;51284:1;51272:14;;;;;;;;;;;;;51243:11;:24;51255:8;;51264:1;51255:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51243:24:0;;;;;;;;;;;;-1:-1:-1;51243:24:0;;;:44;:28;:44;:::i;:::-;51216:11;:24;51228:8;;51237:1;51228:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51216:24:0;;;;;;;;;;;;-1:-1:-1;51216:24:0;:71;51314:29;51328:11;;51340:1;51328:14;;;;;;;;;;;;;51314:9;:13;;:29;;;;:::i;:::-;51302:41;;51391:56;51426:17;;51444:1;51426:20;;;;;;;;;;;;;51391:17;:30;51409:8;;51418:1;51409:11;;;;;;51391:56;51358:17;:30;51376:8;;51385:1;51376:11;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51358:30:0;;;;;;;;;;;;-1:-1:-1;51358:30:0;:89;51480:41;51500:17;;51518:1;51500:20;;;;;;;;;;;;;51480:15;:19;;:41;;;;:::i;:::-;51462:59;-1:-1:-1;51196:3:0;;51155:378;;;-1:-1:-1;51547:14:0;;51543:110;;51578:63;;-1:-1:-1;;;51578:63:0;;-1:-1:-1;;;;;;;;;;;27080:42:0;51578:25;;:63;;51604:10;;51624:4;;51631:9;;51578:63;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51578:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51578:63:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;51578:63:0;;;;;;;;;;51543:110;51667:20;;51663:119;;51704:66;;-1:-1:-1;;;51704:66:0;;27416:42;;51704:22;;:66;;51727:10;;51747:4;;51754:15;;51704:66;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51704:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51704:66:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;51704:66:0;;;;;;;;;;51663:119;50762:1027;;;;;;;;;:::o;27468:73::-;27499:42;27468:73;:::o;24140:64::-;;;;;;;;;;;;;:::o;23245:20::-;;;-1:-1:-1;;;23245:20:0;;;;;:::o;69596:145::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;69708:25;:16;69727:6;;69708:25;:::i;:::-;;69596:145;;:::o;23633:72::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;34742:1902::-;33216:8;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;43803:18;;43868:24;;34887:10;;43803:18;43773:27;;;;44030:114;34887:10;43803:18;43868:24;44030:7;:114::i;:::-;-1:-1:-1;;;;;44155:32:0;;;;;;:23;:32;;;;;;;;:54;;;44220:29;:38;;;;;:66;;;44351:11;:20;;;;;:41;;;44403:17;:26;;;;;:53;;;43905:239;;-1:-1:-1;43905:239:0;;-1:-1:-1;43905:239:0;-1:-1:-1;43905:239:0;-1:-1:-1;44522:187:0;44179:7;43905:239;;;;44522:12;:187::i;:::-;-1:-1:-1;;;;;44470:20:0;;;;;;:11;:20;;;;;;;;44492:17;:26;;;;;44469:240;;;;;;;;44720:15;:24;;;;44747:15;44720:42;;34940:13;;34923;;:30;34915:57;;;;-1:-1:-1;;;34915:57:0;;;;;;;;;35020:10;34985:23;35011:20;;;:8;:20;;;;;;-1:-1:-1;;;;;35011:20:0;;34985:23;;;35131:1506;35155:6;:13;35151:1;:17;35131:1506;;;35198:6;35205:1;35198:9;;;;;;;;;;;;;;35190:17;;-1:-1:-1;;;;;;;;;;;;;;;;35230:13:0;:5;-1:-1:-1;;;;;35230:13:0;;:31;;;-1:-1:-1;;;;;;35247:14:0;;27161:42;35247:14;35230:31;:49;;;-1:-1:-1;;;;;;35265:14:0;;27242:42;35265:14;35230:49;:69;;;-1:-1:-1;;;;;;35283:16:0;;27325:42;35283:16;35230:69;35222:95;;;;-1:-1:-1;;;35222:95:0;;;;;;;;;35350:6;35357:1;35350:9;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35389:24:0;;;;;;:17;:24;;;;;;35414:10;35389:36;;;;;;;;;;35350:9;;-1:-1:-1;35389:36:0;-1:-1:-1;35444:18:0;;;:39;;-1:-1:-1;35466:17:0;;35444:39;35440:88;;;35504:8;;35440:88;35562:12;35546:13;:28;35542:97;;;35611:12;35595:28;;35542:97;-1:-1:-1;;;;;35655:24:0;;;;;;;:17;:24;;;;;;;;35680:10;35655:36;;;;;;;35694:28;;;35655:67;;35788:27;;;:20;:27;;;;;;;:43;;;35758:73;;35895:34;;;;;:17;:34;;;;;:41;;;;;;;;;35955:31;;;35951:233;;;-1:-1:-1;;;;;36007:34:0;;;;;;;:17;:34;;;;;;;;:41;;;;;;;;;36051:31;;;36007:75;;35951:233;;;-1:-1:-1;;;;;36123:34:0;;;36167:1;36123:34;;;:17;:34;;;;;;;;:41;;;;;;;;;;;:45;35951:233;-1:-1:-1;;;;;36204:13:0;;-1:-1:-1;;;;;;;;;;;36204:13:0;:70;;;;-1:-1:-1;36221:37:0;;-1:-1:-1;;;36221:37:0;;36261:13;;-1:-1:-1;;;;;;;;;;;27080:42:0;36221:22;;:37;;36252:4;;36221:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36221:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36221:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;36221:37:0;;;;;;;;;:53;36204:70;36200:193;;;27161:42;-1:-1:-1;;;;;36349:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36349:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36349:28:0;;;;36200:193;36409:53;-1:-1:-1;;;;;36409:26:0;;36436:10;36448:13;36409:53;:26;:53;:::i;:::-;36563:15;-1:-1:-1;;;;;36484:141:0;36539:5;-1:-1:-1;;;;;36484:141:0;36510:10;-1:-1:-1;;;;;36484:141:0;;36597:13;36484:141;;;;;;;;;;;;;;;35131:1506;;35170:3;;35131:1506;;;;44775:1;;;;33246;;;;;;;34742:1902;;:::o;71217:211::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;71356:4;71338:14;:22;;71330:49;;;;-1:-1:-1;;;71330:49:0;;;;;;;;;71390:13;:30;71217:211::o;27707:73::-;27738:42;27707:73;:::o;33263:1471::-;33216:8;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;43803:18;;43868:24;;33412:10;;43803:18;43773:27;;;;44030:114;33412:10;43803:18;43868:24;44030:7;:114::i;:::-;-1:-1:-1;;;;;44155:32:0;;;;;;:23;:32;;;;;;;;:54;;;44220:29;:38;;;;;:66;;;44351:11;:20;;;;;:41;;;44403:17;:26;;;;;:53;;;43905:239;;-1:-1:-1;43905:239:0;;-1:-1:-1;43905:239:0;-1:-1:-1;43905:239:0;-1:-1:-1;44522:187:0;44179:7;43905:239;;;;44522:12;:187::i;:::-;-1:-1:-1;;;;;44470:20:0;;;;;;:11;:20;;;;;;;;44492:17;:26;;;;;44469:240;;;;;;;;44720:15;:24;;;;44747:15;44720:42;;33448:30;;;33440:57;;;;-1:-1:-1;;;33440:57:0;;;;;;;;;33545:10;33510:23;33536:20;;;:8;:20;;;;;;-1:-1:-1;;;;;33536:20:0;33571:29;33567:194;;-1:-1:-1;33635:10:0;33660:20;;;;:8;:20;;;;;:38;;-1:-1:-1;;;;;;33660:38:0;;;;;33713:36;:13;33635:10;33713:36;:24;:36;:::i;:::-;;33567:194;33773:13;;;33829:898;33849:17;;;33829:898;;;33896:6;;33903:1;33896:9;;;;;;;;;;;;;;;;;;;;;;33888:17;-1:-1:-1;;;;;;33928:13:0;;-1:-1:-1;;;;;;;;;;;33928:13:0;;:31;;-1:-1:-1;;;;;;33945:14:0;;27161:42;33945:14;33928:31;:49;;;-1:-1:-1;;;;;;33963:14:0;;27242:42;33963:14;33928:49;:69;;;-1:-1:-1;;;;;;33981:16:0;;27325:42;33981:16;33928:69;33920:95;;;;-1:-1:-1;;;33920:95:0;;;;;;;;;34046:6;;34053:1;34046:9;;;;;;;;;;;;;34032:23;;34074:11;34089:1;34074:16;34070:65;;;34111:8;;34070:65;-1:-1:-1;;;;;34190:24:0;;;;;;:17;:24;;;;;;;;34215:10;34190:36;;;;;;;;:53;;34231:11;34190:53;:40;:53;:::i;:::-;-1:-1:-1;;;;;34151:24:0;;;;;;:17;:24;;;;;;;;34176:10;34151:36;;;;;;;:92;;;;34288:27;;;:20;:27;;;;;:44;;34320:11;34288:44;:31;:44;:::i;:::-;-1:-1:-1;;;;;34258:27:0;;;;;;;:20;:27;;;;;;;;:74;;;;34393:34;;;;;:17;:34;;;;;:41;;;;;;;:76;;34457:11;34393:76;:63;:76;:::i;:::-;-1:-1:-1;;;;;34349:34:0;;;;;;;:17;:34;;;;;;;;:41;;;;;;;;;;;;:120;;;;34486:70;;34517:10;34537:4;34544:11;34486:70;:30;:70;:::i;:::-;34655:15;-1:-1:-1;;;;;34578:137:0;34631:5;-1:-1:-1;;;;;34578:137:0;34602:10;-1:-1:-1;;;;;34578:137:0;;34689:11;34578:137;;;;;;;;;;;;;;;33829:898;33868:3;;33829:898;;;;44775:1;;;33246;;;;;;;33263:1471;;;;:::o;24842:36::-;;;;:::o;59358:209::-;59460:19;59481;59525:34;59542:16;59525:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59525:34:0;;;;;;;;;;;;;;;;;;;;;:16;:34::i;:::-;59518:41;;;;59358:209;;:::o;28106:63::-;28161:8;28106:63;:::o;28761:47::-;28804:4;28761:47;:::o;24733:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;24733:46:0;;-1:-1:-1;24733:46:0;;-1:-1:-1;24733:46:0:o;27548:72::-;27578:42;27548:72;:::o;39579:320::-;33216:8;;39691:31;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;43803:18;;43868:24;;39661:10;;43803:18;43773:27;;;;44030:114;39661:10;43803:18;43868:24;44030:7;:114::i;:::-;-1:-1:-1;;;;;44155:32:0;;;;;;:23;:32;;;;;;;;:54;;;44220:29;:38;;;;;:66;;;44351:11;:20;;;;;:41;;;44403:17;:26;;;;;:53;;;43905:239;;-1:-1:-1;43905:239:0;;-1:-1:-1;43905:239:0;-1:-1:-1;43905:239:0;-1:-1:-1;44522:187:0;44179:7;43905:239;;;;44522:12;:187::i;:::-;-1:-1:-1;;;;;44470:20:0;;;;;;:11;:20;;;;;;;;44492:17;:26;;;;;44469:240;;;;;;;;44720:15;:24;;;;44747:15;44720:42;;39766:12;:10;:12::i;:::-;39740:38;;39816:10;-1:-1:-1;;;;;39796:95:0;;39841:1;39857:23;39796:95;;;;;;;;42003:531;42117:16;;;42131:1;42117:16;;;;;;;;;42091:23;;42117:16;;;17:15:-1;;105:10;42117:16:0;88:34:-1;-1:-1;;42170:16:0;;;42184:1;42170:16;;;;;;;;;42091:42;;-1:-1:-1;42144:23:0;;42170:16;-1:-1:-1;42170:16:0;;;17:15:-1;;105:10;42170:16:0;88:34:-1;136:17;;-1:-1;42170:16:0;42144:42;;27242;42197:6;42204:1;42197:9;;;;;;;;;;;;;:17;-1:-1:-1;;;;;42197:17:0;;;-1:-1:-1;;;;;42197:17:0;;;;;27325:42;42225:6;42232:1;42225:9;;;;;;;;;;;;;:19;-1:-1:-1;;;;;42225:19:0;;;-1:-1:-1;;;;;42225:19:0;;;;;27161:42;42255:6;42262:1;42255:9;;;;;;;;;;;;;:17;-1:-1:-1;;;;;42255:17:0;;;-1:-1:-1;;;;;42255:17:0;;;;;-1:-1:-1;;;;;;;;;;;42283:6:0;42290:1;42283:9;;;;;;;;;;;;;:16;-1:-1:-1;;;;;42283:16:0;;;-1:-1:-1;;;;;42283:16:0;;;;;-1:-1:-1;;42310:6:0;42317:1;42310:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;42344:6:0;42351:1;42344:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;42378:6:0;42385:1;42378:9;;;;;;;;;;;;;:23;;;;;-1:-1:-1;;42412:6:0;42419:1;42412:9;;;;;;;;;;;;;:23;;;;;42456;42464:6;42472;42456:7;:23::i;:::-;42513:13;42520:5;42513:6;:13::i;23746:33::-;;;;:::o;57596:564::-;57760:17;;27161:42;57673:14;57714:27;;;:20;:27;;;;57673:14;;57714:88;;57797:4;;57714:64;;:27;:64;:45;:64;:::i;:88::-;-1:-1:-1;;;;;;;;;;;57824:26:0;;:20;:26;;-1:-1:-1;;;;;;;;;;;57824:26:0;57705:97;;-1:-1:-1;57824:52:0;;57705:97;57824:52;:44;:52;:::i;:::-;57944:17;;27242:42;57898:27;;:20;:27;;;;57815:61;;-1:-1:-1;57898:114:0;;57815:61;;57898:88;;57981:4;;57898:64;;:27;:64;:45;:64;:::i;:114::-;58082:19;;27325:42;58034:29;;:20;:29;;;;57889:123;;-1:-1:-1;58034:118:0;;57889:123;;58034:92;;58121:4;;58034:68;;:29;:68;:47;:68;:::i;:118::-;58025:127;;57596:564;:::o;3524:109::-;3141:9;:7;:9::i;:::-;3133:34;;;;-1:-1:-1;;;3133:34:0;;;;;;;;;3597:28;3616:8;3597:18;:28::i;:::-;3524:109;:::o;27049:73::-;-1:-1:-1;;;;;;;;;;;27049:73:0;:::o;51857:507::-;33216:8;;-1:-1:-1;;;33216:8:0;;;;33215:9;33207:28;;;;-1:-1:-1;;;33207:28:0;;;;;;;;;51994:12;;;;:34;;-1:-1:-1;52010:18:0;;;51994:34;51990:367;;;52045:35;52057:7;52066:13;52045:11;:35::i;:::-;52099:12;;52095:114;;52132:61;;-1:-1:-1;;;52132:61:0;;-1:-1:-1;;;;;;;;;;;27080:42:0;52132:25;;:61;;52158:10;;52178:4;;52185:7;;52132:61;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52132:61:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52132:61:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52132:61:0;;;;;;;;;;52095:114;52227:18;;52223:123;;52266:64;;-1:-1:-1;;;52266:64:0;;27416:42;;52266:22;;:64;;52289:10;;52309:4;;52316:13;;52266:64;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52266:64:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52266:64:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52266:64:0;;;;;;;;52223:123;51857:507;;:::o;46023:3143::-;-1:-1:-1;;;;;46372:32:0;;46187:25;46372:32;;;:23;:32;;;;;;46187:25;;;;;;;;46354:51;;:13;;:51;:17;:51;:::i;:::-;-1:-1:-1;;;;;46475:38:0;;46416:32;46475:38;;;:29;:38;;;;;;46325:80;;-1:-1:-1;46416:32:0;46451:63;;:19;;:63;:23;:63;:::i;:::-;-1:-1:-1;;;;;46547:20:0;;;;;;:11;:20;;;;;;;;;46604:17;:26;;;;;;46662:11;:20;;;;;;46720:17;:26;;;;;;;;46547:20;;-1:-1:-1;46604:26:0;-1:-1:-1;46662:20:0;-1:-1:-1;46720:26:0;-1:-1:-1;46416:98:0;-1:-1:-1;46763:23:0;;;;:56;;-1:-1:-1;46790:29:0;;;46763:56;46759:2400;;;46836:13;46864:18;46897:16;46931:21;46954:22;46980:24;46996:7;46980:15;:24::i;:::-;46930:74;;-1:-1:-1;46930:74:0;-1:-1:-1;47029:55:0;46930:74;47065:18;47029:55;:35;:55;:::i;:::-;-1:-1:-1;;;47099:13:0;;;-1:-1:-1;47147:46:0;47099:13;47175:17;47147:27;:46::i;:::-;47127:66;-1:-1:-1;47218:61:0;:13;47254:24;47218:61;:35;:61;:::i;:::-;-1:-1:-1;;;47294:13:0;;;-1:-1:-1;47348:52:0;47294:13;47376:23;47348:27;:52::i;:::-;47322:78;-1:-1:-1;47421:19:0;;;;;:46;;-1:-1:-1;47444:23:0;;;47421:46;47417:800;;;47548:60;:14;47589:18;47548:60;:40;:60;:::i;:::-;-1:-1:-1;;;47627:13:0;;;-1:-1:-1;47680:51:0;:18;47627:13;47680:44;:51::i;:::-;-1:-1:-1;;;;;47831:24:0;;;;;;:15;:24;;;;;;47659:72;;-1:-1:-1;47831:24:0;;-1:-1:-1;47887:123:0;;-1:-1:-1;;;47932:4:0;47831:24;47887:22;:123::i;:::-;47874:136;-1:-1:-1;48037:43:0;:5;47874:136;48037:43;:31;:43;:::i;:::-;-1:-1:-1;;;48099:13:0;;;-1:-1:-1;48151:50:0;:17;48099:13;48151:43;:50::i;:::-;48131:70;;47417:800;48235:19;;;;;:52;;-1:-1:-1;48258:29:0;;;48235:52;48231:917;;;48368:66;:14;48409:24;48368:66;:40;:66;:::i;:::-;-1:-1:-1;;;48453:13:0;;;-1:-1:-1;48512:57:0;:24;48453:13;48512:50;:57::i;:::-;48485:84;-1:-1:-1;48662:13:0;48658:272;;-1:-1:-1;;;;;48711:24:0;;;;;;:15;:24;;;;;;;-1:-1:-1;48771:139:0;;-1:-1:-1;;;48820:4:0;48711:24;48771:22;:139::i;:::-;48758:152;;48658:272;48956:43;:5;48988:10;48956:43;:31;:43;:::i;:::-;-1:-1:-1;;;49018:13:0;;;-1:-1:-1;49076:56:0;:23;49018:13;49076:49;:56::i;:::-;49050:82;;48231:917;46759:2400;;;;;;46023:3143;;;;;;;;;:::o;49174:1520::-;-1:-1:-1;;;;;49491:24:0;;49431:7;49491:24;;;:15;:24;;;;;;49431:7;;49551:15;49532:34;;49528:1095;;49583:21;49619:18;49640:128;-1:-1:-1;;;49704:15:0;49738;49640:22;:128::i;:::-;49619:149;-1:-1:-1;49789:23:0;;49785:221;;49849:88;-1:-1:-1;;;49849:56:0;:18;49894:10;49849:56;:44;:56;:::i;:88::-;49956:34;;;;49833:104;-1:-1:-1;49785:221:0;50026:29;;50022:239;;50092:94;-1:-1:-1;;;50092:62:0;:24;50143:10;50092:62;:50;:62;:::i;:94::-;50205:40;;;;50076:110;-1:-1:-1;50022:239:0;-1:-1:-1;;;;;50300:33:0;;50277:20;50300:33;;;-1:-1:-1;;;;;;;;;;;50300:24:0;:33;:24;:33;;;50352:17;;50348:264;;50461:82;-1:-1:-1;;;50461:50:0;:12;50500:10;50461:50;:38;:50;:::i;:82::-;50562:34;;;;50445:98;-1:-1:-1;50348:264:0;49528:1095;;;;-1:-1:-1;50643:17:0;;50662:23;;-1:-1:-1;49174:1520:0;;-1:-1:-1;;;;49174:1520:0:o;9171:471::-;9229:7;9474:6;9470:47;;-1:-1:-1;9504:1:0;9497:8;;9470:47;9541:5;;;9545:1;9541;:5;:1;9565:5;;;;;:10;9557:56;;;;-1:-1:-1;;;9557:56:0;;;;;;;;;9633:1;-1:-1:-1;9171:471:0;;;;;:::o;10110:132::-;10168:7;10195:39;10199:1;10202;10195:39;;;;;;;;;;;;;;;;;:3;:39::i;8255:136::-;8313:7;8340:43;8344:1;8347;8340:43;;;;;;;;;;;;;;;;;:3;:43::i;39907:377::-;39983:25;40010:31;40079:19;40090:7;40079:10;:19::i;:::-;40059:39;;40135:12;:10;:12::i;:::-;40109:38;;40185:10;-1:-1:-1;;;;;40165:111:0;;40210:17;40242:23;40165:111;;;;;;;;;;;;;;;;39907:377;;;:::o;14168:621::-;14538:10;;;14537:62;;-1:-1:-1;14554:39:0;;-1:-1:-1;;;14554:39:0;;-1:-1:-1;;;;;14554:15:0;;;;;:39;;14578:4;;14585:7;;14554:39;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14554:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;14554:39:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;14554:39:0;;;;;;;;;:44;14537:62;14529:152;;;;-1:-1:-1;;;14529:152:0;;;;;;;;;14718:62;;14692:89;;14711:5;;-1:-1:-1;;;14741:22:0;14718:62;;14765:7;;14774:5;;14718:62;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;14718:62:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;14718:62:0;;;179:29:-1;;;;160:49;;;14692:18:0;:89::i;7799:181::-;7857:7;7889:5;;;7913:6;;;;7905:46;;;;-1:-1:-1;;;7905:46:0;;;;;;;;40292:737;40447:10;40372:25;40435:23;;;:11;:23;;;;;;40473:22;;40469:553;;40524:10;40538:1;40512:23;;;:11;:23;;;;;:27;40554:457;;;;40586:104;40621:10;40654:17;40586:12;:104::i;:::-;40554:457;;;40735:37;;-1:-1:-1;;;40735:37:0;;40775:17;;-1:-1:-1;;;;;;;;;;;27080:42:0;40735:22;;:37;;40766:4;;40735:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40735:37:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40735:37:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;40735:37:0;;;;;;;;;:57;40731:192;;;27161:42;-1:-1:-1;;;;;40875:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40875:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40875:28:0;;;;40731:192;40943:52;;-1:-1:-1;;;40943:52:0;;-1:-1:-1;;;;;;;;;;;27080:42:0;40943:21;;:52;;40965:10;;40977:17;;40943:52;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40943:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;40943:52:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;40943:52:0;;;;;;;;;;40292:737;;;:::o;59926:495::-;60081:69;;-1:-1:-1;;;60081:69:0;;60020:16;;;;28054:42;;60081:16;;:69;;60098:6;;60114:4;;60121:28;;60081:69;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60081:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60081:69:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;60081:69:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;60081:69:0;;;;;;;;;60054:96;-1:-1:-1;60168:9:0;60163:158;60187:6;:13;60183:1;:17;60163:158;;;60250:59;60298:7;60306:1;60298:10;;;;;;;;;;;;;;60250:14;:25;60265:6;60272:1;60265:9;;;;;;;;;;;;;;-1:-1:-1;;;;;60250:25:0;-1:-1:-1;;;;;60250:25:0;;;;;;;;;;;;;:47;;:59;;;;:::i;:::-;60222:14;:25;60237:6;60244:1;60237:9;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60222:25:0;;;;;;;;;;;-1:-1:-1;60222:25:0;:87;60202:3;;60163:158;;;-1:-1:-1;60338:48:0;;60365:10;;60338:48;;;;;60406:7;59926:495;-1:-1:-1;;59926:495:0:o;60429:1808::-;60557:18;60577;60638:7;:14;60621:6;:13;:31;60613:58;;;;-1:-1:-1;;;60613:58:0;;;;;;;;;60685:22;28054:42;-1:-1:-1;;;;;60722:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60722:16:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60722:16:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;60722:16:0;;;;;;;;;60685:54;;60751:16;60772:10;-1:-1:-1;;;;;60772:20:0;;-1:-1:-1;;;;;;;;;;;27499:42:0;60772:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60772:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60772:69:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;60772:69:0;;;;;;;;;-1:-1:-1;60878:22:0;;60750:91;;-1:-1:-1;60852:23:0;;;;;61023:705;61047:6;:13;61043:1;:17;61023:705;;;61090:6;61097:1;61090:9;;;;;;;;;;;;;;61082:17;;-1:-1:-1;;;;;;;;;;;;;;;;61118:13:0;:5;-1:-1:-1;;;;;61118:13:0;;61114:437;;;61152:8;;61114:437;-1:-1:-1;;;;;61186:12:0;;27578:42;61186:12;61182:369;;;61231:25;61245:7;61253:1;61245:10;;;;;;;;;;;;;;61231:9;:13;;:25;;;;:::i;:::-;61219:37;;61275:8;;61182:369;-1:-1:-1;;;;;61309:13:0;;27658:42;61309:13;61305:246;;;61356:26;61371:7;61379:1;61371:10;;;;;;;;;;;;;;61356;:14;;:26;;;;:::i;:::-;61343:39;;61401:8;;61305:246;-1:-1:-1;;;;;61435:13:0;;27738:42;61435:13;61431:120;;;61482:26;61497:7;61505:1;61497:10;;;;;;;;;;;;;;61482;:14;;:26;;;;:::i;:::-;61469:39;;61527:8;;61431:120;61571:7;61579:1;61571:10;;;;;;;;;;;;;;61585:1;61571:15;61567:150;;61621:80;61644:5;61651:7;61659:1;61651:10;;;;;;;;;;;;;;61663;61675:8;61685:15;61621:22;:80::i;:::-;61607:94;;;;61567:150;61062:3;;61023:705;;;-1:-1:-1;61742:15:0;;61738:82;;-1:-1:-1;;;;;;;;;;;61774:20:0;;:14;:20;;;:34;;;;;;61738:82;61836:14;;;;:33;;-1:-1:-1;61854:15:0;;;61836:33;:52;;;-1:-1:-1;61873:15:0;;;61836:52;61832:283;;;61918:122;61958:9;61986:10;62015;61918:21;:122::i;:::-;27416:42;62055:34;;:14;:34;;;:48;;;;;;61905:135;-1:-1:-1;61832:283:0;62158:10;-1:-1:-1;;;;;62132:97:0;;62183:10;62208;62132:97;;;;;;;;;;;;;;;;60429:1808;;;;;;;;;;;;:::o;62245:1953::-;62380:14;:20;;;;27416:42;62308:19;62425:34;;;62474:16;;;;:36;;-1:-1:-1;62494:16:0;;;62474:36;62470:1601;;;62550:11;;-1:-1:-1;;;;;62550:11:0;62527:20;;62650:16;;62646:669;;-1:-1:-1;;;;;;;;;;;62710:1:0;62687:20;;;:14;:20;;;:24;62785:13;;62747:84;;62826:4;;62747:52;;:11;;:52;:37;:52;:::i;:84::-;62850:124;;-1:-1:-1;;;62850:124:0;;62732:99;;-1:-1:-1;;;;;;;;;;;;27080:42:0;62850:21;;:124;;62894:12;;62929:26;;;;62850:124;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62850:124:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62850:124:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;62850:124:0;;;;;;;;;;63007:12;62993:26;;63069:19;;63055:11;:33;;;;;63107:108;;-1:-1:-1;;;63107:108:0;;63055:33;;;;-1:-1:-1;;;;;;;;;;;;27080:42:0;63107:21;;:108;;63151:10;;63055:33;;63107:108;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63107:108:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63107:108:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63107:108:0;;;;;;;;;-1:-1:-1;63248:51:0;:11;63286:12;63248:51;:37;:51;:::i;:::-;63234:65;;62646:669;63333:16;;63329:677;;27416:42;63407:1;63370:34;;;:14;:34;;;:38;63482:13;;63444:84;;63523:4;;63444:52;;:11;;:52;:37;:52;:::i;:84::-;63547:121;;-1:-1:-1;;;63547:121:0;;63429:99;;-1:-1:-1;27416:42:0;;63547:18;;:121;;63588:12;;63623:26;;;;63547:121;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63547:121:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63547:121:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63547:121:0;;;;;;;;;;63701:12;63687:26;;63763:19;;63749:11;:33;;;;;63801:105;;-1:-1:-1;;;63801:105:0;;63749:33;;;;-1:-1:-1;27416:42:0;;63801:18;;:105;;63842:10;;63749:33;;63801:105;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63801:105:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63801:105:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;63801:105:0;;;;;;;;;-1:-1:-1;63939:51:0;:11;63977:12;63939:51;:37;:51;:::i;:::-;63925:65;;63329:677;64022:37;64034:11;64047;64022;:37::i;:::-;62470:1601;;;;64117:10;-1:-1:-1;;;;;64088:102:0;;64142:11;64168;64088:102;;;;;;;;;;;;;;;;62245:1953;;:::o;13092:115::-;13155:7;13187:2;13182;:7;:17;;13197:2;13182:17;;;-1:-1:-1;13192:2:0;;13092:115;-1:-1:-1;13092:115:0:o;1720:98::-;1800:10;1720:98;:::o;13772:176::-;13881:58;;13855:85;;13874:5;;-1:-1:-1;;;13904:23:0;13881:58;;13929:2;;13933:5;;13881:58;;;;17687:245;17786:4;17865:9;17902:22;17913:3;17865:9;17902:10;:22::i;:::-;17895:29;17687:245;-1:-1:-1;;;;17687:245:0:o;13956:204::-;14083:68;;14057:95;;14076:5;;-1:-1:-1;;;14106:27:0;14083:68;;14135:4;;14141:2;;14145:5;;14083:68;;;;41037:345;41189:10;41096:31;41171:29;;;:17;:29;;;;;;41215:28;;41211:164;;41278:10;41292:1;41260:29;;;:17;:29;;;;;;:33;;;;41308:55;-1:-1:-1;;;41308:55:0;;27416:42;;41308:18;;:55;;41278:10;41339:23;;41308:55;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41308:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41308:55:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;41308:55:0;;;;;;;;;;41037:345;:::o;3739:229::-;-1:-1:-1;;;;;3813:22:0;;3805:73;;;;-1:-1:-1;;;3805:73:0;;;;;;;;;3915:6;;;3894:38;;-1:-1:-1;;;;;3894:38:0;;;;3915:6;;;3894:38;;;3943:6;:17;;-1:-1:-1;;;;;;3943:17:0;-1:-1:-1;;;;;3943:17:0;;;;;;;;;;3739:229::o;52372:761::-;52548:20;:18;:20::i;:::-;52525:19;52486:82;52506:17;52486:82;52487:17;52486:82;52487:17;52603:19;:17;:19::i;:::-;52581:41;-1:-1:-1;52641:16:0;52633:43;;;;-1:-1:-1;;;52633:43:0;;;;;;;;;52791:18;;52710:100;;:62;52760:11;52710:31;:7;-1:-1:-1;;;52710:31:0;:25;:31;:::i;:100::-;52689:18;:121;52937:24;;52850:112;;:68;52906:11;52850:37;:13;-1:-1:-1;;;52850:37:0;:31;:37;:::i;:112::-;52823:24;:139;52996:15;52975:18;:36;53029:96;;53054:10;;53029:96;;;;53079:7;;53101:13;;53029:96;;;;;;;;;;52372:761;;;:::o;10772:346::-;10858:7;10961:12;10953:6;10945:29;;;;-1:-1:-1;;;10945:29:0;;;;;;;;;;;10985:9;11001:1;10997;:5;;;;8728:192;8814:7;8850:12;8842:6;;;;8834:29;;;;-1:-1:-1;;;8834:29:0;;;;;;;;;;-1:-1:-1;;;8886:5:0;;;8728:192::o;15811:1114::-;16415:27;16423:5;-1:-1:-1;;;;;16415:25:0;;:27::i;:::-;16407:71;;;;-1:-1:-1;;;16407:71:0;;;;;;;;;16552:12;16566:23;16601:5;-1:-1:-1;;;;;16593:19:0;16613:4;16593:25;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;16551:67:0;;;;16637:7;16629:52;;;;-1:-1:-1;;;16629:52:0;;;;;;;;;16698:17;;:21;16694:224;;16840:10;16829:30;;;;;;;;;;;;;;16821:85;;;;-1:-1:-1;;;16821:85:0;;;;;;;;41390:605;-1:-1:-1;;;;;41524:17:0;;;41498:23;41524:17;;;:8;:17;;;;;;;;;-1:-1:-1;;;;;;;;;;;41587:32:0;;;;;;;41524:17;;;41587:58;;41638:6;41587:50;:58::i;:::-;-1:-1:-1;;;;;41552:32:0;;:23;:32;;;-1:-1:-1;;;;;;;;;;;41552:23:0;:32;;;:23;:32;;:93;;;;-1:-1:-1;;;;;;;;;;;41687:26:0;;:20;:26;;-1:-1:-1;;;;;;;;;;;41687:26:0;:52;;41732:6;41687:52;:44;:52;:::i;:::-;-1:-1:-1;;;;;;;;;;;41658:81:0;-1:-1:-1;;;;;41795:34:0;;41658:26;41795:34;;;:17;41658:26;41795:34;;;41658:26;41795:34;;;-1:-1:-1;;;;;;;;;;;41795:40:0;;;;;;;;:66;;41854:6;41795:66;:58;:66;:::i;:::-;-1:-1:-1;;;;;41752:34:0;;;;;;;:17;:34;;;;;;;;-1:-1:-1;;;;;;;;;;;41752:40:0;;;;;;;;;:109;;;;41879:108;41752:34;;27080:42;41879:108;;;;;;;41970:6;;41879:108;;;;;;;;;;41390:605;;;:::o;64206:1121::-;-1:-1:-1;;;;;64480:21:0;;64418:20;64480:21;;;:14;:21;;;;;;64516:18;;64512:808;;64564:13;64555:6;:22;64551:85;;;64607:13;64598:22;;64551:85;64674:43;:13;64710:6;64674:43;:35;:43;:::i;:::-;-1:-1:-1;;;;;64650:21:0;;;;;;:14;:21;;;;;;;;:67;;;;64879:9;:16;;;;;64761:215;;-1:-1:-1;;;64761:215:0;;64734:24;;27855:42;;64761:38;;:215;;64818:6;;64843:1;;64922:4;;64946:15;;64761:215;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64761:215:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64761:215:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;64761:215:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;64761:215:0;;;;;;;;;64734:242;;65008:7;65033:1;65016:7;:14;:18;65008:27;;;;;;;;;;;;;;64993:42;;65102:206;65142:5;65166:6;65191:12;65222:10;65251:8;65278:15;65102:21;:206::i;:::-;64512:808;;64206:1121;;;;;;;;:::o;65335:2121::-;65489:20;65527:30;;:::i;:::-;65568:18;;65635:14;;65631:431;;-1:-1:-1;27578:42:0;65682:19;;:14;:19;;;;65720:18;;65716:335;;65775:13;65763:9;:25;65759:99;;;65825:13;65813:25;;65759:99;65898:50;:13;65938:9;65898:50;:39;:50;:::i;:::-;27578:42;65876:19;;:14;:19;;;:72;65967:27;;;65985:9;;-1:-1:-1;65716:335:0;66076:15;;66072:493;;-1:-1:-1;27658:42:0;66124:20;;:14;:20;;;;66163:18;;66159:395;;66219:13;66206:10;:26;66202:101;;;66270:13;66257:26;;66202:101;66344:51;:13;66384:10;66344:51;:39;:51;:::i;:::-;27658:42;66321:20;;:14;:20;;;:74;66432:10;66414:12;66427:1;66414:15;;;:28;66474:36;66489:20;:10;66504:4;66489:20;:14;:20;:::i;:::-;66474:10;;:36;:14;:36;:::i;:::-;66461:49;;66159:395;66579:15;;66575:493;;-1:-1:-1;27738:42:0;66627:20;;:14;:20;;;;66666:18;;66662:395;;66722:13;66709:10;:26;66705:101;;;66773:13;66760:26;;66705:101;66847:51;:13;66887:10;66847:51;:39;:51;:::i;:::-;27738:42;66824:20;;:14;:20;;;:74;66917:15;;;:28;;;66977:36;66992:20;66935:10;67007:4;66992:14;:20::i;66977:36::-;66964:49;;66662:395;67104:34;;-1:-1:-1;;;67104:34:0;;67080:21;;27416:42;;67104:19;;:34;;67132:4;;67104:34;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67104:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67104:34:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;67104:34:0;;;;;;;;;67149:41;;-1:-1:-1;;;67149:41:0;;67080:58;;-1:-1:-1;27958:42:0;;67149:24;;:41;;67174:12;;67188:1;;67149:41;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67149:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;67218:34:0;;-1:-1:-1;;;67218:34:0;;67255:13;;-1:-1:-1;27416:42:0;;-1:-1:-1;67218:19:0;;:34;;67246:4;;67218:34;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67218:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67218:34:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;67218:34:0;;;;;;;;;:50;67203:65;;67327:121;67365:10;67390:12;67417:20;;67327:23;:121::i;:::-;65335:2121;;;;;;;;;:::o;18058:289::-;18153:4;18180:20;18189:3;18194:5;18180:8;:20::i;:::-;18175:165;;-1:-1:-1;18235:10:0;;;;27::-1;;23:18;;;45:23;;;-1:-1;18235:22:0;;;;;;;;;;;;;18216:16;;;;;;;;;;;:41;18272:11;;18175:165;-1:-1:-1;18323:5:0;18316:12;;4657:619;4717:4;5185:20;;5028:66;5225:23;;;;;;:42;;-1:-1:-1;;5252:15:0;;;5217:51;-1:-1:-1;;4657:619:0:o;67468:1026::-;67726:12;67740:17;67761:10;-1:-1:-1;;;;;67761:20:0;;67796:5;27499:42;67761:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67761:70:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67761:70:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;67761:70:0;;;;;;;;;67725:106;;-1:-1:-1;67725:106:0;-1:-1:-1;67851:85:0;67927:8;67851:57;67725:106;67851:57;67725:106;-1:-1:-1;;;67851:28:0;:22;:28;:::i;:85::-;67844:92;-1:-1:-1;67949:28:0;67980:65;68033:11;67980:34;:10;68009:4;67980:34;:28;:34;:::i;:65::-;67949:96;;68058:19;68103:4;68080:20;:27;:113;;68173:20;68166:4;:27;68080:113;;;68146:4;68123:20;:27;68080:113;68058:135;-1:-1:-1;68210:16:0;;68206:281;;68257:83;68319:20;68257:39;:11;68291:4;68257:39;:33;:39;:::i;:83::-;68243:97;;68398:15;68383:11;:30;;68357:118;;;;-1:-1:-1;;;68357:118:0;;;;;;;;;67468:1026;;;;;;;;;;:::o;68502:769::-;68717:22;68742:84;27958:42;-1:-1:-1;;;;;68795:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68795:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68795:30:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;68795:30:0;;;;;;;;;68742:34;:10;68771:4;68742:34;:28;:34;:::i;:84::-;68717:109;;68839:19;68876:14;68861:12;:29;:119;;68968:12;68951:14;:29;68861:119;;;68921:14;68906:12;:29;68861:119;68839:141;-1:-1:-1;68997:16:0;;68993:271;;69044:75;69106:12;69044:39;:11;69078:4;69044:39;:33;:39;:::i;:75::-;69030:89;;69177:15;69162:11;:30;;69136:116;;;;-1:-1:-1;;;69136:116:0;;;;;;;;;68502:769;;;;;:::o;20019:165::-;20126:4;20155:16;;;;;;;;;;;;:21;;;20019:165::o;33006:39180::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;33006:39180:0;-1:-1:-1;;;;;33006:39180:0;;;;;;;;;;;-1:-1:-1;33006:39180:0;;;;;;;-1:-1:-1;33006:39180:0;;;-1:-1:-1;33006:39180:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;33006:39180:0;-1:-1:-1;;;;;33006:39180:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;33006:39180:0;;;-1:-1:-1;;33006:39180:0:o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;;33006:39180:0;;;;;;;5:130:-1;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;301:352;;;431:3;424:4;416:6;412:17;408:27;398:2;;449:1;446;439:12;398:2;-1:-1;469:20;;-1:-1;;;;;498:30;;495:2;;;541:1;538;531:12;495:2;575:4;567:6;563:17;551:29;;626:3;618:4;610:6;606:17;596:8;592:32;589:41;586:2;;;643:1;640;633:12;586:2;391:262;;;;;;679:707;;796:3;789:4;781:6;777:17;773:27;763:2;;814:1;811;804:12;763:2;851:6;838:20;873:80;888:64;945:6;888:64;;;873:80;;;864:89;;970:5;995:6;988:5;981:21;1025:4;1017:6;1013:17;1003:27;;1047:4;1042:3;1038:14;1031:21;;1100:6;1147:3;1139:4;1131:6;1127:17;1122:3;1118:27;1115:36;1112:2;;;1164:1;1161;1154:12;1112:2;1189:1;1174:206;1199:6;1196:1;1193:13;1174:206;;;1257:3;1279:37;1312:3;1300:10;1279:37;;;1267:50;;-1:-1;1340:4;1331:14;;;;1359;;;;;1221:1;1214:9;1174:206;;;1178:14;756:630;;;;;;;;2193:707;;2310:3;2303:4;2295:6;2291:17;2287:27;2277:2;;2328:1;2325;2318:12;2277:2;2365:6;2352:20;2387:80;2402:64;2459:6;2402:64;;2387:80;2378:89;;2484:5;2509:6;2502:5;2495:21;2539:4;2531:6;2527:17;2517:27;;2561:4;2556:3;2552:14;2545:21;;2614:6;2661:3;2653:4;2645:6;2641:17;2636:3;2632:27;2629:36;2626:2;;;2678:1;2675;2668:12;2626:2;2703:1;2688:206;2713:6;2710:1;2707:13;2688:206;;;2771:3;2793:37;2826:3;2814:10;2793:37;;;2781:50;;-1:-1;2854:4;2845:14;;;;2873;;;;;2735:1;2728:9;2688:206;;2926:722;;3054:3;3047:4;3039:6;3035:17;3031:27;3021:2;;3072:1;3069;3062:12;3021:2;3102:6;3096:13;3124:80;3139:64;3196:6;3139:64;;3124:80;3115:89;;3221:5;3246:6;3239:5;3232:21;3276:4;3268:6;3264:17;3254:27;;3298:4;3293:3;3289:14;3282:21;;3351:6;3398:3;3390:4;3382:6;3378:17;3373:3;3369:27;3366:36;3363:2;;;3415:1;3412;3405:12;3363:2;3440:1;3425:217;3450:6;3447:1;3444:13;3425:217;;;3508:3;3530:48;3574:3;3562:10;3530:48;;;3518:61;;-1:-1;3602:4;3593:14;;;;3621;;;;;3472:1;3465:9;3425:217;;3656:124;3720:20;;3745:30;3720:20;3745:30;;3787:128;3862:13;;3880:30;3862:13;3880:30;;3922:130;3989:20;;4014:33;3989:20;4014:33;;4059:134;4137:13;;4155:33;4137:13;4155:33;;4200:241;;4304:2;4292:9;4283:7;4279:23;4275:32;4272:2;;;4320:1;4317;4310:12;4272:2;4355:1;4372:53;4417:7;4397:9;4372:53;;4448:263;;4563:2;4551:9;4542:7;4538:23;4534:32;4531:2;;;4579:1;4576;4569:12;4531:2;4614:1;4631:64;4687:7;4667:9;4631:64;;4718:366;;;4839:2;4827:9;4818:7;4814:23;4810:32;4807:2;;;4855:1;4852;4845:12;4807:2;4890:1;4907:53;4952:7;4932:9;4907:53;;;4897:63;;4869:97;4997:2;5015:53;5060:7;5051:6;5040:9;5036:22;5015:53;;;5005:63;;4976:98;4801:283;;;;;;5091:366;;;5212:2;5200:9;5191:7;5187:23;5183:32;5180:2;;;5228:1;5225;5218:12;5180:2;5263:1;5280:53;5325:7;5305:9;5280:53;;;5270:63;;5242:97;5370:2;5388:53;5433:7;5424:6;5413:9;5409:22;5388:53;;5464:397;;;5603:2;5591:9;5582:7;5578:23;5574:32;5571:2;;;5619:1;5616;5609:12;5571:2;5654:31;;-1:-1;;;;;5694:30;;5691:2;;;5737:1;5734;5727:12;5691:2;5765:80;5837:7;5828:6;5817:9;5813:22;5765:80;;;5755:90;;;;5633:218;5565:296;;;;;;5868:678;;;;;6059:2;6047:9;6038:7;6034:23;6030:32;6027:2;;;6075:1;6072;6065:12;6027:2;6110:31;;-1:-1;;;;;6150:30;;6147:2;;;6193:1;6190;6183:12;6147:2;6221:80;6293:7;6284:6;6273:9;6269:22;6221:80;;;6211:90;;;;6089:218;6366:2;6355:9;6351:18;6338:32;-1:-1;;;;;6382:6;6379:30;6376:2;;;6422:1;6419;6412:12;6376:2;6450:80;6522:7;6513:6;6502:9;6498:22;6450:80;;;6021:525;;;;-1:-1;6440:90;-1:-1;;;;6021:525;6553:959;;;;;;;6796:2;6784:9;6775:7;6771:23;6767:32;6764:2;;;6812:1;6809;6802:12;6764:2;6847:31;;-1:-1;;;;;6887:30;;6884:2;;;6930:1;6927;6920:12;6884:2;6958:80;7030:7;7021:6;7010:9;7006:22;6958:80;;;6948:90;;;;6826:218;7103:2;7092:9;7088:18;7075:32;-1:-1;;;;;7119:6;7116:30;7113:2;;;7159:1;7156;7149:12;7113:2;7187:80;7259:7;7250:6;7239:9;7235:22;7187:80;;;7177:90;;;;7054:219;7332:2;7321:9;7317:18;7304:32;-1:-1;;;;;7348:6;7345:30;7342:2;;;7388:1;7385;7378:12;7342:2;7416:80;7488:7;7479:6;7468:9;7464:22;7416:80;;;7406:90;;;;7283:219;6758:754;;;;;;;;;7519:377;;7648:2;7636:9;7627:7;7623:23;7619:32;7616:2;;;7664:1;7661;7654:12;7616:2;7699:31;;-1:-1;;;;;7739:30;;7736:2;;;7782:1;7779;7772:12;7736:2;7802:78;7872:7;7863:6;7852:9;7848:22;7802:78;;7903:638;;;8074:2;8062:9;8053:7;8049:23;8045:32;8042:2;;;8090:1;8087;8080:12;8042:2;8125:31;;-1:-1;;;;;8165:30;;8162:2;;;8208:1;8205;8198:12;8162:2;8228:78;8298:7;8289:6;8278:9;8274:22;8228:78;;;8218:88;;8104:208;8371:2;8360:9;8356:18;8343:32;-1:-1;;;;;8387:6;8384:30;8381:2;;;8427:1;8424;8417:12;8381:2;8447:78;8517:7;8508:6;8497:9;8493:22;8447:78;;8998:392;;9138:2;9126:9;9117:7;9113:23;9109:32;9106:2;;;9154:1;9151;9144:12;9106:2;9189:24;;-1:-1;;;;;9222:30;;9219:2;;;9265:1;9262;9255:12;9219:2;9285:89;9366:7;9357:6;9346:9;9342:22;9285:89;;9397:235;;9498:2;9486:9;9477:7;9473:23;9469:32;9466:2;;;9514:1;9511;9504:12;9466:2;9549:1;9566:50;9608:7;9588:9;9566:50;;9639:257;;9751:2;9739:9;9730:7;9726:23;9722:32;9719:2;;;9767:1;9764;9757:12;9719:2;9802:1;9819:61;9872:7;9852:9;9819:61;;9903:241;;10007:2;9995:9;9986:7;9982:23;9978:32;9975:2;;;10023:1;10020;10013:12;9975:2;10058:1;10075:53;10120:7;10100:9;10075:53;;10151:263;;10266:2;10254:9;10245:7;10241:23;10237:32;10234:2;;;10282:1;10279;10272:12;10234:2;10317:1;10334:64;10390:7;10370:9;10334:64;;10421:366;;;10542:2;10530:9;10521:7;10517:23;10513:32;10510:2;;;10558:1;10555;10548:12;10510:2;10593:1;10610:53;10655:7;10635:9;10610:53;;10794:399;;;10926:2;10914:9;10905:7;10901:23;10897:32;10894:2;;;10942:1;10939;10932:12;10894:2;10977:1;10994:64;11050:7;11030:9;10994:64;;;10984:74;;10956:108;11095:2;11113:64;11169:7;11160:6;11149:9;11145:22;11113:64;;11200:491;;;;11338:2;11326:9;11317:7;11313:23;11309:32;11306:2;;;11354:1;11351;11344:12;11306:2;11389:1;11406:53;11451:7;11431:9;11406:53;;;11396:63;;11368:97;11496:2;11514:53;11559:7;11550:6;11539:9;11535:22;11514:53;;;11504:63;;11475:98;11604:2;11622:53;11667:7;11658:6;11647:9;11643:22;11622:53;;;11612:63;;11583:98;11300:391;;;;;;11699:173;;11786:46;11828:3;11820:6;11786:46;;;-1:-1;;11861:4;11852:14;;11779:93;11881:173;;11968:46;12010:3;12002:6;11968:46;;12062:142;12153:45;12192:5;12153:45;;;12148:3;12141:58;12135:69;;;12211:103;12284:24;12302:5;12284:24;;12472:690;;12617:54;12665:5;12617:54;;;12684:86;12763:6;12758:3;12684:86;;;12677:93;;12791:56;12841:5;12791:56;;;12867:7;12895:1;12880:260;12905:6;12902:1;12899:13;12880:260;;;12972:6;12966:13;12993:63;13052:3;13037:13;12993:63;;;12986:70;;13073:60;13126:6;13073:60;;;13063:70;-1:-1;;12927:1;12920:9;12880:260;;;-1:-1;13153:3;;12596:566;-1:-1;;;;;12596:566;13201:709;;13343:51;13388:5;13343:51;;;13407:86;13486:6;13481:3;13407:86;;;13400:93;;13514:53;13561:5;13514:53;;;13587:7;13615:1;13600:288;13625:6;13622:1;13619:13;13600:288;;;13686:44;13723:6;13686:44;;;13744:63;13803:3;13788:13;13744:63;;;13737:70;;13824:57;13874:6;13824:57;;;13814:67;-1:-1;;13647:1;13640:9;13600:288;;13951:660;14084:52;14130:5;14084:52;;;14149:84;14226:6;14221:3;14149:84;;;14142:91;;14254:54;14302:5;14254:54;;;14328:7;14356:1;14341:258;14366:6;14363:1;14360:13;14341:258;;;14433:6;14427:13;14454:63;14513:3;14498:13;14454:63;;;14447:70;;14534:58;14585:6;14534:58;;;14524:68;-1:-1;;14388:1;14381:9;14341:258;;;14345:14;14063:548;;;;;;14619:104;14696:21;14711:5;14696:21;;14730:356;;14858:38;14890:5;14858:38;;;14908:88;14989:6;14984:3;14908:88;;;14901:95;;15001:52;15046:6;15041:3;15034:4;15027:5;15023:16;15001:52;;;15065:16;;;;;14838:248;-1:-1;;14838:248;15093:166;15196:57;15247:5;15196:57;;15781:156;15879:52;15925:5;15879:52;;15944:142;16035:45;16074:5;16035:45;;16411:347;;16523:39;16556:5;16523:39;;;16574:71;16638:6;16633:3;16574:71;;;16567:78;;16650:52;16695:6;16690:3;16683:4;16676:5;16672:16;16650:52;;;16723:29;16745:6;16723:29;;;16714:39;;;;16503:255;-1:-1;;;16503:255;16766:375;;16926:67;16990:2;16985:3;16926:67;;;17026:34;17006:55;;-1:-1;;;17090:2;17081:12;;17074:30;17132:2;17123:12;;16912:229;-1:-1;;16912:229;17150:324;;17310:67;17374:2;17369:3;17310:67;;;17410:26;17390:47;;17465:2;17456:12;;17296:178;-1:-1;;17296:178;17483:327;;17643:67;17707:2;17702:3;17643:67;;;17743:29;17723:50;;17801:2;17792:12;;17629:181;-1:-1;;17629:181;17819:332;;17979:67;18043:2;18038:3;17979:67;;;18079:34;18059:55;;18142:2;18133:12;;17965:186;-1:-1;;17965:186;18160:314;;18320:67;18384:2;18379:3;18320:67;;;-1:-1;;;18400:37;;18465:2;18456:12;;18306:168;-1:-1;;18306:168;18483:312;;18643:67;18707:2;18702:3;18643:67;;;-1:-1;;;18723:35;;18786:2;18777:12;;18629:166;-1:-1;;18629:166;18804:314;;18964:67;19028:2;19023:3;18964:67;;;-1:-1;;;19044:37;;19109:2;19100:12;;18950:168;-1:-1;;18950:168;19127:370;;19287:67;19351:2;19346:3;19287:67;;;19387:34;19367:55;;-1:-1;;;19451:2;19442:12;;19435:25;19488:2;19479:12;;19273:224;-1:-1;;19273:224;19506:313;;19666:67;19730:2;19725:3;19666:67;;;-1:-1;;;19746:36;;19810:2;19801:12;;19652:167;-1:-1;;19652:167;19828:312;;19988:67;20052:2;20047:3;19988:67;;;-1:-1;;;20068:35;;20131:2;20122:12;;19974:166;-1:-1;;19974:166;20149:313;;20309:67;20373:2;20368:3;20309:67;;;-1:-1;;;20389:36;;20453:2;20444:12;;20295:167;-1:-1;;20295:167;20471:379;;20631:67;20695:2;20690:3;20631:67;;;20731:34;20711:55;;-1:-1;;;20795:2;20786:12;;20779:34;20841:2;20832:12;;20617:233;-1:-1;;20617:233;20859:319;;21019:67;21083:2;21078:3;21019:67;;;-1:-1;;;21099:42;;21169:2;21160:12;;21005:173;-1:-1;;21005:173;21187:305;;21347:66;21411:1;21406:3;21347:66;;;-1:-1;;;21426:29;;21483:2;21474:12;;21333:159;-1:-1;;21333:159;21501:391;;21661:67;21725:2;21720:3;21661:67;;;21761:34;21741:55;;-1:-1;;;21825:2;21816:12;;21809:46;21883:2;21874:12;;21647:245;-1:-1;;21647:245;21901:331;;22061:67;22125:2;22120:3;22061:67;;;22161:33;22141:54;;22223:2;22214:12;;22047:185;-1:-1;;22047:185;22241:314;;22401:67;22465:2;22460:3;22401:67;;;-1:-1;;;22481:37;;22546:2;22537:12;;22387:168;-1:-1;;22387:168;22564:326;;22724:67;22788:2;22783:3;22724:67;;;22824:28;22804:49;;22881:2;22872:12;;22710:180;-1:-1;;22710:180;22898:103;22971:24;22989:5;22971:24;;23128:262;;23272:93;23361:3;23352:6;23272:93;;23397:213;23515:2;23500:18;;23529:71;23504:9;23573:6;23529:71;;23617:451;23799:2;23784:18;;23813:79;23788:9;23865:6;23813:79;;;23903:72;23971:2;23960:9;23956:18;23947:6;23903:72;;;23986;24054:2;24043:9;24039:18;24030:6;23986:72;;24075:340;24229:2;24214:18;;24243:79;24218:9;24295:6;24243:79;;;24333:72;24401:2;24390:9;24386:18;24377:6;24333:72;;24422:324;24568:2;24553:18;;24582:71;24557:9;24626:6;24582:71;;;24664:72;24732:2;24721:9;24717:18;24708:6;24664:72;;24753:435;24927:2;24912:18;;24941:71;24916:9;24985:6;24941:71;;25195:324;25341:2;25326:18;;25355:71;25330:9;25399:6;25355:71;;25526:613;25765:2;25779:47;;;25750:18;;25840:108;25750:18;25934:6;25840:108;;;25832:116;;25959:72;26027:2;26016:9;26012:18;26003:6;25959:72;;;26042:87;26125:2;26114:9;26110:18;26101:6;26042:87;;26146:433;26346:3;26331:19;;26361:117;26335:9;26451:6;26361:117;;;26489:80;26565:2;26554:9;26550:18;26541:6;26489:80;;26586:201;26698:2;26683:18;;26712:65;26687:9;26750:6;26712:65;;26794:253;26932:2;26917:18;;26946:91;26921:9;27010:6;26946:91;;27830:340;27984:2;27969:18;;27998:79;27973:9;28050:6;27998:79;;28177:508;28391:2;28376:18;;28405:89;28380:9;28467:6;28405:89;;;28542:9;28536:4;28532:20;28527:2;28516:9;28512:18;28505:48;28567:108;28670:4;28661:6;28567:108;;28692:301;28830:2;28844:47;;;28815:18;;28905:78;28815:18;28969:6;28905:78;;29000:407;29191:2;29205:47;;;29176:18;;29266:131;29176:18;29266:131;;29414:407;29605:2;29619:47;;;29590:18;;29680:131;29590:18;29680:131;;29828:407;30019:2;30033:47;;;30004:18;;30094:131;30004:18;30094:131;;30242:407;30433:2;30447:47;;;30418:18;;30508:131;30418:18;30508:131;;30656:407;30847:2;30861:47;;;30832:18;;30922:131;30832:18;30922:131;;31070:407;31261:2;31275:47;;;31246:18;;31336:131;31246:18;31336:131;;31484:407;31675:2;31689:47;;;31660:18;;31750:131;31660:18;31750:131;;31898:407;32089:2;32103:47;;;32074:18;;32164:131;32074:18;32164:131;;32312:407;32503:2;32517:47;;;32488:18;;32578:131;32488:18;32578:131;;32726:407;32917:2;32931:47;;;32902:18;;32992:131;32902:18;32992:131;;33140:407;33331:2;33345:47;;;33316:18;;33406:131;33316:18;33406:131;;33554:407;33745:2;33759:47;;;33730:18;;33820:131;33730:18;33820:131;;33968:407;34159:2;34173:47;;;34144:18;;34234:131;34144:18;34234:131;;34382:407;34573:2;34587:47;;;34558:18;;34648:131;34558:18;34648:131;;34796:407;34987:2;35001:47;;;34972:18;;35062:131;34972:18;35062:131;;35210:407;35401:2;35415:47;;;35386:18;;35476:131;35386:18;35476:131;;35624:407;35815:2;35829:47;;;35800:18;;35890:131;35800:18;35890:131;;36038:407;36229:2;36243:47;;;36214:18;;36304:131;36214:18;36304:131;;36452:213;36570:2;36555:18;;36584:71;36559:9;36628:6;36584:71;;36672:340;36826:2;36811:18;;36840:71;36815:9;36884:6;36840:71;;;36922:80;36998:2;36987:9;36983:18;36974:6;36922:80;;37019:817;37304:3;37289:19;;37319:71;37293:9;37363:6;37319:71;;;37401:80;37477:2;37466:9;37462:18;37453:6;37401:80;;;37529:9;37523:4;37519:20;37514:2;37503:9;37499:18;37492:48;37554:105;37654:4;37645:6;37554:105;;;37546:113;;37670:72;37738:2;37727:9;37723:18;37714:6;37670:72;;;37753:73;37821:3;37810:9;37806:19;37797:6;37753:73;;;37275:561;;;;;;;;;37843:324;37989:2;37974:18;;38003:71;37978:9;38047:6;38003:71;;38174:435;38348:2;38333:18;;38362:71;38337:9;38406:6;38362:71;;;38444:72;38512:2;38501:9;38497:18;38488:6;38444:72;;38616:547;38818:3;38803:19;;38833:71;38807:9;38877:6;38833:71;;;38915:72;38983:2;38972:9;38968:18;38959:6;38915:72;;;38998;39066:2;39055:9;39051:18;39042:6;38998:72;;;39081;39149:2;39138:9;39134:18;39125:6;39081:72;;;38789:374;;;;;;;;39170:256;39232:2;39226:9;39258:17;;;-1:-1;;;;;39318:34;;39354:22;;;39315:62;39312:2;;;39390:1;39387;39380:12;39312:2;39406;39399:22;39210:216;;-1:-1;39210:216;39433:304;;-1:-1;;;;;39584:6;39581:30;39578:2;;;39624:1;39621;39614:12;39578:2;-1:-1;39659:4;39647:17;;;39712:15;;39515:222;40055:151;40179:4;40170:14;;40127:79;40213:173;;40323:14;;;40365:4;40352:18;;;40282:104;40497:137;40600:12;;40571:63;40641:141;40747:12;;40712:70;40789:108;-1:-1;40883:4;;40861:36;41276:105;41371:4;41362:14;;41348:33;41502:178;41620:19;;;41669:4;41660:14;;41613:67;42162:134;-1:-1;;;;;42237:54;;42220:76;42303:91;;42365:24;42383:5;42365:24;;42401:85;42467:13;42460:21;;42443:43;42493:140;42572:5;42578:50;42572:5;42578:50;;42847:129;;42934:37;42965:5;42983:161;;43082:57;43133:5;43082:57;;44189:140;;44283:41;44318:5;44283:41;;44336:116;;44423:24;44441:5;44423:24;;44959:268;45024:1;45031:101;45045:6;45042:1;45039:13;45031:101;;;45112:11;;;45106:18;45093:11;;;45086:39;45067:2;45060:10;45031:101;;;45147:6;45144:1;45141:13;45138:2;;;-1:-1;;45212:1;45194:16;;45187:27;45008:219;45235:161;;45325:66;45356:34;45379:10;45356:34;;;45325:66;;45403:138;;45479:57;45530:4;45524:11;45479:57;;45548:97;45636:2;45616:14;-1:-1;;45612:28;;45596:49;45763:108;45849:1;45842:5;45839:12;45829:2;;45855:9;45878:117;45947:24;45965:5;45947:24;;;45940:5;45937:35;45927:2;;45986:1;45983;45976:12;46002:111;46068:21;46083:5;46068:21;;46120:117;46189:24;46207:5;46189:24;

Swarm Source

bzzr://87df8006a8f10f4032ff4d4bb599504cbb6e2164ae637a956d0b9080e73b8860

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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.