ETH Price: $2,555.03 (+4.79%)

Contract

0x987c2661d7f6928538Aa1BF66D48d48539E6c13F
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Executor Swap To...128666962021-07-21 0:49:281157 days ago1626828568IN
0x987c2661...539E6c13F
0 ETH0.0017487514.11444389
Executor Swap To...127274662021-06-29 6:48:551179 days ago1624949335IN
0x987c2661...539E6c13F
0 ETH0.003137037.14021606
Executor Swap To...127260922021-06-29 1:39:461179 days ago1624930786IN
0x987c2661...539E6c13F
0 ETH0.000927396.79292091
Executor Swap To...127258312021-06-29 0:38:261179 days ago1624927106IN
0x987c2661...539E6c13F
0 ETH0.004082518.33584182
Executor Swap To...127247012021-06-28 20:36:301179 days ago1624912590IN
0x987c2661...539E6c13F
0 ETH0.0026111821.08205553
Executor Swap To...126011672021-06-09 15:42:191198 days ago1623253339IN
0x987c2661...539E6c13F
0 ETH0.0063432151.45
Executor Swap To...125599662021-06-03 6:37:051205 days ago1622702225IN
0x987c2661...539E6c13F
0 ETH0.0100928681.423
Executor Swap To...125553662021-06-02 13:30:081205 days ago1622640608IN
0x987c2661...539E6c13F
0 ETH0.0057913446.721
Executor Swap To...125405002021-05-31 6:23:401208 days ago1622442220IN
0x987c2661...539E6c13F
0 ETH0.0021575517.5
Executor Swap To...125338052021-05-30 5:17:481209 days ago1622351868IN
0x987c2661...539E6c13F
0 ETH0.0034520928
Executor Swap To...125328502021-05-30 1:42:431209 days ago1622338963IN
0x987c2661...539E6c13F
0 ETH0.009642320
Executor Swap To...125279642021-05-29 7:43:041209 days ago1622274184IN
0x987c2661...539E6c13F
0 ETH0.0132410127
Executor Swap To...125106952021-05-26 15:12:571212 days ago1622041977IN
0x987c2661...539E6c13F
0 ETH0.0040328732.55
Executor Swap To...125094362021-05-26 10:27:121212 days ago1622024832IN
0x987c2661...539E6c13F
0 ETH0.0047384531.70000148
Executor Swap To...125072442021-05-26 2:28:341213 days ago1621996114IN
0x987c2661...539E6c13F
0 ETH0.0227331448.2
Executor Swap To...125015372021-05-25 5:08:121214 days ago1621919292IN
0x987c2661...539E6c13F
0 ETH0.0151916831.5105
Executor Swap To...124977972021-05-24 15:25:231214 days ago1621869923IN
0x987c2661...539E6c13F
0 ETH0.0215694945.738
Executor Swap To...124760842021-05-21 6:27:491218 days ago1621578469IN
0x987c2661...539E6c13F
0 ETH0.0226529350.40000153
Executor Swap To...124760432021-05-21 6:19:071218 days ago1621577947IN
0x987c2661...539E6c13F
0 ETH0.0257126551.45
Executor Swap To...124714642021-05-20 13:02:401218 days ago1621515760IN
0x987c2661...539E6c13F
0 ETH0.0435254190.3
Finish Change St...124282442021-05-13 20:30:331225 days ago1620937833IN
0x987c2661...539E6c13F
0 ETH0.00780747110
Start Change Sta...124147382021-05-11 18:32:221227 days ago1620757942IN
0x987c2661...539E6c13F
0 ETH0.0270726300
Executor Swap To...123960232021-05-08 21:10:591230 days ago1620508259IN
0x987c2661...539E6c13F
0 ETH0.02015244157.5
0x60806040123779812021-05-06 2:14:071233 days ago1620267247IN
 Create: StabilizeStrategyFEIArbV2
0 ETH0.1953247240

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StabilizeStrategyFEIArbV2

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
// File: @openzeppelin/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);
    
    function decimals() external view returns (uint8);

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

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

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

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

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

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

// File: @openzeppelin/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 IERC20;` 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));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    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. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "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/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.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

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

// File: @openzeppelin/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 Ownable is Context {
    address private _governance;

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

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

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

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

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

// File: contracts/strategies/StabilizeStrategyFEIArbV2.sol

pragma solidity =0.6.6;

// This is a strategy that takes advantage of arb opportunities for fei
// Users deposit fei into the strategy and the strategy will sell into usdc when above usdc and usdc into fei when below
// Selling will occur via Uniswap and buying WETH via Uniswap
// Strat will also arbitrage with Aave flash loans between FEI bonding curve and  Uniswap to multiply gains

interface StabilizeStakingPool {
    function notifyRewardAmount(uint256) external;
}

interface UniswapRouter {
    function swapExactETHForTokens(uint, address[] calldata, address, uint) external payable returns (uint[] memory);
    function swapExactTokensForTokens(uint, uint, address[] calldata, address, uint) external returns (uint[] memory);
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint, uint, address[] calldata, address, uint) external;
    function getAmountsOut(uint, address[] calldata) external view returns (uint[] memory); // For a value in, it calculates value out
}

interface LendingPoolAddressesProvider {
    function getLendingPool() external view returns (address);
}

interface LendingPool {
  function flashLoan(address, address[] calldata, uint256[] calldata, uint256[] calldata, address, bytes calldata params, uint16) external;
}

interface AggregatorV3Interface {
  function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}

interface WrappedEther {
    function withdraw(uint256) external;
    function deposit() external payable;
}

interface FeiToken {
    function incentiveContract(address) external view returns (address); // Returns the Incentive contract for an LP token contract
}

interface FeiIncentiveContract {
    function getBuyIncentive(uint256 amount) external view returns (uint256, uint32);
    function getSellPenalty(uint256 amount) external view returns (uint256, uint32);
}

interface FeiBondingCurve {
    function getAmountOut(uint256 amountIn) external view returns (uint256 amountOut);
    function purchase(address to, uint256 amountIn) external payable returns (uint256 amountOut);
    function paused() external view returns (bool);
}

interface FeiOracle{
    function update() external returns (bool);
}

