ETH Price: $3,890.29 (-1.04%)

Token

Ether Cards Founder (ECF)
 

Overview

Max Total Supply

10,000 ECF

Holders

2,204

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 ECF
0x404Df15B36A2Ee78112dEF9C19Dc350EC0c00Dfa
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Ethercards is an NFT monetization and gamification framework.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ethercards

Compiler Version
v0.7.3+commit.9bfce1f6

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: UNLICENSED
// produced by the Solididy File Flattener (c) David Appleton 2018 - 2020 and beyond
// contact : [email protected]
// source  : https://github.com/DaveAppleton/SolidityFlattery
// released under Apache 2.0 licence
// input  /Users/daveappleton/Documents/akombalabs/ec_traits/contracts/ethercards.sol
// flattened :  Monday, 01-Mar-21 20:16:06 UTC
pragma solidity ^0.7.3;
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}

library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;

        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) { // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({ _key: key, _value: value }));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function _remove(Map storage map, bytes32 key) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex != 0) { // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function _contains(Map storage map, bytes32 key) private view returns (bool) {
        return map._indexes[key] != 0;
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

   /**
    * @dev Returns the key-value pair stored at position `index` in the map. O(1).
    *
    * Note that there are no guarantees on the ordering of entries inside the
    * array, and it may change when more entries are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
        require(map._entries.length > index, "EnumerableMap: index out of bounds");

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     */
    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {_tryGet}.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return _remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return _contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return _length(map._inner);
    }

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

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     *
     * _Available since v3.4._
     */
    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
    }
}

interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

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;
    }
}

library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = bytes1(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}

library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

abstract contract IRNG {

    function requestRandomNumber() external virtual returns (bytes32 requestId) ;

    function isRequestComplete(bytes32 requestId) external virtual view returns (bool isCompleted) ; 

    function randomNumber(bytes32 requestId) external view virtual returns (uint256 randomNum) ;
}
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

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

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

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

            return true;
        } else {
            return false;
        }
    }

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

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

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


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

abstract contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor () internal {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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

abstract contract Ownable is Context {
    address private _owner;

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

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

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

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

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

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

interface IERC721Metadata is IERC721 {

    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
    using SafeMath for uint256;
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping (address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping (uint256 => string) private _tokenURIs;

    // Base URI
    string private _baseURI;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _holderTokens[owner].length();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, uint256(tokenId).toString()));
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a prefix in {tokenURI} to each token's URI, or
    * to the token ID if no specific URI is set for that token ID.
    */
    function baseURI() public view virtual returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _tokenOwners.contains(tokenId);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     d*
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId); // internal owner

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

    function _approve(address to, uint256 tokenId) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}

abstract contract xERC20 {
    function transfer(address,uint256) public virtual returns (bool);
    function balanceOf(address) public view virtual returns (uint256);
}

