ETH Price: $3,253.78 (+0.13%)

Contract

0x9e008F48ADae92f57b9183f3039B3FF9F9b4765e
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
VestedLPMining

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

/*
https://powerpool.finance/

          wrrrw r wrr
         ppwr rrr wppr0       prwwwrp                                 prwwwrp                   wr0
        rr 0rrrwrrprpwp0      pp   pr  prrrr0 pp   0r  prrrr0  0rwrrr pp   pr  prrrr0  prrrr0    r0
        rrp pr   wr00rrp      prwww0  pp   wr pp w00r prwwwpr  0rw    prwww0  pp   wr pp   wr    r0
        r0rprprwrrrp pr0      pp      wr   pr pp rwwr wr       0r     pp      wr   pr wr   pr    r0
         prwr wrr0wpwr        00        www0   0w0ww    www0   0w     00        www0    www0   0www0
          wrr ww0rrrr

*/

// SPDX-License-Identifier: MIT

// File: @openzeppelin/contracts-ethereum-package/contracts/Initializable.sol

pragma solidity >=0.4.24 <0.7.0;


/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool isTopLevelCall = !initializing;
    if (isTopLevelCall) {
      initializing = true;
      initialized = true;
    }

    _;

    if (isTopLevelCall) {
      initializing = false;
    }
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    address self = address(this);
    uint256 cs;
    assembly { cs := extcodesize(self) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

// File: @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol

pragma solidity ^0.6.0;


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

    function __Context_init() internal initializer {
        __Context_init_unchained();
    }

    function __Context_init_unchained() internal initializer {


    }


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

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

    uint256[50] private __gap;
}

// File: @openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol

pragma solidity ^0.6.0;


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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */

    function __Ownable_init() internal initializer {
        __Context_init_unchained();
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal initializer {


        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(_owner == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

    uint256[49] private __gap;
}

// File: @openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol

pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, 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.
     */
    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.
     */
    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 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.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.6.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts-ethereum-package/contracts/utils/Address.sol

pragma solidity ^0.6.2;

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

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

// File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol

pragma solidity ^0.6.0;




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

// File: @openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol

pragma solidity ^0.6.0;


/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
contract ReentrancyGuardUpgradeSafe is Initializable {
    bool private _notEntered;


    function __ReentrancyGuard_init() internal initializer {
        __ReentrancyGuard_init_unchained();
    }

    function __ReentrancyGuard_init_unchained() internal initializer {


        // Storing an initial non-zero value makes deployment a bit more
        // expensive, but in exchange the refund on every call to nonReentrant
        // will be lower in amount. Since refunds are capped to a percetange of
        // the total transaction's gas, it is best to keep them low in cases
        // like this one, to increase the likelihood of the full refund coming
        // into effect.
        _notEntered = true;

    }


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

        // Any calls to nonReentrant after this point will fail
        _notEntered = false;

        _;

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

    uint256[49] private __gap;
}

// File: contracts/interfaces/ILpTokenMigrator.sol

pragma solidity 0.6.12;

// note "contracts-ethereum-package" (but not "contracts") version of the package


interface ILpTokenMigrator {
  // Perform LP token migration from legacy UniswapV2 to PowerSwap.
  // Take the current LP token address and return the new LP token address.
  // Migrator should have full access to the caller's LP token.
  // Return the new LP token address.
  //
  // XXX Migrator must have allowance access to UniswapV2 LP tokens.
  // PowerSwap must mint EXACTLY the same amount of PowerSwap LP tokens or
  // else something bad will happen. Traditional UniswapV2 does not
  // do that so be careful!
  function migrate(IERC20 token, uint8 poolType) external returns (IERC20);
}

// File: contracts/interfaces/IVestedLPMining.sol

pragma solidity 0.6.12;



/**
 * @notice
 */
interface IVestedLPMining {
  /**
   * @notice Initializes the storage of the contract
   * @dev "constructor" to be called on a new proxy deployment
   * @dev Sets the contract `owner` account to the deploying account
   */
  function initialize(
    IERC20 _cvp,
    address _reservoir,
    uint256 _cvpPerBlock,
    uint256 _startBlock,
    uint256 _cvpVestingPeriodInBlocks
  ) external;

  function poolLength() external view returns (uint256);

  /// @notice Add a new pool (only the owner may call)
  function add(
    uint256 _allocPoint,
    IERC20 _lpToken,
    uint8 _poolType,
    bool _votesEnabled,
    uint256 _lpBoostRate,
    uint256 _cvpBoostRate,
    uint256 _lpBoostMinRatio,
    uint256 _lpBoostMaxRatio
  ) external;

  /// @notice Update parameters of the given pool (only the owner may call)
  function set(
    uint256 _pid,
    uint256 _allocPoint,
    uint8 _poolType,
    bool _votesEnabled,
    uint256 _lpBoostRate,
    uint256 _cvpBoostRate,
    uint256 _lpBoostMinRatio,
    uint256 _lpBoostMaxRatio
  ) external;

  /// @notice Set the migrator contract (only the owner may call)
  function setMigrator(ILpTokenMigrator _migrator) external;

  /// @notice Set CVP reward per block (only the owner may call)
  /// @dev Consider updating pool before calling this function
  function setCvpPerBlock(uint256 _cvpPerBlock) external;

  /// @notice Set CVP vesting period in blocks (only the owner may call)
  function setCvpVestingPeriodInBlocks(uint256 _cvpVestingPeriodInBlocks) external;

  function setCvpPoolByMetaPool(address _metaPool, address _cvpPool) external;

  /// @notice Return the amount of pending CVPs entitled to the given user of the pool
  function pendingCvp(uint256 _pid, address _user) external view returns (uint256);

  /// @notice Return the amount of CVP tokens which may be vested to a user of a pool in the current block
  function vestableCvp(uint256 _pid, address user) external view returns (uint256);

  /// @notice Return `true` if the LP Token is added to created pools
  function isLpTokenAdded(IERC20 _lpToken) external view returns (bool);

  /// @notice Update reward computation params for all pools
  /// @dev Be careful of gas spending
  function massUpdatePools() external;

  /// @notice Update CVP tokens allocation for the given pool
  function updatePool(uint256 _pid) external;

  /// @notice Deposit the given amount of LP tokens to the given pool
  function deposit(
    uint256 _pid,
    uint256 _amount,
    uint256 _boostAmount
  ) external;

  /// @notice Withdraw the given amount of LP tokens from the given pool
  function withdraw(
    uint256 _pid,
    uint256 _amount,
    uint256 _boostAmount
  ) external;

  /// @notice Withdraw LP tokens without caring about pending CVP tokens. EMERGENCY ONLY.
  function emergencyWithdraw(uint256 _pid) external;

  /// @notice Write votes of the given user at the current block
  function checkpointVotes(address _user) external;

  /// @notice Get CVP amount and the share of CVPs in LP pools for the given account and the checkpoint
  function getCheckpoint(address account, uint32 checkpointId)
    external
    view
    returns (
      uint32 fromBlock,
      uint96 cvpAmount,
      uint96 pooledCvpShare
    );

  event AddLpToken(address indexed lpToken, uint256 indexed pid, uint256 allocPoint);
  event SetLpToken(address indexed lpToken, uint256 indexed pid, uint256 allocPoint);
  event SetMigrator(address indexed migrator);
  event SetCvpPerBlock(uint256 cvpPerBlock);
  event SetCvpVestingPeriodInBlocks(uint256 cvpVestingPeriodInBlocks);
  event SetCvpPoolByMetaPool(address indexed metaPool, address indexed cvpPool);
  event MigrateLpToken(address indexed oldLpToken, address indexed newLpToken, uint256 indexed pid);

  event Deposit(address indexed user, uint256 indexed pid, uint256 amount, uint256 boostAmount);
  event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, uint256 boostAmount);
  event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount, uint256 boostAmount);

  event CheckpointTotalLpVotes(uint256 lpVotes);
  event CheckpointUserLpVotes(address indexed user, uint256 indexed pid, uint256 lpVotes);
  event CheckpointUserVotes(address indexed user, uint256 pendedVotes, uint256 lpVotesShare);
}

// File: contracts/lib/ReservedSlots.sol

pragma solidity 0.6.12;

/// @dev Slots reserved for possible storage layout changes (it neither spends gas nor adds extra bytecode)
contract ReservedSlots {
    uint256[100] private __gap;
}

// File: contracts/lib/SafeMath96.sol

pragma solidity 0.6.12;