contract StabilizeStrategyFEIArbV2 is Ownable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using Address for address;
    
    address public treasuryAddress; // Address of the treasury
    address public stakingAddress; // Address to the STBZ staking pool
    address public zsTokenAddress; // The address of the controlling zs-Token
    
    uint256 constant DIVISION_FACTOR = 100000;
    uint256 public lastTradeTime = 0;
    uint256 public lastActionBalance = 0; // Balance before last deposit or withdraw
    uint256 public maxPoolSize = 10000000e18; // The maximum amount of ust tokens this strategy can hold, 10 mil by default
    uint256 public percentTradeTrigger = 10000; // 10% change in value will trigger a trade
    uint256 public maxPercentSell = 80000; // Up to 80% of the tokens are sold to the cheapest token
    uint256 public maxAmountSell = 500000; // The maximum amount of tokens that can be sold at once
    uint256 public percentDepositor = 50000; // 1000 = 1%, depositors earn 50% of all gains
    uint256 public percentFlashDepositor = 10000; // Depositors by default get 10% of flash loan profit, since funds aren't used for trade
    uint256 public percentExecutor = 10000; // 10000 = 10% of WETH goes to executor, 5% of total profit. This is on top of gas stipend
    uint256 public percentStakers = 50000; // 50% of non-depositors WETH goes to stakers, can be changed
    uint256 public minTradeSplit = 20000; // If the balance is less than or equal to this, it trades the entire balance
    uint256 public maxPercentStipend = 30000; // The maximum amount of WETH profit that can be allocated to the executor for gas in percent
    uint256 public gasStipend = 2000000; // This is the gas units that are covered by executing a trade taken from the WETH profit
    bool public incentiveActive = false; // FEI has disabled the incentive calculator
    uint256[3] private flashParams; // Global parameters guiding the flash loan setup
    uint256 constant minGain = 1e16; // Minimum amount of gain (0.01 coin) before buying WETH and splitting it
    
    // Token information
    // This strategy accepts fei and usdc
    struct TokenInfo {
        IERC20 token; // Reference of token
        uint256 decimals; // Decimals of token
    }
    
    TokenInfo[] private tokenList; // An array of tokens accepted as deposits

    // Strategy specific variables
    address constant UNISWAP_ROUTER_ADDRESS = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); //Address of Uniswap
    address constant WETH_ADDRESS = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
    address constant GAS_ORACLE_ADDRESS = address(0x169E633A2D1E6c10dD91238Ba11c4A708dfEF37C); // Chainlink address for fast gas oracle
    address constant LENDING_POOL_ADDRESS_PROVIDER = address(0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5); // Provider for Aave addresses
    address constant FEI_LP_CONTRACT = address(0x94B0A3d511b6EcDb17eBF877278Ab030acb0A878);
    address constant FEI_BONDING_CURVE = address(0xe1578B4a32Eaefcd563a9E6d0dc02a4213f673B7); // ETH Bonding curve
    address constant FEI_UNISWAP_ORACLE = address(0x087F35bd241e41Fc28E43f0E8C58d283DD55bD65);
    address constant FEI_BONDING_ORACLE = address(0x89714d3AC9149426219a3568543200D1964101C4);
    uint256 constant MAX_ETH_BUY = 1000 ether;
    uint256 constant WETH_ID = 2; // This strat will buy USDC with WETH and sell other tokens for WETH
    
    constructor(
        address _treasury,
        address _staking,
        address _zsToken
    ) public {
        treasuryAddress = _treasury;
        stakingAddress = _staking;
        zsTokenAddress = _zsToken;
        setupWithdrawTokens();
    }

    // Initialization functions
    
    function setupWithdrawTokens() internal {
        // Start with FEI
        IERC20 _token = IERC20(address(0x956F47F50A910163D8BF957Cf5846D573E7f87CA));
        tokenList.push(
            TokenInfo({
                token: _token,
                decimals: _token.decimals()
            })
        );
        
        // USDC
        _token = IERC20(address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48));
        tokenList.push(
            TokenInfo({
                token: _token,
                decimals: _token.decimals()
            })
        );
    }
    
    // Modifier
    modifier onlyZSToken() {
        require(zsTokenAddress == _msgSender(), "Call not sent from the zs-Token");
        _;
    }
    
    // Read functions
    
    function rewardTokensCount() external view returns (uint256) {
        return tokenList.length;
    }
    
    function rewardTokenAddress(uint256 _pos) external view returns (address) {
        require(_pos < tokenList.length,"No token at that position");
        return address(tokenList[_pos].token);
    }
    
    function balance() public view returns (uint256) {
        return getNormalizedTotalBalance(address(this));
    }
    
    function getNormalizedTotalBalance(address _address) public view returns (uint256) {
        uint256 _balance = 0;
        for(uint256 i = 0; i < tokenList.length; i++){
            uint256 _bal = tokenList[i].token.balanceOf(_address);
            _bal = _bal.mul(1e18).div(10**tokenList[i].decimals);
            _balance = _balance.add(_bal); // This has been normalized to 1e18 decimals
        }
        return _balance;
    }
    
    function withdrawTokenReserves() public view returns (address, uint256) {
        // This function will return the address and amount of fei, then usdc
        if(tokenList[0].token.balanceOf(address(this)) > 0){
            return (address(tokenList[0].token), tokenList[0].token.balanceOf(address(this)));
        }else if(tokenList[1].token.balanceOf(address(this)) > 0){
            return (address(tokenList[1].token), tokenList[1].token.balanceOf(address(this)));
        }else{
            return (address(0), 0); // No balance
        }
    }
    
    // Write functions
    
    receive() external payable {
        // We need an anonymous fallback function to accept ether into this contract
    }
    
    function enter() external onlyZSToken {
        deposit(false);
    }
    
    function exit() external onlyZSToken {
        // The ZS token vault is removing all tokens from this strategy
        withdraw(_msgSender(),1,1, false);
    }
    
    function deposit(bool nonContract) public onlyZSToken {
        // Only the ZS token can call the function
        
        // No trading is performed on deposit
        if(nonContract == true){ }
        lastActionBalance = balance();
        require(lastActionBalance <= maxPoolSize,"This strategy has reached its maximum balance");
    }
    
    function simulateExchange(uint256 _inID, uint256 _outID, uint256 _amount, bool doFlashLoan) internal view returns (uint256) {
        if(doFlashLoan == false){
            UniswapRouter router = UniswapRouter(UNISWAP_ROUTER_ADDRESS);
            if(_inID == 0){
                // Selling Fei, apply the fee on the amount in
                _amount = applyFEIFee(_amount);
                if(_amount == 0){return 0;}
            }
            
            if(_inID == _outID) { return 0;}
            if(_inID == WETH_ID || _outID == WETH_ID){
                // We will use Uniswap to buy or sell ETH
                address _inputToken;
                address _outputToken;
                if(_inID == WETH_ID){
                    _inputToken = WETH_ADDRESS;
                    _outputToken = address(tokenList[_outID].token);
                }else{
                    _inputToken = address(tokenList[_inID].token); 
                    _outputToken = WETH_ADDRESS;          
                }
                address[] memory path = new address[](2);
                path[0] = _inputToken;
                path[1] = _outputToken;
                uint256[] memory estimates = router.getAmountsOut(_amount, path);
                _amount = estimates[estimates.length - 1]; // Get output amount
            }else{
                // USDC for FEI or FEI for USDC
                address _inputToken = address(tokenList[_inID].token);
                address _outputToken = address(tokenList[_outID].token);
                address[] memory path = new address[](3);
                path[0] = _inputToken;
                path[1] = WETH_ADDRESS;
                path[2] = _outputToken;
                uint256[] memory estimates = router.getAmountsOut(_amount, path);
                _amount = estimates[estimates.length - 1]; // Get output amount                
            }
            
            if(_outID == 0){
                // Buying Fei, apply the bonus on amount out
                _amount = applyFEIBonus(_amount);
            }
            return _amount;
        }else{
            if(_inID != WETH_ID || _outID != WETH_ID) { return 0; } // Only can use ETH
            // We want to buy from bonding curve and sell to Uniswap for more ETH
            FeiBondingCurve bond = FeiBondingCurve(FEI_BONDING_CURVE);
            if(bond.paused() == true) { return 0; } // Not active
            _amount = bond.getAmountOut(_amount); // Will return FEI back
            _amount = simulateExchange(0, WETH_ID, _amount, false); // Will return ETH back
            return _amount;
        }
    }

    function applyFEIFee(uint256 _amount) internal view returns (uint256) {
        if(incentiveActive == false) { return _amount; }
        FeiIncentiveContract incCon = FeiIncentiveContract(FeiToken(address(tokenList[0].token)).incentiveContract(FEI_LP_CONTRACT));
        (uint256 feiFee,) = incCon.getSellPenalty(_amount);
        if(feiFee >= _amount) { return 0;}
        return _amount.sub(feiFee);
    }
    
    function applyFEIBonus(uint256 _amount) internal view returns (uint256) {
        if(incentiveActive == false) { return _amount; }
        FeiIncentiveContract incCon = FeiIncentiveContract(FeiToken(address(tokenList[0].token)).incentiveContract(FEI_LP_CONTRACT));
        (uint256 feiBonus,) = incCon.getBuyIncentive(_amount);
        return _amount.add(feiBonus);
    }
    
    function exchange(uint256 _inID, uint256 _outID, uint256 _amount, bool doFlashLoan) internal {
        if(doFlashLoan == false){
            UniswapRouter router = UniswapRouter(UNISWAP_ROUTER_ADDRESS);
            if(_inID == _outID) { return;}
            if(_inID == WETH_ID || _outID == WETH_ID){
                // We will use Uniswap to buy or sell ETH
                address _inputToken;
                address _outputToken;
                if(_inID == WETH_ID){
                    _inputToken = WETH_ADDRESS;
                    _outputToken = address(tokenList[_outID].token);
                }else{
                    _inputToken = address(tokenList[_inID].token); 
                    _outputToken = WETH_ADDRESS;          
                }
                address[] memory path = new address[](2);
                path[0] = _inputToken;
                path[1] = _outputToken;
                // Fees / bonuses are applied automatically
                IERC20(_inputToken).safeApprove(UNISWAP_ROUTER_ADDRESS, 0);
                IERC20(_inputToken).safeApprove(UNISWAP_ROUTER_ADDRESS, _amount);
                router.swapExactTokensForTokensSupportingFeeOnTransferTokens(_amount, 1, path, address(this), now.add(60));
                return;
            }else{
                // USDC for FEI or FEI for USDC
                address _inputToken = address(tokenList[_inID].token);
                address _outputToken = address(tokenList[_outID].token);
                address[] memory path = new address[](3);
                path[0] = _inputToken;
                path[1] = WETH_ADDRESS;
                path[2] = _outputToken;
                // Fees / bonuses are applied automatically
                IERC20(_inputToken).safeApprove(UNISWAP_ROUTER_ADDRESS, 0);
                IERC20(_inputToken).safeApprove(UNISWAP_ROUTER_ADDRESS, _amount);
                router.swapExactTokensForTokensSupportingFeeOnTransferTokens(_amount, 1, path, address(this), now.add(60));
                return;              
            }            
        }else{
            if(_inID != WETH_ID || _outID != WETH_ID) { return; } // Only can use ETH
            // We want to buy from bonding curve and sell to Uniswap for more ETH
            FeiBondingCurve bond = FeiBondingCurve(FEI_BONDING_CURVE);
            // We need to convert WETH to ETH as Aave supplies in WETH
            WrappedEther(WETH_ADDRESS).withdraw(_amount);
            uint256 _bal = tokenList[0].token.balanceOf(address(this));
            bond.purchase{value: _amount}(address(this), _amount); // Buy FEI from bonding curve with ETH
            _amount = tokenList[0].token.balanceOf(address(this)).sub(_bal); // Balance gain in FEI
            exchange(0, WETH_ID, _amount, false); // Buy WETH with FEI
            if(address(this).balance > 0){
                // Convert to WETH if any leftover ETH
                WrappedEther(WETH_ADDRESS).deposit{value: address(this).balance}();
            }
            return;      
        }
    }

    function getCheaperToken() internal view returns (uint256) {
        // This will give us the ID of the cheapest token on Uniswap
        // We will estimate the return for trading 1 FEI
        // The higher the return, the lower the price of the other token
        
        uint256 targetID = 0;
        uint256 mainAmount = uint256(1).mul(10**tokenList[0].decimals);
        
        // Estimate sell FEI for USDC, inclusive of FEI sell penalty
        uint256 estimate = 0;
        estimate = simulateExchange(0,1,mainAmount,false);
        estimate = estimate.mul(10**tokenList[0].decimals).div(10**tokenList[1].decimals); // Convert to main decimals
        if(estimate > mainAmount){
            // This token is worth less than the UST on Uniswap
            targetID = 1;
        }
        return targetID;
    }
    
    function estimateSellAtMaximumProfit(uint256 originID, uint256 targetID, uint256 _tokenBalance, bool doFlashLoan) internal view returns (uint256) {
        // This will estimate the amount that can be sold for the maximum profit possible
        // We discover the price then compare it to the actual return
        // The return must be positive to return a positive amount
        
        uint256 originDecimals = 0;
        uint256 targetDecimals = 0;
        if(doFlashLoan == false){
            originDecimals = tokenList[originID].decimals;
            targetDecimals = tokenList[targetID].decimals;
        }else{
            originDecimals = 18;
            targetDecimals = 18;
        }
        
        // Discover the price with near 0 slip
        uint256 _minAmount = _tokenBalance.mul(maxPercentSell.div(1000)).div(DIVISION_FACTOR);
        if(_minAmount == 0){ return 0; } // Nothing to sell, can't calculate
        uint256 _minReturn = _minAmount.mul(10**targetDecimals).div(10**originDecimals); // Convert decimals
        uint256 _return = simulateExchange(originID, targetID, _minAmount, doFlashLoan);
        if(_return <= _minReturn){
            return 0; // We are not going to gain from this trade
        }
        _return = _return.mul(10**originDecimals).div(10**targetDecimals); // Convert to origin decimals
        uint256 _startPrice = _return.mul(1e18).div(_minAmount);
        
        // Now get the price at a higher amount, expected to be lower due to slippage
        uint256 _bigAmount = _tokenBalance.mul(maxPercentSell).div(DIVISION_FACTOR);
        _return = simulateExchange(originID, targetID, _bigAmount, doFlashLoan);
        _return = _return.mul(10**originDecimals).div(10**targetDecimals); // Convert to origin decimals
        uint256 _endPrice = _return.mul(1e18).div(_bigAmount);
        if(_endPrice >= _startPrice){
            // Really good liquidity
            return _bigAmount;
        }
        
        // Else calculate amount at max profit
        uint256 scaleFactor = uint256(1).mul(10**originDecimals);
        uint256 _targetAmount = _startPrice.sub(1e18).mul(scaleFactor).div(_startPrice.sub(_endPrice).mul(scaleFactor).div(_bigAmount.sub(_minAmount))).div(2);
        if(_targetAmount > _bigAmount){
            // Cannot create an estimate larger than what we want to sell
            return _bigAmount;
        }
        return _targetAmount;
    }
    
    // Flash loan functions
    function estimateFlashLoanResult(uint256 _tradeSize, bool _asWETH) internal view returns (uint256) {
        // This will estimate the return of our flash loan minus the fee
        uint256 fee = _tradeSize.mul(90).div(DIVISION_FACTOR); // This is the Aave fee (0.09%)
        uint256 _return = 0;
        _return = simulateExchange(WETH_ID, WETH_ID, _tradeSize, true);
        if(_return > _tradeSize.add(fee)){
            // Positive return on the flash
            _return = _return.sub(fee).sub(_tradeSize); // This is return in WETH gain
            if(_asWETH == false){
                _return = simulateExchange(WETH_ID, 1, _return, false); // Convert return to USDC amount
                _return = _return.mul(1e18).div(10**tokenList[1].decimals); // Normalize return
            }
            return _return;
        }else{
            return 0; // Do not take out a flash loan as not enough gain
        }
    }
    
    function performFlashLoan(uint256 _amount) internal returns (uint256) {
        // Will call Aave
        IERC20 weth = IERC20(WETH_ADDRESS);
        uint256 flashGain = weth.balanceOf(address(this)); // Get base weth amount
        
        flashParams[0] = 1; // Authorize flash loan receiving
        
        // Call the flash loan
        LendingPool lender = LendingPool(LendingPoolAddressesProvider(LENDING_POOL_ADDRESS_PROVIDER).getLendingPool()); // Load the lending pool
        
        address[] memory assets = new address[](1);
        assets[0] = address(WETH_ADDRESS);       
        
        uint256[] memory amounts = new uint256[](1);
        amounts[0] = _amount; // The amount we want to borrow
        
        uint256[] memory modes = new uint256[](1);
        modes[0] = 0; // Revert if we fail to return funds
        
        bytes memory params = "";
        lender.flashLoan(address(this), assets, amounts, modes, address(this), params, 0);
        
        flashParams[0] = 0; // Deactivate flash loan receiving
        uint256 newBal = weth.balanceOf(address(this));
        require(newBal > flashGain, "Flash loan failed to increase balance");
        flashGain = newBal.sub(flashGain);
        uint256 depositorPayout = 0;
        if(balance() > 0){
            // Only pay depositors if there are depositors here
            depositorPayout = flashGain.mul(percentFlashDepositor).div(DIVISION_FACTOR);
            if(depositorPayout > 0){
                // Convert part to USDC
                exchange(WETH_ID, 1, depositorPayout, false);
                flashGain = flashGain.sub(depositorPayout);
            }
        }
        return flashGain;
    }
    
    function executeOperation(
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata premiums,
        address initiator,
        bytes calldata params
    )
        external
        returns (bool)
    {
        require(flashParams[0] == 1, "No flash loan authorized on this contract");
        address lendingPool = LendingPoolAddressesProvider(LENDING_POOL_ADDRESS_PROVIDER).getLendingPool();
        require(_msgSender() == lendingPool, "Not called from Aave");
        require(initiator == address(this), "Not Authorized"); // Prevent other contracts from calling this function
        if(params.length == 0){} // Removes the warning
        flashParams[0] = 0; // Prevent a replay;
        
        exchange(WETH_ID, WETH_ID, amounts[0], true); // Buy WETH from bonding curve and sell on Uniswap
        
        // Authorize Aave to pull funds from this contract
        // Approve the LendingPool contract allowance to *pull* the owed amount
        {
            for(uint256 i = 0; i < assets.length; i++) {
                uint256 amountOwing = amounts[i].add(premiums[i]);
                IERC20(assets[i]).safeApprove(lendingPool, 0);
                IERC20(assets[i]).safeApprove(lendingPool, amountOwing);
            }
        }
        
        return true;
    }
    // ---------------------
    
    function getFastGasPrice() internal view returns (uint256) {
        AggregatorV3Interface gasOracle = AggregatorV3Interface(GAS_ORACLE_ADDRESS);
        ( , int intGasPrice, , , ) = gasOracle.latestRoundData(); // We only want the answer 
        return uint256(intGasPrice);
    }
    
    function checkAndSwapTokens(address _executor, uint256 targetID, bool doFlashLoan) internal {
        lastTradeTime = now;
        
        // Update the Fei Uniswap Oracle
        FeiOracle(FEI_UNISWAP_ORACLE).update();

        uint256 gain = 0;
        if(doFlashLoan == false){
            uint256 length = tokenList.length;
            // Now sell all the other tokens into this token
            uint256 _totalBalance = balance(); // Get the token balance at this contract, should increase
            bool _expectIncrease = false;
            for(uint256 i = 0; i < length; i++){
                if(i != targetID){
                    uint256 sellBalance = 0;
                    uint256 _bal = tokenList[i].token.balanceOf(address(this));
                    uint256 _minTradeTarget = minTradeSplit.mul(10**tokenList[i].decimals);
                    uint256 _maxTradeTarget = maxAmountSell.mul(10**tokenList[i].decimals); // Determine the maximum amount of tokens to sell at once
                    if(_bal <= _minTradeTarget){
                        // If balance is too small,sell all tokens at once
                        sellBalance = _bal;
                    }else{
                        sellBalance = estimateSellAtMaximumProfit(i, targetID, _bal, false);
                    }
                    if(sellBalance > _maxTradeTarget){
                        // If greater than the maximum trade allowed, match it
                        sellBalance = _maxTradeTarget;
                    }
                    if(sellBalance > 0){
                        uint256 minReceiveBalance = sellBalance.mul(10**tokenList[targetID].decimals).div(10**tokenList[i].decimals); // Change to match decimals of destination
                        uint256 estimate = simulateExchange(i, targetID, sellBalance, false);
                        if(estimate > minReceiveBalance){
                            _expectIncrease = true;
                            exchange(i, targetID, sellBalance, false);
                        }                        
                    }
                }
            }
            uint256 _newBalance = balance();
            if(_expectIncrease == true){
                // There may be rare scenarios where we don't gain any by calling this function
                require(_newBalance > _totalBalance, "Failed to gain in balance from selling tokens");
            }
            gain = _newBalance.sub(_totalBalance);
        }else{
            // We want to perform a flash loan
            FeiOracle(FEI_BONDING_ORACLE).update();
            uint256 tradeSize = estimateSellAtMaximumProfit(WETH_ID, WETH_ID, MAX_ETH_BUY, true); // This will return our ideal trade size
            if(tradeSize > 0){
                performFlashLoan(tradeSize); // Our weth balance should increase, otherwise this will revert
            }            
        }

        IERC20 weth = IERC20(WETH_ADDRESS);
        uint256 _wethBalance = weth.balanceOf(address(this));
        if(gain >= minGain){
            // Buy WETH from Uniswap with tokens
            uint256 sellBalance = gain.mul(10**tokenList[targetID].decimals).div(1e18); // Convert to target decimals
            sellBalance = sellBalance.mul(uint256(100000).sub(percentDepositor)).div(DIVISION_FACTOR);
            if(sellBalance <= tokenList[targetID].token.balanceOf(address(this))){
                // Sell some of our gained token for WETH
                exchange(targetID, WETH_ID, sellBalance, false);
                _wethBalance = weth.balanceOf(address(this));
            }
        }
        if(_wethBalance > 0){
            // Split the rest between the stakers and such
            // This is pure profit, figure out allocation
            // Split the amount sent to the treasury, stakers and executor if one exists
            if(_executor != address(0)){
                // Executors will get a gas reimbursement in WETH and a percent of the remaining
                uint256 maxGasFee = getFastGasPrice().mul(gasStipend); // This is gas stipend in wei
                uint256 gasFee = tx.gasprice.mul(gasStipend); // This is gas fee requested
                if(gasFee > maxGasFee){
                    gasFee = maxGasFee; // Gas fee cannot be greater than the maximum
                }
                uint256 executorAmount = gasFee;
                if(gasFee >= _wethBalance.mul(maxPercentStipend).div(DIVISION_FACTOR)){
                    executorAmount = _wethBalance.mul(maxPercentStipend).div(DIVISION_FACTOR); // The executor will get the entire amount up to point
                }else{
                    // Add the executor percent on top of gas fee
                    executorAmount = _wethBalance.sub(gasFee).mul(percentExecutor).div(DIVISION_FACTOR).add(gasFee);
                }
                if(executorAmount > 0){
                    weth.safeTransfer(_executor, executorAmount);
                    _wethBalance = weth.balanceOf(address(this)); // Recalculate WETH in contract           
                }
            }
            if(_wethBalance > 0){
                uint256 stakersAmount = _wethBalance.mul(percentStakers).div(DIVISION_FACTOR);
                uint256 treasuryAmount = _wethBalance.sub(stakersAmount);
                if(treasuryAmount > 0){
                    weth.safeTransfer(treasuryAddress, treasuryAmount);
                }
                if(stakersAmount > 0){
                    if(stakingAddress != address(0)){
                        weth.safeTransfer(stakingAddress, stakersAmount);
                        StabilizeStakingPool(stakingAddress).notifyRewardAmount(stakersAmount);                                
                    }else{
                        // No staking pool selected, just send to the treasury
                        weth.safeTransfer(treasuryAddress, stakersAmount);
                    }
                }
            }                
        }
    }
    
    function expectedProfit(bool inWETHForExecutor, bool checkFlashLoan) external view returns (uint256, uint256) {
        // This view will return the amount of gain a forced swap or loan will make on next call
        
        // Now find our target token to sell into
        uint256 targetID = 0;
        uint256 _normalizedGain = 0;
        if(checkFlashLoan == false){
            targetID = getCheaperToken();
            uint256 length = tokenList.length;
            for(uint256 i = 0; i < length; i++){
                if(i != targetID){
                    uint256 sellBalance = 0;
                    uint256 _bal = tokenList[i].token.balanceOf(address(this));
                    uint256 _minTradeTarget = minTradeSplit.mul(10**tokenList[i].decimals);
                    uint256 _maxTradeTarget = maxAmountSell.mul(10**tokenList[i].decimals); // Determine the maximum amount of tokens to sell at once
                    if(_bal <= _minTradeTarget){
                        // If balance is too small,sell all tokens at once
                        sellBalance = _bal;
                    }else{
                        sellBalance = estimateSellAtMaximumProfit(i, targetID, _bal, false);
                    }
                    if(sellBalance > _maxTradeTarget){
                        // If greater than the maximum trade allowed, match it
                        sellBalance = _maxTradeTarget;
                    }
                    if(sellBalance > 0){
                        uint256 minReceiveBalance = sellBalance.mul(10**tokenList[targetID].decimals).div(10**tokenList[i].decimals); // Change to match decimals of destination
                        uint256 estimate = simulateExchange(i, targetID, sellBalance, false);
                        if(estimate > minReceiveBalance){
                            uint256 _gain = estimate.sub(minReceiveBalance).mul(1e18).div(10**tokenList[targetID].decimals); // Normalized gain
                            _normalizedGain = _normalizedGain.add(_gain);
                        }                        
                    }
                }
            }
        }else{
            // We want to see if flash loans are profitable
            uint256 tradeSize = estimateSellAtMaximumProfit(WETH_ID, WETH_ID, MAX_ETH_BUY, true); // This will return our ideal trade size
            if(tradeSize > 0){
                _normalizedGain = estimateFlashLoanResult(tradeSize, inWETHForExecutor);
            }
        }

        if(inWETHForExecutor == false){
            return (_normalizedGain, 0); // This will be in stablecoins regardless of whether flash loan or not
        }else{
            if(_normalizedGain == 0){
                return (0, 0);
            }
            // Calculate how much WETH the executor would make as profit
            uint256 estimate = 0;
            if(checkFlashLoan == false){
                if(_normalizedGain > 0){
                    uint256 sellBalance = _normalizedGain.mul(10**tokenList[targetID].decimals).div(1e18); // Convert to target decimals
                    sellBalance = sellBalance.mul(uint256(100000).sub(percentDepositor)).div(DIVISION_FACTOR);
                    // Estimate output
                    estimate = simulateExchange(targetID, WETH_ID, sellBalance, false);           
                }
            }else{
                // If we are checking for flash loan, normalized gain is WETH profit from loan, allocate percent for depositors
                if(balance() > 0){
                    estimate = _normalizedGain.mul(uint256(100000).sub(percentFlashDepositor)).div(DIVISION_FACTOR);
                }else{
                    // If there is no balance here, allocate all to stakers, treasury and executors only
                    estimate = _normalizedGain;
                }
            }
            // Now calculate the amount going to the executor
            uint256 gasFee = getFastGasPrice().mul(gasStipend); // This is gas stipend in wei
            if(gasFee >= estimate.mul(maxPercentStipend).div(DIVISION_FACTOR)){ // Max percent of total
                return (estimate.mul(maxPercentStipend).div(DIVISION_FACTOR), targetID); // The executor will get max percent of total
            }else{
                estimate = estimate.sub(gasFee); // Subtract fee from remaining balance
                return (estimate.mul(percentExecutor).div(DIVISION_FACTOR).add(gasFee), targetID); // Executor amount with fee added
            }
        }  
    }
    
    function withdraw(address _depositor, uint256 _share, uint256 _total, bool nonContract) public onlyZSToken returns (uint256) {
        require(balance() > 0, "There are no tokens in this strategy");
        if(nonContract == true){
            if( _share > _total.mul(percentTradeTrigger).div(DIVISION_FACTOR)){
                uint256 buyID = getCheaperToken();
                checkAndSwapTokens(address(0), buyID, false);
            }
        }
        
        uint256 withdrawAmount = 0;
        uint256 _balance = balance();
        if(_share < _total){
            uint256 _myBalance = _balance.mul(_share).div(_total);
            withdrawPerOrder(_depositor, _myBalance, false); // This will withdraw based on token price
            withdrawAmount = _myBalance;
        }else{
            // We are all shares, transfer all
            withdrawPerOrder(_depositor, _balance, true);
            withdrawAmount = _balance;
        }       
        lastActionBalance = balance();
        
        return withdrawAmount;
    }
    
    // This will withdraw the tokens from the contract based on their order
    function withdrawPerOrder(address _receiver, uint256 _withdrawAmount, bool _takeAll) internal {
        uint256 length = tokenList.length;
        if(_takeAll == true){
            // Send the entire balance
            for(uint256 i = 0; i < length; i++){
                uint256 _bal = tokenList[i].token.balanceOf(address(this));
                if(_bal > 0){
                    tokenList[i].token.safeTransfer(_receiver, _bal);
                }
            }
            return;
        }
        
        for(uint256 i = 0; i < length; i++){
            // Determine the balance left
            uint256 _normalizedBalance = tokenList[i].token.balanceOf(address(this)).mul(1e18).div(10**tokenList[i].decimals);
            if(_normalizedBalance <= _withdrawAmount){
                // Withdraw the entire balance of this token
                if(_normalizedBalance > 0){
                    _withdrawAmount = _withdrawAmount.sub(_normalizedBalance);
                    tokenList[i].token.safeTransfer(_receiver, tokenList[i].token.balanceOf(address(this)));                    
                }
            }else{
                // Withdraw a partial amount of this token
                if(_withdrawAmount > 0){
                    // Convert the withdraw amount to the token's decimal amount
                    uint256 _balance = _withdrawAmount.mul(10**tokenList[i].decimals).div(1e18);
                    _withdrawAmount = 0;
                    tokenList[i].token.safeTransfer(_receiver, _balance);
                }
                break; // Nothing more to withdraw
            }
        }
    }
    
    function executorSwapTokens(address _executor, uint256 _minSecSinceLastTrade, uint256 _buyID, bool doFlash) external {
        // Function designed to promote trading with incentive. Users get 20% of WETH from profitable trades
        require(now.sub(lastTradeTime) > _minSecSinceLastTrade, "The last trade was too recent");
        require(_msgSender() == tx.origin, "Contracts cannot interact with this function");
        checkAndSwapTokens(_executor, _buyID, doFlash);
    }
    
    // Governance functions
    function governanceSwapTokens(uint256 _buyID, bool doFlash) external onlyGovernance {
        // This is function that force trade tokens at anytime. It can only be called by governance
        checkAndSwapTokens(governance(), _buyID, doFlash);
    }

    // Change the trading conditions used by the strategy without timelock
    // --------------------
    function changeTradingConditions(uint256 _pTradeTrigger,
                                    uint256 _minSplit,
                                    uint256 _pSellPercent, 
                                    uint256 _maxSell,
                                    uint256 _pStipend,
                                    uint256 _maxStipend,
                                    bool _changeIncentive) external onlyGovernance {
        // Changes a lot of trading parameters in one call
        require(_pTradeTrigger <= 100000 && _pSellPercent <= 100000 && _pStipend <= 100000,"Percent cannot be greater than 100%");
        percentTradeTrigger = _pTradeTrigger;
        minTradeSplit = _minSplit;
        maxPercentSell = _pSellPercent;
        maxAmountSell = _maxSell;
        maxPercentStipend = _pStipend;
        gasStipend = _maxStipend;
        incentiveActive = _changeIncentive;
    }
    // --------------------
    
    // Timelock variables
    
    uint256 private _timelockStart; // The start of the timelock to change governance variables
    uint256 private _timelockType; // The function that needs to be changed
    uint256 constant TIMELOCK_DURATION = 86400; // Timelock is 24 hours
    
    // Reusable timelock variables
    address private _timelock_address;
    uint256[5] private _timelock_data;
    
    modifier timelockConditionsMet(uint256 _type) {
        require(_timelockType == _type, "Timelock not acquired for this function");
        _timelockType = 0; // Reset the type once the timelock is used
        if(balance() > 0){ // Timelock only applies when balance exists
            require(now >= _timelockStart + TIMELOCK_DURATION, "Timelock time not met");
        }
        _;
    }
    
    // Change the owner of the token contract
    // --------------------
    function startGovernanceChange(address _address) external onlyGovernance {
        _timelockStart = now;
        _timelockType = 1;
        _timelock_address = _address;       
    }
    
    function finishGovernanceChange() external onlyGovernance timelockConditionsMet(1) {
        transferGovernance(_timelock_address);
    }
    // --------------------
    
    // Change the treasury address
    // --------------------
    function startChangeTreasury(address _address) external onlyGovernance {
        _timelockStart = now;
        _timelockType = 2;
        _timelock_address = _address;
    }
    
    function finishChangeTreasury() external onlyGovernance timelockConditionsMet(2) {
        treasuryAddress = _timelock_address;
    }
    // --------------------
    
    // Change the staking address
    // --------------------
    function startChangeStakingPool(address _address) external onlyGovernance {
        _timelockStart = now;
        _timelockType = 3;
        _timelock_address = _address;
    }
    
    function finishChangeStakingPool() external onlyGovernance timelockConditionsMet(3) {
        stakingAddress = _timelock_address;
    }
    // --------------------
    
    // Change the zsToken address
    // --------------------
    function startChangeZSToken(address _address) external onlyGovernance {
        _timelockStart = now;
        _timelockType = 4;
        _timelock_address = _address;
    }
    
    function finishChangeZSToken() external onlyGovernance timelockConditionsMet(4) {
        zsTokenAddress = _timelock_address;
    }
    // --------------------
    
    // Change the strategy allocations between the parties
    // --------------------
    
    function startChangeStrategyAllocations(uint256 _pDepositors, uint256 _pFDepositors, 
                                            uint256 _pExecutor, uint256 _pStakers, uint256 _maxPool) external onlyGovernance {
        // Changes strategy allocations in one call
        require(_pDepositors <= 100000 && _pFDepositors <= 100000 && _pExecutor <= 100000 && _pStakers <= 100000,"Percent cannot be greater than 100%");
        _timelockStart = now;
        _timelockType = 5;
        _timelock_data[0] = _pDepositors;
        _timelock_data[1] = _pExecutor;
        _timelock_data[2] = _pStakers;
        _timelock_data[3] = _maxPool;
        _timelock_data[4] = _pFDepositors;
    }
    
    function finishChangeStrategyAllocations() external onlyGovernance timelockConditionsMet(5) {
        percentDepositor = _timelock_data[0];
        percentExecutor = _timelock_data[1];
        percentStakers = _timelock_data[2];
        maxPoolSize = _timelock_data[3];
        percentFlashDepositor = _timelock_data[4];
    }
    // --------------------
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_staking","type":"address"},{"internalType":"address","name":"_zsToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"GovernanceTransferred","type":"event"},{"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pTradeTrigger","type":"uint256"},{"internalType":"uint256","name":"_minSplit","type":"uint256"},{"internalType":"uint256","name":"_pSellPercent","type":"uint256"},{"internalType":"uint256","name":"_maxSell","type":"uint256"},{"internalType":"uint256","name":"_pStipend","type":"uint256"},{"internalType":"uint256","name":"_maxStipend","type":"uint256"},{"internalType":"bool","name":"_changeIncentive","type":"bool"}],"name":"changeTradingConditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"nonContract","type":"bool"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"premiums","type":"uint256[]"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_executor","type":"address"},{"internalType":"uint256","name":"_minSecSinceLastTrade","type":"uint256"},{"internalType":"uint256","name":"_buyID","type":"uint256"},{"internalType":"bool","name":"doFlash","type":"bool"}],"name":"executorSwapTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"inWETHForExecutor","type":"bool"},{"internalType":"bool","name":"checkFlashLoan","type":"bool"}],"name":"expectedProfit","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finishChangeStakingPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishChangeStrategyAllocations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishChangeTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishChangeZSToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishGovernanceChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasStipend","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getNormalizedTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_buyID","type":"uint256"},{"internalType":"bool","name":"doFlash","type":"bool"}],"name":"governanceSwapTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"incentiveActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastActionBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTradeTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmountSell","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPercentSell","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPercentStipend","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPoolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTradeSplit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentDepositor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentExecutor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentFlashDepositor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentStakers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentTradeTrigger","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pos","type":"uint256"}],"name":"rewardTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardTokensCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"startChangeStakingPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pDepositors","type":"uint256"},{"internalType":"uint256","name":"_pFDepositors","type":"uint256"},{"internalType":"uint256","name":"_pExecutor","type":"uint256"},{"internalType":"uint256","name":"_pStakers","type":"uint256"},{"internalType":"uint256","name":"_maxPool","type":"uint256"}],"name":"startChangeStrategyAllocations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"startChangeTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"startChangeZSToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"startGovernanceChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"},{"internalType":"uint256","name":"_share","type":"uint256"},{"internalType":"uint256","name":"_total","type":"uint256"},{"internalType":"bool","name":"nonContract","type":"bool"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTokenReserves","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zsTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600060048190556005556a084595161401484a0000006006556127106007819055620138806008556207a12060095561c350600a819055600b829055600c91909155600d55614e20600e55617530600f55621e84806010556011805460ff191690553480156200007357600080fd5b506040516200523438038062005234833981810160405260608110156200009957600080fd5b50805160208201516040909201519091906000620000bf6001600160e01b036200016216565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce80908290a350600180546001600160a01b038086166001600160a01b031992831617909255600280548584169083161790556003805492841692909116919091179055620001596001600160e01b036200016616565b5050506200031f565b3390565b600073956f47f50a910163d8bf957cf5846d573e7f87ca905060156040518060400160405280836001600160a01b03168152602001836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620001d557600080fd5b505afa158015620001ea573d6000803e3d6000fd5b505050506040513d60208110156200020157600080fd5b505160ff1690528154600180820184556000938452602093849020835160029093020180546001600160a01b0319166001600160a01b039093169290921782559183015191015560408051808201825273a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48808252825163313ce56760e01b81529251909450601593919283830192869263313ce567926004808201939291829003018186803b158015620002a857600080fd5b505afa158015620002bd573d6000803e3d6000fd5b505050506040513d6020811015620002d457600080fd5b505160ff1690528154600180820184556000938452602093849020835160029093020180546001600160a01b0319166001600160a01b03909316929092178255919092015191015550565b614f05806200032f6000396000f3fe6080604052600436106102555760003560e01c80639d63b8f711610139578063cc403262116100b6578063d821a3381161007a578063d821a338146108c6578063e97dcb62146108db578063e9fad8ee146108f0578063f03bcd8e14610905578063f800877614610938578063f95201da1461096b5761025c565b8063cc4032621461085d578063d523733314610872578063d5344f7914610887578063d5eee8b61461089c578063d7b4be24146108b15761025c565b8063ba49848b116100fd578063ba49848b146107ba578063c5579dc0146107cf578063c57273c2146107e4578063c5f956af14610810578063c650ea59146108255761025c565b80639d63b8f714610716578063a7e712ce14610749578063b69ef8a81461075e578063b919507214610773578063b961b34f146107885761025c565b80635aa6e675116101d2578063780d9d2d11610196578063780d9d2d1461053557806387f61c811461054a5780638867517c1461055f578063920f5c84146105745780639434c910146106ec57806399840b7a146107015761025c565b80635aa6e6751461044b578063614dede814610460578063628ee6cc146104a757806365a893ae146104f75780636dbc132a146105205761025c565b80633047e762116102195780633047e762146103665780633303b8ab1461037b5780633babade2146103905780634a6818ea146103c35780635930a0a1146104055761025c565b806314aabd01146102615780631d0fa032146102965780632195c542146102bd578063234b6745146102d25780632a7b9ee4146103195761025c565b3661025c57005b600080fd5b34801561026d57600080fd5b506102946004803603602081101561028457600080fd5b50356001600160a01b0316610980565b005b3480156102a257600080fd5b506102ab610a03565b60408051918252519081900360200190f35b3480156102c957600080fd5b506102ab610a09565b3480156102de57600080fd5b506102ab600480360360808110156102f557600080fd5b506001600160a01b0381351690602081013590604081013590606001351515610a0f565b34801561032557600080fd5b5061034d6004803603604081101561033c57600080fd5b508035151590602001351515610b6b565b6040805192835260208301919091528051918290030190f35b34801561037257600080fd5b506102ab610fa5565b34801561038757600080fd5b506102ab610fab565b34801561039c57600080fd5b50610294600480360360208110156103b357600080fd5b50356001600160a01b0316610fb1565b3480156103cf57600080fd5b50610294600480360360a08110156103e657600080fd5b5080359060208101359060408101359060608101359060800135611034565b34801561041157600080fd5b5061042f6004803603602081101561042857600080fd5b503561111e565b604080516001600160a01b039092168252519081900360200190f35b34801561045757600080fd5b5061042f6111a6565b34801561046c57600080fd5b506102946004803603608081101561048357600080fd5b506001600160a01b03813516906020810135906040810135906060013515156111b5565b3480156104b357600080fd5b50610294600480360360e08110156104ca57600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c00135151561127c565b34801561050357600080fd5b5061050c611362565b604080519115158252519081900360200190f35b34801561052c57600080fd5b5061042f61136b565b34801561054157600080fd5b506102ab61137a565b34801561055657600080fd5b50610294611380565b34801561056b57600080fd5b506102ab6114a8565b34801561058057600080fd5b5061050c600480360360a081101561059757600080fd5b810190602081018135600160201b8111156105b157600080fd5b8201836020820111156105c357600080fd5b803590602001918460208302840111600160201b831117156105e457600080fd5b919390929091602081019035600160201b81111561060157600080fd5b82018360208201111561061357600080fd5b803590602001918460208302840111600160201b8311171561063457600080fd5b919390929091602081019035600160201b81111561065157600080fd5b82018360208201111561066357600080fd5b803590602001918460208302840111600160201b8311171561068457600080fd5b919390926001600160a01b0383351692604081019060200135600160201b8111156106ae57600080fd5b8201836020820111156106c057600080fd5b803590602001918460018302840111600160201b831117156106e157600080fd5b5090925090506114ae565b3480156106f857600080fd5b506102ab6116f3565b34801561070d57600080fd5b506102ab6116f9565b34801561072257600080fd5b506102ab6004803603602081101561073957600080fd5b50356001600160a01b03166116ff565b34801561075557600080fd5b5061029461180a565b34801561076a57600080fd5b506102ab611932565b34801561077f57600080fd5b50610294611942565b34801561079457600080fd5b50610294600480360360408110156107ab57600080fd5b50803590602001351515611a5d565b3480156107c657600080fd5b50610294611acb565b3480156107db57600080fd5b506102ab611bf3565b3480156107f057600080fd5b506102946004803603602081101561080757600080fd5b50351515611bf9565b34801561081c57600080fd5b5061042f611c9e565b34801561083157600080fd5b5061083a611cad565b604080516001600160a01b03909316835260208301919091528051918290030190f35b34801561086957600080fd5b50610294611ee1565b34801561087e57600080fd5b506102ab612005565b34801561089357600080fd5b506102ab61200b565b3480156108a857600080fd5b506102ab612011565b3480156108bd57600080fd5b5061042f612017565b3480156108d257600080fd5b506102ab612026565b3480156108e757600080fd5b5061029461202c565b3480156108fc57600080fd5b50610294612090565b34801561091157600080fd5b506102946004803603602081101561092857600080fd5b50356001600160a01b03166120fd565b34801561094457600080fd5b506102946004803603602081101561095b57600080fd5b50356001600160a01b0316612180565b34801561097757600080fd5b506102ab612203565b610988612209565b6000546001600160a01b039081169116146109d8576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556003601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b600c5481565b60095481565b6000610a19612209565b6003546001600160a01b03908116911614610a69576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b6000610a73611932565b11610aaf5760405162461bcd60e51b8152600401808060200182810382526024815260200180614e296024913960400191505060405180910390fd5b60018215151415610b0457610ae2620186a0610ad66007548661220d90919063ffffffff16565b9063ffffffff61226f16565b841115610b04576000610af36122b1565b9050610b026000826000612375565b505b600080610b0f611932565b905084861015610b44576000610b2f86610ad6848a63ffffffff61220d16565b9050610b3d88826000612b34565b9150610b54565b610b5087826001612b34565b8091505b610b5c611932565b6005555090505b949350505050565b600080808084610dca57610b7d6122b1565b60155490925060005b81811015610dc357838114610dbb576000809050600060158381548110610ba957fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b505160158054919250600091610c68919086908110610c4257fe5b906000526020600020906002020160010154600a0a600e5461220d90919063ffffffff16565b90506000610ca260158681548110610c7c57fe5b906000526020600020906002020160010154600a0a60095461220d90919063ffffffff16565b9050818311610cb357829350610cc3565b610cc08589856000612e42565b93505b80841115610ccf578093505b8315610db6576000610d3060158781548110610ce757fe5b906000526020600020906002020160010154600a0a610ad660158c81548110610d0c57fe5b906000526020600020906002020160010154600a0a8861220d90919063ffffffff16565b90506000610d41878b886000613078565b905081811115610db3576000610d9d60158c81548110610d5d57fe5b906000526020600020906002020160010154600a0a610ad6670de0b6b3a7640000610d91878761373590919063ffffffff16565b9063ffffffff61220d16565b9050610daf8a8263ffffffff61377716565b9950505b50505b505050505b600101610b86565b5050610dfa565b6000610de3600280683635c9adc5dea000006001612e42565b90508015610df857610df581886137d1565b91505b505b85610e0c57925060009150610f9e9050565b80610e20575060009250829150610f9e9050565b600085610eb9578115610eb4576000610e6f670de0b6b3a7640000610ad660158781548110610e4b57fe5b906000526020600020906002020160010154600a0a8661220d90919063ffffffff16565b9050610ea0620186a0610ad6610e93600a54620186a061373590919063ffffffff16565b849063ffffffff61220d16565b9050610eb0846002836000613078565b9150505b610f02565b6000610ec3611932565b1115610eff57610ef8620186a0610ad6610eeb600b54620186a061373590919063ffffffff16565b859063ffffffff61220d16565b9050610f02565b50805b6000610f12601054610d91613877565b9050610f30620186a0610ad6600f548561220d90919063ffffffff16565b8110610f6057610f52620186a0610ad6600f548561220d90919063ffffffff16565b849550955050505050610f9e565b610f70828263ffffffff61373516565b9150610f5281610f92620186a0610ad6600c548761220d90919063ffffffff16565b9063ffffffff61377716565b9250929050565b60075481565b60055481565b610fb9612209565b6000546001600160a01b03908116911614611009576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556004601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b61103c612209565b6000546001600160a01b0390811691161461108c576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b620186a085111580156110a25750620186a08411155b80156110b15750620186a08311155b80156110c05750620186a08211155b6110fb5760405162461bcd60e51b8152600401808060200182810382526023815260200180614e4d6023913960400191505060405180910390fd5b426016556005601755601994909455601a91909155601b55601c91909155601d55565b6015546000908210611177576040805162461bcd60e51b815260206004820152601960248201527f4e6f20746f6b656e206174207468617420706f736974696f6e00000000000000604482015290519081900360640190fd5b6015828154811061118457fe5b60009182526020909120600290910201546001600160a01b031690505b919050565b6000546001600160a01b031690565b826111cb6004544261373590919063ffffffff16565b1161121d576040805162461bcd60e51b815260206004820152601d60248201527f546865206c6173742074726164652077617320746f6f20726563656e74000000604482015290519081900360640190fd5b32611226612209565b6001600160a01b03161461126b5760405162461bcd60e51b815260040180806020018281038252602c815260200180614cfa602c913960400191505060405180910390fd5b611276848383612375565b50505050565b611284612209565b6000546001600160a01b039081169116146112d4576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b620186a087111580156112ea5750620186a08511155b80156112f95750620186a08311155b6113345760405162461bcd60e51b8152600401808060200182810382526023815260200180614e4d6023913960400191505060405180910390fd5b600796909655600e94909455600892909255600955600f556010556011805460ff1916911515919091179055565b60115460ff1681565b6003546001600160a01b031681565b60155490565b611388612209565b6000546001600160a01b039081169116146113d8576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b6003806017541461141a5760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b60006017819055611429611932565b1115611483576201518060165401421015611483576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601854600280546001600160a01b0319166001600160a01b03909216919091179055565b600b5481565b6012546000906001146114f25760405162461bcd60e51b8152600401808060200182810382526029815260200180614e006029913960400191505060405180910390fd5b600073b53c1a33016b2dc2ff3653530bff1848a515c8c56001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561154157600080fd5b505afa158015611555573d6000803e3d6000fd5b505050506040513d602081101561156b57600080fd5b505190506001600160a01b038116611581612209565b6001600160a01b0316146115d3576040805162461bcd60e51b81526020600482015260146024820152734e6f742063616c6c65642066726f6d204161766560601b604482015290519081900360640190fd5b6001600160a01b0385163014611621576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5e995960921b604482015290519081900360640190fd5b600060128101556116476002808b8b60008161163957fe5b905060200201356001613902565b60005b8a8110156116e157600061168b89898481811061166357fe5b905060200201358c8c8581811061167657fe5b9050602002013561377790919063ffffffff16565b90506116c78360008f8f8681811061169f57fe5b905060200201356001600160a01b03166001600160a01b0316613f4b9092919063ffffffff16565b6116d883828f8f8681811061169f57fe5b5060010161164a565b5060019b9a5050505050505050505050565b60105481565b600e5481565b600080805b6015548110156118035760006015828154811061171d57fe5b600091825260209182902060029091020154604080516370a0823160e01b81526001600160a01b038981166004830152915191909216926370a082319260248082019391829003018186803b15801561177557600080fd5b505afa158015611789573d6000803e3d6000fd5b505050506040513d602081101561179f57600080fd5b5051601580549192506117e691849081106117b657fe5b906000526020600020906002020160010154600a0a610ad6670de0b6b3a76400008461220d90919063ffffffff16565b90506117f8838263ffffffff61377716565b925050600101611704565b5092915050565b611812612209565b6000546001600160a01b03908116911614611862576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b600480601754146118a45760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b600060178190556118b3611932565b111561190d57620151806016540142101561190d576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601854600380546001600160a01b0319166001600160a01b03909216919091179055565b600061193d306116ff565b905090565b61194a612209565b6000546001600160a01b0390811691161461199a576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b600180601754146119dc5760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b600060178190556119eb611932565b1115611a45576201518060165401421015611a45576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b601854611a5a906001600160a01b031661405e565b50565b611a65612209565b6000546001600160a01b03908116911614611ab5576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b611ac7611ac06111a6565b8383612375565b5050565b611ad3612209565b6000546001600160a01b03908116911614611b23576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b60028060175414611b655760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b60006017819055611b74611932565b1115611bce576201518060165401421015611bce576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601854600180546001600160a01b0319166001600160a01b03909216919091179055565b60065481565b611c01612209565b6003546001600160a01b03908116911614611c51576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b611c59611932565b60058190556006541015611a5a5760405162461bcd60e51b815260040180806020018281038252602d815260200180614ccd602d913960400191505060405180910390fd5b6001546001600160a01b031681565b60008060006015600081548110611cc057fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015611d1457600080fd5b505afa158015611d28573d6000803e3d6000fd5b505050506040513d6020811015611d3e57600080fd5b50511115611e06576015600081548110611d5457fe5b60009182526020822060029091020154601580546001600160a01b03909216929091611d7c57fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015611dd057600080fd5b505afa158015611de4573d6000803e3d6000fd5b505050506040513d6020811015611dfa57600080fd5b50519092509050611edd565b60006015600181548110611e1657fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015611e6a57600080fd5b505afa158015611e7e573d6000803e3d6000fd5b505050506040513d6020811015611e9457600080fd5b50511115611ed6576015600181548110611eaa57fe5b6000918252602090912060029091020154601580546001600160a01b03909216916001908110611d7c57fe5b5060009050805b9091565b611ee9612209565b6000546001600160a01b03908116911614611f39576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b60058060175414611f7b5760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b60006017819055611f8a611932565b1115611fe4576201518060165401421015611fe4576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601954600a55601a54600c55601b54600d55601c54600655601d54600b55565b60085481565b600d5481565b60045481565b6002546001600160a01b031681565b600f5481565b612034612209565b6003546001600160a01b03908116911614612084576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b61208e6000611bf9565b565b612098612209565b6003546001600160a01b039081169116146120e8576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b611a5a6120f3612209565b6001806000610a0f565b612105612209565b6000546001600160a01b03908116911614612155576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556002601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b612188612209565b6000546001600160a01b039081169116146121d8576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556001601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b600a5481565b3390565b60008261221c57506000612269565b8282028284828161222957fe5b04146122665760405162461bcd60e51b8152600401808060200182810382526021815260200180614d7a6021913960400191505060405180910390fd5b90505b92915050565b600061226683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614156565b6000806000905060006122f060156000815481106122cb57fe5b906000526020600020906002020160010154600a0a600161220d90919063ffffffff16565b905060006123018160018482613078565b905061235e601560018154811061231457fe5b906000526020600020906002020160010154600a0a610ad6601560008154811061233a57fe5b906000526020600020906002020160010154600a0a8461220d90919063ffffffff16565b90508181111561236d57600192505b509091505090565b4260048190555073087f35bd241e41fc28e43f0e8c58d283dd55bd656001600160a01b031663a2e620456040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156123cb57600080fd5b505af11580156123df573d6000803e3d6000fd5b505050506040513d60208110156123f557600080fd5b5060009050816125f957601554600061240c611932565b90506000805b838110156125885786811461258057600080905060006015838154811061243557fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b15801561248957600080fd5b505afa15801561249d573d6000803e3d6000fd5b505050506040513d60208110156124b357600080fd5b5051601580549192506000916124ce919086908110610c4257fe5b905060006124e260158681548110610c7c57fe5b90508183116124f357829350612503565b612500858c856000612e42565b93505b8084111561250f578093505b831561257b57600061254c6015878154811061252757fe5b906000526020600020906002020160010154600a0a610ad660158f81548110610d0c57fe5b9050600061255d878e886000613078565b9050818111156125785760019750612578878e886000613902565b50505b505050505b600101612412565b506000612593611932565b9050600182151514156125de578281116125de5760405162461bcd60e51b815260040180806020018281038252602d815260200180614d26602d913960400191505060405180910390fd5b6125ee818463ffffffff61373516565b9450505050506126a3565b7389714d3ac9149426219a3568543200d1964101c46001600160a01b031663a2e620456040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561264857600080fd5b505af115801561265c573d6000803e3d6000fd5b505050506040513d602081101561267257600080fd5b506000905061268e600280683635c9adc5dea000006001612e42565b905080156126a15761269f816141f8565b505b505b604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29160009183916370a08231916024808301926020929190829003018186803b1580156126f957600080fd5b505afa15801561270d573d6000803e3d6000fd5b505050506040513d602081101561272357600080fd5b50519050662386f26fc1000083106128b5576000612777670de0b6b3a7640000610ad66015898154811061275357fe5b906000526020600020906002020160010154600a0a8761220d90919063ffffffff16565b905061279b620186a0610ad6610e93600a54620186a061373590919063ffffffff16565b9050601586815481106127aa57fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b1580156127fe57600080fd5b505afa158015612812573d6000803e3d6000fd5b505050506040513d602081101561282857600080fd5b505181116128b35761283e866002836000613902565b604080516370a0823160e01b815230600482015290516001600160a01b038516916370a08231916024808301926020929190829003018186803b15801561288457600080fd5b505afa158015612898573d6000803e3d6000fd5b505050506040513d60208110156128ae57600080fd5b505191505b505b8015612b2c576001600160a01b03861615612a085760006128da601054610d91613877565b905060006128f36010543a61220d90919063ffffffff16565b9050818111156129005750805b600f54819061291f90620186a090610ad690879063ffffffff61220d16565b821061294857612941620186a0610ad6600f548761220d90919063ffffffff16565b905061296f565b61296c82610f92620186a0610ad6600c54610d91888b61373590919063ffffffff16565b90505b8015612a045761298f6001600160a01b0386168a8363ffffffff61470916565b604080516370a0823160e01b815230600482015290516001600160a01b038716916370a08231916024808301926020929190829003018186803b1580156129d557600080fd5b505afa1580156129e9573d6000803e3d6000fd5b505050506040513d60208110156129ff57600080fd5b505193505b5050505b8015612b2c576000612a2c620186a0610ad6600d548561220d90919063ffffffff16565b90506000612a40838363ffffffff61373516565b90508015612a6857600154612a68906001600160a01b0386811691168363ffffffff61470916565b8115612b29576002546001600160a01b031615612b0957600254612a9f906001600160a01b0386811691168463ffffffff61470916565b60025460408051633c6b16ab60e01b81526004810185905290516001600160a01b0390921691633c6b16ab9160248082019260009290919082900301818387803b158015612aec57600080fd5b505af1158015612b00573d6000803e3d6000fd5b50505050612b29565b600154612b29906001600160a01b0386811691168463ffffffff61470916565b50505b505050505050565b60155460018215151415612c2d5760005b81811015612c2657600060158281548110612b5c57fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015612bb057600080fd5b505afa158015612bc4573d6000803e3d6000fd5b505050506040513d6020811015612bda57600080fd5b505190508015612c1d57612c1d868260158581548110612bf657fe5b60009182526020909120600290910201546001600160a01b0316919063ffffffff61470916565b50600101612b45565b5050612e3d565b60005b81811015612e3a576000612d0460158381548110612c4a57fe5b906000526020600020906002020160010154600a0a610ad6670de0b6b3a764000060158681548110612c7857fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015612ccc57600080fd5b505afa158015612ce0573d6000803e3d6000fd5b505050506040513d6020811015612cf657600080fd5b50519063ffffffff61220d16565b9050848111612dc9578015612dc457612d23858263ffffffff61373516565b9450612dc48660158481548110612d3657fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015612d8a57600080fd5b505afa158015612d9e573d6000803e3d6000fd5b505050506040513d6020811015612db457600080fd5b50516015805486908110612bf657fe5b612e31565b8415612e2b576000612e11670de0b6b3a7640000610ad660158681548110612ded57fe5b906000526020600020906002020160010154600a0a8961220d90919063ffffffff16565b905060009550612e29878260158681548110612bf657fe5b505b50612e3a565b50600101612c30565b50505b505050565b6000808083612e925760158781548110612e5857fe5b906000526020600020906002020160010154915060158681548110612e7957fe5b9060005260206000209060020201600101549050612e99565b5060129050805b6000612ec9620186a0610ad6612ebc6103e860085461226f90919063ffffffff16565b899063ffffffff61220d16565b905080612edc5760009350505050610b63565b6000612efb84600a0a610ad685600a0a8561220d90919063ffffffff16565b90506000612f0b8a8a858a613078565b9050818111612f2257600095505050505050610b63565b612f3f84600a0a610ad687600a0a8461220d90919063ffffffff16565b90506000612f5f84610ad684670de0b6b3a764000063ffffffff61220d16565b90506000612f7f620186a0610ad66008548d61220d90919063ffffffff16565b9050612f8d8c8c838c613078565b9250612fac86600a0a610ad689600a0a8661220d90919063ffffffff16565b92506000612fcc82610ad686670de0b6b3a764000063ffffffff61220d16565b9050828110612fe457509650610b6395505050505050565b6000612ffb6001600a8b900a63ffffffff61220d16565b9050600061304a6002610ad661302e61301a888d63ffffffff61373516565b610ad687610d918c8b63ffffffff61373516565b610ad686610d918b670de0b6b3a764000063ffffffff61373516565b90508381111561306657839a5050505050505050505050610b63565b9e9d5050505050505050505050505050565b60008161360557737a250d5630b4cf539739df2c5dacb4c659f2488d856130b3576130a28461475b565b9350836130b3576000915050610b63565b848614156130c5576000915050610b63565b60028614806130d45750600285145b1561335f57600080600288141561312a5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291506015878154811061310957fe5b60009182526020909120600290910201546001600160a01b0316905061316b565b6015888154811061313757fe5b60009182526020909120600290910201546001600160a01b0316915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290505b6040805160028082526060808301845292602083019080368337019050509050828160008151811061319957fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081816001815181106131c757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506060846001600160a01b031663d06ca61f89846040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561324f578181015183820152602001613237565b50505050905001935050505060006040518083038186803b15801561327357600080fd5b505afa158015613287573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156132b057600080fd5b8101908080516040519392919084600160201b8211156132cf57600080fd5b9083019060208201858111156132e457600080fd5b82518660208202830111600160201b8211171561330057600080fd5b82525081516020918201928201910280838360005b8381101561332d578181015183820152602001613315565b5050505090500160405250505090508060018251038151811061334c57fe5b60200260200101519750505050506135eb565b60006015878154811061336e57fe5b60009182526020822060029091020154601580546001600160a01b039092169350908890811061339a57fe5b600091825260209182902060029091020154604080516003808252608082019092526001600160a01b0390921693506060928201838036833701905050905082816000815181106133e757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061342957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818160028151811061345757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506060846001600160a01b031663d06ca61f89846040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156134df5781810151838201526020016134c7565b50505050905001935050505060006040518083038186803b15801561350357600080fd5b505afa158015613517573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561354057600080fd5b8101908080516040519392919084600160201b82111561355f57600080fd5b90830190602082018581111561357457600080fd5b82518660208202830111600160201b8211171561359057600080fd5b82525081516020918201928201910280838360005b838110156135bd5781810151838201526020016135a5565b505050509050016040525050509050806001825103815181106135dc57fe5b60200260200101519750505050505b846135fc576135f9846148ac565b93505b83915050610b63565b600285141580613616575060028414155b1561362357506000610b63565b600073e1578b4a32eaefcd563a9e6d0dc02a4213f673b79050806001600160a01b0316635c975abb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561367557600080fd5b505afa158015613689573d6000803e3d6000fd5b505050506040513d602081101561369f57600080fd5b50511515600114156136b5576000915050610b63565b806001600160a01b0316635c195217856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156136f957600080fd5b505afa15801561370d573d6000803e3d6000fd5b505050506040513d602081101561372357600080fd5b505193506135f9600060028682613078565b600061226683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506149eb565b600082820183811015612266576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000806137ec620186a0610ad686605a63ffffffff61220d16565b905060006137fe600280876001613078565b9050613810858363ffffffff61377716565b81111561386c576138378561382b838563ffffffff61373516565b9063ffffffff61373516565b9050836138635761384d60026001836000613078565b905061386060156001815481106117b657fe5b90505b91506122699050565b600092505050612269565b60008073169e633a2d1e6c10dd91238ba11c4a708dfef37c90506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156138cc57600080fd5b505afa1580156138e0573d6000803e3d6000fd5b505050506040513d60a08110156138f657600080fd5b50602001519250505090565b80613c7857737a250d5630b4cf539739df2c5dacb4c659f2488d8484141561392a5750611276565b60028514806139395750600284145b15613b8057600080600287141561398f5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291506015868154811061396e57fe5b60009182526020909120600290910201546001600160a01b031690506139d0565b6015878154811061399c57fe5b60009182526020909120600290910201546001600160a01b0316915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290505b604080516002808252606080830184529260208301908036833701905050905082816000815181106139fe57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508181600181518110613a2c57fe5b6001600160a01b039283166020918202929092010152613a6a908416737a250d5630b4cf539739df2c5dacb4c659f2488d600063ffffffff613f4b16565b613a986001600160a01b038416737a250d5630b4cf539739df2c5dacb4c659f2488d8863ffffffff613f4b16565b6001600160a01b038416635c11d7958760018430613abd42603c63ffffffff61377716565b6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03166001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015613b36578181015183820152602001613b1e565b505050509050019650505050505050600060405180830381600087803b158015613b5f57600080fd5b505af1158015613b73573d6000803e3d6000fd5b5050505050505050611276565b600060158681548110613b8f57fe5b60009182526020822060029091020154601580546001600160a01b0390921693509087908110613bbb57fe5b600091825260209182902060029091020154604080516003808252608082019092526001600160a01b039092169350606092820183803683370190505090508281600081518110613c0857fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110613c4a57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508181600281518110613a2c57fe5b600284141580613c89575060028314155b15613c9357611276565b60408051632e1a7d4d60e01b815260048101849052905173e1578b4a32eaefcd563a9e6d0dc02a4213f673b79173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9160248082019260009290919082900301818387803b158015613cfd57600080fd5b505af1158015613d11573d6000803e3d6000fd5b5050505060006015600081548110613d2557fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015613d7957600080fd5b505afa158015613d8d573d6000803e3d6000fd5b505050506040513d6020811015613da357600080fd5b5051604080516346f4991160e11b81523060048201526024810187905290519192506001600160a01b03841691638de93222918791604480830192602092919082900301818588803b158015613df857600080fd5b505af1158015613e0c573d6000803e3d6000fd5b50505050506040513d6020811015613e2357600080fd5b505060158054613ec4918391600090613e3857fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015613e8c57600080fd5b505afa158015613ea0573d6000803e3d6000fd5b505050506040513d6020811015613eb657600080fd5b50519063ffffffff61373516565b9350613ed560006002866000613902565b4715613f445773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b158015613f2a57600080fd5b505af1158015613f3e573d6000803e3d6000fd5b50505050505b5050611276565b801580613fd1575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015613fa357600080fd5b505afa158015613fb7573d6000803e3d6000fd5b505050506040513d6020811015613fcd57600080fd5b5051155b61400c5760405162461bcd60e51b8152600401808060200182810382526036815260200180614e9a6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612e3d908490614a45565b614066612209565b6000546001600160a01b039081169116146140b6576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b6001600160a01b0381166140fb5760405162461bcd60e51b8152600401808060200182810382526026815260200180614ca76026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce8091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600081836141e25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156141a757818101518382015260200161418f565b50505050905090810190601f1680156141d45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816141ee57fe5b0495945050505050565b604080516370a0823160e01b8152306004820152905160009173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291839183916370a0823191602480820192602092909190829003018186803b15801561425157600080fd5b505afa158015614265573d6000803e3d6000fd5b505050506040513d602081101561427b57600080fd5b505190506001601260000181905550600073b53c1a33016b2dc2ff3653530bff1848a515c8c56001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156142d957600080fd5b505afa1580156142ed573d6000803e3d6000fd5b505050506040513d602081101561430357600080fd5b5051604080516001808252818301909252919250606091906020808301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160008151811061434d57fe5b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252606091816020016020820280368337019050509050868160008151811061439857fe5b60209081029190910101526040805160018082528183019092526060918160200160208202803683370190505090506000816000815181106143d657fe5b6020026020010181815250506060604051806020016040528060008152509050846001600160a01b031663ab9c4b5d30868686308760006040518863ffffffff1660e01b815260040180886001600160a01b03166001600160a01b03168152602001806020018060200180602001876001600160a01b03166001600160a01b03168152602001806020018661ffff16815260200185810385528b818151815260200191508051906020019060200280838360005b838110156144a257818101518382015260200161448a565b5050505090500185810384528a818151815260200191508051906020019060200280838360005b838110156144e15781810151838201526020016144c9565b50505050905001858103835289818151815260200191508051906020019060200280838360005b83811015614520578181015183820152602001614508565b50505050905001858103825287818151815260200191508051906020019080838360005b8381101561455c578181015183820152602001614544565b50505050905090810190601f1680156145895780820380516001836020036101000a031916815260200191505b509b505050505050505050505050600060405180830381600087803b1580156145b157600080fd5b505af11580156145c5573d6000803e3d6000fd5b50505050600060126000600381106145d957fe5b0155604080516370a0823160e01b815230600482015290516000916001600160a01b038a16916370a0823191602480820192602092909190829003018186803b15801561462557600080fd5b505afa158015614639573d6000803e3d6000fd5b505050506040513d602081101561464f57600080fd5b505190508681116146915760405162461bcd60e51b8152600401808060200182810382526025815260200180614ddb6025913960400191505060405180910390fd5b6146a1818863ffffffff61373516565b96506000806146ae611932565b11156146fa576146d0620186a0610ad6600b548b61220d90919063ffffffff16565b905080156146fa576146e760026001836000613902565b6146f7888263ffffffff61373516565b97505b50959998505050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612e3d908490614a45565b60115460009060ff1661476f5750806111a1565b6000601560008154811061477f57fe5b6000918252602091829020600290910201546040805163bc701e7560e01b81527394b0a3d511b6ecdb17ebf877278ab030acb0a878600482015290516001600160a01b039092169263bc701e7592602480840193829003018186803b1580156147e757600080fd5b505afa1580156147fb573d6000803e3d6000fd5b505050506040513d602081101561481157600080fd5b505160408051635a920f0d60e11b81526004810186905281519293506000926001600160a01b0385169263b5241e1a9260248082019391829003018186803b15801561485c57600080fd5b505afa158015614870573d6000803e3d6000fd5b505050506040513d604081101561488657600080fd5b5051905083811061489c576000925050506111a1565b610b63848263ffffffff61373516565b60115460009060ff166148c05750806111a1565b600060156000815481106148d057fe5b6000918252602091829020600290910201546040805163bc701e7560e01b81527394b0a3d511b6ecdb17ebf877278ab030acb0a878600482015290516001600160a01b039092169263bc701e7592602480840193829003018186803b15801561493857600080fd5b505afa15801561494c573d6000803e3d6000fd5b505050506040513d602081101561496257600080fd5b50516040805163098ee15d60e01b81526004810186905281519293506000926001600160a01b0385169263098ee15d9260248082019391829003018186803b1580156149ad57600080fd5b505afa1580156149c1573d6000803e3d6000fd5b505050506040513d60408110156149d757600080fd5b50519050610b63848263ffffffff61377716565b60008184841115614a3d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156141a757818101518382015260200161418f565b505050900390565b6060614a9a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614af69092919063ffffffff16565b805190915015612e3d57808060200190516020811015614ab957600080fd5b5051612e3d5760405162461bcd60e51b815260040180806020018281038252602a815260200180614e70602a913960400191505060405180910390fd5b6060610b6384846000856060614b0b85614c6d565b614b5c576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310614b9b5780518252601f199092019160209182019101614b7c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614bfd576040519150601f19603f3d011682016040523d82523d6000602084013e614c02565b606091505b50915091508115614c16579150610b639050565b805115614c265780518082602001fd5b60405162461bcd60e51b81526020600482018181528651602484015286518793919283926044019190850190808383600083156141a757818101518382015260200161418f565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610b6357505015159291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735468697320737472617465677920686173207265616368656420697473206d6178696d756d2062616c616e6365436f6e7472616374732063616e6e6f7420696e746572616374207769746820746869732066756e6374696f6e4661696c656420746f206761696e20696e2062616c616e63652066726f6d2073656c6c696e6720746f6b656e7354696d656c6f636b206e6f7420616371756972656420666f7220746869732066756e6374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616c6c206e6f742073656e742066726f6d20746865207a732d546f6b656e004f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572466c617368206c6f616e206661696c656420746f20696e6372656173652062616c616e63654e6f20666c617368206c6f616e20617574686f72697a6564206f6e207468697320636f6e7472616374546865726520617265206e6f20746f6b656e7320696e207468697320737472617465677950657263656e742063616e6e6f742062652067726561746572207468616e20313030255361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a264697066735822122039b597b87a31ed70608a3c3ba88beb4a7c4577fd7723ee52a8c6a27bd1e0ab0564736f6c63430006060033000000000000000000000000e05d2a6b97dce9b8e59ad074c2e4b6d51a24aae30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000544b3ff2174016949e56c370808b2c05197b4aff

Deployed Bytecode

0x6080604052600436106102555760003560e01c80639d63b8f711610139578063cc403262116100b6578063d821a3381161007a578063d821a338146108c6578063e97dcb62146108db578063e9fad8ee146108f0578063f03bcd8e14610905578063f800877614610938578063f95201da1461096b5761025c565b8063cc4032621461085d578063d523733314610872578063d5344f7914610887578063d5eee8b61461089c578063d7b4be24146108b15761025c565b8063ba49848b116100fd578063ba49848b146107ba578063c5579dc0146107cf578063c57273c2146107e4578063c5f956af14610810578063c650ea59146108255761025c565b80639d63b8f714610716578063a7e712ce14610749578063b69ef8a81461075e578063b919507214610773578063b961b34f146107885761025c565b80635aa6e675116101d2578063780d9d2d11610196578063780d9d2d1461053557806387f61c811461054a5780638867517c1461055f578063920f5c84146105745780639434c910146106ec57806399840b7a146107015761025c565b80635aa6e6751461044b578063614dede814610460578063628ee6cc146104a757806365a893ae146104f75780636dbc132a146105205761025c565b80633047e762116102195780633047e762146103665780633303b8ab1461037b5780633babade2146103905780634a6818ea146103c35780635930a0a1146104055761025c565b806314aabd01146102615780631d0fa032146102965780632195c542146102bd578063234b6745146102d25780632a7b9ee4146103195761025c565b3661025c57005b600080fd5b34801561026d57600080fd5b506102946004803603602081101561028457600080fd5b50356001600160a01b0316610980565b005b3480156102a257600080fd5b506102ab610a03565b60408051918252519081900360200190f35b3480156102c957600080fd5b506102ab610a09565b3480156102de57600080fd5b506102ab600480360360808110156102f557600080fd5b506001600160a01b0381351690602081013590604081013590606001351515610a0f565b34801561032557600080fd5b5061034d6004803603604081101561033c57600080fd5b508035151590602001351515610b6b565b6040805192835260208301919091528051918290030190f35b34801561037257600080fd5b506102ab610fa5565b34801561038757600080fd5b506102ab610fab565b34801561039c57600080fd5b50610294600480360360208110156103b357600080fd5b50356001600160a01b0316610fb1565b3480156103cf57600080fd5b50610294600480360360a08110156103e657600080fd5b5080359060208101359060408101359060608101359060800135611034565b34801561041157600080fd5b5061042f6004803603602081101561042857600080fd5b503561111e565b604080516001600160a01b039092168252519081900360200190f35b34801561045757600080fd5b5061042f6111a6565b34801561046c57600080fd5b506102946004803603608081101561048357600080fd5b506001600160a01b03813516906020810135906040810135906060013515156111b5565b3480156104b357600080fd5b50610294600480360360e08110156104ca57600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c00135151561127c565b34801561050357600080fd5b5061050c611362565b604080519115158252519081900360200190f35b34801561052c57600080fd5b5061042f61136b565b34801561054157600080fd5b506102ab61137a565b34801561055657600080fd5b50610294611380565b34801561056b57600080fd5b506102ab6114a8565b34801561058057600080fd5b5061050c600480360360a081101561059757600080fd5b810190602081018135600160201b8111156105b157600080fd5b8201836020820111156105c357600080fd5b803590602001918460208302840111600160201b831117156105e457600080fd5b919390929091602081019035600160201b81111561060157600080fd5b82018360208201111561061357600080fd5b803590602001918460208302840111600160201b8311171561063457600080fd5b919390929091602081019035600160201b81111561065157600080fd5b82018360208201111561066357600080fd5b803590602001918460208302840111600160201b8311171561068457600080fd5b919390926001600160a01b0383351692604081019060200135600160201b8111156106ae57600080fd5b8201836020820111156106c057600080fd5b803590602001918460018302840111600160201b831117156106e157600080fd5b5090925090506114ae565b3480156106f857600080fd5b506102ab6116f3565b34801561070d57600080fd5b506102ab6116f9565b34801561072257600080fd5b506102ab6004803603602081101561073957600080fd5b50356001600160a01b03166116ff565b34801561075557600080fd5b5061029461180a565b34801561076a57600080fd5b506102ab611932565b34801561077f57600080fd5b50610294611942565b34801561079457600080fd5b50610294600480360360408110156107ab57600080fd5b50803590602001351515611a5d565b3480156107c657600080fd5b50610294611acb565b3480156107db57600080fd5b506102ab611bf3565b3480156107f057600080fd5b506102946004803603602081101561080757600080fd5b50351515611bf9565b34801561081c57600080fd5b5061042f611c9e565b34801561083157600080fd5b5061083a611cad565b604080516001600160a01b03909316835260208301919091528051918290030190f35b34801561086957600080fd5b50610294611ee1565b34801561087e57600080fd5b506102ab612005565b34801561089357600080fd5b506102ab61200b565b3480156108a857600080fd5b506102ab612011565b3480156108bd57600080fd5b5061042f612017565b3480156108d257600080fd5b506102ab612026565b3480156108e757600080fd5b5061029461202c565b3480156108fc57600080fd5b50610294612090565b34801561091157600080fd5b506102946004803603602081101561092857600080fd5b50356001600160a01b03166120fd565b34801561094457600080fd5b506102946004803603602081101561095b57600080fd5b50356001600160a01b0316612180565b34801561097757600080fd5b506102ab612203565b610988612209565b6000546001600160a01b039081169116146109d8576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556003601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b600c5481565b60095481565b6000610a19612209565b6003546001600160a01b03908116911614610a69576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b6000610a73611932565b11610aaf5760405162461bcd60e51b8152600401808060200182810382526024815260200180614e296024913960400191505060405180910390fd5b60018215151415610b0457610ae2620186a0610ad66007548661220d90919063ffffffff16565b9063ffffffff61226f16565b841115610b04576000610af36122b1565b9050610b026000826000612375565b505b600080610b0f611932565b905084861015610b44576000610b2f86610ad6848a63ffffffff61220d16565b9050610b3d88826000612b34565b9150610b54565b610b5087826001612b34565b8091505b610b5c611932565b6005555090505b949350505050565b600080808084610dca57610b7d6122b1565b60155490925060005b81811015610dc357838114610dbb576000809050600060158381548110610ba957fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b505160158054919250600091610c68919086908110610c4257fe5b906000526020600020906002020160010154600a0a600e5461220d90919063ffffffff16565b90506000610ca260158681548110610c7c57fe5b906000526020600020906002020160010154600a0a60095461220d90919063ffffffff16565b9050818311610cb357829350610cc3565b610cc08589856000612e42565b93505b80841115610ccf578093505b8315610db6576000610d3060158781548110610ce757fe5b906000526020600020906002020160010154600a0a610ad660158c81548110610d0c57fe5b906000526020600020906002020160010154600a0a8861220d90919063ffffffff16565b90506000610d41878b886000613078565b905081811115610db3576000610d9d60158c81548110610d5d57fe5b906000526020600020906002020160010154600a0a610ad6670de0b6b3a7640000610d91878761373590919063ffffffff16565b9063ffffffff61220d16565b9050610daf8a8263ffffffff61377716565b9950505b50505b505050505b600101610b86565b5050610dfa565b6000610de3600280683635c9adc5dea000006001612e42565b90508015610df857610df581886137d1565b91505b505b85610e0c57925060009150610f9e9050565b80610e20575060009250829150610f9e9050565b600085610eb9578115610eb4576000610e6f670de0b6b3a7640000610ad660158781548110610e4b57fe5b906000526020600020906002020160010154600a0a8661220d90919063ffffffff16565b9050610ea0620186a0610ad6610e93600a54620186a061373590919063ffffffff16565b849063ffffffff61220d16565b9050610eb0846002836000613078565b9150505b610f02565b6000610ec3611932565b1115610eff57610ef8620186a0610ad6610eeb600b54620186a061373590919063ffffffff16565b859063ffffffff61220d16565b9050610f02565b50805b6000610f12601054610d91613877565b9050610f30620186a0610ad6600f548561220d90919063ffffffff16565b8110610f6057610f52620186a0610ad6600f548561220d90919063ffffffff16565b849550955050505050610f9e565b610f70828263ffffffff61373516565b9150610f5281610f92620186a0610ad6600c548761220d90919063ffffffff16565b9063ffffffff61377716565b9250929050565b60075481565b60055481565b610fb9612209565b6000546001600160a01b03908116911614611009576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556004601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b61103c612209565b6000546001600160a01b0390811691161461108c576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b620186a085111580156110a25750620186a08411155b80156110b15750620186a08311155b80156110c05750620186a08211155b6110fb5760405162461bcd60e51b8152600401808060200182810382526023815260200180614e4d6023913960400191505060405180910390fd5b426016556005601755601994909455601a91909155601b55601c91909155601d55565b6015546000908210611177576040805162461bcd60e51b815260206004820152601960248201527f4e6f20746f6b656e206174207468617420706f736974696f6e00000000000000604482015290519081900360640190fd5b6015828154811061118457fe5b60009182526020909120600290910201546001600160a01b031690505b919050565b6000546001600160a01b031690565b826111cb6004544261373590919063ffffffff16565b1161121d576040805162461bcd60e51b815260206004820152601d60248201527f546865206c6173742074726164652077617320746f6f20726563656e74000000604482015290519081900360640190fd5b32611226612209565b6001600160a01b03161461126b5760405162461bcd60e51b815260040180806020018281038252602c815260200180614cfa602c913960400191505060405180910390fd5b611276848383612375565b50505050565b611284612209565b6000546001600160a01b039081169116146112d4576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b620186a087111580156112ea5750620186a08511155b80156112f95750620186a08311155b6113345760405162461bcd60e51b8152600401808060200182810382526023815260200180614e4d6023913960400191505060405180910390fd5b600796909655600e94909455600892909255600955600f556010556011805460ff1916911515919091179055565b60115460ff1681565b6003546001600160a01b031681565b60155490565b611388612209565b6000546001600160a01b039081169116146113d8576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b6003806017541461141a5760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b60006017819055611429611932565b1115611483576201518060165401421015611483576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601854600280546001600160a01b0319166001600160a01b03909216919091179055565b600b5481565b6012546000906001146114f25760405162461bcd60e51b8152600401808060200182810382526029815260200180614e006029913960400191505060405180910390fd5b600073b53c1a33016b2dc2ff3653530bff1848a515c8c56001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561154157600080fd5b505afa158015611555573d6000803e3d6000fd5b505050506040513d602081101561156b57600080fd5b505190506001600160a01b038116611581612209565b6001600160a01b0316146115d3576040805162461bcd60e51b81526020600482015260146024820152734e6f742063616c6c65642066726f6d204161766560601b604482015290519081900360640190fd5b6001600160a01b0385163014611621576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5e995960921b604482015290519081900360640190fd5b600060128101556116476002808b8b60008161163957fe5b905060200201356001613902565b60005b8a8110156116e157600061168b89898481811061166357fe5b905060200201358c8c8581811061167657fe5b9050602002013561377790919063ffffffff16565b90506116c78360008f8f8681811061169f57fe5b905060200201356001600160a01b03166001600160a01b0316613f4b9092919063ffffffff16565b6116d883828f8f8681811061169f57fe5b5060010161164a565b5060019b9a5050505050505050505050565b60105481565b600e5481565b600080805b6015548110156118035760006015828154811061171d57fe5b600091825260209182902060029091020154604080516370a0823160e01b81526001600160a01b038981166004830152915191909216926370a082319260248082019391829003018186803b15801561177557600080fd5b505afa158015611789573d6000803e3d6000fd5b505050506040513d602081101561179f57600080fd5b5051601580549192506117e691849081106117b657fe5b906000526020600020906002020160010154600a0a610ad6670de0b6b3a76400008461220d90919063ffffffff16565b90506117f8838263ffffffff61377716565b925050600101611704565b5092915050565b611812612209565b6000546001600160a01b03908116911614611862576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b600480601754146118a45760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b600060178190556118b3611932565b111561190d57620151806016540142101561190d576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601854600380546001600160a01b0319166001600160a01b03909216919091179055565b600061193d306116ff565b905090565b61194a612209565b6000546001600160a01b0390811691161461199a576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b600180601754146119dc5760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b600060178190556119eb611932565b1115611a45576201518060165401421015611a45576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b601854611a5a906001600160a01b031661405e565b50565b611a65612209565b6000546001600160a01b03908116911614611ab5576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b611ac7611ac06111a6565b8383612375565b5050565b611ad3612209565b6000546001600160a01b03908116911614611b23576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b60028060175414611b655760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b60006017819055611b74611932565b1115611bce576201518060165401421015611bce576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601854600180546001600160a01b0319166001600160a01b03909216919091179055565b60065481565b611c01612209565b6003546001600160a01b03908116911614611c51576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b611c59611932565b60058190556006541015611a5a5760405162461bcd60e51b815260040180806020018281038252602d815260200180614ccd602d913960400191505060405180910390fd5b6001546001600160a01b031681565b60008060006015600081548110611cc057fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015611d1457600080fd5b505afa158015611d28573d6000803e3d6000fd5b505050506040513d6020811015611d3e57600080fd5b50511115611e06576015600081548110611d5457fe5b60009182526020822060029091020154601580546001600160a01b03909216929091611d7c57fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015611dd057600080fd5b505afa158015611de4573d6000803e3d6000fd5b505050506040513d6020811015611dfa57600080fd5b50519092509050611edd565b60006015600181548110611e1657fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015611e6a57600080fd5b505afa158015611e7e573d6000803e3d6000fd5b505050506040513d6020811015611e9457600080fd5b50511115611ed6576015600181548110611eaa57fe5b6000918252602090912060029091020154601580546001600160a01b03909216916001908110611d7c57fe5b5060009050805b9091565b611ee9612209565b6000546001600160a01b03908116911614611f39576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b60058060175414611f7b5760405162461bcd60e51b8152600401808060200182810382526027815260200180614d536027913960400191505060405180910390fd5b60006017819055611f8a611932565b1115611fe4576201518060165401421015611fe4576040805162461bcd60e51b8152602060048201526015602482015274151a5b595b1bd8dac81d1a5b59481b9bdd081b595d605a1b604482015290519081900360640190fd5b50601954600a55601a54600c55601b54600d55601c54600655601d54600b55565b60085481565b600d5481565b60045481565b6002546001600160a01b031681565b600f5481565b612034612209565b6003546001600160a01b03908116911614612084576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b61208e6000611bf9565b565b612098612209565b6003546001600160a01b039081169116146120e8576040805162461bcd60e51b815260206004820152601f6024820152600080516020614d9b833981519152604482015290519081900360640190fd5b611a5a6120f3612209565b6001806000610a0f565b612105612209565b6000546001600160a01b03908116911614612155576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556002601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b612188612209565b6000546001600160a01b039081169116146121d8576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b426016556001601755601880546001600160a01b0319166001600160a01b0392909216919091179055565b600a5481565b3390565b60008261221c57506000612269565b8282028284828161222957fe5b04146122665760405162461bcd60e51b8152600401808060200182810382526021815260200180614d7a6021913960400191505060405180910390fd5b90505b92915050565b600061226683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614156565b6000806000905060006122f060156000815481106122cb57fe5b906000526020600020906002020160010154600a0a600161220d90919063ffffffff16565b905060006123018160018482613078565b905061235e601560018154811061231457fe5b906000526020600020906002020160010154600a0a610ad6601560008154811061233a57fe5b906000526020600020906002020160010154600a0a8461220d90919063ffffffff16565b90508181111561236d57600192505b509091505090565b4260048190555073087f35bd241e41fc28e43f0e8c58d283dd55bd656001600160a01b031663a2e620456040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156123cb57600080fd5b505af11580156123df573d6000803e3d6000fd5b505050506040513d60208110156123f557600080fd5b5060009050816125f957601554600061240c611932565b90506000805b838110156125885786811461258057600080905060006015838154811061243557fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b15801561248957600080fd5b505afa15801561249d573d6000803e3d6000fd5b505050506040513d60208110156124b357600080fd5b5051601580549192506000916124ce919086908110610c4257fe5b905060006124e260158681548110610c7c57fe5b90508183116124f357829350612503565b612500858c856000612e42565b93505b8084111561250f578093505b831561257b57600061254c6015878154811061252757fe5b906000526020600020906002020160010154600a0a610ad660158f81548110610d0c57fe5b9050600061255d878e886000613078565b9050818111156125785760019750612578878e886000613902565b50505b505050505b600101612412565b506000612593611932565b9050600182151514156125de578281116125de5760405162461bcd60e51b815260040180806020018281038252602d815260200180614d26602d913960400191505060405180910390fd5b6125ee818463ffffffff61373516565b9450505050506126a3565b7389714d3ac9149426219a3568543200d1964101c46001600160a01b031663a2e620456040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561264857600080fd5b505af115801561265c573d6000803e3d6000fd5b505050506040513d602081101561267257600080fd5b506000905061268e600280683635c9adc5dea000006001612e42565b905080156126a15761269f816141f8565b505b505b604080516370a0823160e01b8152306004820152905173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29160009183916370a08231916024808301926020929190829003018186803b1580156126f957600080fd5b505afa15801561270d573d6000803e3d6000fd5b505050506040513d602081101561272357600080fd5b50519050662386f26fc1000083106128b5576000612777670de0b6b3a7640000610ad66015898154811061275357fe5b906000526020600020906002020160010154600a0a8761220d90919063ffffffff16565b905061279b620186a0610ad6610e93600a54620186a061373590919063ffffffff16565b9050601586815481106127aa57fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b1580156127fe57600080fd5b505afa158015612812573d6000803e3d6000fd5b505050506040513d602081101561282857600080fd5b505181116128b35761283e866002836000613902565b604080516370a0823160e01b815230600482015290516001600160a01b038516916370a08231916024808301926020929190829003018186803b15801561288457600080fd5b505afa158015612898573d6000803e3d6000fd5b505050506040513d60208110156128ae57600080fd5b505191505b505b8015612b2c576001600160a01b03861615612a085760006128da601054610d91613877565b905060006128f36010543a61220d90919063ffffffff16565b9050818111156129005750805b600f54819061291f90620186a090610ad690879063ffffffff61220d16565b821061294857612941620186a0610ad6600f548761220d90919063ffffffff16565b905061296f565b61296c82610f92620186a0610ad6600c54610d91888b61373590919063ffffffff16565b90505b8015612a045761298f6001600160a01b0386168a8363ffffffff61470916565b604080516370a0823160e01b815230600482015290516001600160a01b038716916370a08231916024808301926020929190829003018186803b1580156129d557600080fd5b505afa1580156129e9573d6000803e3d6000fd5b505050506040513d60208110156129ff57600080fd5b505193505b5050505b8015612b2c576000612a2c620186a0610ad6600d548561220d90919063ffffffff16565b90506000612a40838363ffffffff61373516565b90508015612a6857600154612a68906001600160a01b0386811691168363ffffffff61470916565b8115612b29576002546001600160a01b031615612b0957600254612a9f906001600160a01b0386811691168463ffffffff61470916565b60025460408051633c6b16ab60e01b81526004810185905290516001600160a01b0390921691633c6b16ab9160248082019260009290919082900301818387803b158015612aec57600080fd5b505af1158015612b00573d6000803e3d6000fd5b50505050612b29565b600154612b29906001600160a01b0386811691168463ffffffff61470916565b50505b505050505050565b60155460018215151415612c2d5760005b81811015612c2657600060158281548110612b5c57fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015612bb057600080fd5b505afa158015612bc4573d6000803e3d6000fd5b505050506040513d6020811015612bda57600080fd5b505190508015612c1d57612c1d868260158581548110612bf657fe5b60009182526020909120600290910201546001600160a01b0316919063ffffffff61470916565b50600101612b45565b5050612e3d565b60005b81811015612e3a576000612d0460158381548110612c4a57fe5b906000526020600020906002020160010154600a0a610ad6670de0b6b3a764000060158681548110612c7857fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015612ccc57600080fd5b505afa158015612ce0573d6000803e3d6000fd5b505050506040513d6020811015612cf657600080fd5b50519063ffffffff61220d16565b9050848111612dc9578015612dc457612d23858263ffffffff61373516565b9450612dc48660158481548110612d3657fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015612d8a57600080fd5b505afa158015612d9e573d6000803e3d6000fd5b505050506040513d6020811015612db457600080fd5b50516015805486908110612bf657fe5b612e31565b8415612e2b576000612e11670de0b6b3a7640000610ad660158681548110612ded57fe5b906000526020600020906002020160010154600a0a8961220d90919063ffffffff16565b905060009550612e29878260158681548110612bf657fe5b505b50612e3a565b50600101612c30565b50505b505050565b6000808083612e925760158781548110612e5857fe5b906000526020600020906002020160010154915060158681548110612e7957fe5b9060005260206000209060020201600101549050612e99565b5060129050805b6000612ec9620186a0610ad6612ebc6103e860085461226f90919063ffffffff16565b899063ffffffff61220d16565b905080612edc5760009350505050610b63565b6000612efb84600a0a610ad685600a0a8561220d90919063ffffffff16565b90506000612f0b8a8a858a613078565b9050818111612f2257600095505050505050610b63565b612f3f84600a0a610ad687600a0a8461220d90919063ffffffff16565b90506000612f5f84610ad684670de0b6b3a764000063ffffffff61220d16565b90506000612f7f620186a0610ad66008548d61220d90919063ffffffff16565b9050612f8d8c8c838c613078565b9250612fac86600a0a610ad689600a0a8661220d90919063ffffffff16565b92506000612fcc82610ad686670de0b6b3a764000063ffffffff61220d16565b9050828110612fe457509650610b6395505050505050565b6000612ffb6001600a8b900a63ffffffff61220d16565b9050600061304a6002610ad661302e61301a888d63ffffffff61373516565b610ad687610d918c8b63ffffffff61373516565b610ad686610d918b670de0b6b3a764000063ffffffff61373516565b90508381111561306657839a5050505050505050505050610b63565b9e9d5050505050505050505050505050565b60008161360557737a250d5630b4cf539739df2c5dacb4c659f2488d856130b3576130a28461475b565b9350836130b3576000915050610b63565b848614156130c5576000915050610b63565b60028614806130d45750600285145b1561335f57600080600288141561312a5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291506015878154811061310957fe5b60009182526020909120600290910201546001600160a01b0316905061316b565b6015888154811061313757fe5b60009182526020909120600290910201546001600160a01b0316915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290505b6040805160028082526060808301845292602083019080368337019050509050828160008151811061319957fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081816001815181106131c757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506060846001600160a01b031663d06ca61f89846040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561324f578181015183820152602001613237565b50505050905001935050505060006040518083038186803b15801561327357600080fd5b505afa158015613287573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156132b057600080fd5b8101908080516040519392919084600160201b8211156132cf57600080fd5b9083019060208201858111156132e457600080fd5b82518660208202830111600160201b8211171561330057600080fd5b82525081516020918201928201910280838360005b8381101561332d578181015183820152602001613315565b5050505090500160405250505090508060018251038151811061334c57fe5b60200260200101519750505050506135eb565b60006015878154811061336e57fe5b60009182526020822060029091020154601580546001600160a01b039092169350908890811061339a57fe5b600091825260209182902060029091020154604080516003808252608082019092526001600160a01b0390921693506060928201838036833701905050905082816000815181106133e757fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061342957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818160028151811061345757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506060846001600160a01b031663d06ca61f89846040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156134df5781810151838201526020016134c7565b50505050905001935050505060006040518083038186803b15801561350357600080fd5b505afa158015613517573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561354057600080fd5b8101908080516040519392919084600160201b82111561355f57600080fd5b90830190602082018581111561357457600080fd5b82518660208202830111600160201b8211171561359057600080fd5b82525081516020918201928201910280838360005b838110156135bd5781810151838201526020016135a5565b505050509050016040525050509050806001825103815181106135dc57fe5b60200260200101519750505050505b846135fc576135f9846148ac565b93505b83915050610b63565b600285141580613616575060028414155b1561362357506000610b63565b600073e1578b4a32eaefcd563a9e6d0dc02a4213f673b79050806001600160a01b0316635c975abb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561367557600080fd5b505afa158015613689573d6000803e3d6000fd5b505050506040513d602081101561369f57600080fd5b50511515600114156136b5576000915050610b63565b806001600160a01b0316635c195217856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156136f957600080fd5b505afa15801561370d573d6000803e3d6000fd5b505050506040513d602081101561372357600080fd5b505193506135f9600060028682613078565b600061226683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506149eb565b600082820183811015612266576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000806137ec620186a0610ad686605a63ffffffff61220d16565b905060006137fe600280876001613078565b9050613810858363ffffffff61377716565b81111561386c576138378561382b838563ffffffff61373516565b9063ffffffff61373516565b9050836138635761384d60026001836000613078565b905061386060156001815481106117b657fe5b90505b91506122699050565b600092505050612269565b60008073169e633a2d1e6c10dd91238ba11c4a708dfef37c90506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156138cc57600080fd5b505afa1580156138e0573d6000803e3d6000fd5b505050506040513d60a08110156138f657600080fd5b50602001519250505090565b80613c7857737a250d5630b4cf539739df2c5dacb4c659f2488d8484141561392a5750611276565b60028514806139395750600284145b15613b8057600080600287141561398f5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291506015868154811061396e57fe5b60009182526020909120600290910201546001600160a01b031690506139d0565b6015878154811061399c57fe5b60009182526020909120600290910201546001600160a01b0316915073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290505b604080516002808252606080830184529260208301908036833701905050905082816000815181106139fe57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508181600181518110613a2c57fe5b6001600160a01b039283166020918202929092010152613a6a908416737a250d5630b4cf539739df2c5dacb4c659f2488d600063ffffffff613f4b16565b613a986001600160a01b038416737a250d5630b4cf539739df2c5dacb4c659f2488d8863ffffffff613f4b16565b6001600160a01b038416635c11d7958760018430613abd42603c63ffffffff61377716565b6040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03166001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015613b36578181015183820152602001613b1e565b505050509050019650505050505050600060405180830381600087803b158015613b5f57600080fd5b505af1158015613b73573d6000803e3d6000fd5b5050505050505050611276565b600060158681548110613b8f57fe5b60009182526020822060029091020154601580546001600160a01b0390921693509087908110613bbb57fe5b600091825260209182902060029091020154604080516003808252608082019092526001600160a01b039092169350606092820183803683370190505090508281600081518110613c0857fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110613c4a57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508181600281518110613a2c57fe5b600284141580613c89575060028314155b15613c9357611276565b60408051632e1a7d4d60e01b815260048101849052905173e1578b4a32eaefcd563a9e6d0dc02a4213f673b79173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291632e1a7d4d9160248082019260009290919082900301818387803b158015613cfd57600080fd5b505af1158015613d11573d6000803e3d6000fd5b5050505060006015600081548110613d2557fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015613d7957600080fd5b505afa158015613d8d573d6000803e3d6000fd5b505050506040513d6020811015613da357600080fd5b5051604080516346f4991160e11b81523060048201526024810187905290519192506001600160a01b03841691638de93222918791604480830192602092919082900301818588803b158015613df857600080fd5b505af1158015613e0c573d6000803e3d6000fd5b50505050506040513d6020811015613e2357600080fd5b505060158054613ec4918391600090613e3857fe5b600091825260209182902060029091020154604080516370a0823160e01b815230600482015290516001600160a01b03909216926370a0823192602480840193829003018186803b158015613e8c57600080fd5b505afa158015613ea0573d6000803e3d6000fd5b505050506040513d6020811015613eb657600080fd5b50519063ffffffff61373516565b9350613ed560006002866000613902565b4715613f445773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0476040518263ffffffff1660e01b81526004016000604051808303818588803b158015613f2a57600080fd5b505af1158015613f3e573d6000803e3d6000fd5b50505050505b5050611276565b801580613fd1575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015613fa357600080fd5b505afa158015613fb7573d6000803e3d6000fd5b505050506040513d6020811015613fcd57600080fd5b5051155b61400c5760405162461bcd60e51b8152600401808060200182810382526036815260200180614e9a6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612e3d908490614a45565b614066612209565b6000546001600160a01b039081169116146140b6576040805162461bcd60e51b81526020600482018190526024820152600080516020614dbb833981519152604482015290519081900360640190fd5b6001600160a01b0381166140fb5760405162461bcd60e51b8152600401808060200182810382526026815260200180614ca76026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce8091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600081836141e25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156141a757818101518382015260200161418f565b50505050905090810190601f1680156141d45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816141ee57fe5b0495945050505050565b604080516370a0823160e01b8152306004820152905160009173c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291839183916370a0823191602480820192602092909190829003018186803b15801561425157600080fd5b505afa158015614265573d6000803e3d6000fd5b505050506040513d602081101561427b57600080fd5b505190506001601260000181905550600073b53c1a33016b2dc2ff3653530bff1848a515c8c56001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156142d957600080fd5b505afa1580156142ed573d6000803e3d6000fd5b505050506040513d602081101561430357600080fd5b5051604080516001808252818301909252919250606091906020808301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160008151811061434d57fe5b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252606091816020016020820280368337019050509050868160008151811061439857fe5b60209081029190910101526040805160018082528183019092526060918160200160208202803683370190505090506000816000815181106143d657fe5b6020026020010181815250506060604051806020016040528060008152509050846001600160a01b031663ab9c4b5d30868686308760006040518863ffffffff1660e01b815260040180886001600160a01b03166001600160a01b03168152602001806020018060200180602001876001600160a01b03166001600160a01b03168152602001806020018661ffff16815260200185810385528b818151815260200191508051906020019060200280838360005b838110156144a257818101518382015260200161448a565b5050505090500185810384528a818151815260200191508051906020019060200280838360005b838110156144e15781810151838201526020016144c9565b50505050905001858103835289818151815260200191508051906020019060200280838360005b83811015614520578181015183820152602001614508565b50505050905001858103825287818151815260200191508051906020019080838360005b8381101561455c578181015183820152602001614544565b50505050905090810190601f1680156145895780820380516001836020036101000a031916815260200191505b509b505050505050505050505050600060405180830381600087803b1580156145b157600080fd5b505af11580156145c5573d6000803e3d6000fd5b50505050600060126000600381106145d957fe5b0155604080516370a0823160e01b815230600482015290516000916001600160a01b038a16916370a0823191602480820192602092909190829003018186803b15801561462557600080fd5b505afa158015614639573d6000803e3d6000fd5b505050506040513d602081101561464f57600080fd5b505190508681116146915760405162461bcd60e51b8152600401808060200182810382526025815260200180614ddb6025913960400191505060405180910390fd5b6146a1818863ffffffff61373516565b96506000806146ae611932565b11156146fa576146d0620186a0610ad6600b548b61220d90919063ffffffff16565b905080156146fa576146e760026001836000613902565b6146f7888263ffffffff61373516565b97505b50959998505050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052612e3d908490614a45565b60115460009060ff1661476f5750806111a1565b6000601560008154811061477f57fe5b6000918252602091829020600290910201546040805163bc701e7560e01b81527394b0a3d511b6ecdb17ebf877278ab030acb0a878600482015290516001600160a01b039092169263bc701e7592602480840193829003018186803b1580156147e757600080fd5b505afa1580156147fb573d6000803e3d6000fd5b505050506040513d602081101561481157600080fd5b505160408051635a920f0d60e11b81526004810186905281519293506000926001600160a01b0385169263b5241e1a9260248082019391829003018186803b15801561485c57600080fd5b505afa158015614870573d6000803e3d6000fd5b505050506040513d604081101561488657600080fd5b5051905083811061489c576000925050506111a1565b610b63848263ffffffff61373516565b60115460009060ff166148c05750806111a1565b600060156000815481106148d057fe5b6000918252602091829020600290910201546040805163bc701e7560e01b81527394b0a3d511b6ecdb17ebf877278ab030acb0a878600482015290516001600160a01b039092169263bc701e7592602480840193829003018186803b15801561493857600080fd5b505afa15801561494c573d6000803e3d6000fd5b505050506040513d602081101561496257600080fd5b50516040805163098ee15d60e01b81526004810186905281519293506000926001600160a01b0385169263098ee15d9260248082019391829003018186803b1580156149ad57600080fd5b505afa1580156149c1573d6000803e3d6000fd5b505050506040513d60408110156149d757600080fd5b50519050610b63848263ffffffff61377716565b60008184841115614a3d5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156141a757818101518382015260200161418f565b505050900390565b6060614a9a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614af69092919063ffffffff16565b805190915015612e3d57808060200190516020811015614ab957600080fd5b5051612e3d5760405162461bcd60e51b815260040180806020018281038252602a815260200180614e70602a913960400191505060405180910390fd5b6060610b6384846000856060614b0b85614c6d565b614b5c576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310614b9b5780518252601f199092019160209182019101614b7c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614bfd576040519150601f19603f3d011682016040523d82523d6000602084013e614c02565b606091505b50915091508115614c16579150610b639050565b805115614c265780518082602001fd5b60405162461bcd60e51b81526020600482018181528651602484015286518793919283926044019190850190808383600083156141a757818101518382015260200161418f565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610b6357505015159291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735468697320737472617465677920686173207265616368656420697473206d6178696d756d2062616c616e6365436f6e7472616374732063616e6e6f7420696e746572616374207769746820746869732066756e6374696f6e4661696c656420746f206761696e20696e2062616c616e63652066726f6d2073656c6c696e6720746f6b656e7354696d656c6f636b206e6f7420616371756972656420666f7220746869732066756e6374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616c6c206e6f742073656e742066726f6d20746865207a732d546f6b656e004f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572466c617368206c6f616e206661696c656420746f20696e6372656173652062616c616e63654e6f20666c617368206c6f616e20617574686f72697a6564206f6e207468697320636f6e7472616374546865726520617265206e6f20746f6b656e7320696e207468697320737472617465677950657263656e742063616e6e6f742062652067726561746572207468616e20313030255361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a264697066735822122039b597b87a31ed70608a3c3ba88beb4a7c4577fd7723ee52a8c6a27bd1e0ab0564736f6c63430006060033

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

000000000000000000000000e05d2a6b97dce9b8e59ad074c2e4b6d51a24aae30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000544b3ff2174016949e56c370808b2c05197b4aff

-----Decoded View---------------
Arg [0] : _treasury (address): 0xE05D2A6b97dce9B8e59ad074c2E4b6D51a24aAe3
Arg [1] : _staking (address): 0x0000000000000000000000000000000000000000
Arg [2] : _zsToken (address): 0x544b3FF2174016949e56C370808B2C05197b4aff

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000e05d2a6b97dce9b8e59ad074c2e4b6d51a24aae3
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 000000000000000000000000544b3ff2174016949e56c370808b2c05197b4aff


Deployed Bytecode Sourcemap

23437:40147:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;61624:180:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;61624:180:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;61624:180:0;-1:-1:-1;;;;;61624:180:0;;:::i;:::-;;24642:38;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24642:38:0;;;:::i;:::-;;;;;;;;;;;;;;;;24308:37;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24308:37:0;;;:::i;55217:1056::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;55217:1056:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;;;;;;55217:1056:0;;;;;;;;;;;;;;;;;;;;:::i;50629:4576::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;50629:4576:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;50629:4576:0;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;24113:42;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24113:42:0;;;:::i;23902:36::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;23902:36:0;;;:::i;62058:176::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62058:176:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62058:176:0;-1:-1:-1;;;;;62058:176:0;;:::i;62515:693::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62515:693:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;62515:693:0;;;;;;;;;;;;;;;;;;;;;;:::i;28126:201::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;28126:201:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;28126:201:0;;:::i;:::-;;;;-1:-1:-1;;;;;28126:201:0;;;;;;;;;;;;;;20314:89;;5:9:-1;2:2;;;27:1;24;17:12;2:2;20314:89:0;;;:::i;58021:484::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58021:484:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;;;;;;58021:484:0;;;;;;;;;;;;;;;;;;;;:::i;58912:906::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58912:906:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;58912:906:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;25278:35::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;25278:35:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;23730:29;;5:9:-1;2:2;;;27:1;24;17:12;2:2;23730:29:0;;;:::i;28011:103::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;28011:103:0;;;:::i;61816:137::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;61816:137:0;;;:::i;24502:44::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24502:44:0;;;:::i;42878:1348::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;42878:1348:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;42878:1348:0;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;42878:1348:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;42878:1348:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;42878:1348:0;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;42878:1348:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;42878:1348:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;42878:1348:0;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;42878:1348:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;42878:1348:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;42878:1348:0;;;;-1:-1:-1;;;;;42878:1348:0;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;42878:1348:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;42878:1348:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;42878:1348:0;;-1:-1:-1;42878:1348:0;-1:-1:-1;42878:1348:0;:::i;25146:35::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;25146:35:0;;;:::i;24884:36::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24884:36:0;;;:::i;28466:439::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;28466:439:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;28466:439:0;-1:-1:-1;;;;;28466:439:0;;:::i;62246:133::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62246:133:0;;;:::i;28339:115::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;28339:115:0;;;:::i;60950:139::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;60950:139:0;;;:::i;58546:253::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;58546:253:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;58546:253:0;;;;;;;;;:::i;61384:135::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;61384:135:0;;;:::i;23988:40::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;23988:40:0;;;:::i;29908:347::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;29908:347:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;29908:347:0;;;;:::i;23594:30::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;23594:30:0;;;:::i;28917:559::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;28917:559:0;;;:::i;:::-;;;;-1:-1:-1;;;;;28917:559:0;;;;;;;;;;;;;;;;;;;;;63220:332;;5:9:-1;2:2;;;27:1;24;17:12;2:2;63220:332:0;;;:::i;24206:37::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24206:37:0;;;:::i;24778:::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24778:37:0;;;:::i;23863:32::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;23863:32:0;;;:::i;23658:29::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;23658:29:0;;;:::i;25005:40::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;25005:40:0;;;:::i;29651:71::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;29651:71:0;;;:::i;29734:162::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;29734:162:0;;;:::i;61195:177::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;61195:177:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;61195:177:0;-1:-1:-1;;;;;61195:177:0;;:::i;60752:186::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;60752:186:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;60752:186:0;-1:-1:-1;;;;;60752:186:0;;:::i;24409:39::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;24409:39:0;;;:::i;61624:180::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;61726:3:::1;61709:14;:20:::0;61756:1:::1;61740:13;:17:::0;61768::::1;:28:::0;;-1:-1:-1;;;;;;61768:28:0::1;-1:-1:-1::0;;;;;61768:28:0;;;::::1;::::0;;;::::1;::::0;;61624:180::o;24642:38::-;;;;:::o;24308:37::-;;;;:::o;55217:1056::-;55333:7;27902:12;:10;:12::i;:::-;27884:14;;-1:-1:-1;;;;;27884:14:0;;;:30;;;27876:74;;;;;-1:-1:-1;;;27876:74:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;27876:74:0;;;;;;;;;;;;;;;55373:1:::1;55361:9;:7;:9::i;:::-;:13;55353:62;;;;-1:-1:-1::0;;;55353:62:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55444:4;55429:19:::0;::::1;;;55426:246;;;55477:52;23850:6;55477:31;55488:19;;55477:6;:10;;:31;;;;:::i;:::-;:35:::0;:52:::1;:35;:52;:::i;:::-;55468:6;:61;55464:197;;;55549:13;55565:17;:15;:17::i;:::-;55549:33;;55601:44;55628:1;55632:5;55639;55601:18;:44::i;:::-;55464:197;;55692:22;::::0;55748:9:::1;:7;:9::i;:::-;55729:28;;55780:6;55771;:15;55768:409;;;55802:18;55823:32;55848:6:::0;55823:20:::1;:8:::0;55836:6;55823:20:::1;:12;:20;:::i;:32::-;55802:53;;55870:47;55887:10;55899;55911:5;55870:16;:47::i;:::-;55992:10:::0;-1:-1:-1;55768:409:0::1;;;56081:44;56098:10;56110:8;56120:4;56081:16;:44::i;:::-;56157:8;56140:25;;55768:409;56214:9;:7;:9::i;:::-;56194:17;:29:::0;-1:-1:-1;56251:14:0;-1:-1:-1;27961:1:0::1;55217:1056:::0;;;;;;:::o;50629:4576::-;50721:7;;;;50981:23;50978:2174;;51031:17;:15;:17::i;:::-;51080:9;:16;51020:28;;-1:-1:-1;51063:14:0;51111:1676;51134:6;51130:1;:10;51111:1676;;;51173:8;51168:1;:13;51165:1607;;51205:19;51227:1;51205:23;;51251:12;51266:9;51276:1;51266:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;51266:43:0;;51303:4;51266:43;;;;;;-1:-1:-1;;;;;51266:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;51266:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51266:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;51266:43:0;51380:9;:12;;51266:43;;-1:-1:-1;51332:23:0;;51358:44;;51380:9;51390:1;;51380:12;;;;;;;;;;;;;;;;:21;;;51376:2;:25;51358:13;;:17;;:44;;;;:::i;:::-;51332:70;;51425:23;51451:44;51473:9;51483:1;51473:12;;;;;;;;;;;;;;;;;;:21;;;51469:2;:25;51451:13;;:17;;:44;;;;:::i;:::-;51425:70;;51587:15;51579:4;:23;51576:294;;51720:4;51706:18;;51576:294;;;51793:53;51821:1;51824:8;51834:4;51840:5;51793:27;:53::i;:::-;51779:67;;51576:294;51909:15;51895:11;:29;51892:193;;;52046:15;52032:29;;51892:193;52110:15;;52107:646;;52153:25;52181:80;52239:9;52249:1;52239:12;;;;;;;;;;;;;;;;;;:21;;;52235:2;:25;52181:49;52201:9;52211:8;52201:19;;;;;;;;;;;;;;;;;;:28;;;52197:2;:32;52181:11;:15;;:49;;;;:::i;:80::-;52153:108;;52331:16;52350:49;52367:1;52370:8;52380:11;52393:5;52350:16;:49::i;:::-;52331:68;;52440:17;52429:8;:28;52426:280;;;52489:13;52505:79;52555:9;52565:8;52555:19;;;;;;;;;;;;;;;;;;:28;;;52551:2;:32;52505:41;52541:4;52505:31;52518:17;52505:8;:12;;:31;;;;:::i;:::-;:35;:41;:35;:41;:::i;:79::-;52489:95;-1:-1:-1;52652:26:0;:15;52489:95;52652:26;:19;:26;:::i;:::-;52634:44;;52426:280;;52107:646;;;51165:1607;;;;;51142:3;;51111:1676;;;;50978:2174;;;;52878:17;52898:64;26848:1;;26804:10;52957:4;52898:27;:64::i;:::-;52878:84;-1:-1:-1;53021:13:0;;53018:123;;53072:53;53096:9;53107:17;53072:23;:53::i;:::-;53054:71;;53018:123;50978:2174;;53167:26;53164:2032;;53217:15;-1:-1:-1;53234:1:0;;-1:-1:-1;53209:27:0;;-1:-1:-1;53209:27:0;53164:2032;53341:20;53338:72;;-1:-1:-1;53389:1:0;;-1:-1:-1;53389:1:0;;-1:-1:-1;53381:13:0;;-1:-1:-1;53381:13:0;53338:72;53498:16;53536:23;53533:995;;53582:19;;53579:433;;53625:19;53647:63;53705:4;53647:53;53671:9;53681:8;53671:19;;;;;;;;;;;;;;;;;;:28;;;53667:2;:32;53647:15;:19;;:53;;;;:::i;:63::-;53625:85;;53777:75;23850:6;53777:54;53793:37;53813:16;;53801:6;53793:19;;:37;;;;:::i;:::-;53777:11;;:54;:15;:54;:::i;:75::-;53763:89;;53926:55;53943:8;26848:1;53962:11;53975:5;53926:16;:55::i;:::-;53915:66;;53579:433;;53533:995;;;54194:1;54182:9;:7;:9::i;:::-;:13;54179:334;;;54230:84;23850:6;54230:63;54250:42;54270:21;;54258:6;54250:19;;:42;;;;:::i;:::-;54230:15;;:63;:19;:63;:::i;:84::-;54219:95;;54179:334;;;-1:-1:-1;54478:15:0;54179:334;54605:14;54622:33;54644:10;;54622:17;:15;:17::i;:33::-;54605:50;;54713:52;23850:6;54713:31;54726:17;;54713:8;:12;;:31;;;;:::i;:52::-;54703:6;:62;54700:485;;54817:52;23850:6;54817:31;54830:17;;54817:8;:12;;:31;;;;:::i;:52::-;54871:8;54809:71;;;;;;;;;;54700:485;54976:20;:8;54989:6;54976:20;:12;:20;:::i;:::-;54965:31;;55062:62;55117:6;55062:50;23850:6;55062:29;55075:15;;55062:8;:12;;:29;;;;:::i;:50::-;:54;:62;:54;:62;:::i;50629:4576::-;;;;;;:::o;24113:42::-;;;;:::o;23902:36::-;;;;:::o;62058:176::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;62156:3:::1;62139:14;:20:::0;62186:1:::1;62170:13;:17:::0;62198::::1;:28:::0;;-1:-1:-1;;;;;;62198:28:0::1;-1:-1:-1::0;;;;;62198:28:0;;;::::1;::::0;;;::::1;::::0;;62058:176::o;62515:693::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;62815:6:::1;62799:12;:22;;:49;;;;;62842:6;62825:13;:23;;62799:49;:73;;;;;62866:6;62852:10;:20;;62799:73;:96;;;;;62889:6;62876:9;:19;;62799:96;62791:143;;;;-1:-1:-1::0;;;62791:143:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62962:3;62945:14;:20:::0;62992:1:::1;62976:13;:17:::0;63004:14:::1;:32:::0;;;;63047:17;:30;;;;63088:17;:29;63128:17;:28;;;;63167:17;:33;62515:693::o;28126:201::-;28226:9;:16;28191:7;;28219:23;;28211:60;;;;;-1:-1:-1;;;28211:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;28297:9;28307:4;28297:15;;;;;;;;;;;;;;;;;;;;;:21;-1:-1:-1;;;;;28297:21:0;;-1:-1:-1;28126:201:0;;;;:::o;20314:89::-;20357:7;20384:11;-1:-1:-1;;;;;20384:11:0;20314:89;:::o;58021:484::-;58292:21;58267:22;58275:13;;58267:3;:7;;:22;;;;:::i;:::-;:46;58259:88;;;;;-1:-1:-1;;;58259:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;58382:9;58366:12;:10;:12::i;:::-;-1:-1:-1;;;;;58366:25:0;;58358:82;;;;-1:-1:-1;;;58358:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58451:46;58470:9;58481:6;58489:7;58451:18;:46::i;:::-;58021:484;;;;:::o;58912:906::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;59436:6:::1;59418:14;:24;;:51;;;;;59463:6;59446:13;:23;;59418:51;:74;;;;;59486:6;59473:9;:19;;59418:74;59410:121;;;;-1:-1:-1::0;;;59410:121:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59542:19;:36:::0;;;;59589:13:::1;:25:::0;;;;59625:14:::1;:30:::0;;;;59666:13:::1;:24:::0;59701:17:::1;:29:::0;59741:10:::1;:24:::0;59776:15:::1;:34:::0;;-1:-1:-1;;59776:34:0::1;::::0;::::1;;::::0;;;::::1;::::0;;58912:906::o;25278:35::-;;;;;;:::o;23730:29::-;;;-1:-1:-1;;;;;23730:29:0;;:::o;28011:103::-;28090:9;:16;28011:103;:::o;61816:137::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;61897:1:::1;60349:5;60332:13;;:22;60324:74;;;;-1:-1:-1::0;;;60324:74:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60425:1;60409:13;:17:::0;;;60484:9:::1;:7;:9::i;:::-;:13;60481:164;;;60103:5;60573:14;;:34;60566:3;:41;;60558:75;;;::::0;;-1:-1:-1;;;60558:75:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60558:75:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;61928:17:0::2;::::0;61911:14:::2;:34:::0;;-1:-1:-1;;;;;;61911:34:0::2;-1:-1:-1::0;;;;;61928:17:0;;::::2;61911:34:::0;;;::::2;::::0;;61816:137::o;24502:44::-;;;;:::o;42878:1348::-;43148:11;:14;43118:4;;43166:1;43148:19;43140:73;;;;-1:-1:-1;;;43140:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43224:19;26291:42;-1:-1:-1;;;;;43246:74:0;;:76;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;43246:76:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;43246:76:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;43246:76:0;;-1:-1:-1;;;;;;43341:27:0;;:12;:10;:12::i;:::-;-1:-1:-1;;;;;43341:27:0;;43333:60;;;;;-1:-1:-1;;;43333:60:0;;;;;;;;;;;;-1:-1:-1;;;43333:60:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;43412:26:0;;43433:4;43412:26;43404:53;;;;;-1:-1:-1;;;43404:53:0;;;;;;;;;;;;-1:-1:-1;;;43404:53:0;;;;;;;;;;;;;;;43596:1;43579:11;43596:1;43579:14;:18;43639:44;26848:1;;43666:7;;43674:1;43666:10;;;;;;;;;;;43678:4;43639:8;:44::i;:::-;43915:9;43911:265;43930:17;;;43911:265;;;43973:19;43995:27;44010:8;;44019:1;44010:11;;;;;;;;;;;;;43995:7;;44003:1;43995:10;;;;;;;;;;;;;:14;;:27;;;;:::i;:::-;43973:49;;44041:45;44071:11;44084:1;44048:6;;44055:1;44048:9;;;;;;;;;;;;;-1:-1:-1;;;;;44048:9:0;-1:-1:-1;;;;;44041:29:0;;;:45;;;;;:::i;:::-;44105:55;44135:11;44148;44112:6;;44119:1;44112:9;;;;;;44105:55;-1:-1:-1;43949:3:0;;43911:265;;;-1:-1:-1;44214:4:0;;42878:1348;-1:-1:-1;;;;;;;;;;;42878:1348:0:o;25146:35::-;;;;:::o;24884:36::-;;;;:::o;28466:439::-;28540:7;;;28591:281;28614:9;:16;28610:20;;28591:281;;;28651:12;28666:9;28676:1;28666:12;;;;;;;;;;;;;;;;;;;;;;:18;:38;;;-1:-1:-1;;;28666:38:0;;-1:-1:-1;;;;;28666:38:0;;;;;;;;;:18;;;;;:28;;:38;;;;;;;;;;;:18;:38;;;2:2:-1;;;;27:1;24;17:12;2:2;28666:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28666:38:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;28666:38:0;28749:9;:12;;28666:38;;-1:-1:-1;28726:45:0;;28759:1;;28749:12;;;;;;;;;;;;;;;;:21;;;28745:2;:25;28726:14;28735:4;28726;:8;;:14;;;;:::i;:45::-;28719:52;-1:-1:-1;28797:18:0;:8;28719:52;28797:18;:12;:18;:::i;:::-;28786:29;-1:-1:-1;;28632:3:0;;28591:281;;;-1:-1:-1;28889:8:0;28466:439;-1:-1:-1;;28466:439:0:o;62246:133::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;62323:1:::1;60349:5;60332:13;;:22;60324:74;;;;-1:-1:-1::0;;;60324:74:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60425:1;60409:13;:17:::0;;;60484:9:::1;:7;:9::i;:::-;:13;60481:164;;;60103:5;60573:14;;:34;60566:3;:41;;60558:75;;;::::0;;-1:-1:-1;;;60558:75:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60558:75:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;62354:17:0::2;::::0;62337:14:::2;:34:::0;;-1:-1:-1;;;;;;62337:34:0::2;-1:-1:-1::0;;;;;62354:17:0;;::::2;62337:34:::0;;;::::2;::::0;;62246:133::o;28339:115::-;28379:7;28406:40;28440:4;28406:25;:40::i;:::-;28399:47;;28339:115;:::o;60950:139::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;61030:1:::1;60349:5;60332:13;;:22;60324:74;;;;-1:-1:-1::0;;;60324:74:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60425:1;60409:13;:17:::0;;;60484:9:::1;:7;:9::i;:::-;:13;60481:164;;;60103:5;60573:14;;:34;60566:3;:41;;60558:75;;;::::0;;-1:-1:-1;;;60558:75:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60558:75:0;;;;;;;;;;;;;::::1;;61063:17:::2;::::0;61044:37:::2;::::0;-1:-1:-1;;;;;61063:17:0::2;61044:18;:37::i;:::-;20616:1:::1;60950:139::o:0;58546:253::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;58742:49:::1;58761:12;:10;:12::i;:::-;58775:6;58783:7;58742:18;:49::i;:::-;58546:253:::0;;:::o;61384:135::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;61462:1:::1;60349:5;60332:13;;:22;60324:74;;;;-1:-1:-1::0;;;60324:74:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60425:1;60409:13;:17:::0;;;60484:9:::1;:7;:9::i;:::-;:13;60481:164;;;60103:5;60573:14;;:34;60566:3;:41;;60558:75;;;::::0;;-1:-1:-1;;;60558:75:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60558:75:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;61494:17:0::2;::::0;;61476:35;;-1:-1:-1;;;;;;61476:35:0::2;-1:-1:-1::0;;;;;61494:17:0;;::::2;61476:35:::0;;;::::2;::::0;;61384:135::o;23988:40::-;;;;:::o;29908:347::-;27902:12;:10;:12::i;:::-;27884:14;;-1:-1:-1;;;;;27884:14:0;;;:30;;;27876:74;;;;;-1:-1:-1;;;27876:74:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;27876:74:0;;;;;;;;;;;;;;;30138:9:::1;:7;:9::i;:::-;30118:17;:29:::0;;;30187:11:::1;::::0;-1:-1:-1;30166:32:0::1;30158:89;;;;-1:-1:-1::0;;;30158:89:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23594:30:::0;;;-1:-1:-1;;;;;23594:30:0;;:::o;28917:559::-;28971:7;28980;29128:1;29082:9;29092:1;29082:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;29082:43:0;;29119:4;29082:43;;;;;;-1:-1:-1;;;;;29082:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;29082:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29082:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;29082:43:0;:47;29079:390;;;29161:9;29171:1;29161:12;;;;;;;;;;;;;;;;;;;;:18;29182:9;:12;;-1:-1:-1;;;;;29161:18:0;;;;29182:9;;:12;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;29182:43:0;;29219:4;29182:43;;;;;;-1:-1:-1;;;;;29182:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;29182:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29182:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;29182:43:0;29145:81;;-1:-1:-1;29182:43:0;-1:-1:-1;29145:81:0;;29079:390;29292:1;29246:9;29256:1;29246:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;29246:43:0;;29283:4;29246:43;;;;;;-1:-1:-1;;;;;29246:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;29246:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;29246:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;29246:43:0;:47;29243:226;;;29325:9;29335:1;29325:12;;;;;;;;;;;;;;;;;;;;;:18;29346:9;:12;;-1:-1:-1;;;;;29325:18:0;;;;;;29346:12;;;;;29243:226;-1:-1:-1;29437:1:0;;-1:-1:-1;29437:1:0;29243:226;28917:559;;:::o;63220:332::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;63309:1:::1;60349:5;60332:13;;:22;60324:74;;;;-1:-1:-1::0;;;60324:74:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60425:1;60409:13;:17:::0;;;60484:9:::1;:7;:9::i;:::-;:13;60481:164;;;60103:5;60573:14;;:34;60566:3;:41;;60558:75;;;::::0;;-1:-1:-1;;;60558:75:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;60558:75:0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;63342:14:0::2;:17:::0;63323:16:::2;:36:::0;63388:17;;63370:15:::2;:35:::0;63433:17;;-1:-1:-1;63416:34:0;63475:17;;63461:11:::2;:31:::0;63527:17;;63503:21:::2;:41:::0;63220:332::o;24206:37::-;;;;:::o;24778:::-;;;;:::o;23863:32::-;;;;:::o;23658:29::-;;;-1:-1:-1;;;;;23658:29:0;;:::o;25005:40::-;;;;:::o;29651:71::-;27902:12;:10;:12::i;:::-;27884:14;;-1:-1:-1;;;;;27884:14:0;;;:30;;;27876:74;;;;;-1:-1:-1;;;27876:74:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;27876:74:0;;;;;;;;;;;;;;;29700:14:::1;29708:5;29700:7;:14::i;:::-;29651:71::o:0;29734:162::-;27902:12;:10;:12::i;:::-;27884:14;;-1:-1:-1;;;;;27884:14:0;;;:30;;;27876:74;;;;;-1:-1:-1;;;27876:74:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;27876:74:0;;;;;;;;;;;;;;;29855:33:::1;29864:12;:10;:12::i;:::-;29877:1;29879::::0;29882:5:::1;29855:8;:33::i;61195:177::-:0;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;61294:3:::1;61277:14;:20:::0;61324:1:::1;61308:13;:17:::0;61336::::1;:28:::0;;-1:-1:-1;;;;;;61336:28:0::1;-1:-1:-1::0;;;;;61336:28:0;;;::::1;::::0;;;::::1;::::0;;61195:177::o;60752:186::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;60853:3:::1;60836:14;:20:::0;60883:1:::1;60867:13;:17:::0;60895::::1;:28:::0;;-1:-1:-1;;;;;;60895:28:0::1;-1:-1:-1::0;;;;;60895:28:0;;;::::1;::::0;;;::::1;::::0;;60752:186::o;24409:39::-;;;;:::o;18858:106::-;18946:10;18858:106;:::o;5169:471::-;5227:7;5472:6;5468:47;;-1:-1:-1;5502:1:0;5495:8;;5468:47;5539:5;;;5543:1;5539;:5;:1;5563:5;;;;;:10;5555:56;;;;-1:-1:-1;;;5555:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5631:1;-1:-1:-1;5169:471:0;;;;;:::o;6116:132::-;6174:7;6201:39;6205:1;6208;6201:39;;;;;;;;;;;;;;;;;:3;:39::i;36829:839::-;36879:7;37111:16;37130:1;37111:20;;37142:18;37163:41;37182:9;37192:1;37182:12;;;;;;;;;;;;;;;;;;:21;;;37178:2;:25;37171:1;37163:14;;:41;;;;:::i;:::-;37142:62;-1:-1:-1;37295:16:0;37337:38;37295:16;37356:1;37142:62;37295:16;37337;:38::i;:::-;37326:49;;37397:70;37445:9;37455:1;37445:12;;;;;;;;;;;;;;;;;;:21;;;37441:2;:25;37397:39;37414:9;37424:1;37414:12;;;;;;;;;;;;;;;;;;:21;;;37410:2;:25;37397:8;:12;;:39;;;;:::i;:70::-;37386:81;;37520:10;37509:8;:21;37506:129;;;37622:1;37611:12;;37506:129;-1:-1:-1;37652:8:0;;-1:-1:-1;;36829:839:0;:::o;44566:6051::-;44685:3;44669:13;:19;;;;26627:42;-1:-1:-1;;;;;44751:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;44751:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44751:38:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;44802:12:0;;-1:-1:-1;44832:20:0;44829:2673;;44885:9;:16;44868:14;45002:9;:7;:9::i;:::-;44978:33;-1:-1:-1;45085:20:0;;45128:1581;45151:6;45147:1;:10;45128:1581;;;45190:8;45185:1;:13;45182:1512;;45222:19;45244:1;45222:23;;45268:12;45283:9;45293:1;45283:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;45283:43:0;;45320:4;45283:43;;;;;;-1:-1:-1;;;;;45283:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;45283:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45283:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;45283:43:0;45397:9;:12;;45283:43;;-1:-1:-1;45349:23:0;;45375:44;;45397:9;45407:1;;45397:12;;;;;45375:44;45349:70;;45442:23;45468:44;45490:9;45500:1;45490:12;;;;;;;45468:44;45442:70;;45604:15;45596:4;:23;45593:294;;45737:4;45723:18;;45593:294;;;45810:53;45838:1;45841:8;45851:4;45857:5;45810:27;:53::i;:::-;45796:67;;45593:294;45926:15;45912:11;:29;45909:193;;;46063:15;46049:29;;45909:193;46127:15;;46124:551;;46170:25;46198:80;46256:9;46266:1;46256:12;;;;;;;;;;;;;;;;;;:21;;;46252:2;:25;46198:49;46218:9;46228:8;46218:19;;;;;;;46198:80;46170:108;;46348:16;46367:49;46384:1;46387:8;46397:11;46410:5;46367:16;:49::i;:::-;46348:68;;46457:17;46446:8;:28;46443:185;;;46524:4;46506:22;;46559:41;46568:1;46571:8;46581:11;46594:5;46559:8;:41::i;:::-;46124:551;;;45182:1512;;;;;45159:3;;45128:1581;;;;46723:19;46745:9;:7;:9::i;:::-;46723:31;-1:-1:-1;46791:4:0;46772:23;;;;46769:244;;;46934:13;46920:11;:27;46912:85;;;;-1:-1:-1;;;46912:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47034:30;:11;47050:13;47034:30;:15;:30;:::i;:::-;47027:37;;44829:2673;;;;;;;26723:42;-1:-1:-1;;;;;47143:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;47143:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47143:38:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;47196:17:0;;-1:-1:-1;47216:64:0;26848:1;;26804:10;47275:4;47216:27;:64::i;:::-;47196:84;-1:-1:-1;47339:13:0;;47336:143;;47372:27;47389:9;47372:16;:27::i;:::-;;47336:143;44829:2673;;47582:29;;;-1:-1:-1;;;47582:29:0;;47605:4;47582:29;;;;;;26047:42;;47514:11;;26047:42;;47582:14;;:29;;;;;;;;;;;;;;26047:42;47582:29;;;2:2:-1;;;;27:1;24;17:12;2:2;47582:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47582:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;47582:29:0;;-1:-1:-1;25479:4:0;47625:15;;47622:591;;47706:19;47728:52;47775:4;47728:42;47741:9;47751:8;47741:19;;;;;;;;;;;;;;;;;;:28;;;47737:2;:32;47728:4;:8;;:42;;;;:::i;:52::-;47706:74;;47839:75;23850:6;47839:54;47855:37;47875:16;;47863:6;47855:19;;:37;;;;:::i;47839:75::-;47825:89;;47947:9;47957:8;47947:19;;;;;;;;;;;;;;;;;;;;;;:25;:50;;;-1:-1:-1;;;47947:50:0;;47991:4;47947:50;;;;;;-1:-1:-1;;;;;47947:25:0;;;;:35;;:50;;;;;;;;;;:25;:50;;;2:2:-1;;;;27:1;24;17:12;2:2;47947:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;47947:50:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;47947:50:0;47932:65;;47929:273;;48076:47;48085:8;26848:1;48104:11;48117:5;48076:8;:47::i;:::-;48157:29;;;-1:-1:-1;;;48157:29:0;;48180:4;48157:29;;;;;;-1:-1:-1;;;;;48157:14:0;;;;;:29;;;;;;;;;;;;;;:14;:29;;;2:2:-1;;;;27:1;24;17:12;2:2;48157:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;48157:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;48157:29:0;;-1:-1:-1;47929:273:0;47622:591;;48226:16;;48223:2387;;-1:-1:-1;;;;;48470:23:0;;;48467:1237;;48611:17;48631:33;48653:10;;48631:17;:15;:17::i;:33::-;48611:53;;48713:14;48730:27;48746:10;;48730:11;:15;;:27;;;;:::i;:::-;48713:44;;48817:9;48808:6;:18;48805:129;;;-1:-1:-1;48859:9:0;48805:129;49032:17;;48977:6;;49015:56;;23850:6;;49015:35;;:12;;:35;:16;:35;:::i;:56::-;49005:6;:66;49002:450;;49112:56;23850:6;49112:35;49129:17;;49112:12;:16;;:35;;;;:::i;:56::-;49095:73;;49002:450;;;49354:78;49425:6;49354:66;23850:6;49354:45;49383:15;;49354:24;49371:6;49354:12;:16;;:24;;;;:::i;:78::-;49337:95;;49002:450;49473:18;;49470:219;;49515:44;-1:-1:-1;;;;;49515:17:0;;49533:9;49544:14;49515:44;:17;:44;:::i;:::-;49597:29;;;-1:-1:-1;;;49597:29:0;;49620:4;49597:29;;;;;;-1:-1:-1;;;;;49597:14:0;;;;;:29;;;;;;;;;;;;;;:14;:29;;;2:2:-1;;;;27:1;24;17:12;2:2;49597:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49597:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;49597:29:0;;-1:-1:-1;49470:219:0;48467:1237;;;;49721:16;;49718:865;;49757:21;49781:53;23850:6;49781:32;49798:14;;49781:12;:16;;:32;;;;:::i;:53::-;49757:77;-1:-1:-1;49853:22:0;49878:31;:12;49757:77;49878:31;:16;:31;:::i;:::-;49853:56;-1:-1:-1;49931:18:0;;49928:115;;49991:15;;49973:50;;-1:-1:-1;;;;;49973:17:0;;;;49991:15;50008:14;49973:50;:17;:50;:::i;:::-;50064:17;;50061:507;;50108:14;;-1:-1:-1;;;;;50108:14:0;:28;50105:444;;50182:14;;50164:48;;-1:-1:-1;;;;;50164:17:0;;;;50182:14;50198:13;50164:48;:17;:48;:::i;:::-;50260:14;;50239:70;;;-1:-1:-1;;;50239:70:0;;;;;;;;;;-1:-1:-1;;;;;50260:14:0;;;;50239:55;;:70;;;;;50260:14;;50239:70;;;;;;;;50260:14;;50239:70;;;2:2:-1;;;;27:1;24;17:12;2:2;50239:70:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50239:70:0;;;;50105:444;;;50494:15;;50476:49;;-1:-1:-1;;;;;50476:17:0;;;;50494:15;50511:13;50476:49;:17;:49;:::i;:::-;49718:865;;;44566:6051;;;;;;:::o;56362:1647::-;56484:9;:16;56526:4;56514:16;;;;56511:356;;;56590:9;56586:249;56609:6;56605:1;:10;56586:249;;;56640:12;56655:9;56665:1;56655:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;56655:43:0;;56692:4;56655:43;;;;;;-1:-1:-1;;;;;56655:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;56655:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56655:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;56655:43:0;;-1:-1:-1;56720:8:0;;56717:103;;56752:48;56784:9;56795:4;56752:9;56762:1;56752:12;;;;;;;;;;;;;;;;;;;;;:18;-1:-1:-1;;;;;56752:18:0;;:48;;:31;:48;:::i;:::-;-1:-1:-1;56617:3:0;;56586:249;;;;56849:7;;;56511:356;56891:9;56887:1115;56910:6;56906:1;:10;56887:1115;;;56980:26;57009:84;57071:9;57081:1;57071:12;;;;;;;;;;;;;;;;;;:21;;;57067:2;:25;57009:53;57057:4;57009:9;57019:1;57009:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;57009:43:0;;57046:4;57009:43;;;;;;-1:-1:-1;;;;;57009:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;57009:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57009:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;57009:43:0;;:53;:47;:53;:::i;:84::-;56980:113;;57133:15;57111:18;:37;57108:883;;57233:22;;57230:256;;57297:39;:15;57317:18;57297:39;:19;:39;:::i;:::-;57279:57;;57359:87;57391:9;57402;57412:1;57402:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;57402:43:0;;57439:4;57402:43;;;;;;-1:-1:-1;;;;;57402:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;57402:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57402:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;57402:43:0;57359:9;:12;;57369:1;;57359:12;;;;;:87;57108:883;;;57587:19;;57584:340;;57712:16;57731:56;57782:4;57731:46;57755:9;57765:1;57755:12;;;;;;;;;;;;;;;;;;:21;;;57751:2;:25;57731:15;:19;;:46;;;;:::i;:56::-;57712:75;;57828:1;57810:19;;57852:52;57884:9;57895:8;57852:9;57862:1;57852:12;;;;;;;:52;57584:340;;57942:5;;;57108:883;-1:-1:-1;56918:3:0;;56887:1115;;;;56362:1647;;;;;:::o;37680:2467::-;37817:7;;;38154:20;38151:240;;38207:9;38217:8;38207:19;;;;;;;;;;;;;;;;;;:28;;;38190:45;;38267:9;38277:8;38267:19;;;;;;;;;;;;;;;;;;:28;;;38250:45;;38151:240;;;-1:-1:-1;38343:2:0;;-1:-1:-1;38343:2:0;38151:240;38459:18;38480:64;23850:6;38480:43;38498:24;38517:4;38498:14;;:18;;:24;;;;:::i;:::-;38480:13;;:43;:17;:43;:::i;:64::-;38459:85;-1:-1:-1;38558:15:0;38555:32;;38583:1;38576:8;;;;;;;38555:32;38633:18;38654:58;38697:14;38693:2;:18;38654:34;38673:14;38669:2;:18;38654:10;:14;;:34;;;;:::i;:58::-;38633:79;;38743:15;38761:61;38778:8;38788;38798:10;38810:11;38761:16;:61::i;:::-;38743:79;;38847:10;38836:7;:21;38833:104;;38880:1;38873:8;;;;;;;;;38833:104;38957:55;38997:14;38993:2;:18;38957:31;38973:14;38969:2;:18;38957:7;:11;;:31;;;;:::i;:55::-;38947:65;-1:-1:-1;39053:19:0;39075:33;39097:10;39075:17;38947:65;39087:4;39075:17;:11;:17;:::i;:33::-;39053:55;;39216:18;39237:54;23850:6;39237:33;39255:14;;39237:13;:17;;:33;;;;:::i;:54::-;39216:75;;39312:61;39329:8;39339;39349:10;39361:11;39312:16;:61::i;:::-;39302:71;;39394:55;39434:14;39430:2;:18;39394:31;39410:14;39406:2;:18;39394:7;:11;;:31;;;;:::i;:55::-;39384:65;-1:-1:-1;39490:17:0;39510:33;39532:10;39510:17;39384:65;39522:4;39510:17;:11;:17;:::i;:33::-;39490:53;;39570:11;39557:9;:24;39554:110;;-1:-1:-1;39642:10:0;-1:-1:-1;39635:17:0;;-1:-1:-1;;;;;;39635:17:0;39554:110;39732:19;39754:34;39762:1;39769:2;:18;;;39754:34;:14;:34;:::i;:::-;39732:56;-1:-1:-1;39799:21:0;39823:126;39947:1;39823:119;39866:75;39914:26;:10;39929;39914:26;:14;:26;:::i;:::-;39866:43;39897:11;39866:26;:11;39882:9;39866:26;:15;:26;:::i;:75::-;39823:38;39849:11;39823:21;:11;39839:4;39823:21;:15;:21;:::i;:126::-;39799:150;;39979:10;39963:13;:26;39960:149;;;40087:10;40080:17;;;;;;;;;;;;;;39960:149;40126:13;37680:2467;-1:-1:-1;;;;;;;;;;;;;;37680:2467:0:o;30267:2657::-;30382:7;30405:20;30402:2515;;25936:42;30519:10;30516:188;;30623:20;30635:7;30623:11;:20::i;:::-;30613:30;-1:-1:-1;30665:12:0;30662:27;;30686:1;30679:8;;;;;30662:27;30744:6;30735:5;:15;30732:32;;;30761:1;30754:8;;;;;30732:32;26848:1;30781:5;:16;:37;;;;26848:1;30801:6;:17;30781:37;30778:1403;;;30897:19;30935:20;26848:1;30977:5;:16;30974:312;;;26047:42;31017:26;;31089:9;31099:6;31089:17;;;;;;;;;;;;;;;;;;;;;:23;-1:-1:-1;;;;;31089:23:0;;-1:-1:-1;30974:312:0;;;31182:9;31192:5;31182:16;;;;;;;;;;;;;;;;;;;;;:22;-1:-1:-1;;;;;31182:22:0;;-1:-1:-1;26047:42:0;;-1:-1:-1;30974:312:0;31328:16;;;31342:1;31328:16;;;31304:21;31328:16;;;;;31304:21;31328:16;;;;;109:14:-1;31328:16:0;88:42:-1;144:17;;-1:-1;31328:16:0;31304:40;;31373:11;31363:4;31368:1;31363:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;31363:21:0;;;-1:-1:-1;;;;;31363:21:0;;;;;31413:12;31403:4;31408:1;31403:7;;;;;;;;;;;;;:22;-1:-1:-1;;;;;31403:22:0;;;-1:-1:-1;;;;;31403:22:0;;;;;31444:26;31473:6;-1:-1:-1;;;;;31473:20:0;;31494:7;31503:4;31473:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;31473:35:0;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;31473:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;31473:35:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;31473:35:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;15:2;7:11;;4:2;;;31:1;28;21:12;4:2;31473:35:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;31473:35:0;;421:4:-1;412:14;;;;31473:35:0;;;;;412:14:-1;31473:35:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;31473:35:0;;;;;;;;;;;31444:64;;31537:9;31566:1;31547:9;:16;:20;31537:31;;;;;;;;;;;;;;31527:41;;30778:1403;;;;;;;31677:19;31707:9;31717:5;31707:16;;;;;;;;;;;;;;;;;;;;:22;31780:9;:17;;-1:-1:-1;;;;;31707:22:0;;;;-1:-1:-1;31780:9:0;31790:6;;31780:17;;;;;;;;;;;;;;;;;;;;:23;31847:16;;;31861:1;31847:16;;;;;;;;;-1:-1:-1;;;;;31780:23:0;;;;-1:-1:-1;31823:21:0;;31847:16;;31823:21;;109:14:-1;31847:16:0;88:42:-1;144:17;;-1:-1;31847:16:0;31823:40;;31892:11;31882:4;31887:1;31882:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;31882:21:0;;;-1:-1:-1;;;;;31882:21:0;;;;;26047:42;31922:4;31927:1;31922:7;;;;;;;;;;;;;:22;-1:-1:-1;;;;;31922:22:0;;;-1:-1:-1;;;;;31922:22:0;;;;;31973:12;31963:4;31968:1;31963:7;;;;;;;;;;;;;:22;-1:-1:-1;;;;;31963:22:0;;;-1:-1:-1;;;;;31963:22:0;;;;;32004:26;32033:6;-1:-1:-1;;;;;32033:20:0;;32054:7;32063:4;32033:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;32033:35:0;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;32033:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32033:35:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;32033:35:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;15:2;7:11;;4:2;;;31:1;28;21:12;4:2;32033:35:0;;;;;;;;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;32033:35:0;;421:4:-1;412:14;;;;32033:35:0;;;;;412:14:-1;32033:35:0;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;32033:35:0;;;;;;;;;;;32004:64;;32097:9;32126:1;32107:9;:16;:20;32097:31;;;;;;;;;;;;;;32087:41;;30778:1403;;;;;32212:11;32209:144;;32315:22;32329:7;32315:13;:22::i;:::-;32305:32;;32209:144;32374:7;32367:14;;;;;30402:2515;26848:1;32415:5;:16;;:37;;;;26848:1;32435:6;:17;;32415:37;32412:55;;;-1:-1:-1;32463:1:0;32456:8;;32412:55;32584:20;26510:42;32584:57;;32659:4;-1:-1:-1;;;;;32659:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;32659:13:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32659:13:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32659:13:0;:21;;32676:4;32659:21;32656:39;;;32691:1;32684:8;;;;;32656:39;32733:4;-1:-1:-1;;;;;32733:17:0;;32751:7;32733:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;32733:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;32733:26:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32733:26:0;;-1:-1:-1;32808:44:0;32825:1;26848;32733:26;32825:1;32808:16;:44::i;4279:136::-;4337:7;4364:43;4368:1;4371;4364:43;;;;;;;;;;;;;;;;;:3;:43::i;3815:181::-;3873:7;3905:5;;;3929:6;;;;3921:46;;;;;-1:-1:-1;;;3921:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;40188:940;40278:7;;40386:39;23850:6;40386:18;:10;40401:2;40386:18;:14;:18;:::i;:39::-;40372:53;-1:-1:-1;40468:15:0;40508:52;26848:1;;40543:10;40555:4;40508:16;:52::i;:::-;40498:62;-1:-1:-1;40584:19:0;:10;40599:3;40584:19;:14;:19;:::i;:::-;40574:7;:29;40571:550;;;40674:32;40695:10;40674:16;:7;40686:3;40674:16;:11;:16;:::i;:::-;:20;:32;:20;:32;:::i;:::-;40664:42;-1:-1:-1;40755:16:0;40752:239;;40801:44;26848:1;40827;40830:7;40839:5;40801:16;:44::i;:::-;40791:54;;40907:48;40933:9;40943:1;40933:12;;;;;;;40907:48;40897:58;;40752:239;41012:7;-1:-1:-1;41005:14:0;;-1:-1:-1;41005:14:0;40571:550;41057:1;41050:8;;;;;;44268:286;44318:7;44338:31;26143:42;44338:75;;44428:15;44453:9;-1:-1:-1;;;;;44453:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;44453:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;44453:27:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;44453:27:0;;;;-1:-1:-1;;;44268:286:0;:::o;33745:3076::-;33852:20;33849:2965;;25936:42;33966:15;;;33963:30;;;33985:7;;;33963:30;26848:1;34010:5;:16;:37;;;;26848:1;34030:6;:17;34010:37;34007:1815;;;34126:19;34164:20;26848:1;34206:5;:16;34203:312;;;26047:42;34246:26;;34318:9;34328:6;34318:17;;;;;;;;;;;;;;;;;;;;;:23;-1:-1:-1;;;;;34318:23:0;;-1:-1:-1;34203:312:0;;;34411:9;34421:5;34411:16;;;;;;;;;;;;;;;;;;;;;:22;-1:-1:-1;;;;;34411:22:0;;-1:-1:-1;26047:42:0;;-1:-1:-1;34203:312:0;34557:16;;;34571:1;34557:16;;;34533:21;34557:16;;;;;34533:21;34557:16;;;;;109:14:-1;34557:16:0;88:42:-1;144:17;;-1:-1;34557:16:0;34533:40;;34602:11;34592:4;34597:1;34592:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;34592:21:0;;;-1:-1:-1;;;;;34592:21:0;;;;;34642:12;34632:4;34637:1;34632:7;;;;;;;;-1:-1:-1;;;;;34632:22:0;;;:7;;;;;;;;;:22;34734:58;;:31;;25936:42;34790:1;34734:58;:31;:58;:::i;:::-;34811:64;-1:-1:-1;;;;;34811:31:0;;25936:42;34867:7;34811:64;:31;:64;:::i;:::-;-1:-1:-1;;;;;34894:60:0;;;34955:7;34964:1;34967:4;34981;34988:11;:3;34996:2;34988:11;:7;:11;:::i;:::-;34894:106;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34894:106:0;-1:-1:-1;;;;;34894:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;34894:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;34894:106:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;34894:106:0;;;;35019:7;;;;;;34007:1815;35113:19;35143:9;35153:5;35143:16;;;;;;;;;;;;;;;;;;;;:22;35216:9;:17;;-1:-1:-1;;;;;35143:22:0;;;;-1:-1:-1;35216:9:0;35226:6;;35216:17;;;;;;;;;;;;;;;;;;;;:23;35283:16;;;35297:1;35283:16;;;;;;;;;-1:-1:-1;;;;;35216:23:0;;;;-1:-1:-1;35259:21:0;;35283:16;;35259:21;;109:14:-1;35283:16:0;88:42:-1;144:17;;-1:-1;35283:16:0;35259:40;;35328:11;35318:4;35323:1;35318:7;;;;;;;;;;;;;:21;-1:-1:-1;;;;;35318:21:0;;;-1:-1:-1;;;;;35318:21:0;;;;;26047:42;35358:4;35363:1;35358:7;;;;;;;;;;;;;:22;-1:-1:-1;;;;;35358:22:0;;;-1:-1:-1;;;;;35358:22:0;;;;;35409:12;35399:4;35404:1;35399:7;;;;;;;33849:2965;26848:1;35867:5;:16;;:37;;;;26848:1;35887:6;:17;;35867:37;35864:53;;;35908:7;;35864:53;36178:44;;;-1:-1:-1;;;36178:44:0;;;;;;;;;;26510:42;;26047;;36178:35;;:44;;;;;36034:20;;36178:44;;;;;;;;36034:20;26047:42;36178:44;;;2:2:-1;;;;27:1;24;17:12;2:2;36178:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36178:44:0;;;;36237:12;36252:9;36262:1;36252:12;;;;;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;36252:43:0;;36289:4;36252:43;;;;;;-1:-1:-1;;;;;36252:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;36252:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36252:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;36252:43:0;36310:53;;;-1:-1:-1;;;36310:53:0;;36348:4;36310:53;;;;;;;;;;;;36252:43;;-1:-1:-1;;;;;;36310:13:0;;;;;36331:7;;36310:53;;;;;36252:43;;36310:53;;;;;;;36331:7;36310:13;:53;;;2:2:-1;;;;27:1;24;17:12;2:2;36310:53:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36310:53:0;;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;36427:9:0;:12;;:53;;36475:4;;36437:1;;36427:12;;;;;;;;;;;;;;;;;;:18;:43;;;-1:-1:-1;;;36427:43:0;;36464:4;36427:43;;;;;;-1:-1:-1;;;;;36427:18:0;;;;:28;;:43;;;;;;;;;;:18;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;36427:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36427:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;36427:43:0;;:53;:47;:53;:::i;:::-;36417:63;;36518:36;36527:1;26848;36539:7;36548:5;36518:8;:36::i;:::-;36593:21;:25;36590:186;;26047:42;-1:-1:-1;;;;;36694:34:0;;36736:21;36694:66;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;36694:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;36694:66:0;;;;;36590:186;36790:7;;;;15822:622;16192:10;;;16191:62;;-1:-1:-1;16208:39:0;;;-1:-1:-1;;;16208:39:0;;16232:4;16208:39;;;;-1:-1:-1;;;;;16208:39:0;;;;;;;;;:15;;;;;;:39;;;;;;;;;;;;;;;:15;:39;;;2:2:-1;;;;27:1;24;17:12;2:2;16208:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;16208:39:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;16208:39:0;:44;16191:62;16183:152;;;;-1:-1:-1;;;16183:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16373:62;;;-1:-1:-1;;;;;16373:62:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;16373:62:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;16346:90:0;;16366:5;;16346:19;:90::i;20780:263::-;20556:12;:10;:12::i;:::-;20541:11;;-1:-1:-1;;;;;20541:11:0;;;:27;;;20533:72;;;;;-1:-1:-1;;;20533:72:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;20533:72:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;20877:22:0;::::1;20869:73;;;;-1:-1:-1::0;;;20869:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20980:11;::::0;;20958:44:::1;::::0;-1:-1:-1;;;;;20958:44:0;;::::1;::::0;20980:11;::::1;::::0;20958:44:::1;::::0;::::1;21013:11;:22:::0;;-1:-1:-1;;;;;;21013:22:0::1;-1:-1:-1::0;;;;;21013:22:0;;;::::1;::::0;;;::::1;::::0;;20780:263::o;6744:278::-;6830:7;6865:12;6858:5;6850:28;;;;-1:-1:-1;;;6850:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;6850:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6889:9;6905:1;6901;:5;;;;;;;6744:278;-1:-1:-1;;;;;6744:278:0:o;41140:1726::-;41313:29;;;-1:-1:-1;;;41313:29:0;;41336:4;41313:29;;;;;;41201:7;;26047:42;;41201:7;;26047:42;;41313:14;;:29;;;;;;;;;;;;;;;26047:42;41313:29;;;2:2:-1;;;;27:1;24;17:12;2:2;41313:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41313:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;41313:29:0;;-1:-1:-1;41404:1:0;41387:11;41399:1;41387:14;:18;;;;41492;26291:42;-1:-1:-1;;;;;41525:74:0;;:76;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;41525:76:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41525:76:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;41525:76:0;41674:16;;;41688:1;41674:16;;;;;;;;;41525:76;;-1:-1:-1;41648:23:0;;41674:16;;;;;;;109:14:-1;41674:16:0;88:42:-1;144:17;;-1:-1;41674:16:0;41648:42;;26047;41701:6;41708:1;41701:9;;;;;;;;-1:-1:-1;;;;;41701:33:0;;;;:9;;;;;;;;;;;:33;41789:16;;;41803:1;41789:16;;;;;;;;;41762:24;;41789:16;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;;-1:-1;41789:16:0;41762:43;;41829:7;41816;41824:1;41816:10;;;;;;;;;;;;;;;;;:20;41914:16;;;41928:1;41914:16;;;;;;;;;41889:22;;41914:16;;;29:2:-1;21:6;17:15;125:4;109:14;101:6;88:42;144:17;;-1:-1;41914:16:0;41889:41;;41952:1;41941:5;41947:1;41941:8;;;;;;;;;;;;;:12;;;;;42011:19;:24;;;;;;;;;;;;;;42046:6;-1:-1:-1;;;;;42046:16:0;;42071:4;42078:6;42086:7;42095:5;42110:4;42117:6;42125:1;42046:81;;;;;;;;;;;;;-1:-1:-1;;;;;42046:81:0;-1:-1:-1;;;;;42046:81:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;42046:81:0;-1:-1:-1;;;;;42046:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;42046:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;42046:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;42046:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;42046:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;42046:81:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42046:81:0;;;;42165:1;42148:11;42160:1;42148:14;;;;;;;;:18;42229:29;;;-1:-1:-1;;;42229:29:0;;42252:4;42229:29;;;;;;42212:14;;-1:-1:-1;;;;;42229:14:0;;;;;:29;;;;;;;;;;;;;;;:14;:29;;;2:2:-1;;;;27:1;24;17:12;2:2;42229:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;42229:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;42229:29:0;;-1:-1:-1;42277:18:0;;;42269:68;;;;-1:-1:-1;;;42269:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42360:21;:6;42371:9;42360:21;:10;:21;:::i;:::-;42348:33;-1:-1:-1;42392:23:0;;42433:9;:7;:9::i;:::-;:13;42430:402;;;42545:57;23850:6;42545:36;42559:21;;42545:9;:13;;:36;;;;:::i;:57::-;42527:75;-1:-1:-1;42620:19:0;;42617:204;;42700:44;26848:1;42718;42721:15;42738:5;42700:8;:44::i;:::-;42775:30;:9;42789:15;42775:30;:13;:30;:::i;:::-;42763:42;;42617:204;-1:-1:-1;42849:9:0;;41140:1726;-1:-1:-1;;;;;;;;;41140:1726:0:o;15163:177::-;15273:58;;;-1:-1:-1;;;;;15273:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;15273:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;15246:86:0;;15266:5;;15246:19;:86::i;32932:413::-;33016:15;;32993:7;;33016:15;;33013:48;;-1:-1:-1;33051:7:0;33044:14;;33013:48;33071:27;33139:9;33149:1;33139:12;;;;;;;;;;;;;;;;;;;;;;:18;33122:72;;;-1:-1:-1;;;33122:72:0;;26415:42;33122:72;;;;;;-1:-1:-1;;;;;33139:18:0;;;;33122:55;;:72;;;;;;;;;;33139:18;33122:72;;;2:2:-1;;;;27:1;24;17:12;2:2;33122:72:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33122:72:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;33122:72:0;33226:30;;;-1:-1:-1;;;33226:30:0;;;;;;;;;;33122:72;;-1:-1:-1;33207:14:0;;-1:-1:-1;;;;;33226:21:0;;;;;:30;;;;;;;;;;;:21;:30;;;2:2:-1;;;;27:1;24;17:12;2:2;33226:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33226:30:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;33226:30:0;;-1:-1:-1;33270:17:0;;;33267:34;;33298:1;33291:8;;;;;;33267:34;33318:19;:7;33330:6;33318:19;:11;:19;:::i;33357:376::-;33443:15;;33420:7;;33443:15;;33440:48;;-1:-1:-1;33478:7:0;33471:14;;33440:48;33498:27;33566:9;33576:1;33566:12;;;;;;;;;;;;;;;;;;;;;;:18;33549:72;;;-1:-1:-1;;;33549:72:0;;26415:42;33549:72;;;;;;-1:-1:-1;;;;;33566:18:0;;;;33549:55;;:72;;;;;;;;;;33566:18;33549:72;;;2:2:-1;;;;27:1;24;17:12;2:2;33549:72:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33549:72:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;33549:72:0;33655:31;;;-1:-1:-1;;;33655:31:0;;;;;;;;;;33549:72;;-1:-1:-1;33634:16:0;;-1:-1:-1;;;;;33655:22:0;;;;;:31;;;;;;;;;;;:22;:31;;;2:2:-1;;;;27:1;24;17:12;2:2;33655:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33655:31:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;33655:31:0;;-1:-1:-1;33704:21:0;:7;33655:31;33704:21;:11;:21;:::i;4718:192::-;4804:7;4840:12;4832:6;;;;4824:29;;;;-1:-1:-1;;;4824:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;4824:29:0;-1:-1:-1;;;4876:5:0;;;4718:192::o;17468:761::-;17892:23;17918:69;17946:4;17918:69;;;;;;;;;;;;;;;;;17926:5;-1:-1:-1;;;;;17918:27:0;;;:69;;;;;:::i;:::-;18002:17;;17892:95;;-1:-1:-1;18002:21:0;17998:224;;18144:10;18133:30;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;18133:30:0;18125:85;;;;-1:-1:-1;;;18125:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12152:196;12255:12;12287:53;12310:6;12318:4;12324:1;12327:12;13659;13692:18;13703:6;13692:10;:18::i;:::-;13684:60;;;;;-1:-1:-1;;;13684:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;13818:12;13832:23;13859:6;-1:-1:-1;;;;;13859:11:0;13879:8;13890:4;13859:36;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;13859:36:0;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;13817:78:0;;;;13910:7;13906:595;;;13941:10;-1:-1:-1;13934:17:0;;-1:-1:-1;13934:17:0;13906:595;14055:17;;:21;14051:439;;14318:10;14312:17;14379:15;14366:10;14362:2;14358:19;14351:44;14266:148;14454:20;;-1:-1:-1;;;14454:20:0;;;;;;;;;;;;;;;;;14461:12;;14454:20;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;9037:619:0;9097:4;9565:20;;9408:66;9605:23;;;;;;:42;;-1:-1:-1;;9632:15:0;;;9037:619;-1:-1:-1;;9037:619:0:o

Swarm Source

ipfs://39b597b87a31ed70608a3c3ba88beb4a7c4577fd7723ee52a8c6a27bd1e0ab05

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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