contract ethercards is ERC721 , Ownable, Pausable{
    using Strings for uint256;
    using SafeMath for uint256;

    IRNG rng;

    enum CardType { OG, Alpha, Random, Common, Founder,  Unresolved } 

    uint256   constant oStart = 10;
    uint256   constant aStart = 100;
    uint256   constant cStart = 1000;
    uint256   constant oMax = 99;
    uint256   constant aMax = 999;
    uint256   constant cMax = 9999;

    uint256   constant tr_ass_order_length = 14;
    uint256   constant tr_ass_order_mask   = 0x3ff;

    uint256   extra_trait_offset ;



    // sale conditions
    uint256   immutable sale_start;
    uint256   immutable sale_end;

    
    bool      curve_set;


    // sold AND resolved
    uint256   public oSold;
    uint256   public aSold;
    uint256   public cSold;
    // pending resolution
    uint256   public oPending;
    uint256   public aPending;
    uint256   public cPending;
    
    uint256   public nextTokenId = 10;
    // Random Stuff
    mapping (uint256 => bytes32) public randomRequests;
    uint256                      public lastRandomRequested;
    uint256                      public lastRandomProcessed;
    uint256                      public randomOneOfEight;

    // pricing stuff
    uint256[]                   og_stop;
    uint256[]                   og_price;
    uint256[]                   alpha_stop;
    uint256[]                   alpha_price;
    uint256[]                   common_stop;
    uint256[]                   common_price;
    uint256                     og_pointer;
    uint256                     alpha_pointer;
    uint256                     common_pointer;

    address payable             wallet;


    // traits stuff
    bytes32[50] public           traitHashes;
    mapping (uint256 => uint256)  traitAssignmentOrder;
    // Validation
    uint256                     startPos;
    bytes32                     tokenIdHash;


    //mapping(uint256 => uint256) serialToTokenId;
    //mapping(uint256 => uint256) tokenIdToSerial;
    mapping(uint256 => uint256) cardTraits;
    

    bytes32      public fullTokenIDHash;
    bytes32[50]  public allTokenIDHashes;


    
    bool    presale_closed;
    bool    founders_done;
    address oracle;
    address controller;

    event OG_Ordered(address buyer, uint256 price_paid, uint256 tokenID);
    event ALPHA_Ordered(address buyer, uint256 price_paid, uint256 tokenID);
    event COMMON_Ordered(address buyer, uint256 price_paid, uint256 tokenID);

    event Resolution(uint256 tokenId,uint256 chance);

    event PresaleClosed();
    event OracleSet( address oracle);
    event ControllerSet( address oracle);
    event SaleSet(uint256 start, uint256 end);
    event RandomSet(address random);
    event HashesSet();
    
    event WheresWallet(address wallet);
    event Upgrade(uint256 tokenID, uint256 position);

    event UpgradeToOG(uint256 tokenId,uint256 pos);
    event UpgradeToAlpha(uint256 tokenId,uint256 pos);

    event TraitsClaimed(uint tokenID,uint traits);
    event TraitsAlreadyClaimed(uint tokenID);
 
    
    modifier onlyOracle() {
        require(msg.sender == oracle,"Not Authorised");
        _;
    }

    modifier onlyAllowed() {
        require(
            msg.sender == owner() ||
            msg.sender == controller,"Not Authorised");
        _;
    }

    // SECTIONS IN CAPS TO RETAIN SANITY

    // CONSTRUCTOR
    // traitHashes : hashes of 50 x 200 elements

    constructor(
        IRNG _rng, 
        uint256 _start, uint256 _end,
        address payable _wallet, address _oracle
        ) ERC721("Ether Cards Founder","ECF") {

        
        rng = _rng;
        sale_start = _start;
        sale_end = _end;
        wallet = _wallet;
        oracle = _oracle;
// need events
        emit OracleSet(_oracle);
        emit SaleSet(_start,_end);
        emit RandomSet(address(_rng));
        emit WheresWallet(_wallet);
    }

    function setTraitHashes(bytes32[50] memory _traitHashes) external onlyOwner {
        traitHashes = _traitHashes;
        emit HashesSet();
    }

    function setCurve(
        uint256[] memory _og_stop, uint256[] memory _og_price,
        uint256[] memory _alpha_stop, uint256[] memory _alpha_price,
        uint256[] memory _random_stop, uint256[] memory _random_price) external onlyOwner {
        og_stop = _og_stop;
        og_price = _og_price;
        alpha_stop = _alpha_stop;
        alpha_price = _alpha_price;
        common_stop = _random_stop;
        common_price = _random_price;
        curve_set = true;
        _setBaseURI("temp.ether.cards/metadata");
    }


    // ENTRY POINT TO SALE CONTRACT
    // 0 = OG
    // 1 = ALPHA
    // 2 = RANDOM

    event Refund(address buyer, uint sent, uint purchased, uint refund);

    function buyCard(uint card_type) external payable sale_active whenNotPaused {
        buyCardInternal(card_type);
    }


    function buyCardInternal(uint card_type) internal {
        require(curve_set,"price curve not set");
        uint balance = msg.value;
        uint price;
        require(card_type < 3, "Invalid card type");
        for (uint j = 0; j < 100; j++) {
            if (card_type == 0) {
                price = OG_price();
            }  else if (card_type == 1) {
                price =  ALPHA_price();
            } else {
                price = COMMON_price();
            }
            if (balance < price) {
                if (j == 0) require(false,"Not enough sent");
                payable(wallet).transfer(msg.value.sub(balance));
                payable(msg.sender).transfer(balance);
                emit Refund(msg.sender,msg.value, j,balance);
                return;
            }
            assignCard(msg.sender,card_type);
            balance = balance.sub(price);
        }
        payable(wallet).transfer(msg.value.sub(balance));
        payable(msg.sender).transfer(balance);
        emit Refund(msg.sender,msg.value, 100,balance);
}

    // PRESALE FUNCTIONS
    // 0 - OG
    // 1 - ALPHA
    // 2 - COMMON

    function allocateManyCards(address[] memory buyers, uint256 card_type) external onlyOwner {
        require(curve_set,"price curve not set");
         require(founders_done, "mint founders first");
        require(card_type < 3 , "Invalid Card Type");
        require(!presale_closed,"Presale is over");
        for (uint j = 0; j < buyers.length; j++) {
            assignCard(buyers[j],card_type);
        }
    }
    
    function allocateCard(address buyer, uint256 card_type) external onlyOwner {
        require(curve_set,"price curve not set");
         require(founders_done, "mint founders first");
        require(card_type < 3, "Invalid Card Type");
        require((!presale_closed) || sale_is_over() ,"Presale is over");
        assignCard(buyer,card_type);
    }

    function closePresalePartOne() external onlyOwner {
        if (randomOneOfEight % 16 > 7) {
            request_random();
        }
        if (randomOneOfEight % 16 > 0) {
            request_random();
        }
    }

    function closePresalePartTwo() external onlyOwner {
        processRand();
        presale_closed = true;
        emit PresaleClosed();
    }


    // FOUNDERS CARDS

    function mintFounders(address[10] memory founders) external onlyOwner {
        require(!founders_done, "Founders already minted");
        for (uint j = 0; j < 10; j++) {
            _mint(founders[j],j);
            traitAssignmentOrder[j] = 1;
        }
        founders_done = true;
    }

    // Extra Traits

    function setExtraTraits(uint256 tokenId, uint256 bitNumber) external onlyAllowed {
        require((bitNumber >= extra_trait_offset) && (bitNumber < 256), "illegal bit number");
        cardTraits[tokenId] |=   (1 << bitNumber);
    }

    function setExtraTraitOffset(uint256 _offset) external onlyOwner {
        require(extra_trait_offset == 0, "Extra Trait offset already set");
        extra_trait_offset = _offset;
    }

    // ORACLE ACTIVATION

    function numberPending() public view returns (uint256) {
        return oPending + cPending  +aPending;
    }

    function needProcessing() public view returns (bool) {
        uint count = 15;
        
        return (oPending + cPending  +aPending > count || nextTokenId > cMax) && randomAvailable();
    }

    event ProcessRandom();
    function processRandom() external onlyOracle {
        processRand();
    }

    function processRand() internal {
        emit ProcessRandom();
        uint random = nextRandom();
    
        uint count = 16;
        uint mask = 0xffff;
        uint shift = 16;
        
        uint pending = oPending + cPending +aPending;
        for (uint i = 0; i < count; i++) {
            if (pending-- == 0) {
                return;
            }
            resolve(random & mask);
            random = random >> shift;
        }
    }

    function setOracle(address _oracle) external onlyOwner {
        oracle = _oracle;
        emit OracleSet(_oracle);
    }

   function setController(address _controller) external onlyOwner {
        controller = _controller;
        emit ControllerSet(_controller);
    }

    // WEB3 SALE SUPPORT


    function OG_remaining() public view returns (uint256) {
        return oMax - (oStart + oSold + oPending)+1;
    }

    function ALPHA_remaining() public view returns (uint256) {
        return aMax - (aStart + aSold + aPending)+1;
    }

    function COMMON_remaining() public view returns (uint256) {
        return cMax - (cStart + cSold + cPending)+1;
    }

    function OG_price() public view returns (uint256) {
        require(OG_remaining() > 0,"OG Cards sold out"); 
        return og_price[og_pointer];
    }

    function ALPHA_price() public view returns (uint256) {
        require(ALPHA_remaining() > 0,"Alpha Cards sold out"); 
        return alpha_price[alpha_pointer];        
    }

    function COMMON_price() public view returns (uint256) {
        require(COMMON_remaining() > 0,"Random Cards sold out"); 
        return common_price[common_pointer];
    }

    modifier sale_active() {
        require(block.timestamp >= sale_start,"Sale not started");
        require(block.timestamp <= sale_end,"Sale ended");
        require(nextTokenId <= cMax, "Sorry. Sold out");
        _;
    }


    function request_random_if_needed() internal {

        if (randomOneOfEight++ % 16 == 15) {
            request_random();
        }

    }

 
    function assignCard(address buyer, uint256 card_type) internal {
        require(curve_set,"price curve not set");
        
        uint common_remaining = COMMON_remaining();
        uint alpha_remaining = ALPHA_remaining();
        request_random_if_needed();
        if (card_type == 2) {
            require(common_remaining > 0, "Sorry no random tickets available");
            uint cSum = cStart+cSold+cPending;
            _mint(buyer,cSum);
            cPending++;
            common_pointer = bump(cSold , cPending , common_stop,common_pointer);
            emit COMMON_Ordered(msg.sender, msg.value,cSum);
            return;
        } else if (card_type == 1)  {
            require (alpha_remaining > 0,"Sorry - no Alpha tickets available");
            uint aSum =aStart+aSold+aPending;
            _mint(buyer,aSum);
            emit ALPHA_Ordered(msg.sender, msg.value,aSum);
            aPending++;
            alpha_pointer = bump(aSold , aPending , alpha_stop,alpha_pointer);
            return;
        }
        require (OG_remaining() > 0, "Sorry, no OG cards available");
        uint oSum = oStart + oSold+oPending;
        _mint(buyer,oSum);
        emit OG_Ordered(msg.sender, msg.value,oSum);
        oPending++;
        og_pointer = bump(oSold,oPending,og_stop,og_pointer);
        return;
    }
 
   function resolve(uint256 random) internal {
        //bool upgrade;
        uint256 card_pos;
        //uint256 draw_pos;  // let's not get them confused
        uint256 r = random;
        if (cPending > 0) {
            card_pos = cStart + cSold++;
            cPending--;
        } else if (aPending > 0) {
            card_pos = aStart + aSold++;
            aPending--;
        } else if (oPending > 0) {
            card_pos = oStart+oSold++;
            oPending--;
        }   else {
            return; // NOTHING TO DO
        }
        uint256 chance = (r & tr_ass_order_mask)+1;       
        traitAssignmentOrder[card_pos] = chance;
        emit Resolution(card_pos,chance);
    }

    function bump(uint sold, uint pending, uint[] memory stop, uint pointer) internal pure returns (uint256) {
        if (pointer == stop.length - 1) return pointer; 
        if (sold + pending > stop[pointer]) {
            return pointer + 1;
        }
        return pointer;
    }
    
    function mintTheRest(uint card_type, address target) external onlyOwner {
        require(sale_is_over(), "not until it's over");
        require(card_type < 3,"invalid card type");
        uint remaining;
        uint toMint = 50;
        if (card_type == 0) remaining = OG_remaining();
        else if (card_type == 1) remaining = ALPHA_remaining();
        else if (card_type == 2) {
            remaining = COMMON_remaining();
            toMint = 30;
        }
        remaining = Math.min(remaining,toMint);
        for (uint j = 0; j < remaining; j++) {
            assignCard(target,card_type);
        }
    }


  
    function setSimpleHash200(uint pos,bytes32 hashX) external onlyAllowed {        
        allTokenIDHashes[pos] = hashX;
    }

    function hash10k(uint256[10000] memory data) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(data));
    }

    function hash200(uint256[200] memory data) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(data));
    }

    // ensures that the hashes are all correct
    function checkSimpleHash200( uint[10000] calldata input) public view returns (bool) {
        uint256[200] memory data;
        for (uint pos = 0; pos < 50; pos++){  
            for (uint j = 0; j < 200; j++) {
                data[j] = input[j+pos*200];
            }
            bytes32 h32 = hash200(data);
            if(allTokenIDHashes[pos]!= h32) {
                return (false);
            }
        }
        return (true);
    }

    function getTokenIDPosition(uint tokenID, uint[10000] calldata tokenIdArray) external pure returns (uint blockOf200, uint position) {
        for (uint j = 0; j < 100000; j++) {
            if (tokenID == tokenIdArray[j]) 
                return (j/200,j%200);
        }
        require(false,"Not Found");
    }

    function verifyTokenAt(uint256 position, uint[10000] calldata tokenIdArray) public view returns (bool) {
        require (position < 10000,"invalid position") ;
        if (position < 11) return true; // founder or first OG
        if (position == 100) return true; // First Alpha
        if (position == 1000) return true; // First Common
        uint tokenId = tokenIdArray[position];
        uint prevToken = tokenIdArray[position-1];
        require(_exists(tokenId),"Token does not exist");
        require(_exists(prevToken),"Prev Token does not exist");
        require(cardType(tokenId) == cardType(prevToken),"different types of card");
        if (traitAssignmentOrder[tokenId] > traitAssignmentOrder[prevToken]) return true;
        if (traitAssignmentOrder[tokenId] < traitAssignmentOrder[prevToken]) return false;
        return (tokenId > prevToken );
    }

    function revealTokenAt(uint256 hashBlock, uint256 hashBlockPos,uint256[200] memory _tokenIds, uint256[200] memory _traits) external {
        require(hash200(_tokenIds)==allTokenIDHashes[hashBlock],"IDs in wrong order");
        require(hash200(_traits)==traitHashes[hashBlock],"Traits in wrong order");
 
        uint tokenID = _tokenIds[hashBlockPos];
        require(ownerOf(tokenID) == msg.sender,"Not your token");
        if (cardTraits[tokenID] == 0) {
            cardTraits[tokenID] = _traits[hashBlockPos];
            emit TraitsClaimed(tokenID,_traits[hashBlockPos]);
        } else {
            emit TraitsAlreadyClaimed(tokenID);
        }       
    }

    event TraitSet(uint pos,uint256 tokenId, uint256 traits);

    function randomAvailable() public view returns (bool) {
        return (lastRandomRequested > lastRandomProcessed) && rng.isRequestComplete(randomRequests[lastRandomProcessed]);
    }

    function nextRandom() internal returns (uint256) {
        require(randomAvailable(),"Nothing to process");
        return rng.randomNumber(randomRequests[lastRandomProcessed++]);
    }

    function request_random() internal {
        randomRequests[lastRandomRequested++] = rng.requestRandomNumber();
    }

    function request_another_random() external onlyOwner {
        request_random();
    }

    // View Function to get graphic properties

    function isCardResolved(uint256 tokenId) public view returns (bool) {
        return traitAssignmentOrder[tokenId] > 0;
    }


    function fullTrait(uint256 tokenId) external view returns (uint256) {
        return cardTraits[tokenId];
    }

    function cardType(uint256 serial) public view returns(CardType) {
        if (!isCardResolved(serial)) return CardType.Unresolved;
        if (serial < oStart) return CardType.Founder;
        if (serial < aStart) return CardType.OG;
        if (serial < cStart) return CardType.Alpha;
        return CardType.Common;
    }

     function traitAssignment(uint256 tokenId) external view returns (uint256) {
        return traitAssignmentOrder[tokenId];
    }

  
    function OG_next() external view returns (uint256 left, uint256 nextPrice) {
        return CARD_next(og_stop, og_price, oSold,oPending,og_pointer);
    }

    function ALPHA_next() external view returns (uint256 left, uint256 nextPrice) {
            return CARD_next(alpha_stop, alpha_price, aSold,aPending,alpha_pointer);
    }
    function RANDOM_next() external view returns (uint256 left, uint256 nextPrice) {
            return CARD_next(common_stop, common_price, cSold,cPending,common_pointer);
    }

    function CARD_next(uint256[] storage stop, uint256[] memory price, uint256 sold, uint256 pending, uint256 pointer) internal view returns (uint256 left, uint256 nextPrice) {
        left = stop[pointer] - (sold + pending);
        if (pointer < stop.length - 1)
            nextPrice = price[pointer+1];
        else
            nextPrice = price[pointer];
    }

        function drain(xERC20 token) external onlyOwner {
        if (address(token) == 0x0000000000000000000000000000000000000000) {
            payable(owner()).transfer(address(this).balance);
        } else {
            token.transfer(owner(),token.balanceOf(address(this)));
        }
    }

    bool _FuzeBlown;
    // after finalization the images will be assigned to match the trait data
    // but due to onboarding more artists we will have a late assignment.
    // when it is proven OK we burn

    // should be of the format ipfs://<hash>/path
    function setDataFolder(string memory _baseURI) external onlyAllowed {
        require(!_FuzeBlown,"This data can no longer be changed");
        _setBaseURI(_baseURI);
    }

    function burnDataFolder() external onlyAllowed {
        _FuzeBlown = true;
    }

    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        CardType ct = cardType(tokenId);
        if (ct == CardType.Unresolved) {
            return "https://temp.ether.cards/metadata/Unresolved";
        }
        // reformat to directory structure as below
        string memory folder = (tokenId % 100).toString(); 
        string memory file = tokenId.toString();
        string memory slash = "/";
        return string(abi.encodePacked(baseURI(),folder,slash,file,".json"));
    }

    /// 1 ... 10000
    /// 1 - 100 / 1 - 100

    function is_sale_on() external view returns (bool) {
        if (sale_is_over()) return false;
        if (block.timestamp < sale_start) return false;
        if (nextTokenId > cMax) return false;
        return true;
    }

    function TokenExists(uint tokenId) external view returns (bool) {
        return _exists(tokenId);
    }
    
    uint launch_date = 1616072400;

    function sale_is_over() public view returns (bool) {
        return (block.timestamp > sale_end);
    }
    
    function how_long_more() public view returns (uint Days, uint Hours, uint Minutes, uint Seconds) {
        require(block.timestamp < launch_date,"Missed It");
        uint gap = launch_date - block.timestamp;
        Days = gap / (24 * 60 * 60);
        gap = gap %  (24 * 60 * 60);
        Hours = gap / (60 * 60);
        gap = gap % (60 * 60);
        Minutes = gap / 60;
        Seconds = gap % 60;
        return (Days,Hours,Minutes,Seconds);
    }

    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        require(!paused(), "ERC721Pausable: token transfer while paused");
    }

    function pause() external onlyAllowed {
        _pause();
    }

    function unpause() external onlyAllowed {
        _unpause();
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IRNG","name":"_rng","type":"address"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"},{"internalType":"address payable","name":"_wallet","type":"address"},{"internalType":"address","name":"_oracle","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"price_paid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"ALPHA_Ordered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"price_paid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"COMMON_Ordered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"ControllerSet","type":"event"},{"anonymous":false,"inputs":[],"name":"HashesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"price_paid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"OG_Ordered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"OracleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[],"name":"PresaleClosed","type":"event"},{"anonymous":false,"inputs":[],"name":"ProcessRandom","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"random","type":"address"}],"name":"RandomSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"sent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"purchased","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refund","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"chance","type":"uint256"}],"name":"Resolution","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"end","type":"uint256"}],"name":"SaleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"traits","type":"uint256"}],"name":"TraitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"}],"name":"TraitsAlreadyClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"traits","type":"uint256"}],"name":"TraitsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"position","type":"uint256"}],"name":"Upgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"}],"name":"UpgradeToAlpha","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pos","type":"uint256"}],"name":"UpgradeToOG","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"}],"name":"WheresWallet","type":"event"},{"inputs":[],"name":"ALPHA_next","outputs":[{"internalType":"uint256","name":"left","type":"uint256"},{"internalType":"uint256","name":"nextPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ALPHA_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ALPHA_remaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COMMON_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COMMON_remaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OG_next","outputs":[{"internalType":"uint256","name":"left","type":"uint256"},{"internalType":"uint256","name":"nextPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OG_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OG_remaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RANDOM_next","outputs":[{"internalType":"uint256","name":"left","type":"uint256"},{"internalType":"uint256","name":"nextPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TokenExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aSold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTokenIDHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"card_type","type":"uint256"}],"name":"allocateCard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"buyers","type":"address[]"},{"internalType":"uint256","name":"card_type","type":"uint256"}],"name":"allocateManyCards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnDataFolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"card_type","type":"uint256"}],"name":"buyCard","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"cPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cSold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"serial","type":"uint256"}],"name":"cardType","outputs":[{"internalType":"enum ethercards.CardType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[10000]","name":"input","type":"uint256[10000]"}],"name":"checkSimpleHash200","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closePresalePartOne","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closePresalePartTwo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract xERC20","name":"token","type":"address"}],"name":"drain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fullTokenIDHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"fullTrait","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256[10000]","name":"tokenIdArray","type":"uint256[10000]"}],"name":"getTokenIDPosition","outputs":[{"internalType":"uint256","name":"blockOf200","type":"uint256"},{"internalType":"uint256","name":"position","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256[10000]","name":"data","type":"uint256[10000]"}],"name":"hash10k","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256[200]","name":"data","type":"uint256[200]"}],"name":"hash200","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"how_long_more","outputs":[{"internalType":"uint256","name":"Days","type":"uint256"},{"internalType":"uint256","name":"Hours","type":"uint256"},{"internalType":"uint256","name":"Minutes","type":"uint256"},{"internalType":"uint256","name":"Seconds","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isCardResolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"is_sale_on","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRandomProcessed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRandomRequested","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[10]","name":"founders","type":"address[10]"}],"name":"mintFounders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"card_type","type":"uint256"},{"internalType":"address","name":"target","type":"address"}],"name":"mintTheRest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"needProcessing","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oSold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"randomAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomOneOfEight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"randomRequests","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"request_another_random","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"hashBlock","type":"uint256"},{"internalType":"uint256","name":"hashBlockPos","type":"uint256"},{"internalType":"uint256[200]","name":"_tokenIds","type":"uint256[200]"},{"internalType":"uint256[200]","name":"_traits","type":"uint256[200]"}],"name":"revealTokenAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sale_is_over","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_og_stop","type":"uint256[]"},{"internalType":"uint256[]","name":"_og_price","type":"uint256[]"},{"internalType":"uint256[]","name":"_alpha_stop","type":"uint256[]"},{"internalType":"uint256[]","name":"_alpha_price","type":"uint256[]"},{"internalType":"uint256[]","name":"_random_stop","type":"uint256[]"},{"internalType":"uint256[]","name":"_random_price","type":"uint256[]"}],"name":"setCurve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setDataFolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"}],"name":"setExtraTraitOffset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"bitNumber","type":"uint256"}],"name":"setExtraTraits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pos","type":"uint256"},{"internalType":"bytes32","name":"hashX","type":"bytes32"}],"name":"setSimpleHash200","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[50]","name":"_traitHashes","type":"bytes32[50]"}],"name":"setTraitHashes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"traitAssignment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"traitHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"position","type":"uint256"},{"internalType":"uint256[10000]","name":"tokenIdArray","type":"uint256[10000]"}],"name":"verifyTokenAt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60c0604052600a6014556360534ed0608e553480156200001e57600080fd5b5060405162005e7e38038062005e7e833981810160405260a08110156200004457600080fd5b508051602080830151604080850151606086015160809096015182518084018452601381527f457468657220436172647320466f756e64657200000000000000000000000000818701528351808501909452600384526222a1a360e91b958401959095529495929490939091620000c26301ffc9a760e01b620002d5565b8151620000d79060069060208501906200035e565b508051620000ed9060079060208401906200035e565b50620001006380ac58cd60e01b620002d5565b62000112635b5e139f60e01b620002d5565b6200012463780e9d6360e01b620002d5565b5060009050620001336200035a565b600a80546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600a805460ff60a01b19169055600b80546001600160a01b03199081166001600160a01b0388811691909117909255608086905260a085905260228054909116848316179055608c805462010000600160b01b0319166201000092841692830217905560408051918252517f3f32684a32a11dabdbb8c0177de80aa3ae36a004d75210335b49e544e48cd0aa916020908290030190a1604080518581526020810185905281517fd842e47c53c997128a412004c38f600cb1be726ed67bf5728c437e4f8278b87e929181900390910190a1604080516001600160a01b038716815290517fcafa7605369906005d1af24081d822876a61a14c32d359cb5b4a546748858ec09181900360200190a1604080516001600160a01b038416815290517f368d32a0fbe4cc525a449977f6037b48bdc3748012a35c39f4c39061a2adc6b49181900360200190a15050505050620003fa565b6001600160e01b0319808216141562000335576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620003a157805160ff1916838001178555620003d1565b82800160010185558215620003d1579182015b82811115620003d1578251825591602001919060010190620003b4565b50620003df929150620003e3565b5090565b5b80821115620003df5760008155600101620003e4565b60805160a051615a5662000428600039806120ca528061315a5250806130f25280613d1c5250615a566000f3fe6080604052600436106104895760003560e01c806375794a3c11610255578063b6bd11e111610144578063ece53132116100c1578063f4e75f2b11610085578063f4e75f2b146115af578063f5dfd534146115e8578063f849688e146115fd578063f965e0351461162d578063fcf49adf14611642578063fdc086ec1461168d57610489565b8063ece53132146114f4578063ed87968814611527578063ee31991d14611552578063f014095714611567578063f2fde38b1461157c57610489565b8063c952316111610108578063c9523161146113a0578063ca067ad014611450578063d688a31d1461147a578063e8022449146114a4578063e985e9c5146114b957610489565b8063b6bd11e114610f3b578063b88d4fde14610f50578063b91dc1ea14611021578063c70f5eaa14611359578063c87b56dd1461137657610489565b80638f950101116101d2578063969bd8a411610196578063969bd8a414610e455780639a6be11614610e5a5780639bfb5ca714610e8a578063a22cb46514610e9f578063ac80c3ca14610eda57610489565b80638f95010114610d0d5780639102235514610d37578063924868c514610de857806392eefe9b14610dfd57806395d89b4114610e3057610489565b80637f015416116102195780637f01541614610c8f5780638456cb5914610ca457806385fa305a14610cb95780638a13feac14610ce35780638da5cb5b14610cf857610489565b806375794a3c14610c085780637831a73d14610c1d57806379cb331114610c325780637adbf97314610c475780637bad0e3f14610c7a57610489565b80634296b25d1161037c5780636352211e116102f957806367a48fc4116102bd57806367a48fc414610ad45780636a570e3d14610ae95780636c0360eb14610b4a5780636fe9a77114610b5f57806370a0823114610bc0578063715018a614610bf357610489565b80636352211e14610a565780636372ba8e14610a805780636428268914610a95578063664d1cd814610aaa57806366bd0f8b14610abf57610489565b80634f6ccce7116103405780634f6ccce7146109b45780635457e9f7146109de5780635503df44146109f35780635c975abb14610a2c5780636310a80514610a4157610489565b80634296b25d146108ca57806347942d65146108fb57806347a99bc01461096057806349975f7f146109755780634d176a191461099f57610489565b806321afa5571161040a5780633a8a98e2116103ce5780633a8a98e21461081a5780633d6445c3146108485780633f4ba83a1461085d5780633fbaf7a41461087257806342842e0e1461088757610489565b806321afa557146106b357806323b872dd146106dd57806326697b11146107205780632933c832146107b75780632f745c59146107e157610489565b80630ba855d7116104515780630ba855d7146106085780630c16a9aa1461063957806310e33de31461064e57806315db10c21461068957806318160ddd1461069e57610489565b806301ffc9a71461048e578063046cd7f2146104d657806306fdde03146104fd578063081812fc14610587578063095ea7b3146105cd575b600080fd5b34801561049a57600080fd5b506104c2600480360360208110156104b157600080fd5b50356001600160e01b0319166116b7565b604080519115158252519081900360200190f35b3480156104e257600080fd5b506104eb6116da565b60408051918252519081900360200190f35b34801561050957600080fd5b506105126116e0565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561054c578181015183820152602001610534565b50505050905090810190601f1680156105795780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561059357600080fd5b506105b1600480360360208110156105aa57600080fd5b5035611777565b604080516001600160a01b039092168252519081900360200190f35b3480156105d957600080fd5b50610606600480360360408110156105f057600080fd5b506001600160a01b0381351690602001356117d9565b005b34801561061457600080fd5b506104c260048036036204e22081101561062d57600080fd5b508035906020016118b4565b34801561064557600080fd5b506104eb611adf565b34801561065a57600080fd5b50610663611ae5565b604080519485526020850193909352838301919091526060830152519081900360800190f35b34801561069557600080fd5b506104eb611b5b565b3480156106aa57600080fd5b506104eb611b6d565b3480156106bf57600080fd5b506104c2600480360360208110156106d657600080fd5b5035611b7e565b3480156106e957600080fd5b506106066004803603606081101561070057600080fd5b506001600160a01b03813581169160208101359091169060400135611b92565b34801561072c57600080fd5b50610606600480360361324081101561074457600080fd5b6040805161190081810183528435946020810135948101939092611940840192909184019060c89083908390808284376000920191909152505060408051611900818101909252929594938181019392509060c8908390839080828437600092019190915250919450611be99350505050565b3480156107c357600080fd5b50610606600480360360208110156107da57600080fd5b5035611ddf565b3480156107ed57600080fd5b506104eb6004803603604081101561080457600080fd5b506001600160a01b038135169060200135611e9b565b34801561082657600080fd5b5061082f611ec4565b6040805192835260208301919091528051918290030190f35b34801561085457600080fd5b506104eb611f33565b34801561086957600080fd5b50610606611f39565b34801561087e57600080fd5b506104eb611fb6565b34801561089357600080fd5b50610606600480360360608110156108aa57600080fd5b506001600160a01b03813581169160208101359091169060400135611fbc565b3480156108d657600080fd5b5061082f60048036036204e2208110156108ef57600080fd5b50803590602001611fd7565b34801561090757600080fd5b506104eb60048036036204e20081101561092057600080fd5b81019080806204e20001906127108060200260405190810160405280929190826127106020028082843760009201919091525091945061205a9350505050565b34801561096c57600080fd5b506104eb6120b0565b34801561098157600080fd5b506104eb6004803603602081101561099857600080fd5b50356120b6565b3480156109ab57600080fd5b506104c26120c8565b3480156109c057600080fd5b506104eb600480360360208110156109d757600080fd5b50356120ee565b3480156109ea57600080fd5b506104eb612104565b3480156109ff57600080fd5b5061060660048036036040811015610a1657600080fd5b50803590602001356001600160a01b0316612112565b348015610a3857600080fd5b506104c2612276565b348015610a4d57600080fd5b506104eb612286565b348015610a6257600080fd5b506105b160048036036020811015610a7957600080fd5b5035612297565b348015610a8c57600080fd5b506106066122bf565b348015610aa157600080fd5b506104eb612347565b348015610ab657600080fd5b506104eb61235a565b348015610acb57600080fd5b506104c26123cd565b348015610ae057600080fd5b506104eb612404565b348015610af557600080fd5b506104eb6004803603611900811015610b0d57600080fd5b8101908080611900019060c880602002604051908101604052809291908260c86020028082843760009201919091525091945061240a9350505050565b348015610b5657600080fd5b5061051261242e565b348015610b6b57600080fd5b506106066004803603610640811015610b8357600080fd5b81019080806106400190603280602002604051908101604052809291908260326020028082843760009201919091525091945061248f9350505050565b348015610bcc57600080fd5b506104eb60048036036020811015610be357600080fd5b50356001600160a01b031661252b565b348015610bff57600080fd5b50610606612593565b348015610c1457600080fd5b506104eb61263f565b348015610c2957600080fd5b50610606612645565b348015610c3e57600080fd5b506104eb6126a3565b348015610c5357600080fd5b5061060660048036036020811015610c6a57600080fd5b50356001600160a01b03166126a9565b348015610c8657600080fd5b5061082f612769565b348015610c9b57600080fd5b506104eb6127d0565b348015610cb057600080fd5b506106066127d6565b348015610cc557600080fd5b506104eb60048036036020811015610cdc57600080fd5b5035612851565b348015610cef57600080fd5b506104eb612865565b348015610d0457600080fd5b506105b161286b565b348015610d1957600080fd5b506104c260048036036020811015610d3057600080fd5b503561287a565b348015610d4357600080fd5b5061060660048036036020811015610d5a57600080fd5b810190602081018135600160201b811115610d7457600080fd5b820183602082011115610d8657600080fd5b803590602001918460018302840111600160201b83111715610da757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612885945050505050565b348015610df457600080fd5b506104eb61294d565b348015610e0957600080fd5b5061060660048036036020811015610e2057600080fd5b50356001600160a01b03166129b1565b348015610e3c57600080fd5b50610512612a67565b348015610e5157600080fd5b50610606612ac8565b348015610e6657600080fd5b5061060660048036036040811015610e7d57600080fd5b5080359060200135612b6a565b348015610e9657600080fd5b50610606612c53565b348015610eab57600080fd5b5061060660048036036040811015610ec257600080fd5b506001600160a01b0381351690602001351515612cef565b348015610ee657600080fd5b506106066004803603610140811015610efe57600080fd5b81019080806101400190600a806020026040519081016040528092919082600a60200280828437600092019190915250919450612df49350505050565b348015610f4757600080fd5b506104eb612f06565b348015610f5c57600080fd5b5061060660048036036080811015610f7357600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610fad57600080fd5b820183602082011115610fbf57600080fd5b803590602001918460018302840111600160201b83111715610fe057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612f66945050505050565b34801561102d57600080fd5b50610606600480360360c081101561104457600080fd5b810190602081018135600160201b81111561105e57600080fd5b82018360208201111561107057600080fd5b803590602001918460208302840111600160201b8311171561109157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156110e057600080fd5b8201836020820111156110f257600080fd5b803590602001918460208302840111600160201b8311171561111357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561116257600080fd5b82018360208201111561117457600080fd5b803590602001918460208302840111600160201b8311171561119557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156111e457600080fd5b8201836020820111156111f657600080fd5b803590602001918460208302840111600160201b8311171561121757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561126657600080fd5b82018360208201111561127857600080fd5b803590602001918460208302840111600160201b8311171561129957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156112e857600080fd5b8201836020820111156112fa57600080fd5b803590602001918460208302840111600160201b8311171561131b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612fc4945050505050565b6106066004803603602081101561136f57600080fd5b50356130f0565b34801561138257600080fd5b506105126004803603602081101561139957600080fd5b503561325b565b3480156113ac57600080fd5b50610606600480360360408110156113c357600080fd5b810190602081018135600160201b8111156113dd57600080fd5b8201836020820111156113ef57600080fd5b803590602001918460208302840111600160201b8311171561141057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550509135925061347e915050565b34801561145c57600080fd5b506104eb6004803603602081101561147357600080fd5b5035613643565b34801561148657600080fd5b506104eb6004803603602081101561149d57600080fd5b5035613655565b3480156114b057600080fd5b506104c2613667565b3480156114c557600080fd5b506104c2600480360360408110156114dc57600080fd5b506001600160a01b0381358116916020013516613705565b34801561150057600080fd5b506106066004803603602081101561151757600080fd5b50356001600160a01b0316613733565b34801561153357600080fd5b506104c260048036036204e20081101561154c57600080fd5b506138eb565b34801561155e57600080fd5b5061082f61397f565b34801561157357600080fd5b506106066139e6565b34801561158857600080fd5b506106066004803603602081101561159f57600080fd5b50356001600160a01b0316613a50565b3480156115bb57600080fd5b50610606600480360360408110156115d257600080fd5b506001600160a01b038135169060200135613b53565b3480156115f457600080fd5b506104c2613d03565b34801561160957600080fd5b506106066004803603604081101561162057600080fd5b5080359060200135613d64565b34801561163957600080fd5b506104eb613deb565b34801561164e57600080fd5b5061166c6004803603602081101561166557600080fd5b5035613df1565b6040518082600581111561167c57fe5b815260200191505060405180910390f35b34801561169957600080fd5b506104eb600480360360208110156116b057600080fd5b5035613e44565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b600e5481565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561176c5780601f106117415761010080835404028352916020019161176c565b820191906000526020600020905b81548152906001019060200180831161174f57829003601f168201915b505050505090505b90565b600061178282613e51565b6117bd5760405162461bcd60e51b815260040180806020018281038252602c815260200180615909602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006117e482612297565b9050806001600160a01b0316836001600160a01b031614156118375760405162461bcd60e51b81526004018080602001828103825260218152602001806159ad6021913960400191505060405180910390fd5b806001600160a01b0316611849613e5e565b6001600160a01b0316148061186a575061186a81611865613e5e565b613705565b6118a55760405162461bcd60e51b815260040180806020018281038252603881526020018061585c6038913960400191505060405180910390fd5b6118af8383613e62565b505050565b600061271083106118ff576040805162461bcd60e51b815260206004820152601060248201526f34b73b30b634b2103837b9b4ba34b7b760811b604482015290519081900360640190fd5b600b83101561191057506001611ad9565b826064141561192157506001611ad9565b826103e8141561193357506001611ad9565b60008284612710811061194257fe5b6020020135905060008360018603612710811061195b57fe5b6020020135905061196b82613e51565b6119b3576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b6119bc81613e51565b611a0d576040805162461bcd60e51b815260206004820152601960248201527f5072657620546f6b656e20646f6573206e6f7420657869737400000000000000604482015290519081900360640190fd5b611a1681613df1565b6005811115611a2157fe5b611a2a83613df1565b6005811115611a3557fe5b14611a87576040805162461bcd60e51b815260206004820152601760248201527f646966666572656e74207479706573206f662063617264000000000000000000604482015290519081900360640190fd5b600081815260556020526040808220548483529120541115611aae57600192505050611ad9565b600081815260556020526040808220548483529120541015611ad557600092505050611ad9565b1090505b92915050565b600f5481565b600080600080608e544210611b2d576040805162461bcd60e51b8152602060048201526009602482015268135a5cdcd95908125d60ba1b604482015290519081900360640190fd5b5050608e54620151804290910381810494610e10929091068281049450603c92900682810493509190910690565b601254600f54016103e7036062190190565b6000611b796002613ed0565b905090565b600090815260556020526040902054151590565b611ba3611b9d613e5e565b82613edb565b611bde5760405162461bcd60e51b81526004018080602001828103825260318152602001806159ce6031913960400191505060405180910390fd5b6118af838383613f7f565b605a8460328110611bf657fe5b0154611c018361240a565b14611c48576040805162461bcd60e51b815260206004820152601260248201527124a2399034b7103bb937b7339037b93232b960711b604482015290519081900360640190fd5b60238460328110611c5557fe5b0154611c608261240a565b14611caa576040805162461bcd60e51b81526020600482015260156024820152742a3930b4ba399034b7103bb937b7339037b93232b960591b604482015290519081900360640190fd5b6000828460c88110611cb857fe5b6020020151905033611cc982612297565b6001600160a01b031614611d15576040805162461bcd60e51b815260206004820152600e60248201526d2737ba103cb7bab9103a37b5b2b760911b604482015290519081900360640190fd5b600081815260586020526040902054611da457818460c88110611d3457fe5b602002015160586000838152602001908152602001600020819055507fe008379df09c702acb883beef4ab360a5f7bfbe39ee860c5ce8074329ece314181838660c88110611d7e57fe5b6020020151604051808381526020018281526020019250505060405180910390a1611dd8565b6040805182815290517f80d9daddf76e9b53a89f542b657628edf28ba4d489b80bfb0ca67ef9a6dd3c619181900360200190a15b5050505050565b611de7613e5e565b6001600160a01b0316611df861286b565b6001600160a01b031614611e41576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600c5415611e96576040805162461bcd60e51b815260206004820152601e60248201527f4578747261205472616974206f666673657420616c7265616479207365740000604482015290519081900360640190fd5b600c55565b6001600160a01b0382166000908152600160205260408120611ebd90836140cb565b9392505050565b600080611f2b601d601e805480602002602001604051908101604052809291908181526020018280548015611f1857602002820191906000526020600020905b815481526020019060010190808311611f04575b50505050506010546013546021546140d7565b915091509091565b60595481565b611f4161286b565b6001600160a01b0316336001600160a01b03161480611f6a5750608d546001600160a01b031633145b611fac576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b611fb4614145565b565b60185481565b6118af83838360405180602001604052806000815250612f66565b60008060005b620186a08110156120195783816127108110611ff557fe5b60200201358514156120115760c8808204935090069050612053565b600101611fdd565b506040805162461bcd60e51b8152602060048201526009602482015268139bdd08119bdd5b9960ba1b604482015290519081900360640190fd5b9250929050565b600081604051602001808261271060200280838360005b83811015612089578181015183820152602001612071565b50505050905001915050604051602081830303815290604052805190602001209050919050565b60115481565b60009081526055602052604090205490565b7f0000000000000000000000000000000000000000000000000000000000000000421190565b6000806120fc6002846141e8565b509392505050565b601254601354601154010190565b61211a613e5e565b6001600160a01b031661212b61286b565b6001600160a01b031614612174576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b61217c6120c8565b6121c3576040805162461bcd60e51b81526020600482015260136024820152723737ba103ab73a34b61034ba13b99037bb32b960691b604482015290519081900360640190fd5b6003821061220c576040805162461bcd60e51b8152602060048201526011602482015270696e76616c69642063617264207479706560781b604482015290519081900360640190fd5b60006032836122245761221d612286565b915061224d565b83600114156122355761221d611b5b565b836002141561224d57612246612347565b9150601e90505b6122578282614204565b915060005b82811015611dd85761226e848661421a565b60010161225c565b600a54600160a01b900460ff1690565b601154600e54016063036008190190565b6000611ad9826040518060600160405280602981526020016158be60299139600291906145cc565b6122c761286b565b6001600160a01b0316336001600160a01b031614806122f05750608d546001600160a01b031633145b612332576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b608d805460ff60a01b1916600160a01b179055565b6013546010540161270f036103e6190190565b600080612365611b5b565b116123ae576040805162461bcd60e51b8152602060048201526014602482015273105b1c1a184810d85c991cc81cdbdb19081bdd5d60621b604482015290519081900360640190fd5b601c602054815481106123bd57fe5b9060005260206000200154905090565b600080600f905080601254601354601154010111806123ef575061270f601454115b80156123fe57506123fe613667565b91505090565b60165481565b60405160009082906020018082611900808383888181015183820152602001612071565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561176c5780601f106117415761010080835404028352916020019161176c565b612497613e5e565b6001600160a01b03166124a861286b565b6001600160a01b0316146124f1576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6124fe60238260326155de565b506040517f2af92c687ed23319e7139fbf744debde65ef220052dd9ac26b3680a4680e3cdd90600090a150565b60006001600160a01b0382166125725760405162461bcd60e51b815260040180806020018281038252602a815260200180615894602a913960400191505060405180910390fd5b6001600160a01b0382166000908152600160205260409020611ad990613ed0565b61259b613e5e565b6001600160a01b03166125ac61286b565b6001600160a01b0316146125f5576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b60145481565b608c546201000090046001600160a01b0316331461269b576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b611fb46145d9565b60135481565b6126b1613e5e565b6001600160a01b03166126c261286b565b6001600160a01b03161461270b576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b608c80546001600160a01b03831662010000810262010000600160b01b03199092169190911790915560408051918252517f3f32684a32a11dabdbb8c0177de80aa3ae36a004d75210335b49e544e48cd0aa9181900360200190a150565b600080611f2b601b601c8054806020026020016040519081016040528092919081815260200182805480156127bd57602002820191906000526020600020905b8154815260200190600101908083116127a9575b5050505050600f546012546020546140d7565b60105481565b6127de61286b565b6001600160a01b0316336001600160a01b031614806128075750608d546001600160a01b031633145b612849576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b611fb461465d565b6023816032811061285e57fe5b0154905081565b60125481565b600a546001600160a01b031690565b6000611ad982613e51565b61288d61286b565b6001600160a01b0316336001600160a01b031614806128b65750608d546001600160a01b031633145b6128f8576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b608d54600160a01b900460ff16156129415760405162461bcd60e51b81526004018080602001828103825260228152602001806159ff6022913960400191505060405180910390fd5b61294a816146e6565b50565b600080612958612347565b116129a2576040805162461bcd60e51b815260206004820152601560248201527414985b991bdb4810d85c991cc81cdbdb19081bdd5d605a1b604482015290519081900360640190fd5b601e602154815481106123bd57fe5b6129b9613e5e565b6001600160a01b03166129ca61286b565b6001600160a01b031614612a13576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b608d80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f79f74fd5964b6943d8a1865abfb7f668c92fa3f32c0a2e3195da7d0946703ad79181900360200190a150565b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561176c5780601f106117415761010080835404028352916020019161176c565b612ad0613e5e565b6001600160a01b0316612ae161286b565b6001600160a01b031614612b2a576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b612b326145d9565b608c805460ff191660011790556040517f178883df77bd1da8fe0f452c81786ec2daed0fe6bf06928f621f32239ff9e3fc90600090a1565b612b7261286b565b6001600160a01b0316336001600160a01b03161480612b9b5750608d546001600160a01b031633145b612bdd576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b600c548110158015612bf0575061010081105b612c36576040805162461bcd60e51b815260206004820152601260248201527134b63632b3b0b6103134ba10373ab6b132b960711b604482015290519081900360640190fd5b6000918252605860205260409091208054600190921b9091179055565b612c5b613e5e565b6001600160a01b0316612c6c61286b565b6001600160a01b031614612cb5576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6007601060185481612cc357fe5b061115612cd257612cd26146f9565b6000601060185481612ce057fe5b061115611fb457611fb46146f9565b612cf7613e5e565b6001600160a01b0316826001600160a01b03161415612d5d576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000612d6a613e5e565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612dae613e5e565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b612dfc613e5e565b6001600160a01b0316612e0d61286b565b6001600160a01b031614612e56576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b608c54610100900460ff1615612eb3576040805162461bcd60e51b815260206004820152601760248201527f466f756e6465727320616c7265616479206d696e746564000000000000000000604482015290519081900360640190fd5b60005b600a811015612ef357612ed98282600a8110612ece57fe5b602002015182614791565b600081815260556020526040902060019081905501612eb6565b5050608c805461ff001916610100179055565b600080612f11612286565b11612f57576040805162461bcd60e51b815260206004820152601160248201527013d1c810d85c991cc81cdbdb19081bdd5d607a1b604482015290519081900360640190fd5b601a601f54815481106123bd57fe5b612f77612f71613e5e565b83613edb565b612fb25760405162461bcd60e51b81526004018080602001828103825260318152602001806159ce6031913960400191505060405180910390fd5b612fbe848484846148bf565b50505050565b612fcc613e5e565b6001600160a01b0316612fdd61286b565b6001600160a01b031614613026576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b855161303990601990602089019061561c565b50845161304d90601a90602088019061561c565b50835161306190601b90602087019061561c565b50825161307590601c90602086019061561c565b50815161308990601d90602085019061561c565b50805161309d90601e90602084019061561c565b50600d805460ff1916600117905560408051808201909152601981527f74656d702e65746865722e63617264732f6d657461646174610000000000000060208201526130e8906146e6565b505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000421015613158576040805162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd081cdd185c9d195960821b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000004211156131ba576040805162461bcd60e51b815260206004820152600a60248201526914d85b1948195b99195960b21b604482015290519081900360640190fd5b61270f6014541115613205576040805162461bcd60e51b815260206004820152600f60248201526e14dbdc9c9e4b8814dbdb19081bdd5d608a1b604482015290519081900360640190fd5b61320d612276565b15613252576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b61294a81614911565b606061326682613e51565b6132a15760405162461bcd60e51b815260040180806020018281038252602f81526020018061597e602f913960400191505060405180910390fd5b60006132ac83613df1565b905060058160058111156132bc57fe5b14156132e3576040518060600160405280602c8152602001615804602c91399150506116d5565b60606132f160648506614bca565b905060606132fe85614bca565b6040805180820190915260018152602f60f81b602082015290915061332161242e565b8382846040516020018085805190602001908083835b602083106133565780518252601f199092019160209182019101613337565b51815160209384036101000a600019018019909216911617905287519190930192870191508083835b6020831061339e5780518252601f19909201916020918201910161337f565b51815160209384036101000a600019018019909216911617905286519190930192860191508083835b602083106133e65780518252601f1990920191602091820191016133c7565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b6020831061342e5780518252601f19909201916020918201910161340f565b5181516020939093036101000a600019018019909116921691909117905264173539b7b760d91b92019182525060408051808303601a19018152600590920190529b9a5050505050505050505050565b613486613e5e565b6001600160a01b031661349761286b565b6001600160a01b0316146134e0576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600d5460ff1661352d576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b608c54610100900460ff1661357f576040805162461bcd60e51b81526020600482015260136024820152721b5a5b9d08199bdd5b99195c9cc8199a5c9cdd606a1b604482015290519081900360640190fd5b600381106135c8576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642043617264205479706560781b604482015290519081900360640190fd5b608c5460ff1615613612576040805162461bcd60e51b815260206004820152600f60248201526e283932b9b0b6329034b99037bb32b960891b604482015290519081900360640190fd5b60005b82518110156118af5761363b83828151811061362d57fe5b60200260200101518361421a565b600101613615565b60156020526000908152604090205481565b60009081526058602052604090205490565b6000601754601654118015611b795750600b546017546000908152601560209081526040918290205482516313afb27f60e01b8152600481019190915291516001600160a01b03909316926313afb27f926024808201939291829003018186803b1580156136d457600080fd5b505afa1580156136e8573d6000803e3d6000fd5b505050506040513d60208110156136fe57600080fd5b5051905090565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61373b613e5e565b6001600160a01b031661374c61286b565b6001600160a01b031614613795576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6001600160a01b0381166137e9576137ab61286b565b6001600160a01b03166108fc479081150290604051600060405180830381858888f193505050501580156137e3573d6000803e3d6000fd5b5061294a565b806001600160a01b031663a9059cbb61380061286b565b604080516370a0823160e01b815230600482015290516001600160a01b038616916370a08231916024808301926020929190829003018186803b15801561384657600080fd5b505afa15801561385a573d6000803e3d6000fd5b505050506040513d602081101561387057600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b1580156138c157600080fd5b505af11580156138d5573d6000803e3d6000fd5b505050506040513d60208110156118af57600080fd5b60006138f5615656565b60005b60328110156139755760005b60c881101561393d57848260c8028201612710811061391f57fe5b6020020135838260c8811061393057fe5b6020020152600101613904565b5060006139498361240a565b905080605a836032811061395957fe5b01541461396c57600093505050506116d5565b506001016138f8565b5060019392505050565b600080611f2b6019601a8054806020026020016040519081016040528092919081815260200182805480156139d357602002820191906000526020600020905b8154815260200190600101908083116139bf575b5050505050600e54601154601f546140d7565b6139ee613e5e565b6001600160a01b03166139ff61286b565b6001600160a01b031614613a48576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b611fb46146f9565b613a58613e5e565b6001600160a01b0316613a6961286b565b6001600160a01b031614613ab2576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6001600160a01b038116613af75760405162461bcd60e51b81526004018080602001828103825260268152602001806157ba6026913960400191505060405180910390fd5b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b613b5b613e5e565b6001600160a01b0316613b6c61286b565b6001600160a01b031614613bb5576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600d5460ff16613c02576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b608c54610100900460ff16613c54576040805162461bcd60e51b81526020600482015260136024820152721b5a5b9d08199bdd5b99195c9cc8199a5c9cdd606a1b604482015290519081900360640190fd5b60038110613c9d576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642043617264205479706560781b604482015290519081900360640190fd5b608c5460ff161580613cb25750613cb26120c8565b613cf5576040805162461bcd60e51b815260206004820152600f60248201526e283932b9b0b6329034b99037bb32b960891b604482015290519081900360640190fd5b613cff828261421a565b5050565b6000613d0d6120c8565b15613d1a57506000611774565b7f0000000000000000000000000000000000000000000000000000000000000000421015613d4a57506000611774565b61270f6014541115613d5e57506000611774565b50600190565b613d6c61286b565b6001600160a01b0316336001600160a01b03161480613d955750608d546001600160a01b031633145b613dd7576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b80605a8360328110613de557fe5b01555050565b60175481565b6000613dfc82611b7e565b613e08575060056116d5565b600a821015613e19575060046116d5565b6064821015613e2a575060006116d5565b6103e8821015613e3c575060016116d5565b506003919050565b605a816032811061285e57fe5b6000611ad9600283614ca5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190613e9782612297565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611ad982614cb1565b6000613ee682613e51565b613f215760405162461bcd60e51b815260040180806020018281038252602c815260200180615830602c913960400191505060405180910390fd5b6000613f2c83612297565b9050806001600160a01b0316846001600160a01b03161480613f675750836001600160a01b0316613f5c84611777565b6001600160a01b0316145b80613f775750613f778185613705565b949350505050565b826001600160a01b0316613f9282612297565b6001600160a01b031614613fd75760405162461bcd60e51b81526004018080602001828103825260298152602001806159556029913960400191505060405180910390fd5b6001600160a01b03821661401c5760405162461bcd60e51b81526004018080602001828103825260248152602001806157e06024913960400191505060405180910390fd5b614027838383614cb5565b614032600082613e62565b6001600160a01b03831660009081526001602052604090206140549082614d04565b506001600160a01b03821660009081526001602052604090206140779082614d10565b5061408460028284614d1c565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611ebd8383614d32565b6000808385018784815481106140e957fe5b906000526020600020015403915060018780549050038310156141245785836001018151811061411557fe5b6020026020010151905061413b565b85838151811061413057fe5b602002602001015190505b9550959350505050565b61414d612276565b614195576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6141cb613e5e565b604080516001600160a01b039092168252519081900360200190a1565b60008080806141f78686614d96565b9097909650945050505050565b60008183106142135781611ebd565b5090919050565b600d5460ff16614267576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b6000614271612347565b9050600061427d611b5b565b9050614287614e11565b826002141561439857600082116142cf5760405162461bcd60e51b81526004018080602001828103825260218152602001806157676021913960400191505060405180910390fd5b601354601054016103e8016142e48582614791565b6013805460010190819055601054601d80546040805160208084028201810190925282815261434e95939092909183018282801561434157602002820191906000526020600020905b81548152602001906001019080831161432d575b5050505050602154614e30565b6021556040805133815234602082015280820183905290517f8cd8e8b2f55e42622fdad0e00fc0d8daf21246a1564886af3b6ad0b1f7f94e0a9181900360600190a1505050613cff565b82600114156144a957600081116143e05760405162461bcd60e51b81526004018080602001828103825260228152602001806157456022913960400191505060405180910390fd5b601254600f54016064016143f48582614791565b6040805133815234602082015280820183905290517f6e69c5ee2c945cc28f9655e03826339ec332b3b7eb055c7dc60aec86674b47e29181900360600190a16012805460010190819055600f54601b80546040805160208084028201810190925282815261449d95939092909183018282801561449057602002820191906000526020600020905b81548152602001906001019080831161447c575b5050505050602054614e30565b60205550613cff915050565b60006144b3612286565b11614505576040805162461bcd60e51b815260206004820152601c60248201527f536f7272792c206e6f204f4720636172647320617661696c61626c6500000000604482015290519081900360640190fd5b601154600e5401600a016145198582614791565b6040805133815234602082015280820183905290517f37a9b963e479fe85bd668e3841cb900a0248efd10e397afe18b3096f37f40ca59181900360600190a16011805460010190819055600e5460198054604080516020808402820181019092528281526145c29593909290918301828280156145b557602002820191906000526020600020905b8154815260200190600101908083116145a1575b5050505050601f54614e30565b601f555050505050565b6000613f77848484614e6c565b6040517f2bccbdacf27af5a4a14fb2d0e8237074c0f3a97f4c73e086175a06d5536ea3b890600090a1600061460c614f36565b60125460135460115492935060109261ffff928492919091010160005b848110156130e85760001982019161464657505050505050611fb4565b614651848716614feb565b94821c94600101614629565b614665612276565b156146aa576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586141cb613e5e565b8051613cff906009906020840190615675565b600b60009054906101000a90046001600160a01b03166001600160a01b0316638678a7b26040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561474957600080fd5b505af115801561475d573d6000803e3d6000fd5b505050506040513d602081101561477357600080fd5b50516016805460018101909155600090815260156020526040902055565b6001600160a01b0382166147ec576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6147f581613e51565b15614847576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b61485360008383614cb5565b6001600160a01b03821660009081526001602052604090206148759082614d10565b5061488260028284614d1c565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6148ca848484613f7f565b6148d6848484846150c8565b612fbe5760405162461bcd60e51b81526004018080602001828103825260328152602001806157886032913960400191505060405180910390fd5b600d5460ff1661495e576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b346000600383106149aa576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642063617264207479706560781b604482015290519081900360640190fd5b60005b6064811015614b0e57836149ca576149c3612f06565b91506149e6565b83600114156149db576149c361235a565b6149e361294d565b91505b81831015614af05780614a32576040805162461bcd60e51b815260206004820152600f60248201526e139bdd08195b9bdd59da081cd95b9d608a1b604482015290519081900360640190fd5b6022546001600160a01b03166108fc614a4b3486615230565b6040518115909202916000818181858888f19350505050158015614a73573d6000803e3d6000fd5b50604051339084156108fc029085906000818181858888f19350505050158015614aa1573d6000803e3d6000fd5b50604080513381523460208201528082018390526060810185905290517fb7048c2ad36aadee977bb16b4543a18866044d27a2ca753e1c7dbcfa7d7a69629181900360800190a150505061294a565b614afa338561421a565b614b048383615230565b92506001016149ad565b506022546001600160a01b03166108fc614b283485615230565b6040518115909202916000818181858888f19350505050158015614b50573d6000803e3d6000fd5b50604051339083156108fc029084906000818181858888f19350505050158015614b7e573d6000803e3d6000fd5b50604080513381523460208201526064818301526060810184905290517fb7048c2ad36aadee977bb16b4543a18866044d27a2ca753e1c7dbcfa7d7a69629181900360800190a1505050565b606081614bef57506040805180820190915260018152600360fc1b60208201526116d5565b8160005b8115614c0757600101600a82049150614bf3565b60608167ffffffffffffffff81118015614c2057600080fd5b506040519080825280601f01601f191660200182016040528015614c4b576020820181803683370190505b50859350905060001982015b8315614c9c57600a840660300160f81b82828060019003935081518110614c7a57fe5b60200101906001600160f81b031916908160001a905350600a84049350614c57565b50949350505050565b6000611ebd838361528d565b5490565b614cc08383836118af565b614cc8612276565b156118af5760405162461bcd60e51b815260040180806020018281038252602b81526020018061571a602b913960400191505060405180910390fd5b6000611ebd83836152a5565b6000611ebd838361536b565b6000613f7784846001600160a01b0385166153b5565b81546000908210614d745760405162461bcd60e51b81526004018080602001828103825260228152602001806156f86022913960400191505060405180910390fd5b826000018281548110614d8357fe5b9060005260206000200154905092915050565b815460009081908310614dda5760405162461bcd60e51b81526004018080602001828103825260228152602001806158e76022913960400191505060405180910390fd5b6000846000018481548110614deb57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b601880546001810190915560109006600f1415611fb457611fb46146f9565b60006001835103821415614e45575080613f77565b828281518110614e5157fe5b602002602001015184860111156120fc575060018101613f77565b60008281526001840160205260408120548281614f075760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614ecc578181015183820152602001614eb4565b50505050905090810190601f168015614ef95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110614f1a57fe5b9060005260206000209060020201600101549150509392505050565b6000614f40613667565b614f86576040805162461bcd60e51b81526020600482015260126024820152714e6f7468696e6720746f2070726f6365737360701b604482015290519081900360640190fd5b600b54601780546001810190915560009081526015602090815260409182902054825163205a1e3960e11b8152600481019190915291516001600160a01b03909316926340b43c72926024808201939291829003018186803b1580156136d457600080fd5b601354600090829015615018576010805460018101909155601380546000190190556103e801915061506d565b6012541561503f57600f80546001810190915560128054600019019055606401915061506d565b6011541561506657600e80546001810190915560118054600019019055600a01915061506d565b505061294a565b60008281526055602090815260409182902060016103ff851601908190558251858152918201819052825190927f422ac4ddfd5e11612221e380b75b24e9aff8bf16fbb187544e2764b78e289137928290030190a150505050565b60006150dc846001600160a01b031661544c565b6150e857506001613f77565b60606151f6630a85bd0160e11b6150fd613e5e565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561516457818101518382015260200161514c565b50505050905090810190601f1680156151915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001615788603291396001600160a01b0388169190615452565b9050600081806020019051602081101561520f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b600082821115615287576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60009081526001919091016020526040902054151590565b6000818152600183016020526040812054801561536157835460001980830191908101906000908790839081106152d857fe5b90600052602060002001549050808760000184815481106152f557fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061532557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611ad9565b6000915050611ad9565b6000615377838361528d565b6153ad57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611ad9565b506000611ad9565b60008281526001840160205260408120548061541a575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611ebd565b8285600001600183038154811061542d57fe5b9060005260206000209060020201600101819055506000915050611ebd565b3b151590565b6060613f778484600085856154668561544c565b6154b7576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106154f65780518252601f1990920191602091820191016154d7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615558576040519150601f19603f3d011682016040523d82523d6000602084013e61555d565b606091505b509150915061556d828286615578565b979650505050505050565b60608315615587575081611ebd565b8251156155975782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315614ecc578181015183820152602001614eb4565b826032810192821561560c579160200282015b8281111561560c5782518255916020019190600101906155f1565b506156189291506156e2565b5090565b82805482825590600052602060002090810192821561560c579160200282018281111561560c5782518255916020019190600101906155f1565b60405180611900016040528060c8906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106156b657805160ff191683800117855561560c565b8280016001018555821561560c579182018281111561560c5782518255916020019190600101906155f1565b5b8082111561561857600081556001016156e356fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732315061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564536f727279202d206e6f20416c706861207469636b65747320617661696c61626c65536f727279206e6f2072616e646f6d207469636b65747320617661696c61626c654552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f206164647265737368747470733a2f2f74656d702e65746865722e63617264732f6d657461646174612f556e7265736f6c7665644552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665645468697320646174612063616e206e6f206c6f6e676572206265206368616e676564a2646970667358221220d8ff33e2b85e68f29135427088442bda3fcc302afb136b99bbe51c0735e3177664736f6c634300070300330000000000000000000000005638bf5c73d8aa7f7926954f7415e52230efe9bd0000000000000000000000000000000000000000000000000000000060534ed000000000000000000000000000000000000000000000000000000000606efe500000000000000000000000006a80d451135720c51af81ecb4334a1a94b3a6055000000000000000000000000a218b55ec696cc32b388fc97334db41dab48d8e1