library SafeMath96 {

    function add(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {
        uint96 c = a + b;
        require(c >= a, errorMessage);
        return c;
    }

    function add(uint96 a, uint96 b) internal pure returns (uint96) {
        return add(a, b, "SafeMath96: addition overflow");
    }

    function sub(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {
        require(b <= a, errorMessage);
        return a - b;
    }

    function sub(uint96 a, uint96 b) internal pure returns (uint96) {
        return sub(a, b, "SafeMath96: subtraction overflow");
    }

    function average(uint96 a, uint96 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }

    function fromUint(uint n, string memory errorMessage) internal pure returns (uint96) {
        require(n < 2**96, errorMessage);
        return uint96(n);
    }

    function fromUint(uint n) internal pure returns (uint96) {
        return fromUint(n, "SafeMath96: exceeds 96 bits");
    }
}

// File: contracts/lib/SafeMath32.sol

pragma solidity 0.6.12;

library SafeMath32 {

    function add(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) {
        uint32 c = a + b;
        require(c >= a, errorMessage);
        return c;
    }

    function add(uint32 a, uint32 b) internal pure returns (uint32) {
        return add(a, b, "SafeMath32: addition overflow");
    }

    function sub(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) {
        require(b <= a, errorMessage);
        return a - b;
    }

    function sub(uint32 a, uint32 b) internal pure returns (uint32) {
        return sub(a, b, "SafeMath32: subtraction overflow");
    }

    function fromUint(uint n, string memory errorMessage) internal pure returns (uint32) {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }

    function fromUint(uint n) internal pure returns (uint32) {
        return fromUint(n, "SafeMath32: exceeds 32 bits");
    }
}

// File: contracts/lib/DelegatableCheckpoints.sol

pragma solidity 0.6.12;


library DelegatableCheckpoints {

    /// @dev A checkpoint storing some data effective from a given block
    struct Checkpoint {
        uint32 fromBlock;
        uint192 data;
        // uint32 __reserved;
    }

    /// @dev A set of checkpoints and a 'delegatee'
    struct Record {
        uint32 numCheckpoints;
        uint32 lastCheckpointBlock;
        address delegatee;
        // uint32 __reserved;

        // Checkpoints by IDs
        mapping (uint32 => Checkpoint) checkpoints;
        // Checkpoint IDs get counted from 1 (but not from 0) -
        // the 1st checkpoint has ID of 1, and the last checkpoint' ID is `numCheckpoints`
    }

    function getCheckpoint(Record storage record, uint checkpointId)
    internal view returns (uint32 fromBlock, uint192 data)
    {
        return checkpointId == 0 || checkpointId > record.numCheckpoints
            ? (0, 0)
            : _getCheckpoint(record, uint32(checkpointId));
    }

    function _getCheckpoint(Record storage record, uint32 checkpointId)
    internal view returns (uint32 fromBlock, uint192 data)
    {
        return (record.checkpoints[checkpointId].fromBlock, record.checkpoints[checkpointId].data);
    }

    /**
     * @dev Gets the data recorded in the latest checkpoint of the given record
     */
    function getLatestData(Record storage record)
    internal view returns (uint192, uint32)
    {
        Record memory _record = record;
        return _record.numCheckpoints == 0
        ? (0, 0)
        : (record.checkpoints[_record.numCheckpoints].data, record.checkpoints[_record.numCheckpoints].fromBlock);
    }

    /**
     * @dev Returns the prior data written in the given record' checkpoints as of a block number
     * (reverts if the requested block has not been finalized)
     * @param record The record with checkpoints
     * @param blockNumber The block number to get the data at
     * @param checkpointId Optional ID of a checkpoint to first look into
     * @return The data effective as of the given block
     */
    function getPriorData(Record storage record, uint blockNumber, uint checkpointId)
    internal view returns (uint192, uint32)
    {
        uint32 blockNum = _safeMinedBlockNum(blockNumber);
        Record memory _record = record;
        Checkpoint memory cp;

        // First check specific checkpoint, if it's provided
        if (checkpointId != 0) {
            require(checkpointId <= _record.numCheckpoints, "ChPoints: invalid checkpoint id");
            uint32 cpId = uint32(checkpointId);

            cp = record.checkpoints[cpId];
            if (cp.fromBlock == blockNum) {
                return (cp.data, cp.fromBlock);
            } else if (cp.fromBlock < cp.fromBlock) {
                if (cpId == _record.numCheckpoints) {
                    return (cp.data, cp.fromBlock);
                }
                uint32 nextFromBlock = record.checkpoints[cpId + 1].fromBlock;
                if (nextFromBlock > blockNum) {
                    return (cp.data, cp.fromBlock);
                }
            }
        }

        // Finally, search trough all checkpoints
        (uint32 checkpointId, uint192 data) = _findCheckpoint(record, _record.numCheckpoints, blockNum);
        return (data, record.checkpoints[checkpointId].fromBlock);
    }

    /**
     * @dev Finds a checkpoint in the given record for the given block number
     * (reverts if the requested block has not been finalized)
     * @param record The record with checkpoints
     * @param blockNumber The block number to get the checkpoint at
     * @return id The checkpoint ID
     * @return data The checkpoint data
     */
    function findCheckpoint(Record storage record, uint blockNumber)
    internal view returns (uint32 id, uint192 data)
    {
        uint32 blockNum = _safeMinedBlockNum(blockNumber);
        uint32 numCheckpoints = record.numCheckpoints;

        (id, data) = _findCheckpoint(record, numCheckpoints, blockNum);
    }

    /**
     * @dev Writes a checkpoint with given data to the given record and returns the checkpoint ID
     */
    function writeCheckpoint(Record storage record, uint192 data)
    internal returns (uint32 id)
    {
        uint32 blockNum = _safeBlockNum(block.number);
        Record memory _record = record;

        uint192 oldData = _record.numCheckpoints > 0 ? record.checkpoints[_record.numCheckpoints].data : 0;
        bool isChanged = data != oldData;

        if (_record.lastCheckpointBlock != blockNum) {
            _record.numCheckpoints = _record.numCheckpoints + 1; // overflow chance ignored
            record.numCheckpoints = _record.numCheckpoints;
            record.lastCheckpointBlock = blockNum;
            isChanged = true;
        }
        if (isChanged) {
            record.checkpoints[_record.numCheckpoints] = Checkpoint(blockNum, data);
        }
        id = _record.numCheckpoints;
    }

    /**
     * @dev Gets the given record properties (w/o mappings)
     */
    function getProperties(Record storage record) internal view returns (uint32, uint32, address) {
        return (record.numCheckpoints, record.lastCheckpointBlock, record.delegatee);
    }

    /**
     * @dev Writes given delegatee to the given record
     */
    function writeDelegatee(Record storage record, address delegatee) internal {
        record.delegatee = delegatee;
    }

    function _safeBlockNum(uint256 blockNumber) private pure returns (uint32) {
        require(blockNumber < 2**32, "ChPoints: blockNum >= 2**32");
        return uint32(blockNumber);
    }

    function _safeMinedBlockNum(uint256 blockNumber) private view returns (uint32) {
        require(blockNumber < block.number, "ChPoints: block not yet mined");
        return _safeBlockNum(blockNumber);
    }

    function _findCheckpoint(Record storage record, uint32 numCheckpoints, uint32 blockNum)
    private view returns (uint32, uint192)
    {
        Checkpoint memory cp;

        // Check special cases first
        if (numCheckpoints == 0) {
            return (0, 0);
        }
        cp = record.checkpoints[numCheckpoints];
        if (cp.fromBlock <= blockNum) {
            return (numCheckpoints, cp.data);
        }
        if (record.checkpoints[1].fromBlock > blockNum) {
            return (0, 0);
        }

        uint32 lower = 1;
        uint32 upper = numCheckpoints;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
            cp = record.checkpoints[center];
            if (cp.fromBlock == blockNum) {
                return (center, cp.data);
            } else if (cp.fromBlock < blockNum) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return (lower, record.checkpoints[lower].data);
    }
}

// File: contracts/powerindex-mining/DelegatableVotes.sol

pragma solidity 0.6.12;



abstract contract DelegatableVotes {
  using SafeMath96 for uint96;
  using DelegatableCheckpoints for DelegatableCheckpoints.Record;

  /**
   * @notice Votes computation data for each account
   * @dev Data adjusted to account "delegated" votes
   * @dev For the contract address, stores shared for all accounts data
   */
  mapping(address => DelegatableCheckpoints.Record) public book;

  /**
   * @dev Data on votes which an account may delegate or has already delegated
   */
  mapping(address => uint192) internal delegatables;

  /// @notice The event is emitted when a delegate account' vote balance changes
  event CheckpointBalanceChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

  /// @notice An event that's emitted when an account changes its delegate
  event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

  /**
   * @notice Get the "delegatee" account for the message sender
   */
  function delegatee() public view returns (address) {
    return book[msg.sender].delegatee;
  }

  /**
   * @notice Delegate votes from `msg.sender` to `delegatee`
   * @param delegatee_ The address to delegate votes to
   */
  function delegate(address delegatee_) public {
    require(delegatee_ != address(this), "delegate: can't delegate to the contract address");
    return _delegate(msg.sender, delegatee_);
  }

  /**
   * @notice Get the current votes balance for `account`
   * @param account The address to get votes balance
   * @return The number of current votes for `account`
   */
  function _getCurrentVotes(address account) internal view returns (uint96) {
    (uint192 userData, uint32 userDataBlockNumber) = book[account].getLatestData();
    if (userData == 0) return 0;

    (uint192 sharedData, ) = book[address(this)].getLatestData();
    (uint192 sharedDataAtUserSave, ) = book[address(this)].getPriorData(userDataBlockNumber, 0);
    return _computeUserVotes(userData, sharedData, sharedDataAtUserSave);
  }

  /**
   * @notice Determine the prior number of votes for the given account as of the given block
   * @dev To prevent misinformation, the call reverts if the block requested is not finalized
   * @param account The address of the account to get votes for
   * @param blockNumber The block number to get votes at
   * @return The number of votes the account had as of the given block
   */
  function _getPriorVotes(address account, uint256 blockNumber) internal view returns (uint96) {
    return _getPriorVotes(account, blockNumber, 0, 0);
  }

  /**
   * @notice Gas-optimized version of the `getPriorVotes` function -
   * it accepts IDs of checkpoints to look for votes data as of the given block in
   * (if the checkpoints miss the data, it get searched through all checkpoints recorded)
   * @dev Call (off-chain) the `findCheckpoints` function to get needed IDs
   * @param account The address of the account to get votes for
   * @param blockNumber The block number to get votes at
   * @param userCheckpointId ID of the checkpoint to look for the user data first
   * @param userCheckpointId ID of the checkpoint to look for the shared data first
   * @return The number of votes the account had as of the given block
   */
  function _getPriorVotes(
    address account,
    uint256 blockNumber,
    uint32 userCheckpointId,
    uint32 sharedCheckpointId
  ) internal view returns (uint96) {
    (uint192 userData, uint32 userDataBlockNumber) = book[account].getPriorData(blockNumber, userCheckpointId);
    if (userData == 0) return 0;

    (uint192 sharedData, ) = book[address(this)].getPriorData(blockNumber, sharedCheckpointId);
    (uint192 sharedDataAtUserSave, ) = book[address(this)].getPriorData(userDataBlockNumber, 0);
    return _computeUserVotes(userData, sharedData, sharedDataAtUserSave);
  }

  /// @notice Returns IDs of checkpoints which store the given account' votes computation data
  /// @dev Intended for off-chain use (by UI)
  function findCheckpoints(address account, uint256 blockNumber)
    external
    view
    returns (uint32 userCheckpointId, uint32 sharedCheckpointId)
  {
    require(account != address(0), "findCheckpoints: zero account");
    (userCheckpointId, ) = book[account].findCheckpoint(blockNumber);
    (sharedCheckpointId, ) = book[address(this)].findCheckpoint(blockNumber);
  }

  function _getCheckpoint(address account, uint32 checkpointId) internal view returns (uint32 fromBlock, uint192 data) {
    (fromBlock, data) = book[account].getCheckpoint(checkpointId);
  }

  function _writeSharedData(uint192 data) internal {
    book[address(this)].writeCheckpoint(data);
  }

  function _writeUserData(address account, uint192 data) internal {
    DelegatableCheckpoints.Record storage src = book[account];
    address _delegatee = src.delegatee;
    DelegatableCheckpoints.Record storage dst = _delegatee == address(0) ? src : book[_delegatee];

    (uint192 latestData, ) = dst.getLatestData();
    dst.writeCheckpoint(
      // keep in mind votes which others could have delegated
      _computeUserData(latestData, data, delegatables[account])
    );
    delegatables[account] = data;
  }

  function _moveUserData(
    address account,
    address from,
    address to
  ) internal {
    DelegatableCheckpoints.Record storage src;
    DelegatableCheckpoints.Record storage dst;

    if (from == address(0)) {
      // no former delegatee
      src = book[account];
      dst = book[to];
    } else if (to == address(0)) {
      // delegation revoked
      src = book[from];
      dst = book[account];
    } else {
      src = book[from];
      dst = book[to];
    }
    uint192 delegatable = delegatables[account];

    (uint192 srcPrevData, ) = src.getLatestData();
    uint192 srcData = _computeUserData(srcPrevData, 0, delegatable);
    if (srcPrevData != srcData) src.writeCheckpoint(srcData);

    (uint192 dstPrevData, ) = dst.getLatestData();
    uint192 dstData = _computeUserData(dstPrevData, delegatable, 0);
    if (dstPrevData != dstData) dst.writeCheckpoint(dstData);
  }

  function _delegate(address delegator, address delegatee_) internal {
    address currentDelegate = book[delegator].delegatee;
    book[delegator].delegatee = delegatee_;

    emit DelegateChanged(delegator, currentDelegate, delegatee_);

    _moveUserData(delegator, currentDelegate, delegatee_);
  }

  function _computeUserVotes(
    uint192 userData,
    uint192 sharedData,
    uint192 sharedDataAtUserSave
  ) internal pure virtual returns (uint96 votes);

  function _computeUserData(
    uint192 prevData,
    uint192 newDelegated,
    uint192 prevDelegated
  ) internal pure virtual returns (uint192 userData) {
    (uint96 prevA, uint96 prevB) = _unpackData(prevData);
    (uint96 newDelegatedA, uint96 newDelegatedB) = _unpackData(newDelegated);
    (uint96 prevDelegatedA, uint96 prevDelegatedB) = _unpackData(prevDelegated);
    userData = _packData(
      _getNewValue(prevA, newDelegatedA, prevDelegatedA),
      _getNewValue(prevB, newDelegatedB, prevDelegatedB)
    );
  }

  function _unpackData(uint192 data) internal pure virtual returns (uint96 valA, uint96 valB) {
    return (uint96(data >> 96), uint96((data << 96) >> 96));
  }

  function _packData(uint96 valA, uint96 valB) internal pure virtual returns (uint192 data) {
    return ((uint192(valA) << 96) | uint192(valB));
  }

  function _getNewValue(
    uint96 val,
    uint96 more,
    uint96 less
  ) internal pure virtual returns (uint96 newVal) {
    if (more == less) {
      newVal = val;
    } else if (more > less) {
      newVal = val.add(more.sub(less));
    } else {
      uint96 decrease = less.sub(more);
      newVal = val > decrease ? val.sub(decrease) : 0;
    }
  }

  uint256[50] private _gap; // reserved
}

// File: contracts/powerindex-mining/VestedLPMining.sol

pragma solidity 0.6.12;












contract VestedLPMining is
  OwnableUpgradeSafe,
  ReentrancyGuardUpgradeSafe,
  ReservedSlots,
  DelegatableVotes,
  IVestedLPMining
{
  using SafeMath for uint256;
  using SafeMath96 for uint96;
  using SafeMath32 for uint32;

  using SafeERC20 for IERC20;

  /// @dev properties grouped to optimize storage costs

  struct User {
    uint32 lastUpdateBlock; // block when the params (below) were updated
    uint32 vestingBlock; // block by when all entitled CVP tokens to be vested
    uint96 pendedCvp; // amount of CVPs tokens entitled but not yet vested to the user
    uint96 cvpAdjust; // adjustments for pended CVP tokens amount computation
    // (with regard to LP token deposits/withdrawals in the past)
    uint256 lptAmount; // amount of LP tokens the user has provided to a pool
    /** @dev
     * At any time, the amount of CVP tokens entitled to a user but not yet vested is the sum of:
     * (1) CVP token amount entitled after the user last time deposited or withdrawn LP tokens
     *     = (user.lptAmount * pool.accCvpPerLpt) - user.cvpAdjust
     * (2) CVP token amount entitled before the last deposit or withdrawal but not yet vested
     *     = user.pendedCvp
     *
     * Whenever a user deposits or withdraws LP tokens to a pool:
     *   1. `pool.accCvpPerLpt` for the pool gets updated;
     *   2. CVP token amounts to be entitled and vested to the user get computed;
     *   3. Token amount which may be vested get sent to the user;
     *   3. User' `lptAmount`, `cvpAdjust` and `pendedCvp` get updated.
     *
     * Note comments on vesting rules in the `function _computeCvpVesting` code bellow.
     */
  }

  struct Pool {
    IERC20 lpToken; // address of the LP token contract
    bool votesEnabled; // if the pool is enabled to write votes
    uint8 poolType; // pool type (1 - Uniswap, 2 - Balancer)
    uint32 allocPoint; // points assigned to the pool, which affect CVPs distribution between pools
    uint32 lastUpdateBlock; // latest block when the pool params which follow was updated
    uint256 accCvpPerLpt; // accumulated distributed CVPs per one deposited LP token, times 1e12
  }

  // scale factor for `accCvpPerLpt`
  uint256 internal constant SCALE = 1e12;

  // The CVP TOKEN
  IERC20 public cvp;
  // Total amount of CVP tokens pended (not yet vested to users)
  uint96 public cvpVestingPool;

  // Reservoir address
  address public reservoir;
  // Vesting duration in blocks
  uint32 public cvpVestingPeriodInBlocks;
  // The block number when CVP powerindex-mining starts
  uint32 public startBlock;
  // The amount of CVP tokens rewarded to all pools every block
  uint96 public cvpPerBlock;

  // The migrator contract (only the owner may assign it)
  ILpTokenMigrator public migrator;

  // Params of each pool
  Pool[] public pools;
  // Pid (i.e. the index in `pools`) of each pool by its LP token address
  mapping(address => uint256) public poolPidByAddress;
  // Params of each user that stakes LP tokens, by the Pid and the user address
  mapping(uint256 => mapping(address => User)) public users;
  // Sum of allocation points for all pools
  uint256 public totalAllocPoint = 0;

  mapping(address => address) public cvpPoolByMetaPool;

  mapping(address => uint256) public lastSwapBlock;

  struct PoolBoost {
    uint256 lpBoostRate;
    uint256 cvpBoostRate;
    uint32 lastUpdateBlock;
    uint256 accCvpPerLpBoost;
    uint256 accCvpPerCvpBoost;
  }

  struct UserPoolBoost {
    uint256 balance;
    uint32 lastUpdateBlock;
  }

  mapping(uint256 => PoolBoost) public poolBoostByLp;
  mapping(uint256 => mapping(address => UserPoolBoost)) public usersPoolBoost;

  mapping(address => uint256) public lpBoostRatioByToken;
  mapping(address => uint256) public lpBoostMaxRatioByToken;

  mapping(address => bool) public votingEnabled;

  /// @inheritdoc IVestedLPMining
  function initialize(
    IERC20 _cvp,
    address _reservoir,
    uint256 _cvpPerBlock,
    uint256 _startBlock,
    uint256 _cvpVestingPeriodInBlocks
  ) external override initializer {
    __Ownable_init();
    __ReentrancyGuard_init_unchained();

    cvp = _cvp;
    reservoir = _reservoir;
    startBlock = SafeMath32.fromUint(_startBlock, "VLPMining: too big startBlock");
    cvpVestingPeriodInBlocks = SafeMath32.fromUint(_cvpVestingPeriodInBlocks, "VLPMining: too big vest period");
    setCvpPerBlock(_cvpPerBlock);
  }

  /// @inheritdoc IVestedLPMining
  function poolLength() external view override returns (uint256) {
    return pools.length;
  }

  /// @inheritdoc IVestedLPMining
  function add(
    uint256 _allocPoint,
    IERC20 _lpToken,
    uint8 _poolType,
    bool _votesEnabled,
    uint256 _lpBoostRate,
    uint256 _cvpBoostRate,
    uint256 _lpBoostMinRatio,
    uint256 _lpBoostMaxRatio
  ) public override onlyOwner {
    require(!isLpTokenAdded(_lpToken), "VLPMining: token already added");

    massUpdatePools();
    uint32 blockNum = _currBlock();
    uint32 lastUpdateBlock = blockNum > startBlock ? blockNum : startBlock;
    totalAllocPoint = totalAllocPoint.add(_allocPoint);

    uint256 pid = pools.length;
    pools.push(
      Pool({
        lpToken: _lpToken,
        votesEnabled: _votesEnabled,
        poolType: _poolType,
        allocPoint: SafeMath32.fromUint(_allocPoint, "VLPMining: too big allocation"),
        lastUpdateBlock: lastUpdateBlock,
        accCvpPerLpt: 0
      })
    );
    poolPidByAddress[address(_lpToken)] = pid;

    poolBoostByLp[pid].lpBoostRate = _lpBoostRate;
    poolBoostByLp[pid].cvpBoostRate = _cvpBoostRate;

    poolBoostByLp[pid].lastUpdateBlock = lastUpdateBlock;
    lpBoostRatioByToken[address(_lpToken)] = _lpBoostMinRatio;
    lpBoostMaxRatioByToken[address(_lpToken)] = _lpBoostMaxRatio;

    emit AddLpToken(address(_lpToken), pid, _allocPoint);
  }

  /// @inheritdoc IVestedLPMining
  function set(
    uint256 _pid,
    uint256 _allocPoint,
    uint8 _poolType,
    bool _votesEnabled,
    uint256 _lpBoostRate,
    uint256 _cvpBoostRate,
    uint256 _lpBoostMinRatio,
    uint256 _lpBoostMaxRatio
  ) public override onlyOwner {
    massUpdatePools();
    totalAllocPoint = totalAllocPoint.sub(uint256(pools[_pid].allocPoint)).add(_allocPoint);
    pools[_pid].allocPoint = SafeMath32.fromUint(_allocPoint, "VLPMining: too big allocation");
    pools[_pid].votesEnabled = _votesEnabled;
    pools[_pid].poolType = _poolType;

    poolBoostByLp[_pid].lpBoostRate = _lpBoostRate;
    poolBoostByLp[_pid].cvpBoostRate = _cvpBoostRate;

    lpBoostRatioByToken[address(pools[_pid].lpToken)] = _lpBoostMinRatio;
    lpBoostMaxRatioByToken[address(pools[_pid].lpToken)] = _lpBoostMaxRatio;

    emit SetLpToken(address(pools[_pid].lpToken), _pid, _allocPoint);
  }

  /// @inheritdoc IVestedLPMining
  function setMigrator(ILpTokenMigrator _migrator) public override onlyOwner {
    migrator = _migrator;

    emit SetMigrator(address(_migrator));
  }

  /// @inheritdoc IVestedLPMining
  function setCvpPerBlock(uint256 _cvpPerBlock) public override onlyOwner {
    cvpPerBlock = SafeMath96.fromUint(_cvpPerBlock, "VLPMining: too big cvpPerBlock");

    emit SetCvpPerBlock(_cvpPerBlock);
  }

  /// @inheritdoc IVestedLPMining
  function setCvpVestingPeriodInBlocks(uint256 _cvpVestingPeriodInBlocks) public override onlyOwner {
    cvpVestingPeriodInBlocks = SafeMath32.fromUint(
      _cvpVestingPeriodInBlocks,
      "VLPMining: too big cvpVestingPeriodInBlocks"
    );

    emit SetCvpVestingPeriodInBlocks(_cvpVestingPeriodInBlocks);
  }

  /// @inheritdoc IVestedLPMining
  function setCvpPoolByMetaPool(address _metaPool, address _cvpPool) public override onlyOwner {
    cvpPoolByMetaPool[_metaPool] = _cvpPool;

    emit SetCvpPoolByMetaPool(_metaPool, _cvpPool);
  }

  function updateCvpAdjust(
    uint256 _pid,
    address[] calldata _users,
    uint96[] calldata _cvpAdjust
  ) external onlyOwner {
    uint256 len = _users.length;
    require(len == _cvpAdjust.length, "Lengths not match");
    for (uint256 i = 0; i < len; i++) {
      users[_pid][_users[i]].cvpAdjust = _cvpAdjust[i];
    }
  }

  function updatePendedCvp(
    uint256 _pid,
    address[] calldata _users,
    uint96[] calldata _pendedCvp
  ) external onlyOwner {
    uint256 len = _users.length;
    require(len == _pendedCvp.length, "Lengths not match");
    for (uint256 i = 0; i < len; i++) {
      users[_pid][_users[i]].pendedCvp = _pendedCvp[i];
    }
  }

  /// @inheritdoc IVestedLPMining
  function pendingCvp(uint256 _pid, address _user) external view override returns (uint256) {
    if (_pid >= pools.length) return 0;

    Pool memory _pool = pools[_pid];
    PoolBoost memory _poolBoost = poolBoostByLp[_pid];
    User memory user = users[_pid][_user];
    UserPoolBoost memory userPB = usersPoolBoost[_pid][_user];

    _computePoolReward(_pool);
    _computePoolBoostReward(_poolBoost);

    _pool.lastUpdateBlock = pools[_pid].lastUpdateBlock;
    _computePoolRewardByBoost(_pool, _poolBoost);
    uint96 newlyEntitled = _computeCvpToEntitle(user, _pool, userPB, _poolBoost);

    return uint256(newlyEntitled.add(user.pendedCvp));
  }

  /// @inheritdoc IVestedLPMining
  function vestableCvp(uint256 _pid, address user) external view override returns (uint256) {
    Pool memory _pool = pools[_pid];
    PoolBoost memory _poolBoost = poolBoostByLp[_pid];
    User memory _user = users[_pid][user];
    UserPoolBoost memory _userPB = usersPoolBoost[_pid][user];

    _computePoolReward(_pool);
    _computePoolBoostReward(_poolBoost);

    _pool.lastUpdateBlock = pools[_pid].lastUpdateBlock;
    _computePoolRewardByBoost(_pool, _poolBoost);
    (, uint256 newlyVested) = _computeCvpVesting(_user, _pool, _userPB, _poolBoost);

    return newlyVested;
  }

  /// @inheritdoc IVestedLPMining
  function isLpTokenAdded(IERC20 _lpToken) public view override returns (bool) {
    uint256 pid = poolPidByAddress[address(_lpToken)];
    return pools.length > pid && address(pools[pid].lpToken) == address(_lpToken);
  }

  /// @inheritdoc IVestedLPMining
  function massUpdatePools() public override {
    uint256 length = pools.length;
    for (uint256 pid = 0; pid < length; ++pid) {
      updatePool(pid);
    }
  }

  /// @inheritdoc IVestedLPMining
  function updatePool(uint256 _pid) public override nonReentrant {
    _doPoolUpdate(pools[_pid], poolBoostByLp[_pid]);
  }

  /// @inheritdoc IVestedLPMining
  function deposit(
    uint256 _pid,
    uint256 _amount,
    uint256 _boostAmount
  ) public override nonReentrant {
    _validatePoolId(_pid);
    _preventSameTxOriginAndMsgSender();

    Pool storage pool = pools[_pid];
    PoolBoost storage poolBoost = poolBoostByLp[_pid];
    User storage user = users[_pid][msg.sender];
    UserPoolBoost storage userPB = usersPoolBoost[_pid][msg.sender];

    _doPoolUpdate(pool, poolBoost);
    _vestUserCvp(user, pool, userPB, poolBoost);

    if (_amount != 0) {
      pool.lpToken.safeTransferFrom(msg.sender, address(this), _amount);
      user.lptAmount = user.lptAmount.add(_amount);
    }
    if (_boostAmount != 0) {
      cvp.safeTransferFrom(msg.sender, address(this), _boostAmount);
      userPB.balance = userPB.balance.add(_boostAmount);
    }
    if (userPB.balance != 0) {
      require(!cvpAmountNotInBoundsToBoost(userPB.balance, user.lptAmount, address(pool.lpToken)), "BOOST_BOUNDS");
    }
    user.cvpAdjust = _computeCvpAdjustmentWithBoost(user.lptAmount, pool, userPB, poolBoost);
    emit Deposit(msg.sender, _pid, _amount, _boostAmount);

    if (votingEnabled[msg.sender]) {
      _doCheckpointVotes(msg.sender);
    }
  }

  /// @inheritdoc IVestedLPMining
  function withdraw(
    uint256 _pid,
    uint256 _amount,
    uint256 _boostAmount
  ) public override nonReentrant {
    _validatePoolId(_pid);
    _preventSameTxOriginAndMsgSender();

    Pool storage pool = pools[_pid];
    PoolBoost storage poolBoost = poolBoostByLp[_pid];
    User storage user = users[_pid][msg.sender];
    UserPoolBoost storage userPB = usersPoolBoost[_pid][msg.sender];
    require(user.lptAmount >= _amount, "VLPMining: amount exceeds balance");

    _doPoolUpdate(pool, poolBoost);
    _vestUserCvp(user, pool, userPB, poolBoost);

    if (_amount != 0) {
      user.lptAmount = user.lptAmount.sub(_amount);
      pool.lpToken.safeTransfer(msg.sender, _amount);
    }
    if (_boostAmount != 0) {
      userPB.balance = userPB.balance.sub(_boostAmount);
      cvp.safeTransfer(msg.sender, _boostAmount);
    }
    if (userPB.balance != 0) {
      require(!cvpAmountNotInBoundsToBoost(userPB.balance, user.lptAmount, address(pool.lpToken)), "BOOST_BOUNDS");
    }
    user.cvpAdjust = _computeCvpAdjustmentWithBoost(user.lptAmount, pool, userPB, poolBoost);
    emit Withdraw(msg.sender, _pid, _amount, _boostAmount);

    if (votingEnabled[msg.sender]) {
      _doCheckpointVotes(msg.sender);
    }
  }

  /// @inheritdoc IVestedLPMining
  function emergencyWithdraw(uint256 _pid) public override nonReentrant {
    _validatePoolId(_pid);
    _preventSameTxOriginAndMsgSender();

    Pool storage pool = pools[_pid];
    User storage user = users[_pid][msg.sender];
    UserPoolBoost storage userPB = usersPoolBoost[_pid][msg.sender];

    pool.lpToken.safeTransfer(msg.sender, user.lptAmount);
    if (userPB.balance != 0) {
      cvp.safeTransfer(msg.sender, userPB.balance);
    }
    emit EmergencyWithdraw(msg.sender, _pid, user.lptAmount, userPB.balance);

    if (user.pendedCvp > 0) {
      // TODO: Make user.pendedCvp be updated as of the pool' lastUpdateBlock
      cvpVestingPool = user.pendedCvp > cvpVestingPool ? 0 : cvpVestingPool.sub(user.pendedCvp);
    }

    user.lptAmount = 0;
    user.cvpAdjust = 0;
    user.pendedCvp = 0;
    user.vestingBlock = 0;
    userPB.balance = 0;

    if (votingEnabled[msg.sender]) {
      _doCheckpointVotes(msg.sender);
    }
  }

  function setVotingEnabled(bool _isEnabled) public nonReentrant {
    votingEnabled[msg.sender] = _isEnabled;
    if (_isEnabled) {
      _doCheckpointVotes(msg.sender);
    }
  }

  /// @inheritdoc IVestedLPMining
  function checkpointVotes(address _user) public override nonReentrant {
    _doCheckpointVotes(_user);
  }

  function getCurrentVotes(address account) external view returns (uint96) {
    if (!votingEnabled[account]) {
      return 0;
    }
    return _getCurrentVotes(account);
  }

  function getPriorVotes(address account, uint256 blockNumber) external view returns (uint96) {
    if (!votingEnabled[account]) {
      return 0;
    }
    return _getPriorVotes(account, blockNumber);
  }

  function getPriorVotes(
    address account,
    uint256 blockNumber,
    uint32 userCheckpointId,
    uint32 sharedCheckpointId
  ) external view returns (uint96) {
    if (!votingEnabled[account]) {
      return 0;
    }
    return _getPriorVotes(account, blockNumber, userCheckpointId, sharedCheckpointId);
  }

  /// @inheritdoc IVestedLPMining
  function getCheckpoint(address account, uint32 checkpointId)
    external
    view
    override
    returns (
      uint32 fromBlock,
      uint96 cvpAmount,
      uint96 pooledCvpShare
    )
  {
    uint192 data;
    (fromBlock, data) = _getCheckpoint(account, checkpointId);
    (cvpAmount, pooledCvpShare) = _unpackData(data);
  }

  function _doCheckpointVotes(address _user) internal {
    uint256 length = pools.length;
    uint96 userPendedCvp = 0;
    uint256 userTotalLpCvp = 0;
    uint96 totalLpCvp = 0;
    for (uint256 pid = 0; pid < length; ++pid) {
      userPendedCvp = userPendedCvp.add(users[pid][_user].pendedCvp);

      Pool storage pool = pools[pid];
      uint96 lpCvp;
      address lpToken = address(pool.lpToken);
      address cvpPoolByMeta = cvpPoolByMetaPool[lpToken];
      if (cvpPoolByMeta == address(0)) {
        lpCvp = SafeMath96.fromUint(cvp.balanceOf(lpToken), "VLPMining::_doCheckpointVotes:1");
        totalLpCvp = totalLpCvp.add(lpCvp);
      } else {
        uint256 poolTotalSupply = IERC20(cvpPoolByMeta).totalSupply();
        uint256 poolBalance = IERC20(cvpPoolByMeta).balanceOf(lpToken);
        uint256 lpShare = uint256(poolBalance).mul(SCALE).div(poolTotalSupply);
        uint256 metaPoolCvp = cvp.balanceOf(cvpPoolByMeta);
        lpCvp = SafeMath96.fromUint(metaPoolCvp.mul(lpShare).div(SCALE), "VLPMining::_doCheckpointVotes:1");
      }

      if (!pool.votesEnabled) {
        continue;
      }

      uint256 lptTotalSupply = pool.lpToken.totalSupply();
      uint256 lptAmount = users[pid][_user].lptAmount;
      if (lptAmount != 0 && lptTotalSupply != 0) {
        uint256 cvpPerLpt = uint256(lpCvp).mul(SCALE).div(lptTotalSupply);
        uint256 userLpCvp = lptAmount.mul(cvpPerLpt).div(SCALE);
        userTotalLpCvp = userTotalLpCvp.add(userLpCvp);

        emit CheckpointUserLpVotes(_user, pid, userLpCvp);
      }
    }

    uint96 lpCvpUserShare =
      (userTotalLpCvp == 0 || totalLpCvp == 0)
        ? 0
        : SafeMath96.fromUint(userTotalLpCvp.mul(SCALE).div(totalLpCvp), "VLPMining::_doCheckpointVotes:2");

    emit CheckpointTotalLpVotes(totalLpCvp);
    emit CheckpointUserVotes(_user, uint256(userPendedCvp), lpCvpUserShare);

    _writeUserData(_user, _packData(userPendedCvp, lpCvpUserShare));
    _writeSharedData(_packData(totalLpCvp, 0));
  }

  function _transferCvp(address _to, uint256 _amount) internal {
    SafeERC20.safeTransferFrom(cvp, reservoir, _to, _amount);
  }

  /// @dev must be guarded for reentrancy
  function _doPoolUpdate(Pool storage pool, PoolBoost storage poolBoost) internal {
    Pool memory _pool = pool;
    uint32 prevBlock = _pool.lastUpdateBlock;
    uint256 prevAcc = _pool.accCvpPerLpt;

    uint256 cvpReward = _computePoolReward(_pool);

    if (poolBoost.lpBoostRate != 0) {
      PoolBoost memory _poolBoost = poolBoost;
      uint32 prevBoostBlock = poolBoost.lastUpdateBlock;
      uint256 prevCvpBoostAcc = poolBoost.accCvpPerCvpBoost;
      uint256 prevLpBoostAcc = poolBoost.accCvpPerLpBoost;

      cvpReward = cvpReward.add(_computePoolBoostReward(_poolBoost));
      _pool.lastUpdateBlock = prevBlock;
      cvpReward = cvpReward.add(_computePoolRewardByBoost(_pool, _poolBoost));

      if (_poolBoost.accCvpPerCvpBoost > prevCvpBoostAcc) {
        poolBoost.accCvpPerCvpBoost = _poolBoost.accCvpPerCvpBoost;
      }
      if (_poolBoost.accCvpPerLpBoost > prevLpBoostAcc) {
        poolBoost.accCvpPerLpBoost = _poolBoost.accCvpPerLpBoost;
      }
      if (_poolBoost.lastUpdateBlock > prevBoostBlock) {
        poolBoost.lastUpdateBlock = _poolBoost.lastUpdateBlock;
      }
    }

    if (_pool.accCvpPerLpt > prevAcc) {
      pool.accCvpPerLpt = _pool.accCvpPerLpt;
    }
    if (_pool.lastUpdateBlock > prevBlock) {
      pool.lastUpdateBlock = _pool.lastUpdateBlock;
    }

    if (cvpReward != 0) {
      cvpVestingPool = cvpVestingPool.add(
        SafeMath96.fromUint(cvpReward, "VLPMining::_doPoolUpdate:1"),
        "VLPMining::_doPoolUpdate:2"
      );
    }
  }

  function _vestUserCvp(
    User storage user,
    Pool storage pool,
    UserPoolBoost storage userPB,
    PoolBoost storage poolBoost
  ) internal {
    User memory _user = user;
    UserPoolBoost memory _userPB = userPB;
    uint32 prevVestingBlock = _user.vestingBlock;
    uint32 prevUpdateBlock = _user.lastUpdateBlock;
    (uint256 newlyEntitled, uint256 newlyVested) = _computeCvpVesting(_user, pool, _userPB, poolBoost);

    if (newlyEntitled != 0 || newlyVested != 0) {
      user.pendedCvp = _user.pendedCvp;
    }
    if (newlyVested != 0) {
      if (newlyVested > cvpVestingPool) newlyVested = uint256(cvpVestingPool);
      cvpVestingPool = cvpVestingPool.sub(
        SafeMath96.fromUint(newlyVested, "VLPMining::_vestUserCvp:1"),
        "VLPMining::_vestUserCvp:2"
      );
      _transferCvp(msg.sender, newlyVested);
    }
    if (_user.vestingBlock > prevVestingBlock) {
      user.vestingBlock = _user.vestingBlock;
    }
    if (_user.lastUpdateBlock > prevUpdateBlock) {
      user.lastUpdateBlock = _user.lastUpdateBlock;
    }
  }

  /* @dev Compute the amount of CVP tokens to be entitled and vested to a user of a pool
   * ... and update the `_user` instance (in the memory):
   *   `_user.pendedCvp` gets increased by `newlyEntitled - newlyVested`
   *   `_user.vestingBlock` set to the updated value
   *   `_user.lastUpdateBlock` set to the current block
   *
   * @param _user - user to compute tokens for
   * @param accCvpPerLpt - value of the pool' `pool.accCvpPerLpt`
   * @return newlyEntitled - CVP amount to entitle (on top of tokens entitled so far)
   * @return newlyVested - CVP amount to vest (on top of tokens already vested)
   */
  function _computeCvpVesting(
    User memory _user,
    Pool memory pool,
    UserPoolBoost memory _userPB,
    PoolBoost memory _poolBoost
  ) internal view returns (uint256 newlyEntitled, uint256 newlyVested) {
    uint32 prevBlock = _user.lastUpdateBlock;
    _user.lastUpdateBlock = _currBlock();
    if (prevBlock >= _user.lastUpdateBlock) {
      return (0, 0);
    }

    uint32 age = _user.lastUpdateBlock - prevBlock;

    // Tokens which are to be entitled starting from the `user.lastUpdateBlock`, shall be
    // vested proportionally to the number of blocks already minted within the period between
    // the `user.lastUpdateBlock` and `cvpVestingPeriodInBlocks` following the current block
    newlyEntitled = uint256(_computeCvpToEntitle(_user, pool, _userPB, _poolBoost));
    uint256 newToVest =
      newlyEntitled == 0 ? 0 : (newlyEntitled.mul(uint256(age)).div(uint256(age + cvpVestingPeriodInBlocks)));

    // Tokens which have been pended since the `user.lastUpdateBlock` shall be vested:
    // - in full, if the `user.vestingBlock` has been mined
    // - otherwise, proportionally to the number of blocks already mined so far in the period
    //   between the `user.lastUpdateBlock` and the `user.vestingBlock` (not yet mined)
    uint256 pended = uint256(_user.pendedCvp);
    age = _user.lastUpdateBlock >= _user.vestingBlock ? cvpVestingPeriodInBlocks : _user.lastUpdateBlock - prevBlock;
    uint256 pendedToVest =
      pended == 0
        ? 0
        : (
          age >= cvpVestingPeriodInBlocks
            ? pended
            : pended.mul(uint256(age)).div(uint256(_user.vestingBlock - prevBlock))
        );

    newlyVested = pendedToVest.add(newToVest);
    _user.pendedCvp = SafeMath96.fromUint(
      uint256(_user.pendedCvp).add(newlyEntitled).sub(newlyVested),
      "VLPMining::computeCvpVest:1"
    );

    // Amount of CVP token pended (i.e. not yet vested) from now
    uint256 remainingPended = pended == 0 ? 0 : pended.sub(pendedToVest);
    uint256 unreleasedNewly = newlyEntitled == 0 ? 0 : newlyEntitled.sub(newToVest);
    uint256 pending = remainingPended.add(unreleasedNewly);

    // Compute the vesting block (i.e. when the pended tokens to be all vested)
    uint256 period = 0;
    if (remainingPended == 0 || pending == 0) {
      // newly entitled CVPs only or nothing remain pended
      period = cvpVestingPeriodInBlocks;
    } else {
      // "old" CVPs and, perhaps, "new" CVPs are pending - the weighted average applied
      age = _user.vestingBlock - _user.lastUpdateBlock;
      period = ((remainingPended.mul(age)).add(unreleasedNewly.mul(cvpVestingPeriodInBlocks))).div(pending);
    }
    _user.vestingBlock =
      _user.lastUpdateBlock +
      (cvpVestingPeriodInBlocks > uint32(period) ? uint32(period) : cvpVestingPeriodInBlocks);

    return (newlyEntitled, newlyVested);
  }

  function _computePoolReward(Pool memory _pool) internal view returns (uint256 poolCvpReward) {
    (poolCvpReward, _pool.accCvpPerLpt, _pool.lastUpdateBlock) = _computeReward(
      _pool.lastUpdateBlock,
      _pool.accCvpPerLpt,
      _pool.lpToken,
      SCALE.mul(uint256(cvpPerBlock)).mul(uint256(_pool.allocPoint)).div(totalAllocPoint)
    );
  }

  function _computePoolRewardByBoost(Pool memory _pool, PoolBoost memory _poolBoost)
    internal
    view
    returns (uint256 poolCvpReward)
  {
    (poolCvpReward, _poolBoost.accCvpPerLpBoost, _pool.lastUpdateBlock) = _computeReward(
      _pool.lastUpdateBlock,
      _poolBoost.accCvpPerLpBoost,
      _pool.lpToken,
      _poolBoost.lpBoostRate
    );
  }

  function _computePoolBoostReward(PoolBoost memory _poolBoost) internal view returns (uint256 poolCvpReward) {
    (poolCvpReward, _poolBoost.accCvpPerCvpBoost, _poolBoost.lastUpdateBlock) = _computeReward(
      _poolBoost.lastUpdateBlock,
      _poolBoost.accCvpPerCvpBoost,
      cvp,
      _poolBoost.cvpBoostRate
    );
  }

  function _computeReward(
    uint256 _lastUpdateBlock,
    uint256 _accumulated,
    IERC20 _token,
    uint256 _cvpPoolRate
  )
    internal
    view
    returns (
      uint256 poolCvpReward,
      uint256 newAccumulated,
      uint32 newLastUpdateBlock
    )
  {
    newAccumulated = _accumulated;

    newLastUpdateBlock = _currBlock();
    if (newLastUpdateBlock > _lastUpdateBlock) {
      uint256 multiplier = uint256(newLastUpdateBlock - _lastUpdateBlock); // can't overflow

      uint256 lptBalance = _token.balanceOf(address(this));
      if (lptBalance != 0) {
        poolCvpReward = multiplier.mul(_cvpPoolRate).div(SCALE);

        newAccumulated = newAccumulated.add(poolCvpReward.mul(SCALE).div(lptBalance));
      }
    }
  }

  function _computeUserVotes(
    uint192 userData,
    uint192 sharedData,
    uint192 sharedDataAtUserSave
  ) internal pure override returns (uint96 votes) {
    (uint96 ownCvp, uint96 pooledCvpShare) = _unpackData(userData);
    (uint96 currentTotalPooledCvp, ) = _unpackData(sharedData);
    (uint96 totalPooledCvpAtUserSave, ) = _unpackData(sharedDataAtUserSave);

    if (pooledCvpShare == 0) {
      votes = ownCvp;
    } else {
      uint256 pooledCvp = uint256(pooledCvpShare).mul(currentTotalPooledCvp).div(SCALE);
      if (currentTotalPooledCvp != totalPooledCvpAtUserSave) {
        uint256 totalCvpDiffRatio = uint256(currentTotalPooledCvp).mul(SCALE).div(uint256(totalPooledCvpAtUserSave));
        if (totalCvpDiffRatio > SCALE) {
          pooledCvp = pooledCvp.mul(SCALE).div(totalCvpDiffRatio);
        }
      }
      votes = ownCvp.add(SafeMath96.fromUint(pooledCvp, "VLPMining::_computeVotes"));
    }
  }

  function _computeCvpToEntitle(
    User memory user,
    Pool memory pool,
    UserPoolBoost memory userPB,
    PoolBoost memory poolBoost
  ) private view returns (uint96 cvpResult) {
    if (user.lptAmount == 0) {
      return 0;
    }
    return
      _computeCvpAdjustmentWithBoost(user.lptAmount, pool, userPB, poolBoost).sub(
        user.cvpAdjust,
        "VLPMining::computeCvp:2"
      );
  }

  function _computeCvpAdjustmentWithBoost(
    uint256 lptAmount,
    Pool memory pool,
    UserPoolBoost memory userPB,
    PoolBoost memory poolBoost
  ) private view returns (uint96 cvpResult) {
    cvpResult = _computeCvpAdjustment(lptAmount, pool.accCvpPerLpt);
    if (poolBoost.cvpBoostRate == 0 || poolBoost.lpBoostRate == 0 || userPB.balance == 0) {
      return cvpResult;
    }
    return
      cvpResult.add(_computeCvpAdjustment(userPB.balance, poolBoost.accCvpPerCvpBoost)).add(
        _computeCvpAdjustment(lptAmount, poolBoost.accCvpPerLpBoost)
      );
  }

  function _computeCvpAdjustment(uint256 lptAmount, uint256 accCvpPerLpt) private pure returns (uint96) {
    return SafeMath96.fromUint(lptAmount.mul(accCvpPerLpt).div(SCALE), "VLPMining::_computeCvpAdj");
  }

  function cvpAmountNotInBoundsToBoost(
    uint256 _cvpAmount,
    uint256 _lpAmount,
    address _lpToken
  ) public view returns (bool) {
    return
      _cvpAmount < cvpBalanceToBoost(_lpAmount, _lpToken, true) ||
      _cvpAmount > cvpBalanceToBoost(_lpAmount, _lpToken, false);
  }

  function cvpBalanceToBoost(
    uint256 _lpAmount,
    address _lpToken,
    bool _min
  ) public view returns (uint256) {
    return _lpAmount.mul(_min ? lpBoostRatioByToken[_lpToken] : lpBoostMaxRatioByToken[_lpToken]).div(SCALE);
  }

  function _validatePoolId(uint256 pid) private view {
    require(pid < pools.length, "VLPMining: invalid pool id");
  }

  function _currBlock() private view returns (uint32) {
    return SafeMath32.fromUint(block.number, "VLPMining::_currBlock:overflow");
  }

  function _preventSameTxOriginAndMsgSender() internal {
    require(block.number > lastSwapBlock[tx.origin], "SAME_TX_ORIGIN");
    lastSwapBlock[tx.origin] = block.number;

    if (msg.sender != tx.origin) {
      require(block.number > lastSwapBlock[msg.sender], "SAME_MSG_SENDER");
      lastSwapBlock[msg.sender] = block.number;
    }
  }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"AddLpToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"CheckpointBalanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lpVotes","type":"uint256"}],"name":"CheckpointTotalLpVotes","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpVotes","type":"uint256"}],"name":"CheckpointUserLpVotes","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"pendedVotes","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpVotesShare","type":"uint256"}],"name":"CheckpointUserVotes","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostAmount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostAmount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldLpToken","type":"address"},{"indexed":true,"internalType":"address","name":"newLpToken","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"MigrateLpToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cvpPerBlock","type":"uint256"}],"name":"SetCvpPerBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"metaPool","type":"address"},{"indexed":true,"internalType":"address","name":"cvpPool","type":"address"}],"name":"SetCvpPoolByMetaPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cvpVestingPeriodInBlocks","type":"uint256"}],"name":"SetCvpVestingPeriodInBlocks","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"SetLpToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"migrator","type":"address"}],"name":"SetMigrator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostAmount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"uint8","name":"_poolType","type":"uint8"},{"internalType":"bool","name":"_votesEnabled","type":"bool"},{"internalType":"uint256","name":"_lpBoostRate","type":"uint256"},{"internalType":"uint256","name":"_cvpBoostRate","type":"uint256"},{"internalType":"uint256","name":"_lpBoostMinRatio","type":"uint256"},{"internalType":"uint256","name":"_lpBoostMaxRatio","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"book","outputs":[{"internalType":"uint32","name":"numCheckpoints","type":"uint32"},{"internalType":"uint32","name":"lastCheckpointBlock","type":"uint32"},{"internalType":"address","name":"delegatee","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"checkpointVotes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cvp","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cvpAmount","type":"uint256"},{"internalType":"uint256","name":"_lpAmount","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"}],"name":"cvpAmountNotInBoundsToBoost","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lpAmount","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"bool","name":"_min","type":"bool"}],"name":"cvpBalanceToBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvpPerBlock","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"cvpPoolByMetaPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvpVestingPeriodInBlocks","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvpVestingPool","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee_","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delegatee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"findCheckpoints","outputs":[{"internalType":"uint32","name":"userCheckpointId","type":"uint32"},{"internalType":"uint32","name":"sharedCheckpointId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"checkpointId","type":"uint32"}],"name":"getCheckpoint","outputs":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint96","name":"cvpAmount","type":"uint96"},{"internalType":"uint96","name":"pooledCvpShare","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint32","name":"userCheckpointId","type":"uint32"},{"internalType":"uint32","name":"sharedCheckpointId","type":"uint32"}],"name":"getPriorVotes","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPriorVotes","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_cvp","type":"address"},{"internalType":"address","name":"_reservoir","type":"address"},{"internalType":"uint256","name":"_cvpPerBlock","type":"uint256"},{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_cvpVestingPeriodInBlocks","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_lpToken","type":"address"}],"name":"isLpTokenAdded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastSwapBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lpBoostMaxRatioByToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lpBoostRatioByToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrator","outputs":[{"internalType":"contract ILpTokenMigrator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingCvp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolBoostByLp","outputs":[{"internalType":"uint256","name":"lpBoostRate","type":"uint256"},{"internalType":"uint256","name":"cvpBoostRate","type":"uint256"},{"internalType":"uint32","name":"lastUpdateBlock","type":"uint32"},{"internalType":"uint256","name":"accCvpPerLpBoost","type":"uint256"},{"internalType":"uint256","name":"accCvpPerCvpBoost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolPidByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"bool","name":"votesEnabled","type":"bool"},{"internalType":"uint8","name":"poolType","type":"uint8"},{"internalType":"uint32","name":"allocPoint","type":"uint32"},{"internalType":"uint32","name":"lastUpdateBlock","type":"uint32"},{"internalType":"uint256","name":"accCvpPerLpt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservoir","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint8","name":"_poolType","type":"uint8"},{"internalType":"bool","name":"_votesEnabled","type":"bool"},{"internalType":"uint256","name":"_lpBoostRate","type":"uint256"},{"internalType":"uint256","name":"_cvpBoostRate","type":"uint256"},{"internalType":"uint256","name":"_lpBoostMinRatio","type":"uint256"},{"internalType":"uint256","name":"_lpBoostMaxRatio","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cvpPerBlock","type":"uint256"}],"name":"setCvpPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_metaPool","type":"address"},{"internalType":"address","name":"_cvpPool","type":"address"}],"name":"setCvpPoolByMetaPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cvpVestingPeriodInBlocks","type":"uint256"}],"name":"setCvpVestingPeriodInBlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ILpTokenMigrator","name":"_migrator","type":"address"}],"name":"setMigrator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isEnabled","type":"bool"}],"name":"setVotingEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint96[]","name":"_cvpAdjust","type":"uint96[]"}],"name":"updateCvpAdjust","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint96[]","name":"_pendedCvp","type":"uint96[]"}],"name":"updatePendedCvp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"uint32","name":"lastUpdateBlock","type":"uint32"},{"internalType":"uint32","name":"vestingBlock","type":"uint32"},{"internalType":"uint96","name":"pendedCvp","type":"uint96"},{"internalType":"uint96","name":"cvpAdjust","type":"uint96"},{"internalType":"uint256","name":"lptAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"usersPoolBoost","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint32","name":"lastUpdateBlock","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"vestableCvp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"votingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260006101675534801561001657600080fd5b50615ca380620000276000396000f3fe608060405234801561001057600080fd5b50600436106102f05760003560e01c8063782d6fe11161019d578063a41fe49f116100e9578063cfc2cb60116100a2578063e99f5b801161007c578063e99f5b8014610c3f578063f247c4b014610c65578063f2fde38b14610c6d578063f3f14ed014610c93576102f0565b8063cfc2cb6014610bab578063d13f90b414610bf5578063d8f14f2b14610c37576102f0565b8063a41fe49f14610a44578063ab85cfe414610a6d578063ac4afa3814610a93578063b4b5ea5714610af5578063b9d02df414610b1b578063bfd05aaa14610b85576102f0565b80638da5cb5b1161015657806394f70aca1161013057806394f70aca1461098f578063996517a5146109ac5780639c954c9d146109d2578063a153d965146109ef576102f0565b80638da5cb5b146109295780638e782f4d14610931578063932bb0a11461095d576102f0565b8063782d6fe1146108165780637ca81460146108425780637cd07e471461089857806385d9aabb146108a0578063866bf7ae146108ed5780638cd0d629146108f5576102f0565b8063433cc0e41161025c5780635c19a95c116102155780636aa7098c116101ef5780636aa7098c1461073e578063715018a61461077e5780637644c30f146107865780637733fdbb146107c0576102f0565b80635c19a95c146106e25780635c2ef9a314610708578063630b5ba114610736576102f0565b8063433cc0e41461054f57806348cd4cb11461061457806351eb05a6146106355780635312ea8e1461065257806356b2ed531461066f5780635754f8d614610695576102f0565b80631db56032116102ae5780631db56032146104515780631e31d0531461047d578063238684911461048557806323cf3118146104a457806334940fa8146104ca578063430bf6df1461052b576102f0565b8062aeef8a146102f55780630795debe14610320578063081e3eda14610362578063151e6aa51461037c57806317caf6f114610384578063180abddd1461038c575b600080fd5b61031e6004803603606081101561030b57600080fd5b5080359060208101359060400135610cb9565b005b6103466004803603602081101561033657600080fd5b50356001600160a01b0316610fb7565b604080516001600160a01b039092168252519081900360200190f35b61036a610fd3565b60408051918252519081900360200190f35b610346610fda565b61036a610fea565b61031e600480360360608110156103a257600080fd5b81359190810190604081016020820135600160201b8111156103c357600080fd5b8201836020820111156103d557600080fd5b803590602001918460208302840111600160201b831117156103f657600080fd5b919390929091602081019035600160201b81111561041357600080fd5b82018360208201111561042557600080fd5b803590602001918460208302840111600160201b8311171561044657600080fd5b509092509050610ff1565b61036a6004803603604081101561046757600080fd5b50803590602001356001600160a01b031661113d565b610346611367565b61031e6004803603602081101561049b57600080fd5b5035151561138b565b61031e600480360360208110156104ba57600080fd5b50356001600160a01b0316611417565b6104fc600480360360408110156104e057600080fd5b5080356001600160a01b0316906020013563ffffffff166114c2565b6040805163ffffffff90941684526001600160601b039283166020850152911682820152519081900360600190f35b6105336114ed565b604080516001600160601b039092168252519081900360200190f35b61031e6004803603606081101561056557600080fd5b81359190810190604081016020820135600160201b81111561058657600080fd5b82018360208201111561059857600080fd5b803590602001918460208302840111600160201b831117156105b957600080fd5b919390929091602081019035600160201b8111156105d657600080fd5b8201836020820111156105e857600080fd5b803590602001918460208302840111600160201b8311171561060957600080fd5b509092509050611504565b61061c61163a565b6040805163ffffffff9092168252519081900360200190f35b61031e6004803603602081101561064b57600080fd5b503561164e565b61031e6004803603602081101561066857600080fd5b50356116d8565b61031e6004803603602081101561068557600080fd5b50356001600160a01b03166118f0565b6106b2600480360360208110156106ab57600080fd5b5035611948565b60408051958652602086019490945263ffffffff9092168484015260608401526080830152519081900360a00190f35b61031e600480360360208110156106f857600080fd5b50356001600160a01b031661197f565b61031e6004803603604081101561071e57600080fd5b506001600160a01b03813581169160200135166119d4565b61031e611a84565b6105336004803603608081101561075457600080fd5b506001600160a01b038135169060208101359063ffffffff60408201358116916060013516611aa8565b61031e611ae8565b6107ac6004803603602081101561079c57600080fd5b50356001600160a01b0316611b8a565b604080519115158252519081900360200190f35b61031e60048036036101008110156107d757600080fd5b508035906001600160a01b036020820135169060ff60408201351690606081013515159060808101359060a08101359060c08101359060e00135611ba0565b6105336004803603604081101561082c57600080fd5b506001600160a01b038135169060200135611f79565b6108686004803603602081101561085857600080fd5b50356001600160a01b0316611fb3565b6040805163ffffffff94851681529290931660208301526001600160a01b03168183015290519081900360600190f35b610346611fea565b61031e60048036036101008110156108b757600080fd5b5080359060208101359060ff60408201351690606081013515159060808101359060a08101359060c08101359060e00135612001565b61061c6122a5565b61036a6004803603606081101561090b57600080fd5b508035906001600160a01b03602082013516906040013515156122b9565b610346612313565b61036a6004803603604081101561094757600080fd5b50803590602001356001600160a01b0316612322565b6107ac6004803603606081101561097357600080fd5b50803590602081013590604001356001600160a01b0316612587565b61031e600480360360208110156109a557600080fd5b50356125b3565b61036a600480360360208110156109c257600080fd5b50356001600160a01b0316612689565b61031e600480360360208110156109e857600080fd5b503561269c565b610a1b60048036036040811015610a0557600080fd5b506001600160a01b038135169060200135612790565b604051808363ffffffff1681526020018263ffffffff1681526020019250505060405180910390f35b61031e60048036036060811015610a5a57600080fd5b508035906020810135906040013561283b565b6107ac60048036036020811015610a8357600080fd5b50356001600160a01b0316612b65565b610ab060048036036020811015610aa957600080fd5b5035612bc9565b604080516001600160a01b039097168752941515602087015260ff9093168585015263ffffffff918216606086015216608084015260a0830152519081900360c00190f35b61053360048036036020811015610b0b57600080fd5b50356001600160a01b0316612c2d565b610b4760048036036040811015610b3157600080fd5b50803590602001356001600160a01b0316612c5f565b6040805163ffffffff96871681529490951660208501526001600160601b039283168486015291166060830152608082015290519081900360a00190f35b61036a60048036036020811015610b9b57600080fd5b50356001600160a01b0316612cb3565b610bd760048036036040811015610bc157600080fd5b50803590602001356001600160a01b0316612cc6565b6040805192835263ffffffff90911660208301528051918290030190f35b61031e600480360360a0811015610c0b57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060800135612cf1565b610346612ea3565b61036a60048036036020811015610c5557600080fd5b50356001600160a01b0316612eb3565b610533612ec6565b61031e60048036036020811015610c8357600080fd5b50356001600160a01b0316612ed6565b61036a60048036036020811015610ca957600080fd5b50356001600160a01b0316612fcf565b60975460ff16610cfe576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff19169055610d1183612fe2565b610d19613039565b60006101648481548110610d2957fe5b6000918252602080832087845261016a825260408085206101668452818620338088529085528287208b885261016b865283882091885294529420600290930201935090610d778484613113565b610d838285838661339f565b8515610db5578354610da0906001600160a01b031633308961369b565b6001820154610daf90876136fb565b60018301555b8415610de35761016154610dd4906001600160a01b031633308861369b565b8054610de090866136fb565b81555b805415610e4857805460018301548554610e079291906001600160a01b0316612587565b15610e48576040805162461bcd60e51b815260206004820152600c60248201526b424f4f53545f424f554e445360a01b604482015290519081900360640190fd5b6001808301546040805160c08101825287546001600160a01b038116825260ff600160a01b820481161515602080850191909152600160a81b83049091168385015263ffffffff600160b01b83048116606080860191909152600160d01b90930481166080808601919091528b88015460a080870191909152865180880188528a5481528a8a0154841681860152875191820188528c548252988c01549381019390935260028b015490911694820194909452600389015491810191909152600488015492810192909252610f1e939091613755565b82546001600160601b0391909116600160a01b026001600160a01b0390911617825560408051878152602081018790528151899233927f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e929081900390910190a333600090815261016e602052604090205460ff1615610fa157610fa1336137d2565b50506097805460ff191660011790555050505050565b610168602052600090815260409020546001600160a01b031681565b6101645490565b610162546001600160a01b031681565b6101675481565b610ff9613dca565b6065546001600160a01b03908116911614611049576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b82818114611092576040805162461bcd60e51b8152602060048201526011602482015270098cadccee8d0e640dcdee840dac2e8c6d607b1b604482015290519081900360640190fd5b60005b81811015611134578383828181106110a957fe5b905060200201356001600160601b0316610166600089815260200190815260200160002060008888858181106110db57fe5b602090810292909201356001600160a01b031683525081019190915260400160002080546bffffffffffffffffffffffff60401b1916600160401b6001600160601b039390931692909202919091179055600101611095565b50505050505050565b6000611147615a43565b610164848154811061115557fe5b60009182526020918290206040805160c081018252600290930290910180546001600160a01b038116845260ff600160a01b82048116151595850195909552600160a81b81049094169183019190915263ffffffff600160b01b840481166060840152600160d01b909304909216608082015260019091015460a082015290506111dd615a78565b50600084815261016a6020908152604091829020825160a08101845281548152600182015492810192909252600281015463ffffffff1692820192909252600382015460608201526004909101546080820152611238615aad565b506000858152610166602090815260408083206001600160a01b0388168452825291829020825160a081018452815463ffffffff8082168352600160201b820416938201939093526001600160601b03600160401b8404811694820194909452600160a01b909204909216606082015260019091015460808201526112bb615adb565b50600086815261016b602090815260408083206001600160a01b03891684528252918290208251808401909352805483526001015463ffffffff169082015261130384613dce565b5061130d83613e57565b50610164878154811061131c57fe5b6000918252602090912060029091020154600160d01b900463ffffffff1660808501526113498484613ea5565b50600061135883868487613ee6565b96505050505050505b92915050565b33600090815261012d6020526040902054600160401b90046001600160a01b031690565b60975460ff166113d0576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1990811690915533600090815261016e602052604090208054831580159190931617905561140757611407336137d2565b506097805460ff19166001179055565b61141f613dca565b6065546001600160a01b0390811691161461146f576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b61016380546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517ff40543f3e605deae7fbca26db18ff1de07eda2925d68655836eae4c167444e3290600090a250565b6000806000806114d286866141c2565b90945090506114e0816141fb565b9497909650939450505050565b61016154600160a01b90046001600160601b031681565b61150c613dca565b6065546001600160a01b0390811691161461155c576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b828181146115a5576040805162461bcd60e51b8152602060048201526011602482015270098cadccee8d0e640dcdee840dac2e8c6d607b1b604482015290519081900360640190fd5b60005b81811015611134578383828181106115bc57fe5b905060200201356001600160601b0316610166600089815260200190815260200160002060008888858181106115ee57fe5b6001600160a01b036020918202939093013583168452830193909352604090910160002080546001600160601b0394909416600160a01b029390911692909217909155506001016115a8565b61016254600160c01b900463ffffffff1681565b60975460ff16611693576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1916905561016480546114079190839081106116b157fe5b906000526020600020906002020161016a6000848152602001908152602001600020613113565b60975460ff1661171d576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1916905561173081612fe2565b611738613039565b6000610164828154811061174857fe5b60009182526020808320858452610166825260408085203380875290845281862088875261016b85528287208288529094529420600183015460029094029091018054909550919390926117a6926001600160a01b03169190614210565b8054156117ca578054610161546117ca916001600160a01b03909116903390614210565b600182015481546040805192835260208301919091528051869233927f2369db1bafee945aee5630782f4a170682e3f8188d8dc247a4c73eb8c9e692d292918290030190a38154600160401b90046001600160601b0316156118a857610161548254600160a01b9091046001600160601b03908116600160401b909204161161187d5781546101615461187891600160a01b9091046001600160601b0390811691600160401b900416614267565b611880565b60005b61016160146101000a8154816001600160601b0302191690836001600160601b031602179055505b600060018301819055825463ffffffff16835580825533815261016e602052604090205460ff16156118dd576118dd336137d2565b50506097805460ff191660011790555050565b60975460ff16611935576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff19169055611407816137d2565b61016a60205260009081526040902080546001820154600283015460038401546004909401549293919263ffffffff909116919085565b6001600160a01b0381163014156119c75760405162461bcd60e51b8152600401808060200182810382526030815260200180615c3e6030913960400191505060405180910390fd5b6119d133826142a9565b50565b6119dc613dca565b6065546001600160a01b03908116911614611a2c576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b6001600160a01b038281166000818152610168602052604080822080546001600160a01b0319169486169485179055517fb7b89eb0ea057d36260d49cabb87830afa2a5fcfe748fe2ae71de060b6410f939190a35050565b6101645460005b81811015611aa457611a9c8161164e565b600101611a8b565b5050565b6001600160a01b038416600090815261016e602052604081205460ff16611ad157506000611ae0565b611add85858585614326565b90505b949350505050565b611af0613dca565b6065546001600160a01b03908116911614611b40576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b61016e6020526000908152604090205460ff1681565b611ba8613dca565b6065546001600160a01b03908116911614611bf8576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b611c0187612b65565b15611c53576040805162461bcd60e51b815260206004820152601e60248201527f564c504d696e696e673a20746f6b656e20616c72656164792061646465640000604482015290519081900360640190fd5b611c5b611a84565b6000611c656143e1565b6101625490915060009063ffffffff600160c01b909104811690831611611c9c5761016254600160c01b900463ffffffff16611c9e565b815b61016754909150611caf908b6136fb565b6101678190555060006101648054905090506101646040518060c001604052808c6001600160a01b031681526020018a151581526020018b60ff168152602001611d2e8e6040518060400160405280601d81526020017f564c504d696e696e673a20746f6f2062696720616c6c6f636174696f6e000000815250614427565b63ffffffff1681526020018463ffffffff1681526020016000815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160000160156101000a81548160ff021916908360ff16021790555060608201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001601a6101000a81548163ffffffff021916908363ffffffff16021790555060a0820151816001015550508061016560008c6001600160a01b03166001600160a01b03168152602001908152602001600020819055508661016a6000838152602001908152602001600020600001819055508561016a6000838152602001908152602001600020600101819055508161016a600083815260200190815260200160002060020160006101000a81548163ffffffff021916908363ffffffff1602179055508461016c60008c6001600160a01b03166001600160a01b03168152602001908152602001600020819055508361016d60008c6001600160a01b03166001600160a01b0316815260200190815260200160002081905550808a6001600160a01b03167f4ca3b1f4222c9ac99ea2eb1c68764056287a101a2f63d81e21c3a7ccfcef36e48d6040518082815260200191505060405180910390a35050505050505050505050565b6001600160a01b038216600090815261016e602052604081205460ff16611fa257506000611361565b611fac83836144c1565b9392505050565b61012d6020526000908152604090205463ffffffff80821691600160201b810490911690600160401b90046001600160a01b031683565b61016354600160601b90046001600160a01b031681565b612009613dca565b6065546001600160a01b03908116911614612059576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b612061611a84565b6120a8876120a26101648b8154811061207657fe5b6000918252602090912060029091020154610167549063ffffffff600160b01b9091048116906144d016565b906136fb565b6101675560408051808201909152601d81527f564c504d696e696e673a20746f6f2062696720616c6c6f636174696f6e00000060208201526120eb908890614427565b61016489815481106120f957fe5b906000526020600020906002020160000160166101000a81548163ffffffff021916908363ffffffff16021790555084610164898154811061213757fe5b906000526020600020906002020160000160146101000a81548160ff02191690831515021790555085610164898154811061216e57fe5b600091825260208083206002909202909101805460ff94909416600160a81b0260ff60a81b199094169390931790925589815261016a909152604081208581556001018490556101648054849261016c9290918c9081106121cb57fe5b600091825260208083206002909202909101546001600160a01b031683528201929092526040018120919091556101648054839261016d9290918c90811061220f57fe5b600091825260208083206002909202909101546001600160a01b0316835282019290925260400190205561016480548991908290811061224b57fe5b600091825260209182902060029091020154604080518b815290516001600160a01b03909216927f0e6fb68a420d604687d312365a9cb09a342eecccc96c0dc3283dbdbb070ce10392918290030190a35050505050505050565b61016254600160a01b900463ffffffff1681565b6000611ae064e8d4a5100061230d846122eb576001600160a01b038616600090815261016d6020526040902054612306565b6001600160a01b038616600090815261016c60205260409020545b8790614512565b9061456b565b6065546001600160a01b031690565b61016454600090831061233757506000611361565b61233f615a43565b610164848154811061234d57fe5b60009182526020918290206040805160c081018252600290930290910180546001600160a01b038116845260ff600160a01b82048116151595850195909552600160a81b81049094169183019190915263ffffffff600160b01b840481166060840152600160d01b909304909216608082015260019091015460a082015290506123d5615a78565b50600084815261016a6020908152604091829020825160a08101845281548152600182015492810192909252600281015463ffffffff1692820192909252600382015460608201526004909101546080820152612430615aad565b506000858152610166602090815260408083206001600160a01b0388168452825291829020825160a081018452815463ffffffff8082168352600160201b820416938201939093526001600160601b03600160401b8404811694820194909452600160a01b909204909216606082015260019091015460808201526124b3615adb565b50600086815261016b602090815260408083206001600160a01b03891684528252918290208251808401909352805483526001015463ffffffff16908201526124fb84613dce565b5061250583613e57565b50610164878154811061251457fe5b6000918252602090912060029091020154600160d01b900463ffffffff1660808501526125418484613ea5565b506000612550838684876145ad565b90506125728360400151826001600160601b031661462290919063ffffffff16565b6001600160601b031698975050505050505050565b6000612595838360016122b9565b841080611ae057506125a9838360006122b9565b9093119392505050565b6125bb613dca565b6065546001600160a01b0390811691161461260b576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b61262d816040518060600160405280602b8152602001615b59602b9139614427565b610162805463ffffffff92909216600160a01b0263ffffffff60a01b199092169190911790556040805182815290517fb6d927d1177d65639186d960a1926f0aa9cd35eca2b1b244e62f50fe3bff99a09181900360200190a150565b61016c6020526000908152604090205481565b6126a4613dca565b6065546001600160a01b039081169116146126f4576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b612733816040518060400160405280601e81526020017f564c504d696e696e673a20746f6f2062696720637670506572426c6f636b0000815250614664565b61016380546bffffffffffffffffffffffff19166001600160601b03929092169190911790556040805182815290517f11d360a0021a6a2561238805127962df1163ba47bfd43d6936083b0e0029c88d916020908290030190a150565b6000806001600160a01b0384166127ee576040805162461bcd60e51b815260206004820152601d60248201527f66696e64436865636b706f696e74733a207a65726f206163636f756e74000000604482015290519081900360640190fd5b6001600160a01b038416600090815261012d6020526040902061281190846146b9565b5030600090815261012d6020526040902090925061282f90846146b9565b50809150509250929050565b60975460ff16612880576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1916905561289383612fe2565b61289b613039565b600061016484815481106128ab57fe5b6000918252602080832087845261016a825260408085206101668452818620338088529085528287208b885261016b86528388209188529452942060018301546002909402909101945090918611156129355760405162461bcd60e51b8152600401808060200182810382526021815260200180615b846021913960400191505060405180910390fd5b61293f8484613113565b61294b8285838661339f565b851561297b57600182015461296090876144d0565b6001830155835461297b906001600160a01b03163388614210565b84156129a757805461298d90866144d0565b8155610161546129a7906001600160a01b03163387614210565b805415612a0c578054600183015485546129cb9291906001600160a01b0316612587565b15612a0c576040805162461bcd60e51b815260206004820152600c60248201526b424f4f53545f424f554e445360a01b604482015290519081900360640190fd5b6001808301546040805160c08101825287546001600160a01b038116825260ff600160a01b820481161515602080850191909152600160a81b83049091168385015263ffffffff600160b01b83048116606080860191909152600160d01b90930481166080808601919091528b88015460a080870191909152865180880188528a5481528a8a0154841681860152875191820188528c548252988c01549381019390935260028b015490911694820194909452600389015491810191909152600488015492810192909252612ae2939091613755565b82546001600160601b0391909116600160a01b026001600160a01b0390911617825560408051878152602081018790528151899233927f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94929081900390910190a333600090815261016e602052604090205460ff1615610fa157610fa1336137d2565b6001600160a01b038116600090815261016560205260408120546101645481108015612bc05750826001600160a01b03166101648281548110612ba457fe5b60009182526020909120600290910201546001600160a01b0316145b9150505b919050565b6101648181548110612bd757fe5b6000918252602090912060029091020180546001909101546001600160a01b038216925060ff600160a01b8304811692600160a81b81049091169163ffffffff600160b01b8304811692600160d01b9004169086565b6001600160a01b038116600090815261016e602052604081205460ff16612c5657506000612bc4565b611361826146ea565b6101666020908152600092835260408084209091529082529020805460019091015463ffffffff80831692600160201b8104909116916001600160601b03600160401b8304811692600160a01b9004169085565b61016d6020526000908152604090205481565b61016b6020908152600092835260408084209091529082529020805460019091015463ffffffff1682565b600054610100900460ff1680612d0a5750612d0a61478c565b80612d18575060005460ff16155b612d535760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff16158015612d7e576000805460ff1961ff0019909116610100171660011790555b612d86614792565b612d8e614843565b61016180546001600160a01b038089166001600160a01b03199283161790925561016280549288169290911691909117905560408051808201909152601d81527f564c504d696e696e673a20746f6f20626967207374617274426c6f636b0000006020820152612dff908490614427565b61016260186101000a81548163ffffffff021916908363ffffffff160217905550612e5f826040518060400160405280601e81526020017f564c504d696e696e673a20746f6f20626967207665737420706572696f640000815250614427565b61016260146101000a81548163ffffffff021916908363ffffffff160217905550612e898461269c565b8015612e9b576000805461ff00191690555b505050505050565b610161546001600160a01b031681565b6101696020526000908152604090205481565b610163546001600160601b031681565b612ede613dca565b6065546001600160a01b03908116911614612f2e576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b6001600160a01b038116612f735760405162461bcd60e51b8152600401808060200182810382526026815260200180615b336026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b6101656020526000908152604090205481565b6101645481106119d1576040805162461bcd60e51b815260206004820152601a60248201527f564c504d696e696e673a20696e76616c696420706f6f6c206964000000000000604482015290519081900360640190fd5b3260009081526101696020526040902054431161308e576040805162461bcd60e51b815260206004820152600e60248201526d29a0a6a2afaa2c2fa7a924a3a4a760911b604482015290519081900360640190fd5b32600081815261016960205260409020439055331461311157336000908152610169602052604090205443116130fd576040805162461bcd60e51b815260206004820152600f60248201526e29a0a6a2afa6a9a3afa9a2a72222a960891b604482015290519081900360640190fd5b336000908152610169602052604090204390555b565b61311b615a43565b506040805160c08101825283546001600160a01b038116825260ff600160a01b8204811615156020840152600160a81b8204169282019290925263ffffffff600160b01b830481166060830152600160d01b90920490911660808201819052600184015460a08301819052600061319184613dce565b855490915015613285576131a3615a78565b506040805160a0810182528654815260018701546020820152600287015463ffffffff16918101829052600387015460608201819052600488015460808301819052919291906131fc6131f585613e57565b86906136fb565b63ffffffff881660808a015294506132176131f58986613ea5565b9450818460800151111561323057608084015160048a01555b808460600151111561324757606084015160038a01555b8263ffffffff16846040015163ffffffff16111561328057604084015160028a01805463ffffffff191663ffffffff9092169190911790555b505050505b818460a00151111561329c5760a084015160018701555b8263ffffffff16846080015163ffffffff1611156132d9576080840151865463ffffffff909116600160d01b0263ffffffff60d01b199091161786555b8015612e9b57613370613321826040518060400160405280601a81526020017f564c504d696e696e673a3a5f646f506f6f6c5570646174653a31000000000000815250614664565b60408051808201909152601a81527f564c504d696e696e673a3a5f646f506f6f6c5570646174653a32000000000000602082015261016154600160a01b90046001600160601b031691906148f1565b61016160146101000a8154816001600160601b0302191690836001600160601b03160217905550505050505050565b6133a7615aad565b506040805160a081018252855463ffffffff8082168352600160201b82041660208301526001600160601b03600160401b8204811693830193909352600160a01b9004909116606082015260018501546080820152613404615adb565b506040805180820182528454815260018086015463ffffffff908116602080850191909152858101518651865160c0810188528b546001600160a01b038116825260ff600160a01b82048116151583870152600160a81b820416828a0152600160b01b81048616606080840191909152600160d01b90910486166080808401919091528d88015460a0808501919091528a519081018b528c548152978c01549588019590955260028b0154909516978601979097526003890154938501939093526004880154918401919091529293909160009182916134e79188918890613ee6565b915091508160001415806134fa57508015155b1561352f5760408601518a546001600160601b03909116600160401b026bffffffffffffffffffffffff60401b19909116178a555b80156136285761016154600160a01b90046001600160601b0316811115613566575061016154600160a01b90046001600160601b03165b6135f76135a8826040518060400160405280601981526020017f564c504d696e696e673a3a5f76657374557365724376703a3100000000000000815250614664565b60408051808201909152601981527f564c504d696e696e673a3a5f76657374557365724376703a3200000000000000602082015261016154600160a01b90046001600160601b0316919061495b565b61016160146101000a8154816001600160601b0302191690836001600160601b0316021790555061362833826149c8565b8363ffffffff16866020015163ffffffff1611156136665760208601518a5463ffffffff909116600160201b0267ffffffff0000000019909116178a555b855163ffffffff8085169116111561368f5785518a5463ffffffff191663ffffffff909116178a555b50505050505050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526136f59085906149e8565b50505050565b600082820183811015611fac576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000613765858560a00151614ba0565b905081602001516000148061377957508151155b8061378357508251155b1561378d57611ae0565b611add61379e868460600151614ba0565b6137c36137b386600001518660800151614ba0565b6001600160601b03851690614622565b6001600160601b031690614622565b6101645460008080805b84811015613c9a576000818152610166602090815260408083206001600160a01b038a168452909152902054613825906001600160601b0386811691600160401b900416614622565b93506000610164828154811061383757fe5b60009182526020808320600290920290910180546001600160a01b03908116808552610168909352604084205491945016806139415761016154604080516370a0823160e01b81526001600160a01b03858116600483015291516139259392909216916370a0823191602480820192602092909190829003018186803b1580156138c057600080fd5b505afa1580156138d4573d6000803e3d6000fd5b505050506040513d60208110156138ea57600080fd5b505160408051808201909152601f81527f564c504d696e696e673a3a5f646f436865636b706f696e74566f7465733a31006020820152614664565b925061393a6001600160601b03871684614622565b9550613b15565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561397c57600080fd5b505afa158015613990573d6000803e3d6000fd5b505050506040513d60208110156139a657600080fd5b5051604080516370a0823160e01b81526001600160a01b0386811660048301529151929350600092918516916370a0823191602480820192602092909190829003018186803b1580156139f857600080fd5b505afa158015613a0c573d6000803e3d6000fd5b505050506040513d6020811015613a2257600080fd5b505190506000613a3b8361230d8464e8d4a51000614512565b61016154604080516370a0823160e01b81526001600160a01b038881166004830152915193945060009391909216916370a08231916024808301926020929190829003018186803b158015613a8f57600080fd5b505afa158015613aa3573d6000803e3d6000fd5b505050506040513d6020811015613ab957600080fd5b50519050613b0e613ad364e8d4a5100061230d8486614512565b6040518060400160405280601f81526020017f564c504d696e696e673a3a5f646f436865636b706f696e74566f7465733a3100815250614664565b9650505050505b8354600160a01b900460ff16613b2e5750505050613c92565b8354604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015613b7257600080fd5b505afa158015613b86573d6000803e3d6000fd5b505050506040513d6020811015613b9c57600080fd5b810190808051906020019092919050505090506000610166600088815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060010154905080600014158015613bfe57508115155b15613c8b576000613c218361230d6001600160601b03891664e8d4a51000614512565b90506000613c3864e8d4a5100061230d8585614512565b9050613c448b826136fb565b9a50888e6001600160a01b03167f84f3863b4a309d20b83ad6a41ab2860bf0603f2e4cdab881907e7a847276a661836040518082815260200191505060405180910390a350505b5050505050505b6001016137dc565b506000821580613cb157506001600160601b038216155b613d1457613d0f613cd46001600160601b03841661230d8664e8d4a51000614512565b6040518060400160405280601f81526020017f564c504d696e696e673a3a5f646f436865636b706f696e74566f7465733a3200815250614664565b613d17565b60005b604080516001600160601b038516815290519192507fa51ed239c57bb58dd90b5196b2a3a35e8254954f924d0a8eed8e68460d90254f919081900360200190a1604080516001600160601b0380871682528316602082015281516001600160a01b038916927ff55c0f893af4049399318f4399e95624341f7d36e6958902eb15a73ab771c14f928290030190a2613db786613db28684614bf3565b614c17565b612e9b613dc5836000614bf3565b614cf1565b3390565b6000613e3f826080015163ffffffff168360a001518460000151613e3a6101675461230d886060015163ffffffff16613e3461016360009054906101000a90046001600160601b03166001600160601b031664e8d4a5100061451290919063ffffffff16565b90614512565b614d0b565b63ffffffff16608085015260a0909301929092525090565b6000613e8d826040015163ffffffff16836080015161016160009054906101000a90046001600160a01b03168560200151614d0b565b63ffffffff1660408501526080909301929092525090565b6000613ec9836080015163ffffffff16836060015185600001518560000151614d0b565b63ffffffff16608090950194909452606090920192909252919050565b83516000908190613ef56143e1565b63ffffffff90811680895290821610613f155760008092509250506141b9565b8651819003613f26888888886145ad565b6001600160601b0316935060008415613f6a5761016254613f659063ffffffff600160a01b9091048116840181169061230d9088908681169061451216565b613f6d565b60005b9050600089604001516001600160601b03169050896020015163ffffffff168a6000015163ffffffff161015613fa7578951849003613fb9565b61016254600160a01b900463ffffffff165b925060008115614014576101625463ffffffff600160a01b9091048116908516101561400d57614008858c602001510363ffffffff1661230d8663ffffffff168561451290919063ffffffff16565b61400f565b815b614017565b60005b905061402381846136fb565b955061408d6140528761404c8a8f604001516001600160601b03166136fb90919063ffffffff16565b906144d0565b6040518060400160405280601b81526020017f564c504d696e696e673a3a636f6d70757465437670566573743a310000000000815250614664565b6001600160601b031660408c0152600082156140b2576140ad83836144d0565b6140b5565b60005b9050600088156140ce576140c989866144d0565b6140d1565b60005b905060006140df83836136fb565b905060008315806140ee575081155b1561410a575061016254600160a01b900463ffffffff16614160565b8e600001518f6020015103975061415d8261230d61414a61016260149054906101000a900463ffffffff1663ffffffff168761451290919063ffffffff16565b6120a28863ffffffff808f169061451216565b90505b6101625463ffffffff808316600160a01b90920416116141905761016254600160a01b900463ffffffff16614192565b805b8f60000151018f6020019063ffffffff16908163ffffffff16815250505050505050505050505b94509492505050565b6001600160a01b038216600090815261012d6020526040812081906141f09063ffffffff80861690614df116565b909590945092505050565b6001600160601b03606082901c811692911690565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526142629084906149e8565b505050565b6000611fac83836040518060400160405280602081526020017f536166654d61746839363a207375627472616374696f6e206f766572666c6f7781525061495b565b6001600160a01b03808316600081815261012d60205260408082208054868616600160401b81810268010000000000000000600160e01b03198416179093559251919004909416939092849290917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4614262838284614e29565b6001600160a01b038416600090815261012d6020526040812081908190614357908763ffffffff80891690614f7216565b91509150816001600160c01b03166000141561437857600092505050611ae0565b30600090815261012d6020526040812061439c908863ffffffff80891690614f7216565b5030600090815261012d60205260408120919250906143c69063ffffffff808616908490614f7216565b5090506143d48483836150d6565b9998505050505050505050565b6000614422436040518060400160405280601e81526020017f564c504d696e696e673a3a5f63757272426c6f636b3a6f766572666c6f770000815250614427565b905090565b600081600160201b84106144b95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561447e578181015183820152602001614466565b50505050905090810190601f1680156144ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b6000611fac8383600080614326565b6000611fac83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615200565b60008261452157506000611361565b8282028284828161452e57fe5b0414611fac5760405162461bcd60e51b8152600401808060200182810382526021815260200180615ba56021913960400191505060405180910390fd5b6000611fac83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250615252565b60008460800151600014156145c457506000611ae0565b611add85606001516040518060400160405280601781526020017f564c504d696e696e673a3a636f6d707574654376703a320000000000000000008152506146128860800151888888613755565b6001600160601b0316919061495b565b6000611fac83836040518060400160405280601d81526020017f536166654d61746839363a206164646974696f6e206f766572666c6f770000008152506148f1565b600081600160601b84106144b95760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b60008060006146c7846152b7565b855490915063ffffffff166146dd868284615316565b9097909650945050505050565b6001600160a01b038116600090815261012d6020526040812081908190614710906154ae565b91509150816001600160c01b03166000141561473157600092505050612bc4565b30600090815261012d6020526040812061474a906154ae565b5030600090815261012d60205260408120919250906147749063ffffffff808616908490614f7216565b5090506147828483836150d6565b9695505050505050565b303b1590565b600054610100900460ff16806147ab57506147ab61478c565b806147b9575060005460ff16155b6147f45760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff1615801561481f576000805460ff1961ff0019909116610100171660011790555b614827615549565b61482f6155e9565b80156119d1576000805461ff001916905550565b600054610100900460ff168061485c575061485c61478c565b8061486a575060005460ff16155b6148a55760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff161580156148d0576000805460ff1961ff0019909116610100171660011790555b6097805460ff1916600117905580156119d1576000805461ff001916905550565b6000838301826001600160601b0380871690831610156149525760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b50949350505050565b6000836001600160601b0316836001600160601b0316111582906149c05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b505050900390565b6101615461016254611aa4916001600160a01b039081169116848461369b565b6149fa826001600160a01b03166156e2565b614a4b576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310614a895780518252601f199092019160209182019101614a6a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614aeb576040519150601f19603f3d011682016040523d82523d6000602084013e614af0565b606091505b509150915081614b47576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156136f557808060200190516020811015614b6357600080fd5b50516136f55760405162461bcd60e51b815260040180806020018281038252602a815260200180615c14602a913960400191505060405180910390fd5b6000611fac614bb864e8d4a5100061230d8686614512565b6040518060400160405280601981526020017f564c504d696e696e673a3a5f636f6d7075746543767041646a00000000000000815250614664565b6001600160601b031660609190911b6bffffffffffffffffffffffff60601b161790565b6001600160a01b03808316600090815261012d6020526040812080549092600160401b90910416908115614c63576001600160a01b038216600090815261012d60205260409020614c65565b825b90506000614c72826154ae565b506001600160a01b038716600090815261012e6020526040902054909150614cb190614caa90839088906001600160c01b031661571b565b8390615779565b505050506001600160a01b0392909216600090815261012e6020526040902080546001600160c01b0319166001600160c01b039290921691909117905550565b30600090815261012d60205260409020611aa49082615779565b60008381614d176143e1565b9050868163ffffffff161115614de757604080516370a0823160e01b8152306004820152905163ffffffff8316899003916000916001600160a01b038916916370a08231916024808301926020929190829003018186803b158015614d7b57600080fd5b505afa158015614d8f573d6000803e3d6000fd5b505050506040513d6020811015614da557600080fd5b505190508015614de457614dc264e8d4a5100061230d8489614512565b9450614de1614dda8261230d8864e8d4a51000614512565b85906136fb565b93505b50505b9450945094915050565b600080821580614e075750835463ffffffff1683115b614e1a57614e1584846158f4565b614e1e565b6000805b915091509250929050565b6000806001600160a01b038416614e635750506001600160a01b03808416600090815261012d602052604080822092841682529020614ebf565b6001600160a01b038316614e9a5750506001600160a01b03808316600090815261012d602052604080822092861682529020614ebf565b50506001600160a01b03808316600090815261012d6020526040808220928416825290205b6001600160a01b038516600090815261012e60205260408120546001600160c01b031690614eec846154ae565b5090506000614efd8260008561571b565b9050806001600160c01b0316826001600160c01b031614614f2457614f228582615779565b505b6000614f2f856154ae565b5090506000614f408286600061571b565b9050806001600160c01b0316826001600160c01b03161461368f57614f658682615779565b5050505050505050505050565b6000806000614f80856152b7565b9050614f8a615af2565b5060408051606081018252875463ffffffff8082168352600160201b8204166020830152600160401b90046001600160a01b031691810191909152614fcd615adb565b851561509757815163ffffffff1686111561502f576040805162461bcd60e51b815260206004820152601f60248201527f4368506f696e74733a20696e76616c696420636865636b706f696e7420696400604482015290519081900360640190fd5b5063ffffffff8581166000908152600189016020908152604091829020825180840190935254808416808452600160201b9091046001600160c01b03169183019190915290918791908516141561509557506020810151905190945092506150ce915050565b505b6000806150a98a856000015187615316565b63ffffffff918216600090815260018d01602052604090205490985016955050505050505b935093915050565b60008060006150e4866141fb565b9150915060006150f3866141fb565b5090506000615101866141fb565b5090506001600160601b03831661511a578394506151f5565b600061513b64e8d4a5100061230d6001600160601b03878116908716614512565b9050816001600160601b0316836001600160601b03161461519f5760006151786001600160601b038085169061230d90871664e8d4a51000614512565b905064e8d4a5100081111561519d5761519a8161230d8464e8d4a51000614512565b91505b505b6151f16151e1826040518060400160405280601881526020017f564c504d696e696e673a3a5f636f6d70757465566f7465730000000000000000815250614664565b6001600160601b03871690614622565b9550505b505050509392505050565b600081848411156149c05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b600081836152a15760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b5060008385816152ad57fe5b0495945050505050565b600043821061530d576040805162461bcd60e51b815260206004820152601d60248201527f4368506f696e74733a20626c6f636b206e6f7420796574206d696e6564000000604482015290519081900360640190fd5b61136182615928565b600080615321615adb565b63ffffffff85166153395760008092509250506150ce565b5063ffffffff8481166000908152600187016020908152604091829020825180840190935254808416808452600160201b9091046001600160c01b0316918301919091529091851610615394576020015184925090506150ce565b60016000818152908701602052604090205463ffffffff808616911611156153c35760008092509250506150ce565b6001855b8163ffffffff168163ffffffff161115615476576000600263ffffffff8484031604820363ffffffff818116600090815260018c016020908152604091829020825180840190935254808416808452600160201b9091046001600160c01b0316918301919091529096509192508816141561544f5780846020015195509550505050506150ce565b835163ffffffff8089169116101561546957809250615470565b6001810391505b506153c7565b5063ffffffff811660009081526001880160205260409020549093506001600160c01b03600160201b90910416915050935093915050565b6000806154b9615af2565b5060408051606081018252845463ffffffff808216808452600160201b83049091166020840152600160401b9091046001600160a01b031692820192909252901561553b57805163ffffffff908116600090815260018601602052604080822054845184168352912054600160201b9091046001600160c01b0316911661553f565b6000805b9250925050915091565b600054610100900460ff1680615562575061556261478c565b80615570575060005460ff16155b6155ab5760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff1615801561482f576000805460ff1961ff00199091166101001716600117905580156119d1576000805461ff001916905550565b600054610100900460ff1680615602575061560261478c565b80615610575060005460ff16155b61564b5760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff16158015615676576000805460ff1961ff0019909116610100171660011790555b6000615680613dca565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156119d1576000805461ff001916905550565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611ae0575050151592915050565b6000806000615729866141fb565b91509150600080615739876141fb565b91509150600080615749886141fb565b9150915061576b61575b878685615986565b615766878685615986565b614bf3565b9a9950505050505050505050565b60008061578543615928565b905061578f615af2565b5060408051606081018252855463ffffffff808216808452600160201b83049091166020840152600160401b9091046001600160a01b031692820192909252906000906157dd576000615807565b815163ffffffff166000908152600187016020526040902054600160201b90046001600160c01b03165b90506000816001600160c01b0316866001600160c01b0316141590508363ffffffff16836020015163ffffffff161461587257508151600190810163ffffffff908116808552885463ffffffff19161767ffffffff000000001916600160201b918616919091021787555b80156158e95760408051808201825263ffffffff86811682526001600160c01b03898116602080850191825288518416600090815260018e019091529490942092518354945163ffffffff19909516921691909117640100000000600160e01b031916600160201b93909116929092029190911790555b505051949350505050565b63ffffffff908116600090815260019290920160205260409091205490811691600160201b9091046001600160c01b031690565b6000600160201b8210615982576040805162461bcd60e51b815260206004820152601b60248201527f4368506f696e74733a20626c6f636b4e756d203e3d20322a2a33320000000000604482015290519081900360640190fd5b5090565b6000816001600160601b0316836001600160601b031614156159a9575082611fac565b816001600160601b0316836001600160601b031611156159f0576159e96159d96001600160601b03851684614267565b6001600160601b03861690614622565b9050611fac565b6000615a056001600160601b03841685614267565b9050806001600160601b0316856001600160601b031611615a27576000615a3a565b615a3a6001600160601b03861682614267565b95945050505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518060a001604052806000815260200160008152602001600063ffffffff16815260200160008152602001600081525090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604080518082019091526000808252602082015290565b60408051606081018252600080825260208201819052918101919091529056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373564c504d696e696e673a20746f6f206269672063767056657374696e67506572696f64496e426c6f636b73564c504d696e696e673a20616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656464656c65676174653a2063616e27742064656c656761746520746f2074686520636f6e74726163742061646472657373a26469706673582212208f4a4eae85ea3a2943c1b14fbff5f401925e82e4cf561d40d50739e73289346164736f6c634300060c0033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102f05760003560e01c8063782d6fe11161019d578063a41fe49f116100e9578063cfc2cb60116100a2578063e99f5b801161007c578063e99f5b8014610c3f578063f247c4b014610c65578063f2fde38b14610c6d578063f3f14ed014610c93576102f0565b8063cfc2cb6014610bab578063d13f90b414610bf5578063d8f14f2b14610c37576102f0565b8063a41fe49f14610a44578063ab85cfe414610a6d578063ac4afa3814610a93578063b4b5ea5714610af5578063b9d02df414610b1b578063bfd05aaa14610b85576102f0565b80638da5cb5b1161015657806394f70aca1161013057806394f70aca1461098f578063996517a5146109ac5780639c954c9d146109d2578063a153d965146109ef576102f0565b80638da5cb5b146109295780638e782f4d14610931578063932bb0a11461095d576102f0565b8063782d6fe1146108165780637ca81460146108425780637cd07e471461089857806385d9aabb146108a0578063866bf7ae146108ed5780638cd0d629146108f5576102f0565b8063433cc0e41161025c5780635c19a95c116102155780636aa7098c116101ef5780636aa7098c1461073e578063715018a61461077e5780637644c30f146107865780637733fdbb146107c0576102f0565b80635c19a95c146106e25780635c2ef9a314610708578063630b5ba114610736576102f0565b8063433cc0e41461054f57806348cd4cb11461061457806351eb05a6146106355780635312ea8e1461065257806356b2ed531461066f5780635754f8d614610695576102f0565b80631db56032116102ae5780631db56032146104515780631e31d0531461047d578063238684911461048557806323cf3118146104a457806334940fa8146104ca578063430bf6df1461052b576102f0565b8062aeef8a146102f55780630795debe14610320578063081e3eda14610362578063151e6aa51461037c57806317caf6f114610384578063180abddd1461038c575b600080fd5b61031e6004803603606081101561030b57600080fd5b5080359060208101359060400135610cb9565b005b6103466004803603602081101561033657600080fd5b50356001600160a01b0316610fb7565b604080516001600160a01b039092168252519081900360200190f35b61036a610fd3565b60408051918252519081900360200190f35b610346610fda565b61036a610fea565b61031e600480360360608110156103a257600080fd5b81359190810190604081016020820135600160201b8111156103c357600080fd5b8201836020820111156103d557600080fd5b803590602001918460208302840111600160201b831117156103f657600080fd5b919390929091602081019035600160201b81111561041357600080fd5b82018360208201111561042557600080fd5b803590602001918460208302840111600160201b8311171561044657600080fd5b509092509050610ff1565b61036a6004803603604081101561046757600080fd5b50803590602001356001600160a01b031661113d565b610346611367565b61031e6004803603602081101561049b57600080fd5b5035151561138b565b61031e600480360360208110156104ba57600080fd5b50356001600160a01b0316611417565b6104fc600480360360408110156104e057600080fd5b5080356001600160a01b0316906020013563ffffffff166114c2565b6040805163ffffffff90941684526001600160601b039283166020850152911682820152519081900360600190f35b6105336114ed565b604080516001600160601b039092168252519081900360200190f35b61031e6004803603606081101561056557600080fd5b81359190810190604081016020820135600160201b81111561058657600080fd5b82018360208201111561059857600080fd5b803590602001918460208302840111600160201b831117156105b957600080fd5b919390929091602081019035600160201b8111156105d657600080fd5b8201836020820111156105e857600080fd5b803590602001918460208302840111600160201b8311171561060957600080fd5b509092509050611504565b61061c61163a565b6040805163ffffffff9092168252519081900360200190f35b61031e6004803603602081101561064b57600080fd5b503561164e565b61031e6004803603602081101561066857600080fd5b50356116d8565b61031e6004803603602081101561068557600080fd5b50356001600160a01b03166118f0565b6106b2600480360360208110156106ab57600080fd5b5035611948565b60408051958652602086019490945263ffffffff9092168484015260608401526080830152519081900360a00190f35b61031e600480360360208110156106f857600080fd5b50356001600160a01b031661197f565b61031e6004803603604081101561071e57600080fd5b506001600160a01b03813581169160200135166119d4565b61031e611a84565b6105336004803603608081101561075457600080fd5b506001600160a01b038135169060208101359063ffffffff60408201358116916060013516611aa8565b61031e611ae8565b6107ac6004803603602081101561079c57600080fd5b50356001600160a01b0316611b8a565b604080519115158252519081900360200190f35b61031e60048036036101008110156107d757600080fd5b508035906001600160a01b036020820135169060ff60408201351690606081013515159060808101359060a08101359060c08101359060e00135611ba0565b6105336004803603604081101561082c57600080fd5b506001600160a01b038135169060200135611f79565b6108686004803603602081101561085857600080fd5b50356001600160a01b0316611fb3565b6040805163ffffffff94851681529290931660208301526001600160a01b03168183015290519081900360600190f35b610346611fea565b61031e60048036036101008110156108b757600080fd5b5080359060208101359060ff60408201351690606081013515159060808101359060a08101359060c08101359060e00135612001565b61061c6122a5565b61036a6004803603606081101561090b57600080fd5b508035906001600160a01b03602082013516906040013515156122b9565b610346612313565b61036a6004803603604081101561094757600080fd5b50803590602001356001600160a01b0316612322565b6107ac6004803603606081101561097357600080fd5b50803590602081013590604001356001600160a01b0316612587565b61031e600480360360208110156109a557600080fd5b50356125b3565b61036a600480360360208110156109c257600080fd5b50356001600160a01b0316612689565b61031e600480360360208110156109e857600080fd5b503561269c565b610a1b60048036036040811015610a0557600080fd5b506001600160a01b038135169060200135612790565b604051808363ffffffff1681526020018263ffffffff1681526020019250505060405180910390f35b61031e60048036036060811015610a5a57600080fd5b508035906020810135906040013561283b565b6107ac60048036036020811015610a8357600080fd5b50356001600160a01b0316612b65565b610ab060048036036020811015610aa957600080fd5b5035612bc9565b604080516001600160a01b039097168752941515602087015260ff9093168585015263ffffffff918216606086015216608084015260a0830152519081900360c00190f35b61053360048036036020811015610b0b57600080fd5b50356001600160a01b0316612c2d565b610b4760048036036040811015610b3157600080fd5b50803590602001356001600160a01b0316612c5f565b6040805163ffffffff96871681529490951660208501526001600160601b039283168486015291166060830152608082015290519081900360a00190f35b61036a60048036036020811015610b9b57600080fd5b50356001600160a01b0316612cb3565b610bd760048036036040811015610bc157600080fd5b50803590602001356001600160a01b0316612cc6565b6040805192835263ffffffff90911660208301528051918290030190f35b61031e600480360360a0811015610c0b57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060800135612cf1565b610346612ea3565b61036a60048036036020811015610c5557600080fd5b50356001600160a01b0316612eb3565b610533612ec6565b61031e60048036036020811015610c8357600080fd5b50356001600160a01b0316612ed6565b61036a60048036036020811015610ca957600080fd5b50356001600160a01b0316612fcf565b60975460ff16610cfe576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff19169055610d1183612fe2565b610d19613039565b60006101648481548110610d2957fe5b6000918252602080832087845261016a825260408085206101668452818620338088529085528287208b885261016b865283882091885294529420600290930201935090610d778484613113565b610d838285838661339f565b8515610db5578354610da0906001600160a01b031633308961369b565b6001820154610daf90876136fb565b60018301555b8415610de35761016154610dd4906001600160a01b031633308861369b565b8054610de090866136fb565b81555b805415610e4857805460018301548554610e079291906001600160a01b0316612587565b15610e48576040805162461bcd60e51b815260206004820152600c60248201526b424f4f53545f424f554e445360a01b604482015290519081900360640190fd5b6001808301546040805160c08101825287546001600160a01b038116825260ff600160a01b820481161515602080850191909152600160a81b83049091168385015263ffffffff600160b01b83048116606080860191909152600160d01b90930481166080808601919091528b88015460a080870191909152865180880188528a5481528a8a0154841681860152875191820188528c548252988c01549381019390935260028b015490911694820194909452600389015491810191909152600488015492810192909252610f1e939091613755565b82546001600160601b0391909116600160a01b026001600160a01b0390911617825560408051878152602081018790528151899233927f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e929081900390910190a333600090815261016e602052604090205460ff1615610fa157610fa1336137d2565b50506097805460ff191660011790555050505050565b610168602052600090815260409020546001600160a01b031681565b6101645490565b610162546001600160a01b031681565b6101675481565b610ff9613dca565b6065546001600160a01b03908116911614611049576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b82818114611092576040805162461bcd60e51b8152602060048201526011602482015270098cadccee8d0e640dcdee840dac2e8c6d607b1b604482015290519081900360640190fd5b60005b81811015611134578383828181106110a957fe5b905060200201356001600160601b0316610166600089815260200190815260200160002060008888858181106110db57fe5b602090810292909201356001600160a01b031683525081019190915260400160002080546bffffffffffffffffffffffff60401b1916600160401b6001600160601b039390931692909202919091179055600101611095565b50505050505050565b6000611147615a43565b610164848154811061115557fe5b60009182526020918290206040805160c081018252600290930290910180546001600160a01b038116845260ff600160a01b82048116151595850195909552600160a81b81049094169183019190915263ffffffff600160b01b840481166060840152600160d01b909304909216608082015260019091015460a082015290506111dd615a78565b50600084815261016a6020908152604091829020825160a08101845281548152600182015492810192909252600281015463ffffffff1692820192909252600382015460608201526004909101546080820152611238615aad565b506000858152610166602090815260408083206001600160a01b0388168452825291829020825160a081018452815463ffffffff8082168352600160201b820416938201939093526001600160601b03600160401b8404811694820194909452600160a01b909204909216606082015260019091015460808201526112bb615adb565b50600086815261016b602090815260408083206001600160a01b03891684528252918290208251808401909352805483526001015463ffffffff169082015261130384613dce565b5061130d83613e57565b50610164878154811061131c57fe5b6000918252602090912060029091020154600160d01b900463ffffffff1660808501526113498484613ea5565b50600061135883868487613ee6565b96505050505050505b92915050565b33600090815261012d6020526040902054600160401b90046001600160a01b031690565b60975460ff166113d0576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1990811690915533600090815261016e602052604090208054831580159190931617905561140757611407336137d2565b506097805460ff19166001179055565b61141f613dca565b6065546001600160a01b0390811691161461146f576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b61016380546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517ff40543f3e605deae7fbca26db18ff1de07eda2925d68655836eae4c167444e3290600090a250565b6000806000806114d286866141c2565b90945090506114e0816141fb565b9497909650939450505050565b61016154600160a01b90046001600160601b031681565b61150c613dca565b6065546001600160a01b0390811691161461155c576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b828181146115a5576040805162461bcd60e51b8152602060048201526011602482015270098cadccee8d0e640dcdee840dac2e8c6d607b1b604482015290519081900360640190fd5b60005b81811015611134578383828181106115bc57fe5b905060200201356001600160601b0316610166600089815260200190815260200160002060008888858181106115ee57fe5b6001600160a01b036020918202939093013583168452830193909352604090910160002080546001600160601b0394909416600160a01b029390911692909217909155506001016115a8565b61016254600160c01b900463ffffffff1681565b60975460ff16611693576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1916905561016480546114079190839081106116b157fe5b906000526020600020906002020161016a6000848152602001908152602001600020613113565b60975460ff1661171d576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1916905561173081612fe2565b611738613039565b6000610164828154811061174857fe5b60009182526020808320858452610166825260408085203380875290845281862088875261016b85528287208288529094529420600183015460029094029091018054909550919390926117a6926001600160a01b03169190614210565b8054156117ca578054610161546117ca916001600160a01b03909116903390614210565b600182015481546040805192835260208301919091528051869233927f2369db1bafee945aee5630782f4a170682e3f8188d8dc247a4c73eb8c9e692d292918290030190a38154600160401b90046001600160601b0316156118a857610161548254600160a01b9091046001600160601b03908116600160401b909204161161187d5781546101615461187891600160a01b9091046001600160601b0390811691600160401b900416614267565b611880565b60005b61016160146101000a8154816001600160601b0302191690836001600160601b031602179055505b600060018301819055825463ffffffff16835580825533815261016e602052604090205460ff16156118dd576118dd336137d2565b50506097805460ff191660011790555050565b60975460ff16611935576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff19169055611407816137d2565b61016a60205260009081526040902080546001820154600283015460038401546004909401549293919263ffffffff909116919085565b6001600160a01b0381163014156119c75760405162461bcd60e51b8152600401808060200182810382526030815260200180615c3e6030913960400191505060405180910390fd5b6119d133826142a9565b50565b6119dc613dca565b6065546001600160a01b03908116911614611a2c576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b6001600160a01b038281166000818152610168602052604080822080546001600160a01b0319169486169485179055517fb7b89eb0ea057d36260d49cabb87830afa2a5fcfe748fe2ae71de060b6410f939190a35050565b6101645460005b81811015611aa457611a9c8161164e565b600101611a8b565b5050565b6001600160a01b038416600090815261016e602052604081205460ff16611ad157506000611ae0565b611add85858585614326565b90505b949350505050565b611af0613dca565b6065546001600160a01b03908116911614611b40576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b6065546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3606580546001600160a01b0319169055565b61016e6020526000908152604090205460ff1681565b611ba8613dca565b6065546001600160a01b03908116911614611bf8576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b611c0187612b65565b15611c53576040805162461bcd60e51b815260206004820152601e60248201527f564c504d696e696e673a20746f6b656e20616c72656164792061646465640000604482015290519081900360640190fd5b611c5b611a84565b6000611c656143e1565b6101625490915060009063ffffffff600160c01b909104811690831611611c9c5761016254600160c01b900463ffffffff16611c9e565b815b61016754909150611caf908b6136fb565b6101678190555060006101648054905090506101646040518060c001604052808c6001600160a01b031681526020018a151581526020018b60ff168152602001611d2e8e6040518060400160405280601d81526020017f564c504d696e696e673a20746f6f2062696720616c6c6f636174696f6e000000815250614427565b63ffffffff1681526020018463ffffffff1681526020016000815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160000160156101000a81548160ff021916908360ff16021790555060608201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001601a6101000a81548163ffffffff021916908363ffffffff16021790555060a0820151816001015550508061016560008c6001600160a01b03166001600160a01b03168152602001908152602001600020819055508661016a6000838152602001908152602001600020600001819055508561016a6000838152602001908152602001600020600101819055508161016a600083815260200190815260200160002060020160006101000a81548163ffffffff021916908363ffffffff1602179055508461016c60008c6001600160a01b03166001600160a01b03168152602001908152602001600020819055508361016d60008c6001600160a01b03166001600160a01b0316815260200190815260200160002081905550808a6001600160a01b03167f4ca3b1f4222c9ac99ea2eb1c68764056287a101a2f63d81e21c3a7ccfcef36e48d6040518082815260200191505060405180910390a35050505050505050505050565b6001600160a01b038216600090815261016e602052604081205460ff16611fa257506000611361565b611fac83836144c1565b9392505050565b61012d6020526000908152604090205463ffffffff80821691600160201b810490911690600160401b90046001600160a01b031683565b61016354600160601b90046001600160a01b031681565b612009613dca565b6065546001600160a01b03908116911614612059576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b612061611a84565b6120a8876120a26101648b8154811061207657fe5b6000918252602090912060029091020154610167549063ffffffff600160b01b9091048116906144d016565b906136fb565b6101675560408051808201909152601d81527f564c504d696e696e673a20746f6f2062696720616c6c6f636174696f6e00000060208201526120eb908890614427565b61016489815481106120f957fe5b906000526020600020906002020160000160166101000a81548163ffffffff021916908363ffffffff16021790555084610164898154811061213757fe5b906000526020600020906002020160000160146101000a81548160ff02191690831515021790555085610164898154811061216e57fe5b600091825260208083206002909202909101805460ff94909416600160a81b0260ff60a81b199094169390931790925589815261016a909152604081208581556001018490556101648054849261016c9290918c9081106121cb57fe5b600091825260208083206002909202909101546001600160a01b031683528201929092526040018120919091556101648054839261016d9290918c90811061220f57fe5b600091825260208083206002909202909101546001600160a01b0316835282019290925260400190205561016480548991908290811061224b57fe5b600091825260209182902060029091020154604080518b815290516001600160a01b03909216927f0e6fb68a420d604687d312365a9cb09a342eecccc96c0dc3283dbdbb070ce10392918290030190a35050505050505050565b61016254600160a01b900463ffffffff1681565b6000611ae064e8d4a5100061230d846122eb576001600160a01b038616600090815261016d6020526040902054612306565b6001600160a01b038616600090815261016c60205260409020545b8790614512565b9061456b565b6065546001600160a01b031690565b61016454600090831061233757506000611361565b61233f615a43565b610164848154811061234d57fe5b60009182526020918290206040805160c081018252600290930290910180546001600160a01b038116845260ff600160a01b82048116151595850195909552600160a81b81049094169183019190915263ffffffff600160b01b840481166060840152600160d01b909304909216608082015260019091015460a082015290506123d5615a78565b50600084815261016a6020908152604091829020825160a08101845281548152600182015492810192909252600281015463ffffffff1692820192909252600382015460608201526004909101546080820152612430615aad565b506000858152610166602090815260408083206001600160a01b0388168452825291829020825160a081018452815463ffffffff8082168352600160201b820416938201939093526001600160601b03600160401b8404811694820194909452600160a01b909204909216606082015260019091015460808201526124b3615adb565b50600086815261016b602090815260408083206001600160a01b03891684528252918290208251808401909352805483526001015463ffffffff16908201526124fb84613dce565b5061250583613e57565b50610164878154811061251457fe5b6000918252602090912060029091020154600160d01b900463ffffffff1660808501526125418484613ea5565b506000612550838684876145ad565b90506125728360400151826001600160601b031661462290919063ffffffff16565b6001600160601b031698975050505050505050565b6000612595838360016122b9565b841080611ae057506125a9838360006122b9565b9093119392505050565b6125bb613dca565b6065546001600160a01b0390811691161461260b576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b61262d816040518060600160405280602b8152602001615b59602b9139614427565b610162805463ffffffff92909216600160a01b0263ffffffff60a01b199092169190911790556040805182815290517fb6d927d1177d65639186d960a1926f0aa9cd35eca2b1b244e62f50fe3bff99a09181900360200190a150565b61016c6020526000908152604090205481565b6126a4613dca565b6065546001600160a01b039081169116146126f4576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b612733816040518060400160405280601e81526020017f564c504d696e696e673a20746f6f2062696720637670506572426c6f636b0000815250614664565b61016380546bffffffffffffffffffffffff19166001600160601b03929092169190911790556040805182815290517f11d360a0021a6a2561238805127962df1163ba47bfd43d6936083b0e0029c88d916020908290030190a150565b6000806001600160a01b0384166127ee576040805162461bcd60e51b815260206004820152601d60248201527f66696e64436865636b706f696e74733a207a65726f206163636f756e74000000604482015290519081900360640190fd5b6001600160a01b038416600090815261012d6020526040902061281190846146b9565b5030600090815261012d6020526040902090925061282f90846146b9565b50809150509250929050565b60975460ff16612880576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b13833981519152604482015290519081900360640190fd5b6097805460ff1916905561289383612fe2565b61289b613039565b600061016484815481106128ab57fe5b6000918252602080832087845261016a825260408085206101668452818620338088529085528287208b885261016b86528388209188529452942060018301546002909402909101945090918611156129355760405162461bcd60e51b8152600401808060200182810382526021815260200180615b846021913960400191505060405180910390fd5b61293f8484613113565b61294b8285838661339f565b851561297b57600182015461296090876144d0565b6001830155835461297b906001600160a01b03163388614210565b84156129a757805461298d90866144d0565b8155610161546129a7906001600160a01b03163387614210565b805415612a0c578054600183015485546129cb9291906001600160a01b0316612587565b15612a0c576040805162461bcd60e51b815260206004820152600c60248201526b424f4f53545f424f554e445360a01b604482015290519081900360640190fd5b6001808301546040805160c08101825287546001600160a01b038116825260ff600160a01b820481161515602080850191909152600160a81b83049091168385015263ffffffff600160b01b83048116606080860191909152600160d01b90930481166080808601919091528b88015460a080870191909152865180880188528a5481528a8a0154841681860152875191820188528c548252988c01549381019390935260028b015490911694820194909452600389015491810191909152600488015492810192909252612ae2939091613755565b82546001600160601b0391909116600160a01b026001600160a01b0390911617825560408051878152602081018790528151899233927f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94929081900390910190a333600090815261016e602052604090205460ff1615610fa157610fa1336137d2565b6001600160a01b038116600090815261016560205260408120546101645481108015612bc05750826001600160a01b03166101648281548110612ba457fe5b60009182526020909120600290910201546001600160a01b0316145b9150505b919050565b6101648181548110612bd757fe5b6000918252602090912060029091020180546001909101546001600160a01b038216925060ff600160a01b8304811692600160a81b81049091169163ffffffff600160b01b8304811692600160d01b9004169086565b6001600160a01b038116600090815261016e602052604081205460ff16612c5657506000612bc4565b611361826146ea565b6101666020908152600092835260408084209091529082529020805460019091015463ffffffff80831692600160201b8104909116916001600160601b03600160401b8304811692600160a01b9004169085565b61016d6020526000908152604090205481565b61016b6020908152600092835260408084209091529082529020805460019091015463ffffffff1682565b600054610100900460ff1680612d0a5750612d0a61478c565b80612d18575060005460ff16155b612d535760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff16158015612d7e576000805460ff1961ff0019909116610100171660011790555b612d86614792565b612d8e614843565b61016180546001600160a01b038089166001600160a01b03199283161790925561016280549288169290911691909117905560408051808201909152601d81527f564c504d696e696e673a20746f6f20626967207374617274426c6f636b0000006020820152612dff908490614427565b61016260186101000a81548163ffffffff021916908363ffffffff160217905550612e5f826040518060400160405280601e81526020017f564c504d696e696e673a20746f6f20626967207665737420706572696f640000815250614427565b61016260146101000a81548163ffffffff021916908363ffffffff160217905550612e898461269c565b8015612e9b576000805461ff00191690555b505050505050565b610161546001600160a01b031681565b6101696020526000908152604090205481565b610163546001600160601b031681565b612ede613dca565b6065546001600160a01b03908116911614612f2e576040805162461bcd60e51b81526020600482018190526024820152600080516020615bc6833981519152604482015290519081900360640190fd5b6001600160a01b038116612f735760405162461bcd60e51b8152600401808060200182810382526026815260200180615b336026913960400191505060405180910390fd5b6065546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3606580546001600160a01b0319166001600160a01b0392909216919091179055565b6101656020526000908152604090205481565b6101645481106119d1576040805162461bcd60e51b815260206004820152601a60248201527f564c504d696e696e673a20696e76616c696420706f6f6c206964000000000000604482015290519081900360640190fd5b3260009081526101696020526040902054431161308e576040805162461bcd60e51b815260206004820152600e60248201526d29a0a6a2afaa2c2fa7a924a3a4a760911b604482015290519081900360640190fd5b32600081815261016960205260409020439055331461311157336000908152610169602052604090205443116130fd576040805162461bcd60e51b815260206004820152600f60248201526e29a0a6a2afa6a9a3afa9a2a72222a960891b604482015290519081900360640190fd5b336000908152610169602052604090204390555b565b61311b615a43565b506040805160c08101825283546001600160a01b038116825260ff600160a01b8204811615156020840152600160a81b8204169282019290925263ffffffff600160b01b830481166060830152600160d01b90920490911660808201819052600184015460a08301819052600061319184613dce565b855490915015613285576131a3615a78565b506040805160a0810182528654815260018701546020820152600287015463ffffffff16918101829052600387015460608201819052600488015460808301819052919291906131fc6131f585613e57565b86906136fb565b63ffffffff881660808a015294506132176131f58986613ea5565b9450818460800151111561323057608084015160048a01555b808460600151111561324757606084015160038a01555b8263ffffffff16846040015163ffffffff16111561328057604084015160028a01805463ffffffff191663ffffffff9092169190911790555b505050505b818460a00151111561329c5760a084015160018701555b8263ffffffff16846080015163ffffffff1611156132d9576080840151865463ffffffff909116600160d01b0263ffffffff60d01b199091161786555b8015612e9b57613370613321826040518060400160405280601a81526020017f564c504d696e696e673a3a5f646f506f6f6c5570646174653a31000000000000815250614664565b60408051808201909152601a81527f564c504d696e696e673a3a5f646f506f6f6c5570646174653a32000000000000602082015261016154600160a01b90046001600160601b031691906148f1565b61016160146101000a8154816001600160601b0302191690836001600160601b03160217905550505050505050565b6133a7615aad565b506040805160a081018252855463ffffffff8082168352600160201b82041660208301526001600160601b03600160401b8204811693830193909352600160a01b9004909116606082015260018501546080820152613404615adb565b506040805180820182528454815260018086015463ffffffff908116602080850191909152858101518651865160c0810188528b546001600160a01b038116825260ff600160a01b82048116151583870152600160a81b820416828a0152600160b01b81048616606080840191909152600160d01b90910486166080808401919091528d88015460a0808501919091528a519081018b528c548152978c01549588019590955260028b0154909516978601979097526003890154938501939093526004880154918401919091529293909160009182916134e79188918890613ee6565b915091508160001415806134fa57508015155b1561352f5760408601518a546001600160601b03909116600160401b026bffffffffffffffffffffffff60401b19909116178a555b80156136285761016154600160a01b90046001600160601b0316811115613566575061016154600160a01b90046001600160601b03165b6135f76135a8826040518060400160405280601981526020017f564c504d696e696e673a3a5f76657374557365724376703a3100000000000000815250614664565b60408051808201909152601981527f564c504d696e696e673a3a5f76657374557365724376703a3200000000000000602082015261016154600160a01b90046001600160601b0316919061495b565b61016160146101000a8154816001600160601b0302191690836001600160601b0316021790555061362833826149c8565b8363ffffffff16866020015163ffffffff1611156136665760208601518a5463ffffffff909116600160201b0267ffffffff0000000019909116178a555b855163ffffffff8085169116111561368f5785518a5463ffffffff191663ffffffff909116178a555b50505050505050505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526136f59085906149e8565b50505050565b600082820183811015611fac576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000613765858560a00151614ba0565b905081602001516000148061377957508151155b8061378357508251155b1561378d57611ae0565b611add61379e868460600151614ba0565b6137c36137b386600001518660800151614ba0565b6001600160601b03851690614622565b6001600160601b031690614622565b6101645460008080805b84811015613c9a576000818152610166602090815260408083206001600160a01b038a168452909152902054613825906001600160601b0386811691600160401b900416614622565b93506000610164828154811061383757fe5b60009182526020808320600290920290910180546001600160a01b03908116808552610168909352604084205491945016806139415761016154604080516370a0823160e01b81526001600160a01b03858116600483015291516139259392909216916370a0823191602480820192602092909190829003018186803b1580156138c057600080fd5b505afa1580156138d4573d6000803e3d6000fd5b505050506040513d60208110156138ea57600080fd5b505160408051808201909152601f81527f564c504d696e696e673a3a5f646f436865636b706f696e74566f7465733a31006020820152614664565b925061393a6001600160601b03871684614622565b9550613b15565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561397c57600080fd5b505afa158015613990573d6000803e3d6000fd5b505050506040513d60208110156139a657600080fd5b5051604080516370a0823160e01b81526001600160a01b0386811660048301529151929350600092918516916370a0823191602480820192602092909190829003018186803b1580156139f857600080fd5b505afa158015613a0c573d6000803e3d6000fd5b505050506040513d6020811015613a2257600080fd5b505190506000613a3b8361230d8464e8d4a51000614512565b61016154604080516370a0823160e01b81526001600160a01b038881166004830152915193945060009391909216916370a08231916024808301926020929190829003018186803b158015613a8f57600080fd5b505afa158015613aa3573d6000803e3d6000fd5b505050506040513d6020811015613ab957600080fd5b50519050613b0e613ad364e8d4a5100061230d8486614512565b6040518060400160405280601f81526020017f564c504d696e696e673a3a5f646f436865636b706f696e74566f7465733a3100815250614664565b9650505050505b8354600160a01b900460ff16613b2e5750505050613c92565b8354604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015613b7257600080fd5b505afa158015613b86573d6000803e3d6000fd5b505050506040513d6020811015613b9c57600080fd5b810190808051906020019092919050505090506000610166600088815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002060010154905080600014158015613bfe57508115155b15613c8b576000613c218361230d6001600160601b03891664e8d4a51000614512565b90506000613c3864e8d4a5100061230d8585614512565b9050613c448b826136fb565b9a50888e6001600160a01b03167f84f3863b4a309d20b83ad6a41ab2860bf0603f2e4cdab881907e7a847276a661836040518082815260200191505060405180910390a350505b5050505050505b6001016137dc565b506000821580613cb157506001600160601b038216155b613d1457613d0f613cd46001600160601b03841661230d8664e8d4a51000614512565b6040518060400160405280601f81526020017f564c504d696e696e673a3a5f646f436865636b706f696e74566f7465733a3200815250614664565b613d17565b60005b604080516001600160601b038516815290519192507fa51ed239c57bb58dd90b5196b2a3a35e8254954f924d0a8eed8e68460d90254f919081900360200190a1604080516001600160601b0380871682528316602082015281516001600160a01b038916927ff55c0f893af4049399318f4399e95624341f7d36e6958902eb15a73ab771c14f928290030190a2613db786613db28684614bf3565b614c17565b612e9b613dc5836000614bf3565b614cf1565b3390565b6000613e3f826080015163ffffffff168360a001518460000151613e3a6101675461230d886060015163ffffffff16613e3461016360009054906101000a90046001600160601b03166001600160601b031664e8d4a5100061451290919063ffffffff16565b90614512565b614d0b565b63ffffffff16608085015260a0909301929092525090565b6000613e8d826040015163ffffffff16836080015161016160009054906101000a90046001600160a01b03168560200151614d0b565b63ffffffff1660408501526080909301929092525090565b6000613ec9836080015163ffffffff16836060015185600001518560000151614d0b565b63ffffffff16608090950194909452606090920192909252919050565b83516000908190613ef56143e1565b63ffffffff90811680895290821610613f155760008092509250506141b9565b8651819003613f26888888886145ad565b6001600160601b0316935060008415613f6a5761016254613f659063ffffffff600160a01b9091048116840181169061230d9088908681169061451216565b613f6d565b60005b9050600089604001516001600160601b03169050896020015163ffffffff168a6000015163ffffffff161015613fa7578951849003613fb9565b61016254600160a01b900463ffffffff165b925060008115614014576101625463ffffffff600160a01b9091048116908516101561400d57614008858c602001510363ffffffff1661230d8663ffffffff168561451290919063ffffffff16565b61400f565b815b614017565b60005b905061402381846136fb565b955061408d6140528761404c8a8f604001516001600160601b03166136fb90919063ffffffff16565b906144d0565b6040518060400160405280601b81526020017f564c504d696e696e673a3a636f6d70757465437670566573743a310000000000815250614664565b6001600160601b031660408c0152600082156140b2576140ad83836144d0565b6140b5565b60005b9050600088156140ce576140c989866144d0565b6140d1565b60005b905060006140df83836136fb565b905060008315806140ee575081155b1561410a575061016254600160a01b900463ffffffff16614160565b8e600001518f6020015103975061415d8261230d61414a61016260149054906101000a900463ffffffff1663ffffffff168761451290919063ffffffff16565b6120a28863ffffffff808f169061451216565b90505b6101625463ffffffff808316600160a01b90920416116141905761016254600160a01b900463ffffffff16614192565b805b8f60000151018f6020019063ffffffff16908163ffffffff16815250505050505050505050505b94509492505050565b6001600160a01b038216600090815261012d6020526040812081906141f09063ffffffff80861690614df116565b909590945092505050565b6001600160601b03606082901c811692911690565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526142629084906149e8565b505050565b6000611fac83836040518060400160405280602081526020017f536166654d61746839363a207375627472616374696f6e206f766572666c6f7781525061495b565b6001600160a01b03808316600081815261012d60205260408082208054868616600160401b81810268010000000000000000600160e01b03198416179093559251919004909416939092849290917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4614262838284614e29565b6001600160a01b038416600090815261012d6020526040812081908190614357908763ffffffff80891690614f7216565b91509150816001600160c01b03166000141561437857600092505050611ae0565b30600090815261012d6020526040812061439c908863ffffffff80891690614f7216565b5030600090815261012d60205260408120919250906143c69063ffffffff808616908490614f7216565b5090506143d48483836150d6565b9998505050505050505050565b6000614422436040518060400160405280601e81526020017f564c504d696e696e673a3a5f63757272426c6f636b3a6f766572666c6f770000815250614427565b905090565b600081600160201b84106144b95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561447e578181015183820152602001614466565b50505050905090810190601f1680156144ab5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509192915050565b6000611fac8383600080614326565b6000611fac83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615200565b60008261452157506000611361565b8282028284828161452e57fe5b0414611fac5760405162461bcd60e51b8152600401808060200182810382526021815260200180615ba56021913960400191505060405180910390fd5b6000611fac83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250615252565b60008460800151600014156145c457506000611ae0565b611add85606001516040518060400160405280601781526020017f564c504d696e696e673a3a636f6d707574654376703a320000000000000000008152506146128860800151888888613755565b6001600160601b0316919061495b565b6000611fac83836040518060400160405280601d81526020017f536166654d61746839363a206164646974696f6e206f766572666c6f770000008152506148f1565b600081600160601b84106144b95760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b60008060006146c7846152b7565b855490915063ffffffff166146dd868284615316565b9097909650945050505050565b6001600160a01b038116600090815261012d6020526040812081908190614710906154ae565b91509150816001600160c01b03166000141561473157600092505050612bc4565b30600090815261012d6020526040812061474a906154ae565b5030600090815261012d60205260408120919250906147749063ffffffff808616908490614f7216565b5090506147828483836150d6565b9695505050505050565b303b1590565b600054610100900460ff16806147ab57506147ab61478c565b806147b9575060005460ff16155b6147f45760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff1615801561481f576000805460ff1961ff0019909116610100171660011790555b614827615549565b61482f6155e9565b80156119d1576000805461ff001916905550565b600054610100900460ff168061485c575061485c61478c565b8061486a575060005460ff16155b6148a55760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff161580156148d0576000805460ff1961ff0019909116610100171660011790555b6097805460ff1916600117905580156119d1576000805461ff001916905550565b6000838301826001600160601b0380871690831610156149525760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b50949350505050565b6000836001600160601b0316836001600160601b0316111582906149c05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b505050900390565b6101615461016254611aa4916001600160a01b039081169116848461369b565b6149fa826001600160a01b03166156e2565b614a4b576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310614a895780518252601f199092019160209182019101614a6a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614aeb576040519150601f19603f3d011682016040523d82523d6000602084013e614af0565b606091505b509150915081614b47576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b8051156136f557808060200190516020811015614b6357600080fd5b50516136f55760405162461bcd60e51b815260040180806020018281038252602a815260200180615c14602a913960400191505060405180910390fd5b6000611fac614bb864e8d4a5100061230d8686614512565b6040518060400160405280601981526020017f564c504d696e696e673a3a5f636f6d7075746543767041646a00000000000000815250614664565b6001600160601b031660609190911b6bffffffffffffffffffffffff60601b161790565b6001600160a01b03808316600090815261012d6020526040812080549092600160401b90910416908115614c63576001600160a01b038216600090815261012d60205260409020614c65565b825b90506000614c72826154ae565b506001600160a01b038716600090815261012e6020526040902054909150614cb190614caa90839088906001600160c01b031661571b565b8390615779565b505050506001600160a01b0392909216600090815261012e6020526040902080546001600160c01b0319166001600160c01b039290921691909117905550565b30600090815261012d60205260409020611aa49082615779565b60008381614d176143e1565b9050868163ffffffff161115614de757604080516370a0823160e01b8152306004820152905163ffffffff8316899003916000916001600160a01b038916916370a08231916024808301926020929190829003018186803b158015614d7b57600080fd5b505afa158015614d8f573d6000803e3d6000fd5b505050506040513d6020811015614da557600080fd5b505190508015614de457614dc264e8d4a5100061230d8489614512565b9450614de1614dda8261230d8864e8d4a51000614512565b85906136fb565b93505b50505b9450945094915050565b600080821580614e075750835463ffffffff1683115b614e1a57614e1584846158f4565b614e1e565b6000805b915091509250929050565b6000806001600160a01b038416614e635750506001600160a01b03808416600090815261012d602052604080822092841682529020614ebf565b6001600160a01b038316614e9a5750506001600160a01b03808316600090815261012d602052604080822092861682529020614ebf565b50506001600160a01b03808316600090815261012d6020526040808220928416825290205b6001600160a01b038516600090815261012e60205260408120546001600160c01b031690614eec846154ae565b5090506000614efd8260008561571b565b9050806001600160c01b0316826001600160c01b031614614f2457614f228582615779565b505b6000614f2f856154ae565b5090506000614f408286600061571b565b9050806001600160c01b0316826001600160c01b03161461368f57614f658682615779565b5050505050505050505050565b6000806000614f80856152b7565b9050614f8a615af2565b5060408051606081018252875463ffffffff8082168352600160201b8204166020830152600160401b90046001600160a01b031691810191909152614fcd615adb565b851561509757815163ffffffff1686111561502f576040805162461bcd60e51b815260206004820152601f60248201527f4368506f696e74733a20696e76616c696420636865636b706f696e7420696400604482015290519081900360640190fd5b5063ffffffff8581166000908152600189016020908152604091829020825180840190935254808416808452600160201b9091046001600160c01b03169183019190915290918791908516141561509557506020810151905190945092506150ce915050565b505b6000806150a98a856000015187615316565b63ffffffff918216600090815260018d01602052604090205490985016955050505050505b935093915050565b60008060006150e4866141fb565b9150915060006150f3866141fb565b5090506000615101866141fb565b5090506001600160601b03831661511a578394506151f5565b600061513b64e8d4a5100061230d6001600160601b03878116908716614512565b9050816001600160601b0316836001600160601b03161461519f5760006151786001600160601b038085169061230d90871664e8d4a51000614512565b905064e8d4a5100081111561519d5761519a8161230d8464e8d4a51000614512565b91505b505b6151f16151e1826040518060400160405280601881526020017f564c504d696e696e673a3a5f636f6d70757465566f7465730000000000000000815250614664565b6001600160601b03871690614622565b9550505b505050509392505050565b600081848411156149c05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b600081836152a15760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561447e578181015183820152602001614466565b5060008385816152ad57fe5b0495945050505050565b600043821061530d576040805162461bcd60e51b815260206004820152601d60248201527f4368506f696e74733a20626c6f636b206e6f7420796574206d696e6564000000604482015290519081900360640190fd5b61136182615928565b600080615321615adb565b63ffffffff85166153395760008092509250506150ce565b5063ffffffff8481166000908152600187016020908152604091829020825180840190935254808416808452600160201b9091046001600160c01b0316918301919091529091851610615394576020015184925090506150ce565b60016000818152908701602052604090205463ffffffff808616911611156153c35760008092509250506150ce565b6001855b8163ffffffff168163ffffffff161115615476576000600263ffffffff8484031604820363ffffffff818116600090815260018c016020908152604091829020825180840190935254808416808452600160201b9091046001600160c01b0316918301919091529096509192508816141561544f5780846020015195509550505050506150ce565b835163ffffffff8089169116101561546957809250615470565b6001810391505b506153c7565b5063ffffffff811660009081526001880160205260409020549093506001600160c01b03600160201b90910416915050935093915050565b6000806154b9615af2565b5060408051606081018252845463ffffffff808216808452600160201b83049091166020840152600160401b9091046001600160a01b031692820192909252901561553b57805163ffffffff908116600090815260018601602052604080822054845184168352912054600160201b9091046001600160c01b0316911661553f565b6000805b9250925050915091565b600054610100900460ff1680615562575061556261478c565b80615570575060005460ff16155b6155ab5760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff1615801561482f576000805460ff1961ff00199091166101001716600117905580156119d1576000805461ff001916905550565b600054610100900460ff1680615602575061560261478c565b80615610575060005460ff16155b61564b5760405162461bcd60e51b815260040180806020018281038252602e815260200180615be6602e913960400191505060405180910390fd5b600054610100900460ff16158015615676576000805460ff1961ff0019909116610100171660011790555b6000615680613dca565b606580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156119d1576000805461ff001916905550565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590611ae0575050151592915050565b6000806000615729866141fb565b91509150600080615739876141fb565b91509150600080615749886141fb565b9150915061576b61575b878685615986565b615766878685615986565b614bf3565b9a9950505050505050505050565b60008061578543615928565b905061578f615af2565b5060408051606081018252855463ffffffff808216808452600160201b83049091166020840152600160401b9091046001600160a01b031692820192909252906000906157dd576000615807565b815163ffffffff166000908152600187016020526040902054600160201b90046001600160c01b03165b90506000816001600160c01b0316866001600160c01b0316141590508363ffffffff16836020015163ffffffff161461587257508151600190810163ffffffff908116808552885463ffffffff19161767ffffffff000000001916600160201b918616919091021787555b80156158e95760408051808201825263ffffffff86811682526001600160c01b03898116602080850191825288518416600090815260018e019091529490942092518354945163ffffffff19909516921691909117640100000000600160e01b031916600160201b93909116929092029190911790555b505051949350505050565b63ffffffff908116600090815260019290920160205260409091205490811691600160201b9091046001600160c01b031690565b6000600160201b8210615982576040805162461bcd60e51b815260206004820152601b60248201527f4368506f696e74733a20626c6f636b4e756d203e3d20322a2a33320000000000604482015290519081900360640190fd5b5090565b6000816001600160601b0316836001600160601b031614156159a9575082611fac565b816001600160601b0316836001600160601b031611156159f0576159e96159d96001600160601b03851684614267565b6001600160601b03861690614622565b9050611fac565b6000615a056001600160601b03841685614267565b9050806001600160601b0316856001600160601b031611615a27576000615a3a565b615a3a6001600160601b03861682614267565b95945050505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518060a001604052806000815260200160008152602001600063ffffffff16815260200160008152602001600081525090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604080518082019091526000808252602082015290565b60408051606081018252600080825260208201819052918101919091529056fe5265656e7472616e637947756172643a207265656e7472616e742063616c6c004f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373564c504d696e696e673a20746f6f206269672063767056657374696e67506572696f64496e426c6f636b73564c504d696e696e673a20616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65645361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656464656c65676174653a2063616e27742064656c656761746520746f2074686520636f6e74726163742061646472657373a26469706673582212208f4a4eae85ea3a2943c1b14fbff5f401925e82e4cf561d40d50739e73289346164736f6c634300060c0033

