ETH Price: $2,633.92 (+1.73%)
Gas: 1.22 Gwei

Token

Metaverse Monkeys (MM)
 

Overview

Max Total Supply

349 MM

Holders

258

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 MM
0x85772147d5d30b5a493eb4120dea412131e64294
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:
MetaverseMonkeys

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-11-28
*/

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

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 `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @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`.
     *
     * 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;

    /**
     * @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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

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

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

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

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

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

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @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: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        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) {
        _requireMinted(tokenId);

        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 overridden 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 token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_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: caller is not token owner or 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: caller is not token owner or 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @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 _ownerOf(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) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @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 from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @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 {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



/**
 * @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 ERC721, IERC721Enumerable {
    // 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 See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

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

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: contracts/MetaverseMonkeys.sol


pragma solidity ^0.8.7;






contract MetaverseMonkeys is ERC721Enumerable, Ownable {
    using Strings for uint256;
    
    uint256 public MAX_SUPPLY = 333;

    string private BASE_URI;
    string private UNREVEAL_URI;

    bytes32 public PRIVATE_ROOT;
    bytes32 public WHITELIST_ROOT;

    uint256 public PRICE = 0.92 ether;
    uint256 public PUBLIC_MINT_LIMIT = 2;

    uint256 public SALE_STEP = 0; // 0 => NONE, 1 => PRIVATE, 2 => WHITELIST, 3 => PUBLIC

    mapping(address=>uint256) private MAP_MINTED;
    uint256 public SPECIAL_INDEX = 1;
    uint256 public PUBLIC_INDEX = 56;
    constructor() ERC721("Metaverse Monkeys", "MM") {}

    function setPrivateRoot(bytes32 _root) external onlyOwner {
        PRIVATE_ROOT = _root;
    }
    function setWhitelistRoot(bytes32 _root) external onlyOwner {
        WHITELIST_ROOT = _root;
    }
    function setMintPrice(uint256 _price) external onlyOwner {
        PRICE = _price;
    }
    function setPublicMintLimit(uint256 _publicMintLimit) external onlyOwner {
        PUBLIC_MINT_LIMIT = _publicMintLimit;
    }

    
    function isPrivateListed(bytes32 _leafNode, bytes32[] memory _proof) public view returns (bool) {
        return MerkleProof.verify(_proof, PRIVATE_ROOT, _leafNode);
    }
    function isWhiteListed(bytes32 _leafNode, bytes32[] memory _proof) public view returns (bool) {
        return MerkleProof.verify(_proof, WHITELIST_ROOT, _leafNode);
    }
    function toLeaf(address account, uint256 index, uint256 amount) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(index, account, amount));
    }
    
    function numberMinted(address _owner) public view returns (uint256) {
        return MAP_MINTED[_owner];
    }

    function mintPrivatelist(uint256 _mintAmount, uint256 _index, uint256 _amount, bytes32[] calldata _proof) external payable {
        require(PUBLIC_INDEX + _mintAmount <= MAX_SUPPLY + 1, "Exceeds Max Supply");

        require(SALE_STEP >= 1, "Private sale is not opened");

        require(PRICE * _mintAmount <= msg.value, "ETH not enough");

        require(isPrivateListed(toLeaf(msg.sender, _index, _amount), _proof), "Invalid proof");
        
        require((numberMinted(msg.sender) + _mintAmount) <= _amount, "Exceeds Max Mint Amount");

        if (numberMinted(msg.sender) == 0 && SPECIAL_INDEX <= 55) {
            _mintLoopSpecial(msg.sender, 1);
            _mintLoopPublic(msg.sender, _mintAmount - 1);
        } else {
            _mintLoopPublic(msg.sender, _mintAmount);
        }
    }

    function mintWhitelist(uint256 _mintAmount, uint256 _index, uint256 _amount, bytes32[] calldata _proof) external payable {
        require(PUBLIC_INDEX + _mintAmount <= MAX_SUPPLY + 1, "Exceeds Max Supply");

        require(SALE_STEP >= 2, "Whitelist sale is not opened");

        require(PRICE * _mintAmount <= msg.value, "ETH not enough");

        require(isWhiteListed(toLeaf(msg.sender, _index, _amount), _proof), "Invalid proof");
        
        require((numberMinted(msg.sender) + _mintAmount) <= _amount, "Exceeds Max Mint Amount");

        _mintLoopPublic(msg.sender, _mintAmount);
    }

    function mintPublic(uint256 _mintAmount) external payable {
        require(PUBLIC_INDEX + _mintAmount <= MAX_SUPPLY + 1, "Exceeds Max Supply");

        require(SALE_STEP == 3, "Public Sale is not opened");

        require(PRICE * _mintAmount <= msg.value, "ETH not enough");
        
        require((numberMinted(msg.sender) + _mintAmount) <= PUBLIC_MINT_LIMIT, "Exceeds Max Mint Amount");

        _mintLoopPublic(msg.sender, _mintAmount);
    }

    function airdropSpecial(address[] memory _airdropAddresses, uint256 _mintAmount) external onlyOwner {
        require(SPECIAL_INDEX + _airdropAddresses.length * _mintAmount <= 56, "Exceeds Max Supply");

        for (uint256 i = 0; i < _airdropAddresses.length; i++) {
            address to = _airdropAddresses[i];
            _mintLoopSpecial(to, _mintAmount);
        }
    }

    function airdropPublic(address[] memory _airdropAddresses, uint256 _mintAmount) external onlyOwner {
        require(PUBLIC_INDEX + _airdropAddresses.length * _mintAmount <= MAX_SUPPLY + 1, "Exceeds Max Supply");

        for (uint256 i = 0; i < _airdropAddresses.length; i++) {
            address to = _airdropAddresses[i];
            _mintLoopPublic(to, _mintAmount);
        }
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return BASE_URI;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString())) : UNREVEAL_URI;
    }

    function setMaxSupply(uint256 _supply) external onlyOwner {
        MAX_SUPPLY = _supply;
    }

    function setBaseURI(string memory _newBaseURI) external onlyOwner {
        BASE_URI = _newBaseURI;
    }

    function setUnrevealURI(string memory _newUnrevealURI) external onlyOwner {
        UNREVEAL_URI = _newUnrevealURI;
    }

    function setSaleStep(uint256 _saleStep) external onlyOwner {
        SALE_STEP = _saleStep;
    }

    function _mintLoopSpecial(address _receiver, uint256 _mintAmount) internal {
        for (uint256 i = 0; i < _mintAmount; i++) {
            _safeMint(_receiver, SPECIAL_INDEX + i);
        }
        SPECIAL_INDEX += _mintAmount;
        MAP_MINTED[_receiver] += _mintAmount;
    }
    function _mintLoopPublic(address _receiver, uint256 _mintAmount) internal {
        for (uint256 i = 0; i < _mintAmount; i++) {
            _safeMint(_receiver, PUBLIC_INDEX + i);
        }
        PUBLIC_INDEX += _mintAmount;
        MAP_MINTED[_receiver] += _mintAmount;
    }

    function withdraw() external onlyOwner {
        uint256 curBalance = address(this).balance;
        payable(msg.sender).transfer(curBalance);
    }
}

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":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_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRIVATE_ROOT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_INDEX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_MINT_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SALE_STEP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SPECIAL_INDEX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELIST_ROOT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_airdropAddresses","type":"address[]"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"airdropPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_airdropAddresses","type":"address[]"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"airdropSpecial","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":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_leafNode","type":"bytes32"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"isPrivateListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_leafNode","type":"bytes32"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"isWhiteListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"mintPrivatelist","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mintPublic","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"mintWhitelist","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"setPrivateRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_publicMintLimit","type":"uint256"}],"name":"setPublicMintLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleStep","type":"uint256"}],"name":"setSaleStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newUnrevealURI","type":"string"}],"name":"setUnrevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"setWhitelistRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"toLeaf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405261014d600b55670cc47f20295c000060105560026011556000601255600160145560386015553480156200003757600080fd5b50604051806040016040528060118152602001704d6574617665727365204d6f6e6b65797360781b815250604051806040016040528060028152602001614d4d60f01b81525081600090816200008e9190620001bb565b5060016200009d8282620001bb565b505050620000ba620000b4620000c060201b60201c565b620000c4565b62000287565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200014157607f821691505b6020821081036200016257634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620001b657600081815260208120601f850160051c81016020861015620001915750805b601f850160051c820191505b81811015620001b2578281556001016200019d565b5050505b505050565b81516001600160401b03811115620001d757620001d762000116565b620001ef81620001e884546200012c565b8462000168565b602080601f8311600181146200022757600084156200020e5750858301515b600019600386901b1c1916600185901b178555620001b2565b600085815260208120601f198616915b82811015620002585788860151825594840194600190910190840162000237565b5085821015620002775787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612c0f80620002976000396000f3fe6080604052600436106102725760003560e01c806380dc041b1161014f578063c87b56dd116100c1578063f2fde38b1161007a578063f2fde38b14610743578063f4a0a52814610763578063f5aa406d14610783578063f9947478146107a3578063fdaf0125146107b9578063ff63cf01146107d957600080fd5b8063c87b56dd1461065e578063dc33e6811461067e578063dde47e85146106b4578063e985e9c5146106c7578063ef3e067c14610710578063efd0cbf91461073057600080fd5b806397bc411c1161011357806397bc411c146105a8578063a22cb465146105c8578063afd2b87c146105e8578063b88d4fde14610608578063bceae77b14610628578063bd6454541461063e57600080fd5b806380dc041b1461053357806384b9a4a5146105495780638d859f3e1461055f5780638da5cb5b1461057557806395d89b411461059357600080fd5b80633ccfd60b116101e85780636352211e116101ac5780636352211e146104885780636f8b44b0146104a857806370a08231146104c8578063715018a6146104e8578063731edc44146104fd578063762c0f6a1461051d57600080fd5b80633ccfd60b146103f357806342842e0e146104085780634f6ccce71461042857806353e90cbd1461044857806355f804b31461046857600080fd5b80631521b3111161023a5780631521b3111461034857806318160ddd1461036857806323b872dd146103875780632a1d6190146103a75780632f745c59146103bd57806332cb6b0c146103dd57600080fd5b806301ffc9a71461027757806302dbc96d146102ac57806306fdde03146102ce578063081812fc146102f0578063095ea7b314610328575b600080fd5b34801561028357600080fd5b506102976102923660046122d1565b6107ec565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102cc6102c7366004612375565b610817565b005b3480156102da57600080fd5b506102e36108ae565b6040516102a39190612468565b3480156102fc57600080fd5b5061031061030b36600461247b565b610940565b6040516001600160a01b0390911681526020016102a3565b34801561033457600080fd5b506102cc610343366004612494565b610967565b34801561035457600080fd5b506102976103633660046124be565b610a77565b34801561037457600080fd5b506008545b6040519081526020016102a3565b34801561039357600080fd5b506102cc6103a236600461255b565b610a8d565b3480156103b357600080fd5b50610379600f5481565b3480156103c957600080fd5b506103796103d8366004612494565b610abe565b3480156103e957600080fd5b50610379600b5481565b3480156103ff57600080fd5b506102cc610b54565b34801561041457600080fd5b506102cc61042336600461255b565b610b8f565b34801561043457600080fd5b5061037961044336600461247b565b610baa565b34801561045457600080fd5b506102cc61046336600461247b565b610c3d565b34801561047457600080fd5b506102cc6104833660046125ef565b610c4a565b34801561049457600080fd5b506103106104a336600461247b565b610c5e565b3480156104b457600080fd5b506102cc6104c336600461247b565b610cbe565b3480156104d457600080fd5b506103796104e3366004612638565b610ccb565b3480156104f457600080fd5b506102cc610d51565b34801561050957600080fd5b506102cc610518366004612375565b610d65565b34801561052957600080fd5b5061037960155481565b34801561053f57600080fd5b50610379600e5481565b34801561055557600080fd5b5061037960125481565b34801561056b57600080fd5b5061037960105481565b34801561058157600080fd5b50600a546001600160a01b0316610310565b34801561059f57600080fd5b506102e3610dfa565b3480156105b457600080fd5b506102cc6105c33660046125ef565b610e09565b3480156105d457600080fd5b506102cc6105e3366004612653565b610e1d565b3480156105f457600080fd5b506102cc61060336600461247b565b610e28565b34801561061457600080fd5b506102cc61062336600461268f565b610e35565b34801561063457600080fd5b5061037960115481565b34801561064a57600080fd5b506102976106593660046124be565b610e6d565b34801561066a57600080fd5b506102e361067936600461247b565b610e7c565b34801561068a57600080fd5b50610379610699366004612638565b6001600160a01b031660009081526013602052604090205490565b6102cc6106c236600461270b565b610fd1565b3480156106d357600080fd5b506102976106e236600461279b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561071c57600080fd5b506102cc61072b36600461247b565b6111a3565b6102cc61073e36600461247b565b6111b0565b34801561074f57600080fd5b506102cc61075e366004612638565b6112b2565b34801561076f57600080fd5b506102cc61077e36600461247b565b611328565b34801561078f57600080fd5b506102cc61079e36600461247b565b611335565b3480156107af57600080fd5b5061037960145481565b3480156107c557600080fd5b506103796107d43660046127ce565b611342565b6102cc6107e736600461270b565b61138b565b60006001600160e01b0319821663780e9d6360e01b1480610811575061081182611503565b92915050565b61081f611553565b603881835161082e9190612817565b60145461083b919061282e565b11156108625760405162461bcd60e51b815260040161085990612841565b60405180910390fd5b60005b82518110156108a95760008382815181106108825761088261286d565b6020026020010151905061089681846115ad565b50806108a181612883565b915050610865565b505050565b6060600080546108bd9061289c565b80601f01602080910402602001604051908101604052809291908181526020018280546108e99061289c565b80156109365780601f1061090b57610100808354040283529160200191610936565b820191906000526020600020905b81548152906001019060200180831161091957829003601f168201915b5050505050905090565b600061094b8261162a565b506000908152600460205260409020546001600160a01b031690565b600061097282610c5e565b9050806001600160a01b0316836001600160a01b0316036109df5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610859565b336001600160a01b03821614806109fb57506109fb81336106e2565b610a6d5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610859565b6108a98383611689565b6000610a8682600e54856116f7565b9392505050565b610a97338261170d565b610ab35760405162461bcd60e51b8152600401610859906128d6565b6108a983838361178c565b6000610ac983610ccb565b8210610b2b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610859565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610b5c611553565b6040514790339082156108fc029083906000818181858888f19350505050158015610b8b573d6000803e3d6000fd5b5050565b6108a983838360405180602001604052806000815250610e35565b6000610bb560085490565b8210610c185760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610859565b60088281548110610c2b57610c2b61286d565b90600052602060002001549050919050565b610c45611553565b601255565b610c52611553565b600c610b8b8282612971565b6000818152600260205260408120546001600160a01b0316806108115760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610859565b610cc6611553565b600b55565b60006001600160a01b038216610d355760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610859565b506001600160a01b031660009081526003602052604090205490565b610d59611553565b610d6360006118fd565b565b610d6d611553565b600b54610d7b90600161282e565b818351610d889190612817565b601554610d95919061282e565b1115610db35760405162461bcd60e51b815260040161085990612841565b60005b82518110156108a9576000838281518110610dd357610dd361286d565b60200260200101519050610de7818461194f565b5080610df281612883565b915050610db6565b6060600180546108bd9061289c565b610e11611553565b600d610b8b8282612971565b610b8b338383611991565b610e30611553565b600e55565b610e3f338361170d565b610e5b5760405162461bcd60e51b8152600401610859906128d6565b610e6784848484611a5f565b50505050565b6000610a8682600f54856116f7565b6000818152600260205260409020546060906001600160a01b0316610efb5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610859565b6000610f05611a92565b90506000815111610fa057600d8054610f1d9061289c565b80601f0160208091040260200160405190810160405280929190818152602001828054610f499061289c565b8015610f965780601f10610f6b57610100808354040283529160200191610f96565b820191906000526020600020905b815481529060010190602001808311610f7957829003601f168201915b5050505050610a86565b80610faa84611aa1565b604051602001610fbb929190612a31565b6040516020818303038152906040529392505050565b600b54610fdf90600161282e565b85601554610fed919061282e565b111561100b5760405162461bcd60e51b815260040161085990612841565b6001601254101561105e5760405162461bcd60e51b815260206004820152601a60248201527f507269766174652073616c65206973206e6f74206f70656e65640000000000006044820152606401610859565b348560105461106d9190612817565b111561108b5760405162461bcd60e51b815260040161085990612a60565b6110d2611099338686611342565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610a7792505050565b61110e5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610859565b33600090815260136020526040902054839061112b90879061282e565b11156111495760405162461bcd60e51b815260040161085990612a88565b336000908152601360205260409020541580156111695750603760145411155b15611192576111793360016115ad565b61118d33611188600188612abf565b61194f565b61119c565b61119c338661194f565b5050505050565b6111ab611553565b601155565b600b546111be90600161282e565b816015546111cc919061282e565b11156111ea5760405162461bcd60e51b815260040161085990612841565b60125460031461123c5760405162461bcd60e51b815260206004820152601960248201527f5075626c69632053616c65206973206e6f74206f70656e6564000000000000006044820152606401610859565b348160105461124b9190612817565b11156112695760405162461bcd60e51b815260040161085990612a60565b6011543360009081526013602052604090205461128790839061282e565b11156112a55760405162461bcd60e51b815260040161085990612a88565b6112af338261194f565b50565b6112ba611553565b6001600160a01b03811661131f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610859565b6112af816118fd565b611330611553565b601055565b61133d611553565b600f55565b6040805160208082019490945260609490941b6bffffffffffffffffffffffff191684820152605480850192909252805180850390920182526074909301909252815191012090565b600b5461139990600161282e565b856015546113a7919061282e565b11156113c55760405162461bcd60e51b815260040161085990612841565b600260125410156114185760405162461bcd60e51b815260206004820152601c60248201527f57686974656c6973742073616c65206973206e6f74206f70656e6564000000006044820152606401610859565b34856010546114279190612817565b11156114455760405162461bcd60e51b815260040161085990612a60565b61148c611453338686611342565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610e6d92505050565b6114c85760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610859565b3360009081526013602052604090205483906114e590879061282e565b11156111925760405162461bcd60e51b815260040161085990612a88565b60006001600160e01b031982166380ac58cd60e01b148061153457506001600160e01b03198216635b5e139f60e01b145b8061081157506301ffc9a760e01b6001600160e01b0319831614610811565b600a546001600160a01b03163314610d635760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610859565b60005b818110156115e1576115cf83826014546115ca919061282e565b611b34565b806115d981612883565b9150506115b0565b5080601460008282546115f4919061282e565b90915550506001600160a01b0382166000908152601360205260408120805483929061162190849061282e565b90915550505050565b6000818152600260205260409020546001600160a01b03166112af5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610859565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906116be82610c5e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000826117048584611b4e565b14949350505050565b60008061171983610c5e565b9050806001600160a01b0316846001600160a01b0316148061176057506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806117845750836001600160a01b031661177984610940565b6001600160a01b0316145b949350505050565b826001600160a01b031661179f82610c5e565b6001600160a01b0316146117c55760405162461bcd60e51b815260040161085990612ad2565b6001600160a01b0382166118275760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610859565b6118348383836001611b9b565b826001600160a01b031661184782610c5e565b6001600160a01b03161461186d5760405162461bcd60e51b815260040161085990612ad2565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60005b8181101561197e5761196c83826015546115ca919061282e565b8061197681612883565b915050611952565b5080601560008282546115f4919061282e565b816001600160a01b0316836001600160a01b0316036119f25760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610859565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611a6a84848461178c565b611a7684848484611ccf565b610e675760405162461bcd60e51b815260040161085990612b17565b6060600c80546108bd9061289c565b60606000611aae83611dd0565b600101905060008167ffffffffffffffff811115611ace57611ace6122ee565b6040519080825280601f01601f191660200182016040528015611af8576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611b0257509392505050565b610b8b828260405180602001604052806000815250611ea8565b600081815b8451811015611b9357611b7f82868381518110611b7257611b7261286d565b6020026020010151611edb565b915080611b8b81612883565b915050611b53565b509392505050565b611ba784848484611f0a565b6001811115611c165760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610859565b816001600160a01b038516611c7257611c6d81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611c95565b836001600160a01b0316856001600160a01b031614611c9557611c958582611f92565b6001600160a01b038416611cac5761118d8161202f565b846001600160a01b0316846001600160a01b03161461119c5761119c84826120de565b60006001600160a01b0384163b15611dc557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611d13903390899088908890600401612b69565b6020604051808303816000875af1925050508015611d4e575060408051601f3d908101601f19168201909252611d4b91810190612ba6565b60015b611dab573d808015611d7c576040519150601f19603f3d011682016040523d82523d6000602084013e611d81565b606091505b508051600003611da35760405162461bcd60e51b815260040161085990612b17565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611784565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611e0f5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611e3b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611e5957662386f26fc10000830492506010015b6305f5e1008310611e71576305f5e100830492506008015b6127108310611e8557612710830492506004015b60648310611e97576064830492506002015b600a83106108115760010192915050565b611eb28383612122565b611ebf6000848484611ccf565b6108a95760405162461bcd60e51b815260040161085990612b17565b6000818310611ef7576000828152602084905260409020610a86565b6000838152602083905260409020610a86565b6001811115610e67576001600160a01b03841615611f50576001600160a01b03841660009081526003602052604081208054839290611f4a908490612abf565b90915550505b6001600160a01b03831615610e67576001600160a01b03831660009081526003602052604081208054839290611f8790849061282e565b909155505050505050565b60006001611f9f84610ccb565b611fa99190612abf565b600083815260076020526040902054909150808214611ffc576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061204190600190612abf565b600083815260096020526040812054600880549394509092849081106120695761206961286d565b90600052602060002001549050806008838154811061208a5761208a61286d565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806120c2576120c2612bc3565b6001900381819060005260206000200160009055905550505050565b60006120e983610ccb565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166121785760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610859565b6000818152600260205260409020546001600160a01b0316156121dd5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610859565b6121eb600083836001611b9b565b6000818152600260205260409020546001600160a01b0316156122505760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610859565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b0319811681146112af57600080fd5b6000602082840312156122e357600080fd5b8135610a86816122bb565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561232d5761232d6122ee565b604052919050565b600067ffffffffffffffff82111561234f5761234f6122ee565b5060051b60200190565b80356001600160a01b038116811461237057600080fd5b919050565b6000806040838503121561238857600080fd5b823567ffffffffffffffff81111561239f57600080fd5b8301601f810185136123b057600080fd5b803560206123c56123c083612335565b612304565b82815260059290921b830181019181810190888411156123e457600080fd5b938201935b83851015612409576123fa85612359565b825293820193908201906123e9565b98969091013596505050505050565b60005b8381101561243357818101518382015260200161241b565b50506000910152565b60008151808452612454816020860160208601612418565b601f01601f19169290920160200192915050565b602081526000610a86602083018461243c565b60006020828403121561248d57600080fd5b5035919050565b600080604083850312156124a757600080fd5b6124b083612359565b946020939093013593505050565b600080604083850312156124d157600080fd5b8235915060208084013567ffffffffffffffff8111156124f057600080fd5b8401601f8101861361250157600080fd5b803561250f6123c082612335565b81815260059190911b8201830190838101908883111561252e57600080fd5b928401925b8284101561254c57833582529284019290840190612533565b80955050505050509250929050565b60008060006060848603121561257057600080fd5b61257984612359565b925061258760208501612359565b9150604084013590509250925092565b600067ffffffffffffffff8311156125b1576125b16122ee565b6125c4601f8401601f1916602001612304565b90508281528383830111156125d857600080fd5b828260208301376000602084830101529392505050565b60006020828403121561260157600080fd5b813567ffffffffffffffff81111561261857600080fd5b8201601f8101841361262957600080fd5b61178484823560208401612597565b60006020828403121561264a57600080fd5b610a8682612359565b6000806040838503121561266657600080fd5b61266f83612359565b91506020830135801515811461268457600080fd5b809150509250929050565b600080600080608085870312156126a557600080fd5b6126ae85612359565b93506126bc60208601612359565b925060408501359150606085013567ffffffffffffffff8111156126df57600080fd5b8501601f810187136126f057600080fd5b6126ff87823560208401612597565b91505092959194509250565b60008060008060006080868803121561272357600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8082111561275057600080fd5b818801915088601f83011261276457600080fd5b81358181111561277357600080fd5b8960208260051b850101111561278857600080fd5b9699959850939650602001949392505050565b600080604083850312156127ae57600080fd5b6127b783612359565b91506127c560208401612359565b90509250929050565b6000806000606084860312156127e357600080fd5b6127ec84612359565b95602085013595506040909401359392505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761081157610811612801565b8082018082111561081157610811612801565b60208082526012908201527145786365656473204d617820537570706c7960701b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006001820161289557612895612801565b5060010190565b600181811c908216806128b057607f821691505b6020821081036128d057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b601f8211156108a957600081815260208120601f850160051c8101602086101561294a5750805b601f850160051c820191505b8181101561296957828155600101612956565b505050505050565b815167ffffffffffffffff81111561298b5761298b6122ee565b61299f81612999845461289c565b84612923565b602080601f8311600181146129d457600084156129bc5750858301515b600019600386901b1c1916600185901b178555612969565b600085815260208120601f198616915b82811015612a03578886015182559484019460019091019084016129e4565b5085821015612a215787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008351612a43818460208801612418565b835190830190612a57818360208801612418565b01949350505050565b6020808252600e908201526d08aa89040dcdee840cadcdeeaced60931b604082015260600190565b60208082526017908201527f45786365656473204d6178204d696e7420416d6f756e74000000000000000000604082015260600190565b8181038181111561081157610811612801565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612b9c9083018461243c565b9695505050505050565b600060208284031215612bb857600080fd5b8151610a86816122bb565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220274caea4e792d0837a4f4ced777b8d2413e77fbbfdf50b8b304d98e0d713133064736f6c63430008110033

Deployed Bytecode

0x6080604052600436106102725760003560e01c806380dc041b1161014f578063c87b56dd116100c1578063f2fde38b1161007a578063f2fde38b14610743578063f4a0a52814610763578063f5aa406d14610783578063f9947478146107a3578063fdaf0125146107b9578063ff63cf01146107d957600080fd5b8063c87b56dd1461065e578063dc33e6811461067e578063dde47e85146106b4578063e985e9c5146106c7578063ef3e067c14610710578063efd0cbf91461073057600080fd5b806397bc411c1161011357806397bc411c146105a8578063a22cb465146105c8578063afd2b87c146105e8578063b88d4fde14610608578063bceae77b14610628578063bd6454541461063e57600080fd5b806380dc041b1461053357806384b9a4a5146105495780638d859f3e1461055f5780638da5cb5b1461057557806395d89b411461059357600080fd5b80633ccfd60b116101e85780636352211e116101ac5780636352211e146104885780636f8b44b0146104a857806370a08231146104c8578063715018a6146104e8578063731edc44146104fd578063762c0f6a1461051d57600080fd5b80633ccfd60b146103f357806342842e0e146104085780634f6ccce71461042857806353e90cbd1461044857806355f804b31461046857600080fd5b80631521b3111161023a5780631521b3111461034857806318160ddd1461036857806323b872dd146103875780632a1d6190146103a75780632f745c59146103bd57806332cb6b0c146103dd57600080fd5b806301ffc9a71461027757806302dbc96d146102ac57806306fdde03146102ce578063081812fc146102f0578063095ea7b314610328575b600080fd5b34801561028357600080fd5b506102976102923660046122d1565b6107ec565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102cc6102c7366004612375565b610817565b005b3480156102da57600080fd5b506102e36108ae565b6040516102a39190612468565b3480156102fc57600080fd5b5061031061030b36600461247b565b610940565b6040516001600160a01b0390911681526020016102a3565b34801561033457600080fd5b506102cc610343366004612494565b610967565b34801561035457600080fd5b506102976103633660046124be565b610a77565b34801561037457600080fd5b506008545b6040519081526020016102a3565b34801561039357600080fd5b506102cc6103a236600461255b565b610a8d565b3480156103b357600080fd5b50610379600f5481565b3480156103c957600080fd5b506103796103d8366004612494565b610abe565b3480156103e957600080fd5b50610379600b5481565b3480156103ff57600080fd5b506102cc610b54565b34801561041457600080fd5b506102cc61042336600461255b565b610b8f565b34801561043457600080fd5b5061037961044336600461247b565b610baa565b34801561045457600080fd5b506102cc61046336600461247b565b610c3d565b34801561047457600080fd5b506102cc6104833660046125ef565b610c4a565b34801561049457600080fd5b506103106104a336600461247b565b610c5e565b3480156104b457600080fd5b506102cc6104c336600461247b565b610cbe565b3480156104d457600080fd5b506103796104e3366004612638565b610ccb565b3480156104f457600080fd5b506102cc610d51565b34801561050957600080fd5b506102cc610518366004612375565b610d65565b34801561052957600080fd5b5061037960155481565b34801561053f57600080fd5b50610379600e5481565b34801561055557600080fd5b5061037960125481565b34801561056b57600080fd5b5061037960105481565b34801561058157600080fd5b50600a546001600160a01b0316610310565b34801561059f57600080fd5b506102e3610dfa565b3480156105b457600080fd5b506102cc6105c33660046125ef565b610e09565b3480156105d457600080fd5b506102cc6105e3366004612653565b610e1d565b3480156105f457600080fd5b506102cc61060336600461247b565b610e28565b34801561061457600080fd5b506102cc61062336600461268f565b610e35565b34801561063457600080fd5b5061037960115481565b34801561064a57600080fd5b506102976106593660046124be565b610e6d565b34801561066a57600080fd5b506102e361067936600461247b565b610e7c565b34801561068a57600080fd5b50610379610699366004612638565b6001600160a01b031660009081526013602052604090205490565b6102cc6106c236600461270b565b610fd1565b3480156106d357600080fd5b506102976106e236600461279b565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561071c57600080fd5b506102cc61072b36600461247b565b6111a3565b6102cc61073e36600461247b565b6111b0565b34801561074f57600080fd5b506102cc61075e366004612638565b6112b2565b34801561076f57600080fd5b506102cc61077e36600461247b565b611328565b34801561078f57600080fd5b506102cc61079e36600461247b565b611335565b3480156107af57600080fd5b5061037960145481565b3480156107c557600080fd5b506103796107d43660046127ce565b611342565b6102cc6107e736600461270b565b61138b565b60006001600160e01b0319821663780e9d6360e01b1480610811575061081182611503565b92915050565b61081f611553565b603881835161082e9190612817565b60145461083b919061282e565b11156108625760405162461bcd60e51b815260040161085990612841565b60405180910390fd5b60005b82518110156108a95760008382815181106108825761088261286d565b6020026020010151905061089681846115ad565b50806108a181612883565b915050610865565b505050565b6060600080546108bd9061289c565b80601f01602080910402602001604051908101604052809291908181526020018280546108e99061289c565b80156109365780601f1061090b57610100808354040283529160200191610936565b820191906000526020600020905b81548152906001019060200180831161091957829003601f168201915b5050505050905090565b600061094b8261162a565b506000908152600460205260409020546001600160a01b031690565b600061097282610c5e565b9050806001600160a01b0316836001600160a01b0316036109df5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610859565b336001600160a01b03821614806109fb57506109fb81336106e2565b610a6d5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610859565b6108a98383611689565b6000610a8682600e54856116f7565b9392505050565b610a97338261170d565b610ab35760405162461bcd60e51b8152600401610859906128d6565b6108a983838361178c565b6000610ac983610ccb565b8210610b2b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610859565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610b5c611553565b6040514790339082156108fc029083906000818181858888f19350505050158015610b8b573d6000803e3d6000fd5b5050565b6108a983838360405180602001604052806000815250610e35565b6000610bb560085490565b8210610c185760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610859565b60088281548110610c2b57610c2b61286d565b90600052602060002001549050919050565b610c45611553565b601255565b610c52611553565b600c610b8b8282612971565b6000818152600260205260408120546001600160a01b0316806108115760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610859565b610cc6611553565b600b55565b60006001600160a01b038216610d355760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610859565b506001600160a01b031660009081526003602052604090205490565b610d59611553565b610d6360006118fd565b565b610d6d611553565b600b54610d7b90600161282e565b818351610d889190612817565b601554610d95919061282e565b1115610db35760405162461bcd60e51b815260040161085990612841565b60005b82518110156108a9576000838281518110610dd357610dd361286d565b60200260200101519050610de7818461194f565b5080610df281612883565b915050610db6565b6060600180546108bd9061289c565b610e11611553565b600d610b8b8282612971565b610b8b338383611991565b610e30611553565b600e55565b610e3f338361170d565b610e5b5760405162461bcd60e51b8152600401610859906128d6565b610e6784848484611a5f565b50505050565b6000610a8682600f54856116f7565b6000818152600260205260409020546060906001600160a01b0316610efb5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610859565b6000610f05611a92565b90506000815111610fa057600d8054610f1d9061289c565b80601f0160208091040260200160405190810160405280929190818152602001828054610f499061289c565b8015610f965780601f10610f6b57610100808354040283529160200191610f96565b820191906000526020600020905b815481529060010190602001808311610f7957829003601f168201915b5050505050610a86565b80610faa84611aa1565b604051602001610fbb929190612a31565b6040516020818303038152906040529392505050565b600b54610fdf90600161282e565b85601554610fed919061282e565b111561100b5760405162461bcd60e51b815260040161085990612841565b6001601254101561105e5760405162461bcd60e51b815260206004820152601a60248201527f507269766174652073616c65206973206e6f74206f70656e65640000000000006044820152606401610859565b348560105461106d9190612817565b111561108b5760405162461bcd60e51b815260040161085990612a60565b6110d2611099338686611342565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610a7792505050565b61110e5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610859565b33600090815260136020526040902054839061112b90879061282e565b11156111495760405162461bcd60e51b815260040161085990612a88565b336000908152601360205260409020541580156111695750603760145411155b15611192576111793360016115ad565b61118d33611188600188612abf565b61194f565b61119c565b61119c338661194f565b5050505050565b6111ab611553565b601155565b600b546111be90600161282e565b816015546111cc919061282e565b11156111ea5760405162461bcd60e51b815260040161085990612841565b60125460031461123c5760405162461bcd60e51b815260206004820152601960248201527f5075626c69632053616c65206973206e6f74206f70656e6564000000000000006044820152606401610859565b348160105461124b9190612817565b11156112695760405162461bcd60e51b815260040161085990612a60565b6011543360009081526013602052604090205461128790839061282e565b11156112a55760405162461bcd60e51b815260040161085990612a88565b6112af338261194f565b50565b6112ba611553565b6001600160a01b03811661131f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610859565b6112af816118fd565b611330611553565b601055565b61133d611553565b600f55565b6040805160208082019490945260609490941b6bffffffffffffffffffffffff191684820152605480850192909252805180850390920182526074909301909252815191012090565b600b5461139990600161282e565b856015546113a7919061282e565b11156113c55760405162461bcd60e51b815260040161085990612841565b600260125410156114185760405162461bcd60e51b815260206004820152601c60248201527f57686974656c6973742073616c65206973206e6f74206f70656e6564000000006044820152606401610859565b34856010546114279190612817565b11156114455760405162461bcd60e51b815260040161085990612a60565b61148c611453338686611342565b838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610e6d92505050565b6114c85760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610859565b3360009081526013602052604090205483906114e590879061282e565b11156111925760405162461bcd60e51b815260040161085990612a88565b60006001600160e01b031982166380ac58cd60e01b148061153457506001600160e01b03198216635b5e139f60e01b145b8061081157506301ffc9a760e01b6001600160e01b0319831614610811565b600a546001600160a01b03163314610d635760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610859565b60005b818110156115e1576115cf83826014546115ca919061282e565b611b34565b806115d981612883565b9150506115b0565b5080601460008282546115f4919061282e565b90915550506001600160a01b0382166000908152601360205260408120805483929061162190849061282e565b90915550505050565b6000818152600260205260409020546001600160a01b03166112af5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610859565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906116be82610c5e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000826117048584611b4e565b14949350505050565b60008061171983610c5e565b9050806001600160a01b0316846001600160a01b0316148061176057506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806117845750836001600160a01b031661177984610940565b6001600160a01b0316145b949350505050565b826001600160a01b031661179f82610c5e565b6001600160a01b0316146117c55760405162461bcd60e51b815260040161085990612ad2565b6001600160a01b0382166118275760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610859565b6118348383836001611b9b565b826001600160a01b031661184782610c5e565b6001600160a01b03161461186d5760405162461bcd60e51b815260040161085990612ad2565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60005b8181101561197e5761196c83826015546115ca919061282e565b8061197681612883565b915050611952565b5080601560008282546115f4919061282e565b816001600160a01b0316836001600160a01b0316036119f25760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610859565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611a6a84848461178c565b611a7684848484611ccf565b610e675760405162461bcd60e51b815260040161085990612b17565b6060600c80546108bd9061289c565b60606000611aae83611dd0565b600101905060008167ffffffffffffffff811115611ace57611ace6122ee565b6040519080825280601f01601f191660200182016040528015611af8576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611b0257509392505050565b610b8b828260405180602001604052806000815250611ea8565b600081815b8451811015611b9357611b7f82868381518110611b7257611b7261286d565b6020026020010151611edb565b915080611b8b81612883565b915050611b53565b509392505050565b611ba784848484611f0a565b6001811115611c165760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610859565b816001600160a01b038516611c7257611c6d81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611c95565b836001600160a01b0316856001600160a01b031614611c9557611c958582611f92565b6001600160a01b038416611cac5761118d8161202f565b846001600160a01b0316846001600160a01b03161461119c5761119c84826120de565b60006001600160a01b0384163b15611dc557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611d13903390899088908890600401612b69565b6020604051808303816000875af1925050508015611d4e575060408051601f3d908101601f19168201909252611d4b91810190612ba6565b60015b611dab573d808015611d7c576040519150601f19603f3d011682016040523d82523d6000602084013e611d81565b606091505b508051600003611da35760405162461bcd60e51b815260040161085990612b17565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611784565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611e0f5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611e3b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611e5957662386f26fc10000830492506010015b6305f5e1008310611e71576305f5e100830492506008015b6127108310611e8557612710830492506004015b60648310611e97576064830492506002015b600a83106108115760010192915050565b611eb28383612122565b611ebf6000848484611ccf565b6108a95760405162461bcd60e51b815260040161085990612b17565b6000818310611ef7576000828152602084905260409020610a86565b6000838152602083905260409020610a86565b6001811115610e67576001600160a01b03841615611f50576001600160a01b03841660009081526003602052604081208054839290611f4a908490612abf565b90915550505b6001600160a01b03831615610e67576001600160a01b03831660009081526003602052604081208054839290611f8790849061282e565b909155505050505050565b60006001611f9f84610ccb565b611fa99190612abf565b600083815260076020526040902054909150808214611ffc576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061204190600190612abf565b600083815260096020526040812054600880549394509092849081106120695761206961286d565b90600052602060002001549050806008838154811061208a5761208a61286d565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806120c2576120c2612bc3565b6001900381819060005260206000200160009055905550505050565b60006120e983610ccb565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166121785760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610859565b6000818152600260205260409020546001600160a01b0316156121dd5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610859565b6121eb600083836001611b9b565b6000818152600260205260409020546001600160a01b0316156122505760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610859565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b0319811681146112af57600080fd5b6000602082840312156122e357600080fd5b8135610a86816122bb565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561232d5761232d6122ee565b604052919050565b600067ffffffffffffffff82111561234f5761234f6122ee565b5060051b60200190565b80356001600160a01b038116811461237057600080fd5b919050565b6000806040838503121561238857600080fd5b823567ffffffffffffffff81111561239f57600080fd5b8301601f810185136123b057600080fd5b803560206123c56123c083612335565b612304565b82815260059290921b830181019181810190888411156123e457600080fd5b938201935b83851015612409576123fa85612359565b825293820193908201906123e9565b98969091013596505050505050565b60005b8381101561243357818101518382015260200161241b565b50506000910152565b60008151808452612454816020860160208601612418565b601f01601f19169290920160200192915050565b602081526000610a86602083018461243c565b60006020828403121561248d57600080fd5b5035919050565b600080604083850312156124a757600080fd5b6124b083612359565b946020939093013593505050565b600080604083850312156124d157600080fd5b8235915060208084013567ffffffffffffffff8111156124f057600080fd5b8401601f8101861361250157600080fd5b803561250f6123c082612335565b81815260059190911b8201830190838101908883111561252e57600080fd5b928401925b8284101561254c57833582529284019290840190612533565b80955050505050509250929050565b60008060006060848603121561257057600080fd5b61257984612359565b925061258760208501612359565b9150604084013590509250925092565b600067ffffffffffffffff8311156125b1576125b16122ee565b6125c4601f8401601f1916602001612304565b90508281528383830111156125d857600080fd5b828260208301376000602084830101529392505050565b60006020828403121561260157600080fd5b813567ffffffffffffffff81111561261857600080fd5b8201601f8101841361262957600080fd5b61178484823560208401612597565b60006020828403121561264a57600080fd5b610a8682612359565b6000806040838503121561266657600080fd5b61266f83612359565b91506020830135801515811461268457600080fd5b809150509250929050565b600080600080608085870312156126a557600080fd5b6126ae85612359565b93506126bc60208601612359565b925060408501359150606085013567ffffffffffffffff8111156126df57600080fd5b8501601f810187136126f057600080fd5b6126ff87823560208401612597565b91505092959194509250565b60008060008060006080868803121561272357600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8082111561275057600080fd5b818801915088601f83011261276457600080fd5b81358181111561277357600080fd5b8960208260051b850101111561278857600080fd5b9699959850939650602001949392505050565b600080604083850312156127ae57600080fd5b6127b783612359565b91506127c560208401612359565b90509250929050565b6000806000606084860312156127e357600080fd5b6127ec84612359565b95602085013595506040909401359392505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761081157610811612801565b8082018082111561081157610811612801565b60208082526012908201527145786365656473204d617820537570706c7960701b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006001820161289557612895612801565b5060010190565b600181811c908216806128b057607f821691505b6020821081036128d057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b601f8211156108a957600081815260208120601f850160051c8101602086101561294a5750805b601f850160051c820191505b8181101561296957828155600101612956565b505050505050565b815167ffffffffffffffff81111561298b5761298b6122ee565b61299f81612999845461289c565b84612923565b602080601f8311600181146129d457600084156129bc5750858301515b600019600386901b1c1916600185901b178555612969565b600085815260208120601f198616915b82811015612a03578886015182559484019460019091019084016129e4565b5085821015612a215787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008351612a43818460208801612418565b835190830190612a57818360208801612418565b01949350505050565b6020808252600e908201526d08aa89040dcdee840cadcdeeaced60931b604082015260600190565b60208082526017908201527f45786365656473204d6178204d696e7420416d6f756e74000000000000000000604082015260600190565b8181038181111561081157610811612801565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612b9c9083018461243c565b9695505050505050565b600060208284031215612bb857600080fd5b8151610a86816122bb565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220274caea4e792d0837a4f4ced777b8d2413e77fbbfdf50b8b304d98e0d713133064736f6c63430008110033

Deployed Bytecode Sourcemap

72068:6151:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56490:224;;;;;;;;;;-1:-1:-1;56490:224:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;56490:224:0;;;;;;;;75739:385;;;;;;;;;;-1:-1:-1;75739:385:0;;;;;:::i;:::-;;:::i;:::-;;40552:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;42064:171::-;;;;;;;;;;-1:-1:-1;42064:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3447:32:1;;;3429:51;;3417:2;3402:18;42064:171:0;3283:203:1;41582:416:0;;;;;;;;;;-1:-1:-1;41582:416:0;;;;;:::i;:::-;;:::i;73159:173::-;;;;;;;;;;-1:-1:-1;73159:173:0;;;;;:::i;:::-;;:::i;57130:113::-;;;;;;;;;;-1:-1:-1;57218:10:0;:17;57130:113;;;4860:25:1;;;4848:2;4833:18;57130:113:0;4714:177:1;42764:335:0;;;;;;;;;;-1:-1:-1;42764:335:0;;;;;:::i;:::-;;:::i;72308:29::-;;;;;;;;;;;;;;;;56798:256;;;;;;;;;;-1:-1:-1;56798:256:0;;;;;:::i;:::-;;:::i;72168:31::-;;;;;;;;;;;;;;;;78065:151;;;;;;;;;;;;;:::i;43170:185::-;;;;;;;;;;-1:-1:-1;43170:185:0;;;;;:::i;:::-;;:::i;57320:233::-;;;;;;;;;;-1:-1:-1;57320:233:0;;;;;:::i;:::-;;:::i;77373:99::-;;;;;;;;;;-1:-1:-1;77373:99:0;;;;;:::i;:::-;;:::i;77127:107::-;;;;;;;;;;-1:-1:-1;77127:107:0;;;;;:::i;:::-;;:::i;40262:223::-;;;;;;;;;;-1:-1:-1;40262:223:0;;;;;:::i;:::-;;:::i;77022:97::-;;;;;;;;;;-1:-1:-1;77022:97:0;;;;;:::i;:::-;;:::i;39993:207::-;;;;;;;;;;-1:-1:-1;39993:207:0;;;;;:::i;:::-;;:::i;12773:103::-;;;;;;;;;;;;;:::i;76132:394::-;;;;;;;;;;-1:-1:-1;76132:394:0;;;;;:::i;:::-;;:::i;72614:32::-;;;;;;;;;;;;;;;;72274:27;;;;;;;;;;;;;;;;72431:28;;;;;;;;;;;;;;;;72346:33;;;;;;;;;;;;;;;;12125:87;;;;;;;;;;-1:-1:-1;12198:6:0;;-1:-1:-1;;;;;12198:6:0;12125:87;;40721:104;;;;;;;;;;;;;:::i;77242:123::-;;;;;;;;;;-1:-1:-1;77242:123:0;;;;;:::i;:::-;;:::i;42307:155::-;;;;;;;;;;-1:-1:-1;42307:155:0;;;;;:::i;:::-;;:::i;72711:97::-;;;;;;;;;;-1:-1:-1;72711:97:0;;;;;:::i;:::-;;:::i;43426:322::-;;;;;;;;;;-1:-1:-1;43426:322:0;;;;;:::i;:::-;;:::i;72386:36::-;;;;;;;;;;;;;;;;73338:173;;;;;;;;;;-1:-1:-1;73338:173:0;;;;;:::i;:::-;;:::i;76651:363::-;;;;;;;;;;-1:-1:-1;76651:363:0;;;;;:::i;:::-;;:::i;73700:112::-;;;;;;;;;;-1:-1:-1;73700:112:0;;;;;:::i;:::-;-1:-1:-1;;;;;73786:18:0;73759:7;73786:18;;;:10;:18;;;;;;;73700:112;73820:822;;;;;;:::i;:::-;;:::i;42533:164::-;;;;;;;;;;-1:-1:-1;42533:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;42654:25:0;;;42630:4;42654:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;42533:164;73017:128;;;;;;;;;;-1:-1:-1;73017:128:0;;;;;:::i;:::-;;:::i;75271:460::-;;;;;;:::i;:::-;;:::i;13031:201::-;;;;;;;;;;-1:-1:-1;13031:201:0;;;;;:::i;:::-;;:::i;72921:90::-;;;;;;;;;;-1:-1:-1;72921:90:0;;;;;:::i;:::-;;:::i;72814:101::-;;;;;;;;;;-1:-1:-1;72814:101:0;;;;;:::i;:::-;;:::i;72575:32::-;;;;;;;;;;;;;;;;73517:171;;;;;;;;;;-1:-1:-1;73517:171:0;;;;;:::i;:::-;;:::i;74650:613::-;;;;;;:::i;:::-;;:::i;56490:224::-;56592:4;-1:-1:-1;;;;;;56616:50:0;;-1:-1:-1;;;56616:50:0;;:90;;;56670:36;56694:11;56670:23;:36::i;:::-;56609:97;56490:224;-1:-1:-1;;56490:224:0:o;75739:385::-;12011:13;:11;:13::i;:::-;75916:2:::1;75901:11;75874:17;:24;:38;;;;:::i;:::-;75858:13;;:54;;;;:::i;:::-;:60;;75850:91;;;;-1:-1:-1::0;;;75850:91:0::1;;;;;;;:::i;:::-;;;;;;;;;75959:9;75954:163;75978:17;:24;75974:1;:28;75954:163;;;76024:10;76037:17;76055:1;76037:20;;;;;;;;:::i;:::-;;;;;;;76024:33;;76072;76089:2;76093:11;76072:16;:33::i;:::-;-1:-1:-1::0;76004:3:0;::::1;::::0;::::1;:::i;:::-;;;;75954:163;;;;75739:385:::0;;:::o;40552:100::-;40606:13;40639:5;40632:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40552:100;:::o;42064:171::-;42140:7;42160:23;42175:7;42160:14;:23::i;:::-;-1:-1:-1;42203:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;42203:24:0;;42064:171::o;41582:416::-;41663:13;41679:23;41694:7;41679:14;:23::i;:::-;41663:39;;41727:5;-1:-1:-1;;;;;41721:11:0;:2;-1:-1:-1;;;;;41721:11:0;;41713:57;;;;-1:-1:-1;;;41713:57:0;;10737:2:1;41713:57:0;;;10719:21:1;10776:2;10756:18;;;10749:30;10815:34;10795:18;;;10788:62;-1:-1:-1;;;10866:18:1;;;10859:31;10907:19;;41713:57:0;10535:397:1;41713:57:0;10756:10;-1:-1:-1;;;;;41805:21:0;;;;:62;;-1:-1:-1;41830:37:0;41847:5;10756:10;42533:164;:::i;41830:37::-;41783:173;;;;-1:-1:-1;;;41783:173:0;;11139:2:1;41783:173:0;;;11121:21:1;11178:2;11158:18;;;11151:30;11217:34;11197:18;;;11190:62;11288:31;11268:18;;;11261:59;11337:19;;41783:173:0;10937:425:1;41783:173:0;41969:21;41978:2;41982:7;41969:8;:21::i;73159:173::-;73249:4;73273:51;73292:6;73300:12;;73314:9;73273:18;:51::i;:::-;73266:58;73159:173;-1:-1:-1;;;73159:173:0:o;42764:335::-;42959:41;10756:10;42992:7;42959:18;:41::i;:::-;42951:99;;;;-1:-1:-1;;;42951:99:0;;;;;;;:::i;:::-;43063:28;43073:4;43079:2;43083:7;43063:9;:28::i;56798:256::-;56895:7;56931:23;56948:5;56931:16;:23::i;:::-;56923:5;:31;56915:87;;;;-1:-1:-1;;;56915:87:0;;11983:2:1;56915:87:0;;;11965:21:1;12022:2;12002:18;;;11995:30;12061:34;12041:18;;;12034:62;-1:-1:-1;;;12112:18:1;;;12105:41;12163:19;;56915:87:0;11781:407:1;56915:87:0;-1:-1:-1;;;;;;57020:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;56798:256::o;78065:151::-;12011:13;:11;:13::i;:::-;78168:40:::1;::::0;78136:21:::1;::::0;78176:10:::1;::::0;78168:40;::::1;;;::::0;78136:21;;78115:18:::1;78168:40:::0;78115:18;78168:40;78136:21;78176:10;78168:40;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;78104:112;78065:151::o:0;43170:185::-;43308:39;43325:4;43331:2;43335:7;43308:39;;;;;;;;;;;;:16;:39::i;57320:233::-;57395:7;57431:30;57218:10;:17;;57130:113;57431:30;57423:5;:38;57415:95;;;;-1:-1:-1;;;57415:95:0;;12395:2:1;57415:95:0;;;12377:21:1;12434:2;12414:18;;;12407:30;12473:34;12453:18;;;12446:62;-1:-1:-1;;;12524:18:1;;;12517:42;12576:19;;57415:95:0;12193:408:1;57415:95:0;57528:10;57539:5;57528:17;;;;;;;;:::i;:::-;;;;;;;;;57521:24;;57320:233;;;:::o;77373:99::-;12011:13;:11;:13::i;:::-;77443:9:::1;:21:::0;77373:99::o;77127:107::-;12011:13;:11;:13::i;:::-;77204:8:::1;:22;77215:11:::0;77204:8;:22:::1;:::i;40262:223::-:0;40334:7;45149:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45149:16:0;;40398:56;;;;-1:-1:-1;;;40398:56:0;;15012:2:1;40398:56:0;;;14994:21:1;15051:2;15031:18;;;15024:30;-1:-1:-1;;;15070:18:1;;;15063:54;15134:18;;40398:56:0;14810:348:1;77022:97:0;12011:13;:11;:13::i;:::-;77091:10:::1;:20:::0;77022:97::o;39993:207::-;40065:7;-1:-1:-1;;;;;40093:19:0;;40085:73;;;;-1:-1:-1;;;40085:73:0;;15365:2:1;40085:73:0;;;15347:21:1;15404:2;15384:18;;;15377:30;15443:34;15423:18;;;15416:62;-1:-1:-1;;;15494:18:1;;;15487:39;15543:19;;40085:73:0;15163:405:1;40085:73:0;-1:-1:-1;;;;;;40176:16:0;;;;;:9;:16;;;;;;;39993:207::o;12773:103::-;12011:13;:11;:13::i;:::-;12838:30:::1;12865:1;12838:18;:30::i;:::-;12773:103::o:0;76132:394::-;12011:13;:11;:13::i;:::-;76307:10:::1;::::0;:14:::1;::::0;76320:1:::1;76307:14;:::i;:::-;76292:11;76265:17;:24;:38;;;;:::i;:::-;76250:12;;:53;;;;:::i;:::-;:71;;76242:102;;;;-1:-1:-1::0;;;76242:102:0::1;;;;;;;:::i;:::-;76362:9;76357:162;76381:17;:24;76377:1;:28;76357:162;;;76427:10;76440:17;76458:1;76440:20;;;;;;;;:::i;:::-;;;;;;;76427:33;;76475:32;76491:2;76495:11;76475:15;:32::i;:::-;-1:-1:-1::0;76407:3:0;::::1;::::0;::::1;:::i;:::-;;;;76357:162;;40721:104:::0;40777:13;40810:7;40803:14;;;;;:::i;77242:123::-;12011:13;:11;:13::i;:::-;77327:12:::1;:30;77342:15:::0;77327:12;:30:::1;:::i;42307:155::-:0;42402:52;10756:10;42435:8;42445;42402:18;:52::i;72711:97::-;12011:13;:11;:13::i;:::-;72780:12:::1;:20:::0;72711:97::o;43426:322::-;43600:41;10756:10;43633:7;43600:18;:41::i;:::-;43592:99;;;;-1:-1:-1;;;43592:99:0;;;;;;;:::i;:::-;43702:38;43716:4;43722:2;43726:7;43735:4;43702:13;:38::i;:::-;43426:322;;;;:::o;73338:173::-;73426:4;73450:53;73469:6;73477:14;;73493:9;73450:18;:53::i;76651:363::-;45551:4;45149:16;;;:7;:16;;;;;;76724:13;;-1:-1:-1;;;;;45149:16:0;76750:76;;;;-1:-1:-1;;;76750:76:0;;15775:2:1;76750:76:0;;;15757:21:1;15814:2;15794:18;;;15787:30;15853:34;15833:18;;;15826:62;-1:-1:-1;;;15904:18:1;;;15897:45;15959:19;;76750:76:0;15573:411:1;76750:76:0;76837:28;76868:10;:8;:10::i;:::-;76837:41;;76927:1;76902:14;76896:28;:32;:110;;76994:12;76896:110;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76955:14;76971:18;:7;:16;:18::i;:::-;76938:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;76889:117;76651:363;-1:-1:-1;;;76651:363:0:o;73820:822::-;73992:10;;:14;;74005:1;73992:14;:::i;:::-;73977:11;73962:12;;:26;;;;:::i;:::-;:44;;73954:75;;;;-1:-1:-1;;;73954:75:0;;;;;;;:::i;:::-;74063:1;74050:9;;:14;;74042:53;;;;-1:-1:-1;;;74042:53:0;;16692:2:1;74042:53:0;;;16674:21:1;16731:2;16711:18;;;16704:30;16770:28;16750:18;;;16743:56;16816:18;;74042:53:0;16490:350:1;74042:53:0;74139:9;74124:11;74116:5;;:19;;;;:::i;:::-;:32;;74108:59;;;;-1:-1:-1;;;74108:59:0;;;;;;;:::i;:::-;74188:60;74204:35;74211:10;74223:6;74231:7;74204:6;:35::i;:::-;74241:6;;74188:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74188:15:0;;-1:-1:-1;;;74188:60:0:i;:::-;74180:86;;;;-1:-1:-1;;;74180:86:0;;17390:2:1;74180:86:0;;;17372:21:1;17429:2;17409:18;;;17402:30;-1:-1:-1;;;17448:18:1;;;17441:43;17501:18;;74180:86:0;17188:337:1;74180:86:0;74309:10;73759:7;73786:18;;;:10;:18;;;;;;74339:7;;74296:38;;74323:11;;74296:38;:::i;:::-;74295:51;;74287:87;;;;-1:-1:-1;;;74287:87:0;;;;;;;:::i;:::-;74404:10;73759:7;73786:18;;;:10;:18;;;;;;74391:29;:52;;;;;74441:2;74424:13;;:19;;74391:52;74387:248;;;74460:31;74477:10;74489:1;74460:16;:31::i;:::-;74506:44;74522:10;74534:15;74548:1;74534:11;:15;:::i;:::-;74506;:44::i;:::-;74387:248;;;74583:40;74599:10;74611:11;74583:15;:40::i;:::-;73820:822;;;;;:::o;73017:128::-;12011:13;:11;:13::i;:::-;73101:17:::1;:36:::0;73017:128::o;75271:460::-;75378:10;;:14;;75391:1;75378:14;:::i;:::-;75363:11;75348:12;;:26;;;;:::i;:::-;:44;;75340:75;;;;-1:-1:-1;;;75340:75:0;;;;;;;:::i;:::-;75436:9;;75449:1;75436:14;75428:52;;;;-1:-1:-1;;;75428:52:0;;18217:2:1;75428:52:0;;;18199:21:1;18256:2;18236:18;;;18229:30;18295:27;18275:18;;;18268:55;18340:18;;75428:52:0;18015:349:1;75428:52:0;75524:9;75509:11;75501:5;;:19;;;;:::i;:::-;:32;;75493:59;;;;-1:-1:-1;;;75493:59:0;;;;;;;:::i;:::-;75625:17;;75595:10;73759:7;73786:18;;;:10;:18;;;;;;75582:38;;75609:11;;75582:38;:::i;:::-;75581:61;;75573:97;;;;-1:-1:-1;;;75573:97:0;;;;;;;:::i;:::-;75683:40;75699:10;75711:11;75683:15;:40::i;:::-;75271:460;:::o;13031:201::-;12011:13;:11;:13::i;:::-;-1:-1:-1;;;;;13120:22:0;::::1;13112:73;;;::::0;-1:-1:-1;;;13112:73:0;;18571:2:1;13112:73:0::1;::::0;::::1;18553:21:1::0;18610:2;18590:18;;;18583:30;18649:34;18629:18;;;18622:62;-1:-1:-1;;;18700:18:1;;;18693:36;18746:19;;13112:73:0::1;18369:402:1::0;13112:73:0::1;13196:28;13215:8;13196:18;:28::i;72921:90::-:0;12011:13;:11;:13::i;:::-;72989:5:::1;:14:::0;72921:90::o;72814:101::-;12011:13;:11;:13::i;:::-;72885:14:::1;:22:::0;72814:101::o;73517:171::-;73639:40;;;;;;;18961:19:1;;;;19018:2;19014:15;;;;-1:-1:-1;;19010:53:1;18996:12;;;18989:75;19080:12;;;;19073:28;;;;73639:40:0;;;;;;;;;;19117:12:1;;;;73639:40:0;;;73629:51;;;;;;73517:171::o;74650:613::-;74820:10;;:14;;74833:1;74820:14;:::i;:::-;74805:11;74790:12;;:26;;;;:::i;:::-;:44;;74782:75;;;;-1:-1:-1;;;74782:75:0;;;;;;;:::i;:::-;74891:1;74878:9;;:14;;74870:55;;;;-1:-1:-1;;;74870:55:0;;19342:2:1;74870:55:0;;;19324:21:1;19381:2;19361:18;;;19354:30;19420;19400:18;;;19393:58;19468:18;;74870:55:0;19140:352:1;74870:55:0;74969:9;74954:11;74946:5;;:19;;;;:::i;:::-;:32;;74938:59;;;;-1:-1:-1;;;74938:59:0;;;;;;;:::i;:::-;75018:58;75032:35;75039:10;75051:6;75059:7;75032:6;:35::i;:::-;75069:6;;75018:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75018:13:0;;-1:-1:-1;;;75018:58:0:i;:::-;75010:84;;;;-1:-1:-1;;;75010:84:0;;17390:2:1;75010:84:0;;;17372:21:1;17429:2;17409:18;;;17402:30;-1:-1:-1;;;17448:18:1;;;17441:43;17501:18;;75010:84:0;17188:337:1;75010:84:0;75137:10;73759:7;73786:18;;;:10;:18;;;;;;75167:7;;75124:38;;75151:11;;75124:38;:::i;:::-;75123:51;;75115:87;;;;-1:-1:-1;;;75115:87:0;;;;;;;:::i;39624:305::-;39726:4;-1:-1:-1;;;;;;39763:40:0;;-1:-1:-1;;;39763:40:0;;:105;;-1:-1:-1;;;;;;;39820:48:0;;-1:-1:-1;;;39820:48:0;39763:105;:158;;;-1:-1:-1;;;;;;;;;;2945:40:0;;;39885:36;2836:157;12290:132;12198:6;;-1:-1:-1;;;;;12198:6:0;10756:10;12354:23;12346:68;;;;-1:-1:-1;;;12346:68:0;;19699:2:1;12346:68:0;;;19681:21:1;;;19718:18;;;19711:30;19777:34;19757:18;;;19750:62;19829:18;;12346:68:0;19497:356:1;77480:287:0;77571:9;77566:108;77590:11;77586:1;:15;77566:108;;;77623:39;77633:9;77660:1;77644:13;;:17;;;;:::i;:::-;77623:9;:39::i;:::-;77603:3;;;;:::i;:::-;;;;77566:108;;;;77701:11;77684:13;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;77723:21:0;;;;;;:10;:21;;;;;:36;;77748:11;;77723:21;:36;;77748:11;;77723:36;:::i;:::-;;;;-1:-1:-1;;;;77480:287:0:o;51883:135::-;45551:4;45149:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45149:16:0;51957:53;;;;-1:-1:-1;;;51957:53:0;;15012:2:1;51957:53:0;;;14994:21:1;15051:2;15031:18;;;15024:30;-1:-1:-1;;;15070:18:1;;;15063:54;15134:18;;51957:53:0;14810:348:1;51162:174:0;51237:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;51237:29:0;-1:-1:-1;;;;;51237:29:0;;;;;;;;:24;;51291:23;51237:24;51291:14;:23::i;:::-;-1:-1:-1;;;;;51282:46:0;;;;;;;;;;;51162:174;;:::o;63647:190::-;63772:4;63825;63796:25;63809:5;63816:4;63796:12;:25::i;:::-;:33;;63647:190;-1:-1:-1;;;;63647:190:0:o;45781:264::-;45874:4;45891:13;45907:23;45922:7;45907:14;:23::i;:::-;45891:39;;45960:5;-1:-1:-1;;;;;45949:16:0;:7;-1:-1:-1;;;;;45949:16:0;;:52;;;-1:-1:-1;;;;;;42654:25:0;;;42630:4;42654:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;45969:32;45949:87;;;;46029:7;-1:-1:-1;;;;;46005:31:0;:20;46017:7;46005:11;:20::i;:::-;-1:-1:-1;;;;;46005:31:0;;45949:87;45941:96;45781:264;-1:-1:-1;;;;45781:264:0:o;49780:1263::-;49939:4;-1:-1:-1;;;;;49912:31:0;:23;49927:7;49912:14;:23::i;:::-;-1:-1:-1;;;;;49912:31:0;;49904:81;;;;-1:-1:-1;;;49904:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;50004:16:0;;49996:65;;;;-1:-1:-1;;;49996:65:0;;20466:2:1;49996:65:0;;;20448:21:1;20505:2;20485:18;;;20478:30;20544:34;20524:18;;;20517:62;-1:-1:-1;;;20595:18:1;;;20588:34;20639:19;;49996:65:0;20264:400:1;49996:65:0;50074:42;50095:4;50101:2;50105:7;50114:1;50074:20;:42::i;:::-;50246:4;-1:-1:-1;;;;;50219:31:0;:23;50234:7;50219:14;:23::i;:::-;-1:-1:-1;;;;;50219:31:0;;50211:81;;;;-1:-1:-1;;;50211:81:0;;;;;;;:::i;:::-;50364:24;;;;:15;:24;;;;;;;;50357:31;;-1:-1:-1;;;;;;50357:31:0;;;;;;-1:-1:-1;;;;;50840:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;50840:20:0;;;50875:13;;;;;;;;;:18;;50357:31;50875:18;;;50915:16;;;:7;:16;;;;;;:21;;;;;;;;;;50954:27;;50380:7;;50954:27;;;75954:163:::1;75739:385:::0;;:::o;13392:191::-;13485:6;;;-1:-1:-1;;;;;13502:17:0;;;-1:-1:-1;;;;;;13502:17:0;;;;;;;13535:40;;13485:6;;;13502:17;13485:6;;13535:40;;13466:16;;13535:40;13455:128;13392:191;:::o;77773:284::-;77863:9;77858:107;77882:11;77878:1;:15;77858:107;;;77915:38;77925:9;77951:1;77936:12;;:16;;;;:::i;77915:38::-;77895:3;;;;:::i;:::-;;;;77858:107;;;;77991:11;77975:12;;:27;;;;;;;:::i;51479:315::-;51634:8;-1:-1:-1;;;;;51625:17:0;:5;-1:-1:-1;;;;;51625:17:0;;51617:55;;;;-1:-1:-1;;;51617:55:0;;20871:2:1;51617:55:0;;;20853:21:1;20910:2;20890:18;;;20883:30;20949:27;20929:18;;;20922:55;20994:18;;51617:55:0;20669:349:1;51617:55:0;-1:-1:-1;;;;;51683:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;51683:46:0;;;;;;;;;;51745:41;;540::1;;;51745::0;;513:18:1;51745:41:0;;;;;;;51479:315;;;:::o;44629:313::-;44785:28;44795:4;44801:2;44805:7;44785:9;:28::i;:::-;44832:47;44855:4;44861:2;44865:7;44874:4;44832:22;:47::i;:::-;44824:110;;;;-1:-1:-1;;;44824:110:0;;;;;;;:::i;76534:109::-;76594:13;76627:8;76620:15;;;;;:::i;36323:716::-;36379:13;36430:14;36447:17;36458:5;36447:10;:17::i;:::-;36467:1;36447:21;36430:38;;36483:20;36517:6;36506:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36506:18:0;-1:-1:-1;36483:41:0;-1:-1:-1;36648:28:0;;;36664:2;36648:28;36705:288;-1:-1:-1;;36737:5:0;-1:-1:-1;;;36874:2:0;36863:14;;36858:30;36737:5;36845:44;36935:2;36926:11;;;-1:-1:-1;36956:21:0;36705:288;36956:21;-1:-1:-1;37014:6:0;36323:716;-1:-1:-1;;;36323:716:0:o;46387:110::-;46463:26;46473:2;46477:7;46463:26;;;;;;;;;;;;:9;:26::i;64514:296::-;64597:7;64640:4;64597:7;64655:118;64679:5;:12;64675:1;:16;64655:118;;;64728:33;64738:12;64752:5;64758:1;64752:8;;;;;;;;:::i;:::-;;;;;;;64728:9;:33::i;:::-;64713:48;-1:-1:-1;64693:3:0;;;;:::i;:::-;;;;64655:118;;;-1:-1:-1;64790:12:0;64514:296;-1:-1:-1;;;64514:296:0:o;57627:915::-;57804:61;57831:4;57837:2;57841:12;57855:9;57804:26;:61::i;:::-;57894:1;57882:9;:13;57878:222;;;58025:63;;-1:-1:-1;;;58025:63:0;;21776:2:1;58025:63:0;;;21758:21:1;21815:2;21795:18;;;21788:30;21854:34;21834:18;;;21827:62;-1:-1:-1;;;21905:18:1;;;21898:51;21966:19;;58025:63:0;21574:417:1;57878:222:0;58130:12;-1:-1:-1;;;;;58159:18:0;;58155:187;;58194:40;58226:7;59369:10;:17;;59342:24;;;;:15;:24;;;;;:44;;;59397:24;;;;;;;;;;;;59265:164;58194:40;58155:187;;;58264:2;-1:-1:-1;;;;;58256:10:0;:4;-1:-1:-1;;;;;58256:10:0;;58252:90;;58283:47;58316:4;58322:7;58283:32;:47::i;:::-;-1:-1:-1;;;;;58356:16:0;;58352:183;;58389:45;58426:7;58389:36;:45::i;58352:183::-;58462:4;-1:-1:-1;;;;;58456:10:0;:2;-1:-1:-1;;;;;58456:10:0;;58452:83;;58483:40;58511:2;58515:7;58483:27;:40::i;52582:853::-;52736:4;-1:-1:-1;;;;;52757:13:0;;15118:19;:23;52753:675;;52793:71;;-1:-1:-1;;;52793:71:0;;-1:-1:-1;;;;;52793:36:0;;;;;:71;;10756:10;;52844:4;;52850:7;;52859:4;;52793:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52793:71:0;;;;;;;;-1:-1:-1;;52793:71:0;;;;;;;;;;;;:::i;:::-;;;52789:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53034:6;:13;53051:1;53034:18;53030:328;;53077:60;;-1:-1:-1;;;53077:60:0;;;;;;;:::i;53030:328::-;53308:6;53302:13;53293:6;53289:2;53285:15;53278:38;52789:584;-1:-1:-1;;;;;;52915:51:0;-1:-1:-1;;;52915:51:0;;-1:-1:-1;52908:58:0;;52753:675;-1:-1:-1;53412:4:0;52582:853;;;;;;:::o;33189:922::-;33242:7;;-1:-1:-1;;;33320:15:0;;33316:102;;-1:-1:-1;;;33356:15:0;;;-1:-1:-1;33400:2:0;33390:12;33316:102;33445:6;33436:5;:15;33432:102;;33481:6;33472:15;;;-1:-1:-1;33516:2:0;33506:12;33432:102;33561:6;33552:5;:15;33548:102;;33597:6;33588:15;;;-1:-1:-1;33632:2:0;33622:12;33548:102;33677:5;33668;:14;33664:99;;33712:5;33703:14;;;-1:-1:-1;33746:1:0;33736:11;33664:99;33790:5;33781;:14;33777:99;;33825:5;33816:14;;;-1:-1:-1;33859:1:0;33849:11;33777:99;33903:5;33894;:14;33890:99;;33938:5;33929:14;;;-1:-1:-1;33972:1:0;33962:11;33890:99;34016:5;34007;:14;34003:66;;34052:1;34042:11;34097:6;33189:922;-1:-1:-1;;33189:922:0:o;46724:319::-;46853:18;46859:2;46863:7;46853:5;:18::i;:::-;46904:53;46935:1;46939:2;46943:7;46952:4;46904:22;:53::i;:::-;46882:153;;;;-1:-1:-1;;;46882:153:0;;;;;;;:::i;71554:149::-;71617:7;71648:1;71644;:5;:51;;71779:13;71873:15;;;71909:4;71902:15;;;71956:4;71940:21;;71644:51;;;71779:13;71873:15;;;71909:4;71902:15;;;71956:4;71940:21;;71652:20;71711:268;54167:410;54357:1;54345:9;:13;54341:229;;;-1:-1:-1;;;;;54379:18:0;;;54375:87;;-1:-1:-1;;;;;54418:15:0;;;;;;:9;:15;;;;;:28;;54437:9;;54418:15;:28;;54437:9;;54418:28;:::i;:::-;;;;-1:-1:-1;;54375:87:0;-1:-1:-1;;;;;54480:16:0;;;54476:83;;-1:-1:-1;;;;;54517:13:0;;;;;;:9;:13;;;;;:26;;54534:9;;54517:13;:26;;54534:9;;54517:26;:::i;:::-;;;;-1:-1:-1;;54167:410:0;;;;:::o;60056:988::-;60322:22;60372:1;60347:22;60364:4;60347:16;:22::i;:::-;:26;;;;:::i;:::-;60384:18;60405:26;;;:17;:26;;;;;;60322:51;;-1:-1:-1;60538:28:0;;;60534:328;;-1:-1:-1;;;;;60605:18:0;;60583:19;60605:18;;;:12;:18;;;;;;;;:34;;;;;;;;;60656:30;;;;;;:44;;;60773:30;;:17;:30;;;;;:43;;;60534:328;-1:-1:-1;60958:26:0;;;;:17;:26;;;;;;;;60951:33;;;-1:-1:-1;;;;;61002:18:0;;;;;:12;:18;;;;;:34;;;;;;;60995:41;60056:988::o;61339:1079::-;61617:10;:17;61592:22;;61617:21;;61637:1;;61617:21;:::i;:::-;61649:18;61670:24;;;:15;:24;;;;;;62043:10;:26;;61592:46;;-1:-1:-1;61670:24:0;;61592:46;;62043:26;;;;;;:::i;:::-;;;;;;;;;62021:48;;62107:11;62082:10;62093;62082:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;62187:28;;;:15;:28;;;;;;;:41;;;62359:24;;;;;62352:31;62394:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;61410:1008;;;61339:1079;:::o;58843:221::-;58928:14;58945:20;58962:2;58945:16;:20::i;:::-;-1:-1:-1;;;;;58976:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;59021:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;58843:221:0:o;47379:942::-;-1:-1:-1;;;;;47459:16:0;;47451:61;;;;-1:-1:-1;;;47451:61:0;;23078:2:1;47451:61:0;;;23060:21:1;;;23097:18;;;23090:30;23156:34;23136:18;;;23129:62;23208:18;;47451:61:0;22876:356:1;47451:61:0;45551:4;45149:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45149:16:0;45575:31;47523:58;;;;-1:-1:-1;;;47523:58:0;;23439:2:1;47523:58:0;;;23421:21:1;23478:2;23458:18;;;23451:30;23517;23497:18;;;23490:58;23565:18;;47523:58:0;23237:352:1;47523:58:0;47594:48;47623:1;47627:2;47631:7;47640:1;47594:20;:48::i;:::-;45551:4;45149:16;;;:7;:16;;;;;;-1:-1:-1;;;;;45149:16:0;45575:31;47732:58;;;;-1:-1:-1;;;47732:58:0;;23439:2:1;47732:58:0;;;23421:21:1;23478:2;23458:18;;;23451:30;23517;23497:18;;;23490:58;23565:18;;47732:58:0;23237:352:1;47732:58:0;-1:-1:-1;;;;;48139:13:0;;;;;;:9;:13;;;;;;;;:18;;48156:1;48139:18;;;48181:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;48181:21:0;;;;;48220:33;48189:7;;48139:13;;48220:33;;48139:13;;48220:33;78168:40:::1;78104:112;78065:151::o:0;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:127::-;653:10;648:3;644:20;641:1;634:31;684:4;681:1;674:15;708:4;705:1;698:15;724:275;795:2;789:9;860:2;841:13;;-1:-1:-1;;837:27:1;825:40;;895:18;880:34;;916:22;;;877:62;874:88;;;942:18;;:::i;:::-;978:2;971:22;724:275;;-1:-1:-1;724:275:1:o;1004:183::-;1064:4;1097:18;1089:6;1086:30;1083:56;;;1119:18;;:::i;:::-;-1:-1:-1;1164:1:1;1160:14;1176:4;1156:25;;1004:183::o;1192:173::-;1260:20;;-1:-1:-1;;;;;1309:31:1;;1299:42;;1289:70;;1355:1;1352;1345:12;1289:70;1192:173;;;:::o;1370:967::-;1463:6;1471;1524:2;1512:9;1503:7;1499:23;1495:32;1492:52;;;1540:1;1537;1530:12;1492:52;1580:9;1567:23;1613:18;1605:6;1602:30;1599:50;;;1645:1;1642;1635:12;1599:50;1668:22;;1721:4;1713:13;;1709:27;-1:-1:-1;1699:55:1;;1750:1;1747;1740:12;1699:55;1786:2;1773:16;1808:4;1832:60;1848:43;1888:2;1848:43;:::i;:::-;1832:60;:::i;:::-;1926:15;;;2008:1;2004:10;;;;1996:19;;1992:28;;;1957:12;;;;2032:19;;;2029:39;;;2064:1;2061;2054:12;2029:39;2088:11;;;;2108:148;2124:6;2119:3;2116:15;2108:148;;;2190:23;2209:3;2190:23;:::i;:::-;2178:36;;2141:12;;;;2234;;;;2108:148;;;2275:5;2312:18;;;;2299:32;;-1:-1:-1;;;;;;1370:967:1:o;2342:250::-;2427:1;2437:113;2451:6;2448:1;2445:13;2437:113;;;2527:11;;;2521:18;2508:11;;;2501:39;2473:2;2466:10;2437:113;;;-1:-1:-1;;2584:1:1;2566:16;;2559:27;2342:250::o;2597:271::-;2639:3;2677:5;2671:12;2704:6;2699:3;2692:19;2720:76;2789:6;2782:4;2777:3;2773:14;2766:4;2759:5;2755:16;2720:76;:::i;:::-;2850:2;2829:15;-1:-1:-1;;2825:29:1;2816:39;;;;2857:4;2812:50;;2597:271;-1:-1:-1;;2597:271:1:o;2873:220::-;3022:2;3011:9;3004:21;2985:4;3042:45;3083:2;3072:9;3068:18;3060:6;3042:45;:::i;3098:180::-;3157:6;3210:2;3198:9;3189:7;3185:23;3181:32;3178:52;;;3226:1;3223;3216:12;3178:52;-1:-1:-1;3249:23:1;;3098:180;-1:-1:-1;3098:180:1:o;3491:254::-;3559:6;3567;3620:2;3608:9;3599:7;3595:23;3591:32;3588:52;;;3636:1;3633;3626:12;3588:52;3659:29;3678:9;3659:29;:::i;:::-;3649:39;3735:2;3720:18;;;;3707:32;;-1:-1:-1;;;3491:254:1:o;3750:959::-;3843:6;3851;3904:2;3892:9;3883:7;3879:23;3875:32;3872:52;;;3920:1;3917;3910:12;3872:52;3956:9;3943:23;3933:33;;3985:2;4038;4027:9;4023:18;4010:32;4065:18;4057:6;4054:30;4051:50;;;4097:1;4094;4087:12;4051:50;4120:22;;4173:4;4165:13;;4161:27;-1:-1:-1;4151:55:1;;4202:1;4199;4192:12;4151:55;4238:2;4225:16;4261:60;4277:43;4317:2;4277:43;:::i;4261:60::-;4355:15;;;4437:1;4433:10;;;;4425:19;;4421:28;;;4386:12;;;;4461:19;;;4458:39;;;4493:1;4490;4483:12;4458:39;4517:11;;;;4537:142;4553:6;4548:3;4545:15;4537:142;;;4619:17;;4607:30;;4570:12;;;;4657;;;;4537:142;;;4698:5;4688:15;;;;;;;3750:959;;;;;:::o;4896:328::-;4973:6;4981;4989;5042:2;5030:9;5021:7;5017:23;5013:32;5010:52;;;5058:1;5055;5048:12;5010:52;5081:29;5100:9;5081:29;:::i;:::-;5071:39;;5129:38;5163:2;5152:9;5148:18;5129:38;:::i;:::-;5119:48;;5214:2;5203:9;5199:18;5186:32;5176:42;;4896:328;;;;;:::o;5411:407::-;5476:5;5510:18;5502:6;5499:30;5496:56;;;5532:18;;:::i;:::-;5570:57;5615:2;5594:15;;-1:-1:-1;;5590:29:1;5621:4;5586:40;5570:57;:::i;:::-;5561:66;;5650:6;5643:5;5636:21;5690:3;5681:6;5676:3;5672:16;5669:25;5666:45;;;5707:1;5704;5697:12;5666:45;5756:6;5751:3;5744:4;5737:5;5733:16;5720:43;5810:1;5803:4;5794:6;5787:5;5783:18;5779:29;5772:40;5411:407;;;;;:::o;5823:451::-;5892:6;5945:2;5933:9;5924:7;5920:23;5916:32;5913:52;;;5961:1;5958;5951:12;5913:52;6001:9;5988:23;6034:18;6026:6;6023:30;6020:50;;;6066:1;6063;6056:12;6020:50;6089:22;;6142:4;6134:13;;6130:27;-1:-1:-1;6120:55:1;;6171:1;6168;6161:12;6120:55;6194:74;6260:7;6255:2;6242:16;6237:2;6233;6229:11;6194:74;:::i;6279:186::-;6338:6;6391:2;6379:9;6370:7;6366:23;6362:32;6359:52;;;6407:1;6404;6397:12;6359:52;6430:29;6449:9;6430:29;:::i;6470:347::-;6535:6;6543;6596:2;6584:9;6575:7;6571:23;6567:32;6564:52;;;6612:1;6609;6602:12;6564:52;6635:29;6654:9;6635:29;:::i;:::-;6625:39;;6714:2;6703:9;6699:18;6686:32;6761:5;6754:13;6747:21;6740:5;6737:32;6727:60;;6783:1;6780;6773:12;6727:60;6806:5;6796:15;;;6470:347;;;;;:::o;7007:667::-;7102:6;7110;7118;7126;7179:3;7167:9;7158:7;7154:23;7150:33;7147:53;;;7196:1;7193;7186:12;7147:53;7219:29;7238:9;7219:29;:::i;:::-;7209:39;;7267:38;7301:2;7290:9;7286:18;7267:38;:::i;:::-;7257:48;;7352:2;7341:9;7337:18;7324:32;7314:42;;7407:2;7396:9;7392:18;7379:32;7434:18;7426:6;7423:30;7420:50;;;7466:1;7463;7456:12;7420:50;7489:22;;7542:4;7534:13;;7530:27;-1:-1:-1;7520:55:1;;7571:1;7568;7561:12;7520:55;7594:74;7660:7;7655:2;7642:16;7637:2;7633;7629:11;7594:74;:::i;:::-;7584:84;;;7007:667;;;;;;;:::o;7679:820::-;7792:6;7800;7808;7816;7824;7877:3;7865:9;7856:7;7852:23;7848:33;7845:53;;;7894:1;7891;7884:12;7845:53;7930:9;7917:23;7907:33;;7987:2;7976:9;7972:18;7959:32;7949:42;;8038:2;8027:9;8023:18;8010:32;8000:42;;8093:2;8082:9;8078:18;8065:32;8116:18;8157:2;8149:6;8146:14;8143:34;;;8173:1;8170;8163:12;8143:34;8211:6;8200:9;8196:22;8186:32;;8256:7;8249:4;8245:2;8241:13;8237:27;8227:55;;8278:1;8275;8268:12;8227:55;8318:2;8305:16;8344:2;8336:6;8333:14;8330:34;;;8360:1;8357;8350:12;8330:34;8413:7;8408:2;8398:6;8395:1;8391:14;8387:2;8383:23;8379:32;8376:45;8373:65;;;8434:1;8431;8424:12;8373:65;7679:820;;;;-1:-1:-1;7679:820:1;;-1:-1:-1;8465:2:1;8457:11;;8487:6;7679:820;-1:-1:-1;;;7679:820:1:o;8504:260::-;8572:6;8580;8633:2;8621:9;8612:7;8608:23;8604:32;8601:52;;;8649:1;8646;8639:12;8601:52;8672:29;8691:9;8672:29;:::i;:::-;8662:39;;8720:38;8754:2;8743:9;8739:18;8720:38;:::i;:::-;8710:48;;8504:260;;;;;:::o;8769:322::-;8846:6;8854;8862;8915:2;8903:9;8894:7;8890:23;8886:32;8883:52;;;8931:1;8928;8921:12;8883:52;8954:29;8973:9;8954:29;:::i;:::-;8944:39;9030:2;9015:18;;9002:32;;-1:-1:-1;9081:2:1;9066:18;;;9053:32;;8769:322;-1:-1:-1;;;8769:322:1:o;9096:127::-;9157:10;9152:3;9148:20;9145:1;9138:31;9188:4;9185:1;9178:15;9212:4;9209:1;9202:15;9228:168;9301:9;;;9332;;9349:15;;;9343:22;;9329:37;9319:71;;9370:18;;:::i;9401:125::-;9466:9;;;9487:10;;;9484:36;;;9500:18;;:::i;9531:342::-;9733:2;9715:21;;;9772:2;9752:18;;;9745:30;-1:-1:-1;;;9806:2:1;9791:18;;9784:48;9864:2;9849:18;;9531:342::o;9878:127::-;9939:10;9934:3;9930:20;9927:1;9920:31;9970:4;9967:1;9960:15;9994:4;9991:1;9984:15;10010:135;10049:3;10070:17;;;10067:43;;10090:18;;:::i;:::-;-1:-1:-1;10137:1:1;10126:13;;10010:135::o;10150:380::-;10229:1;10225:12;;;;10272;;;10293:61;;10347:4;10339:6;10335:17;10325:27;;10293:61;10400:2;10392:6;10389:14;10369:18;10366:38;10363:161;;10446:10;10441:3;10437:20;10434:1;10427:31;10481:4;10478:1;10471:15;10509:4;10506:1;10499:15;10363:161;;10150:380;;;:::o;11367:409::-;11569:2;11551:21;;;11608:2;11588:18;;;11581:30;11647:34;11642:2;11627:18;;11620:62;-1:-1:-1;;;11713:2:1;11698:18;;11691:43;11766:3;11751:19;;11367:409::o;12732:545::-;12834:2;12829:3;12826:11;12823:448;;;12870:1;12895:5;12891:2;12884:17;12940:4;12936:2;12926:19;13010:2;12998:10;12994:19;12991:1;12987:27;12981:4;12977:38;13046:4;13034:10;13031:20;13028:47;;;-1:-1:-1;13069:4:1;13028:47;13124:2;13119:3;13115:12;13112:1;13108:20;13102:4;13098:31;13088:41;;13179:82;13197:2;13190:5;13187:13;13179:82;;;13242:17;;;13223:1;13212:13;13179:82;;;13183:3;;;12732:545;;;:::o;13453:1352::-;13579:3;13573:10;13606:18;13598:6;13595:30;13592:56;;;13628:18;;:::i;:::-;13657:97;13747:6;13707:38;13739:4;13733:11;13707:38;:::i;:::-;13701:4;13657:97;:::i;:::-;13809:4;;13873:2;13862:14;;13890:1;13885:663;;;;14592:1;14609:6;14606:89;;;-1:-1:-1;14661:19:1;;;14655:26;14606:89;-1:-1:-1;;13410:1:1;13406:11;;;13402:24;13398:29;13388:40;13434:1;13430:11;;;13385:57;14708:81;;13855:944;;13885:663;12679:1;12672:14;;;12716:4;12703:18;;-1:-1:-1;;13921:20:1;;;14039:236;14053:7;14050:1;14047:14;14039:236;;;14142:19;;;14136:26;14121:42;;14234:27;;;;14202:1;14190:14;;;;14069:19;;14039:236;;;14043:3;14303:6;14294:7;14291:19;14288:201;;;14364:19;;;14358:26;-1:-1:-1;;14447:1:1;14443:14;;;14459:3;14439:24;14435:37;14431:42;14416:58;14401:74;;14288:201;-1:-1:-1;;;;;14535:1:1;14519:14;;;14515:22;14502:36;;-1:-1:-1;13453:1352:1:o;15989:496::-;16168:3;16206:6;16200:13;16222:66;16281:6;16276:3;16269:4;16261:6;16257:17;16222:66;:::i;:::-;16351:13;;16310:16;;;;16373:70;16351:13;16310:16;16420:4;16408:17;;16373:70;:::i;:::-;16459:20;;15989:496;-1:-1:-1;;;;15989:496:1:o;16845:338::-;17047:2;17029:21;;;17086:2;17066:18;;;17059:30;-1:-1:-1;;;17120:2:1;17105:18;;17098:44;17174:2;17159:18;;16845:338::o;17530:347::-;17732:2;17714:21;;;17771:2;17751:18;;;17744:30;17810:25;17805:2;17790:18;;17783:53;17868:2;17853:18;;17530:347::o;17882:128::-;17949:9;;;17970:11;;;17967:37;;;17984:18;;:::i;19858:401::-;20060:2;20042:21;;;20099:2;20079:18;;;20072:30;20138:34;20133:2;20118:18;;20111:62;-1:-1:-1;;;20204:2:1;20189:18;;20182:35;20249:3;20234:19;;19858:401::o;21023:414::-;21225:2;21207:21;;;21264:2;21244:18;;;21237:30;21303:34;21298:2;21283:18;;21276:62;-1:-1:-1;;;21369:2:1;21354:18;;21347:48;21427:3;21412:19;;21023:414::o;21996:489::-;-1:-1:-1;;;;;22265:15:1;;;22247:34;;22317:15;;22312:2;22297:18;;22290:43;22364:2;22349:18;;22342:34;;;22412:3;22407:2;22392:18;;22385:31;;;22190:4;;22433:46;;22459:19;;22451:6;22433:46;:::i;:::-;22425:54;21996:489;-1:-1:-1;;;;;;21996:489:1:o;22490:249::-;22559:6;22612:2;22600:9;22591:7;22587:23;22583:32;22580:52;;;22628:1;22625;22618:12;22580:52;22660:9;22654:16;22679:30;22703:5;22679:30;:::i;22744:127::-;22805:10;22800:3;22796:20;22793:1;22786:31;22836:4;22833:1;22826:15;22860:4;22857:1;22850:15

Swarm Source

ipfs://274caea4e792d0837a4f4ced777b8d2413e77fbbfdf50b8b304d98e0d7131330
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.