Deployed Bytecode

0x6080604052600436106104895760003560e01c806375794a3c11610255578063b6bd11e111610144578063ece53132116100c1578063f4e75f2b11610085578063f4e75f2b146115af578063f5dfd534146115e8578063f849688e146115fd578063f965e0351461162d578063fcf49adf14611642578063fdc086ec1461168d57610489565b8063ece53132146114f4578063ed87968814611527578063ee31991d14611552578063f014095714611567578063f2fde38b1461157c57610489565b8063c952316111610108578063c9523161146113a0578063ca067ad014611450578063d688a31d1461147a578063e8022449146114a4578063e985e9c5146114b957610489565b8063b6bd11e114610f3b578063b88d4fde14610f50578063b91dc1ea14611021578063c70f5eaa14611359578063c87b56dd1461137657610489565b80638f950101116101d2578063969bd8a411610196578063969bd8a414610e455780639a6be11614610e5a5780639bfb5ca714610e8a578063a22cb46514610e9f578063ac80c3ca14610eda57610489565b80638f95010114610d0d5780639102235514610d37578063924868c514610de857806392eefe9b14610dfd57806395d89b4114610e3057610489565b80637f015416116102195780637f01541614610c8f5780638456cb5914610ca457806385fa305a14610cb95780638a13feac14610ce35780638da5cb5b14610cf857610489565b806375794a3c14610c085780637831a73d14610c1d57806379cb331114610c325780637adbf97314610c475780637bad0e3f14610c7a57610489565b80634296b25d1161037c5780636352211e116102f957806367a48fc4116102bd57806367a48fc414610ad45780636a570e3d14610ae95780636c0360eb14610b4a5780636fe9a77114610b5f57806370a0823114610bc0578063715018a614610bf357610489565b80636352211e14610a565780636372ba8e14610a805780636428268914610a95578063664d1cd814610aaa57806366bd0f8b14610abf57610489565b80634f6ccce7116103405780634f6ccce7146109b45780635457e9f7146109de5780635503df44146109f35780635c975abb14610a2c5780636310a80514610a4157610489565b80634296b25d146108ca57806347942d65146108fb57806347a99bc01461096057806349975f7f146109755780634d176a191461099f57610489565b806321afa5571161040a5780633a8a98e2116103ce5780633a8a98e21461081a5780633d6445c3146108485780633f4ba83a1461085d5780633fbaf7a41461087257806342842e0e1461088757610489565b806321afa557146106b357806323b872dd146106dd57806326697b11146107205780632933c832146107b75780632f745c59146107e157610489565b80630ba855d7116104515780630ba855d7146106085780630c16a9aa1461063957806310e33de31461064e57806315db10c21461068957806318160ddd1461069e57610489565b806301ffc9a71461048e578063046cd7f2146104d657806306fdde03146104fd578063081812fc14610587578063095ea7b3146105cd575b600080fd5b34801561049a57600080fd5b506104c2600480360360208110156104b157600080fd5b50356001600160e01b0319166116b7565b604080519115158252519081900360200190f35b3480156104e257600080fd5b506104eb6116da565b60408051918252519081900360200190f35b34801561050957600080fd5b506105126116e0565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561054c578181015183820152602001610534565b50505050905090810190601f1680156105795780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561059357600080fd5b506105b1600480360360208110156105aa57600080fd5b5035611777565b604080516001600160a01b039092168252519081900360200190f35b3480156105d957600080fd5b50610606600480360360408110156105f057600080fd5b506001600160a01b0381351690602001356117d9565b005b34801561061457600080fd5b506104c260048036036204e22081101561062d57600080fd5b508035906020016118b4565b34801561064557600080fd5b506104eb611adf565b34801561065a57600080fd5b50610663611ae5565b604080519485526020850193909352838301919091526060830152519081900360800190f35b34801561069557600080fd5b506104eb611b5b565b3480156106aa57600080fd5b506104eb611b6d565b3480156106bf57600080fd5b506104c2600480360360208110156106d657600080fd5b5035611b7e565b3480156106e957600080fd5b506106066004803603606081101561070057600080fd5b506001600160a01b03813581169160208101359091169060400135611b92565b34801561072c57600080fd5b50610606600480360361324081101561074457600080fd5b6040805161190081810183528435946020810135948101939092611940840192909184019060c89083908390808284376000920191909152505060408051611900818101909252929594938181019392509060c8908390839080828437600092019190915250919450611be99350505050565b3480156107c357600080fd5b50610606600480360360208110156107da57600080fd5b5035611ddf565b3480156107ed57600080fd5b506104eb6004803603604081101561080457600080fd5b506001600160a01b038135169060200135611e9b565b34801561082657600080fd5b5061082f611ec4565b6040805192835260208301919091528051918290030190f35b34801561085457600080fd5b506104eb611f33565b34801561086957600080fd5b50610606611f39565b34801561087e57600080fd5b506104eb611fb6565b34801561089357600080fd5b50610606600480360360608110156108aa57600080fd5b506001600160a01b03813581169160208101359091169060400135611fbc565b3480156108d657600080fd5b5061082f60048036036204e2208110156108ef57600080fd5b50803590602001611fd7565b34801561090757600080fd5b506104eb60048036036204e20081101561092057600080fd5b81019080806204e20001906127108060200260405190810160405280929190826127106020028082843760009201919091525091945061205a9350505050565b34801561096c57600080fd5b506104eb6120b0565b34801561098157600080fd5b506104eb6004803603602081101561099857600080fd5b50356120b6565b3480156109ab57600080fd5b506104c26120c8565b3480156109c057600080fd5b506104eb600480360360208110156109d757600080fd5b50356120ee565b3480156109ea57600080fd5b506104eb612104565b3480156109ff57600080fd5b5061060660048036036040811015610a1657600080fd5b50803590602001356001600160a01b0316612112565b348015610a3857600080fd5b506104c2612276565b348015610a4d57600080fd5b506104eb612286565b348015610a6257600080fd5b506105b160048036036020811015610a7957600080fd5b5035612297565b348015610a8c57600080fd5b506106066122bf565b348015610aa157600080fd5b506104eb612347565b348015610ab657600080fd5b506104eb61235a565b348015610acb57600080fd5b506104c26123cd565b348015610ae057600080fd5b506104eb612404565b348015610af557600080fd5b506104eb6004803603611900811015610b0d57600080fd5b8101908080611900019060c880602002604051908101604052809291908260c86020028082843760009201919091525091945061240a9350505050565b348015610b5657600080fd5b5061051261242e565b348015610b6b57600080fd5b506106066004803603610640811015610b8357600080fd5b81019080806106400190603280602002604051908101604052809291908260326020028082843760009201919091525091945061248f9350505050565b348015610bcc57600080fd5b506104eb60048036036020811015610be357600080fd5b50356001600160a01b031661252b565b348015610bff57600080fd5b50610606612593565b348015610c1457600080fd5b506104eb61263f565b348015610c2957600080fd5b50610606612645565b348015610c3e57600080fd5b506104eb6126a3565b348015610c5357600080fd5b5061060660048036036020811015610c6a57600080fd5b50356001600160a01b03166126a9565b348015610c8657600080fd5b5061082f612769565b348015610c9b57600080fd5b506104eb6127d0565b348015610cb057600080fd5b506106066127d6565b348015610cc557600080fd5b506104eb60048036036020811015610cdc57600080fd5b5035612851565b348015610cef57600080fd5b506104eb612865565b348015610d0457600080fd5b506105b161286b565b348015610d1957600080fd5b506104c260048036036020811015610d3057600080fd5b503561287a565b348015610d4357600080fd5b5061060660048036036020811015610d5a57600080fd5b810190602081018135600160201b811115610d7457600080fd5b820183602082011115610d8657600080fd5b803590602001918460018302840111600160201b83111715610da757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612885945050505050565b348015610df457600080fd5b506104eb61294d565b348015610e0957600080fd5b5061060660048036036020811015610e2057600080fd5b50356001600160a01b03166129b1565b348015610e3c57600080fd5b50610512612a67565b348015610e5157600080fd5b50610606612ac8565b348015610e6657600080fd5b5061060660048036036040811015610e7d57600080fd5b5080359060200135612b6a565b348015610e9657600080fd5b50610606612c53565b348015610eab57600080fd5b5061060660048036036040811015610ec257600080fd5b506001600160a01b0381351690602001351515612cef565b348015610ee657600080fd5b506106066004803603610140811015610efe57600080fd5b81019080806101400190600a806020026040519081016040528092919082600a60200280828437600092019190915250919450612df49350505050565b348015610f4757600080fd5b506104eb612f06565b348015610f5c57600080fd5b5061060660048036036080811015610f7357600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610fad57600080fd5b820183602082011115610fbf57600080fd5b803590602001918460018302840111600160201b83111715610fe057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612f66945050505050565b34801561102d57600080fd5b50610606600480360360c081101561104457600080fd5b810190602081018135600160201b81111561105e57600080fd5b82018360208201111561107057600080fd5b803590602001918460208302840111600160201b8311171561109157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156110e057600080fd5b8201836020820111156110f257600080fd5b803590602001918460208302840111600160201b8311171561111357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561116257600080fd5b82018360208201111561117457600080fd5b803590602001918460208302840111600160201b8311171561119557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156111e457600080fd5b8201836020820111156111f657600080fd5b803590602001918460208302840111600160201b8311171561121757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561126657600080fd5b82018360208201111561127857600080fd5b803590602001918460208302840111600160201b8311171561129957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156112e857600080fd5b8201836020820111156112fa57600080fd5b803590602001918460208302840111600160201b8311171561131b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612fc4945050505050565b6106066004803603602081101561136f57600080fd5b50356130f0565b34801561138257600080fd5b506105126004803603602081101561139957600080fd5b503561325b565b3480156113ac57600080fd5b50610606600480360360408110156113c357600080fd5b810190602081018135600160201b8111156113dd57600080fd5b8201836020820111156113ef57600080fd5b803590602001918460208302840111600160201b8311171561141057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550509135925061347e915050565b34801561145c57600080fd5b506104eb6004803603602081101561147357600080fd5b5035613643565b34801561148657600080fd5b506104eb6004803603602081101561149d57600080fd5b5035613655565b3480156114b057600080fd5b506104c2613667565b3480156114c557600080fd5b506104c2600480360360408110156114dc57600080fd5b506001600160a01b0381358116916020013516613705565b34801561150057600080fd5b506106066004803603602081101561151757600080fd5b50356001600160a01b0316613733565b34801561153357600080fd5b506104c260048036036204e20081101561154c57600080fd5b506138eb565b34801561155e57600080fd5b5061082f61397f565b34801561157357600080fd5b506106066139e6565b34801561158857600080fd5b506106066004803603602081101561159f57600080fd5b50356001600160a01b0316613a50565b3480156115bb57600080fd5b50610606600480360360408110156115d257600080fd5b506001600160a01b038135169060200135613b53565b3480156115f457600080fd5b506104c2613d03565b34801561160957600080fd5b506106066004803603604081101561162057600080fd5b5080359060200135613d64565b34801561163957600080fd5b506104eb613deb565b34801561164e57600080fd5b5061166c6004803603602081101561166557600080fd5b5035613df1565b6040518082600581111561167c57fe5b815260200191505060405180910390f35b34801561169957600080fd5b506104eb600480360360208110156116b057600080fd5b5035613e44565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b600e5481565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561176c5780601f106117415761010080835404028352916020019161176c565b820191906000526020600020905b81548152906001019060200180831161174f57829003601f168201915b505050505090505b90565b600061178282613e51565b6117bd5760405162461bcd60e51b815260040180806020018281038252602c815260200180615909602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006117e482612297565b9050806001600160a01b0316836001600160a01b031614156118375760405162461bcd60e51b81526004018080602001828103825260218152602001806159ad6021913960400191505060405180910390fd5b806001600160a01b0316611849613e5e565b6001600160a01b0316148061186a575061186a81611865613e5e565b613705565b6118a55760405162461bcd60e51b815260040180806020018281038252603881526020018061585c6038913960400191505060405180910390fd5b6118af8383613e62565b505050565b600061271083106118ff576040805162461bcd60e51b815260206004820152601060248201526f34b73b30b634b2103837b9b4ba34b7b760811b604482015290519081900360640190fd5b600b83101561191057506001611ad9565b826064141561192157506001611ad9565b826103e8141561193357506001611ad9565b60008284612710811061194257fe5b6020020135905060008360018603612710811061195b57fe5b6020020135905061196b82613e51565b6119b3576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b6119bc81613e51565b611a0d576040805162461bcd60e51b815260206004820152601960248201527f5072657620546f6b656e20646f6573206e6f7420657869737400000000000000604482015290519081900360640190fd5b611a1681613df1565b6005811115611a2157fe5b611a2a83613df1565b6005811115611a3557fe5b14611a87576040805162461bcd60e51b815260206004820152601760248201527f646966666572656e74207479706573206f662063617264000000000000000000604482015290519081900360640190fd5b600081815260556020526040808220548483529120541115611aae57600192505050611ad9565b600081815260556020526040808220548483529120541015611ad557600092505050611ad9565b1090505b92915050565b600f5481565b600080600080608e544210611b2d576040805162461bcd60e51b8152602060048201526009602482015268135a5cdcd95908125d60ba1b604482015290519081900360640190fd5b5050608e54620151804290910381810494610e10929091068281049450603c92900682810493509190910690565b601254600f54016103e7036062190190565b6000611b796002613ed0565b905090565b600090815260556020526040902054151590565b611ba3611b9d613e5e565b82613edb565b611bde5760405162461bcd60e51b81526004018080602001828103825260318152602001806159ce6031913960400191505060405180910390fd5b6118af838383613f7f565b605a8460328110611bf657fe5b0154611c018361240a565b14611c48576040805162461bcd60e51b815260206004820152601260248201527124a2399034b7103bb937b7339037b93232b960711b604482015290519081900360640190fd5b60238460328110611c5557fe5b0154611c608261240a565b14611caa576040805162461bcd60e51b81526020600482015260156024820152742a3930b4ba399034b7103bb937b7339037b93232b960591b604482015290519081900360640190fd5b6000828460c88110611cb857fe5b6020020151905033611cc982612297565b6001600160a01b031614611d15576040805162461bcd60e51b815260206004820152600e60248201526d2737ba103cb7bab9103a37b5b2b760911b604482015290519081900360640190fd5b600081815260586020526040902054611da457818460c88110611d3457fe5b602002015160586000838152602001908152602001600020819055507fe008379df09c702acb883beef4ab360a5f7bfbe39ee860c5ce8074329ece314181838660c88110611d7e57fe5b6020020151604051808381526020018281526020019250505060405180910390a1611dd8565b6040805182815290517f80d9daddf76e9b53a89f542b657628edf28ba4d489b80bfb0ca67ef9a6dd3c619181900360200190a15b5050505050565b611de7613e5e565b6001600160a01b0316611df861286b565b6001600160a01b031614611e41576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600c5415611e96576040805162461bcd60e51b815260206004820152601e60248201527f4578747261205472616974206f666673657420616c7265616479207365740000604482015290519081900360640190fd5b600c55565b6001600160a01b0382166000908152600160205260408120611ebd90836140cb565b9392505050565b600080611f2b601d601e805480602002602001604051908101604052809291908181526020018280548015611f1857602002820191906000526020600020905b815481526020019060010190808311611f04575b50505050506010546013546021546140d7565b915091509091565b60595481565b611f4161286b565b6001600160a01b0316336001600160a01b03161480611f6a5750608d546001600160a01b031633145b611fac576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b611fb4614145565b565b60185481565b6118af83838360405180602001604052806000815250612f66565b60008060005b620186a08110156120195783816127108110611ff557fe5b60200201358514156120115760c8808204935090069050612053565b600101611fdd565b506040805162461bcd60e51b8152602060048201526009602482015268139bdd08119bdd5b9960ba1b604482015290519081900360640190fd5b9250929050565b600081604051602001808261271060200280838360005b83811015612089578181015183820152602001612071565b50505050905001915050604051602081830303815290604052805190602001209050919050565b60115481565b60009081526055602052604090205490565b7f00000000000000000000000000000000000000000000000000000000606efe50421190565b6000806120fc6002846141e8565b509392505050565b601254601354601154010190565b61211a613e5e565b6001600160a01b031661212b61286b565b6001600160a01b031614612174576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b61217c6120c8565b6121c3576040805162461bcd60e51b81526020600482015260136024820152723737ba103ab73a34b61034ba13b99037bb32b960691b604482015290519081900360640190fd5b6003821061220c576040805162461bcd60e51b8152602060048201526011602482015270696e76616c69642063617264207479706560781b604482015290519081900360640190fd5b60006032836122245761221d612286565b915061224d565b83600114156122355761221d611b5b565b836002141561224d57612246612347565b9150601e90505b6122578282614204565b915060005b82811015611dd85761226e848661421a565b60010161225c565b600a54600160a01b900460ff1690565b601154600e54016063036008190190565b6000611ad9826040518060600160405280602981526020016158be60299139600291906145cc565b6122c761286b565b6001600160a01b0316336001600160a01b031614806122f05750608d546001600160a01b031633145b612332576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b608d805460ff60a01b1916600160a01b179055565b6013546010540161270f036103e6190190565b600080612365611b5b565b116123ae576040805162461bcd60e51b8152602060048201526014602482015273105b1c1a184810d85c991cc81cdbdb19081bdd5d60621b604482015290519081900360640190fd5b601c602054815481106123bd57fe5b9060005260206000200154905090565b600080600f905080601254601354601154010111806123ef575061270f601454115b80156123fe57506123fe613667565b91505090565b60165481565b60405160009082906020018082611900808383888181015183820152602001612071565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561176c5780601f106117415761010080835404028352916020019161176c565b612497613e5e565b6001600160a01b03166124a861286b565b6001600160a01b0316146124f1576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6124fe60238260326155de565b506040517f2af92c687ed23319e7139fbf744debde65ef220052dd9ac26b3680a4680e3cdd90600090a150565b60006001600160a01b0382166125725760405162461bcd60e51b815260040180806020018281038252602a815260200180615894602a913960400191505060405180910390fd5b6001600160a01b0382166000908152600160205260409020611ad990613ed0565b61259b613e5e565b6001600160a01b03166125ac61286b565b6001600160a01b0316146125f5576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b60145481565b608c546201000090046001600160a01b0316331461269b576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b611fb46145d9565b60135481565b6126b1613e5e565b6001600160a01b03166126c261286b565b6001600160a01b03161461270b576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b608c80546001600160a01b03831662010000810262010000600160b01b03199092169190911790915560408051918252517f3f32684a32a11dabdbb8c0177de80aa3ae36a004d75210335b49e544e48cd0aa9181900360200190a150565b600080611f2b601b601c8054806020026020016040519081016040528092919081815260200182805480156127bd57602002820191906000526020600020905b8154815260200190600101908083116127a9575b5050505050600f546012546020546140d7565b60105481565b6127de61286b565b6001600160a01b0316336001600160a01b031614806128075750608d546001600160a01b031633145b612849576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b611fb461465d565b6023816032811061285e57fe5b0154905081565b60125481565b600a546001600160a01b031690565b6000611ad982613e51565b61288d61286b565b6001600160a01b0316336001600160a01b031614806128b65750608d546001600160a01b031633145b6128f8576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b608d54600160a01b900460ff16156129415760405162461bcd60e51b81526004018080602001828103825260228152602001806159ff6022913960400191505060405180910390fd5b61294a816146e6565b50565b600080612958612347565b116129a2576040805162461bcd60e51b815260206004820152601560248201527414985b991bdb4810d85c991cc81cdbdb19081bdd5d605a1b604482015290519081900360640190fd5b601e602154815481106123bd57fe5b6129b9613e5e565b6001600160a01b03166129ca61286b565b6001600160a01b031614612a13576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b608d80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f79f74fd5964b6943d8a1865abfb7f668c92fa3f32c0a2e3195da7d0946703ad79181900360200190a150565b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561176c5780601f106117415761010080835404028352916020019161176c565b612ad0613e5e565b6001600160a01b0316612ae161286b565b6001600160a01b031614612b2a576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b612b326145d9565b608c805460ff191660011790556040517f178883df77bd1da8fe0f452c81786ec2daed0fe6bf06928f621f32239ff9e3fc90600090a1565b612b7261286b565b6001600160a01b0316336001600160a01b03161480612b9b5750608d546001600160a01b031633145b612bdd576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b600c548110158015612bf0575061010081105b612c36576040805162461bcd60e51b815260206004820152601260248201527134b63632b3b0b6103134ba10373ab6b132b960711b604482015290519081900360640190fd5b6000918252605860205260409091208054600190921b9091179055565b612c5b613e5e565b6001600160a01b0316612c6c61286b565b6001600160a01b031614612cb5576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6007601060185481612cc357fe5b061115612cd257612cd26146f9565b6000601060185481612ce057fe5b061115611fb457611fb46146f9565b612cf7613e5e565b6001600160a01b0316826001600160a01b03161415612d5d576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000612d6a613e5e565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612dae613e5e565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b612dfc613e5e565b6001600160a01b0316612e0d61286b565b6001600160a01b031614612e56576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b608c54610100900460ff1615612eb3576040805162461bcd60e51b815260206004820152601760248201527f466f756e6465727320616c7265616479206d696e746564000000000000000000604482015290519081900360640190fd5b60005b600a811015612ef357612ed98282600a8110612ece57fe5b602002015182614791565b600081815260556020526040902060019081905501612eb6565b5050608c805461ff001916610100179055565b600080612f11612286565b11612f57576040805162461bcd60e51b815260206004820152601160248201527013d1c810d85c991cc81cdbdb19081bdd5d607a1b604482015290519081900360640190fd5b601a601f54815481106123bd57fe5b612f77612f71613e5e565b83613edb565b612fb25760405162461bcd60e51b81526004018080602001828103825260318152602001806159ce6031913960400191505060405180910390fd5b612fbe848484846148bf565b50505050565b612fcc613e5e565b6001600160a01b0316612fdd61286b565b6001600160a01b031614613026576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b855161303990601990602089019061561c565b50845161304d90601a90602088019061561c565b50835161306190601b90602087019061561c565b50825161307590601c90602086019061561c565b50815161308990601d90602085019061561c565b50805161309d90601e90602084019061561c565b50600d805460ff1916600117905560408051808201909152601981527f74656d702e65746865722e63617264732f6d657461646174610000000000000060208201526130e8906146e6565b505050505050565b7f0000000000000000000000000000000000000000000000000000000060534ed0421015613158576040805162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd081cdd185c9d195960821b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000606efe504211156131ba576040805162461bcd60e51b815260206004820152600a60248201526914d85b1948195b99195960b21b604482015290519081900360640190fd5b61270f6014541115613205576040805162461bcd60e51b815260206004820152600f60248201526e14dbdc9c9e4b8814dbdb19081bdd5d608a1b604482015290519081900360640190fd5b61320d612276565b15613252576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b61294a81614911565b606061326682613e51565b6132a15760405162461bcd60e51b815260040180806020018281038252602f81526020018061597e602f913960400191505060405180910390fd5b60006132ac83613df1565b905060058160058111156132bc57fe5b14156132e3576040518060600160405280602c8152602001615804602c91399150506116d5565b60606132f160648506614bca565b905060606132fe85614bca565b6040805180820190915260018152602f60f81b602082015290915061332161242e565b8382846040516020018085805190602001908083835b602083106133565780518252601f199092019160209182019101613337565b51815160209384036101000a600019018019909216911617905287519190930192870191508083835b6020831061339e5780518252601f19909201916020918201910161337f565b51815160209384036101000a600019018019909216911617905286519190930192860191508083835b602083106133e65780518252601f1990920191602091820191016133c7565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b6020831061342e5780518252601f19909201916020918201910161340f565b5181516020939093036101000a600019018019909116921691909117905264173539b7b760d91b92019182525060408051808303601a19018152600590920190529b9a5050505050505050505050565b613486613e5e565b6001600160a01b031661349761286b565b6001600160a01b0316146134e0576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600d5460ff1661352d576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b608c54610100900460ff1661357f576040805162461bcd60e51b81526020600482015260136024820152721b5a5b9d08199bdd5b99195c9cc8199a5c9cdd606a1b604482015290519081900360640190fd5b600381106135c8576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642043617264205479706560781b604482015290519081900360640190fd5b608c5460ff1615613612576040805162461bcd60e51b815260206004820152600f60248201526e283932b9b0b6329034b99037bb32b960891b604482015290519081900360640190fd5b60005b82518110156118af5761363b83828151811061362d57fe5b60200260200101518361421a565b600101613615565b60156020526000908152604090205481565b60009081526058602052604090205490565b6000601754601654118015611b795750600b546017546000908152601560209081526040918290205482516313afb27f60e01b8152600481019190915291516001600160a01b03909316926313afb27f926024808201939291829003018186803b1580156136d457600080fd5b505afa1580156136e8573d6000803e3d6000fd5b505050506040513d60208110156136fe57600080fd5b5051905090565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61373b613e5e565b6001600160a01b031661374c61286b565b6001600160a01b031614613795576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6001600160a01b0381166137e9576137ab61286b565b6001600160a01b03166108fc479081150290604051600060405180830381858888f193505050501580156137e3573d6000803e3d6000fd5b5061294a565b806001600160a01b031663a9059cbb61380061286b565b604080516370a0823160e01b815230600482015290516001600160a01b038616916370a08231916024808301926020929190829003018186803b15801561384657600080fd5b505afa15801561385a573d6000803e3d6000fd5b505050506040513d602081101561387057600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b1580156138c157600080fd5b505af11580156138d5573d6000803e3d6000fd5b505050506040513d60208110156118af57600080fd5b60006138f5615656565b60005b60328110156139755760005b60c881101561393d57848260c8028201612710811061391f57fe5b6020020135838260c8811061393057fe5b6020020152600101613904565b5060006139498361240a565b905080605a836032811061395957fe5b01541461396c57600093505050506116d5565b506001016138f8565b5060019392505050565b600080611f2b6019601a8054806020026020016040519081016040528092919081815260200182805480156139d357602002820191906000526020600020905b8154815260200190600101908083116139bf575b5050505050600e54601154601f546140d7565b6139ee613e5e565b6001600160a01b03166139ff61286b565b6001600160a01b031614613a48576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b611fb46146f9565b613a58613e5e565b6001600160a01b0316613a6961286b565b6001600160a01b031614613ab2576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b6001600160a01b038116613af75760405162461bcd60e51b81526004018080602001828103825260268152602001806157ba6026913960400191505060405180910390fd5b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b613b5b613e5e565b6001600160a01b0316613b6c61286b565b6001600160a01b031614613bb5576040805162461bcd60e51b81526020600482018190526024820152600080516020615935833981519152604482015290519081900360640190fd5b600d5460ff16613c02576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b608c54610100900460ff16613c54576040805162461bcd60e51b81526020600482015260136024820152721b5a5b9d08199bdd5b99195c9cc8199a5c9cdd606a1b604482015290519081900360640190fd5b60038110613c9d576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642043617264205479706560781b604482015290519081900360640190fd5b608c5460ff161580613cb25750613cb26120c8565b613cf5576040805162461bcd60e51b815260206004820152600f60248201526e283932b9b0b6329034b99037bb32b960891b604482015290519081900360640190fd5b613cff828261421a565b5050565b6000613d0d6120c8565b15613d1a57506000611774565b7f0000000000000000000000000000000000000000000000000000000060534ed0421015613d4a57506000611774565b61270f6014541115613d5e57506000611774565b50600190565b613d6c61286b565b6001600160a01b0316336001600160a01b03161480613d955750608d546001600160a01b031633145b613dd7576040805162461bcd60e51b815260206004820152600e60248201526d139bdd08105d5d1a1bdc9a5cd95960921b604482015290519081900360640190fd5b80605a8360328110613de557fe5b01555050565b60175481565b6000613dfc82611b7e565b613e08575060056116d5565b600a821015613e19575060046116d5565b6064821015613e2a575060006116d5565b6103e8821015613e3c575060016116d5565b506003919050565b605a816032811061285e57fe5b6000611ad9600283614ca5565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190613e9782612297565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611ad982614cb1565b6000613ee682613e51565b613f215760405162461bcd60e51b815260040180806020018281038252602c815260200180615830602c913960400191505060405180910390fd5b6000613f2c83612297565b9050806001600160a01b0316846001600160a01b03161480613f675750836001600160a01b0316613f5c84611777565b6001600160a01b0316145b80613f775750613f778185613705565b949350505050565b826001600160a01b0316613f9282612297565b6001600160a01b031614613fd75760405162461bcd60e51b81526004018080602001828103825260298152602001806159556029913960400191505060405180910390fd5b6001600160a01b03821661401c5760405162461bcd60e51b81526004018080602001828103825260248152602001806157e06024913960400191505060405180910390fd5b614027838383614cb5565b614032600082613e62565b6001600160a01b03831660009081526001602052604090206140549082614d04565b506001600160a01b03821660009081526001602052604090206140779082614d10565b5061408460028284614d1c565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000611ebd8383614d32565b6000808385018784815481106140e957fe5b906000526020600020015403915060018780549050038310156141245785836001018151811061411557fe5b6020026020010151905061413b565b85838151811061413057fe5b602002602001015190505b9550959350505050565b61414d612276565b614195576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6141cb613e5e565b604080516001600160a01b039092168252519081900360200190a1565b60008080806141f78686614d96565b9097909650945050505050565b60008183106142135781611ebd565b5090919050565b600d5460ff16614267576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b6000614271612347565b9050600061427d611b5b565b9050614287614e11565b826002141561439857600082116142cf5760405162461bcd60e51b81526004018080602001828103825260218152602001806157676021913960400191505060405180910390fd5b601354601054016103e8016142e48582614791565b6013805460010190819055601054601d80546040805160208084028201810190925282815261434e95939092909183018282801561434157602002820191906000526020600020905b81548152602001906001019080831161432d575b5050505050602154614e30565b6021556040805133815234602082015280820183905290517f8cd8e8b2f55e42622fdad0e00fc0d8daf21246a1564886af3b6ad0b1f7f94e0a9181900360600190a1505050613cff565b82600114156144a957600081116143e05760405162461bcd60e51b81526004018080602001828103825260228152602001806157456022913960400191505060405180910390fd5b601254600f54016064016143f48582614791565b6040805133815234602082015280820183905290517f6e69c5ee2c945cc28f9655e03826339ec332b3b7eb055c7dc60aec86674b47e29181900360600190a16012805460010190819055600f54601b80546040805160208084028201810190925282815261449d95939092909183018282801561449057602002820191906000526020600020905b81548152602001906001019080831161447c575b5050505050602054614e30565b60205550613cff915050565b60006144b3612286565b11614505576040805162461bcd60e51b815260206004820152601c60248201527f536f7272792c206e6f204f4720636172647320617661696c61626c6500000000604482015290519081900360640190fd5b601154600e5401600a016145198582614791565b6040805133815234602082015280820183905290517f37a9b963e479fe85bd668e3841cb900a0248efd10e397afe18b3096f37f40ca59181900360600190a16011805460010190819055600e5460198054604080516020808402820181019092528281526145c29593909290918301828280156145b557602002820191906000526020600020905b8154815260200190600101908083116145a1575b5050505050601f54614e30565b601f555050505050565b6000613f77848484614e6c565b6040517f2bccbdacf27af5a4a14fb2d0e8237074c0f3a97f4c73e086175a06d5536ea3b890600090a1600061460c614f36565b60125460135460115492935060109261ffff928492919091010160005b848110156130e85760001982019161464657505050505050611fb4565b614651848716614feb565b94821c94600101614629565b614665612276565b156146aa576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586141cb613e5e565b8051613cff906009906020840190615675565b600b60009054906101000a90046001600160a01b03166001600160a01b0316638678a7b26040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561474957600080fd5b505af115801561475d573d6000803e3d6000fd5b505050506040513d602081101561477357600080fd5b50516016805460018101909155600090815260156020526040902055565b6001600160a01b0382166147ec576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6147f581613e51565b15614847576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b61485360008383614cb5565b6001600160a01b03821660009081526001602052604090206148759082614d10565b5061488260028284614d1c565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6148ca848484613f7f565b6148d6848484846150c8565b612fbe5760405162461bcd60e51b81526004018080602001828103825260328152602001806157886032913960400191505060405180910390fd5b600d5460ff1661495e576040805162461bcd60e51b81526020600482015260136024820152721c1c9a58d94818dd5c9d99481b9bdd081cd95d606a1b604482015290519081900360640190fd5b346000600383106149aa576040805162461bcd60e51b8152602060048201526011602482015270496e76616c69642063617264207479706560781b604482015290519081900360640190fd5b60005b6064811015614b0e57836149ca576149c3612f06565b91506149e6565b83600114156149db576149c361235a565b6149e361294d565b91505b81831015614af05780614a32576040805162461bcd60e51b815260206004820152600f60248201526e139bdd08195b9bdd59da081cd95b9d608a1b604482015290519081900360640190fd5b6022546001600160a01b03166108fc614a4b3486615230565b6040518115909202916000818181858888f19350505050158015614a73573d6000803e3d6000fd5b50604051339084156108fc029085906000818181858888f19350505050158015614aa1573d6000803e3d6000fd5b50604080513381523460208201528082018390526060810185905290517fb7048c2ad36aadee977bb16b4543a18866044d27a2ca753e1c7dbcfa7d7a69629181900360800190a150505061294a565b614afa338561421a565b614b048383615230565b92506001016149ad565b506022546001600160a01b03166108fc614b283485615230565b6040518115909202916000818181858888f19350505050158015614b50573d6000803e3d6000fd5b50604051339083156108fc029084906000818181858888f19350505050158015614b7e573d6000803e3d6000fd5b50604080513381523460208201526064818301526060810184905290517fb7048c2ad36aadee977bb16b4543a18866044d27a2ca753e1c7dbcfa7d7a69629181900360800190a1505050565b606081614bef57506040805180820190915260018152600360fc1b60208201526116d5565b8160005b8115614c0757600101600a82049150614bf3565b60608167ffffffffffffffff81118015614c2057600080fd5b506040519080825280601f01601f191660200182016040528015614c4b576020820181803683370190505b50859350905060001982015b8315614c9c57600a840660300160f81b82828060019003935081518110614c7a57fe5b60200101906001600160f81b031916908160001a905350600a84049350614c57565b50949350505050565b6000611ebd838361528d565b5490565b614cc08383836118af565b614cc8612276565b156118af5760405162461bcd60e51b815260040180806020018281038252602b81526020018061571a602b913960400191505060405180910390fd5b6000611ebd83836152a5565b6000611ebd838361536b565b6000613f7784846001600160a01b0385166153b5565b81546000908210614d745760405162461bcd60e51b81526004018080602001828103825260228152602001806156f86022913960400191505060405180910390fd5b826000018281548110614d8357fe5b9060005260206000200154905092915050565b815460009081908310614dda5760405162461bcd60e51b81526004018080602001828103825260228152602001806158e76022913960400191505060405180910390fd5b6000846000018481548110614deb57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b601880546001810190915560109006600f1415611fb457611fb46146f9565b60006001835103821415614e45575080613f77565b828281518110614e5157fe5b602002602001015184860111156120fc575060018101613f77565b60008281526001840160205260408120548281614f075760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614ecc578181015183820152602001614eb4565b50505050905090810190601f168015614ef95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110614f1a57fe5b9060005260206000209060020201600101549150509392505050565b6000614f40613667565b614f86576040805162461bcd60e51b81526020600482015260126024820152714e6f7468696e6720746f2070726f6365737360701b604482015290519081900360640190fd5b600b54601780546001810190915560009081526015602090815260409182902054825163205a1e3960e11b8152600481019190915291516001600160a01b03909316926340b43c72926024808201939291829003018186803b1580156136d457600080fd5b601354600090829015615018576010805460018101909155601380546000190190556103e801915061506d565b6012541561503f57600f80546001810190915560128054600019019055606401915061506d565b6011541561506657600e80546001810190915560118054600019019055600a01915061506d565b505061294a565b60008281526055602090815260409182902060016103ff851601908190558251858152918201819052825190927f422ac4ddfd5e11612221e380b75b24e9aff8bf16fbb187544e2764b78e289137928290030190a150505050565b60006150dc846001600160a01b031661544c565b6150e857506001613f77565b60606151f6630a85bd0160e11b6150fd613e5e565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561516457818101518382015260200161514c565b50505050905090810190601f1680156151915780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001615788603291396001600160a01b0388169190615452565b9050600081806020019051602081101561520f57600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b600082821115615287576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60009081526001919091016020526040902054151590565b6000818152600183016020526040812054801561536157835460001980830191908101906000908790839081106152d857fe5b90600052602060002001549050808760000184815481106152f557fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061532557fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050611ad9565b6000915050611ad9565b6000615377838361528d565b6153ad57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611ad9565b506000611ad9565b60008281526001840160205260408120548061541a575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611ebd565b8285600001600183038154811061542d57fe5b9060005260206000209060020201600101819055506000915050611ebd565b3b151590565b6060613f778484600085856154668561544c565b6154b7576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106154f65780518252601f1990920191602091820191016154d7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615558576040519150601f19603f3d011682016040523d82523d6000602084013e61555d565b606091505b509150915061556d828286615578565b979650505050505050565b60608315615587575081611ebd565b8251156155975782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315614ecc578181015183820152602001614eb4565b826032810192821561560c579160200282015b8281111561560c5782518255916020019190600101906155f1565b506156189291506156e2565b5090565b82805482825590600052602060002090810192821561560c579160200282018281111561560c5782518255916020019190600101906155f1565b60405180611900016040528060c8906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106156b657805160ff191683800117855561560c565b8280016001018555821561560c579182018281111561560c5782518255916020019190600101906155f1565b5b8082111561561857600081556001016156e356fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732315061757361626c653a20746f6b656e207472616e73666572207768696c6520706175736564536f727279202d206e6f20416c706861207469636b65747320617661696c61626c65536f727279206e6f2072616e646f6d207469636b65747320617661696c61626c654552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f206164647265737368747470733a2f2f74656d702e65746865722e63617264732f6d657461646174612f556e7265736f6c7665644552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665645468697320646174612063616e206e6f206c6f6e676572206265206368616e676564a2646970667358221220d8ff33e2b85e68f29135427088442bda3fcc302afb136b99bbe51c0735e3177664736f6c63430007030033

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