Deployed Bytecode Sourcemap

47209:29282:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57866:1222;;;;;;;;;;;;;;;;-1:-1:-1;57866:1222:0;;;;;;;;;;;;:::i;:::-;;50445:52;;;;;;;;;;;;;;;;-1:-1:-1;50445:52:0;-1:-1:-1;;;;;50445:52:0;;:::i;:::-;;;;-1:-1:-1;;;;;50445:52:0;;;;;;;;;;;;;;51748:95;;;:::i;:::-;;;;;;;;;;;;;;;;49649:24;;;:::i;50404:34::-;;;:::i;55500:341::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55500:341:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55500:341:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55500:341:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55500:341:0;;;;;;;;;;-1:-1:-1;55500:341:0;;-1:-1:-1;55500:341:0;-1:-1:-1;55500:341:0;:::i;56592:598::-;;;;;;;;;;;;;;;;-1:-1:-1;56592:598:0;;;;;;-1:-1:-1;;;;;56592:598:0;;:::i;40122:97::-;;;:::i;61411:183::-;;;;;;;;;;;;;;;;-1:-1:-1;61411:183:0;;;;:::i;54143:153::-;;;;;;;;;;;;;;;;-1:-1:-1;54143:153:0;-1:-1:-1;;;;;54143:153:0;;:::i;62510:346::-;;;;;;;;;;;;;;;;-1:-1:-1;62510:346:0;;-1:-1:-1;;;;;62510:346:0;;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;;;;62510:346:0;;;;;;;;;;;;;;;;;;;;;;49590:28;;;:::i;:::-;;;;-1:-1:-1;;;;;49590:28:0;;;;;;;;;;;;;;55153:341;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55153:341:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55153:341:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55153:341:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55153:341:0;;;;;;;;;;-1:-1:-1;55153:341:0;;-1:-1:-1;55153:341:0;-1:-1:-1;55153:341:0;:::i;49811:24::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;57702:123;;;;;;;;;;;;;;;;-1:-1:-1;57702:123:0;;:::i;60434:971::-;;;;;;;;;;;;;;;;-1:-1:-1;60434:971:0;;:::i;61635:107::-;;;;;;;;;;;;;;;;-1:-1:-1;61635:107:0;-1:-1:-1;;;;;61635:107:0;;:::i;50817:50::-;;;;;;;;;;;;;;;;-1:-1:-1;50817:50:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40358:193;;;;;;;;;;;;;;;;-1:-1:-1;40358:193:0;-1:-1:-1;;;;;40358:193:0;;:::i;54947:200::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;54947:200:0;;;;;;;;;;:::i;57495:166::-;;;:::i;62146:323::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;62146:323:0;;;;;;;;;;;;;;;;;;;;;;:::i;6162:148::-;;;:::i;51077:45::-;;;;;;;;;;;;;;;;-1:-1:-1;51077:45:0;-1:-1:-1;;;;;51077:45:0;;:::i;:::-;;;;;;;;;;;;;;;;;;51884:1279;;;;;;;;;;;;;;;;-1:-1:-1;51884:1279:0;;;-1:-1:-1;;;;;51884:1279:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;61932:208::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;61932:208:0;;;;;;;;:::i;39446:61::-;;;;;;;;;;;;;;;;-1:-1:-1;39446:61:0;-1:-1:-1;;;;;39446:61:0;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39446:61:0;;;;;;;;;;;;;;;49996:32;;;:::i;53204:898::-;;;;;;;;;;;;;;;;-1:-1:-1;53204:898:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;49711:38::-;;;:::i;75619:242::-;;;;;;;;;;;;;;;;-1:-1:-1;75619:242:0;;;-1:-1:-1;;;;;75619:242:0;;;;;;;;;;;;:::i;5520:79::-;;;:::i;55882:669::-;;;;;;;;;;;;;;;;-1:-1:-1;55882:669:0;;;;;;-1:-1:-1;;;;;55882:669:0;;:::i;75319:294::-;;;;;;;;;;;;;;;;-1:-1:-1;75319:294:0;;;;;;;;;;;-1:-1:-1;;;;;75319:294:0;;:::i;54586:320::-;;;;;;;;;;;;;;;;-1:-1:-1;54586:320:0;;:::i;50954:54::-;;;;;;;;;;;;;;;;-1:-1:-1;50954:54:0;-1:-1:-1;;;;;50954:54:0;;:::i;54337:208::-;;;;;;;;;;;;;;;;-1:-1:-1;54337:208:0;;:::i;43188:382::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;43188:382:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59129:1264;;;;;;;;;;;;;;;;-1:-1:-1;59129:1264:0;;;;;;;;;;;;:::i;57231:223::-;;;;;;;;;;;;;;;;-1:-1:-1;57231:223:0;-1:-1:-1;;;;;57231:223:0;;:::i;50061:19::-;;;;;;;;;;;;;;;;-1:-1:-1;50061:19:0;;:::i;:::-;;;;-1:-1:-1;;;;;50061:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61748:178;;;;;;;;;;;;;;;;-1:-1:-1;61748:178:0;-1:-1:-1;;;;;61748:178:0;;:::i;50297:57::-;;;;;;;;;;;;;;;;-1:-1:-1;50297:57:0;;;;;;-1:-1:-1;;;;;50297:57:0;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50297:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;51013;;;;;;;;;;;;;;;;-1:-1:-1;51013:57:0;-1:-1:-1;;;;;51013:57:0;;:::i;50872:75::-;;;;;;;;;;;;;;;;-1:-1:-1;50872:75:0;;;;;;-1:-1:-1;;;;;50872:75:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;51164:543;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;51164:543:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;49502:17::-;;;:::i;50504:48::-;;;;;;;;;;;;;;;;-1:-1:-1;50504:48:0;-1:-1:-1;;;;;50504:48:0;;:::i;49905:25::-;;;:::i;6465:244::-;;;;;;;;;;;;;;;;-1:-1:-1;6465:244:0;-1:-1:-1;;;;;6465:244:0;;:::i;50160:51::-;;;;;;;;;;;;;;;;-1:-1:-1;50160:51:0;-1:-1:-1;;;;;50160:51:0;;:::i;57866:1222::-;23703:11;;;;23695:55;;;;;-1:-1:-1;;;23695:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;23695:55:0;;;;;;;;;;;;;;;23828:11;:19;;-1:-1:-1;;23828:19:0;;;57992:21:::1;58008:4:::0;57992:15:::1;:21::i;:::-;58020:34;:32;:34::i;:::-;58063:17;58083:5;58089:4;58083:11;;;;;;;;;::::0;;;::::1;::::0;;;58131:19;;;:13:::1;:19:::0;;;;;;58177:5:::1;:11:::0;;;;;58189:10:::1;58177:23:::0;;;;;;;;;58238:20;;;:14:::1;:20:::0;;;;;:32;;;;;;;58083:11:::1;::::0;;::::1;;::::0;-1:-1:-1;58177:23:0;58279:30:::1;58083:11:::0;58131:19;58279:13:::1;:30::i;:::-;58316:43;58329:4;58335;58341:6;58349:9;58316:12;:43::i;:::-;58372:12:::0;;58368:153:::1;;58395:12:::0;;:65:::1;::::0;-1:-1:-1;;;;;58395:12:0::1;58425:10;58445:4;58452:7:::0;58395:29:::1;:65::i;:::-;58486:14;::::0;::::1;::::0;:27:::1;::::0;58505:7;58486:18:::1;:27::i;:::-;58469:14;::::0;::::1;:44:::0;58368:153:::1;58531:17:::0;;58527:159:::1;;58559:3;::::0;:61:::1;::::0;-1:-1:-1;;;;;58559:3:0::1;58580:10;58600:4;58607:12:::0;58559:20:::1;:61::i;:::-;58646:14:::0;;:32:::1;::::0;58665:12;58646:18:::1;:32::i;:::-;58629:49:::0;;58527:159:::1;58696:14:::0;;:19;58692:150:::1;;58763:14:::0;;58779::::1;::::0;::::1;::::0;58803:12;;58735:82:::1;::::0;58763:14;58779;-1:-1:-1;;;;;58803:12:0::1;58735:27;:82::i;:::-;58734:83;58726:108;;;::::0;;-1:-1:-1;;;58726:108:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;58726:108:0;;;;;;;;;;;;;::::1;;58896:14;::::0;;::::1;::::0;58865:71:::1;::::0;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;58865:71:0;::::1;::::0;;::::1;-1:-1:-1::0;;;58865:71:0;::::1;::::0;::::1;;;;::::0;;::::1;::::0;;;;-1:-1:-1;;;58865:71:0;::::1;::::0;;::::1;::::0;;;;::::1;-1:-1:-1::0;;;58865:71:0;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;;58865:71:0;;::::1;::::0;::::1;::::0;;;;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;::::0;;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;;:30:::1;:71::i;:::-;58848:88:::0;;-1:-1:-1;;;;;58848:88:0;;;::::1;-1:-1:-1::0;;;58848:88:0::1;-1:-1:-1::0;;;;;58848:88:0;;::::1;;::::0;;58948:48:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;58968:4;;58956:10:::1;::::0;58948:48:::1;::::0;;;;;;;;;::::1;59023:10;59009:25;::::0;;;:13:::1;:25;::::0;;;;;::::1;;59005:78;;;59045:30;59064:10;59045:18;:30::i;:::-;-1:-1:-1::0;;24008:11:0;:18;;-1:-1:-1;;24008:18:0;24022:4;24008:18;;;-1:-1:-1;;;;;57866:1222:0:o;50445:52::-;;;;;;;;;;;;-1:-1:-1;;;;;50445:52:0;;:::o;51748:95::-;51825:5;:12;51748:95;:::o;49649:24::-;;;-1:-1:-1;;;;;49649:24:0;;:::o;50404:34::-;;;;:::o;55500:341::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;55656:6;55684:24;;::::1;55676:54;;;::::0;;-1:-1:-1;;;55676:54:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;55676:54:0;;;;;;;;;;;;;::::1;;55742:9;55737:99;55761:3;55757:1;:7;55737:99;;;55815:10;;55826:1;55815:13;;;;;;;;;;;;;-1:-1:-1::0;;;;;55815:13:0::1;55780:5;:11;55786:4;55780:11;;;;;;;;;;;:22;55792:6;;55799:1;55792:9;;;;;;;;::::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;;;;55792:9:0::1;55780:22:::0;;-1:-1:-1;55780:22:0;::::1;::::0;;;;;;-1:-1:-1;55780:22:0;:48;;-1:-1:-1;;;;55780:48:0::1;-1:-1:-1::0;;;;;;;;55780:48:0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;55766:3:0::1;55737:99;;;;5802:1;55500:341:::0;;;;;:::o;56592:598::-;56673:7;56689:17;;:::i;:::-;56709:5;56715:4;56709:11;;;;;;;;;;;;;;;;;56689:31;;;;;;;;56709:11;;;;;;;56689:31;;-1:-1:-1;;;;;56689:31:0;;;;;-1:-1:-1;;;56689:31:0;;;;;;;;;;;;;-1:-1:-1;;;56689:31:0;;;;;;;;;;;;;-1:-1:-1;;;56689:31:0;;;;;;;;-1:-1:-1;;;56689:31:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56727:27:0;;:::i;:::-;-1:-1:-1;56757:19:0;;;;:13;:19;;;;;;;;;56727:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56783:17;;:::i;:::-;-1:-1:-1;56803:11:0;;;;:5;:11;;;;;;;;-1:-1:-1;;;;;56803:17:0;;;;;;;;;;56783:37;;;;;;;;;;;;;;;-1:-1:-1;;;56783:37:0;;;;;;;;;;-1:-1:-1;;;;;;;;56783:37:0;;;;;;;;;;;-1:-1:-1;;;56783:37:0;;;;;;;;;;;;;;;;;;;56827:28;;:::i;:::-;-1:-1:-1;56858:20:0;;;;:14;:20;;;;;;;;-1:-1:-1;;;;;56858:26:0;;;;;;;;;;56827:57;;;;;;;;;;;;;;;;;;;;;56893:25;56912:5;56893:18;:25::i;:::-;;56925:35;56949:10;56925:23;:35::i;:::-;;56993:5;56999:4;56993:11;;;;;;;;;;;;;;;;;;;;;:27;-1:-1:-1;;;56993:27:0;;;;56969:21;;;:51;57027:44;56969:21;57060:10;57027:25;:44::i;:::-;;57081:19;57104:53;57123:5;57130;57137:7;57146:10;57104:18;:53::i;:::-;57078:79;-1:-1:-1;;;;;;;56592:598:0;;;;;:::o;40122:97::-;40192:10;40164:7;40187:16;;;:4;:16;;;;;:26;-1:-1:-1;;;40187:26:0;;-1:-1:-1;;;;;40187:26:0;40122:97;:::o;61411:183::-;23703:11;;;;23695:55;;;;;-1:-1:-1;;;23695:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;23695:55:0;;;;;;;;;;;;;;;23828:11;:19;;-1:-1:-1;;23828:19:0;;;;;;61495:10:::1;23842:5:::0;61481:25;;;:13:::1;:25;::::0;;;;:38;;;::::1;::::0;::::1;::::0;;;::::1;;::::0;;61526:63:::1;;61551:30;61570:10;61551:18;:30::i;:::-;-1:-1:-1::0;24008:11:0;:18;;-1:-1:-1;;24008:18:0;24022:4;24008:18;;;61411:183::o;54143:153::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;54225:8:::1;:20:::0;;-1:-1:-1;;;;;54225:20:0::1;-1:-1:-1::0;;;;;;;;54225:20:0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;54259:31:::1;::::0;::::1;::::0;-1:-1:-1;;54259:31:0::1;54143:153:::0;:::o;62510:346::-;62631:16;62656;62681:21;62720:12;62759:37;62774:7;62783:12;62759:14;:37::i;:::-;62739:57;;-1:-1:-1;62739:57:0;-1:-1:-1;62833:17:0;62739:57;62833:11;:17::i;:::-;62510:346;;62803:47;;-1:-1:-1;62803:47:0;;-1:-1:-1;;;;62510:346:0:o;49590:28::-;;;-1:-1:-1;;;49590:28:0;;-1:-1:-1;;;;;49590:28:0;;:::o;55153:341::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;55309:6;55337:24;;::::1;55329:54;;;::::0;;-1:-1:-1;;;55329:54:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;55329:54:0;;;;;;;;;;;;;::::1;;55395:9;55390:99;55414:3;55410:1;:7;55390:99;;;55468:10;;55479:1;55468:13;;;;;;;;;;;;;-1:-1:-1::0;;;;;55468:13:0::1;55433:5;:11;55439:4;55433:11;;;;;;;;;;;:22;55445:6;;55452:1;55445:9;;;;;;;-1:-1:-1::0;;;;;55445:9:0::1;::::0;;::::1;::::0;;;::::1;;::::0;::::1;55433:22:::0;;;::::1;::::0;;;;;;;;-1:-1:-1;55433:22:0;:48;;-1:-1:-1;;;;;55433:48:0;;;::::1;-1:-1:-1::0;;;55433:48:0::1;::::0;;;::::1;::::0;;;::::1;::::0;;;-1:-1:-1;;55419:3:0::1;55390:99;;49811:24:::0;;;-1:-1:-1;;;49811:24:0;;;;;:::o;57702:123::-;23703:11;;;;23695:55;;;;;-1:-1:-1;;;23695:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;23695:55:0;;;;;;;;;;;;;;;23828:11;:19;;-1:-1:-1;;23828:19:0;;;57786:5:::1;:11:::0;;57772:47:::1;::::0;57786:5;57792:4;;57786:11;::::1;;;;;;;;;;;;;;;57799:13;:19;57813:4;57799:19;;;;;;;;;;;57772:13;:47::i;60434:971::-:0;23703:11;;;;23695:55;;;;;-1:-1:-1;;;23695:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;23695:55:0;;;;;;;;;;;;;;;23828:11;:19;;-1:-1:-1;;23828:19:0;;;60511:21:::1;60527:4:::0;60511:15:::1;:21::i;:::-;60539:34;:32;:34::i;:::-;60582:17;60602:5;60608:4;60602:11;;;;;;;;;::::0;;;::::1;::::0;;;60640;;;:5:::1;:11:::0;;;;;;60652:10:::1;60640:23:::0;;;;;;;;;60701:20;;;:14:::1;:20:::0;;;;;:32;;;;;;;;60780:14:::1;::::0;::::1;::::0;60602:11:::1;::::0;;::::1;::::0;;::::1;60742:12:::0;;60602:11;;-1:-1:-1;60640:23:0;;60701:32;;60742:53:::1;::::0;-1:-1:-1;;;;;60742:12:0::1;::::0;60652:10;60742:25:::1;:53::i;:::-;60806:14:::0;;:19;60802:86:::1;;60865:14:::0;;60836:3:::1;::::0;:44:::1;::::0;-1:-1:-1;;;;;60836:3:0;;::::1;::::0;60853:10:::1;::::0;60836:16:::1;:44::i;:::-;60935:14;::::0;::::1;::::0;60951;;60899:67:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;60929:4;;60917:10:::1;::::0;60899:67:::1;::::0;;;;;;;::::1;60979:14:::0;;-1:-1:-1;;;60979:14:0;::::1;-1:-1:-1::0;;;;;60979:14:0::1;:18:::0;60975:209:::1;;61121:14;::::0;61104;;-1:-1:-1;;;61121:14:0;;::::1;-1:-1:-1::0;;;;;61121:14:0;;::::1;-1:-1:-1::0;;;61104:14:0;;::::1;;:31;:72;;61161:14:::0;;61142::::1;::::0;:34:::1;::::0;-1:-1:-1;;;61142:14:0;;::::1;-1:-1:-1::0;;;;;61142:14:0;;::::1;::::0;-1:-1:-1;;;61161:14:0;::::1;;61142:18;:34::i;:::-;61104:72;;;61138:1;61104:72;61087:14;;:89;;;;;-1:-1:-1::0;;;;;61087:89:0::1;;;;;-1:-1:-1::0;;;;;61087:89:0::1;;;;;;60975:209;61209:1;61192:14;::::0;::::1;:18:::0;;;61217;;61267:21:::1;::::0;;;61295:18;;;61340:10:::1;61326:25:::0;;:13:::1;:25;::::0;;;;;::::1;;61322:78;;;61362:30;61381:10;61362:18;:30::i;:::-;-1:-1:-1::0;;24008:11:0;:18;;-1:-1:-1;;24008:18:0;24022:4;24008:18;;;-1:-1:-1;;60434:971:0:o;61635:107::-;23703:11;;;;23695:55;;;;;-1:-1:-1;;;23695:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;23695:55:0;;;;;;;;;;;;;;;23828:11;:19;;-1:-1:-1;;23828:19:0;;;61711:25:::1;61730:5:::0;61711:18:::1;:25::i;50817:50::-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;40358:193::-;-1:-1:-1;;;;;40418:27:0;;40440:4;40418:27;;40410:88;;;;-1:-1:-1;;;40410:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40512:33;40522:10;40534;40512:9;:33::i;:::-;40358:193;:::o;54947:200::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;55047:28:0;;::::1;;::::0;;;:17:::1;:28;::::0;;;;;:39;;-1:-1:-1;;;;;;55047:39:0::1;::::0;;::::1;::::0;;::::1;::::0;;55100:41;::::1;::::0;55047:28;55100:41:::1;54947:200:::0;;:::o;57495:166::-;57562:5;:12;57545:14;57581:75;57609:6;57603:3;:12;57581:75;;;57633:15;57644:3;57633:10;:15::i;:::-;57617:5;;57581:75;;;;57495:166;:::o;62146:323::-;-1:-1:-1;;;;;62327:22:0;;62307:6;62327:22;;;:13;:22;;;;;;;;62322:54;;-1:-1:-1;62367:1:0;62360:8;;62322:54;62389:74;62404:7;62413:11;62426:16;62444:18;62389:14;:74::i;:::-;62382:81;;62146:323;;;;;;;:::o;6162:148::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;6253:6:::1;::::0;6232:40:::1;::::0;6269:1:::1;::::0;-1:-1:-1;;;;;6253:6:0::1;::::0;6232:40:::1;::::0;6269:1;;6232:40:::1;6283:6;:19:::0;;-1:-1:-1;;;;;;6283:19:0::1;::::0;;6162:148::o;51077:45::-;;;;;;;;;;;;;;;:::o;51884:1279::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;52156:24:::1;52171:8;52156:14;:24::i;:::-;52155:25;52147:68;;;::::0;;-1:-1:-1;;;52147:68:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;52224:17;:15;:17::i;:::-;52248:15;52266:12;:10;:12::i;:::-;52321:10;::::0;52248:30;;-1:-1:-1;52285:22:0::1;::::0;52321:10:::1;-1:-1:-1::0;;;52321:10:0;;::::1;::::0;::::1;52310:21:::0;;::::1;;:45;;52345:10;::::0;-1:-1:-1;;;52345:10:0;::::1;;;52310:45;;;52334:8;52310:45;52380:15;::::0;52285:70;;-1:-1:-1;52380:32:0::1;::::0;52400:11;52380:19:::1;:32::i;:::-;52362:15;:50;;;;52421:11;52435:5;:12;;;;52421:26;;52454:5;52473:268;;;;;;;;52498:8;-1:-1:-1::0;;;;;52473:268:0::1;;;;;52531:13;52473:268;;;;;;52565:9;52473:268;;;;;;52597:65;52617:11;52597:65;;;;;;;;;;;;;;;;::::0;:19:::1;:65::i;:::-;52473:268;;;;;;52690:15;52473:268;;;;;;52730:1;52473:268;;::::0;52454:294:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;52454:294:0::1;;;;;-1:-1:-1::0;;;;;52454:294:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52793:3;52755:16;:35;52780:8;-1:-1:-1::0;;;;;52755:35:0::1;-1:-1:-1::0;;;;;52755:35:0::1;;;;;;;;;;;;:41;;;;52838:12;52805:13;:18;52819:3;52805:18;;;;;;;;;;;:30;;:45;;;;52891:13;52857;:18;52871:3;52857:18;;;;;;;;;;;:31;;:47;;;;52950:15;52913:13;:18;52927:3;52913:18;;;;;;;;;;;:34;;;:52;;;;;;;;;;;;;;;;;;53013:16;52972:19;:38;53000:8;-1:-1:-1::0;;;;;52972:38:0::1;-1:-1:-1::0;;;;;52972:38:0::1;;;;;;;;;;;;:57;;;;53080:16;53036:22;:41;53067:8;-1:-1:-1::0;;;;;53036:41:0::1;-1:-1:-1::0;;;;;53036:41:0::1;;;;;;;;;;;;:60;;;;53140:3;53129:8;-1:-1:-1::0;;;;;53110:47:0::1;;53145:11;53110:47;;;;;;;;;;;;;;;;;;5802:1;;;51884:1279:::0;;;;;;;;:::o;61932:208::-;-1:-1:-1;;;;;62036:22:0;;62016:6;62036:22;;;:13;:22;;;;;;;;62031:54;;-1:-1:-1;62076:1:0;62069:8;;62031:54;62098:36;62113:7;62122:11;62098:14;:36::i;:::-;62091:43;61932:208;-1:-1:-1;;;61932:208:0:o;39446:61::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;39446:61:0;;;;;;-1:-1:-1;;;39446:61:0;;-1:-1:-1;;;;;39446:61:0;;:::o;49996:32::-;;;-1:-1:-1;;;49996:32:0;;-1:-1:-1;;;;;49996:32:0;;:::o;53204:898::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;53464:17:::1;:15;:17::i;:::-;53506:69;53563:11;53506:52;53534:5;53540:4;53534:11;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;:22:::0;53506:15:::1;::::0;;53534:22:::1;-1:-1:-1::0;;;53534:22:0;;::::1;::::0;::::1;::::0;53506:19:::1;:52;:::i;:::-;:56:::0;::::1;:69::i;:::-;53488:15;:87:::0;53607:65:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;53627:11;;53607:19:::1;:65::i;:::-;53582:5;53588:4;53582:11;;;;;;;;;;;;;;;;;;:22;;;:90;;;;;;;;;;;;;;;;;;53706:13;53679:5;53685:4;53679:11;;;;;;;;;;;;;;;;;;:24;;;:40;;;;;;;;;;;;;;;;;;53749:9;53726:5;53732:4;53726:11;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;:32:::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;;53726:32:0::1;-1:-1:-1::0;;;;53726:32:0;;::::1;::::0;;;::::1;::::0;;;53767:19;;;:13:::1;:19:::0;;;;;;:46;;;-1:-1:-1;53820:32:0::1;:48:::0;;;53905:5:::1;:11:::0;;53929:16;;53877:19:::1;::::0;53726:11;;53781:4;;53905:11;::::1;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;:19:::0;-1:-1:-1;;;;;53905:19:0::1;53877:49:::0;;;::::1;::::0;;;;;;;;:68;;;;53983:5:::1;:11:::0;;54007:16;;53952:22:::1;::::0;53905:11;;53989:4;;53983:11;::::1;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;:19:::0;-1:-1:-1;;;;;53983:19:0::1;53952:52:::0;;;::::1;::::0;;;;;;;;:71;54056:5:::1;:11:::0;;54078:4;;54056:5;54078:4;;54056:11;::::1;;;;;;::::0;;;::::1;::::0;;;;::::1;::::0;;::::1;;:19:::0;54037:59:::1;::::0;;;;;;;-1:-1:-1;;;;;54056:19:0;;::::1;::::0;54037:59:::1;::::0;;;;;;;::::1;53204:898:::0;;;;;;;;:::o;49711:38::-;;;-1:-1:-1;;;49711:38:0;;;;;:::o;75619:242::-;75735:7;75758:97;49471:4;75758:86;75772:4;:71;;-1:-1:-1;;;;;75811:32:0;;;;;;:22;:32;;;;;;75772:71;;;-1:-1:-1;;;;;75779:29:0;;;;;;:19;:29;;;;;;75772:71;75758:9;;:13;:86::i;:::-;:90;;:97::i;5520:79::-;5585:6;;-1:-1:-1;;;;;5585:6:0;5520:79;:::o;55882:669::-;55991:5;:12;55963:7;;55983:20;;55979:34;;-1:-1:-1;56012:1:0;56005:8;;55979:34;56022:17;;:::i;:::-;56042:5;56048:4;56042:11;;;;;;;;;;;;;;;;;56022:31;;;;;;;;56042:11;;;;;;;56022:31;;-1:-1:-1;;;;;56022:31:0;;;;;-1:-1:-1;;;56022:31:0;;;;;;;;;;;;;-1:-1:-1;;;56022:31:0;;;;;;;;;;;;;-1:-1:-1;;;56022:31:0;;;;;;;;-1:-1:-1;;;56022:31:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56060:27:0;;:::i;:::-;-1:-1:-1;56090:19:0;;;;:13;:19;;;;;;;;;56060:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56116:16;;:::i;:::-;-1:-1:-1;56135:11:0;;;;:5;:11;;;;;;;;-1:-1:-1;;;;;56135:18:0;;;;;;;;;;56116:37;;;;;;;;;;;;;;;-1:-1:-1;;;56116:37:0;;;;;;;;;;-1:-1:-1;;;;;;;;56116:37:0;;;;;;;;;;;-1:-1:-1;;;56116:37:0;;;;;;;;;;;;;;;;;;;56160:27;;:::i;:::-;-1:-1:-1;56190:20:0;;;;:14;:20;;;;;;;;-1:-1:-1;;;;;56190:27:0;;;;;;;;;;56160:57;;;;;;;;;;;;;;;;;;;;;56226:25;56245:5;56226:18;:25::i;:::-;;56258:35;56282:10;56258:23;:35::i;:::-;;56326:5;56332:4;56326:11;;;;;;;;;;;;;;;;;;;;;:27;-1:-1:-1;;;56326:27:0;;;;56302:21;;;:51;56360:44;56302:21;56393:10;56360:25;:44::i;:::-;;56411:20;56434:53;56455:4;56461:5;56468:6;56476:10;56434:20;:53::i;:::-;56411:76;;56511:33;56529:4;:14;;;56511:13;-1:-1:-1;;;;;56511:17:0;;;:33;;;;:::i;:::-;-1:-1:-1;;;;;56503:42:0;;55882:669;-1:-1:-1;;;;;;;;55882:669:0:o;75319:294::-;75454:4;75494:44;75512:9;75523:8;75533:4;75494:17;:44::i;:::-;75481:10;:57;:126;;;;75562:45;75580:9;75591:8;75601:5;75562:17;:45::i;:::-;75549:58;;;;75319:294;-1:-1:-1;;;75319:294:0:o;54586:320::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;54718:114:::1;54746:25;54718:114;;;;;;;;;;;;;;;;;:19;:114::i;:::-;54691:24;:141:::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;;54691:141:0::1;-1:-1:-1::0;;;;54691:141:0;;::::1;::::0;;;::::1;::::0;;54846:54:::1;::::0;;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;54586:320:::0;:::o;50954:54::-;;;;;;;;;;;;;:::o;54337:208::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;54430::::1;54450:12;54430:67;;;;;;;;;;;;;;;;::::0;:19:::1;:67::i;:::-;54416:11;:81:::0;;-1:-1:-1;;54416:81:0::1;-1:-1:-1::0;;;;;54416:81:0;;;::::1;::::0;;;::::1;::::0;;54511:28:::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;;;;::::1;54337:208:::0;:::o;43188:382::-;43289:23;;-1:-1:-1;;;;;43359:21:0;;43351:63;;;;;-1:-1:-1;;;43351:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;43444:13:0;;;;;;:4;:13;;;;;:41;;43473:11;43444:28;:41::i;:::-;-1:-1:-1;43530:4:0;43517:19;;;;:4;:19;;;;;43421:64;;-1:-1:-1;43517:47:0;;43552:11;43517:34;:47::i;:::-;43492:72;;;;;43188:382;;;;;:::o;59129:1264::-;23703:11;;;;23695:55;;;;;-1:-1:-1;;;23695:55:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;23695:55:0;;;;;;;;;;;;;;;23828:11;:19;;-1:-1:-1;;23828:19:0;;;59256:21:::1;59272:4:::0;59256:15:::1;:21::i;:::-;59284:34;:32;:34::i;:::-;59327:17;59347:5;59353:4;59347:11;;;;;;;;;::::0;;;::::1;::::0;;;59395:19;;;:13:::1;:19:::0;;;;;;59441:5:::1;:11:::0;;;;;59453:10:::1;59441:23:::0;;;;;;;;;59502:20;;;:14:::1;:20:::0;;;;;:32;;;;;;;59549:14:::1;::::0;::::1;::::0;59347:11:::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;59441:23:0;;59549:25;-1:-1:-1;59549:25:0::1;59541:71;;;;-1:-1:-1::0;;;59541:71:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59621:30;59635:4;59641:9;59621:13;:30::i;:::-;59658:43;59671:4;59677;59683:6;59691:9;59658:12;:43::i;:::-;59714:12:::0;;59710:134:::1;;59754:14;::::0;::::1;::::0;:27:::1;::::0;59773:7;59754:18:::1;:27::i;:::-;59737:14;::::0;::::1;:44:::0;59790:12;;:46:::1;::::0;-1:-1:-1;;;;;59790:12:0::1;59816:10;59828:7:::0;59790:25:::1;:46::i;:::-;59854:17:::0;;59850:140:::1;;59899:14:::0;;:32:::1;::::0;59918:12;59899:18:::1;:32::i;:::-;59882:49:::0;;59940:3:::1;::::0;:42:::1;::::0;-1:-1:-1;;;;;59940:3:0::1;59957:10;59969:12:::0;59940:16:::1;:42::i;:::-;60000:14:::0;;:19;59996:150:::1;;60067:14:::0;;60083::::1;::::0;::::1;::::0;60107:12;;60039:82:::1;::::0;60067:14;60083;-1:-1:-1;;;;;60107:12:0::1;60039:27;:82::i;:::-;60038:83;60030:108;;;::::0;;-1:-1:-1;;;60030:108:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60030:108:0;;;;;;;;;;;;;::::1;;60200:14;::::0;;::::1;::::0;60169:71:::1;::::0;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;60169:71:0;::::1;::::0;;::::1;-1:-1:-1::0;;;60169:71:0;::::1;::::0;::::1;;;;::::0;;::::1;::::0;;;;-1:-1:-1;;;60169:71:0;::::1;::::0;;::::1;::::0;;;;::::1;-1:-1:-1::0;;;60169:71:0;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;;60169:71:0;;::::1;::::0;::::1;::::0;;;;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;::::0;;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;;;:30:::1;:71::i;:::-;60152:88:::0;;-1:-1:-1;;;;;60152:88:0;;;::::1;-1:-1:-1::0;;;60152:88:0::1;-1:-1:-1::0;;;;;60152:88:0;;::::1;;::::0;;60252:49:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;60273:4;;60261:10:::1;::::0;60252:49:::1;::::0;;;;;;;;;::::1;60328:10;60314:25;::::0;;;:13:::1;:25;::::0;;;;;::::1;;60310:78;;;60350:30;60369:10;60350:18;:30::i;57231:223::-:0;-1:-1:-1;;;;;57329:35:0;;57302:4;57329:35;;;:16;:35;;;;;;57378:5;:12;:18;-1:-1:-1;57378:70:0;;;;;57439:8;-1:-1:-1;;;;;57400:48:0;57408:5;57414:3;57408:10;;;;;;;;;;;;;;;;;;;;;:18;-1:-1:-1;;;;;57408:18:0;57400:48;57378:70;57371:77;;;57231:223;;;;:::o;50061:19::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50061:19:0;;;-1:-1:-1;50061:19:0;-1:-1:-1;;;50061:19:0;;;;;-1:-1:-1;;;50061:19:0;;;;;;;-1:-1:-1;;;50061:19:0;;;;;-1:-1:-1;;;50061:19:0;;;;;:::o;61748:178::-;-1:-1:-1;;;;;61833:22:0;;61813:6;61833:22;;;:13;:22;;;;;;;;61828:54;;-1:-1:-1;61873:1:0;61866:8;;61828:54;61895:25;61912:7;61895:16;:25::i;50297:57::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;50297:57:0;;;;;;-1:-1:-1;;;;;;;;50297:57:0;;;;;-1:-1:-1;;;50297:57:0;;;;;:::o;51013:::-;;;;;;;;;;;;;:::o;50872:75::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;51164:543::-;1765:12;;;;;;;;:31;;;1781:15;:13;:15::i;:::-;1765:47;;;-1:-1:-1;1801:11:0;;;;1800:12;1765:47;1757:106;;;;-1:-1:-1;;;1757:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1872:19;1895:12;;;;;;1894:13;1914:83;;;;1943:12;:19;;-1:-1:-1;;;;1943:19:0;;;;;1971:18;1958:4;1971:18;;;1914:83;51362:16:::1;:14;:16::i;:::-;51385:34;:32;:34::i;:::-;51428:3;:10:::0;;-1:-1:-1;;;;;51428:10:0;;::::1;-1:-1:-1::0;;;;;;51428:10:0;;::::1;;::::0;;;51445:9:::1;:22:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;51487:65:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;51507:11;;51487:19:::1;:65::i;:::-;51474:10;;:78;;;;;;;;;;;;;;;;;;51586:80;51606:25;51586:80;;;;;;;;;;;;;;;;::::0;:19:::1;:80::i;:::-;51559:24;;:107;;;;;;;;;;;;;;;;;;51673:28;51688:12;51673:14;:28::i;:::-;2019:14:::0;2015:57;;;2059:5;2044:20;;-1:-1:-1;;2044:20:0;;;2015:57;51164:543;;;;;;:::o;49502:17::-;;;-1:-1:-1;;;;;49502:17:0;;:::o;50504:48::-;;;;;;;;;;;;;:::o;49905:25::-;;;-1:-1:-1;;;;;49905:25:0;;:::o;6465:244::-;5742:12;:10;:12::i;:::-;5732:6;;-1:-1:-1;;;;;5732:6:0;;;:22;;;5724:67;;;;;-1:-1:-1;;;5724:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;5724:67:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;6554:22:0;::::1;6546:73;;;;-1:-1:-1::0;;;6546:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6656:6;::::0;6635:38:::1;::::0;-1:-1:-1;;;;;6635:38:0;;::::1;::::0;6656:6:::1;::::0;6635:38:::1;::::0;6656:6:::1;::::0;6635:38:::1;6684:6;:17:::0;;-1:-1:-1;;;;;;6684:17:0::1;-1:-1:-1::0;;;;;6684:17:0;;;::::1;::::0;;;::::1;::::0;;6465:244::o;50160:51::-;;;;;;;;;;;;;:::o;75867:121::-;75939:5;:12;75933:18;;75925:57;;;;;-1:-1:-1;;;75925:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;76139:349;76236:9;76222:24;;;;:13;:24;;;;;;76207:12;:39;76199:66;;;;;-1:-1:-1;;;76199:66:0;;;;;;;;;;;;-1:-1:-1;;;76199:66:0;;;;;;;;;;;;;;;76286:9;76272:24;;;;:13;:24;;;;;76299:12;76272:39;;76324:10;:23;76320:163;;76395:10;76381:25;;;;:13;:25;;;;;;76366:12;:40;76358:68;;;;;-1:-1:-1;;;76358:68:0;;;;;;;;;;;;-1:-1:-1;;;76358:68:0;;;;;;;;;;;;;;;76449:10;76435:25;;;;:13;:25;;;;;76463:12;76435:40;;76320:163;76139:349::o;65088:1542::-;65175:17;;:::i;:::-;-1:-1:-1;65175:24:0;;;;;;;;;;-1:-1:-1;;;;;65175:24:0;;;;;-1:-1:-1;;;65175:24:0;;;;;;;;;;-1:-1:-1;;;65175:24:0;;;;;;;;;;;-1:-1:-1;;;65175:24:0;;;;;;;;-1:-1:-1;;;65175:24:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65318:25:0;65175:24;65318:18;:25::i;:::-;65356:21;;65298:45;;-1:-1:-1;65356:26:0;65352:871;;65393:27;;:::i;:::-;-1:-1:-1;65393:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65635:50;65649:35;65393:39;65649:23;:35::i;:::-;65635:9;;:13;:50::i;:::-;65694:33;;;:21;;;:33;65623:62;-1:-1:-1;65748:59:0;65762:44;65694:5;65795:10;65762:25;:44::i;65748:59::-;65736:71;;65853:15;65822:10;:28;;;:46;65818:131;;;65911:28;;;;65881:27;;;:58;65818:131;65991:14;65961:10;:27;;;:44;65957:127;;;66047:27;;;;66018:26;;;:56;65957:127;66125:14;66096:43;;:10;:26;;;:43;;;66092:124;;;66180:26;;;;66152:25;;;:54;;-1:-1:-1;;66152:54:0;;;;;;;;;;;66092:124;65352:871;;;;;66256:7;66235:5;:18;;;:28;66231:89;;;66294:18;;;;66274:17;;;:38;66231:89;66354:9;66330:33;;:5;:21;;;:33;;;66326:100;;;66397:21;;;;66374:44;;;;;;-1:-1:-1;;;66374:44:0;-1:-1:-1;;;;66374:44:0;;;;;;66326:100;66438:14;;66434:191;;66480:137;66509:60;66529:9;66509:60;;;;;;;;;;;;;;;;;:19;:60::i;:::-;66480:137;;;;;;;;;;;;;;;;;:14;;-1:-1:-1;;;66480:14:0;;-1:-1:-1;;;;;66480:14:0;;;:18;:137::i;:::-;66463:14;;:154;;;;;-1:-1:-1;;;;;66463:154:0;;;;;-1:-1:-1;;;;;66463:154:0;;;;;;65088:1542;;;;;;:::o;66636:1085::-;66796:17;;:::i;:::-;-1:-1:-1;66796:24:0;;;;;;;;;;;;;;;;-1:-1:-1;;;66796:24:0;;;;;;;-1:-1:-1;;;;;;;;66796:24:0;;;;;;;;;;;-1:-1:-1;;;66796:24:0;;;;;;;;;;;;;;;;;66827:28;;:::i;:::-;-1:-1:-1;66827:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66897:18;;;;66947:21;;67022:51;;;;;;;;;-1:-1:-1;;;;;67022:51:0;;;;;-1:-1:-1;;;67022:51:0;;;;;;;;;;-1:-1:-1;;;67022:51:0;;;;;;;-1:-1:-1;;;67022:51:0;;;;;;;;;;;;-1:-1:-1;;;67022:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66827:37;;66947:21;;-1:-1:-1;;;;67022:51:0;;66897:5;;66827:37;;67022:18;:51::i;:::-;66975:98;;;;67086:13;67103:1;67086:18;;:38;;;-1:-1:-1;67108:16:0;;;67086:38;67082:93;;;67152:15;;;;67135:32;;-1:-1:-1;;;;;67135:32:0;;;-1:-1:-1;;;67135:32:0;-1:-1:-1;;;;67135:32:0;;;;;;67082:93;67185:16;;67181:319;;67230:14;;-1:-1:-1;;;67230:14:0;;-1:-1:-1;;;;;67230:14:0;67216:28;;67212:71;;;-1:-1:-1;67268:14:0;;-1:-1:-1;;;67268:14:0;;-1:-1:-1;;;;;67268:14:0;67212:71;67309:137;67338:61;67358:11;67338:61;;;;;;;;;;;;;;;;;:19;:61::i;:::-;67309:137;;;;;;;;;;;;;;;;;:14;;-1:-1:-1;;;67309:14:0;;-1:-1:-1;;;;;67309:14:0;;;:18;:137::i;:::-;67292:14;;:154;;;;;-1:-1:-1;;;;;67292:154:0;;;;;-1:-1:-1;;;;;67292:154:0;;;;;;67455:37;67468:10;67480:11;67455:12;:37::i;:::-;67531:16;67510:37;;:5;:18;;;:37;;;67506:98;;;67578:18;;;;67558:38;;;;;;-1:-1:-1;;;67558:38:0;-1:-1:-1;;67558:38:0;;;;;;67506:98;67614:21;;:39;;;;;;;67610:106;;;67687:21;;67664:44;;-1:-1:-1;;67664:44:0;;;;;;;;67610:106;66636:1085;;;;;;;;;;:::o;18599:205::-;18727:68;;;-1:-1:-1;;;;;18727:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18727:68:0;-1:-1:-1;;;18727:68:0;;;18700:96;;18720:5;;18700:19;:96::i;:::-;18599:205;;;;:::o;7690:181::-;7748:7;7780:5;;;7804:6;;;;7796:46;;;;;-1:-1:-1;;;7796:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;74511:586;74692:16;74729:51;74751:9;74762:4;:17;;;74729:21;:51::i;:::-;74717:63;;74791:9;:22;;;74817:1;74791:27;:57;;;-1:-1:-1;74822:21:0;;:26;74791:57;:80;;;-1:-1:-1;74852:14:0;;:19;74791:80;74787:119;;;74882:16;;74787:119;74926:165;75022:60;75044:9;75055;:26;;;75022:21;:60::i;:::-;74926:81;74940:66;74962:6;:14;;;74978:9;:27;;;74940:21;:66::i;:::-;-1:-1:-1;;;;;74926:13:0;;;;:81::i;:::-;-1:-1:-1;;;;;74926:85:0;;;:165::i;62862:2041::-;62938:5;:12;62921:14;;;;63049:1400;63077:6;63071:3;:12;63049:1400;;;63135:10;;;;:5;:10;;;;;;;;-1:-1:-1;;;;;63135:17:0;;;;;;;;;:27;63117:46;;-1:-1:-1;;;;;63117:17:0;;;;-1:-1:-1;;;63135:27:0;;;63117:17;:46::i;:::-;63101:62;;63174:17;63194:5;63200:3;63194:10;;;;;;;;;;;;;;;;;;;;;;;63260:12;;-1:-1:-1;;;;;63260:12:0;;;63306:26;;;:17;:26;;;;;;;63194:10;;-1:-1:-1;63306:26:0;63345:27;63341:598;;63413:3;;:22;;;-1:-1:-1;;;63413:22:0;;-1:-1:-1;;;;;63413:22:0;;;;;;;;;63393:78;;63413:3;;;;;:13;;:22;;;;;;;;;;;;;;;:3;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63413:22:0;63393:78;;;;;;;;;;;;;63413:22;63393:78;;;:19;:78::i;:::-;63385:86;-1:-1:-1;63495:21:0;-1:-1:-1;;;;;63495:14:0;;63385:86;63495:14;:21::i;:::-;63482:34;;63341:598;;;63543:23;63576:13;-1:-1:-1;;;;;63569:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63569:35:0;63637:40;;;-1:-1:-1;;;63637:40:0;;-1:-1:-1;;;;;63637:40:0;;;;;;;;;63569:35;;-1:-1:-1;63615:19:0;;63637:31;;;;;;:40;;;;;63569:35;;63637:40;;;;;;;;:31;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63637:40:0;;-1:-1:-1;63688:15:0;63706:52;63742:15;63706:31;63637:40;49471:4;63706:24;:31::i;:52::-;63791:3;;:28;;;-1:-1:-1;;;63791:28:0;;-1:-1:-1;;;;;63791:28:0;;;;;;;;;63688:70;;-1:-1:-1;63769:19:0;;63791:3;;;;;:13;;:28;;;;;;;;;;;;;;:3;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63791:28:0;;-1:-1:-1;63838:91:0;63858:35;49471:4;63858:24;63791:28;63874:7;63858:15;:24::i;:35::-;63838:91;;;;;;;;;;;;;;;;;:19;:91::i;:::-;63830:99;;63341:598;;;;;63954:17;;-1:-1:-1;;;63954:17:0;;;;63949:53;;63984:8;;;;;;63949:53;64037:12;;:26;;;-1:-1:-1;;;64037:26:0;;;;64012:22;;-1:-1:-1;;;;;64037:12:0;;:24;;:26;;;;;;;;;;;;;;:12;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64012:51;;64072:17;64092:5;:10;64098:3;64092:10;;;;;;;;;;;:17;64103:5;-1:-1:-1;;;;;64092:17:0;-1:-1:-1;;;;;64092:17:0;;;;;;;;;;;;:27;;;64072:47;;64132:9;64145:1;64132:14;;:37;;;;-1:-1:-1;64150:19:0;;;64132:37;64128:314;;;64182:17;64202:45;64232:14;64202:25;-1:-1:-1;;;;;64202:14:0;;49471:4;64202:18;:25::i;:45::-;64182:65;-1:-1:-1;64258:17:0;64278:35;49471:4;64278:24;:9;64182:65;64278:13;:24::i;:35::-;64258:55;-1:-1:-1;64341:29:0;:14;64258:55;64341:18;:29::i;:::-;64324:46;;64417:3;64410:5;-1:-1:-1;;;;;64388:44:0;;64422:9;64388:44;;;;;;;;;;;;;;;;;;64128:314;;;63049:1400;;;;;;;63085:5;;63049:1400;;;-1:-1:-1;64457:21:0;64489:19;;;:38;;-1:-1:-1;;;;;;64512:15:0;;;64489:38;64488:162;;64553:97;64573:41;-1:-1:-1;;;;;64573:41:0;;:25;:14;49471:4;64573:18;:25::i;:41::-;64553:97;;;;;;;;;;;;;;;;;:19;:97::i;:::-;64488:162;;;64540:1;64488:162;64664:34;;;-1:-1:-1;;;;;64664:34:0;;;;;;64457:193;;-1:-1:-1;64664:34:0;;;;;;;;;;64710:66;;;-1:-1:-1;;;;;64737:22:0;;;64710:66;;;;;;;;;;-1:-1:-1;;;;;64710:66:0;;;;;;;;;;;64785:63;64800:5;64807:40;64817:13;64832:14;64807:9;:40::i;:::-;64785:14;:63::i;:::-;64855:42;64872:24;64882:10;64894:1;64872:9;:24::i;:::-;64855:16;:42::i;3796:106::-;3884:10;3796:106;:::o;71279:359::-;71349:21;71440:192;71463:5;:21;;;71440:192;;71493:5;:18;;;71520:5;:13;;;71542:83;71609:15;;71542:62;71586:5;:16;;;71578:25;;71542:31;71560:11;;;;;;;;;-1:-1:-1;;;;;71560:11:0;-1:-1:-1;;;;;71552:20:0;49471:4;71542:9;;:31;;;;:::i;:::-;:35;;:62::i;:83::-;71440:14;:192::i;:::-;71379:253;;71415:21;;;71379:253;71395:18;;;;71379:253;;;;-1:-1:-1;71379:253:0;71279:359::o;72020:334::-;72105:21;72211:137;72234:10;:26;;;72211:137;;72269:10;:28;;;72306:3;;;;;;;;;-1:-1:-1;;;;;72306:3:0;72318:10;:23;;;72211:14;:137::i;:::-;72135:213;;72181:26;;;72135:213;72151:28;;;;72135:213;;;;-1:-1:-1;72135:213:0;72020:334::o;71644:370::-;71765:21;71868:140;71891:5;:21;;;71868:140;;71921:10;:27;;;71957:5;:13;;;71979:10;:22;;;71868:14;:140::i;:::-;71798:210;;71843:21;;;;71798:210;;;;71814:27;;;;71798:210;;;;;71644:370;-1:-1:-1;71644:370:0:o;68357:2916::-;68599:21;;68529;;;;68651:12;:10;:12::i;:::-;68627:36;;;;;;;68674:34;;;;68670:70;;68727:1;68730;68719:13;;;;;;;68670:70;68761:21;;:33;;;69107:54;68761:5;69135:4;69141:7;69150:10;69107:20;:54::i;:::-;-1:-1:-1;;;;;69099:63:0;;-1:-1:-1;69169:17:0;69196:18;;:103;;69272:24;;69222:76;;69272:24;-1:-1:-1;;;69272:24:0;;;;;69266:30;;69258:39;;;69222:31;;:13;;69240:12;;;;69222:17;:31;:::i;:76::-;69196:103;;;69217:1;69196:103;69169:130;;69641:14;69666:5;:15;;;-1:-1:-1;;;;;69658:24:0;69641:41;;69720:5;:18;;;69695:43;;:5;:21;;;:43;;;;:106;;69768:21;;:33;;;69695:106;;;69741:24;;-1:-1:-1;;;69741:24:0;;;;69695:106;69689:112;-1:-1:-1;69808:20:0;69838:11;;:198;;69894:24;;;-1:-1:-1;;;69894:24:0;;;;;69887:31;;;;;:138;;69956:69;70014:9;69993:5;:18;;;:30;69985:39;;69956:24;69975:3;69967:12;;69956:6;:10;;:24;;;;:::i;:69::-;69887:138;;;69934:6;69887:138;69838:198;;;69861:1;69838:198;69808:228;-1:-1:-1;70059:27:0;69808:228;70076:9;70059:16;:27::i;:::-;70045:41;;70111:133;70139:60;70187:11;70139:43;70168:13;70147:5;:15;;;-1:-1:-1;;;;;70139:24:0;:28;;:43;;;;:::i;:::-;:47;;:60::i;:::-;70111:133;;;;;;;;;;;;;;;;;:19;:133::i;:::-;-1:-1:-1;;;;;70093:151:0;:15;;;:151;70319:23;70345:11;;:42;;70363:24;:6;70374:12;70363:10;:24::i;:::-;70345:42;;;70359:1;70345:42;70319:68;-1:-1:-1;70394:23:0;70420:18;;:53;;70445:28;:13;70463:9;70445:17;:28::i;:::-;70420:53;;;70441:1;70420:53;70394:79;-1:-1:-1;70480:15:0;70498:36;:15;70394:79;70498:19;:36::i;:::-;70480:54;-1:-1:-1;70624:14:0;70653:20;;;:36;;-1:-1:-1;70677:12:0;;70653:36;70649:422;;;-1:-1:-1;70769:24:0;;-1:-1:-1;;;70769:24:0;;;;70649:422;;;70932:5;:21;;;70911:5;:18;;;:42;70905:48;;70971:92;71055:7;70972:77;71003:45;71023:24;;;;;;;;;;;71003:45;;:15;:19;;:45;;;;:::i;:::-;70973:24;:15;:24;;;;;:19;:24;:::i;70971:92::-;70962:101;;70649:422;71137:24;;:41;;;;-1:-1:-1;;;71137:24:0;;;;:41;:85;;71198:24;;-1:-1:-1;;;71198:24:0;;;;71137:85;;;71188:6;71137:85;71105:5;:21;;;:118;71077:5;:18;;:146;;;;;;;;;;;71232:35;;;;;;;;;68357:2916;;;;;;;;:::o;43576:191::-;-1:-1:-1;;;;;43720:13:0;;43661:16;43720:13;;;:4;:13;;;;;43661:16;;43720:41;;;;;;;:27;:41;:::i;:::-;43700:61;;;;-1:-1:-1;43576:191:0;-1:-1:-1;;;43576:191:0:o;46362:160::-;-1:-1:-1;;;;;46484:2:0;46476:10;;;;;;46496:18;;;46362:160::o;18414:177::-;18524:58;;;-1:-1:-1;;;;;18524:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18524:58:0;-1:-1:-1;;;18524:58:0;;;18497:86;;18517:5;;18497:19;:86::i;:::-;18414:177;;;:::o;30226:135::-;30282:6;30308:45;30312:1;30315;30308:45;;;;;;;;;;;;;;;;;:3;:45::i;45341:307::-;-1:-1:-1;;;;;45441:15:0;;;45415:23;45441:15;;;:4;:15;;;;;;:25;;45473:38;;;-1:-1:-1;;;45473:38:0;;;-1:-1:-1;;;;;;45473:38:0;;;;;;45525:55;;45441:25;;;;;;;45473:38;;45441:25;;:15;;45525:55;;45415:23;45525:55;45589:53;45603:9;45614:15;45631:10;45589:13;:53::i;42444:595::-;-1:-1:-1;;;;;42670:13:0;;42606:6;42670:13;;;:4;:13;;;;;42606:6;;;;42670:57;;42697:11;42670:57;;;;;:26;:57;:::i;:::-;42621:106;;;;42738:8;-1:-1:-1;;;;;42738:13:0;42750:1;42738:13;42734:27;;;42760:1;42753:8;;;;;;42734:27;42808:4;42771:18;42795:19;;;:4;:19;;;;;:65;;42828:11;42795:65;;;;;:32;:65;:::i;:::-;-1:-1:-1;42915:4:0;42868:28;42902:19;;;:4;:19;;;;;42770:90;;-1:-1:-1;42868:28:0;42902:56;;;;;;;42868:28;;42902:32;:56;:::i;:::-;42867:91;;;42972:61;42990:8;43000:10;43012:20;42972:17;:61::i;:::-;42965:68;42444:595;-1:-1:-1;;;;;;;;;42444:595:0:o;75994:139::-;76038:6;76060:67;76080:12;76060:67;;;;;;;;;;;;;;;;;:19;:67::i;:::-;76053:74;;75994:139;:::o;31615:163::-;31692:6;31730:12;-1:-1:-1;;;31719:9:0;;31711:32;;;;-1:-1:-1;;;31711:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31768:1:0;;31615:163;-1:-1:-1;;31615:163:0:o;41584:155::-;41669:6;41691:42;41706:7;41715:11;41728:1;41731;41691:14;:42::i;8146:136::-;8204:7;8231:43;8235:1;8238;8231:43;;;;;;;;;;;;;;;;;:3;:43::i;9020:471::-;9078:7;9323:6;9319:47;;-1:-1:-1;9353:1:0;9346:8;;9319:47;9390:5;;;9394:1;9390;:5;:1;9414:5;;;;;:10;9406:56;;;;-1:-1:-1;;;9406:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9959:132;10017:7;10044:39;10048:1;10051;10044:39;;;;;;;;;;;;;;;;;:3;:39::i;74089:416::-;74259:16;74288:4;:14;;;74306:1;74288:19;74284:50;;;-1:-1:-1;74325:1:0;74318:8;;74284:50;74354:145;74440:4;:14;;;74354:145;;;;;;;;;;;;;;;;;:71;74385:4;:14;;;74401:4;74407:6;74415:9;74354:30;:71::i;:::-;-1:-1:-1;;;;;74354:75:0;;:145;:75;:145::i;29915:132::-;29971:6;29997:42;30001:1;30004;29997:42;;;;;;;;;;;;;;;;;:3;:42::i;30568:163::-;30645:6;30683:12;-1:-1:-1;;;30672:9:0;;30664:32;;;;-1:-1:-1;;;30664:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35749:322;35842:9;35853:12;35883:15;35901:31;35920:11;35901:18;:31::i;:::-;35967:21;;35883:49;;-1:-1:-1;35967:21:0;;36014:49;35967:6;:21;35883:49;36014:15;:49::i;:::-;36001:62;;;;-1:-1:-1;35749:322:0;-1:-1:-1;;;;;35749:322:0:o;40739:441::-;-1:-1:-1;;;;;40869:13:0;;40805:6;40869:13;;;:4;:13;;;;;40805:6;;;;40869:29;;:27;:29::i;:::-;40820:78;;;;40909:8;-1:-1:-1;;;;;40909:13:0;40921:1;40909:13;40905:27;;;40931:1;40924:8;;;;;;40905:27;40979:4;40942:18;40966:19;;;:4;:19;;;;;:35;;:33;:35::i;:::-;-1:-1:-1;41056:4:0;41009:28;41043:19;;;:4;:19;;;;;40941:60;;-1:-1:-1;41009:28:0;41043:56;;;;;;;41009:28;;41043:32;:56;:::i;:::-;41008:91;;;41113:61;41131:8;41141:10;41153:20;41113:17;:61::i;:::-;41106:68;40739:441;-1:-1:-1;;;;;;40739:441:0:o;2166:508::-;2583:4;2629:17;2661:7;2166:508;:::o;5098:129::-;1765:12;;;;;;;;:31;;;1781:15;:13;:15::i;:::-;1765:47;;;-1:-1:-1;1801:11:0;;;;1800:12;1765:47;1757:106;;;;-1:-1:-1;;;1757:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1872:19;1895:12;;;;;;1894:13;1914:83;;;;1943:12;:19;;-1:-1:-1;;;;1943:19:0;;;;;1971:18;1958:4;1971:18;;;1914:83;5156:26:::1;:24;:26::i;:::-;5193;:24;:26::i;:::-;2019:14:::0;2015:57;;;2059:5;2044:20;;-1:-1:-1;;2044:20:0;;;5098:129;:::o;22676:526::-;1765:12;;;;;;;;:31;;;1781:15;:13;:15::i;:::-;1765:47;;;-1:-1:-1;1801:11:0;;;;1800:12;1765:47;1757:106;;;;-1:-1:-1;;;1757:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1872:19;1895:12;;;;;;1894:13;1914:83;;;;1943:12;:19;;-1:-1:-1;;;;1943:19:0;;;;;1971:18;1958:4;1971:18;;;1914:83;23174:11:::1;:18:::0;;-1:-1:-1;;23174:18:0::1;23188:4;23174:18;::::0;;2015:57;;;;2059:5;2044:20;;-1:-1:-1;;2044:20:0;;;22676:526;:::o;29721:186::-;29805:6;29835:5;;;29867:12;-1:-1:-1;;;;;29859:6:0;;;;;;;;29851:29;;;;-1:-1:-1;;;29851:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29898:1:0;29721:186;-1:-1:-1;;;;29721:186:0:o;30055:163::-;30139:6;30171:1;-1:-1:-1;;;;;30166:6:0;:1;-1:-1:-1;;;;;30166:6:0;;;30174:12;30158:29;;;;;-1:-1:-1;;;30158:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30205:5:0;;;30055:163::o;64909:130::-;65004:3;;65009:9;;64977:56;;-1:-1:-1;;;;;65004:3:0;;;;65009:9;65020:3;65025:7;64977:26;:56::i;20458:1115::-;21063:27;21071:5;-1:-1:-1;;;;;21063:25:0;;:27::i;:::-;21055:71;;;;;-1:-1:-1;;;21055:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;21200:12;21214:23;21249:5;-1:-1:-1;;;;;21241:19:0;21261:4;21241:25;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;21241:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21199:67;;;;21285:7;21277:52;;;;;-1:-1:-1;;;21277:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21346:17;;:21;21342:224;;21488:10;21477:30;;;;;;;;;;;;;;;-1:-1:-1;21477:30:0;21469:85;;;;-1:-1:-1;;;21469:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75103:210;75197:6;75219:88;75239:38;49471:4;75239:27;:9;75253:12;75239:13;:27::i;:38::-;75219:88;;;;;;;;;;;;;;;;;:19;:88::i;46528:149::-;-1:-1:-1;;;;;46657:13:0;46651:2;46634:19;;;;-1:-1:-1;;;46634:19:0;46633:37;;46528:149::o;43882:525::-;-1:-1:-1;;;;;43997:13:0;;;43953:41;43997:13;;;:4;:13;;;;;44038;;43997;;-1:-1:-1;;;44038:13:0;;;;;44102:24;;:49;;-1:-1:-1;;;;;44135:16:0;;;;;;:4;:16;;;;;44102:49;;;44129:3;44102:49;44058:93;;44161:18;44185:19;:3;:17;:19::i;:::-;-1:-1:-1;;;;;;44337:21:0;;;;;;:12;:21;;;;;;44160:44;;-1:-1:-1;44211:155:0;;44302:57;;44160:44;;44331:4;;-1:-1:-1;;;;;44337:21:0;44302:16;:57::i;:::-;44211:3;;:19;:155::i;:::-;-1:-1:-1;;;;;;;;;44373:21:0;;;;;;;;:12;:21;;;;;:28;;-1:-1:-1;;;;;;44373:28:0;-1:-1:-1;;;;;44373:28:0;;;;;;;;;;-1:-1:-1;43882:525:0:o;43773:103::-;43842:4;43829:19;;;;:4;:19;;;;;:41;;43865:4;43829:35;:41::i;72360:770::-;72540:21;72661:12;72540:21;72703:12;:10;:12::i;:::-;72682:33;;72747:16;72726:18;:37;;;72722:403;;;72891:31;;;-1:-1:-1;;;72891:31:0;;72916:4;72891:31;;;;;;72803:37;;;;;;;72774:18;;-1:-1:-1;;;;;72891:16:0;;;;;:31;;;;;;;;;;;;;;:16;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72891:31:0;;-1:-1:-1;72935:15:0;;72931:187;;72979:39;49471:4;72979:28;:10;72994:12;72979:14;:28::i;:39::-;72963:55;-1:-1:-1;73048:60:0;73067:40;73096:10;73067:24;72963:55;49471:4;73067:17;:24::i;:40::-;73048:14;;:18;:60::i;:::-;73031:77;;72931:187;72722:403;;;72360:770;;;;;;;;:::o;32683:295::-;32776:16;;32831:17;;;:57;;-1:-1:-1;32867:21:0;;;;32852:36;;32831:57;:139;;32926:44;32941:6;32956:12;32926:14;:44::i;:::-;32831:139;;;32905:1;32908;32831:139;32824:146;;;;32683:295;;;;;:::o;44413:922::-;44515:41;;-1:-1:-1;;;;;44617:18:0;;44613:293;;-1:-1:-1;;;;;;;44682:13:0;;;;;;;:4;:13;;;;;;44710:8;;;;;;;44613:293;;;-1:-1:-1;;;;;44736:16:0;;44732:174;;-1:-1:-1;;;;;;;44798:10:0;;;;;;;:4;:10;;;;;;44823:13;;;;;;;44732:174;;;-1:-1:-1;;;;;;;44865:10:0;;;;;;;:4;:10;;;;;;44890:8;;;;;;;44732:174;-1:-1:-1;;;;;44934:21:0;;44912:19;44934:21;;;:12;:21;;;;;;-1:-1:-1;;;;;44934:21:0;;44990:19;:3;:17;:19::i;:::-;44964:45;;;45016:15;45034:45;45051:11;45064:1;45067:11;45034:16;:45::i;:::-;45016:63;;45105:7;-1:-1:-1;;;;;45090:22:0;:11;-1:-1:-1;;;;;45090:22:0;;45086:56;;45114:28;:3;45134:7;45114:19;:28::i;:::-;;45086:56;45152:19;45177;:3;:17;:19::i;:::-;45151:45;;;45203:15;45221:45;45238:11;45251;45264:1;45221:16;:45::i;:::-;45203:63;;45292:7;-1:-1:-1;;;;;45277:22:0;:11;-1:-1:-1;;;;;45277:22:0;;45273:56;;45301:28;:3;45321:7;45301:19;:28::i;:::-;;44413:922;;;;;;;;;;:::o;34091:1292::-;34201:7;34210:6;34234:15;34252:31;34271:11;34252:18;:31::i;:::-;34234:49;;34294:21;;:::i;:::-;-1:-1:-1;34294:30:0;;;;;;;;;;;;;;;;-1:-1:-1;;;34294:30:0;;;;;;;-1:-1:-1;;;34294:30:0;;-1:-1:-1;;;;;34294:30:0;;;;;;;;34335:20;;:::i;:::-;34434:17;;34430:719;;34492:22;;34476:38;;;;;34468:82;;;;;-1:-1:-1;;;34468:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34621:24:0;;;;34565:11;34621:24;;;:18;;;:24;;;;;;;;;34616:29;;;;;;;;;;;;;;;-1:-1:-1;;;34616:29:0;;;-1:-1:-1;;;;;34616:29:0;;;;;;;;;;34621:24;;34664;;;;34660:478;;;-1:-1:-1;34717:7:0;;;;34726:12;;34717:7;;-1:-1:-1;34726:12:0;-1:-1:-1;34709:30:0;;-1:-1:-1;;34709:30:0;34660:478;34430:719;;35213:19;35234:12;35250:57;35266:6;35274:7;:22;;;35298:8;35250:15;:57::i;:::-;35332:32;;;;;;;;:18;;;:32;;;;;:42;35212:95;;-1:-1:-1;35332:42:0;;-1:-1:-1;;;;;;34091:1292:0;;;;;;;:::o;73136:947::-;73283:12;73305:13;73320:21;73345;73357:8;73345:11;:21::i;:::-;73304:62;;;;73374:28;73408:23;73420:10;73408:11;:23::i;:::-;73373:58;;;73439:31;73476:33;73488:20;73476:11;:33::i;:::-;-1:-1:-1;73438:71:0;-1:-1:-1;;;;;;73522:19:0;;73518:560;;73560:6;73552:14;;73518:560;;;73589:17;73609:61;49471:4;73609:50;-1:-1:-1;;;;;73609:23:0;;;;:50;;:27;:50::i;:61::-;73589:81;;73708:24;-1:-1:-1;;;;;73683:49:0;:21;-1:-1:-1;;;;;73683:49:0;;73679:305;;73745:25;73773:80;-1:-1:-1;;;;;73819:33:0;;;;73773:41;;:30;;49471:4;73773:34;:41::i;:80::-;73745:108;;49471:4;73868:17;:25;73864:111;;;73920:43;73945:17;73920:20;:9;49471:4;73920:13;:20::i;:43::-;73908:55;;73864:111;73679:305;;74000:70;74011:58;74031:9;74011:58;;;;;;;;;;;;;;;;;:19;:58::i;:::-;-1:-1:-1;;;;;74000:10:0;;;;:70::i;:::-;73992:78;;73518:560;;73136:947;;;;;;;;;:::o;8577:192::-;8663:7;8699:12;8691:6;;;;8683:29;;;;-1:-1:-1;;;8683:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10579:345;10665:7;10767:12;10760:5;10752:28;;;;-1:-1:-1;;;10752:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10791:9;10807:1;10803;:5;;;;;;;10579:345;-1:-1:-1;;;;;10579:345:0:o;37708:210::-;37779:6;37820:12;37806:11;:26;37798:68;;;;;-1:-1:-1;;;37798:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;37884:26;37898:11;37884:13;:26::i;37926:1085::-;38041:6;38049:7;38074:20;;:::i;:::-;38149:19;;;38145:65;;38193:1;38196;38185:13;;;;;;;38145:65;-1:-1:-1;38225:34:0;;;;;;;;:18;;;:34;;;;;;;;;38220:39;;;;;;;;;;;;;;;-1:-1:-1;;;38220:39:0;;;-1:-1:-1;;;;;38220:39:0;;;;;;;;;;38274:24;;-1:-1:-1;38270:89:0;;38339:7;;;38323:14;;-1:-1:-1;38339:7:0;-1:-1:-1;38315:32:0;;38270:89;38373:18;:21;;;;:18;;;:21;;;;;:31;:42;;;;:31;;:42;38369:88;;;38440:1;38443;38432:13;;;;;;;38369:88;38484:1;38511:14;38536:411;38551:5;38543:13;;:5;:13;;;38536:411;;;38573:13;38615:1;38597:19;38598:13;;;38597:19;;38589:27;;38663:26;;;;;;;;:18;;;:26;;;;;;;;;38658:31;;;;;;;;;;;;;;;-1:-1:-1;;;38658:31:0;;;-1:-1:-1;;;;;38658:31:0;;;;;;;;;;-1:-1:-1;38589:27:0;;-1:-1:-1;38708:24:0;;;38704:232;;;38761:6;38769:2;:7;;;38753:24;;;;;;;;;;38704:232;38803:12;;:23;;;;;;;38799:137;;;38855:6;38847:14;;38799:137;;;38919:1;38910:6;:10;38902:18;;38799:137;38536:411;;;;-1:-1:-1;38972:25:0;;;;;;;:18;;;:25;;;;;:30;38965:5;;-1:-1:-1;;;;;;;;;38972:30:0;;;;;-1:-1:-1;;37926:1085:0;;;;;;:::o;33335:323::-;33409:7;33418:6;33442:21;;:::i;:::-;-1:-1:-1;33442:30:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;33442:30:0;;;;;;;;;-1:-1:-1;;;33442:30:0;;;-1:-1:-1;;;;;33442:30:0;;;;;;;;;33490:27;:160;;33567:22;;33548:42;;;;;;;;:18;;;:42;;;;;;:47;33616:22;;33597:42;;;;;;:52;-1:-1:-1;;;33548:47:0;;;-1:-1:-1;;;;;33548:47:0;;33597:52;33490:160;;;33530:1;33533;33490:160;33483:167;;;;;33335:323;;;:::o;3717:69::-;1765:12;;;;;;;;:31;;;1781:15;:13;:15::i;:::-;1765:47;;;-1:-1:-1;1801:11:0;;;;1800:12;1765:47;1757:106;;;;-1:-1:-1;;;1757:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1872:19;1895:12;;;;;;1894:13;1914:83;;;;1943:12;:19;;-1:-1:-1;;;;1943:19:0;;;;;1971:18;1958:4;1971:18;;;2019:14;2015:57;;;2059:5;2044:20;;-1:-1:-1;;2044:20:0;;;3717:69;:::o;5235:202::-;1765:12;;;;;;;;:31;;;1781:15;:13;:15::i;:::-;1765:47;;;-1:-1:-1;1801:11:0;;;;1800:12;1765:47;1757:106;;;;-1:-1:-1;;;1757:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1872:19;1895:12;;;;;;1894:13;1914:83;;;;1943:12;:19;;-1:-1:-1;;;;1943:19:0;;;;;1971:18;1958:4;1971:18;;;1914:83;5307:17:::1;5327:12;:10;:12::i;:::-;5350:6;:18:::0;;-1:-1:-1;;;;;;5350:18:0::1;-1:-1:-1::0;;;;;5350:18:0;::::1;::::0;;::::1;::::0;;;5384:43:::1;::::0;5350:18;;-1:-1:-1;5350:18:0;-1:-1:-1;;5384:43:0::1;::::0;-1:-1:-1;;5384:43:0::1;2005:1;2019:14:::0;2015:57;;;2059:5;2044:20;;-1:-1:-1;;2044:20:0;;;5235:202;:::o;15776:619::-;15836:4;16304:20;;16147:66;16344:23;;;;;;:42;;-1:-1:-1;;16371:15:0;;;16336:51;-1:-1:-1;;15776:619:0:o;45820:536::-;45960:16;45986:12;46000;46016:21;46028:8;46016:11;:21::i;:::-;45985:52;;;;46045:20;46067;46091:25;46103:12;46091:11;:25::i;:::-;46044:72;;;;46124:21;46147;46172:26;46184:13;46172:11;:26::i;:::-;46123:75;;;;46216:134;46234:50;46247:5;46254:13;46269:14;46234:12;:50::i;:::-;46293;46306:5;46313:13;46328:14;46293:12;:50::i;:::-;46216:9;:134::i;:::-;46205:145;45820:536;-1:-1:-1;;;;;;;;;;45820:536:0:o;36196:827::-;36281:9;36308:15;36326:27;36340:12;36326:13;:27::i;:::-;36308:45;;36364:21;;:::i;:::-;-1:-1:-1;36364:30:0;;;;;;;;;;;;;;;;;-1:-1:-1;;;36364:30:0;;;;;;;;;-1:-1:-1;;;36364:30:0;;;-1:-1:-1;;;;;36364:30:0;;;;;;;;;-1:-1:-1;;36425:80:0;;36504:1;36425:80;;;36473:22;;36454:42;;;;;;:18;;;:42;;;;;:47;-1:-1:-1;;;36454:47:0;;-1:-1:-1;;;;;36454:47:0;36425:80;36407:98;;36516:14;36541:7;-1:-1:-1;;;;;36533:15:0;:4;-1:-1:-1;;;;;36533:15:0;;;36516:32;;36596:8;36565:39;;:7;:27;;;:39;;;36561:294;;-1:-1:-1;36646:22:0;;36671:1;36646:26;;;36621:51;;;;;;;36714:46;;-1:-1:-1;;36714:46:0;;-1:-1:-1;;36775:37:0;-1:-1:-1;;;36775:37:0;;;;;;;;;;36561:294;36869:9;36865:113;;;36940:26;;;;;;;;;;;;;;-1:-1:-1;;;;;36940:26:0;;;;;;;;;;36914:22;;36895:42;;-1:-1:-1;36895:42:0;;;:18;;;:42;;;;;;;:71;;;;;;-1:-1:-1;;36895:71:0;;;;;;;;;-1:-1:-1;;;;;;36895:71:0;-1:-1:-1;;;36895:71:0;;;;;;;;;;;;;;36865:113;-1:-1:-1;;36993:22:0;;36196:827;-1:-1:-1;;;;36196:827:0:o;32986:242::-;33138:32;;;;33082:16;33138:32;;;:18;;;;;:32;;;;;;:42;;;;;-1:-1:-1;;;33182:37:0;;;-1:-1:-1;;;;;33182:37:0;;32986:242::o;37511:189::-;37577:6;-1:-1:-1;;;37604:11:0;:19;37596:59;;;;;-1:-1:-1;;;37596:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37680:11:0;37511:189::o;46683:368::-;46794:13;46828:4;-1:-1:-1;;;;;46820:12:0;:4;-1:-1:-1;;;;;46820:12:0;;46816:230;;;-1:-1:-1;46852:3:0;46816:230;;;46880:4;-1:-1:-1;;;;;46873:11:0;:4;-1:-1:-1;;;;;46873:11:0;;46869:177;;;46904:23;46912:14;-1:-1:-1;;;;;46912:8:0;;46921:4;46912:8;:14::i;:::-;-1:-1:-1;;;;;46904:7:0;;;;:23::i;:::-;46895:32;;46869:177;;;46950:15;46968:14;-1:-1:-1;;;;;46968:8:0;;46977:4;46968:8;:14::i;:::-;46950:32;;47006:8;-1:-1:-1;;;;;47000:14:0;:3;-1:-1:-1;;;;;47000:14:0;;:38;;47037:1;47000:38;;;47017:17;-1:-1:-1;;;;;47017:7:0;;47025:8;47017:7;:17::i;:::-;46991:47;46683:368;-1:-1:-1;;;;;46683:368:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://8f4a4eae85ea3a2943c1b14fbff5f401925e82e4cf561d40d50739e732893461

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

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.