ETH Price: $3,046.56 (+0.75%)
Gas: 3 Gwei

Token

ENIGMA (ENIGMA)
 

Overview

Max Total Supply

476 ENIGMA

Holders

146

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
delso.eth
Balance
8 ENIGMA
0x641C2fEF13fb417dB01EF955a54904a6400F8b07
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
EnigmaProject

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


pragma solidity ^0.8.0;

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


pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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;
}


pragma solidity ^0.8.0;

//import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
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);
}


pragma solidity ^0.8.0;

//import "../IERC721.sol";

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

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




pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
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);
}


pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
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) {
        unchecked {
            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) {
        unchecked {
            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) {
        unchecked {
            // 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) {
        unchecked {
            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) {
        unchecked {
            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) {
        return a + b;
    }

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

    /**
     * @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.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        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) {
        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) {
        unchecked {
            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.
     *
     * 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) {
        unchecked {
            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) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}


pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // 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;
        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");

        (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");

        (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");

        (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");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
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;

            if (lastIndex != toDeleteIndex) {
                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] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // 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) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

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

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}


pragma solidity ^0.8.0;

//import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
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() {
        _transferOwnership(_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 {
        _transferOwnership(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");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}


pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

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


pragma solidity ^0.8.0;

//import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

pragma solidity ^0.8.0;

/*
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
*/

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

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

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

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @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 _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @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 baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @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 || 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 _owners[tokenId] != address(0);
    }

    /**
     * @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 || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `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);

        _balances[to] += 1;
        _owners[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);

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

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

        _balances[owner] -= 1;
        delete _owners[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");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @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()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @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` and `to` are never both zero.
     *
     * 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 {}
}


pragma solidity ^0.8.0;

//import "../ERC721.sol";
//import "./IERC721Enumerable.sol";

/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is IERC721Enumerable, ERC721 {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @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 override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}


pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal 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);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: @openzeppelin/contracts/utils/EnumerableMap.sol ????


pragma solidity ^0.8.6;
pragma abicoder v2;

contract EnigmaProject is ERC721Enumerable, ReentrancyGuard, Ownable {
    
    using SafeMath for uint256;

    uint256 public constant price = 20000000000000000; // 0.02 ETH

    uint public constant maxPurchase = 20;

    uint256 public constant MAX_TOKENS = 10000;

    uint public tokenReserve = 50;
    
    struct Enigma{
      bytes32 hash;
      address winner;
    }
    
    uint public submissionLockDate;
    address public submissionLockAddress;
    
    bool public gameIsLive = false;
    
    mapping(uint => Enigma) public enigmas; 
     
    string[] private first = [
        "A",
        "B",
        "C",
        "D",
        "E",
        "F"
    ];

    string[] private second = [
        "G",
        "H",
        "I",
        "J",
        "K"
    ];

    string[] private third = [
        "L",
        "M",
        "N",
        "O",
        "P"
    ];

    string[] private fourth = [
        "Q",
        "R",
        "S",
        "T",
        "U"
    ];

    string[] private fifth = [
        "V",
        "W",
        "X",
        "Y",
        "Z"
    ];


    constructor() ERC721("ENIGMA", "ENIGMA") { 
    }
    
    receive() external payable {
    }
    
    event LogEnigmaSolved(uint enigmaId,address Solver);
    
    function addEnigma(uint _enigmaIndex,bytes32 _hash) public onlyOwner {
        require(enigmas[_enigmaIndex].winner == address(0), "Enigma solved and cannot be replaced.");
        enigmas[_enigmaIndex].hash = _hash;
    }
    
    function getEnigma(uint _enigmaIndex) public view returns (bytes32, address) {
        require(enigmas[_enigmaIndex].hash != 0, "This enigma does not exist.");
        bytes32 hash = enigmas[_enigmaIndex].hash;
        address winner = enigmas[_enigmaIndex].winner;
        return (hash, winner);
    }
      


    function flipGameStatus() public onlyOwner {
        gameIsLive = !gameIsLive;
    }
    
    
    function withdraw(uint256 amount) public onlyOwner {
        payable(msg.sender).transfer(amount);
    }
    
    function lockSubmissions() public returns(string memory ) {
        require(gameIsLive, "The game is not live.");
        require(submissionLockDate == 0 || block.timestamp > submissionLockDate + 15 minutes,"Submissions are currently locked for 15 minutes.");
        require(submissionLockAddress != msg.sender,"You cannot lock submissions twice in a row.");
        submissionLockDate = block.timestamp;
        submissionLockAddress = msg.sender;
        return "Submissions successfully locked to your wallet. You have 15 minutes to submit your solution.";
    }
    
    
    
    function solveEnigma(uint _enigmaIndex, string memory _solution) public returns (string memory )  {
        require(gameIsLive, "The game is not live.");
        require(bytes(_solution).length > 0, "Solutions can't be empty.");
        require(enigmas[_enigmaIndex].winner ==  address(0), "Someone has already solved this enigma.");
        require(submissionLockAddress == msg.sender,"Please lock submissions before submitting a solution.");
            
        bool hasAllCharacters = checkOwnerHasAllCharacters(_solution);
        
        if(hasAllCharacters)
        {
            if (keccak256(abi.encodePacked(_solution)) == enigmas[_enigmaIndex].hash) {
                enigmas[_enigmaIndex].winner = msg.sender;
                emit LogEnigmaSolved(_enigmaIndex,msg.sender);
                payable(msg.sender).transfer(1000000000000000000); // 1 ETH
                return "Congratulations, you win!";
            }
        }
        else
        {
          return "You do not hold tokens containing all the characters in your solution.";
        }
        
        return "Sorry, wrong solution.";
    }

    
    
    function mint(uint numberOfTokens) public payable {
        require(numberOfTokens > 0 && numberOfTokens <= maxPurchase, "Can only mint 20 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= MAX_TOKENS, "Purchase would exceed max supply of Tokens");
        require(msg.value >= price.mul(numberOfTokens), "Ether value sent is incorrect");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply();
            if (totalSupply() < MAX_TOKENS) {
                _safeMint(msg.sender, mintIndex);
            }
        }

    }
     

    function reserveTokens(address _to, uint256 _reserveAmount) public onlyOwner {        
        uint supply = totalSupply();
        require(_reserveAmount > 0 && _reserveAmount <= tokenReserve, "Not enough tokens left.");
        for (uint i = 0; i < _reserveAmount; i++) {
            _safeMint(_to, supply + i);
        }
        tokenReserve = tokenReserve.sub(_reserveAmount);
    }

    function tokensOfOwner(address _owner) internal view returns(uint256[] memory ) {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }

    function random(string memory input) internal pure returns (uint256) {
        return uint256(keccak256(abi.encodePacked(input)));
    }
    
    function getTokenCharacters(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        
        string memory output = string(abi.encodePacked(pluck(tokenId, "FIRST", first),pluck(tokenId, "SECOND", second),pluck(tokenId, "THIRD", third),pluck(tokenId, "FOURTH", fourth), pluck(tokenId, "FIFTH", fifth)));
        return output ;
    }
    

    function pluck(uint256 tokenId,string memory prefix,string[] memory array) internal pure returns (string memory) {
        uint256 rand = random(string(abi.encodePacked(prefix, toString(tokenId))));
        string memory output = array[rand % array.length];
        return output;
    }
    
    function existsInToken(uint256 tokenId,bytes1 singleCharacter) internal view returns (bool) {
        
        bytes memory characters = bytes(getTokenCharacters(tokenId));
        bool found = false;
        
        for (uint i=0; i<characters.length; i++) {
            
            if(keccak256(abi.encodePacked((characters[i]))) == keccak256(abi.encodePacked((singleCharacter))))
            {
                found = true;
                break;
            }
            
        }
        
        return found;
    }
    
    
    function checkOwnerHasAllCharacters(string memory solution) internal view returns (bool) {
        bytes memory byteSolution = bytes(solution);
        
        address owner = msg.sender;
        uint256[] memory all_sender_tokens = tokensOfOwner(owner);

        bool all_characters_found = true;
        
        
        for (uint i=0; i<byteSolution.length; i++) {
            bool character_found = false;
            for (uint j=0; j<all_sender_tokens.length; j++) {
                
                if(existsInToken(all_sender_tokens[j],byteSolution[i]))
                {
                    character_found = true;
                    break;
                }
                
            }
            
            if(character_found == false)
            {
                all_characters_found = false;
                break;
            }
        }
        
        return all_characters_found;
    }
    
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        string[11] memory parts;
        parts[0] = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 350"><style>.base { fill: white; font-family: serif; font-size: 14px; }</style><rect width="100%" height="100%" fill="black" /><text x="10" y="20" class="base">';

        parts[1] = pluck(tokenId, "FIRST", first);

        parts[2] = '</text><text x="10" y="40" class="base">';

        parts[3] = pluck(tokenId, "SECOND", second);

        parts[4] = '</text><text x="10" y="60" class="base">';

        parts[5] = pluck(tokenId, "THIRD", third);

        parts[6] = '</text><text x="10" y="80" class="base">';

        parts[7] = pluck(tokenId, "FOURTH", fourth);

        parts[8] = '</text><text x="10" y="100" class="base">';

        parts[9] = pluck(tokenId, "FIFTH", fifth);

        parts[10] = "</text></svg>";

        string memory output = string(
            abi.encodePacked(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8])
        );
        output = string(abi.encodePacked(output,parts[9],parts[10]));

        string memory json = Base64.encode(
            bytes(
                string(
                    abi.encodePacked(
                        '{"name": "EnigmaToken #',
                        toString(tokenId),
                        '", "description": "Enigma NFTs", "image": "data:image/svg+xml;base64,',
                        Base64.encode(bytes(output)),
                        '"}'
                    )
                )
            )
        );
        output = string(abi.encodePacked("data:application/json;base64,", json));

        return output;
    }


   function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // 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);
    while (value != 0) {
        digits -= 1;
        buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
        value /= 10;
    }
    return string(buffer);
} 

}
    
    
    
/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"uint256","name":"enigmaId","type":"uint256"},{"indexed":false,"internalType":"address","name":"Solver","type":"address"}],"name":"LogEnigmaSolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_enigmaIndex","type":"uint256"},{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"addEnigma","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"enigmas","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"address","name":"winner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipGameStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gameIsLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_enigmaIndex","type":"uint256"}],"name":"getEnigma","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenCharacters","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[],"name":"lockSubmissions","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"name":"reserveTokens","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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_enigmaIndex","type":"uint256"},{"internalType":"string","name":"_solution","type":"string"}],"name":"solveEnigma","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"submissionLockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"submissionLockDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"tokenReserve","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":"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":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6032600c55600e805460ff60a01b191690556001610140818152604160f81b610160526080908152610180828152602160f91b6101a05260a0526101c0828152604360f81b6101e05260c052610200828152601160fa1b6102205260e052610240828152604560f81b61026052610100526102c0604052610280918252602360f91b6102a052610120919091526200009c906010906006620003d5565b506040805160e081018252600160a08201818152604760f81b60c0840152825282518084018452818152600960fb1b6020828101919091528084019190915283518085018552828152604960f81b818301528385015283518085018552828152602560f91b8183015260608401528351808501909452908352604b60f81b9083015260808101919091526200013690601190600562000439565b506040805160e081018252600160a08201818152601360fa1b60c0840152825282518084018452818152604d60f81b6020828101919091528084019190915283518085018552828152602760f91b818301528385015283518085018552828152604f60f81b8183015260608401528351808501909452908352600560fc1b908301526080810191909152620001d090601290600562000439565b506040805160e081018252600160a08201818152605160f81b60c0840152825282518084018452818152602960f91b6020828101919091528084019190915283518085018552828152605360f81b818301528385015283518085018552828152601560fa1b8183015260608401528351808501909452908352605560f81b9083015260808101919091526200026a90601390600562000439565b506040805160e081018252600160a08201818152602b60f91b60c0840152825282518084018452818152605760f81b6020828101919091528084019190915283518085018552828152600b60fb1b818301528385015283518085018552828152605960f81b8183015260608401528351808501909452908352602d60f91b9083015260808101919091526200030490601490600562000439565b503480156200031257600080fd5b50604080518082018252600680825265454e49474d4160d01b60208084018281528551808701909652928552840152815191929162000354916000916200048b565b5080516200036a9060019060208401906200048b565b50506001600a55506200037d3362000383565b620005cd565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805482825590600052602060002090810192821562000427579160200282015b82811115620004275782518051620004169184916020909101906200048b565b5091602001919060010190620003f6565b506200043592915062000516565b5090565b82805482825590600052602060002090810192821562000427579160200282015b828111156200042757825180516200047a9184916020909101906200048b565b50916020019190600101906200045a565b828054620004999062000590565b90600052602060002090601f016020900481019282620004bd576000855562000508565b82601f10620004d857805160ff191683800117855562000508565b8280016001018555821562000508579182015b8281111562000508578251825591602001919060010190620004eb565b506200043592915062000537565b80821115620004355760006200052d82826200054e565b5060010162000516565b5b8082111562000435576000815560010162000538565b5080546200055c9062000590565b6000825580601f106200056d575050565b601f0160209004906000526020600020908101906200058d919062000537565b50565b600181811c90821680620005a557607f821691505b60208210811415620005c757634e487b7160e01b600052602260045260246000fd5b50919050565b613b5c80620005dd6000396000f3fe6080604052600436106101d35760003560e01c8063715018a6116100f8578063b88d4fde11610090578063b88d4fde14610555578063c87b56dd14610575578063cbcb317114610595578063cc0dcec7146105ab578063d414d0c2146105cb578063d6c28573146105ec578063e985e9c514610602578063f2fde38b14610622578063f47c84c51461064257600080fd5b8063715018a61461047e57806378cf19e9146104935780638da5cb5b146104b357806395d89b41146104c8578063977b055b146104dd578063989a5c41146104f2578063a035b1fe14610507578063a0712d6814610522578063a22cb4651461053557600080fd5b80632f745c591161016b5780632f745c591461032f578063364861021461034f57806342842e0e1461036f5780634f6ccce71461038f5780636352211e146103af57806363f71af4146103cf57806368cee4331461040c5780636f5e50501461044957806370a082311461045e57600080fd5b806301ffc9a7146101df57806306fdde0314610214578063081812fc14610236578063095ea7b31461026e57806318160ddd1461029057806323b872dd146102af578063247889c3146102cf57806328cbc4b5146102ef5780632e1a7d4d1461030f57600080fd5b366101da57005b600080fd5b3480156101eb57600080fd5b506101ff6101fa3660046131ba565b610658565b60405190151581526020015b60405180910390f35b34801561022057600080fd5b50610229610683565b60405161020b91906135c7565b34801561024257600080fd5b506102566102513660046131f4565b610715565b6040516001600160a01b03909116815260200161020b565b34801561027a57600080fd5b5061028e610289366004613190565b6107a2565b005b34801561029c57600080fd5b506008545b60405190815260200161020b565b3480156102bb57600080fd5b5061028e6102ca36600461309c565b6108b3565b3480156102db57600080fd5b506102296102ea3660046131f4565b6108e4565b3480156102fb57600080fd5b5061028e61030a36600461320d565b610df3565b34801561031b57600080fd5b5061028e61032a3660046131f4565b610eaa565b34801561033b57600080fd5b506102a161034a366004613190565b610f0a565b34801561035b57600080fd5b50600e54610256906001600160a01b031681565b34801561037b57600080fd5b5061028e61038a36600461309c565b610fa0565b34801561039b57600080fd5b506102a16103aa3660046131f4565b610fbb565b3480156103bb57600080fd5b506102566103ca3660046131f4565b61104e565b3480156103db57600080fd5b506103ef6103ea3660046131f4565b6110c5565b604080519283526001600160a01b0390911660208301520161020b565b34801561041857600080fd5b506103ef6104273660046131f4565b600f60205260009081526040902080546001909101546001600160a01b031682565b34801561045557600080fd5b5061022961114a565b34801561046a57600080fd5b506102a161047936600461304e565b611299565b34801561048a57600080fd5b5061028e611320565b34801561049f57600080fd5b5061028e6104ae366004613190565b61135b565b3480156104bf57600080fd5b50610256611435565b3480156104d457600080fd5b50610229611444565b3480156104e957600080fd5b506102a1601481565b3480156104fe57600080fd5b5061028e611453565b34801561051357600080fd5b506102a166470de4df82000081565b61028e6105303660046131f4565b6114a3565b34801561054157600080fd5b5061028e610550366004613154565b611628565b34801561056157600080fd5b5061028e6105703660046130d8565b6116e9565b34801561058157600080fd5b506102296105903660046131f4565b611721565b3480156105a157600080fd5b506102a1600c5481565b3480156105b757600080fd5b506102296105c636600461322f565b611dde565b3480156105d757600080fd5b50600e546101ff90600160a01b900460ff1681565b3480156105f857600080fd5b506102a1600d5481565b34801561060e57600080fd5b506101ff61061d366004613069565b6120b9565b34801561062e57600080fd5b5061028e61063d36600461304e565b6120e7565b34801561064e57600080fd5b506102a161271081565b60006001600160e01b0319821663780e9d6360e01b148061067d575061067d82612187565b92915050565b606060008054610692906137be565b80601f01602080910402602001604051908101604052809291908181526020018280546106be906137be565b801561070b5780601f106106e05761010080835404028352916020019161070b565b820191906000526020600020905b8154815290600101906020018083116106ee57829003601f168201915b5050505050905090565b6000610720826121d7565b6107865760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006107ad8261104e565b9050806001600160a01b0316836001600160a01b0316141561081b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161077d565b336001600160a01b0382161480610837575061083781336120b9565b6108a45760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b606482015260840161077d565b6108ae83836121f4565b505050565b6108bd3382612262565b6108d95760405162461bcd60e51b815260040161077d906136df565b6108ae83838361232c565b60606108ef826121d7565b61090b5760405162461bcd60e51b815260040161077d90613690565b6000610a06836040518060400160405280600581526020016411925494d560da1b8152506010805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610970906137be565b80601f016020809104026020016040519081016040528092919081815260200182805461099c906137be565b80156109e95780601f106109be576101008083540402835291602001916109e9565b820191906000526020600020905b8154815290600101906020018083116109cc57829003601f168201915b505050505081526020019060010190610951565b505050506124d7565b610af7846040518060400160405280600681526020016514d150d3d39160d21b8152506011805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610a6a906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610a96906137be565b8015610ae35780601f10610ab857610100808354040283529160200191610ae3565b820191906000526020600020905b815481529060010190602001808311610ac657829003601f168201915b505050505081526020019060010190610a4b565b610be78560405180604001604052806005815260200164151212549160da1b8152506012805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610b5a906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610b86906137be565b8015610bd35780601f10610ba857610100808354040283529160200191610bd3565b820191906000526020600020905b815481529060010190602001808311610bb657829003601f168201915b505050505081526020019060010190610b3b565b610cd8866040518060400160405280600681526020016508c9eaaa4a8960d31b8152506013805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610c4b906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610c77906137be565b8015610cc45780601f10610c9957610100808354040283529160200191610cc4565b820191906000526020600020905b815481529060010190602001808311610ca757829003601f168201915b505050505081526020019060010190610c2c565b610dc8876040518060400160405280600581526020016408c928ca8960db1b8152506014805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610d3b906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610d67906137be565b8015610db45780601f10610d8957610100808354040283529160200191610db4565b820191906000526020600020905b815481529060010190602001808311610d9757829003601f168201915b505050505081526020019060010190610d1c565b604051602001610ddc959493929190613359565b60408051601f198184030181529190529392505050565b33610dfc611435565b6001600160a01b031614610e225760405162461bcd60e51b815260040161077d9061365b565b6000828152600f60205260409020600101546001600160a01b031615610e985760405162461bcd60e51b815260206004820152602560248201527f456e69676d6120736f6c76656420616e642063616e6e6f74206265207265706c60448201526430b1b2b21760d91b606482015260840161077d565b6000918252600f602052604090912055565b33610eb3611435565b6001600160a01b031614610ed95760405162461bcd60e51b815260040161077d9061365b565b604051339082156108fc029083906000818181858888f19350505050158015610f06573d6000803e3d6000fd5b5050565b6000610f1583611299565b8210610f775760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161077d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6108ae838383604051806020016040528060008152506116e9565b6000610fc660085490565b82106110295760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161077d565b6008828154811061103c5761103c613864565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b03168061067d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161077d565b6000818152600f602052604081205481906111225760405162461bcd60e51b815260206004820152601b60248201527f5468697320656e69676d6120646f6573206e6f742065786973742e0000000000604482015260640161077d565b50506000908152600f60205260409020805460019091015490916001600160a01b0390911690565b600e54606090600160a01b900460ff166111765760405162461bcd60e51b815260040161077d9061362c565b600d5415806111925750600d5461118f90610384613730565b42115b6111f75760405162461bcd60e51b815260206004820152603060248201527f5375626d697373696f6e73206172652063757272656e746c79206c6f636b656460448201526f103337b910189a9036b4b73aba32b99760811b606482015260840161077d565b600e546001600160a01b03163314156112665760405162461bcd60e51b815260206004820152602b60248201527f596f752063616e6e6f74206c6f636b207375626d697373696f6e73207477696360448201526a329034b71030903937bb9760a91b606482015260840161077d565b42600d55600e80546001600160a01b031916331790556040805160808101909152605c808252613a5d6020830139905090565b60006001600160a01b0382166113045760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161077d565b506001600160a01b031660009081526003602052604090205490565b33611329611435565b6001600160a01b03161461134f5760405162461bcd60e51b815260040161077d9061365b565b6113596000612545565b565b33611364611435565b6001600160a01b03161461138a5760405162461bcd60e51b815260040161077d9061365b565b600061139560085490565b90506000821180156113a95750600c548211155b6113ef5760405162461bcd60e51b81526020600482015260176024820152762737ba1032b737bab3b4103a37b5b2b739903632b33a1760491b604482015260640161077d565b60005b8281101561141f5761140d846114088385613730565b612597565b80611417816137f3565b9150506113f2565b50600c5461142d90836125b1565b600c55505050565b600b546001600160a01b031690565b606060018054610692906137be565b3361145c611435565b6001600160a01b0316146114825760405162461bcd60e51b815260040161077d9061365b565b600e805460ff60a01b198116600160a01b9182900460ff1615909102179055565b6000811180156114b4575060148111155b61150a5760405162461bcd60e51b815260206004820152602160248201527f43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d6044820152606560f81b606482015260840161077d565b6127106115208261151a60085490565b906125c4565b11156115815760405162461bcd60e51b815260206004820152602a60248201527f507572636861736520776f756c6420657863656564206d617820737570706c79604482015269206f6620546f6b656e7360b01b606482015260840161077d565b61159266470de4df820000826125d0565b3410156115e15760405162461bcd60e51b815260206004820152601d60248201527f45746865722076616c75652073656e7420697320696e636f7272656374000000604482015260640161077d565b60005b81811015610f065760006115f760085490565b905061271061160560085490565b1015611615576116153382612597565b5080611620816137f3565b9150506115e4565b6001600160a01b03821633141561167d5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b604482015260640161077d565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6116f33383612262565b61170f5760405162461bcd60e51b815260040161077d906136df565b61171b848484846125dc565b50505050565b606061172c826121d7565b6117485760405162461bcd60e51b815260040161077d90613690565b611750612f94565b60405180610120016040528060fd815260200161392060fd91398152604080518082018252600581526411925494d560da1b6020828101919091526010805484518184028101840190955280855261185b948894939092919060009084015b828210156109fd5783829060005260206000200180546117ce906137be565b80601f01602080910402602001604051908101604052809291908181526020018280546117fa906137be565b80156118475780601f1061181c57610100808354040283529160200191611847565b820191906000526020600020905b81548152906001019060200180831161182a57829003601f168201915b5050505050815260200190600101906117af565b8160016020020181905250604051806060016040528060288152602001613aff60289139816002602002018190525061197b836040518060400160405280600681526020016514d150d3d39160d21b8152506011805480602002602001604051908101604052809291908181526020016000905b828210156109fd5783829060005260206000200180546118ee906137be565b80601f016020809104026020016040519081016040528092919081815260200182805461191a906137be565b80156119675780601f1061193c57610100808354040283529160200191611967565b820191906000526020600020905b81548152906001019060200180831161194a57829003601f168201915b5050505050815260200190600101906118cf565b60608083019190915260408051918201905260288082526138a760208301398160046020020181905250611a958360405180604001604052806005815260200164151212549160da1b8152506012805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054611a08906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054611a34906137be565b8015611a815780601f10611a5657610100808354040283529160200191611a81565b820191906000526020600020905b815481529060010190602001808311611a6457829003601f168201915b5050505050815260200190600101906119e9565b60a0820152604080516060810190915260288082526138cf60208301398160066020020181905250611bae836040518060400160405280600681526020016508c9eaaa4a8960d31b8152506013805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054611b21906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054611b4d906137be565b8015611b9a5780601f10611b6f57610100808354040283529160200191611b9a565b820191906000526020600020905b815481529060010190602001808311611b7d57829003601f168201915b505050505081526020019060010190611b02565b60e0820152604080516060810190915260298082526138f760208301398160086020020181905250611cc6836040518060400160405280600581526020016408c928ca8960db1b8152506014805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054611c39906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054611c65906137be565b8015611cb25780601f10611c8757610100808354040283529160200191611cb2565b820191906000526020600020905b815481529060010190602001808311611c9557829003601f168201915b505050505081526020019060010190611c1a565b610120820152604080518082018252600d81526c1e17ba32bc3a1f1e17b9bb339f60991b602080830191909152610140840191909152825181840151838501516060860151608087015160a088015160c089015160e08a01516101008b0151995160009a611d369a9091016133c4565b60408051808303601f1901815290829052610120840151610140850151919350611d6592849290602001613316565b60405160208183030381529060405290506000611db2611d848661260f565b611d8d8461270d565b604051602001611d9e929190613486565b60405160208183030381529060405261270d565b905080604051602001611dc59190613545565b60408051601f1981840301815291905295945050505050565b600e54606090600160a01b900460ff16611e0a5760405162461bcd60e51b815260040161077d9061362c565b6000825111611e575760405162461bcd60e51b815260206004820152601960248201527829b7b63aba34b7b7399031b0b713ba1031329032b6b83a3c9760391b604482015260640161077d565b6000838152600f60205260409020600101546001600160a01b031615611ecf5760405162461bcd60e51b815260206004820152602760248201527f536f6d656f6e652068617320616c726561647920736f6c76656420746869732060448201526632b734b3b6b09760c91b606482015260840161077d565b600e546001600160a01b03163314611f475760405162461bcd60e51b815260206004820152603560248201527f506c65617365206c6f636b207375626d697373696f6e73206265666f726520736044820152743ab136b4ba3a34b73390309039b7b63aba34b7b71760591b606482015260840161077d565b6000611f5283612873565b90508015612063576000848152600f6020908152604091829020549151611f7b918691016132cb565b60405160208183030381529060405280519060200120141561205e576000848152600f602090815260409182902060010180546001600160a01b031916339081179091558251878152918201527f48ea94b0e72519783042156db3137b944348f894f996dc61b7e4b3da6e242254910160405180910390a16040513390600090670de0b6b3a76400009082818181858883f19350505050158015612023573d6000803e3d6000fd5b5060405180604001604052806019815260200178436f6e67726174756c6174696f6e732c20796f752077696e2160381b81525091505061067d565b612084565b604051806080016040528060468152602001613ab96046913991505061067d565b505060408051808201909152601681527529b7b9393c96103bb937b7339039b7b63aba34b7b71760511b602082015292915050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b336120f0611435565b6001600160a01b0316146121165760405162461bcd60e51b815260040161077d9061365b565b6001600160a01b03811661217b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161077d565b61218481612545565b50565b60006001600160e01b031982166380ac58cd60e01b14806121b857506001600160e01b03198216635b5e139f60e01b145b8061067d57506301ffc9a760e01b6001600160e01b031983161461067d565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906122298261104e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061226d826121d7565b6122ce5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161077d565b60006122d98361104e565b9050806001600160a01b0316846001600160a01b031614806123145750836001600160a01b031661230984610715565b6001600160a01b0316145b80612324575061232481856120b9565b949350505050565b826001600160a01b031661233f8261104e565b6001600160a01b0316146123a75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161077d565b6001600160a01b0382166124095760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161077d565b61241483838361292e565b61241f6000826121f4565b6001600160a01b038316600090815260036020526040812080546001929061244890849061377b565b90915550506001600160a01b0382166000908152600360205260408120805460019290612476908490613730565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6060600061250d846124e88761260f565b6040516020016124f99291906132e7565b6040516020818303038152906040526129e6565b905060008384518361251f919061380e565b8151811061252f5761252f613864565b6020026020010151905080925050509392505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610f06828260405180602001604052806000815250612a17565b60006125bd828461377b565b9392505050565b60006125bd8284613730565b60006125bd828461375c565b6125e784848461232c565b6125f384848484612a4a565b61171b5760405162461bcd60e51b815260040161077d906135da565b6060816126335750506040805180820190915260018152600360fc1b602082015290565b8160005b811561265d5780612647816137f3565b91506126569050600a83613748565b9150612637565b60008167ffffffffffffffff8111156126785761267861387a565b6040519080825280601f01601f1916602001820160405280156126a2576020820181803683370190505b5090505b8415612324576126b760018361377b565b91506126c4600a8661380e565b6126cf906030613730565b60f81b8183815181106126e4576126e4613864565b60200101906001600160f81b031916908160001a905350612706600a86613748565b94506126a6565b80516060908061272d575050604080516020810190915260008152919050565b6000600361273c836002613730565b6127469190613748565b61275190600461375c565b90506000612760826020613730565b67ffffffffffffffff8111156127785761277861387a565b6040519080825280601f01601f1916602001820160405280156127a2576020820181803683370190505b5090506000604051806060016040528060408152602001613a1d604091399050600181016020830160005b8681101561282e576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016127cd565b506003860660018114612848576002811461285957612865565b613d3d60f01b600119830152612865565b603d60f81b6000198301525b505050918152949350505050565b600081338261288182612b57565b9050600160005b8451811015612924576000805b8451811015612901576128e18582815181106128b3576128b3613864565b60200260200101518885815181106128cd576128cd613864565b01602001516001600160f81b031916612c16565b156128ef5760019150612901565b806128f9816137f3565b915050612895565b5080612911576000925050612924565b508061291c816137f3565b915050612888565b5095945050505050565b6001600160a01b0383166129895761298481600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6129ac565b816001600160a01b0316836001600160a01b0316146129ac576129ac8382612cc5565b6001600160a01b0382166129c3576108ae81612d62565b826001600160a01b0316826001600160a01b0316146108ae576108ae8282612e11565b6000816040516020016129f991906132cb565b60408051601f19818403018152919052805160209091012092915050565b612a218383612e55565b612a2e6000848484612a4a565b6108ae5760405162461bcd60e51b815260040161077d906135da565b60006001600160a01b0384163b15612b4c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a8e90339089908890889060040161358a565b602060405180830381600087803b158015612aa857600080fd5b505af1925050508015612ad8575060408051601f3d908101601f19168201909252612ad5918101906131d7565b60015b612b32573d808015612b06576040519150601f19603f3d011682016040523d82523d6000602084013e612b0b565b606091505b508051612b2a5760405162461bcd60e51b815260040161077d906135da565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612324565b506001949350505050565b60606000612b6483611299565b905080612b855760408051600080825260208201909252905b509392505050565b60008167ffffffffffffffff811115612ba057612ba061387a565b604051908082528060200260200182016040528015612bc9578160200160208202803683370190505b50905060005b82811015612b7d57612be18582610f0a565b828281518110612bf357612bf3613864565b602090810291909101015280612c08816137f3565b915050612bcf565b50919050565b600080612c22846108e4565b90506000805b8251811015612cbc5784604051602001612c4291906132b6565b60405160208183030381529060405280519060200120838281518110612c6a57612c6a613864565b602001015160f81c60f81b604051602001612c8591906132b6565b604051602081830303815290604052805190602001201415612caa5760019150612cbc565b80612cb4816137f3565b915050612c28565b50949350505050565b60006001612cd284611299565b612cdc919061377b565b600083815260076020526040902054909150808214612d2f576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612d749060019061377b565b60008381526009602052604081205460088054939450909284908110612d9c57612d9c613864565b906000526020600020015490508060088381548110612dbd57612dbd613864565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612df557612df561384e565b6001900381819060005260206000200160009055905550505050565b6000612e1c83611299565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612eab5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161077d565b612eb4816121d7565b15612f015760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161077d565b612f0d6000838361292e565b6001600160a01b0382166000908152600360205260408120805460019290612f36908490613730565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b604051806101600160405280600b905b6060815260200190600190039081612fa45790505090565b600067ffffffffffffffff80841115612fd757612fd761387a565b604051601f8501601f19908116603f01168101908282118183101715612fff57612fff61387a565b8160405280935085815286868601111561301857600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461304957600080fd5b919050565b60006020828403121561306057600080fd5b6125bd82613032565b6000806040838503121561307c57600080fd5b61308583613032565b915061309360208401613032565b90509250929050565b6000806000606084860312156130b157600080fd5b6130ba84613032565b92506130c860208501613032565b9150604084013590509250925092565b600080600080608085870312156130ee57600080fd5b6130f785613032565b935061310560208601613032565b925060408501359150606085013567ffffffffffffffff81111561312857600080fd5b8501601f8101871361313957600080fd5b61314887823560208401612fbc565b91505092959194509250565b6000806040838503121561316757600080fd5b61317083613032565b91506020830135801515811461318557600080fd5b809150509250929050565b600080604083850312156131a357600080fd5b6131ac83613032565b946020939093013593505050565b6000602082840312156131cc57600080fd5b81356125bd81613890565b6000602082840312156131e957600080fd5b81516125bd81613890565b60006020828403121561320657600080fd5b5035919050565b6000806040838503121561322057600080fd5b50508035926020909101359150565b6000806040838503121561324257600080fd5b82359150602083013567ffffffffffffffff81111561326057600080fd5b8301601f8101851361327157600080fd5b61328085823560208401612fbc565b9150509250929050565b600081518084526132a2816020860160208601613792565b601f01601f19169290920160200192915050565b6001600160f81b031991909116815260010190565b600082516132dd818460208701613792565b9190910192915050565b600083516132f9818460208801613792565b83519083019061330d818360208801613792565b01949350505050565b60008451613328818460208901613792565b84519083019061333c818360208901613792565b845191019061334f818360208801613792565b0195945050505050565b6000865161336b818460208b01613792565b86519083019061337f818360208b01613792565b8651910190613392818360208a01613792565b85519101906133a5818360208901613792565b84519101906133b8818360208801613792565b01979650505050505050565b60008a516133d6818460208f01613792565b8a51908301906133ea818360208f01613792565b8a516133fc8183850160208f01613792565b8a51929091010190613412818360208d01613792565b88516134248183850160208d01613792565b885192909101019061343a818360208b01613792565b865161344c8183850160208b01613792565b8651929091010190613462818360208901613792565b84516134748183850160208901613792565b9101019b9a5050505050505050505050565b767b226e616d65223a2022456e69676d61546f6b656e202360481b815282516000906134b9816017850160208801613792565b7f222c20226465736372697074696f6e223a2022456e69676d61204e465473222c6017918401918201527f2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b62616037820152641cd94d8d0b60da1b6057820152835161352a81605c840160208801613792565b61227d60f01b605c9290910191820152605e01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161357d81601d850160208701613792565b91909101601d0192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906135bd9083018461328a565b9695505050505050565b6020815260006125bd602083018461328a565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601590820152742a34329033b0b6b29034b9903737ba103634bb329760591b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561374357613743613822565b500190565b60008261375757613757613838565b500490565b600081600019048311821515161561377657613776613822565b500290565b60008282101561378d5761378d613822565b500390565b60005b838110156137ad578181015183820152602001613795565b8381111561171b5750506000910152565b600181811c908216806137d257607f821691505b60208210811415612c1057634e487b7160e01b600052602260045260246000fd5b600060001982141561380757613807613822565b5060010190565b60008261381d5761381d613838565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461218457600080fdfe3c2f746578743e3c7465787420783d2231302220793d2236302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2231302220793d2238302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2231302220793d223130302220636c6173733d2262617365223e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e2e62617365207b2066696c6c3a2077686974653b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20313470783b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d22626c61636b22202f3e3c7465787420783d2231302220793d2232302220636c6173733d2262617365223e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f5375626d697373696f6e73207375636365737366756c6c79206c6f636b656420746f20796f75722077616c6c65742e20596f752068617665203135206d696e7574657320746f207375626d697420796f757220736f6c7574696f6e2e596f7520646f206e6f7420686f6c6420746f6b656e7320636f6e7461696e696e6720616c6c20746865206368617261637465727320696e20796f757220736f6c7574696f6e2e3c2f746578743e3c7465787420783d2231302220793d2234302220636c6173733d2262617365223ea264697066735822122020c265a0b299f1ce7b342fca6c8fc2d2e12690f395d4f90a086e745286569b7964736f6c63430008070033

Deployed Bytecode

0x6080604052600436106101d35760003560e01c8063715018a6116100f8578063b88d4fde11610090578063b88d4fde14610555578063c87b56dd14610575578063cbcb317114610595578063cc0dcec7146105ab578063d414d0c2146105cb578063d6c28573146105ec578063e985e9c514610602578063f2fde38b14610622578063f47c84c51461064257600080fd5b8063715018a61461047e57806378cf19e9146104935780638da5cb5b146104b357806395d89b41146104c8578063977b055b146104dd578063989a5c41146104f2578063a035b1fe14610507578063a0712d6814610522578063a22cb4651461053557600080fd5b80632f745c591161016b5780632f745c591461032f578063364861021461034f57806342842e0e1461036f5780634f6ccce71461038f5780636352211e146103af57806363f71af4146103cf57806368cee4331461040c5780636f5e50501461044957806370a082311461045e57600080fd5b806301ffc9a7146101df57806306fdde0314610214578063081812fc14610236578063095ea7b31461026e57806318160ddd1461029057806323b872dd146102af578063247889c3146102cf57806328cbc4b5146102ef5780632e1a7d4d1461030f57600080fd5b366101da57005b600080fd5b3480156101eb57600080fd5b506101ff6101fa3660046131ba565b610658565b60405190151581526020015b60405180910390f35b34801561022057600080fd5b50610229610683565b60405161020b91906135c7565b34801561024257600080fd5b506102566102513660046131f4565b610715565b6040516001600160a01b03909116815260200161020b565b34801561027a57600080fd5b5061028e610289366004613190565b6107a2565b005b34801561029c57600080fd5b506008545b60405190815260200161020b565b3480156102bb57600080fd5b5061028e6102ca36600461309c565b6108b3565b3480156102db57600080fd5b506102296102ea3660046131f4565b6108e4565b3480156102fb57600080fd5b5061028e61030a36600461320d565b610df3565b34801561031b57600080fd5b5061028e61032a3660046131f4565b610eaa565b34801561033b57600080fd5b506102a161034a366004613190565b610f0a565b34801561035b57600080fd5b50600e54610256906001600160a01b031681565b34801561037b57600080fd5b5061028e61038a36600461309c565b610fa0565b34801561039b57600080fd5b506102a16103aa3660046131f4565b610fbb565b3480156103bb57600080fd5b506102566103ca3660046131f4565b61104e565b3480156103db57600080fd5b506103ef6103ea3660046131f4565b6110c5565b604080519283526001600160a01b0390911660208301520161020b565b34801561041857600080fd5b506103ef6104273660046131f4565b600f60205260009081526040902080546001909101546001600160a01b031682565b34801561045557600080fd5b5061022961114a565b34801561046a57600080fd5b506102a161047936600461304e565b611299565b34801561048a57600080fd5b5061028e611320565b34801561049f57600080fd5b5061028e6104ae366004613190565b61135b565b3480156104bf57600080fd5b50610256611435565b3480156104d457600080fd5b50610229611444565b3480156104e957600080fd5b506102a1601481565b3480156104fe57600080fd5b5061028e611453565b34801561051357600080fd5b506102a166470de4df82000081565b61028e6105303660046131f4565b6114a3565b34801561054157600080fd5b5061028e610550366004613154565b611628565b34801561056157600080fd5b5061028e6105703660046130d8565b6116e9565b34801561058157600080fd5b506102296105903660046131f4565b611721565b3480156105a157600080fd5b506102a1600c5481565b3480156105b757600080fd5b506102296105c636600461322f565b611dde565b3480156105d757600080fd5b50600e546101ff90600160a01b900460ff1681565b3480156105f857600080fd5b506102a1600d5481565b34801561060e57600080fd5b506101ff61061d366004613069565b6120b9565b34801561062e57600080fd5b5061028e61063d36600461304e565b6120e7565b34801561064e57600080fd5b506102a161271081565b60006001600160e01b0319821663780e9d6360e01b148061067d575061067d82612187565b92915050565b606060008054610692906137be565b80601f01602080910402602001604051908101604052809291908181526020018280546106be906137be565b801561070b5780601f106106e05761010080835404028352916020019161070b565b820191906000526020600020905b8154815290600101906020018083116106ee57829003601f168201915b5050505050905090565b6000610720826121d7565b6107865760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006107ad8261104e565b9050806001600160a01b0316836001600160a01b0316141561081b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161077d565b336001600160a01b0382161480610837575061083781336120b9565b6108a45760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b606482015260840161077d565b6108ae83836121f4565b505050565b6108bd3382612262565b6108d95760405162461bcd60e51b815260040161077d906136df565b6108ae83838361232c565b60606108ef826121d7565b61090b5760405162461bcd60e51b815260040161077d90613690565b6000610a06836040518060400160405280600581526020016411925494d560da1b8152506010805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610970906137be565b80601f016020809104026020016040519081016040528092919081815260200182805461099c906137be565b80156109e95780601f106109be576101008083540402835291602001916109e9565b820191906000526020600020905b8154815290600101906020018083116109cc57829003601f168201915b505050505081526020019060010190610951565b505050506124d7565b610af7846040518060400160405280600681526020016514d150d3d39160d21b8152506011805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610a6a906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610a96906137be565b8015610ae35780601f10610ab857610100808354040283529160200191610ae3565b820191906000526020600020905b815481529060010190602001808311610ac657829003601f168201915b505050505081526020019060010190610a4b565b610be78560405180604001604052806005815260200164151212549160da1b8152506012805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610b5a906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610b86906137be565b8015610bd35780601f10610ba857610100808354040283529160200191610bd3565b820191906000526020600020905b815481529060010190602001808311610bb657829003601f168201915b505050505081526020019060010190610b3b565b610cd8866040518060400160405280600681526020016508c9eaaa4a8960d31b8152506013805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610c4b906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610c77906137be565b8015610cc45780601f10610c9957610100808354040283529160200191610cc4565b820191906000526020600020905b815481529060010190602001808311610ca757829003601f168201915b505050505081526020019060010190610c2c565b610dc8876040518060400160405280600581526020016408c928ca8960db1b8152506014805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054610d3b906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054610d67906137be565b8015610db45780601f10610d8957610100808354040283529160200191610db4565b820191906000526020600020905b815481529060010190602001808311610d9757829003601f168201915b505050505081526020019060010190610d1c565b604051602001610ddc959493929190613359565b60408051601f198184030181529190529392505050565b33610dfc611435565b6001600160a01b031614610e225760405162461bcd60e51b815260040161077d9061365b565b6000828152600f60205260409020600101546001600160a01b031615610e985760405162461bcd60e51b815260206004820152602560248201527f456e69676d6120736f6c76656420616e642063616e6e6f74206265207265706c60448201526430b1b2b21760d91b606482015260840161077d565b6000918252600f602052604090912055565b33610eb3611435565b6001600160a01b031614610ed95760405162461bcd60e51b815260040161077d9061365b565b604051339082156108fc029083906000818181858888f19350505050158015610f06573d6000803e3d6000fd5b5050565b6000610f1583611299565b8210610f775760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161077d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6108ae838383604051806020016040528060008152506116e9565b6000610fc660085490565b82106110295760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161077d565b6008828154811061103c5761103c613864565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b03168061067d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161077d565b6000818152600f602052604081205481906111225760405162461bcd60e51b815260206004820152601b60248201527f5468697320656e69676d6120646f6573206e6f742065786973742e0000000000604482015260640161077d565b50506000908152600f60205260409020805460019091015490916001600160a01b0390911690565b600e54606090600160a01b900460ff166111765760405162461bcd60e51b815260040161077d9061362c565b600d5415806111925750600d5461118f90610384613730565b42115b6111f75760405162461bcd60e51b815260206004820152603060248201527f5375626d697373696f6e73206172652063757272656e746c79206c6f636b656460448201526f103337b910189a9036b4b73aba32b99760811b606482015260840161077d565b600e546001600160a01b03163314156112665760405162461bcd60e51b815260206004820152602b60248201527f596f752063616e6e6f74206c6f636b207375626d697373696f6e73207477696360448201526a329034b71030903937bb9760a91b606482015260840161077d565b42600d55600e80546001600160a01b031916331790556040805160808101909152605c808252613a5d6020830139905090565b60006001600160a01b0382166113045760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161077d565b506001600160a01b031660009081526003602052604090205490565b33611329611435565b6001600160a01b03161461134f5760405162461bcd60e51b815260040161077d9061365b565b6113596000612545565b565b33611364611435565b6001600160a01b03161461138a5760405162461bcd60e51b815260040161077d9061365b565b600061139560085490565b90506000821180156113a95750600c548211155b6113ef5760405162461bcd60e51b81526020600482015260176024820152762737ba1032b737bab3b4103a37b5b2b739903632b33a1760491b604482015260640161077d565b60005b8281101561141f5761140d846114088385613730565b612597565b80611417816137f3565b9150506113f2565b50600c5461142d90836125b1565b600c55505050565b600b546001600160a01b031690565b606060018054610692906137be565b3361145c611435565b6001600160a01b0316146114825760405162461bcd60e51b815260040161077d9061365b565b600e805460ff60a01b198116600160a01b9182900460ff1615909102179055565b6000811180156114b4575060148111155b61150a5760405162461bcd60e51b815260206004820152602160248201527f43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d6044820152606560f81b606482015260840161077d565b6127106115208261151a60085490565b906125c4565b11156115815760405162461bcd60e51b815260206004820152602a60248201527f507572636861736520776f756c6420657863656564206d617820737570706c79604482015269206f6620546f6b656e7360b01b606482015260840161077d565b61159266470de4df820000826125d0565b3410156115e15760405162461bcd60e51b815260206004820152601d60248201527f45746865722076616c75652073656e7420697320696e636f7272656374000000604482015260640161077d565b60005b81811015610f065760006115f760085490565b905061271061160560085490565b1015611615576116153382612597565b5080611620816137f3565b9150506115e4565b6001600160a01b03821633141561167d5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b604482015260640161077d565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6116f33383612262565b61170f5760405162461bcd60e51b815260040161077d906136df565b61171b848484846125dc565b50505050565b606061172c826121d7565b6117485760405162461bcd60e51b815260040161077d90613690565b611750612f94565b60405180610120016040528060fd815260200161392060fd91398152604080518082018252600581526411925494d560da1b6020828101919091526010805484518184028101840190955280855261185b948894939092919060009084015b828210156109fd5783829060005260206000200180546117ce906137be565b80601f01602080910402602001604051908101604052809291908181526020018280546117fa906137be565b80156118475780601f1061181c57610100808354040283529160200191611847565b820191906000526020600020905b81548152906001019060200180831161182a57829003601f168201915b5050505050815260200190600101906117af565b8160016020020181905250604051806060016040528060288152602001613aff60289139816002602002018190525061197b836040518060400160405280600681526020016514d150d3d39160d21b8152506011805480602002602001604051908101604052809291908181526020016000905b828210156109fd5783829060005260206000200180546118ee906137be565b80601f016020809104026020016040519081016040528092919081815260200182805461191a906137be565b80156119675780601f1061193c57610100808354040283529160200191611967565b820191906000526020600020905b81548152906001019060200180831161194a57829003601f168201915b5050505050815260200190600101906118cf565b60608083019190915260408051918201905260288082526138a760208301398160046020020181905250611a958360405180604001604052806005815260200164151212549160da1b8152506012805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054611a08906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054611a34906137be565b8015611a815780601f10611a5657610100808354040283529160200191611a81565b820191906000526020600020905b815481529060010190602001808311611a6457829003601f168201915b5050505050815260200190600101906119e9565b60a0820152604080516060810190915260288082526138cf60208301398160066020020181905250611bae836040518060400160405280600681526020016508c9eaaa4a8960d31b8152506013805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054611b21906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054611b4d906137be565b8015611b9a5780601f10611b6f57610100808354040283529160200191611b9a565b820191906000526020600020905b815481529060010190602001808311611b7d57829003601f168201915b505050505081526020019060010190611b02565b60e0820152604080516060810190915260298082526138f760208301398160086020020181905250611cc6836040518060400160405280600581526020016408c928ca8960db1b8152506014805480602002602001604051908101604052809291908181526020016000905b828210156109fd578382906000526020600020018054611c39906137be565b80601f0160208091040260200160405190810160405280929190818152602001828054611c65906137be565b8015611cb25780601f10611c8757610100808354040283529160200191611cb2565b820191906000526020600020905b815481529060010190602001808311611c9557829003601f168201915b505050505081526020019060010190611c1a565b610120820152604080518082018252600d81526c1e17ba32bc3a1f1e17b9bb339f60991b602080830191909152610140840191909152825181840151838501516060860151608087015160a088015160c089015160e08a01516101008b0151995160009a611d369a9091016133c4565b60408051808303601f1901815290829052610120840151610140850151919350611d6592849290602001613316565b60405160208183030381529060405290506000611db2611d848661260f565b611d8d8461270d565b604051602001611d9e929190613486565b60405160208183030381529060405261270d565b905080604051602001611dc59190613545565b60408051601f1981840301815291905295945050505050565b600e54606090600160a01b900460ff16611e0a5760405162461bcd60e51b815260040161077d9061362c565b6000825111611e575760405162461bcd60e51b815260206004820152601960248201527829b7b63aba34b7b7399031b0b713ba1031329032b6b83a3c9760391b604482015260640161077d565b6000838152600f60205260409020600101546001600160a01b031615611ecf5760405162461bcd60e51b815260206004820152602760248201527f536f6d656f6e652068617320616c726561647920736f6c76656420746869732060448201526632b734b3b6b09760c91b606482015260840161077d565b600e546001600160a01b03163314611f475760405162461bcd60e51b815260206004820152603560248201527f506c65617365206c6f636b207375626d697373696f6e73206265666f726520736044820152743ab136b4ba3a34b73390309039b7b63aba34b7b71760591b606482015260840161077d565b6000611f5283612873565b90508015612063576000848152600f6020908152604091829020549151611f7b918691016132cb565b60405160208183030381529060405280519060200120141561205e576000848152600f602090815260409182902060010180546001600160a01b031916339081179091558251878152918201527f48ea94b0e72519783042156db3137b944348f894f996dc61b7e4b3da6e242254910160405180910390a16040513390600090670de0b6b3a76400009082818181858883f19350505050158015612023573d6000803e3d6000fd5b5060405180604001604052806019815260200178436f6e67726174756c6174696f6e732c20796f752077696e2160381b81525091505061067d565b612084565b604051806080016040528060468152602001613ab96046913991505061067d565b505060408051808201909152601681527529b7b9393c96103bb937b7339039b7b63aba34b7b71760511b602082015292915050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b336120f0611435565b6001600160a01b0316146121165760405162461bcd60e51b815260040161077d9061365b565b6001600160a01b03811661217b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161077d565b61218481612545565b50565b60006001600160e01b031982166380ac58cd60e01b14806121b857506001600160e01b03198216635b5e139f60e01b145b8061067d57506301ffc9a760e01b6001600160e01b031983161461067d565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906122298261104e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061226d826121d7565b6122ce5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161077d565b60006122d98361104e565b9050806001600160a01b0316846001600160a01b031614806123145750836001600160a01b031661230984610715565b6001600160a01b0316145b80612324575061232481856120b9565b949350505050565b826001600160a01b031661233f8261104e565b6001600160a01b0316146123a75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161077d565b6001600160a01b0382166124095760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161077d565b61241483838361292e565b61241f6000826121f4565b6001600160a01b038316600090815260036020526040812080546001929061244890849061377b565b90915550506001600160a01b0382166000908152600360205260408120805460019290612476908490613730565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6060600061250d846124e88761260f565b6040516020016124f99291906132e7565b6040516020818303038152906040526129e6565b905060008384518361251f919061380e565b8151811061252f5761252f613864565b6020026020010151905080925050509392505050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610f06828260405180602001604052806000815250612a17565b60006125bd828461377b565b9392505050565b60006125bd8284613730565b60006125bd828461375c565b6125e784848461232c565b6125f384848484612a4a565b61171b5760405162461bcd60e51b815260040161077d906135da565b6060816126335750506040805180820190915260018152600360fc1b602082015290565b8160005b811561265d5780612647816137f3565b91506126569050600a83613748565b9150612637565b60008167ffffffffffffffff8111156126785761267861387a565b6040519080825280601f01601f1916602001820160405280156126a2576020820181803683370190505b5090505b8415612324576126b760018361377b565b91506126c4600a8661380e565b6126cf906030613730565b60f81b8183815181106126e4576126e4613864565b60200101906001600160f81b031916908160001a905350612706600a86613748565b94506126a6565b80516060908061272d575050604080516020810190915260008152919050565b6000600361273c836002613730565b6127469190613748565b61275190600461375c565b90506000612760826020613730565b67ffffffffffffffff8111156127785761277861387a565b6040519080825280601f01601f1916602001820160405280156127a2576020820181803683370190505b5090506000604051806060016040528060408152602001613a1d604091399050600181016020830160005b8681101561282e576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016127cd565b506003860660018114612848576002811461285957612865565b613d3d60f01b600119830152612865565b603d60f81b6000198301525b505050918152949350505050565b600081338261288182612b57565b9050600160005b8451811015612924576000805b8451811015612901576128e18582815181106128b3576128b3613864565b60200260200101518885815181106128cd576128cd613864565b01602001516001600160f81b031916612c16565b156128ef5760019150612901565b806128f9816137f3565b915050612895565b5080612911576000925050612924565b508061291c816137f3565b915050612888565b5095945050505050565b6001600160a01b0383166129895761298481600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6129ac565b816001600160a01b0316836001600160a01b0316146129ac576129ac8382612cc5565b6001600160a01b0382166129c3576108ae81612d62565b826001600160a01b0316826001600160a01b0316146108ae576108ae8282612e11565b6000816040516020016129f991906132cb565b60408051601f19818403018152919052805160209091012092915050565b612a218383612e55565b612a2e6000848484612a4a565b6108ae5760405162461bcd60e51b815260040161077d906135da565b60006001600160a01b0384163b15612b4c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a8e90339089908890889060040161358a565b602060405180830381600087803b158015612aa857600080fd5b505af1925050508015612ad8575060408051601f3d908101601f19168201909252612ad5918101906131d7565b60015b612b32573d808015612b06576040519150601f19603f3d011682016040523d82523d6000602084013e612b0b565b606091505b508051612b2a5760405162461bcd60e51b815260040161077d906135da565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612324565b506001949350505050565b60606000612b6483611299565b905080612b855760408051600080825260208201909252905b509392505050565b60008167ffffffffffffffff811115612ba057612ba061387a565b604051908082528060200260200182016040528015612bc9578160200160208202803683370190505b50905060005b82811015612b7d57612be18582610f0a565b828281518110612bf357612bf3613864565b602090810291909101015280612c08816137f3565b915050612bcf565b50919050565b600080612c22846108e4565b90506000805b8251811015612cbc5784604051602001612c4291906132b6565b60405160208183030381529060405280519060200120838281518110612c6a57612c6a613864565b602001015160f81c60f81b604051602001612c8591906132b6565b604051602081830303815290604052805190602001201415612caa5760019150612cbc565b80612cb4816137f3565b915050612c28565b50949350505050565b60006001612cd284611299565b612cdc919061377b565b600083815260076020526040902054909150808214612d2f576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612d749060019061377b565b60008381526009602052604081205460088054939450909284908110612d9c57612d9c613864565b906000526020600020015490508060088381548110612dbd57612dbd613864565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612df557612df561384e565b6001900381819060005260206000200160009055905550505050565b6000612e1c83611299565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612eab5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161077d565b612eb4816121d7565b15612f015760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161077d565b612f0d6000838361292e565b6001600160a01b0382166000908152600360205260408120805460019290612f36908490613730565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b604051806101600160405280600b905b6060815260200190600190039081612fa45790505090565b600067ffffffffffffffff80841115612fd757612fd761387a565b604051601f8501601f19908116603f01168101908282118183101715612fff57612fff61387a565b8160405280935085815286868601111561301857600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461304957600080fd5b919050565b60006020828403121561306057600080fd5b6125bd82613032565b6000806040838503121561307c57600080fd5b61308583613032565b915061309360208401613032565b90509250929050565b6000806000606084860312156130b157600080fd5b6130ba84613032565b92506130c860208501613032565b9150604084013590509250925092565b600080600080608085870312156130ee57600080fd5b6130f785613032565b935061310560208601613032565b925060408501359150606085013567ffffffffffffffff81111561312857600080fd5b8501601f8101871361313957600080fd5b61314887823560208401612fbc565b91505092959194509250565b6000806040838503121561316757600080fd5b61317083613032565b91506020830135801515811461318557600080fd5b809150509250929050565b600080604083850312156131a357600080fd5b6131ac83613032565b946020939093013593505050565b6000602082840312156131cc57600080fd5b81356125bd81613890565b6000602082840312156131e957600080fd5b81516125bd81613890565b60006020828403121561320657600080fd5b5035919050565b6000806040838503121561322057600080fd5b50508035926020909101359150565b6000806040838503121561324257600080fd5b82359150602083013567ffffffffffffffff81111561326057600080fd5b8301601f8101851361327157600080fd5b61328085823560208401612fbc565b9150509250929050565b600081518084526132a2816020860160208601613792565b601f01601f19169290920160200192915050565b6001600160f81b031991909116815260010190565b600082516132dd818460208701613792565b9190910192915050565b600083516132f9818460208801613792565b83519083019061330d818360208801613792565b01949350505050565b60008451613328818460208901613792565b84519083019061333c818360208901613792565b845191019061334f818360208801613792565b0195945050505050565b6000865161336b818460208b01613792565b86519083019061337f818360208b01613792565b8651910190613392818360208a01613792565b85519101906133a5818360208901613792565b84519101906133b8818360208801613792565b01979650505050505050565b60008a516133d6818460208f01613792565b8a51908301906133ea818360208f01613792565b8a516133fc8183850160208f01613792565b8a51929091010190613412818360208d01613792565b88516134248183850160208d01613792565b885192909101019061343a818360208b01613792565b865161344c8183850160208b01613792565b8651929091010190613462818360208901613792565b84516134748183850160208901613792565b9101019b9a5050505050505050505050565b767b226e616d65223a2022456e69676d61546f6b656e202360481b815282516000906134b9816017850160208801613792565b7f222c20226465736372697074696f6e223a2022456e69676d61204e465473222c6017918401918201527f2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b62616037820152641cd94d8d0b60da1b6057820152835161352a81605c840160208801613792565b61227d60f01b605c9290910191820152605e01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161357d81601d850160208701613792565b91909101601d0192915050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906135bd9083018461328a565b9695505050505050565b6020815260006125bd602083018461328a565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601590820152742a34329033b0b6b29034b9903737ba103634bb329760591b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561374357613743613822565b500190565b60008261375757613757613838565b500490565b600081600019048311821515161561377657613776613822565b500290565b60008282101561378d5761378d613822565b500390565b60005b838110156137ad578181015183820152602001613795565b8381111561171b5750506000910152565b600181811c908216806137d257607f821691505b60208210811415612c1057634e487b7160e01b600052602260045260246000fd5b600060001982141561380757613807613822565b5060010190565b60008261381d5761381d613838565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461218457600080fdfe3c2f746578743e3c7465787420783d2231302220793d2236302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2231302220793d2238302220636c6173733d2262617365223e3c2f746578743e3c7465787420783d2231302220793d223130302220636c6173733d2262617365223e3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e2e62617365207b2066696c6c3a2077686974653b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20313470783b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d22626c61636b22202f3e3c7465787420783d2231302220793d2232302220636c6173733d2262617365223e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f5375626d697373696f6e73207375636365737366756c6c79206c6f636b656420746f20796f75722077616c6c65742e20596f752068617665203135206d696e7574657320746f207375626d697420796f757220736f6c7574696f6e2e596f7520646f206e6f7420686f6c6420746f6b656e7320636f6e7461696e696e6720616c6c20746865206368617261637465727320696e20796f757220736f6c7574696f6e2e3c2f746578743e3c7465787420783d2231302220793d2234302220636c6173733d2262617365223ea264697066735822122020c265a0b299f1ce7b342fca6c8fc2d2e12690f395d4f90a086e745286569b7964736f6c63430008070033

Deployed Bytecode Sourcemap

65093:10408:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56816:224;;;;;;;;;;-1:-1:-1;56816:224:0;;;;;:::i;:::-;;:::i;:::-;;;11585:14:1;;11578:22;11560:41;;11548:2;11533:18;56816:224:0;;;;;;;;44729:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46288:221::-;;;;;;;;;;-1:-1:-1;46288:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;10883:32:1;;;10865:51;;10853:2;10838:18;46288:221:0;10719:203:1;45811:411:0;;;;;;;;;;-1:-1:-1;45811:411:0;;;;;:::i;:::-;;:::i;:::-;;57456:113;;;;;;;;;;-1:-1:-1;57544:10:0;:17;57456:113;;;24116:25:1;;;24104:2;24089:18;57456:113:0;23970:177:1;47178:339:0;;;;;;;;;;-1:-1:-1;47178:339:0;;;;;:::i;:::-;;:::i;70682:430::-;;;;;;;;;;-1:-1:-1;70682:430:0;;;;;:::i;:::-;;:::i;66424:225::-;;;;;;;;;;-1:-1:-1;66424:225:0;;;;;:::i;:::-;;:::i;67090:106::-;;;;;;;;;;-1:-1:-1;67090:106:0;;;;;:::i;:::-;;:::i;57124:256::-;;;;;;;;;;-1:-1:-1;57124:256:0;;;;;:::i;:::-;;:::i;65533:36::-;;;;;;;;;;-1:-1:-1;65533:36:0;;;;-1:-1:-1;;;;;65533:36:0;;;47588:185;;;;;;;;;;-1:-1:-1;47588:185:0;;;;;:::i;:::-;;:::i;57646:233::-;;;;;;;;;;-1:-1:-1;57646:233:0;;;;;:::i;:::-;;:::i;44423:239::-;;;;;;;;;;-1:-1:-1;44423:239:0;;;;;:::i;:::-;;:::i;66661:307::-;;;;;;;;;;-1:-1:-1;66661:307:0;;;;;:::i;:::-;;:::i;:::-;;;;11786:25:1;;;-1:-1:-1;;;;;11847:32:1;;;11842:2;11827:18;;11820:60;11759:18;66661:307:0;11612:274:1;65625:38:0;;;;;;;;;;-1:-1:-1;65625:38:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65625:38:0;;;67208:573;;;;;;;;;;;;;:::i;44153:208::-;;;;;;;;;;-1:-1:-1;44153:208:0;;;;;:::i;:::-;;:::i;37901:103::-;;;;;;;;;;;;;:::i;69583:393::-;;;;;;;;;;-1:-1:-1;69583:393:0;;;;;:::i;:::-;;:::i;37250:87::-;;;;;;;;;;;;;:::i;44898:104::-;;;;;;;;;;;;;:::i;65280:37::-;;;;;;;;;;;;65315:2;65280:37;;66986:86;;;;;;;;;;;;;:::i;65210:49::-;;;;;;;;;;;;65242:17;65210:49;;68965:603;;;;;;:::i;:::-;;:::i;46581:295::-;;;;;;;;;;-1:-1:-1;46581:295:0;;;;;:::i;:::-;;:::i;47844:328::-;;;;;;;;;;-1:-1:-1;47844:328:0;;;;;:::i;:::-;;:::i;72941:1898::-;;;;;;;;;;-1:-1:-1;72941:1898:0;;;;;:::i;:::-;;:::i;65377:29::-;;;;;;;;;;;;;;;;67805:1140;;;;;;;;;;-1:-1:-1;67805:1140:0;;;;;:::i;:::-;;:::i;65582:30::-;;;;;;;;;;-1:-1:-1;65582:30:0;;;;-1:-1:-1;;;65582:30:0;;;;;;65496;;;;;;;;;;;;;;;;46947:164;;;;;;;;;;-1:-1:-1;46947:164:0;;;;;:::i;:::-;;:::i;38159:201::-;;;;;;;;;;-1:-1:-1;38159:201:0;;;;;:::i;:::-;;:::i;65326:42::-;;;;;;;;;;;;65363:5;65326:42;;56816:224;56918:4;-1:-1:-1;;;;;;56942:50:0;;-1:-1:-1;;;56942:50:0;;:90;;;56996:36;57020:11;56996:23;:36::i;:::-;56935:97;56816:224;-1:-1:-1;;56816:224:0:o;44729:100::-;44783:13;44816:5;44809:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44729:100;:::o;46288:221::-;46364:7;46392:16;46400:7;46392;:16::i;:::-;46384:73;;;;-1:-1:-1;;;46384:73:0;;20097:2:1;46384:73:0;;;20079:21:1;20136:2;20116:18;;;20109:30;20175:34;20155:18;;;20148:62;-1:-1:-1;;;20226:18:1;;;20219:42;20278:19;;46384:73:0;;;;;;;;;-1:-1:-1;46477:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;46477:24:0;;46288:221::o;45811:411::-;45892:13;45908:23;45923:7;45908:14;:23::i;:::-;45892:39;;45956:5;-1:-1:-1;;;;;45950:11:0;:2;-1:-1:-1;;;;;45950:11:0;;;45942:57;;;;-1:-1:-1;;;45942:57:0;;22109:2:1;45942:57:0;;;22091:21:1;22148:2;22128:18;;;22121:30;22187:34;22167:18;;;22160:62;-1:-1:-1;;;22238:18:1;;;22231:31;22279:19;;45942:57:0;21907:397:1;45942:57:0;682:10;-1:-1:-1;;;;;46034:21:0;;;;:62;;-1:-1:-1;46059:37:0;46076:5;682:10;46947:164;:::i;46059:37::-;46012:168;;;;-1:-1:-1;;;46012:168:0;;18490:2:1;46012:168:0;;;18472:21:1;18529:2;18509:18;;;18502:30;18568:34;18548:18;;;18541:62;-1:-1:-1;;;18619:18:1;;;18612:54;18683:19;;46012:168:0;18288:420:1;46012:168:0;46193:21;46202:2;46206:7;46193:8;:21::i;:::-;45881:341;45811:411;;:::o;47178:339::-;47373:41;682:10;47406:7;47373:18;:41::i;:::-;47365:103;;;;-1:-1:-1;;;47365:103:0;;;;;;;:::i;:::-;47481:28;47491:4;47497:2;47501:7;47481:9;:28::i;70682:430::-;70748:13;70782:16;70790:7;70782;:16::i;:::-;70774:76;;;;-1:-1:-1;;;70774:76:0;;;;;;;:::i;:::-;70871:20;70918:30;70924:7;70918:30;;;;;;;;;;;;;-1:-1:-1;;;70918:30:0;;;70942:5;70918:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:5;:30::i;:::-;70949:32;70955:7;70949:32;;;;;;;;;;;;;-1:-1:-1;;;70949:32:0;;;70974:6;70949:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70982:30;70988:7;70982:30;;;;;;;;;;;;;-1:-1:-1;;;70982:30:0;;;71006:5;70982:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71013:32;71019:7;71013:32;;;;;;;;;;;;;-1:-1:-1;;;71013:32:0;;;71038:6;71013:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71047:30;71053:7;71047:30;;;;;;;;;;;;;-1:-1:-1;;;71047:30:0;;;71071:5;71047:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70901:177;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;70901:177:0;;;;;;;;;;70682:430;-1:-1:-1;;;70682:430:0:o;66424:225::-;682:10;37470:7;:5;:7::i;:::-;-1:-1:-1;;;;;37470:23:0;;37462:68;;;;-1:-1:-1;;;37462:68:0;;;;;;;:::i;:::-;66552:1:::1;66512:21:::0;;;:7:::1;:21;::::0;;;;:28:::1;;::::0;-1:-1:-1;;;;;66512:28:0::1;:42:::0;66504:92:::1;;;::::0;-1:-1:-1;;;66504:92:0;;18084:2:1;66504:92:0::1;::::0;::::1;18066:21:1::0;18123:2;18103:18;;;18096:30;18162:34;18142:18;;;18135:62;-1:-1:-1;;;18213:18:1;;;18206:35;18258:19;;66504:92:0::1;17882:401:1::0;66504:92:0::1;66607:21;::::0;;;:7:::1;:21;::::0;;;;;:34;66424:225::o;67090:106::-;682:10;37470:7;:5;:7::i;:::-;-1:-1:-1;;;;;37470:23:0;;37462:68;;;;-1:-1:-1;;;37462:68:0;;;;;;;:::i;:::-;67152:36:::1;::::0;67160:10:::1;::::0;67152:36;::::1;;;::::0;67181:6;;67152:36:::1;::::0;;;67181:6;67160:10;67152:36;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;67090:106:::0;:::o;57124:256::-;57221:7;57257:23;57274:5;57257:16;:23::i;:::-;57249:5;:31;57241:87;;;;-1:-1:-1;;;57241:87:0;;12734:2:1;57241:87:0;;;12716:21:1;12773:2;12753:18;;;12746:30;12812:34;12792:18;;;12785:62;-1:-1:-1;;;12863:18:1;;;12856:41;12914:19;;57241:87:0;12532:407:1;57241:87:0;-1:-1:-1;;;;;;57346:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;57124:256::o;47588:185::-;47726:39;47743:4;47749:2;47753:7;47726:39;;;;;;;;;;;;:16;:39::i;57646:233::-;57721:7;57757:30;57544:10;:17;;57456:113;57757:30;57749:5;:38;57741:95;;;;-1:-1:-1;;;57741:95:0;;23351:2:1;57741:95:0;;;23333:21:1;23390:2;23370:18;;;23363:30;23429:34;23409:18;;;23402:62;-1:-1:-1;;;23480:18:1;;;23473:42;23532:19;;57741:95:0;23149:408:1;57741:95:0;57854:10;57865:5;57854:17;;;;;;;;:::i;:::-;;;;;;;;;57847:24;;57646:233;;;:::o;44423:239::-;44495:7;44531:16;;;:7;:16;;;;;;-1:-1:-1;;;;;44531:16:0;44566:19;44558:73;;;;-1:-1:-1;;;44558:73:0;;19326:2:1;44558:73:0;;;19308:21:1;19365:2;19345:18;;;19338:30;19404:34;19384:18;;;19377:62;-1:-1:-1;;;19455:18:1;;;19448:39;19504:19;;44558:73:0;19124:405:1;66661:307:0;66720:7;66757:21;;;:7;:21;;;;;:26;66720:7;;66749:71;;;;-1:-1:-1;;;66749:71:0;;16559:2:1;66749:71:0;;;16541:21:1;16598:2;16578:18;;;16571:30;16637:29;16617:18;;;16610:57;16684:18;;66749:71:0;16357:351:1;66749:71:0;-1:-1:-1;;66831:12:0;66846:21;;;:7;:21;;;;;:26;;66900:28;;;;;66846:26;;-1:-1:-1;;;;;66900:28:0;;;;66661:307::o;67208:573::-;67285:10;;67250:13;;-1:-1:-1;;;67285:10:0;;;;67277:44;;;;-1:-1:-1;;;67277:44:0;;;;;;;:::i;:::-;67340:18;;:23;;:76;;-1:-1:-1;67385:18:0;;:31;;67406:10;67385:31;:::i;:::-;67367:15;:49;67340:76;67332:136;;;;-1:-1:-1;;;67332:136:0;;12317:2:1;67332:136:0;;;12299:21:1;12356:2;12336:18;;;12329:30;12395:34;12375:18;;;12368:62;-1:-1:-1;;;12446:18:1;;;12439:46;12502:19;;67332:136:0;12115:412:1;67332:136:0;67487:21;;-1:-1:-1;;;;;67487:21:0;67512:10;67487:35;;67479:90;;;;-1:-1:-1;;;67479:90:0;;21697:2:1;67479:90:0;;;21679:21:1;21736:2;21716:18;;;21709:30;21775:34;21755:18;;;21748:62;-1:-1:-1;;;21826:18:1;;;21819:41;21877:19;;67479:90:0;21495:407:1;67479:90:0;67601:15;67580:18;:36;67627:21;:34;;-1:-1:-1;;;;;;67627:34:0;67651:10;67627:34;;;67672:101;;;;;;;;;;;;;;;;;;;;67208:573;:::o;44153:208::-;44225:7;-1:-1:-1;;;;;44253:19:0;;44245:74;;;;-1:-1:-1;;;44245:74:0;;18915:2:1;44245:74:0;;;18897:21:1;18954:2;18934:18;;;18927:30;18993:34;18973:18;;;18966:62;-1:-1:-1;;;19044:18:1;;;19037:40;19094:19;;44245:74:0;18713:406:1;44245:74:0;-1:-1:-1;;;;;;44337:16:0;;;;;:9;:16;;;;;;;44153:208::o;37901:103::-;682:10;37470:7;:5;:7::i;:::-;-1:-1:-1;;;;;37470:23:0;;37462:68;;;;-1:-1:-1;;;37462:68:0;;;;;;;:::i;:::-;37966:30:::1;37993:1;37966:18;:30::i;:::-;37901:103::o:0;69583:393::-;682:10;37470:7;:5;:7::i;:::-;-1:-1:-1;;;;;37470:23:0;;37462:68;;;;-1:-1:-1;;;37462:68:0;;;;;;;:::i;:::-;69679:11:::1;69693:13;57544:10:::0;:17;;57456:113;69693:13:::1;69679:27;;69742:1;69725:14;:18;:52;;;;;69765:12;;69747:14;:30;;69725:52;69717:88;;;::::0;-1:-1:-1;;;69717:88:0;;14679:2:1;69717:88:0::1;::::0;::::1;14661:21:1::0;14718:2;14698:18;;;14691:30;-1:-1:-1;;;14737:18:1;;;14730:53;14800:18;;69717:88:0::1;14477:347:1::0;69717:88:0::1;69821:6;69816:95;69837:14;69833:1;:18;69816:95;;;69873:26;69883:3:::0;69888:10:::1;69897:1:::0;69888:6;:10:::1;:::i;:::-;69873:9;:26::i;:::-;69853:3:::0;::::1;::::0;::::1;:::i;:::-;;;;69816:95;;;-1:-1:-1::0;69936:12:0::1;::::0;:32:::1;::::0;69953:14;69936:16:::1;:32::i;:::-;69921:12;:47:::0;-1:-1:-1;;;69583:393:0:o;37250:87::-;37323:6;;-1:-1:-1;;;;;37323:6:0;;37250:87::o;44898:104::-;44954:13;44987:7;44980:14;;;;;:::i;66986:86::-;682:10;37470:7;:5;:7::i;:::-;-1:-1:-1;;;;;37470:23:0;;37462:68;;;;-1:-1:-1;;;37462:68:0;;;;;;;:::i;:::-;67054:10:::1;::::0;;-1:-1:-1;;;;67040:24:0;::::1;-1:-1:-1::0;;;67054:10:0;;;::::1;;;67053:11;67040:24:::0;;::::1;;::::0;;66986:86::o;68965:603::-;69051:1;69034:14;:18;:51;;;;;65315:2;69056:14;:29;;69034:51;69026:97;;;;-1:-1:-1;;;69026:97:0;;17682:2:1;69026:97:0;;;17664:21:1;17721:2;17701:18;;;17694:30;17760:34;17740:18;;;17733:62;-1:-1:-1;;;17811:18:1;;;17804:31;17852:19;;69026:97:0;17480:397:1;69026:97:0;65363:5;69142:33;69160:14;69142:13;57544:10;:17;;57456:113;69142:13;:17;;:33::i;:::-;:47;;69134:102;;;;-1:-1:-1;;;69134:102:0;;15031:2:1;69134:102:0;;;15013:21:1;15070:2;15050:18;;;15043:30;15109:34;15089:18;;;15082:62;-1:-1:-1;;;15160:18:1;;;15153:40;15210:19;;69134:102:0;14829:406:1;69134:102:0;69268:25;65242:17;69278:14;69268:9;:25::i;:::-;69255:9;:38;;69247:80;;;;-1:-1:-1;;;69247:80:0;;15442:2:1;69247:80:0;;;15424:21:1;15481:2;15461:18;;;15454:30;15520:31;15500:18;;;15493:59;15569:18;;69247:80:0;15240:353:1;69247:80:0;69352:6;69348:211;69368:14;69364:1;:18;69348:211;;;69404:14;69421:13;57544:10;:17;;57456:113;69421:13;69404:30;;65363:5;69453:13;57544:10;:17;;57456:113;69453:13;:26;69449:99;;;69500:32;69510:10;69522:9;69500;:32::i;:::-;-1:-1:-1;69384:3:0;;;;:::i;:::-;;;;69348:211;;46581:295;-1:-1:-1;;;;;46684:24:0;;682:10;46684:24;;46676:62;;;;-1:-1:-1;;;46676:62:0;;16205:2:1;46676:62:0;;;16187:21:1;16244:2;16224:18;;;16217:30;-1:-1:-1;;;16263:18:1;;;16256:55;16328:18;;46676:62:0;16003:349:1;46676:62:0;682:10;46751:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;46751:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;46751:53:0;;;;;;;;;;46820:48;;11560:41:1;;;46751:42:0;;682:10;46820:48;;11533:18:1;46820:48:0;;;;;;;46581:295;;:::o;47844:328::-;48019:41;682:10;48052:7;48019:18;:41::i;:::-;48011:103;;;;-1:-1:-1;;;48011:103:0;;;;;;;:::i;:::-;48125:39;48139:4;48145:2;48149:7;48158:5;48125:13;:39::i;:::-;47844:328;;;;:::o;72941:1898::-;73006:13;73040:16;73048:7;73040;:16::i;:::-;73032:76;;;;-1:-1:-1;;;73032:76:0;;;;;;;:::i;:::-;73119:23;;:::i;:::-;73153:266;;;;;;;;;;;;;;;;;;;73443:30;;;;;;;;;;;-1:-1:-1;;;73153:8:0;73443:30;;;;;;;73467:5;73443:30;;;;;;;;;;;;;;;;;;;73449:7;;73443:30;;;73467:5;73443:30;73159:1;;73443:30;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73432:5;73438:1;73432:8;;;:41;;;;73486:53;;;;;;;;;;;;;;;;;:5;73492:1;73486:8;;;:53;;;;73563:32;73569:7;73563:32;;;;;;;;;;;;;-1:-1:-1;;;73563:32:0;;;73588:6;73563:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73552:8;;;;:43;;;;73608:53;;;;;;;;;;;;;73552:8;73608:53;;;:5;73614:1;73608:8;;;:53;;;;73685:30;73691:7;73685:30;;;;;;;;;;;;;-1:-1:-1;;;73685:30:0;;;73709:5;73685:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73674:8;;;:41;73728:53;;;;;;;;;;;;;;73674:8;73728:53;;;:5;73734:1;73728:8;;;:53;;;;73805:32;73811:7;73805:32;;;;;;;;;;;;;-1:-1:-1;;;73805:32:0;;;73830:6;73805:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73794:8;;;:43;73850:54;;;;;;;;;;;;;;73794:8;73850:54;;;:5;73856:1;73850:8;;;:54;;;;73928:30;73934:7;73928:30;;;;;;;;;;;;;-1:-1:-1;;;73928:30:0;;;73952:5;73928:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73917:8;;;:41;73971:27;;;;;;;;;;;-1:-1:-1;;;73917:8:0;73971:27;;;;;;;:9;;;:27;;;;74072:8;;74082;;;;74092;;;;74102;;;;74112;;;;74122;;;;74132;;;;-1:-1:-1;;;74142:8:0;74152;;;;74055:106;;-1:-1:-1;;74055:106:0;;74152:8;;74055:106;;:::i;:::-;;;;;;;-1:-1:-1;;74055:106:0;;;;;;;74223:8;;;;74232:9;;;;74055:106;;-1:-1:-1;74199:43:0;;74055:106;;74232:9;74223:8;74199:43;;:::i;:::-;;;;;;;;;;;;;74183:60;;74256:18;74277:445;74453:17;74462:7;74453:8;:17::i;:::-;74595:28;74615:6;74595:13;:28::i;:::-;74358:319;;;;;;;;;:::i;:::-;;;;;;;;;;;;;74277:13;:445::i;:::-;74256:466;;74799:4;74749:55;;;;;;;;:::i;:::-;;;;-1:-1:-1;;74749:55:0;;;;;;;;;;72941:1898;-1:-1:-1;;;;;72941:1898:0:o;67805:1140::-;67922:10;;67886:13;;-1:-1:-1;;;67922:10:0;;;;67914:44;;;;-1:-1:-1;;;67914:44:0;;;;;;;:::i;:::-;68003:1;67983:9;67977:23;:27;67969:65;;;;-1:-1:-1;;;67969:65:0;;16915:2:1;67969:65:0;;;16897:21:1;16954:2;16934:18;;;16927:30;-1:-1:-1;;;16973:18:1;;;16966:55;17038:18;;67969:65:0;16713:349:1;67969:65:0;68094:1;68053:21;;;:7;:21;;;;;:28;;;-1:-1:-1;;;;;68053:28:0;:43;68045:95;;;;-1:-1:-1;;;68045:95:0;;23764:2:1;68045:95:0;;;23746:21:1;23803:2;23783:18;;;23776:30;23842:34;23822:18;;;23815:62;-1:-1:-1;;;23893:18:1;;;23886:37;23940:19;;68045:95:0;23562:403:1;68045:95:0;68159:21;;-1:-1:-1;;;;;68159:21:0;68184:10;68159:35;68151:100;;;;-1:-1:-1;;;68151:100:0;;22929:2:1;68151:100:0;;;22911:21:1;22968:2;22948:18;;;22941:30;23007:34;22987:18;;;22980:62;-1:-1:-1;;;23058:18:1;;;23051:51;23119:19;;68151:100:0;22727:417:1;68151:100:0;68276:21;68300:37;68327:9;68300:26;:37::i;:::-;68276:61;;68361:16;68358:528;;;68449:21;;;;:7;:21;;;;;;;;;:26;68417:27;;;;68434:9;;68417:27;;:::i;:::-;;;;;;;;;;;;;68407:38;;;;;;:68;68403:344;;;68496:21;;;;:7;:21;;;;;;;;;:28;;:41;;-1:-1:-1;;;;;;68496:41:0;68527:10;68496:41;;;;;;68561:40;;11786:25:1;;;11827:18;;;11820:60;68561:40:0;;11759:18:1;68561:40:0;;;;;;;68620:49;;68628:10;;68620:49;;68649:19;;68620:49;;;;68649:19;68628:10;68620:49;;;;;;;;;;;;;;;;;;;;;68697:34;;;;;;;;;;;;;-1:-1:-1;;;68697:34:0;;;;;;;;68403:344;68358:528;;;68795:79;;;;;;;;;;;;;;;;;;;;;;68358:528;-1:-1:-1;;68906:31:0;;;;;;;;;;;;-1:-1:-1;;;68906:31:0;;;;67805:1140;;;;:::o;46947:164::-;-1:-1:-1;;;;;47068:25:0;;;47044:4;47068:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;46947:164::o;38159:201::-;682:10;37470:7;:5;:7::i;:::-;-1:-1:-1;;;;;37470:23:0;;37462:68;;;;-1:-1:-1;;;37462:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;38248:22:0;::::1;38240:73;;;::::0;-1:-1:-1;;;38240:73:0;;13915:2:1;38240:73:0::1;::::0;::::1;13897:21:1::0;13954:2;13934:18;;;13927:30;13993:34;13973:18;;;13966:62;-1:-1:-1;;;14044:18:1;;;14037:36;14090:19;;38240:73:0::1;13713:402:1::0;38240:73:0::1;38324:28;38343:8;38324:18;:28::i;:::-;38159:201:::0;:::o;43784:305::-;43886:4;-1:-1:-1;;;;;;43923:40:0;;-1:-1:-1;;;43923:40:0;;:105;;-1:-1:-1;;;;;;;43980:48:0;;-1:-1:-1;;;43980:48:0;43923:105;:158;;;-1:-1:-1;;;;;;;;;;42210:40:0;;;44045:36;42101:157;49682:127;49747:4;49771:16;;;:7;:16;;;;;;-1:-1:-1;;;;;49771:16:0;:30;;;49682:127::o;53664:174::-;53739:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;53739:29:0;-1:-1:-1;;;;;53739:29:0;;;;;;;;:24;;53793:23;53739:24;53793:14;:23::i;:::-;-1:-1:-1;;;;;53784:46:0;;;;;;;;;;;53664:174;;:::o;49976:348::-;50069:4;50094:16;50102:7;50094;:16::i;:::-;50086:73;;;;-1:-1:-1;;;50086:73:0;;17269:2:1;50086:73:0;;;17251:21:1;17308:2;17288:18;;;17281:30;17347:34;17327:18;;;17320:62;-1:-1:-1;;;17398:18:1;;;17391:42;17450:19;;50086:73:0;17067:408:1;50086:73:0;50170:13;50186:23;50201:7;50186:14;:23::i;:::-;50170:39;;50239:5;-1:-1:-1;;;;;50228:16:0;:7;-1:-1:-1;;;;;50228:16:0;;:51;;;;50272:7;-1:-1:-1;;;;;50248:31:0;:20;50260:7;50248:11;:20::i;:::-;-1:-1:-1;;;;;50248:31:0;;50228:51;:87;;;;50283:32;50300:5;50307:7;50283:16;:32::i;:::-;50220:96;49976:348;-1:-1:-1;;;;49976:348:0:o;52968:578::-;53127:4;-1:-1:-1;;;;;53100:31:0;:23;53115:7;53100:14;:23::i;:::-;-1:-1:-1;;;;;53100:31:0;;53092:85;;;;-1:-1:-1;;;53092:85:0;;20871:2:1;53092:85:0;;;20853:21:1;20910:2;20890:18;;;20883:30;20949:34;20929:18;;;20922:62;-1:-1:-1;;;21000:18:1;;;20993:39;21049:19;;53092:85:0;20669:405:1;53092:85:0;-1:-1:-1;;;;;53196:16:0;;53188:65;;;;-1:-1:-1;;;53188:65:0;;15800:2:1;53188:65:0;;;15782:21:1;15839:2;15819:18;;;15812:30;15878:34;15858:18;;;15851:62;-1:-1:-1;;;15929:18:1;;;15922:34;15973:19;;53188:65:0;15598:400:1;53188:65:0;53266:39;53287:4;53293:2;53297:7;53266:20;:39::i;:::-;53370:29;53387:1;53391:7;53370:8;:29::i;:::-;-1:-1:-1;;;;;53412:15:0;;;;;;:9;:15;;;;;:20;;53431:1;;53412:15;:20;;53431:1;;53412:20;:::i;:::-;;;;-1:-1:-1;;;;;;;53443:13:0;;;;;;:9;:13;;;;;:18;;53460:1;;53443:13;:18;;53460:1;;53443:18;:::i;:::-;;;;-1:-1:-1;;53472:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;53472:21:0;-1:-1:-1;;;;;53472:21:0;;;;;;;;;53511:27;;53472:16;;53511:27;;;;;;;52968:578;;;:::o;71126:290::-;71224:13;71250:12;71265:59;71296:6;71304:17;71313:7;71304:8;:17::i;:::-;71279:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;71265:6;:59::i;:::-;71250:74;;71335:20;71358:5;71371;:12;71364:4;:19;;;;:::i;:::-;71358:26;;;;;;;;:::i;:::-;;;;;;;71335:49;;71402:6;71395:13;;;;71126:290;;;;;:::o;38520:191::-;38613:6;;;-1:-1:-1;;;;;38630:17:0;;;-1:-1:-1;;;;;;38630:17:0;;;;;;;38663:40;;38613:6;;;38630:17;38613:6;;38663:40;;38594:16;;38663:40;38583:128;38520:191;:::o;50666:110::-;50742:26;50752:2;50756:7;50742:26;;;;;;;;;;;;:9;:26::i;12004:98::-;12062:7;12089:5;12093:1;12089;:5;:::i;:::-;12082:12;12004:98;-1:-1:-1;;;12004:98:0:o;11623:::-;11681:7;11708:5;11712:1;11708;:5;:::i;12361:98::-;12419:7;12446:5;12450:1;12446;:5;:::i;49054:315::-;49211:28;49221:4;49227:2;49231:7;49211:9;:28::i;:::-;49258:48;49281:4;49287:2;49291:7;49300:5;49258:22;:48::i;:::-;49250:111;;;;-1:-1:-1;;;49250:111:0;;;;;;;:::i;74848:647::-;74904:13;75113:10;75109:45;;-1:-1:-1;;75136:10:0;;;;;;;;;;;;-1:-1:-1;;;75136:10:0;;;;;74848:647::o;75109:45::-;75175:5;75160:12;75208:66;75215:9;;75208:66;;75237:8;;;;:::i;:::-;;-1:-1:-1;75256:10:0;;-1:-1:-1;75264:2:0;75256:10;;:::i;:::-;;;75208:66;;;75280:19;75312:6;75302:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75302:17:0;;75280:39;;75326:138;75333:10;;75326:138;;75356:11;75366:1;75356:11;;:::i;:::-;;-1:-1:-1;75421:10:0;75429:2;75421:5;:10;:::i;:::-;75408:24;;:2;:24;:::i;:::-;75395:39;;75378:6;75385;75378:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;75378:56:0;;;;;;;;-1:-1:-1;75445:11:0;75454:2;75445:11;;:::i;:::-;;;75326:138;;75868:1607;75966:11;;75926:13;;75992:8;75988:23;;-1:-1:-1;;76002:9:0;;;;;;;;;-1:-1:-1;76002:9:0;;;75868:1607;-1:-1:-1;75868:1607:0:o;75988:23::-;76063:18;76101:1;76090:7;:3;76096:1;76090:7;:::i;:::-;76089:13;;;;:::i;:::-;76084:19;;:1;:19;:::i;:::-;76063:40;-1:-1:-1;76161:19:0;76193:15;76063:40;76206:2;76193:15;:::i;:::-;76183:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76183:26:0;;76161:48;;76222:18;76243:5;;;;;;;;;;;;;;;;;76222:26;;76312:1;76305:5;76301:13;76357:2;76349:6;76345:15;76408:1;76376:777;76431:3;76428:1;76425:10;76376:777;;;76486:1;76529:12;;;;;76523:19;76624:4;76612:2;76608:14;;;;;76590:40;;76584:47;76733:2;76729:14;;;76725:25;;76711:40;;76705:47;76862:1;76858:13;;;76854:24;;76840:39;;76834:46;76982:16;;;;76968:31;;76962:38;76660:1;76656:11;;;76754:4;76701:58;;;76692:68;76785:11;;76830:57;;;76821:67;;;;76913:11;;76958:49;;76949:59;77037:3;77033:13;77066:22;;77136:1;77121:17;;;;76479:9;76376:777;;;76380:44;77185:1;77180:3;77176:11;77206:1;77201:84;;;;77304:1;77299:82;;;;77169:212;;77201:84;-1:-1:-1;;;;;77234:17:0;;77227:43;77201:84;;77299:82;-1:-1:-1;;;;;77332:17:0;;77325:41;77169:212;-1:-1:-1;;;77397:26:0;;;77404:6;75868:1607;-1:-1:-1;;;;75868:1607:0:o;71987:942::-;72070:4;72121:8;72167:10;72070:4;72225:20;72167:10;72225:13;:20::i;:::-;72188:57;-1:-1:-1;72286:4:0;72258:25;72321:553;72338:12;:19;72336:1;:21;72321:553;;;72379:20;72427:6;72422:284;72439:17;:24;72437:1;:26;72422:284;;;72510:51;72524:17;72542:1;72524:20;;;;;;;;:::i;:::-;;;;;;;72545:12;72558:1;72545:15;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;72545:15:0;72510:13;:51::i;:::-;72507:166;;;72621:4;72603:22;;72648:5;;72507:166;72465:3;;;;:::i;:::-;;;;72422:284;;;-1:-1:-1;72737:24:0;72734:129;;72818:5;72795:28;;72842:5;;;72734:129;-1:-1:-1;72359:3:0;;;;:::i;:::-;;;;72321:553;;;-1:-1:-1;72901:20:0;71987:942;-1:-1:-1;;;;;71987:942:0:o;58492:589::-;-1:-1:-1;;;;;58698:18:0;;58694:187;;58733:40;58765:7;59908:10;:17;;59881:24;;;;:15;:24;;;;;:44;;;59936:24;;;;;;;;;;;;59804:164;58733:40;58694:187;;;58803:2;-1:-1:-1;;;;;58795:10:0;:4;-1:-1:-1;;;;;58795:10:0;;58791:90;;58822:47;58855:4;58861:7;58822:32;:47::i;:::-;-1:-1:-1;;;;;58895:16:0;;58891:183;;58928:45;58965:7;58928:36;:45::i;58891:183::-;59001:4;-1:-1:-1;;;;;58995:10:0;:2;-1:-1:-1;;;;;58995:10:0;;58991:83;;59022:40;59050:2;59054:7;59022:27;:40::i;70532:138::-;70592:7;70654:5;70637:23;;;;;;;;:::i;:::-;;;;-1:-1:-1;;70637:23:0;;;;;;;;;70627:34;;70637:23;70627:34;;;;;70532:138;-1:-1:-1;;70532:138:0:o;51003:321::-;51133:18;51139:2;51143:7;51133:5;:18::i;:::-;51184:54;51215:1;51219:2;51223:7;51232:5;51184:22;:54::i;:::-;51162:154;;;;-1:-1:-1;;;51162:154:0;;;;;;;:::i;54403:799::-;54558:4;-1:-1:-1;;;;;54579:13:0;;16821:20;16869:8;54575:620;;54615:72;;-1:-1:-1;;;54615:72:0;;-1:-1:-1;;;;;54615:36:0;;;;;:72;;682:10;;54666:4;;54672:7;;54681:5;;54615:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54615:72:0;;;;;;;;-1:-1:-1;;54615:72:0;;;;;;;;;;;;:::i;:::-;;;54611:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54857:13:0;;54853:272;;54900:60;;-1:-1:-1;;;54900:60:0;;;;;;;:::i;54853:272::-;55075:6;55069:13;55060:6;55056:2;55052:15;55045:38;54611:529;-1:-1:-1;;;;;;54738:51:0;-1:-1:-1;;;54738:51:0;;-1:-1:-1;54731:58:0;;54575:620;-1:-1:-1;55179:4:0;54403:799;;;;;;:::o;69984:540::-;70045:16;70075:18;70096:17;70106:6;70096:9;:17::i;:::-;70075:38;-1:-1:-1;70128:15:0;70124:393;;70205:16;;;70219:1;70205:16;;;;;;;;;;;-1:-1:-1;70198:23:0;69984:540;-1:-1:-1;;;69984:540:0:o;70124:393::-;70254:23;70294:10;70280:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;70280:25:0;;70254:51;;70320:13;70348:130;70372:10;70364:5;:18;70348:130;;;70428:34;70448:6;70456:5;70428:19;:34::i;:::-;70412:6;70419:5;70412:13;;;;;;;;:::i;:::-;;;;;;;;;;:50;70384:7;;;;:::i;:::-;;;;70348:130;;70124:393;70064:460;69984:540;;;:::o;71428:541::-;71514:4;71541:23;71573:27;71592:7;71573:18;:27::i;:::-;71541:60;;71612:10;71656:6;71651:278;71668:10;:17;71666:1;:19;71651:278;;;71800:15;71782:35;;;;;;;;:::i;:::-;;;;;;;;;;;;;71772:46;;;;;;71752:10;71763:1;71752:13;;;;;;;;:::i;:::-;;;;;;;;;71734:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;71724:44;;;;;;:94;71721:183;;;71860:4;71852:12;;71883:5;;71721:183;71687:3;;;;:::i;:::-;;;;71651:278;;;-1:-1:-1;71956:5:0;71428:541;-1:-1:-1;;;;71428:541:0:o;60595:988::-;60861:22;60911:1;60886:22;60903:4;60886:16;:22::i;:::-;:26;;;;:::i;:::-;60923:18;60944:26;;;:17;:26;;;;;;60861:51;;-1:-1:-1;61077:28:0;;;61073:328;;-1:-1:-1;;;;;61144:18:0;;61122:19;61144:18;;;:12;:18;;;;;;;;:34;;;;;;;;;61195:30;;;;;;:44;;;61312:30;;:17;:30;;;;;:43;;;61073:328;-1:-1:-1;61497:26:0;;;;:17;:26;;;;;;;;61490:33;;;-1:-1:-1;;;;;61541:18:0;;;;;:12;:18;;;;;:34;;;;;;;61534:41;60595:988::o;61878:1079::-;62156:10;:17;62131:22;;62156:21;;62176:1;;62156:21;:::i;:::-;62188:18;62209:24;;;:15;:24;;;;;;62582:10;:26;;62131:46;;-1:-1:-1;62209:24:0;;62131:46;;62582:26;;;;;;:::i;:::-;;;;;;;;;62560:48;;62646:11;62621:10;62632;62621:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;62726:28;;;:15;:28;;;;;;;:41;;;62898:24;;;;;62891:31;62933:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;61949:1008;;;61878:1079;:::o;59382:221::-;59467:14;59484:20;59501:2;59484:16;:20::i;:::-;-1:-1:-1;;;;;59515:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;59560:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;59382:221:0:o;51660:382::-;-1:-1:-1;;;;;51740:16:0;;51732:61;;;;-1:-1:-1;;;51732:61:0;;19736:2:1;51732:61:0;;;19718:21:1;;;19755:18;;;19748:30;19814:34;19794:18;;;19787:62;19866:18;;51732:61:0;19534:356:1;51732:61:0;51813:16;51821:7;51813;:16::i;:::-;51812:17;51804:58;;;;-1:-1:-1;;;51804:58:0;;14322:2:1;51804:58:0;;;14304:21:1;14361:2;14341:18;;;14334:30;14400;14380:18;;;14373:58;14448:18;;51804:58:0;14120:352:1;51804:58:0;51875:45;51904:1;51908:2;51912:7;51875:20;:45::i;:::-;-1:-1:-1;;;;;51933:13:0;;;;;;:9;:13;;;;;:18;;51950:1;;51933:13;:18;;51950:1;;51933:18;:::i;:::-;;;;-1:-1:-1;;51962:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;51962:21:0;-1:-1:-1;;;;;51962:21:0;;;;;;;;52001:33;;51962:16;;;52001:33;;51962:16;;52001:33;51660:382;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:631:1:-;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:173::-;718:20;;-1:-1:-1;;;;;767:31:1;;757:42;;747:70;;813:1;810;803:12;747:70;650:173;;;:::o;828:186::-;887:6;940:2;928:9;919:7;915:23;911:32;908:52;;;956:1;953;946:12;908:52;979:29;998:9;979:29;:::i;1019:260::-;1087:6;1095;1148:2;1136:9;1127:7;1123:23;1119:32;1116:52;;;1164:1;1161;1154:12;1116:52;1187:29;1206:9;1187:29;:::i;:::-;1177:39;;1235:38;1269:2;1258:9;1254:18;1235:38;:::i;:::-;1225:48;;1019:260;;;;;:::o;1284:328::-;1361:6;1369;1377;1430:2;1418:9;1409:7;1405:23;1401:32;1398:52;;;1446:1;1443;1436:12;1398:52;1469:29;1488:9;1469:29;:::i;:::-;1459:39;;1517:38;1551:2;1540:9;1536:18;1517:38;:::i;:::-;1507:48;;1602:2;1591:9;1587:18;1574:32;1564:42;;1284:328;;;;;:::o;1617:666::-;1712:6;1720;1728;1736;1789:3;1777:9;1768:7;1764:23;1760:33;1757:53;;;1806:1;1803;1796:12;1757:53;1829:29;1848:9;1829:29;:::i;:::-;1819:39;;1877:38;1911:2;1900:9;1896:18;1877:38;:::i;:::-;1867:48;;1962:2;1951:9;1947:18;1934:32;1924:42;;2017:2;2006:9;2002:18;1989:32;2044:18;2036:6;2033:30;2030:50;;;2076:1;2073;2066:12;2030:50;2099:22;;2152:4;2144:13;;2140:27;-1:-1:-1;2130:55:1;;2181:1;2178;2171:12;2130:55;2204:73;2269:7;2264:2;2251:16;2246:2;2242;2238:11;2204:73;:::i;:::-;2194:83;;;1617:666;;;;;;;:::o;2288:347::-;2353:6;2361;2414:2;2402:9;2393:7;2389:23;2385:32;2382:52;;;2430:1;2427;2420:12;2382:52;2453:29;2472:9;2453:29;:::i;:::-;2443:39;;2532:2;2521:9;2517:18;2504:32;2579:5;2572:13;2565:21;2558:5;2555:32;2545:60;;2601:1;2598;2591:12;2545:60;2624:5;2614:15;;;2288:347;;;;;:::o;2640:254::-;2708:6;2716;2769:2;2757:9;2748:7;2744:23;2740:32;2737:52;;;2785:1;2782;2775:12;2737:52;2808:29;2827:9;2808:29;:::i;:::-;2798:39;2884:2;2869:18;;;;2856:32;;-1:-1:-1;;;2640:254:1:o;2899:245::-;2957:6;3010:2;2998:9;2989:7;2985:23;2981:32;2978:52;;;3026:1;3023;3016:12;2978:52;3065:9;3052:23;3084:30;3108:5;3084:30;:::i;3149:249::-;3218:6;3271:2;3259:9;3250:7;3246:23;3242:32;3239:52;;;3287:1;3284;3277:12;3239:52;3319:9;3313:16;3338:30;3362:5;3338:30;:::i;3403:180::-;3462:6;3515:2;3503:9;3494:7;3490:23;3486:32;3483:52;;;3531:1;3528;3521:12;3483:52;-1:-1:-1;3554:23:1;;3403:180;-1:-1:-1;3403:180:1:o;3588:248::-;3656:6;3664;3717:2;3705:9;3696:7;3692:23;3688:32;3685:52;;;3733:1;3730;3723:12;3685:52;-1:-1:-1;;3756:23:1;;;3826:2;3811:18;;;3798:32;;-1:-1:-1;3588:248:1:o;3841:518::-;3919:6;3927;3980:2;3968:9;3959:7;3955:23;3951:32;3948:52;;;3996:1;3993;3986:12;3948:52;4032:9;4019:23;4009:33;;4093:2;4082:9;4078:18;4065:32;4120:18;4112:6;4109:30;4106:50;;;4152:1;4149;4142:12;4106:50;4175:22;;4228:4;4220:13;;4216:27;-1:-1:-1;4206:55:1;;4257:1;4254;4247:12;4206:55;4280:73;4345:7;4340:2;4327:16;4322:2;4318;4314:11;4280:73;:::i;:::-;4270:83;;;3841:518;;;;;:::o;4364:257::-;4405:3;4443:5;4437:12;4470:6;4465:3;4458:19;4486:63;4542:6;4535:4;4530:3;4526:14;4519:4;4512:5;4508:16;4486:63;:::i;:::-;4603:2;4582:15;-1:-1:-1;;4578:29:1;4569:39;;;;4610:4;4565:50;;4364:257;-1:-1:-1;;4364:257:1:o;4626:199::-;-1:-1:-1;;;;;;4765:26:1;;;;4753:39;;4817:1;4808:11;;4626:199::o;4830:276::-;4961:3;4999:6;4993:13;5015:53;5061:6;5056:3;5049:4;5041:6;5037:17;5015:53;:::i;:::-;5084:16;;;;;4830:276;-1:-1:-1;;4830:276:1:o;5111:470::-;5290:3;5328:6;5322:13;5344:53;5390:6;5385:3;5378:4;5370:6;5366:17;5344:53;:::i;:::-;5460:13;;5419:16;;;;5482:57;5460:13;5419:16;5516:4;5504:17;;5482:57;:::i;:::-;5555:20;;5111:470;-1:-1:-1;;;;5111:470:1:o;5586:664::-;5813:3;5851:6;5845:13;5867:53;5913:6;5908:3;5901:4;5893:6;5889:17;5867:53;:::i;:::-;5983:13;;5942:16;;;;6005:57;5983:13;5942:16;6039:4;6027:17;;6005:57;:::i;:::-;6129:13;;6084:20;;;6151:57;6129:13;6084:20;6185:4;6173:17;;6151:57;:::i;:::-;6224:20;;5586:664;-1:-1:-1;;;;;5586:664:1:o;6255:1052::-;6578:3;6616:6;6610:13;6632:53;6678:6;6673:3;6666:4;6658:6;6654:17;6632:53;:::i;:::-;6748:13;;6707:16;;;;6770:57;6748:13;6707:16;6804:4;6792:17;;6770:57;:::i;:::-;6894:13;;6849:20;;;6916:57;6894:13;6849:20;6950:4;6938:17;;6916:57;:::i;:::-;7040:13;;6995:20;;;7062:57;7040:13;6995:20;7096:4;7084:17;;7062:57;:::i;:::-;7186:13;;7141:20;;;7208:57;7186:13;7141:20;7242:4;7230:17;;7208:57;:::i;:::-;7281:20;;6255:1052;-1:-1:-1;;;;;;;6255:1052:1:o;7312:1780::-;7827:3;7865:6;7859:13;7881:53;7927:6;7922:3;7915:4;7907:6;7903:17;7881:53;:::i;:::-;7997:13;;7956:16;;;;8019:57;7997:13;7956:16;8053:4;8041:17;;8019:57;:::i;:::-;8107:6;8101:13;8123:72;8186:8;8175;8168:5;8164:20;8157:4;8149:6;8145:17;8123:72;:::i;:::-;8277:13;;8221:20;;;;8217:35;;8299:57;8277:13;8217:35;8333:4;8321:17;;8299:57;:::i;:::-;8387:6;8381:13;8403:72;8466:8;8455;8448:5;8444:20;8437:4;8429:6;8425:17;8403:72;:::i;:::-;8557:13;;8501:20;;;;8497:35;;8579:57;8557:13;8497:35;8613:4;8601:17;;8579:57;:::i;:::-;8667:6;8661:13;8683:72;8746:8;8735;8728:5;8724:20;8717:4;8709:6;8705:17;8683:72;:::i;:::-;8837:13;;8781:20;;;;8777:35;;8859:57;8837:13;8777:35;8893:4;8881:17;;8859:57;:::i;:::-;8947:6;8941:13;8963:72;9026:8;9015;9008:5;9004:20;8997:4;8989:6;8985:17;8963:72;:::i;:::-;9055:20;;9051:35;;7312:1780;-1:-1:-1;;;;;;;;;;;7312:1780:1:o;9097:1164::-;-1:-1:-1;;;9597:70:1;;9690:13;;9579:3;;9712:62;9690:13;9762:2;9753:12;;9746:4;9734:17;;9712:62;:::i;:::-;9838:66;9833:2;9793:16;;;9825:11;;;9818:87;9934:66;9929:2;9921:11;;9914:87;-1:-1:-1;;;10025:2:1;10017:11;;10010:28;10063:13;;10085:63;10063:13;10134:2;10126:11;;10119:4;10107:17;;10085:63;:::i;:::-;-1:-1:-1;;;10208:2:1;10167:17;;;;10200:11;;;10193:35;10252:2;10244:11;;9097:1164;-1:-1:-1;;;;9097:1164:1:o;10266:448::-;10528:31;10523:3;10516:44;10498:3;10589:6;10583:13;10605:62;10660:6;10655:2;10650:3;10646:12;10639:4;10631:6;10627:17;10605:62;:::i;:::-;10687:16;;;;10705:2;10683:25;;10266:448;-1:-1:-1;;10266:448:1:o;10927:488::-;-1:-1:-1;;;;;11196:15:1;;;11178:34;;11248:15;;11243:2;11228:18;;11221:43;11295:2;11280:18;;11273:34;;;11343:3;11338:2;11323:18;;11316:31;;;11121:4;;11364:45;;11389:19;;11381:6;11364:45;:::i;:::-;11356:53;10927:488;-1:-1:-1;;;;;;10927:488:1:o;11891:219::-;12040:2;12029:9;12022:21;12003:4;12060:44;12100:2;12089:9;12085:18;12077:6;12060:44;:::i;12944:414::-;13146:2;13128:21;;;13185:2;13165:18;;;13158:30;13224:34;13219:2;13204:18;;13197:62;-1:-1:-1;;;13290:2:1;13275:18;;13268:48;13348:3;13333:19;;12944:414::o;13363:345::-;13565:2;13547:21;;;13604:2;13584:18;;;13577:30;-1:-1:-1;;;13638:2:1;13623:18;;13616:51;13699:2;13684:18;;13363:345::o;20308:356::-;20510:2;20492:21;;;20529:18;;;20522:30;20588:34;20583:2;20568:18;;20561:62;20655:2;20640:18;;20308:356::o;21079:411::-;21281:2;21263:21;;;21320:2;21300:18;;;21293:30;21359:34;21354:2;21339:18;;21332:62;-1:-1:-1;;;21425:2:1;21410:18;;21403:45;21480:3;21465:19;;21079:411::o;22309:413::-;22511:2;22493:21;;;22550:2;22530:18;;;22523:30;22589:34;22584:2;22569:18;;22562:62;-1:-1:-1;;;22655:2:1;22640:18;;22633:47;22712:3;22697:19;;22309:413::o;24431:128::-;24471:3;24502:1;24498:6;24495:1;24492:13;24489:39;;;24508:18;;:::i;:::-;-1:-1:-1;24544:9:1;;24431:128::o;24564:120::-;24604:1;24630;24620:35;;24635:18;;:::i;:::-;-1:-1:-1;24669:9:1;;24564:120::o;24689:168::-;24729:7;24795:1;24791;24787:6;24783:14;24780:1;24777:21;24772:1;24765:9;24758:17;24754:45;24751:71;;;24802:18;;:::i;:::-;-1:-1:-1;24842:9:1;;24689:168::o;24862:125::-;24902:4;24930:1;24927;24924:8;24921:34;;;24935:18;;:::i;:::-;-1:-1:-1;24972:9:1;;24862:125::o;24992:258::-;25064:1;25074:113;25088:6;25085:1;25082:13;25074:113;;;25164:11;;;25158:18;25145:11;;;25138:39;25110:2;25103:10;25074:113;;;25205:6;25202:1;25199:13;25196:48;;;-1:-1:-1;;25240:1:1;25222:16;;25215:27;24992:258::o;25255:380::-;25334:1;25330:12;;;;25377;;;25398:61;;25452:4;25444:6;25440:17;25430:27;;25398:61;25505:2;25497:6;25494:14;25474:18;25471:38;25468:161;;;25551:10;25546:3;25542:20;25539:1;25532:31;25586:4;25583:1;25576:15;25614:4;25611:1;25604:15;25640:135;25679:3;-1:-1:-1;;25700:17:1;;25697:43;;;25720:18;;:::i;:::-;-1:-1:-1;25767:1:1;25756:13;;25640:135::o;25780:112::-;25812:1;25838;25828:35;;25843:18;;:::i;:::-;-1:-1:-1;25877:9:1;;25780:112::o;25897:127::-;25958:10;25953:3;25949:20;25946:1;25939:31;25989:4;25986:1;25979:15;26013:4;26010:1;26003:15;26029:127;26090:10;26085:3;26081:20;26078:1;26071:31;26121:4;26118:1;26111:15;26145:4;26142:1;26135:15;26161:127;26222:10;26217:3;26213:20;26210:1;26203:31;26253:4;26250:1;26243:15;26277:4;26274:1;26267:15;26293:127;26354:10;26349:3;26345:20;26342:1;26335:31;26385:4;26382:1;26375:15;26409:4;26406:1;26399:15;26425:127;26486:10;26481:3;26477:20;26474:1;26467:31;26517:4;26514:1;26507:15;26541:4;26538:1;26531:15;26557:131;-1:-1:-1;;;;;;26631:32:1;;26621:43;;26611:71;;26678:1;26675;26668:12

Swarm Source

ipfs://20c265a0b299f1ce7b342fca6c8fc2d2e12690f395d4f90a086e745286569b79
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.