0000000000000000000000005638bf5c73d8aa7f7926954f7415e52230efe9bd0000000000000000000000000000000000000000000000000000000060534ed000000000000000000000000000000000000000000000000000000000606efe500000000000000000000000006a80d451135720c51af81ecb4334a1a94b3a6055000000000000000000000000a218b55ec696cc32b388fc97334db41dab48d8e1

-----Decoded View---------------
Arg [0] : _rng (address): 0x5638Bf5C73D8aa7f7926954F7415E52230EFe9bD
Arg [1] : _start (uint256): 1616072400
Arg [2] : _end (uint256): 1617886800
Arg [3] : _wallet (address): 0x6a80D451135720C51aF81EcB4334a1a94B3A6055
Arg [4] : _oracle (address): 0xa218b55eC696cc32b388fc97334db41dAb48d8E1

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000005638bf5c73d8aa7f7926954f7415e52230efe9bd
Arg [1] : 0000000000000000000000000000000000000000000000000000000060534ed0
Arg [2] : 00000000000000000000000000000000000000000000000000000000606efe50
Arg [3] : 0000000000000000000000006a80d451135720c51af81ecb4334a1a94b3a6055
Arg [4] : 000000000000000000000000a218b55ec696cc32b388fc97334db41dab48d8e1


Deployed Bytecode Sourcemap

64338:21894:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41847:150;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41847:150:0;-1:-1:-1;;;;;;41847:150:0;;:::i;:::-;;;;;;;;;;;;;;;;;;65083:22;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;51324:100;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54119:221;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54119:221:0;;:::i;:::-;;;;-1:-1:-1;;;;;54119:221:0;;;;;;;;;;;;;;53649:404;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;53649:404:0;;;;;;;;:::i;:::-;;79390:884;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79390:884:0;;;;;;:::i;65112:22::-;;;;;;;;;;;;;:::i;85365:463::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73927:119;;;;;;;;;;;;;:::i;53127:211::-;;;;;;;;;;;;;:::i;81696:127::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81696:127:0;;:::i;55009:305::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;55009:305:0;;;;;;;;;;;;;;;;;:::i;80282:679::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;80282:679:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;80282:679:0;;;;;;;;;;;;;;;;;;-1:-1:-1;80282:679:0;;-1:-1:-1;80282:679:0;;-1:-1:-1;;;;80282:679:0:i;72349:189::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72349:189:0;;:::i;52889:162::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;52889:162:0;;;;;;;;:::i;82775:176::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;66476:35;;;;;;;;;;;;;:::i;86158:69::-;;;;;;;;;;;;;:::i;65541:52::-;;;;;;;;;;;;;:::i;55385:151::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;55385:151:0;;;;;;;;;;;;;;;;;:::i;79064:318::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79064:318:0;;;;;;:::i;78273:134::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78273:134:0;;-1:-1:-1;78273:134:0;;-1:-1:-1;;;;78273:134:0:i;65197:25::-;;;;;;;;;;;;;:::i;82292:129::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82292:129:0;;:::i;85248:105::-;;;;;;;;;;;;;:::i;53415:172::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53415:172:0;;:::i;72574:111::-;;;;;;;;;;;;;:::i;77491:633::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77491:633:0;;;;;;-1:-1:-1;;;;;77491:633:0;;:::i;43156:86::-;;;;;;;;;;;;;:::i;73803:116::-;;;;;;;;;;;;;:::i;51080:177::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51080:177:0;;:::i;84090:83::-;;;;;;;;;;;;;:::i;74054:120::-;;;;;;;;;;;;;:::i;74345:178::-;;;;;;;;;;;;;:::i;72693:198::-;;;;;;;;;;;;;:::i;65417:55::-;;;;;;;;;;;;;:::i;78415:132::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78415:132:0;;-1:-1:-1;78415:132:0;;-1:-1:-1;;;;78415:132:0:i;52708:97::-;;;;;;;;;;;;;:::i;68389:148::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68389:148:0;;-1:-1:-1;68389:148:0;;-1:-1:-1;;;;68389:148:0:i;50797:221::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50797:221:0;-1:-1:-1;;;;;50797:221:0;;:::i;46240:148::-;;;;;;;;;;;;;:::i;65299:33::-;;;;;;;;;;;;;:::i;72927:77::-;;;;;;;;;;;;;:::i;65261:25::-;;;;;;;;;;;;;:::i;73486:124::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;73486:124:0;-1:-1:-1;;;;;73486:124:0;;:::i;82597:172::-;;;;;;;;;;;;;:::i;65141:22::-;;;;;;;;;;;;;:::i;86085:65::-;;;;;;;;;;;;;:::i;66103:40::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66103:40:0;;:::i;65229:25::-;;;;;;;;;;;;;:::i;45589:87::-;;;;;;;;;;;;;:::i;85092:106::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;85092:106:0;;:::i;83906:176::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;83906:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;83906:176:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83906:176:0;;-1:-1:-1;83906:176:0;;-1:-1:-1;;;;;83906:176:0:i;74531:175::-;;;;;;;;;;;;;:::i;73617:148::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;73617:148:0;-1:-1:-1;;;;;73617:148:0;;:::i;51493:104::-;;;;;;;;;;;;;:::i;71594:145::-;;;;;;;;;;;;;:::i;72104:237::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72104:237:0;;;;;;;:::i;71360:226::-;;;;;;;;;;;;;:::i;54412:295::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;54412:295:0;;;;;;;;;;:::i;71774:299::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71774:299:0;;-1:-1:-1;71774:299:0;;-1:-1:-1;;;;71774:299:0:i;74182:155::-;;;;;;;;;;;;;:::i;55607:285::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55607:285:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55607:285:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55607:285:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55607:285:0;;-1:-1:-1;55607:285:0;;-1:-1:-1;;;;;55607:285:0:i;68545:538::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68545:538:0;;;;;;;;-1:-1:-1;68545:538:0;;-1:-1:-1;;;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68545:538:0;;;;;;;;-1:-1:-1;68545:538:0;;-1:-1:-1;;;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68545:538:0;;;;;;;;-1:-1:-1;68545:538:0;;-1:-1:-1;;;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68545:538:0;;;;;;;;-1:-1:-1;68545:538:0;;-1:-1:-1;;;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68545:538:0;;;;;;;;-1:-1:-1;68545:538:0;;-1:-1:-1;;;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68545:538:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68545:538:0;;-1:-1:-1;68545:538:0;;-1:-1:-1;;;;;68545:538:0:i;69260:121::-;;;;;;;;;;;;;;;;-1:-1:-1;69260:121:0;;:::i;84181:617::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84181:617:0;;:::i;70560:423::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;70560:423:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;70560:423:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70560:423:0;;-1:-1:-1;;70560:423:0;;;-1:-1:-1;70560:423:0;;-1:-1:-1;;70560:423:0:i;65360:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65360:50:0;;:::i;81833:113::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81833:113:0;;:::i;81034:185::-;;;;;;;;;;;;;:::i;54778:164::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;54778:164:0;;;;;;;;;;:::i;83338:294::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83338:294:0;-1:-1:-1;;;;;83338:294:0;;:::i;78603:453::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78603:453:0;:::i;82433:156::-;;;;;;;;;;;;;:::i;81550:88::-;;;;;;;;;;;;;:::i;46543:244::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46543:244:0;-1:-1:-1;;;;;46543:244:0;;:::i;70995:357::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;70995:357:0;;;;;;;;:::i;84856:228::-;;;;;;;;;;;;;:::i;78138:127::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78138:127:0;;;;;;;:::i;65479:55::-;;;;;;;;;;;;;:::i;81954:329::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81954:329:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;66518:36;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66518:36:0;;:::i;41847:150::-;-1:-1:-1;;;;;;41956:33:0;;41932:4;41956:33;;;;;;;;;;;;;41847:150;;;;:::o;65083:22::-;;;;:::o;51324:100::-;51411:5;51404:12;;;;;;;;-1:-1:-1;;51404:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51378:13;;51404:12;;51411:5;;51404:12;;51411:5;51404:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51324:100;;:::o;54119:221::-;54195:7;54223:16;54231:7;54223;:16::i;:::-;54215:73;;;;-1:-1:-1;;;54215:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54308:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;54308:24:0;;54119:221::o;53649:404::-;53730:13;53746:23;53761:7;53746:14;:23::i;:::-;53730:39;;53794:5;-1:-1:-1;;;;;53788:11:0;:2;-1:-1:-1;;;;;53788:11:0;;;53780:57;;;;-1:-1:-1;;;53780:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53874:5;-1:-1:-1;;;;;53858:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;53858:21:0;;:69;;;;53883:44;53907:5;53914:12;:10;:12::i;:::-;53883:23;:44::i;:::-;53850:161;;;;-1:-1:-1;;;53850:161:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54024:21;54033:2;54037:7;54024:8;:21::i;:::-;53649:404;;;:::o;79390:884::-;79487:4;79524:5;79513:8;:16;79504:45;;;;;-1:-1:-1;;;79504:45:0;;;;;;;;;;;;-1:-1:-1;;;79504:45:0;;;;;;;;;;;;;;;79576:2;79565:8;:13;79561:30;;;-1:-1:-1;79587:4:0;79580:11;;79561:30;79629:8;79641:3;79629:15;79625:32;;;-1:-1:-1;79653:4:0;79646:11;;79625:32;79687:8;79699:4;79687:16;79683:33;;;-1:-1:-1;79712:4:0;79705:11;;79683:33;79743:12;79758;79771:8;79758:22;;;;;;;;;;;79743:37;;79791:14;79808:12;79830:1;79821:8;:10;79808:24;;;;;;;;;;;79791:41;;79851:16;79859:7;79851;:16::i;:::-;79843:48;;;;;-1:-1:-1;;;79843:48:0;;;;;;;;;;;;-1:-1:-1;;;79843:48:0;;;;;;;;;;;;;;;79910:18;79918:9;79910:7;:18::i;:::-;79902:55;;;;;-1:-1:-1;;;79902:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;79997:19;80006:9;79997:8;:19::i;:::-;79976:40;;;;;;;;:17;79985:7;79976:8;:17::i;:::-;:40;;;;;;;;;79968:75;;;;;-1:-1:-1;;;79968:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;80090:31;;;;:20;:31;;;;;;;80058:29;;;;;;:63;80054:80;;;80130:4;80123:11;;;;;;80054:80;80181:31;;;;:20;:31;;;;;;;80149:29;;;;;;:63;80145:81;;;80221:5;80214:12;;;;;;80145:81;-1:-1:-1;80245:19:0;-1:-1:-1;79390:884:0;;;;;:::o;65112:22::-;;;;:::o;85365:463::-;85411:9;85422:10;85434:12;85448;85499:11;;85481:15;:29;85473:50;;;;;-1:-1:-1;;;85473:50:0;;;;;;;;;;;;-1:-1:-1;;;85473:50:0;;;;;;;;;;;;;;;-1:-1:-1;;85545:11:0;;85599:12;85559:15;85545:29;;;85592:20;;;;85676:7;85629:21;;;;85669:15;;;;-1:-1:-1;85743:2:0;85701:15;;;85737:8;;;;-1:-1:-1;85766:8:0;;;;;85365:463::o;73927:119::-;74027:8;;74019:5;;74010:25;64727:3;74002:34;-1:-1:-1;;74002:36:0;;73927:119::o;53127:211::-;53188:7;53309:21;:12;:19;:21::i;:::-;53302:28;;53127:211;:::o;81696:127::-;81758:4;81782:29;;;:20;:29;;;;;;:33;;;81696:127::o;55009:305::-;55170:41;55189:12;:10;:12::i;:::-;55203:7;55170:18;:41::i;:::-;55162:103;;;;-1:-1:-1;;;55162:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55278:28;55288:4;55294:2;55298:7;55278:9;:28::i;80282:679::-;80453:16;80470:9;80453:27;;;;;;;;;80433:18;80441:9;80433:7;:18::i;:::-;:47;80425:77;;;;;-1:-1:-1;;;80425:77:0;;;;;;;;;;;;-1:-1:-1;;;80425:77:0;;;;;;;;;;;;;;;80539:11;80551:9;80539:22;;;;;;;;;80521:16;80529:7;80521;:16::i;:::-;:40;80513:73;;;;;-1:-1:-1;;;80513:73:0;;;;;;;;;;;;-1:-1:-1;;;80513:73:0;;;;;;;;;;;;;;;80600:12;80615:9;80625:12;80615:23;;;;;;;;;;;;-1:-1:-1;80677:10:0;80657:16;80615:23;80657:7;:16::i;:::-;-1:-1:-1;;;;;80657:30:0;;80649:56;;;;;-1:-1:-1;;;80649:56:0;;;;;;;;;;;;-1:-1:-1;;;80649:56:0;;;;;;;;;;;;;;;80720:19;;;;:10;:19;;;;;;80716:231;;80783:7;80791:12;80783:21;;;;;;;;;;;80761:10;:19;80772:7;80761:19;;;;;;;;;;;:43;;;;80824:44;80838:7;80846;80854:12;80846:21;;;;;;;;;;;80824:44;;;;;;;;;;;;;;;;;;;;;;;;80716:231;;;80906:29;;;;;;;;;;;;;;;;;80716:231;80282:679;;;;;:::o;72349:189::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;72433:18:::1;::::0;:23;72425:66:::1;;;::::0;;-1:-1:-1;;;72425:66:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;72502:18;:28:::0;72349:189::o;52889:162::-;-1:-1:-1;;;;;53013:20:0;;52986:7;53013:20;;;:13;:20;;;;;:30;;53037:5;53013:23;:30::i;:::-;53006:37;52889:162;-1:-1:-1;;;52889:162:0:o;82775:176::-;82821:12;82835:17;82876:67;82886:11;82899:12;82876:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82913:5;;82919:8;;82928:14;;82876:9;:67::i;:::-;82869:74;;;;82775:176;;:::o;66476:35::-;;;;:::o;86158:69::-;67687:7;:5;:7::i;:::-;-1:-1:-1;;;;;67673:21:0;:10;-1:-1:-1;;;;;67673:21:0;;:62;;;-1:-1:-1;67725:10:0;;-1:-1:-1;;;;;67725:10:0;67711;:24;67673:62;67651:102;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;;;;86209:10:::1;:8;:10::i;:::-;86158:69::o:0;65541:52::-;;;;:::o;55385:151::-;55489:39;55506:4;55512:2;55516:7;55489:39;;;;;;;;;;;;:16;:39::i;79064:318::-;79164:15;79181:13;79212:6;79207:131;79228:6;79224:1;:10;79207:131;;;79271:12;79284:1;79271:15;;;;;;;;;;;79260:7;:26;79256:70;;;79316:3;79314:5;;;;-1:-1:-1;79320:5:0;;;-1:-1:-1;79306:20:0;;79256:70;79236:3;;79207:131;;;-1:-1:-1;79348:26:0;;;-1:-1:-1;;;79348:26:0;;;;;;;;;;;;-1:-1:-1;;;79348:26:0;;;;;;;;;;;;;;;79064:318;;;;;:::o;78273:134::-;78339:7;78393:4;78376:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78366:33;;;;;;78359:40;;78273:134;;;:::o;65197:25::-;;;;:::o;82292:129::-;82357:7;82384:29;;;:20;:29;;;;;;;82292:129::o;85248:105::-;85336:8;85318:15;:26;85248:105;:::o;53415:172::-;53490:7;;53532:22;:12;53548:5;53532:15;:22::i;:::-;-1:-1:-1;53510:44:0;53415:172;-1:-1:-1;;;53415:172:0:o;72574:111::-;72669:8;;72658;;72647;;:19;:30;72574:111;:::o;77491:633::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;77582:14:::1;:12;:14::i;:::-;77574:46;;;::::0;;-1:-1:-1;;;77574:46:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;77574:46:0;;;;;;;;;;;;;::::1;;77651:1;77639:9;:13;77631:42;;;::::0;;-1:-1:-1;;;77631:42:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;77631:42:0;;;;;;;;;;;;;::::1;;77684:14;77723:2;77740:14:::0;77736:230:::1;;77768:14;:12;:14::i;:::-;77756:26;;77736:230;;;77802:9;77815:1;77802:14;77798:168;;;77830:17;:15;:17::i;77798:168::-;77867:9;77880:1;77867:14;77863:103;;;77910:18;:16;:18::i;:::-;77898:30;;77952:2;77943:11;;77863:103;77988:26;77997:9;78007:6;77988:8;:26::i;:::-;77976:38;;78030:6;78025:92;78046:9;78042:1;:13;78025:92;;;78077:28;78088:6;78095:9;78077:10;:28::i;:::-;78057:3;;78025:92;;43156:86:::0;43227:7;;-1:-1:-1;;;43227:7:0;;;;;43156:86::o;73803:116::-;73900:8;;73892:5;;73883:25;64692:2;73875:34;-1:-1:-1;;73875:36:0;;73803:116::o;51080:177::-;51152:7;51179:70;51196:7;51179:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;84090:83::-;67687:7;:5;:7::i;:::-;-1:-1:-1;;;;;67673:21:0;:10;-1:-1:-1;;;;;67673:21:0;;:62;;;-1:-1:-1;67725:10:0;;-1:-1:-1;;;;;67725:10:0;67711;:24;67673:62;67651:102;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;;;;84148:10:::1;:17:::0;;-1:-1:-1;;;;84148:17:0::1;-1:-1:-1::0;;;84148:17:0::1;::::0;;84090:83::o;74054:120::-;74155:8;;74147:5;;74138:25;64763:4;74130:34;-1:-1:-1;;74130:36:0;;74054:120::o;74345:178::-;74389:7;74437:1;74417:17;:15;:17::i;:::-;:21;74409:53;;;;;-1:-1:-1;;;74409:53:0;;;;;;;;;;;;-1:-1:-1;;;74409:53:0;;;;;;;;;;;;;;;74481:11;74493:13;;74481:26;;;;;;;;;;;;;;;;74474:33;;74345:178;:::o;72693:198::-;72740:4;72757:10;72770:2;72757:15;;72834:5;72823:8;;72812;;72801;;:19;:30;:38;:60;;;;64763:4;72843:11;;:18;72801:60;72800:83;;;;;72866:17;:15;:17::i;:::-;72793:90;;;72693:198;:::o;65417:55::-;;;;:::o;78415:132::-;78516:22;;78479:7;;78533:4;;78516:22;;;78533:4;78516:22;;;78533:4;78479:7;78516:22;;;;;;;;;;;;52708:97;52789:8;52782:15;;;;;;;;-1:-1:-1;;52782:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52756:13;;52782:15;;52789:8;;52782:15;;52789:8;52782:15;;;;;;;;;;;;;;;;;;;;;;;;68389:148;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;68476:26:::1;:11;68490:12:::0;68476:26:::1;;:::i;:::-;-1:-1:-1::0;68518:11:0::1;::::0;::::1;::::0;;;::::1;68389:148:::0;:::o;50797:221::-;50869:7;-1:-1:-1;;;;;50897:19:0;;50889:74;;;;-1:-1:-1;;;50889:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50981:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;46240:148::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;46331:6:::1;::::0;46310:40:::1;::::0;46347:1:::1;::::0;-1:-1:-1;;;;;46331:6:0::1;::::0;46310:40:::1;::::0;46347:1;;46310:40:::1;46361:6;:19:::0;;-1:-1:-1;;;;;;46361:19:0::1;::::0;;46240:148::o;65299:33::-;;;;:::o;72927:77::-;67565:6;;;;;-1:-1:-1;;;;;67565:6:0;67551:10;:20;67543:46;;;;;-1:-1:-1;;;67543:46:0;;;;;;;;;;;;-1:-1:-1;;;67543:46:0;;;;;;;;;;;;;;;72983:13:::1;:11;:13::i;65261:25::-:0;;;;:::o;73486:124::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;73552:6:::1;:16:::0;;-1:-1:-1;;;;;73552:16:0;::::1;::::0;;::::1;-1:-1:-1::0;;;;;;73552:16:0;;::::1;::::0;;;::::1;::::0;;;73584:18:::1;::::0;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;73486:124:::0;:::o;82597:172::-;82642:12;82656:17;82697:64;82707:10;82719:11;82697:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82732:5;;82738:8;;82747:13;;82697:9;:64::i;65141:22::-;;;;:::o;86085:65::-;67687:7;:5;:7::i;:::-;-1:-1:-1;;;;;67673:21:0;:10;-1:-1:-1;;;;;67673:21:0;;:62;;;-1:-1:-1;67725:10:0;;-1:-1:-1;;;;;67725:10:0;67711;:24;67673:62;67651:102;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;;;;86134:8:::1;:6;:8::i;66103:40::-:0;;;;;;;;;;;;;-1:-1:-1;66103:40:0;:::o;65229:25::-;;;;:::o;45589:87::-;45662:6;;-1:-1:-1;;;;;45662:6:0;45589:87;:::o;85092:106::-;85150:4;85174:16;85182:7;85174;:16::i;83906:176::-;67687:7;:5;:7::i;:::-;-1:-1:-1;;;;;67673:21:0;:10;-1:-1:-1;;;;;67673:21:0;;:62;;;-1:-1:-1;67725:10:0;;-1:-1:-1;;;;;67725:10:0;67711;:24;67673:62;67651:102;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;;;;83994:10:::1;::::0;-1:-1:-1;;;83994:10:0;::::1;;;83993:11;83985:57;;;;-1:-1:-1::0;;;83985:57:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84053:21;84065:8;84053:11;:21::i;:::-;83906:176:::0;:::o;74531:175::-;74576:7;74625:1;74604:18;:16;:18::i;:::-;:22;74596:55;;;;;-1:-1:-1;;;74596:55:0;;;;;;;;;;;;-1:-1:-1;;;74596:55:0;;;;;;;;;;;;;;;74670:12;74683:14;;74670:28;;;;;;;73617:148;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;73691:10:::1;:24:::0;;-1:-1:-1;;;;;73691:24:0;::::1;-1:-1:-1::0;;;;;;73691:24:0;;::::1;::::0;::::1;::::0;;;73731:26:::1;::::0;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;73617:148:::0;:::o;51493:104::-;51582:7;51575:14;;;;;;;;-1:-1:-1;;51575:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51549:13;;51575:14;;51582:7;;51575:14;;51582:7;51575:14;;;;;;;;;;;;;;;;;;;;;;;;71594:145;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;71655:13:::1;:11;:13::i;:::-;71679:14;:21:::0;;-1:-1:-1;;71679:21:0::1;71696:4;71679:21;::::0;;71716:15:::1;::::0;::::1;::::0;71679:14:::1;::::0;71716:15:::1;71594:145::o:0;72104:237::-;67687:7;:5;:7::i;:::-;-1:-1:-1;;;;;67673:21:0;:10;-1:-1:-1;;;;;67673:21:0;;:62;;;-1:-1:-1;67725:10:0;;-1:-1:-1;;;;;67725:10:0;67711;:24;67673:62;67651:102;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;;;;72218:18:::1;;72205:9;:31;;72204:54;;;;;72254:3;72242:9;:15;72204:54;72196:85;;;::::0;;-1:-1:-1;;;72196:85:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;72196:85:0;;;;;;;;;;;;;::::1;;72292:19;::::0;;;:10:::1;:19;::::0;;;;;:41;;72318:1:::1;:14:::0;;::::1;72292:41:::0;;::::1;::::0;;72104:237::o;71360:226::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;71449:1:::1;71444:2;71425:16;;:21;;;;;;:25;71421:74;;;71467:16;:14;:16::i;:::-;71533:1;71528:2;71509:16;;:21;;;;;;:25;71505:74;;;71551:16;:14;:16::i;54412:295::-:0;54527:12;:10;:12::i;:::-;-1:-1:-1;;;;;54515:24:0;:8;-1:-1:-1;;;;;54515:24:0;;;54507:62;;;;;-1:-1:-1;;;54507:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54627:8;54582:18;:32;54601:12;:10;:12::i;:::-;-1:-1:-1;;;;;54582:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;54582:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;54582:53:0;;;;;;;;;;;54666:12;:10;:12::i;:::-;-1:-1:-1;;;;;54651:48:0;;54690:8;54651:48;;;;;;;;;;;;;;;;;;;;54412:295;;:::o;71774:299::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;71864:13:::1;::::0;::::1;::::0;::::1;;;71863:14;71855:50;;;::::0;;-1:-1:-1;;;71855:50:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;71921:6;71916:119;71937:2;71933:1;:6;71916:119;;;71961:20;71967:8;71976:1;71967:11;;;;;;;;;;;71979:1;71961:5;:20::i;:::-;71996:23;::::0;;;:20:::1;:23;::::0;;;;72022:1:::1;71996:27:::0;;;;71941:3:::1;71916:119;;;-1:-1:-1::0;;72045:13:0::1;:20:::0;;-1:-1:-1;;72045:20:0::1;;;::::0;;71774:299::o;74182:155::-;74223:7;74268:1;74251:14;:12;:14::i;:::-;:18;74243:47;;;;;-1:-1:-1;;;74243:47:0;;;;;;;;;;;;-1:-1:-1;;;74243:47:0;;;;;;;;;;;;;;;74309:8;74318:10;;74309:20;;;;;;;55607:285;55739:41;55758:12;:10;:12::i;:::-;55772:7;55739:18;:41::i;:::-;55731:103;;;;-1:-1:-1;;;55731:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55845:39;55859:4;55865:2;55869:7;55878:5;55845:13;:39::i;:::-;55607:285;;;;:::o;68545:538::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;68800:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;68829:20:0;;::::1;::::0;:8:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;68860:24:0;;::::1;::::0;:10:::1;::::0;:24:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;68895:26:0;;::::1;::::0;:11:::1;::::0;:26:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;68932:26:0;;::::1;::::0;:11:::1;::::0;:26:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;68969:28:0;;::::1;::::0;:12:::1;::::0;:28:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;69008:9:0::1;:16:::0;;-1:-1:-1;;69008:16:0::1;69020:4;69008:16;::::0;;69035:40:::1;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;:11:::1;:40::i;:::-;68545:538:::0;;;;;;:::o;69260:121::-;74775:10;74756:15;:29;;74748:57;;;;;-1:-1:-1;;;74748:57:0;;;;;;;;;;;;-1:-1:-1;;;74748:57:0;;;;;;;;;;;;;;;74843:8;74824:15;:27;;74816:49;;;;;-1:-1:-1;;;74816:49:0;;;;;;;;;;;;-1:-1:-1;;;74816:49:0;;;;;;;;;;;;;;;64763:4;74884:11;;:19;;74876:47;;;;;-1:-1:-1;;;74876:47:0;;;;;;;;;;;;-1:-1:-1;;;74876:47:0;;;;;;;;;;;;;;;43482:8:::1;:6;:8::i;:::-;43481:9;43473:38;;;::::0;;-1:-1:-1;;;43473:38:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;43473:38:0;;;;;;;;;;;;;::::1;;69347:26:::2;69363:9;69347:15;:26::i;84181:617::-:0;84246:13;84280:16;84288:7;84280;:16::i;:::-;84272:76;;;;-1:-1:-1;;;84272:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84359:11;84373:17;84382:7;84373:8;:17::i;:::-;84359:31;-1:-1:-1;84411:19:0;84405:2;:25;;;;;;;;;84401:111;;;84447:53;;;;;;;;;;;;;;;;;;;;;;84401:111;84575:20;84598:26;84609:3;84599:7;:13;84598:24;:26::i;:::-;84575:49;;84636:18;84657;:7;:16;:18::i;:::-;84686:25;;;;;;;;;;;;-1:-1:-1;;;84686:25:0;;;;84636:39;;-1:-1:-1;84753:9:0;:7;:9::i;:::-;84763:6;84770:5;84776:4;84736:53;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84736:53:0;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84736:53:0;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84736:53:0;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;;;;-1:-1:-1;;;84736:53:0;;;;;-1:-1:-1;84736:53:0;;;;;;-1:-1:-1;;84736:53:0;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;84181:617:0:o;70560:423::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;70669:9:::1;::::0;::::1;;70661:40;;;::::0;;-1:-1:-1;;;70661:40:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;70661:40:0;;;;;;;;;;;;;::::1;;70721:13;::::0;::::1;::::0;::::1;;;70713:45;;;::::0;;-1:-1:-1;;;70713:45:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;70713:45:0;;;;;;;;;;;;;::::1;;70789:1;70777:9;:13;70769:44;;;::::0;;-1:-1:-1;;;70769:44:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;70769:44:0;;;;;;;;;;;;;::::1;;70833:14;::::0;::::1;;70832:15;70824:42;;;::::0;;-1:-1:-1;;;70824:42:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;70824:42:0;;;;;;;;;;;;;::::1;;70882:6;70877:99;70898:6;:13;70894:1;:17;70877:99;;;70933:31;70944:6;70951:1;70944:9;;;;;;;;;;;;;;70954;70933:10;:31::i;:::-;70913:3;;70877:99;;65360:50:::0;;;;;;;;;;;;;:::o;81833:113::-;81892:7;81919:19;;;:10;:19;;;;;;;81833:113::o;81034:185::-;81082:4;81129:19;;81107;;:41;81106:105;;;;-1:-1:-1;81153:3:0;;81190:19;;81153:3;81175:35;;;:14;:35;;;;;;;;;;81153:58;;-1:-1:-1;;;81153:58:0;;;;;;;;;;;-1:-1:-1;;;;;81153:3:0;;;;:21;;:58;;;;;81175:35;81153:58;;;;;;:3;:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81153:58:0;81099:112;;81034:185;:::o;54778:164::-;-1:-1:-1;;;;;54899:25:0;;;54875:4;54899:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;54778:164::o;83338:294::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;83401:60:0;::::1;83397:228;;83486:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;83478:25:0::1;:48;83504:21;83478:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;83397:228;;;83559:5;-1:-1:-1::0;;;;;83559:14:0::1;;83574:7;:5;:7::i;:::-;83582:30;::::0;;-1:-1:-1;;;83582:30:0;;83606:4:::1;83582:30;::::0;::::1;::::0;;;-1:-1:-1;;;;;83582:15:0;::::1;::::0;::::1;::::0;:30;;;;;::::1;::::0;;;;;;;;:15;:30;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;83582:30:0;83559:54:::1;::::0;;-1:-1:-1;;;;;;83559:54:0::1;::::0;;;;;;-1:-1:-1;;;;;83559:54:0;;::::1;;::::0;::::1;::::0;;;;;;;;;;;;;;83582:30:::1;::::0;83559:54;;;;;;;-1:-1:-1;83559:54:0;;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;78603:453:::0;78681:4;78698:24;;:::i;:::-;78738:8;78733:292;78758:2;78752:3;:8;78733:292;;;78790:6;78785:92;78806:3;78802:1;:7;78785:92;;;78845:5;78853:3;78857;78853:7;78851:1;:9;78845:16;;;;;;;;;;;78835:4;78840:1;78835:7;;;;;;;;;;:26;78811:3;;78785:92;;;;78891:11;78905:13;78913:4;78905:7;:13::i;:::-;78891:27;;78960:3;78936:16;78953:3;78936:21;;;;;;;;;:27;78933:81;;78992:5;78984:14;;;;;;;78933:81;-1:-1:-1;78762:5:0;;78733:292;;;-1:-1:-1;79043:4:0;;78603:453;-1:-1:-1;;;78603:453:0:o;82433:156::-;82475:12;82489:17;82526:55;82536:7;82545:8;82526:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82555:5;;82561:8;;82570:10;;82526:9;:55::i;81550:88::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;81614:16:::1;:14;:16::i;46543:244::-:0;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;46632:22:0;::::1;46624:73;;;;-1:-1:-1::0;;;46624:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46734:6;::::0;46713:38:::1;::::0;-1:-1:-1;;;;;46713:38:0;;::::1;::::0;46734:6:::1;::::0;46713:38:::1;::::0;46734:6:::1;::::0;46713:38:::1;46762:6;:17:::0;;-1:-1:-1;;;;;;46762:17:0::1;-1:-1:-1::0;;;;;46762:17:0;;;::::1;::::0;;;::::1;::::0;;46543:244::o;70995:357::-;45820:12;:10;:12::i;:::-;-1:-1:-1;;;;;45809:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;45809:23:0;;45801:68;;;;;-1:-1:-1;;;45801:68:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45801:68:0;;;;;;;;;;;;;;;71089:9:::1;::::0;::::1;;71081:40;;;::::0;;-1:-1:-1;;;71081:40:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;71081:40:0;;;;;;;;;;;;;::::1;;71141:13;::::0;::::1;::::0;::::1;;;71133:45;;;::::0;;-1:-1:-1;;;71133:45:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;71133:45:0;;;;;;;;;;;;;::::1;;71209:1;71197:9;:13;71189:43;;;::::0;;-1:-1:-1;;;71189:43:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;71189:43:0;;;;;;;;;;;;;::::1;;71253:14;::::0;::::1;;71252:15;::::0;71251:35:::1;;;71272:14;:12;:14::i;:::-;71243:63;;;::::0;;-1:-1:-1;;;71243:63:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;71243:63:0;;;;;;;;;;;;;::::1;;71317:27;71328:5;71334:9;71317:10;:27::i;:::-;70995:357:::0;;:::o;84856:228::-;84901:4;84922:14;:12;:14::i;:::-;84918:32;;;-1:-1:-1;84945:5:0;84938:12;;84918:32;84983:10;84965:15;:28;84961:46;;;-1:-1:-1;85002:5:0;84995:12;;84961:46;64763:4;85022:11;;:18;85018:36;;;-1:-1:-1;85049:5:0;85042:12;;85018:36;-1:-1:-1;85072:4:0;84856:228;:::o;78138:127::-;67687:7;:5;:7::i;:::-;-1:-1:-1;;;;;67673:21:0;:10;-1:-1:-1;;;;;67673:21:0;;:62;;;-1:-1:-1;67725:10:0;;-1:-1:-1;;;;;67725:10:0;67711;:24;67673:62;67651:102;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;-1:-1:-1;;;67651:102:0;;;;;;;;;;;;;;;78252:5:::1;78228:16;78245:3;78228:21;;;;;;;;:29:::0;-1:-1:-1;;78138:127:0:o;65479:55::-;;;;:::o;81954:329::-;82008:8;82034:22;82049:6;82034:14;:22::i;:::-;82029:55;;-1:-1:-1;82065:19:0;82058:26;;82029:55;64580:2;82099:6;:15;82095:44;;;-1:-1:-1;82123:16:0;82116:23;;82095:44;64617:3;82154:6;:15;82150:39;;;-1:-1:-1;82178:11:0;82171:18;;82150:39;64655:4;82204:6;:15;82200:42;;;-1:-1:-1;82228:14:0;82221:21;;82200:42;-1:-1:-1;82260:15:0;81954:329;;;:::o;66518:36::-;;;;;;;;;57359:127;57424:4;57448:30;:12;57470:7;57448:21;:30::i;25446:106::-;25534:10;25446:106;:::o;63266:183::-;63332:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;63332:29:0;-1:-1:-1;;;;;63332:29:0;;;;;;;;:24;;63386:23;63332:24;63386:14;:23::i;:::-;-1:-1:-1;;;;;63377:46:0;;;;;;;;;;;63266:183;;:::o;22984:123::-;23053:7;23080:19;23088:3;23080:7;:19::i;57653:355::-;57746:4;57771:16;57779:7;57771;:16::i;:::-;57763:73;;;;-1:-1:-1;;;57763:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57847:13;57863:23;57878:7;57863:14;:23::i;:::-;57847:39;;57916:5;-1:-1:-1;;;;;57905:16:0;:7;-1:-1:-1;;;;;57905:16:0;;:51;;;;57949:7;-1:-1:-1;;;;;57925:31:0;:20;57937:7;57925:11;:20::i;:::-;-1:-1:-1;;;;;57925:31:0;;57905:51;:94;;;;57960:39;57984:5;57991:7;57960:23;:39::i;:::-;57897:103;57653:355;-1:-1:-1;;;;57653:355:0:o;60789:599::-;60914:4;-1:-1:-1;;;;;60887:31:0;:23;60902:7;60887:14;:23::i;:::-;-1:-1:-1;;;;;60887:31:0;;60879:85;;;;-1:-1:-1;;;60879:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;61001:16:0;;60993:65;;;;-1:-1:-1;;;60993:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61071:39;61092:4;61098:2;61102:7;61071:20;:39::i;:::-;61175:29;61192:1;61196:7;61175:8;:29::i;:::-;-1:-1:-1;;;;;61217:19:0;;;;;;:13;:19;;;;;:35;;61244:7;61217:26;:35::i;:::-;-1:-1:-1;;;;;;61263:17:0;;;;;;:13;:17;;;;;:30;;61285:7;61263:21;:30::i;:::-;-1:-1:-1;61306:29:0;:12;61323:7;61332:2;61306:16;:29::i;:::-;;61372:7;61368:2;-1:-1:-1;;;;;61353:27:0;61362:4;-1:-1:-1;;;;;61353:27:0;;;;;;;;;;;60789:599;;;:::o;36442:137::-;36513:7;36548:22;36552:3;36564:5;36548:3;:22::i;82959:367::-;83097:12;83111:17;83172:7;83165:4;:14;83148:4;83153:7;83148:13;;;;;;;;;;;;;;;;:32;83141:39;;83219:1;83205:4;:11;;;;:15;83195:7;:25;83191:127;;;83247:5;83253:7;83261:1;83253:9;83247:16;;;;;;;;;;;;;;83235:28;;83191:127;;;83304:5;83310:7;83304:14;;;;;;;;;;;;;;83292:26;;83191:127;82959:367;;;;;;;;:::o;44215:120::-;43759:8;:6;:8::i;:::-;43751:41;;;;;-1:-1:-1;;;43751:41:0;;;;;;;;;;;;-1:-1:-1;;;43751:41:0;;;;;;;;;;;;;;;44274:7:::1;:15:::0;;-1:-1:-1;;;;44274:15:0::1;::::0;;44305:22:::1;44314:12;:10;:12::i;:::-;44305:22;::::0;;-1:-1:-1;;;;;44305:22:0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;44215:120::o:0;23446:236::-;23526:7;;;;23586:22;23590:3;23602:5;23586:3;:22::i;:::-;23555:53;;;;-1:-1:-1;23446:236:0;-1:-1:-1;;;;;23446:236:0:o;26936:106::-;26994:7;27025:1;27021;:5;:13;;27033:1;27021:13;;;-1:-1:-1;27029:1:0;;26936:106;-1:-1:-1;26936:106:0:o;75109:1353::-;75191:9;;;;75183:40;;;;;-1:-1:-1;;;75183:40:0;;;;;;;;;;;;-1:-1:-1;;;75183:40:0;;;;;;;;;;;;;;;75244:21;75268:18;:16;:18::i;:::-;75244:42;;75297:20;75320:17;:15;:17::i;:::-;75297:40;;75348:26;:24;:26::i;:::-;75389:9;75402:1;75389:14;75385:770;;;75447:1;75428:16;:20;75420:66;;;;-1:-1:-1;;;75420:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75526:8;;75520:5;;75513:21;64655:4;75513:21;75549:17;75555:5;75513:21;75549:5;:17::i;:::-;75581:8;:10;;;;;;;;75628:5;;75647:11;75623:51;;;;;;;;;;;;;;;;;;;;;75581:10;75623:51;;75647:11;;75623:51;;75647:11;75623:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75659:14;;75623:4;:51::i;:::-;75606:14;:68;75694:42;;;75709:10;75694:42;;75721:9;75694:42;;;;;;;;;;;;;;;;;;;;;75751:7;;;;;75385:770;75779:9;75792:1;75779:14;75775:380;;;75838:1;75820:15;:19;75811:66;;;;-1:-1:-1;;;75811:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75916:8;;75910:5;;75903:21;64617:3;75903:21;75939:17;75945:5;75903:21;75939:5;:17::i;:::-;75976:41;;;75990:10;75976:41;;76002:9;75976:41;;;;;;;;;;;;;;;;;;;;;76032:8;:10;;;;;;;;76078:5;;76097:10;76073:49;;;;;;;;;;;;;;;;;;;;;76032:10;76073:49;;76097:10;;76073:49;;76097:10;76073:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76108:13;;76073:4;:49::i;:::-;76057:13;:65;-1:-1:-1;76137:7:0;;-1:-1:-1;;76137:7:0;75775:380;76191:1;76174:14;:12;:14::i;:::-;:18;76165:60;;;;;-1:-1:-1;;;76165:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;76263:8;;76257:5;;76248:23;64580:2;76248:23;76282:17;76288:5;76248:23;76282:5;:17::i;:::-;76315:38;;;76326:10;76315:38;;76338:9;76315:38;;;;;;;;;;;;;;;;;;;;;76364:8;:10;;;;;;;;76403:5;;76418:7;76398:39;;;;;;;;;;;;;;;;;;;;;76364:10;76398:39;;76418:7;;76398:39;;76418:7;76398:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76426:10;;76398:4;:39::i;:::-;76385:10;:52;-1:-1:-1;;;75109:1353:0;;:::o;24732:213::-;24839:7;24890:44;24895:3;24915;24921:12;24890:4;:44::i;73012:466::-;73060:15;;;;;;;73086:11;73100:12;:10;:12::i;:::-;73256:8;;73246;;73235;;73086:26;;-1:-1:-1;73142:2:0;;73167:6;;73142:2;;73235:19;;;;:29;73129:10;73275:196;73296:5;73292:1;:9;73275:196;;;-1:-1:-1;;73327:9:0;;;73323:61;;73362:7;;;;;;;;73323:61;73398:22;73415:4;73406:6;:13;73398:7;:22::i;:::-;73444:15;;;;73303:3;;73275:196;;43956:118;43482:8;:6;:8::i;:::-;43481:9;43473:38;;;;;-1:-1:-1;;;43473:38:0;;;;;;;;;;;;-1:-1:-1;;;43473:38:0;;;;;;;;;;;;;;;44016:7:::1;:14:::0;;-1:-1:-1;;;;44016:14:0::1;-1:-1:-1::0;;;44016:14:0::1;::::0;;44046:20:::1;44053:12;:10;:12::i;61989:100::-:0;62062:19;;;;:8;;:19;;;;;:::i;81423:119::-;81509:3;;;;;;;;;-1:-1:-1;;;;;81509:3:0;-1:-1:-1;;;;;81509:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81509:25:0;81484:19;:21;;;;;;;;81469:37;;;;:14;81509:25;81469:37;;;;:65;81423:119::o;59274:404::-;-1:-1:-1;;;;;59354:16:0;;59346:61;;;;;-1:-1:-1;;;59346:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59427:16;59435:7;59427;:16::i;:::-;59426:17;59418:58;;;;;-1:-1:-1;;;59418:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59489:45;59518:1;59522:2;59526:7;59489:20;:45::i;:::-;-1:-1:-1;;;;;59547:17:0;;;;;;:13;:17;;;;;:30;;59569:7;59547:21;:30::i;:::-;-1:-1:-1;59590:29:0;:12;59607:7;59616:2;59590:16;:29::i;:::-;-1:-1:-1;59637:33:0;;59662:7;;-1:-1:-1;;;;;59637:33:0;;;59654:1;;59637:33;;59654:1;;59637:33;59274:404;;:::o;56774:272::-;56888:28;56898:4;56904:2;56908:7;56888:9;:28::i;:::-;56935:48;56958:4;56964:2;56968:7;56977:5;56935:22;:48::i;:::-;56927:111;;;;-1:-1:-1;;;56927:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69391:1081;69460:9;;;;69452:40;;;;;-1:-1:-1;;;69452:40:0;;;;;;;;;;;;-1:-1:-1;;;69452:40:0;;;;;;;;;;;;;;;69518:9;69503:12;69579:1;69567:13;;69559:43;;;;;-1:-1:-1;;;69559:43:0;;;;;;;;;;;;-1:-1:-1;;;69559:43:0;;;;;;;;;;;;;;;69618:6;69613:692;69634:3;69630:1;:7;69613:692;;;69663:14;69659:220;;69706:10;:8;:10::i;:::-;69698:18;;69659:220;;;69743:9;69756:1;69743:14;69739:140;;;69787:13;:11;:13::i;69739:140::-;69849:14;:12;:14::i;:::-;69841:22;;69739:140;69907:5;69897:7;:15;69893:311;;;69937:6;69933:44;;69945:32;;;-1:-1:-1;;;69945:32:0;;;;;;;;;;;;-1:-1:-1;;;69945:32:0;;;;;;;;;;;;;;;70004:6;;-1:-1:-1;;;;;70004:6:0;69996:48;70021:22;:9;70035:7;70021:13;:22::i;:::-;69996:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70063:37:0;;70071:10;;70063:37;;;;;70092:7;;70063:37;;;;70092:7;70071:10;70063:37;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70124:39:0;;;70131:10;70124:39;;70142:9;70124:39;;;;;;;;;;;;;;;;;;;;;;;;;;;70182:7;;;;;69893:311;70218:32;70229:10;70240:9;70218:10;:32::i;:::-;70275:18;:7;70287:5;70275:11;:18::i;:::-;70265:28;-1:-1:-1;69639:3:0;;69613:692;;;-1:-1:-1;70323:6:0;;-1:-1:-1;;;;;70323:6:0;70315:48;70340:22;:9;70354:7;70340:13;:22::i;:::-;70315:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70374:37:0;;70382:10;;70374:37;;;;;70403:7;;70374:37;;;;70403:7;70382:10;70374:37;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70427:41:0;;;70434:10;70427:41;;70445:9;70427:41;;;;70456:3;70427:41;;;;;;;;;;;;;;;;;;;;;69391:1081;;;:::o;25913:746::-;25969:13;26190:10;26186:53;;-1:-1:-1;26217:10:0;;;;;;;;;;;;-1:-1:-1;;;26217:10:0;;;;;;26186:53;26264:5;26249:12;26305:78;26312:9;;26305:78;;26338:8;;26369:2;26361:10;;;;26305:78;;;26393:19;26425:6;26415:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26415:17:0;-1:-1:-1;26487:5:0;;-1:-1:-1;26393:39:0;-1:-1:-1;;;26459:10:0;;26503:117;26510:9;;26503:117;;26579:2;26572:4;:9;26567:2;:14;26554:29;;26536:6;26543:7;;;;;;;26536:15;;;;;;;;;;;:47;-1:-1:-1;;;;;26536:47:0;;;;;;;;-1:-1:-1;26606:2:0;26598:10;;;;26503:117;;;-1:-1:-1;26644:6:0;25913:746;-1:-1:-1;;;;25913:746:0:o;22745:151::-;22829:4;22853:35;22863:3;22883;22853:9;:35::i;19563:110::-;19646:19;;19563:110::o;85836:241::-;85946:45;85973:4;85979:2;85983:7;85946:26;:45::i;:::-;86013:8;:6;:8::i;:::-;86012:9;86004:65;;;;-1:-1:-1;;;86004:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35529:137;35599:4;35623:35;35631:3;35651:5;35623:7;:35::i;35222:131::-;35289:4;35313:32;35318:3;35338:5;35313:4;:32::i;22168:185::-;22257:4;22281:64;22286:3;22306;-1:-1:-1;;;;;22320:23:0;;22281:4;:64::i;31480:204::-;31575:18;;31547:7;;31575:26;-1:-1:-1;31567:73:0;;;;-1:-1:-1;;;31567:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31658:3;:11;;31670:5;31658:18;;;;;;;;;;;;;;;;31651:25;;31480:204;;;;:::o;20028:279::-;20132:19;;20095:7;;;;20132:27;-1:-1:-1;20124:74:0;;;;-1:-1:-1;;;20124:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20211:22;20236:3;:12;;20249:5;20236:19;;;;;;;;;;;;;;;;;;20211:44;;20274:5;:10;;;20286:5;:12;;;20266:33;;;;;20028:279;;;;;:::o;74953:145::-;75015:16;:18;;;;;;;;75036:2;;75015:23;75042:2;75015:29;75011:78;;;75061:16;:14;:16::i;77192:287::-;77288:7;77337:1;77323:4;:11;:15;77312:7;:26;77308:46;;;-1:-1:-1;77347:7:0;77340:14;;77308:46;77387:4;77392:7;77387:13;;;;;;;;;;;;;;77377:7;77370:4;:14;:30;77366:81;;;-1:-1:-1;77434:1:0;77424:11;;77417:18;;21525:319;21619:7;21658:17;;;:12;;;:17;;;;;;21709:12;21694:13;21686:36;;;;-1:-1:-1;;;21686:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21776:3;:12;;21800:1;21789:8;:12;21776:26;;;;;;;;;;;;;;;;;;:33;;;21769:40;;;21525:319;;;;;:::o;81227:188::-;81267:7;81295:17;:15;:17::i;:::-;81287:47;;;;;-1:-1:-1;;;81287:47:0;;;;;;;;;;;;-1:-1:-1;;;81287:47:0;;;;;;;;;;;;;;;81352:3;;81384:19;:21;;81352:3;81384:21;;;;;81352:3;81369:37;;;:14;:37;;;;;;;;;;81352:55;;-1:-1:-1;;;81352:55:0;;;;;;;;;;;-1:-1:-1;;;;;81352:3:0;;;;:16;;:55;;;;;81369:37;81352:55;;;;;;:3;:55;;;;;;;;;;76470:714;76669:8;;76548:16;;76648:6;;76669:12;76665:359;;76718:5;:7;;;;;;;;76740:8;:10;;-1:-1:-1;;76740:10:0;;;64655:4;76709:16;;-1:-1:-1;76665:359:0;;;76772:8;;:12;76768:256;;76821:5;:7;;;;;;;;76843:8;:10;;-1:-1:-1;;76843:10:0;;;64617:3;76812:16;;-1:-1:-1;76768:256:0;;;76875:8;;:12;76871:153;;76922:5;:7;;;;;;;;76944:8;:10;;-1:-1:-1;;76944:10:0;;;64580:2;76915:14;;-1:-1:-1;76871:153:0;;;76989:7;;;;76871:153;77034:14;77094:30;;;:20;:30;;;;;;;;;77075:1;64867:5;77052:21;;77051:25;77094:39;;;;77149:27;;;;;;;;;;;;;77051:25;;77149:27;;;;;;;;76470:714;;;;:::o;62654:604::-;62775:4;62802:15;:2;-1:-1:-1;;;;;62802:13:0;;:15::i;:::-;62797:60;;-1:-1:-1;62841:4:0;62834:11;;62797:60;62867:23;62893:252;-1:-1:-1;;;63006:12:0;:10;:12::i;:::-;63033:4;63052:7;63074:5;62909:181;;;;;;-1:-1:-1;;;;;62909:181:0;;;;;;-1:-1:-1;;;;;62909:181:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62909:181:0;;;;;;;-1:-1:-1;;;;;62909:181:0;;;;;;;;;;;62893:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62893:15:0;;;:252;:15;:252::i;:::-;62867:278;;63156:13;63183:10;63172:32;;;;;;;;;;;;;;;-1:-1:-1;63172:32:0;-1:-1:-1;;;;;;63223:26:0;-1:-1:-1;;;63223:26:0;;-1:-1:-1;;;62654:604:0;;;;;;:::o;3674:158::-;3732:7;3765:1;3760;:6;;3752:49;;;;;-1:-1:-1;;;3752:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3819:5:0;;;3674:158::o;19343:125::-;19414:4;19438:17;;;:12;;;;;:17;;;;;;:22;;;19343:125::o;29182:1544::-;29248:4;29387:19;;;:12;;;:19;;;;;;29423:15;;29419:1300;;29858:18;;-1:-1:-1;;29809:14:0;;;;29858:22;;;;29785:21;;29858:3;;:22;;30145;;;;;;;;;;;;;;30125:42;;30291:9;30262:3;:11;;30274:13;30262:26;;;;;;;;;;;;;;;;;;;:38;;;;30368:23;;;30410:1;30368:12;;;:23;;;;;;30394:17;;;30368:43;;30520:17;;30368:3;;30520:17;;;;;;;;;;;;;;;;;;;;;;30615:3;:12;;:19;30628:5;30615:19;;;;;;;;;;;30608:26;;;30658:4;30651:11;;;;;;;;29419:1300;30702:5;30695:12;;;;;28592:414;28655:4;28677:21;28687:3;28692:5;28677:9;:21::i;:::-;28672:327;;-1:-1:-1;28715:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;28898:18;;28876:19;;;:12;;;:19;;;;;;:40;;;;28931:11;;28672:327;-1:-1:-1;28982:5:0;28975:12;;16843:692;16919:4;17054:17;;;:12;;;:17;;;;;;17088:13;17084:444;;-1:-1:-1;;17173:38:0;;;;;;;;;;;;;;;;;;17155:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;17370:19;;17350:17;;;:12;;;:17;;;;;;;:39;17404:11;;17084:444;17484:5;17448:3;:12;;17472:1;17461:8;:12;17448:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;17511:5;17504:12;;;;;8489:422;8856:20;8895:8;;;8489:422::o;11407:195::-;11510:12;11542:52;11564:6;11572:4;11578:1;11581:12;11510;12711:18;12722:6;12711:10;:18::i;:::-;12703:60;;;;;-1:-1:-1;;;12703:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;12837:12;12851:23;12878:6;-1:-1:-1;;;;;12878:11:0;12898:5;12906:4;12878:33;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12878:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12836:75;;;;12929:52;12947:7;12956:10;12968:12;12929:17;:52::i;:::-;12922:59;12459:530;-1:-1:-1;;;;;;;12459:530:0:o;14999:742::-;15114:12;15143:7;15139:595;;;-1:-1:-1;15174:10:0;15167:17;;15139:595;15288:17;;:21;15284:439;;15551:10;15545:17;15612:15;15599:10;15595:2;15591:19;15584:44;15499:148;15687:20;;-1:-1:-1;;;15687:20:0;;;;;;;;;;;;;;;;;15694:12;;15687:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

ipfs://d8ff33e2b85e68f29135427088442bda3fcc302afb136b99bbe51c0735e31776
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.