ETH Price: $3,290.27 (-1.50%)

Token

Utopia NFT (UTOPIA)
 

Overview

Max Total Supply

4,457 UTOPIA

Holders

529

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
030725.eth
Balance
2 UTOPIA
0xda704b2e18d989003b139cbc5d4fc978a6d81064
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:
UtopiaNFT

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-10-01
*/

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


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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_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) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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

    /**
     * @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/utils/math/SafeMath.sol


// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

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

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

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

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

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


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

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * 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.
 */
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 proved to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * _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}
     *
     * _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 the sibling nodes in `proof`,
     * consuming from one or the other at each step according to the instructions given by
     * `proofFlags`.
     *
     * _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}
     *
     * _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: @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: erc721a/contracts/IERC721A.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721A.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

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

    // =============================================================
    //                            IERC721
    // =============================================================

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

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

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

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

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

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

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

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

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

// File: erc721a/contracts/extensions/IERC721AQueryable.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @dev Interface of ERC721AQueryable.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}

// File: erc721a/contracts/extensions/IERC721ABurnable.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @dev Interface of ERC721ABurnable.
 */
interface IERC721ABurnable is IERC721A {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) external;
}

// File: erc721a/contracts/ERC721A.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant _BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant _BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant _BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant _BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See {_packedOwnershipOf} implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

    /**
     * @dev Returns the token collection name.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

    /**
     * @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, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around over time.
     */
    function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal virtual {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @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) public payable virtual override {
        address owner = ownerOf(tokenId);

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId].value = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @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) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @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. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @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 memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token IDs
     * are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token IDs
     * have been transferred. This includes minting.
     * And also called after one token has been burned.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, '');
    }

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

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

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }
}

// File: erc721a/contracts/extensions/ERC721AQueryable.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;



/**
 * @title ERC721AQueryable.
 *
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *
     * - `addr = address(0)`
     * - `startTimestamp = 0`
     * - `burned = false`
     * - `extraData = 0`
     *
     * If the `tokenId` is burned:
     *
     * - `addr = <Address of owner before token was burned>`
     * - `startTimestamp = <Timestamp when token was burned>`
     * - `burned = true`
     * - `extraData = <Extra data when token was burned>`
     *
     * Otherwise:
     *
     * - `addr = <Address of owner>`
     * - `startTimestamp = <Timestamp of start of ownership>`
     * - `burned = false`
     * - `extraData = <Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) public view virtual override returns (TokenOwnership memory) {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
            return ownership;
        }
        ownership = _ownershipAt(tokenId);
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] calldata tokenIds)
        external
        view
        virtual
        override
        returns (TokenOwnership[] memory)
    {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view virtual override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _nextTokenId();
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, stopLimit)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}

// File: erc721a/contracts/extensions/ERC721ABurnable.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;



/**
 * @title ERC721ABurnable.
 *
 * @dev ERC721A token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual override {
        _burn(tokenId, true);
    }
}

// File: UtopiaNFT.sol


// creator : Jason Siauw / jason9071.eth
// contact : [email protected]

pragma solidity ^0.8.4;








contract UtopiaNFT is ERC721AQueryable, Ownable {
    using Strings for uint256;

    string public hashProof;
    string public baseURI;
    uint256 public maxSupply;
    uint256 public mintingHardCap;
    uint256 public whitelistHardCap;
    bytes32 public merkleRoot;
    bool public allowWhitelistMint;
    bool public allowPublicMint;
    uint256 public mintPrice;

    mapping( address => uint256 ) public totalBuy;

    event WhitelistMint( address to, uint256 quantity );
    event PublicMint( address to, uint256 quantity );
    event Airdrop( address to, uint256 quantity );

    constructor() ERC721A("Utopia NFT", "UTOPIA") {
        baseURI = "https://api.utopianft.io/hk/metadata/";
        maxSupply = 4570;
        mintingHardCap = 4370;
        whitelistHardCap = 2000;
        merkleRoot = 0x97aa756f15e1077c76b2af6aec065c2772f1295df0d4448bef0cd343bc617823;
        allowWhitelistMint = false;
        allowPublicMint = false;
        mintPrice = 0.022 ether;
        hashProof = "e324296e37b7a1c98eeb69ca118a41b1dd39da815c87342a5f7f711cadaf424d";
    }

    // modifier //

    modifier notContract() {
        require(!_isContract(msg.sender), "contract not allowed");
        require(msg.sender == tx.origin, "proxy contract not allowed");

        _;
    }

    // modifier //

    // main function //

    function whitelistMint(
        address to,
        uint256 quantity,
        bytes32[] calldata proof
    ) external payable notContract {
        require( to == msg.sender, "not the same caller" );
        require( quantity > 0, "quantity can not smaller than 1" );
        require( quantity < 6, "quantity can not bigger than 5" );
        require( totalSupply() + quantity <= whitelistHardCap, "out of whitelist hard cap" );
        require( totalSupply() + quantity <= mintingHardCap, "out of minting hard cap" );
        require( totalBuy[to] + quantity < 6, "out of max quantity for each address" );
        require( allowWhitelistMint, "not allow to whitelist mint now" );
        require( isWhitelist( to, proof, merkleRoot ), "not in whitelist" );

        if ( totalBuy[to] == 0 ) {
            require( msg.value >= ( quantity * mintPrice ) - mintPrice , "not enough ether(1)" );
        }
        else {
            require( msg.value >= quantity * mintPrice , "not enough ether(2)" );
        }

        totalBuy[to] = totalBuy[to] + quantity;
        _mint(to, quantity);

        emit WhitelistMint(to, quantity);
    }

    function publicMint(
        address to,
        uint256 quantity
    ) external payable notContract {
        require( to == msg.sender, "not the same caller" );
        require( quantity > 0, "quantity can not smaller than 1" );
        require( quantity < 6, "quantity can not bigger than 5" );
        require( totalSupply() + quantity <= mintingHardCap, "out of minting hard cap" );
        require( totalBuy[to] + quantity < 6, "out of max quantity for each address" );
        require( allowPublicMint, "not allow to public mint now" );
        require( msg.value >= quantity * mintPrice , "not enough ether" );

        totalBuy[to] = totalBuy[to] + quantity;
        _mint(to, quantity);

        emit PublicMint(to, quantity);
    }

    function airdrop( 
        address to,
        uint256 quantity
    ) external onlyOwner {
        require( totalSupply() + quantity <= maxSupply, "out of max supply" );
        require( quantity > 0, "quantity can not small than 1" );

        _mint(to, quantity);

        emit Airdrop(to, quantity);
    }

    function tokenURI(
        uint256 tokenId
    ) public view virtual override returns (string memory) {
        require(_exists(tokenId), "Token does not exist.");

        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
    }

    // main function //

    // admin function //

    function withdraw() external onlyOwner {
        require(address(this).balance > 0, "insufficient balance");
        payable(msg.sender).transfer(address(this).balance);
    }

    function setMaxSupply(uint256 newMaxSupply) external onlyOwner {
        maxSupply = newMaxSupply;
    }

    function setMerkleRoot(bytes32 newMerkleRoot) external onlyOwner {
        merkleRoot = newMerkleRoot;
    }

    function filpAllowWhitelistMint() external onlyOwner {
        allowWhitelistMint = !allowWhitelistMint;
    }

    function filpAllowPublicMint() external onlyOwner {
        allowPublicMint = !allowPublicMint;
    }

    // admin function //

    // prop function //

    function leaf(
        address _account
    ) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(_account));
    }

    function isWhitelist(
        address adr,
        bytes32[] calldata proof,
        bytes32 root
    ) internal pure returns (bool) {
        return MerkleProof.verify(proof, root, leaf(adr));
    }

    function _isContract(
        address _addr
    ) internal view returns (bool) {
        uint size;
        assembly { size := extcodesize(_addr) }
        return size > 0;
    }

    // prop function //
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"Airdrop","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"PublicMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"WhitelistMint","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allowPublicMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowWhitelistMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"filpAllowPublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"filpAllowWhitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hashProof","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingHardCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","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":"payable","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newMerkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalBuy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistHardCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040518060400160405280600a81526020017f55746f706961204e4654000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f55544f5049410000000000000000000000000000000000000000000000000000815250816002908051906020019062000096929190620002ae565b508060039080519060200190620000af929190620002ae565b50620000c0620001db60201b60201c565b6000819055505050620000e8620000dc620001e060201b60201c565b620001e860201b60201c565b60405180606001604052806025815260200162004cba60259139600a908051906020019062000119929190620002ae565b506111da600b81905550611112600c819055506107d0600d819055507f97aa756f15e1077c76b2af6aec065c2772f1295df0d4448bef0cd343bc61782360001b600e819055506000600f60006101000a81548160ff0219169083151502179055506000600f60016101000a81548160ff021916908315150217905550664e28e2290f000060108190555060405180606001604052806040815260200162004c7a6040913960099080519060200190620001d4929190620002ae565b50620003c3565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002bc906200035e565b90600052602060002090601f016020900481019282620002e057600085556200032c565b82601f10620002fb57805160ff19168380011785556200032c565b828001600101855582156200032c579182015b828111156200032b5782518255916020019190600101906200030e565b5b5090506200033b91906200033f565b5090565b5b808211156200035a57600081600090555060010162000340565b5090565b600060028204905060018216806200037757607f821691505b602082108114156200038e576200038d62000394565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6148a780620003d36000396000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063b88d4fde116100ab578063d3e6e3ef1161006f578063d3e6e3ef146107ed578063d5abeb0114610818578063e985e9c514610843578063f2fde38b14610880578063ff7aa51f146108a957610230565b8063b88d4fde14610724578063b8e1b0da14610740578063c23dc68f14610757578063c87b56dd14610794578063ce6df2b9146107d157610230565b80638da5cb5b116100f25780638da5cb5b1461063d57806395d89b411461066857806399a2557a146106935780639edcc310146106d0578063a22cb465146106fb57610230565b8063715018a6146105805780637c03bdf3146105975780637cb64759146105ae5780638462151c146105d75780638ba4cc3c1461061457610230565b806342842e0e116101bc5780636352211e116101805780636352211e146104875780636817c76c146104c45780636c0360eb146104ef5780636f8b44b01461051a57806370a082311461054357610230565b806342842e0e146103aa5780634b11faaf146103c65780635130d734146103e25780635298ed571461041f5780635bbb21771461044a57610230565b806318160ddd1161020357806318160ddd146102f657806323b872dd146103215780632eb4a7ab1461033d5780633ccfd60b14610368578063420ed6e31461037f57610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c60048036038101906102579190613484565b6108d4565b6040516102699190613c30565b60405180910390f35b34801561027e57600080fd5b50610287610966565b6040516102949190613c66565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf91906134de565b6109f8565b6040516102d19190613b5c565b60405180910390f35b6102f460048036038101906102ef9190613303565b610a77565b005b34801561030257600080fd5b5061030b610bbb565b6040516103189190613f23565b60405180910390f35b61033b600480360381019061033691906131ed565b610bd2565b005b34801561034957600080fd5b50610352610ef7565b60405161035f9190613c4b565b60405180910390f35b34801561037457600080fd5b5061037d610efd565b005b34801561038b57600080fd5b50610394610f91565b6040516103a19190613c66565b60405180910390f35b6103c460048036038101906103bf91906131ed565b61101f565b005b6103e060048036038101906103db9190613343565b61103f565b005b3480156103ee57600080fd5b5061040960048036038101906104049190613180565b611593565b6040516104169190613f23565b60405180910390f35b34801561042b57600080fd5b506104346115ab565b6040516104419190613f23565b60405180910390f35b34801561045657600080fd5b50610471600480360381019061046c919061340a565b6115b1565b60405161047e9190613bec565b60405180910390f35b34801561049357600080fd5b506104ae60048036038101906104a991906134de565b611674565b6040516104bb9190613b5c565b60405180910390f35b3480156104d057600080fd5b506104d9611686565b6040516104e69190613f23565b60405180910390f35b3480156104fb57600080fd5b5061050461168c565b6040516105119190613c66565b60405180910390f35b34801561052657600080fd5b50610541600480360381019061053c91906134de565b61171a565b005b34801561054f57600080fd5b5061056a60048036038101906105659190613180565b61172c565b6040516105779190613f23565b60405180910390f35b34801561058c57600080fd5b506105956117e5565b005b3480156105a357600080fd5b506105ac6117f9565b005b3480156105ba57600080fd5b506105d560048036038101906105d09190613457565b61182d565b005b3480156105e357600080fd5b506105fe60048036038101906105f99190613180565b61183f565b60405161060b9190613c0e565b60405180910390f35b34801561062057600080fd5b5061063b60048036038101906106369190613303565b611989565b005b34801561064957600080fd5b50610652611a72565b60405161065f9190613b5c565b60405180910390f35b34801561067457600080fd5b5061067d611a9c565b60405161068a9190613c66565b60405180910390f35b34801561069f57600080fd5b506106ba60048036038101906106b591906133b7565b611b2e565b6040516106c79190613c0e565b60405180910390f35b3480156106dc57600080fd5b506106e5611d42565b6040516106f29190613c30565b60405180910390f35b34801561070757600080fd5b50610722600480360381019061071d91906132c3565b611d55565b005b61073e60048036038101906107399190613240565b611e60565b005b34801561074c57600080fd5b50610755611ed3565b005b34801561076357600080fd5b5061077e600480360381019061077991906134de565b611f07565b60405161078b9190613f08565b60405180910390f35b3480156107a057600080fd5b506107bb60048036038101906107b691906134de565b611f71565b6040516107c89190613c66565b60405180910390f35b6107eb60048036038101906107e69190613303565b61201a565b005b3480156107f957600080fd5b5061080261241d565b60405161080f9190613f23565b60405180910390f35b34801561082457600080fd5b5061082d612423565b60405161083a9190613f23565b60405180910390f35b34801561084f57600080fd5b5061086a600480360381019061086591906131ad565b612429565b6040516108779190613c30565b60405180910390f35b34801561088c57600080fd5b506108a760048036038101906108a29190613180565b6124bd565b005b3480156108b557600080fd5b506108be612541565b6040516108cb9190613c30565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061092f57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061095f5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461097590614256565b80601f01602080910402602001604051908101604052809291908181526020018280546109a190614256565b80156109ee5780601f106109c3576101008083540402835291602001916109ee565b820191906000526020600020905b8154815290600101906020018083116109d157829003601f168201915b5050505050905090565b6000610a0382612554565b610a39576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a8282611674565b90508073ffffffffffffffffffffffffffffffffffffffff16610aa36125b3565b73ffffffffffffffffffffffffffffffffffffffff1614610b0657610acf81610aca6125b3565b612429565b610b05576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610bc56125bb565b6001546000540303905090565b6000610bdd826125c0565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c44576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c508461268e565b91509150610c668187610c616125b3565b6126b5565b610cb257610c7b86610c766125b3565b612429565b610cb1576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610d19576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2686868660016126f9565b8015610d3157600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610dff85610ddb8888876126ff565b7c020000000000000000000000000000000000000000000000000000000017612727565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e87576000600185019050600060046000838152602001908152602001600020541415610e85576000548114610e84578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610eef8686866001612752565b505050505050565b600e5481565b610f05612758565b60004711610f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3f90613e68565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610f8e573d6000803e3d6000fd5b50565b60098054610f9e90614256565b80601f0160208091040260200160405190810160405280929190818152602001828054610fca90614256565b80156110175780601f10610fec57610100808354040283529160200191611017565b820191906000526020600020905b815481529060010190602001808311610ffa57829003601f168201915b505050505081565b61103a83838360405180602001604052806000815250611e60565b505050565b611048336127d6565b15611088576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107f90613e08565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ed90613ca8565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115b90613e88565b60405180910390fd5b600083116111a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119e90613d28565b60405180910390fd5b600683106111ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e190613e28565b60405180910390fd5b600d54836111f6610bbb565b611200919061405e565b1115611241576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123890613d48565b60405180910390fd5b600c548361124d610bbb565b611257919061405e565b1115611298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128f90613e48565b60405180910390fd5b600683601160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546112e5919061405e565b10611325576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131c90613c88565b60405180910390fd5b600f60009054906101000a900460ff16611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136b90613d88565b60405180910390fd5b611382848383600e546127e9565b6113c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b890613ea8565b60405180910390fd5b6000601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561146b576010546010548461141a91906140e5565b611424919061413f565b341015611466576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145d90613ec8565b60405180910390fd5b6114bc565b6010548361147991906140e5565b3410156114bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b290613d68565b60405180910390fd5b5b82601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611507919061405e565b601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506115548484612849565b7f3175668c3bc41d83dd982a992932fc7512416b71850f41443845d2a4c2e3ec638484604051611585929190613bc3565b60405180910390a150505050565b60116020528060005260406000206000915090505481565b600c5481565b6060600083839050905060008167ffffffffffffffff8111156115d7576115d6614413565b5b60405190808252806020026020018201604052801561161057816020015b6115fd612f97565b8152602001906001900390816115f55790505b50905060005b8281146116685761163f868683818110611633576116326143e4565b5b90506020020135611f07565b828281518110611652576116516143e4565b5b6020026020010181905250806001019050611616565b50809250505092915050565b600061167f826125c0565b9050919050565b60105481565b600a805461169990614256565b80601f01602080910402602001604051908101604052809291908181526020018280546116c590614256565b80156117125780601f106116e757610100808354040283529160200191611712565b820191906000526020600020905b8154815290600101906020018083116116f557829003601f168201915b505050505081565b611722612758565b80600b8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611794576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6117ed612758565b6117f76000612a06565b565b611801612758565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b611835612758565b80600e8190555050565b6060600080600061184f8561172c565b905060008167ffffffffffffffff81111561186d5761186c614413565b5b60405190808252806020026020018201604052801561189b5781602001602082028036833780820191505090505b5090506118a6612f97565b60006118b06125bb565b90505b83861461197b576118c381612acc565b91508160400151156118d457611970565b600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461191457816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141561196f5780838780600101985081518110611962576119616143e4565b5b6020026020010181815250505b5b8060010190506118b3565b508195505050505050919050565b611991612758565b600b548161199d610bbb565b6119a7919061405e565b11156119e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119df90613de8565b60405180910390fd5b60008111611a2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2290613d08565b60405180910390fd5b611a358282612849565b7f8c32c568416fcf97be35ce5b27844cfddcd63a67a1a602c3595ba5dac38f303a8282604051611a66929190613bc3565b60405180910390a15050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611aab90614256565b80601f0160208091040260200160405190810160405280929190818152602001828054611ad790614256565b8015611b245780601f10611af957610100808354040283529160200191611b24565b820191906000526020600020905b815481529060010190602001808311611b0757829003601f168201915b5050505050905090565b6060818310611b69576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611b74612af7565b9050611b7e6125bb565b851015611b9057611b8d6125bb565b94505b80841115611b9c578093505b6000611ba78761172c565b905084861015611bca576000868603905081811015611bc4578091505b50611bcf565b600090505b60008167ffffffffffffffff811115611beb57611bea614413565b5b604051908082528060200260200182016040528015611c195781602001602082028036833780820191505090505b5090506000821415611c315780945050505050611d3b565b6000611c3c88611f07565b905060008160400151611c5157816000015190505b60008990505b888114158015611c675750848714155b15611d2d57611c7581612acc565b9250826040015115611c8657611d22565b600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611cc657826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d215780848880600101995081518110611d1457611d136143e4565b5b6020026020010181815250505b5b806001019050611c57565b508583528296505050505050505b9392505050565b600f60019054906101000a900460ff1681565b8060076000611d626125b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611e0f6125b3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611e549190613c30565b60405180910390a35050565b611e6b848484610bd2565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611ecd57611e9684848484612b00565b611ecc576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611edb612758565b600f60019054906101000a900460ff1615600f60016101000a81548160ff021916908315150217905550565b611f0f612f97565b611f17612f97565b611f1f6125bb565b831080611f335750611f2f612af7565b8310155b15611f415780915050611f6c565b611f4a83612acc565b9050806040015115611f5f5780915050611f6c565b611f6883612c60565b9150505b919050565b6060611f7c82612554565b611fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb290613da8565b60405180910390fd5b6000600a8054611fca90614256565b90501415611fe75760405180602001604052806000815250612013565b600a611ff283612c80565b604051602001612003929190613b38565b6040516020818303038152906040525b9050919050565b612023336127d6565b15612063576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205a90613e08565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146120d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c890613ca8565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461213f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213690613e88565b60405180910390fd5b60008111612182576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217990613d28565b60405180910390fd5b600681106121c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121bc90613e28565b60405180910390fd5b600c54816121d1610bbb565b6121db919061405e565b111561221c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221390613e48565b60405180910390fd5b600681601160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612269919061405e565b106122a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a090613c88565b60405180910390fd5b600f60019054906101000a900460ff166122f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122ef90613cc8565b60405180910390fd5b6010548161230691906140e5565b341015612348576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161233f90613ee8565b60405180910390fd5b80601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612393919061405e565b601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506123e08282612849565b7f748a2986091c2034d6e93b6f44f771a79f0e1d6acd8a60c68c17d4e1e2feaed28282604051612411929190613bc3565b60405180910390a15050565b600d5481565b600b5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6124c5612758565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252c90613ce8565b60405180910390fd5b61253e81612a06565b50565b600f60009054906101000a900460ff1681565b60008161255f6125bb565b1115801561256e575060005482105b80156125ac575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b600080829050806125cf6125bb565b11612657576000548110156126565760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415612654575b600081141561264a57600460008360019003935083815260200190815260200160002054905061261f565b8092505050612689565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612716868684612de1565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612760612dea565b73ffffffffffffffffffffffffffffffffffffffff1661277e611a72565b73ffffffffffffffffffffffffffffffffffffffff16146127d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127cb90613dc8565b60405180910390fd5b565b600080823b905060008111915050919050565b600061283f848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508361283a88612df2565b612e22565b9050949350505050565b600080549050600082141561288a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61289760008483856126f9565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061290e836128ff60008660006126ff565b61290885612e39565b17612727565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146129af57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612974565b5060008214156129eb576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a016000848385612752565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612ad4612f97565b612af06004600084815260200190815260200160002054612e49565b9050919050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612b266125b3565b8786866040518563ffffffff1660e01b8152600401612b489493929190613b77565b602060405180830381600087803b158015612b6257600080fd5b505af1925050508015612b9357506040513d601f19601f82011682018060405250810190612b9091906134b1565b60015b612c0d573d8060008114612bc3576040519150601f19603f3d011682016040523d82523d6000602084013e612bc8565b606091505b50600081511415612c05576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612c68612f97565b612c79612c74836125c0565b612e49565b9050919050565b60606000821415612cc8576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612ddc565b600082905060005b60008214612cfa578080612ce3906142b9565b915050600a82612cf391906140b4565b9150612cd0565b60008167ffffffffffffffff811115612d1657612d15614413565b5b6040519080825280601f01601f191660200182016040528015612d485781602001600182028036833780820191505090505b5090505b60008514612dd557600182612d61919061413f565b9150600a85612d709190614326565b6030612d7c919061405e565b60f81b818381518110612d9257612d916143e4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612dce91906140b4565b9450612d4c565b8093505050505b919050565b60009392505050565b600033905090565b600081604051602001612e059190613b1d565b604051602081830303815290604052805190602001209050919050565b600082612e2f8584612eff565b1490509392505050565b60006001821460e11b9050919050565b612e51612f97565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008082905060005b8451811015612f4a57612f3582868381518110612f2857612f276143e4565b5b6020026020010151612f55565b91508080612f42906142b9565b915050612f08565b508091505092915050565b6000818310612f6d57612f688284612f80565b612f78565b612f778383612f80565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000612ff9612ff484613f63565b613f3e565b90508281526020810184848401111561301557613014614451565b5b613020848285614214565b509392505050565b600081359050613037816147fe565b92915050565b60008083601f84011261305357613052614447565b5b8235905067ffffffffffffffff8111156130705761306f614442565b5b60208301915083602082028301111561308c5761308b61444c565b5b9250929050565b60008083601f8401126130a9576130a8614447565b5b8235905067ffffffffffffffff8111156130c6576130c5614442565b5b6020830191508360208202830111156130e2576130e161444c565b5b9250929050565b6000813590506130f881614815565b92915050565b60008135905061310d8161482c565b92915050565b60008135905061312281614843565b92915050565b60008151905061313781614843565b92915050565b600082601f83011261315257613151614447565b5b8135613162848260208601612fe6565b91505092915050565b60008135905061317a8161485a565b92915050565b6000602082840312156131965761319561445b565b5b60006131a484828501613028565b91505092915050565b600080604083850312156131c4576131c361445b565b5b60006131d285828601613028565b92505060206131e385828601613028565b9150509250929050565b6000806000606084860312156132065761320561445b565b5b600061321486828701613028565b935050602061322586828701613028565b92505060406132368682870161316b565b9150509250925092565b6000806000806080858703121561325a5761325961445b565b5b600061326887828801613028565b945050602061327987828801613028565b935050604061328a8782880161316b565b925050606085013567ffffffffffffffff8111156132ab576132aa614456565b5b6132b78782880161313d565b91505092959194509250565b600080604083850312156132da576132d961445b565b5b60006132e885828601613028565b92505060206132f9858286016130e9565b9150509250929050565b6000806040838503121561331a5761331961445b565b5b600061332885828601613028565b92505060206133398582860161316b565b9150509250929050565b6000806000806060858703121561335d5761335c61445b565b5b600061336b87828801613028565b945050602061337c8782880161316b565b935050604085013567ffffffffffffffff81111561339d5761339c614456565b5b6133a98782880161303d565b925092505092959194509250565b6000806000606084860312156133d0576133cf61445b565b5b60006133de86828701613028565b93505060206133ef8682870161316b565b92505060406134008682870161316b565b9150509250925092565b600080602083850312156134215761342061445b565b5b600083013567ffffffffffffffff81111561343f5761343e614456565b5b61344b85828601613093565b92509250509250929050565b60006020828403121561346d5761346c61445b565b5b600061347b848285016130fe565b91505092915050565b60006020828403121561349a5761349961445b565b5b60006134a884828501613113565b91505092915050565b6000602082840312156134c7576134c661445b565b5b60006134d584828501613128565b91505092915050565b6000602082840312156134f4576134f361445b565b5b60006135028482850161316b565b91505092915050565b60006135178383613a37565b60808301905092915050565b600061352f8383613af0565b60208301905092915050565b61354481614173565b82525050565b61355381614173565b82525050565b61356a61356582614173565b614302565b82525050565b600061357b82613fc9565b613585818561400f565b935061359083613f94565b8060005b838110156135c15781516135a8888261350b565b97506135b383613ff5565b925050600181019050613594565b5085935050505092915050565b60006135d982613fd4565b6135e38185614020565b93506135ee83613fa4565b8060005b8381101561361f5781516136068882613523565b975061361183614002565b9250506001810190506135f2565b5085935050505092915050565b61363581614185565b82525050565b61364481614185565b82525050565b61365381614191565b82525050565b600061366482613fdf565b61366e8185614031565b935061367e818560208601614223565b61368781614460565b840191505092915050565b600061369d82613fea565b6136a78185614042565b93506136b7818560208601614223565b6136c081614460565b840191505092915050565b60006136d682613fea565b6136e08185614053565b93506136f0818560208601614223565b80840191505092915050565b6000815461370981614256565b6137138186614053565b9450600182166000811461372e576001811461373f57613772565b60ff19831686528186019350613772565b61374885613fb4565b60005b8381101561376a5781548189015260018201915060208101905061374b565b838801955050505b50505092915050565b6000613788602483614042565b91506137938261447e565b604082019050919050565b60006137ab601a83614042565b91506137b6826144cd565b602082019050919050565b60006137ce601c83614042565b91506137d9826144f6565b602082019050919050565b60006137f1602683614042565b91506137fc8261451f565b604082019050919050565b6000613814601d83614042565b915061381f8261456e565b602082019050919050565b6000613837601f83614042565b915061384282614597565b602082019050919050565b600061385a601983614042565b9150613865826145c0565b602082019050919050565b600061387d601383614042565b9150613888826145e9565b602082019050919050565b60006138a0601f83614042565b91506138ab82614612565b602082019050919050565b60006138c3601583614042565b91506138ce8261463b565b602082019050919050565b60006138e6602083614042565b91506138f182614664565b602082019050919050565b6000613909601183614042565b91506139148261468d565b602082019050919050565b600061392c601483614042565b9150613937826146b6565b602082019050919050565b600061394f601e83614042565b915061395a826146df565b602082019050919050565b6000613972601783614042565b915061397d82614708565b602082019050919050565b6000613995601483614042565b91506139a082614731565b602082019050919050565b60006139b8601383614042565b91506139c38261475a565b602082019050919050565b60006139db601083614042565b91506139e682614783565b602082019050919050565b60006139fe601383614042565b9150613a09826147ac565b602082019050919050565b6000613a21601083614042565b9150613a2c826147d5565b602082019050919050565b608082016000820151613a4d600085018261353b565b506020820151613a606020850182613b0e565b506040820151613a73604085018261362c565b506060820151613a866060850182613ae1565b50505050565b608082016000820151613aa2600085018261353b565b506020820151613ab56020850182613b0e565b506040820151613ac8604085018261362c565b506060820151613adb6060850182613ae1565b50505050565b613aea816141e7565b82525050565b613af9816141f6565b82525050565b613b08816141f6565b82525050565b613b1781614200565b82525050565b6000613b298284613559565b60148201915081905092915050565b6000613b4482856136fc565b9150613b5082846136cb565b91508190509392505050565b6000602082019050613b71600083018461354a565b92915050565b6000608082019050613b8c600083018761354a565b613b99602083018661354a565b613ba66040830185613aff565b8181036060830152613bb88184613659565b905095945050505050565b6000604082019050613bd8600083018561354a565b613be56020830184613aff565b9392505050565b60006020820190508181036000830152613c068184613570565b905092915050565b60006020820190508181036000830152613c2881846135ce565b905092915050565b6000602082019050613c45600083018461363b565b92915050565b6000602082019050613c60600083018461364a565b92915050565b60006020820190508181036000830152613c808184613692565b905092915050565b60006020820190508181036000830152613ca18161377b565b9050919050565b60006020820190508181036000830152613cc18161379e565b9050919050565b60006020820190508181036000830152613ce1816137c1565b9050919050565b60006020820190508181036000830152613d01816137e4565b9050919050565b60006020820190508181036000830152613d2181613807565b9050919050565b60006020820190508181036000830152613d418161382a565b9050919050565b60006020820190508181036000830152613d618161384d565b9050919050565b60006020820190508181036000830152613d8181613870565b9050919050565b60006020820190508181036000830152613da181613893565b9050919050565b60006020820190508181036000830152613dc1816138b6565b9050919050565b60006020820190508181036000830152613de1816138d9565b9050919050565b60006020820190508181036000830152613e01816138fc565b9050919050565b60006020820190508181036000830152613e218161391f565b9050919050565b60006020820190508181036000830152613e4181613942565b9050919050565b60006020820190508181036000830152613e6181613965565b9050919050565b60006020820190508181036000830152613e8181613988565b9050919050565b60006020820190508181036000830152613ea1816139ab565b9050919050565b60006020820190508181036000830152613ec1816139ce565b9050919050565b60006020820190508181036000830152613ee1816139f1565b9050919050565b60006020820190508181036000830152613f0181613a14565b9050919050565b6000608082019050613f1d6000830184613a8c565b92915050565b6000602082019050613f386000830184613aff565b92915050565b6000613f48613f59565b9050613f548282614288565b919050565b6000604051905090565b600067ffffffffffffffff821115613f7e57613f7d614413565b5b613f8782614460565b9050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614069826141f6565b9150614074836141f6565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156140a9576140a8614357565b5b828201905092915050565b60006140bf826141f6565b91506140ca836141f6565b9250826140da576140d9614386565b5b828204905092915050565b60006140f0826141f6565b91506140fb836141f6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561413457614133614357565b5b828202905092915050565b600061414a826141f6565b9150614155836141f6565b92508282101561416857614167614357565b5b828203905092915050565b600061417e826141c7565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b82818337600083830152505050565b60005b83811015614241578082015181840152602081019050614226565b83811115614250576000848401525b50505050565b6000600282049050600182168061426e57607f821691505b60208210811415614282576142816143b5565b5b50919050565b61429182614460565b810181811067ffffffffffffffff821117156142b0576142af614413565b5b80604052505050565b60006142c4826141f6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156142f7576142f6614357565b5b600182019050919050565b600061430d82614314565b9050919050565b600061431f82614471565b9050919050565b6000614331826141f6565b915061433c836141f6565b92508261434c5761434b614386565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f6f7574206f66206d6178207175616e7469747920666f7220656163682061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f70726f787920636f6e7472616374206e6f7420616c6c6f776564000000000000600082015250565b7f6e6f7420616c6c6f7720746f207075626c6963206d696e74206e6f7700000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f7175616e746974792063616e206e6f7420736d616c6c207468616e2031000000600082015250565b7f7175616e746974792063616e206e6f7420736d616c6c6572207468616e203100600082015250565b7f6f7574206f662077686974656c69737420686172642063617000000000000000600082015250565b7f6e6f7420656e6f75676820657468657228322900000000000000000000000000600082015250565b7f6e6f7420616c6c6f7720746f2077686974656c697374206d696e74206e6f7700600082015250565b7f546f6b656e20646f6573206e6f742065786973742e0000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f6f7574206f66206d617820737570706c79000000000000000000000000000000600082015250565b7f636f6e7472616374206e6f7420616c6c6f776564000000000000000000000000600082015250565b7f7175616e746974792063616e206e6f7420626967676572207468616e20350000600082015250565b7f6f7574206f66206d696e74696e67206861726420636170000000000000000000600082015250565b7f696e73756666696369656e742062616c616e6365000000000000000000000000600082015250565b7f6e6f74207468652073616d652063616c6c657200000000000000000000000000600082015250565b7f6e6f7420696e2077686974656c69737400000000000000000000000000000000600082015250565b7f6e6f7420656e6f75676820657468657228312900000000000000000000000000600082015250565b7f6e6f7420656e6f75676820657468657200000000000000000000000000000000600082015250565b61480781614173565b811461481257600080fd5b50565b61481e81614185565b811461482957600080fd5b50565b61483581614191565b811461484057600080fd5b50565b61484c8161419b565b811461485757600080fd5b50565b614863816141f6565b811461486e57600080fd5b5056fea2646970667358221220a3c609ae1f75ab8a97429219d3155b520480370451e1cb1f8d396c9be6a5402864736f6c634300080700336533323432393665333762376131633938656562363963613131386134316231646433396461383135633837333432613566376637313163616461663432346468747470733a2f2f6170692e75746f7069616e66742e696f2f686b2f6d657461646174612f

Deployed Bytecode

0x6080604052600436106102305760003560e01c8063715018a61161012e578063b88d4fde116100ab578063d3e6e3ef1161006f578063d3e6e3ef146107ed578063d5abeb0114610818578063e985e9c514610843578063f2fde38b14610880578063ff7aa51f146108a957610230565b8063b88d4fde14610724578063b8e1b0da14610740578063c23dc68f14610757578063c87b56dd14610794578063ce6df2b9146107d157610230565b80638da5cb5b116100f25780638da5cb5b1461063d57806395d89b411461066857806399a2557a146106935780639edcc310146106d0578063a22cb465146106fb57610230565b8063715018a6146105805780637c03bdf3146105975780637cb64759146105ae5780638462151c146105d75780638ba4cc3c1461061457610230565b806342842e0e116101bc5780636352211e116101805780636352211e146104875780636817c76c146104c45780636c0360eb146104ef5780636f8b44b01461051a57806370a082311461054357610230565b806342842e0e146103aa5780634b11faaf146103c65780635130d734146103e25780635298ed571461041f5780635bbb21771461044a57610230565b806318160ddd1161020357806318160ddd146102f657806323b872dd146103215780632eb4a7ab1461033d5780633ccfd60b14610368578063420ed6e31461037f57610230565b806301ffc9a71461023557806306fdde0314610272578063081812fc1461029d578063095ea7b3146102da575b600080fd5b34801561024157600080fd5b5061025c60048036038101906102579190613484565b6108d4565b6040516102699190613c30565b60405180910390f35b34801561027e57600080fd5b50610287610966565b6040516102949190613c66565b60405180910390f35b3480156102a957600080fd5b506102c460048036038101906102bf91906134de565b6109f8565b6040516102d19190613b5c565b60405180910390f35b6102f460048036038101906102ef9190613303565b610a77565b005b34801561030257600080fd5b5061030b610bbb565b6040516103189190613f23565b60405180910390f35b61033b600480360381019061033691906131ed565b610bd2565b005b34801561034957600080fd5b50610352610ef7565b60405161035f9190613c4b565b60405180910390f35b34801561037457600080fd5b5061037d610efd565b005b34801561038b57600080fd5b50610394610f91565b6040516103a19190613c66565b60405180910390f35b6103c460048036038101906103bf91906131ed565b61101f565b005b6103e060048036038101906103db9190613343565b61103f565b005b3480156103ee57600080fd5b5061040960048036038101906104049190613180565b611593565b6040516104169190613f23565b60405180910390f35b34801561042b57600080fd5b506104346115ab565b6040516104419190613f23565b60405180910390f35b34801561045657600080fd5b50610471600480360381019061046c919061340a565b6115b1565b60405161047e9190613bec565b60405180910390f35b34801561049357600080fd5b506104ae60048036038101906104a991906134de565b611674565b6040516104bb9190613b5c565b60405180910390f35b3480156104d057600080fd5b506104d9611686565b6040516104e69190613f23565b60405180910390f35b3480156104fb57600080fd5b5061050461168c565b6040516105119190613c66565b60405180910390f35b34801561052657600080fd5b50610541600480360381019061053c91906134de565b61171a565b005b34801561054f57600080fd5b5061056a60048036038101906105659190613180565b61172c565b6040516105779190613f23565b60405180910390f35b34801561058c57600080fd5b506105956117e5565b005b3480156105a357600080fd5b506105ac6117f9565b005b3480156105ba57600080fd5b506105d560048036038101906105d09190613457565b61182d565b005b3480156105e357600080fd5b506105fe60048036038101906105f99190613180565b61183f565b60405161060b9190613c0e565b60405180910390f35b34801561062057600080fd5b5061063b60048036038101906106369190613303565b611989565b005b34801561064957600080fd5b50610652611a72565b60405161065f9190613b5c565b60405180910390f35b34801561067457600080fd5b5061067d611a9c565b60405161068a9190613c66565b60405180910390f35b34801561069f57600080fd5b506106ba60048036038101906106b591906133b7565b611b2e565b6040516106c79190613c0e565b60405180910390f35b3480156106dc57600080fd5b506106e5611d42565b6040516106f29190613c30565b60405180910390f35b34801561070757600080fd5b50610722600480360381019061071d91906132c3565b611d55565b005b61073e60048036038101906107399190613240565b611e60565b005b34801561074c57600080fd5b50610755611ed3565b005b34801561076357600080fd5b5061077e600480360381019061077991906134de565b611f07565b60405161078b9190613f08565b60405180910390f35b3480156107a057600080fd5b506107bb60048036038101906107b691906134de565b611f71565b6040516107c89190613c66565b60405180910390f35b6107eb60048036038101906107e69190613303565b61201a565b005b3480156107f957600080fd5b5061080261241d565b60405161080f9190613f23565b60405180910390f35b34801561082457600080fd5b5061082d612423565b60405161083a9190613f23565b60405180910390f35b34801561084f57600080fd5b5061086a600480360381019061086591906131ad565b612429565b6040516108779190613c30565b60405180910390f35b34801561088c57600080fd5b506108a760048036038101906108a29190613180565b6124bd565b005b3480156108b557600080fd5b506108be612541565b6040516108cb9190613c30565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061092f57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061095f5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461097590614256565b80601f01602080910402602001604051908101604052809291908181526020018280546109a190614256565b80156109ee5780601f106109c3576101008083540402835291602001916109ee565b820191906000526020600020905b8154815290600101906020018083116109d157829003601f168201915b5050505050905090565b6000610a0382612554565b610a39576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a8282611674565b90508073ffffffffffffffffffffffffffffffffffffffff16610aa36125b3565b73ffffffffffffffffffffffffffffffffffffffff1614610b0657610acf81610aca6125b3565b612429565b610b05576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610bc56125bb565b6001546000540303905090565b6000610bdd826125c0565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c44576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080610c508461268e565b91509150610c668187610c616125b3565b6126b5565b610cb257610c7b86610c766125b3565b612429565b610cb1576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415610d19576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d2686868660016126f9565b8015610d3157600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610dff85610ddb8888876126ff565b7c020000000000000000000000000000000000000000000000000000000017612727565b600460008681526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000084161415610e87576000600185019050600060046000838152602001908152602001600020541415610e85576000548114610e84578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610eef8686866001612752565b505050505050565b600e5481565b610f05612758565b60004711610f48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3f90613e68565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610f8e573d6000803e3d6000fd5b50565b60098054610f9e90614256565b80601f0160208091040260200160405190810160405280929190818152602001828054610fca90614256565b80156110175780601f10610fec57610100808354040283529160200191611017565b820191906000526020600020905b815481529060010190602001808311610ffa57829003601f168201915b505050505081565b61103a83838360405180602001604052806000815250611e60565b505050565b611048336127d6565b15611088576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107f90613e08565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110ed90613ca8565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614611164576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115b90613e88565b60405180910390fd5b600083116111a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119e90613d28565b60405180910390fd5b600683106111ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e190613e28565b60405180910390fd5b600d54836111f6610bbb565b611200919061405e565b1115611241576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123890613d48565b60405180910390fd5b600c548361124d610bbb565b611257919061405e565b1115611298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128f90613e48565b60405180910390fd5b600683601160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546112e5919061405e565b10611325576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131c90613c88565b60405180910390fd5b600f60009054906101000a900460ff16611374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136b90613d88565b60405180910390fd5b611382848383600e546127e9565b6113c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b890613ea8565b60405180910390fd5b6000601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054141561146b576010546010548461141a91906140e5565b611424919061413f565b341015611466576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145d90613ec8565b60405180910390fd5b6114bc565b6010548361147991906140e5565b3410156114bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b290613d68565b60405180910390fd5b5b82601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611507919061405e565b601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506115548484612849565b7f3175668c3bc41d83dd982a992932fc7512416b71850f41443845d2a4c2e3ec638484604051611585929190613bc3565b60405180910390a150505050565b60116020528060005260406000206000915090505481565b600c5481565b6060600083839050905060008167ffffffffffffffff8111156115d7576115d6614413565b5b60405190808252806020026020018201604052801561161057816020015b6115fd612f97565b8152602001906001900390816115f55790505b50905060005b8281146116685761163f868683818110611633576116326143e4565b5b90506020020135611f07565b828281518110611652576116516143e4565b5b6020026020010181905250806001019050611616565b50809250505092915050565b600061167f826125c0565b9050919050565b60105481565b600a805461169990614256565b80601f01602080910402602001604051908101604052809291908181526020018280546116c590614256565b80156117125780601f106116e757610100808354040283529160200191611712565b820191906000526020600020905b8154815290600101906020018083116116f557829003601f168201915b505050505081565b611722612758565b80600b8190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611794576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b6117ed612758565b6117f76000612a06565b565b611801612758565b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b611835612758565b80600e8190555050565b6060600080600061184f8561172c565b905060008167ffffffffffffffff81111561186d5761186c614413565b5b60405190808252806020026020018201604052801561189b5781602001602082028036833780820191505090505b5090506118a6612f97565b60006118b06125bb565b90505b83861461197b576118c381612acc565b91508160400151156118d457611970565b600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461191457816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141561196f5780838780600101985081518110611962576119616143e4565b5b6020026020010181815250505b5b8060010190506118b3565b508195505050505050919050565b611991612758565b600b548161199d610bbb565b6119a7919061405e565b11156119e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119df90613de8565b60405180910390fd5b60008111611a2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2290613d08565b60405180910390fd5b611a358282612849565b7f8c32c568416fcf97be35ce5b27844cfddcd63a67a1a602c3595ba5dac38f303a8282604051611a66929190613bc3565b60405180910390a15050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060038054611aab90614256565b80601f0160208091040260200160405190810160405280929190818152602001828054611ad790614256565b8015611b245780601f10611af957610100808354040283529160200191611b24565b820191906000526020600020905b815481529060010190602001808311611b0757829003601f168201915b5050505050905090565b6060818310611b69576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611b74612af7565b9050611b7e6125bb565b851015611b9057611b8d6125bb565b94505b80841115611b9c578093505b6000611ba78761172c565b905084861015611bca576000868603905081811015611bc4578091505b50611bcf565b600090505b60008167ffffffffffffffff811115611beb57611bea614413565b5b604051908082528060200260200182016040528015611c195781602001602082028036833780820191505090505b5090506000821415611c315780945050505050611d3b565b6000611c3c88611f07565b905060008160400151611c5157816000015190505b60008990505b888114158015611c675750848714155b15611d2d57611c7581612acc565b9250826040015115611c8657611d22565b600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611cc657826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611d215780848880600101995081518110611d1457611d136143e4565b5b6020026020010181815250505b5b806001019050611c57565b508583528296505050505050505b9392505050565b600f60019054906101000a900460ff1681565b8060076000611d626125b3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611e0f6125b3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611e549190613c30565b60405180910390a35050565b611e6b848484610bd2565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611ecd57611e9684848484612b00565b611ecc576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b611edb612758565b600f60019054906101000a900460ff1615600f60016101000a81548160ff021916908315150217905550565b611f0f612f97565b611f17612f97565b611f1f6125bb565b831080611f335750611f2f612af7565b8310155b15611f415780915050611f6c565b611f4a83612acc565b9050806040015115611f5f5780915050611f6c565b611f6883612c60565b9150505b919050565b6060611f7c82612554565b611fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb290613da8565b60405180910390fd5b6000600a8054611fca90614256565b90501415611fe75760405180602001604052806000815250612013565b600a611ff283612c80565b604051602001612003929190613b38565b6040516020818303038152906040525b9050919050565b612023336127d6565b15612063576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161205a90613e08565b60405180910390fd5b3273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146120d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c890613ca8565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461213f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161213690613e88565b60405180910390fd5b60008111612182576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161217990613d28565b60405180910390fd5b600681106121c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121bc90613e28565b60405180910390fd5b600c54816121d1610bbb565b6121db919061405e565b111561221c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221390613e48565b60405180910390fd5b600681601160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612269919061405e565b106122a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122a090613c88565b60405180910390fd5b600f60019054906101000a900460ff166122f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122ef90613cc8565b60405180910390fd5b6010548161230691906140e5565b341015612348576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161233f90613ee8565b60405180910390fd5b80601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612393919061405e565b601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506123e08282612849565b7f748a2986091c2034d6e93b6f44f771a79f0e1d6acd8a60c68c17d4e1e2feaed28282604051612411929190613bc3565b60405180910390a15050565b600d5481565b600b5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6124c5612758565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161252c90613ce8565b60405180910390fd5b61253e81612a06565b50565b600f60009054906101000a900460ff1681565b60008161255f6125bb565b1115801561256e575060005482105b80156125ac575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b600080829050806125cf6125bb565b11612657576000548110156126565760006004600083815260200190815260200160002054905060007c010000000000000000000000000000000000000000000000000000000082161415612654575b600081141561264a57600460008360019003935083815260200190815260200160002054905061261f565b8092505050612689565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8612716868684612de1565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b612760612dea565b73ffffffffffffffffffffffffffffffffffffffff1661277e611a72565b73ffffffffffffffffffffffffffffffffffffffff16146127d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127cb90613dc8565b60405180910390fd5b565b600080823b905060008111915050919050565b600061283f848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508361283a88612df2565b612e22565b9050949350505050565b600080549050600082141561288a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61289760008483856126f9565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061290e836128ff60008660006126ff565b61290885612e39565b17612727565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146129af57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612974565b5060008214156129eb576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000819055505050612a016000848385612752565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b612ad4612f97565b612af06004600084815260200190815260200160002054612e49565b9050919050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612b266125b3565b8786866040518563ffffffff1660e01b8152600401612b489493929190613b77565b602060405180830381600087803b158015612b6257600080fd5b505af1925050508015612b9357506040513d601f19601f82011682018060405250810190612b9091906134b1565b60015b612c0d573d8060008114612bc3576040519150601f19603f3d011682016040523d82523d6000602084013e612bc8565b606091505b50600081511415612c05576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b612c68612f97565b612c79612c74836125c0565b612e49565b9050919050565b60606000821415612cc8576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612ddc565b600082905060005b60008214612cfa578080612ce3906142b9565b915050600a82612cf391906140b4565b9150612cd0565b60008167ffffffffffffffff811115612d1657612d15614413565b5b6040519080825280601f01601f191660200182016040528015612d485781602001600182028036833780820191505090505b5090505b60008514612dd557600182612d61919061413f565b9150600a85612d709190614326565b6030612d7c919061405e565b60f81b818381518110612d9257612d916143e4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612dce91906140b4565b9450612d4c565b8093505050505b919050565b60009392505050565b600033905090565b600081604051602001612e059190613b1d565b604051602081830303815290604052805190602001209050919050565b600082612e2f8584612eff565b1490509392505050565b60006001821460e11b9050919050565b612e51612f97565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008082905060005b8451811015612f4a57612f3582868381518110612f2857612f276143e4565b5b6020026020010151612f55565b91508080612f42906142b9565b915050612f08565b508091505092915050565b6000818310612f6d57612f688284612f80565b612f78565b612f778383612f80565b5b905092915050565b600082600052816020526040600020905092915050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000612ff9612ff484613f63565b613f3e565b90508281526020810184848401111561301557613014614451565b5b613020848285614214565b509392505050565b600081359050613037816147fe565b92915050565b60008083601f84011261305357613052614447565b5b8235905067ffffffffffffffff8111156130705761306f614442565b5b60208301915083602082028301111561308c5761308b61444c565b5b9250929050565b60008083601f8401126130a9576130a8614447565b5b8235905067ffffffffffffffff8111156130c6576130c5614442565b5b6020830191508360208202830111156130e2576130e161444c565b5b9250929050565b6000813590506130f881614815565b92915050565b60008135905061310d8161482c565b92915050565b60008135905061312281614843565b92915050565b60008151905061313781614843565b92915050565b600082601f83011261315257613151614447565b5b8135613162848260208601612fe6565b91505092915050565b60008135905061317a8161485a565b92915050565b6000602082840312156131965761319561445b565b5b60006131a484828501613028565b91505092915050565b600080604083850312156131c4576131c361445b565b5b60006131d285828601613028565b92505060206131e385828601613028565b9150509250929050565b6000806000606084860312156132065761320561445b565b5b600061321486828701613028565b935050602061322586828701613028565b92505060406132368682870161316b565b9150509250925092565b6000806000806080858703121561325a5761325961445b565b5b600061326887828801613028565b945050602061327987828801613028565b935050604061328a8782880161316b565b925050606085013567ffffffffffffffff8111156132ab576132aa614456565b5b6132b78782880161313d565b91505092959194509250565b600080604083850312156132da576132d961445b565b5b60006132e885828601613028565b92505060206132f9858286016130e9565b9150509250929050565b6000806040838503121561331a5761331961445b565b5b600061332885828601613028565b92505060206133398582860161316b565b9150509250929050565b6000806000806060858703121561335d5761335c61445b565b5b600061336b87828801613028565b945050602061337c8782880161316b565b935050604085013567ffffffffffffffff81111561339d5761339c614456565b5b6133a98782880161303d565b925092505092959194509250565b6000806000606084860312156133d0576133cf61445b565b5b60006133de86828701613028565b93505060206133ef8682870161316b565b92505060406134008682870161316b565b9150509250925092565b600080602083850312156134215761342061445b565b5b600083013567ffffffffffffffff81111561343f5761343e614456565b5b61344b85828601613093565b92509250509250929050565b60006020828403121561346d5761346c61445b565b5b600061347b848285016130fe565b91505092915050565b60006020828403121561349a5761349961445b565b5b60006134a884828501613113565b91505092915050565b6000602082840312156134c7576134c661445b565b5b60006134d584828501613128565b91505092915050565b6000602082840312156134f4576134f361445b565b5b60006135028482850161316b565b91505092915050565b60006135178383613a37565b60808301905092915050565b600061352f8383613af0565b60208301905092915050565b61354481614173565b82525050565b61355381614173565b82525050565b61356a61356582614173565b614302565b82525050565b600061357b82613fc9565b613585818561400f565b935061359083613f94565b8060005b838110156135c15781516135a8888261350b565b97506135b383613ff5565b925050600181019050613594565b5085935050505092915050565b60006135d982613fd4565b6135e38185614020565b93506135ee83613fa4565b8060005b8381101561361f5781516136068882613523565b975061361183614002565b9250506001810190506135f2565b5085935050505092915050565b61363581614185565b82525050565b61364481614185565b82525050565b61365381614191565b82525050565b600061366482613fdf565b61366e8185614031565b935061367e818560208601614223565b61368781614460565b840191505092915050565b600061369d82613fea565b6136a78185614042565b93506136b7818560208601614223565b6136c081614460565b840191505092915050565b60006136d682613fea565b6136e08185614053565b93506136f0818560208601614223565b80840191505092915050565b6000815461370981614256565b6137138186614053565b9450600182166000811461372e576001811461373f57613772565b60ff19831686528186019350613772565b61374885613fb4565b60005b8381101561376a5781548189015260018201915060208101905061374b565b838801955050505b50505092915050565b6000613788602483614042565b91506137938261447e565b604082019050919050565b60006137ab601a83614042565b91506137b6826144cd565b602082019050919050565b60006137ce601c83614042565b91506137d9826144f6565b602082019050919050565b60006137f1602683614042565b91506137fc8261451f565b604082019050919050565b6000613814601d83614042565b915061381f8261456e565b602082019050919050565b6000613837601f83614042565b915061384282614597565b602082019050919050565b600061385a601983614042565b9150613865826145c0565b602082019050919050565b600061387d601383614042565b9150613888826145e9565b602082019050919050565b60006138a0601f83614042565b91506138ab82614612565b602082019050919050565b60006138c3601583614042565b91506138ce8261463b565b602082019050919050565b60006138e6602083614042565b91506138f182614664565b602082019050919050565b6000613909601183614042565b91506139148261468d565b602082019050919050565b600061392c601483614042565b9150613937826146b6565b602082019050919050565b600061394f601e83614042565b915061395a826146df565b602082019050919050565b6000613972601783614042565b915061397d82614708565b602082019050919050565b6000613995601483614042565b91506139a082614731565b602082019050919050565b60006139b8601383614042565b91506139c38261475a565b602082019050919050565b60006139db601083614042565b91506139e682614783565b602082019050919050565b60006139fe601383614042565b9150613a09826147ac565b602082019050919050565b6000613a21601083614042565b9150613a2c826147d5565b602082019050919050565b608082016000820151613a4d600085018261353b565b506020820151613a606020850182613b0e565b506040820151613a73604085018261362c565b506060820151613a866060850182613ae1565b50505050565b608082016000820151613aa2600085018261353b565b506020820151613ab56020850182613b0e565b506040820151613ac8604085018261362c565b506060820151613adb6060850182613ae1565b50505050565b613aea816141e7565b82525050565b613af9816141f6565b82525050565b613b08816141f6565b82525050565b613b1781614200565b82525050565b6000613b298284613559565b60148201915081905092915050565b6000613b4482856136fc565b9150613b5082846136cb565b91508190509392505050565b6000602082019050613b71600083018461354a565b92915050565b6000608082019050613b8c600083018761354a565b613b99602083018661354a565b613ba66040830185613aff565b8181036060830152613bb88184613659565b905095945050505050565b6000604082019050613bd8600083018561354a565b613be56020830184613aff565b9392505050565b60006020820190508181036000830152613c068184613570565b905092915050565b60006020820190508181036000830152613c2881846135ce565b905092915050565b6000602082019050613c45600083018461363b565b92915050565b6000602082019050613c60600083018461364a565b92915050565b60006020820190508181036000830152613c808184613692565b905092915050565b60006020820190508181036000830152613ca18161377b565b9050919050565b60006020820190508181036000830152613cc18161379e565b9050919050565b60006020820190508181036000830152613ce1816137c1565b9050919050565b60006020820190508181036000830152613d01816137e4565b9050919050565b60006020820190508181036000830152613d2181613807565b9050919050565b60006020820190508181036000830152613d418161382a565b9050919050565b60006020820190508181036000830152613d618161384d565b9050919050565b60006020820190508181036000830152613d8181613870565b9050919050565b60006020820190508181036000830152613da181613893565b9050919050565b60006020820190508181036000830152613dc1816138b6565b9050919050565b60006020820190508181036000830152613de1816138d9565b9050919050565b60006020820190508181036000830152613e01816138fc565b9050919050565b60006020820190508181036000830152613e218161391f565b9050919050565b60006020820190508181036000830152613e4181613942565b9050919050565b60006020820190508181036000830152613e6181613965565b9050919050565b60006020820190508181036000830152613e8181613988565b9050919050565b60006020820190508181036000830152613ea1816139ab565b9050919050565b60006020820190508181036000830152613ec1816139ce565b9050919050565b60006020820190508181036000830152613ee1816139f1565b9050919050565b60006020820190508181036000830152613f0181613a14565b9050919050565b6000608082019050613f1d6000830184613a8c565b92915050565b6000602082019050613f386000830184613aff565b92915050565b6000613f48613f59565b9050613f548282614288565b919050565b6000604051905090565b600067ffffffffffffffff821115613f7e57613f7d614413565b5b613f8782614460565b9050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614069826141f6565b9150614074836141f6565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156140a9576140a8614357565b5b828201905092915050565b60006140bf826141f6565b91506140ca836141f6565b9250826140da576140d9614386565b5b828204905092915050565b60006140f0826141f6565b91506140fb836141f6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561413457614133614357565b5b828202905092915050565b600061414a826141f6565b9150614155836141f6565b92508282101561416857614167614357565b5b828203905092915050565b600061417e826141c7565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b82818337600083830152505050565b60005b83811015614241578082015181840152602081019050614226565b83811115614250576000848401525b50505050565b6000600282049050600182168061426e57607f821691505b60208210811415614282576142816143b5565b5b50919050565b61429182614460565b810181811067ffffffffffffffff821117156142b0576142af614413565b5b80604052505050565b60006142c4826141f6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156142f7576142f6614357565b5b600182019050919050565b600061430d82614314565b9050919050565b600061431f82614471565b9050919050565b6000614331826141f6565b915061433c836141f6565b92508261434c5761434b614386565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f6f7574206f66206d6178207175616e7469747920666f7220656163682061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f70726f787920636f6e7472616374206e6f7420616c6c6f776564000000000000600082015250565b7f6e6f7420616c6c6f7720746f207075626c6963206d696e74206e6f7700000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f7175616e746974792063616e206e6f7420736d616c6c207468616e2031000000600082015250565b7f7175616e746974792063616e206e6f7420736d616c6c6572207468616e203100600082015250565b7f6f7574206f662077686974656c69737420686172642063617000000000000000600082015250565b7f6e6f7420656e6f75676820657468657228322900000000000000000000000000600082015250565b7f6e6f7420616c6c6f7720746f2077686974656c697374206d696e74206e6f7700600082015250565b7f546f6b656e20646f6573206e6f742065786973742e0000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f6f7574206f66206d617820737570706c79000000000000000000000000000000600082015250565b7f636f6e7472616374206e6f7420616c6c6f776564000000000000000000000000600082015250565b7f7175616e746974792063616e206e6f7420626967676572207468616e20350000600082015250565b7f6f7574206f66206d696e74696e67206861726420636170000000000000000000600082015250565b7f696e73756666696369656e742062616c616e6365000000000000000000000000600082015250565b7f6e6f74207468652073616d652063616c6c657200000000000000000000000000600082015250565b7f6e6f7420696e2077686974656c69737400000000000000000000000000000000600082015250565b7f6e6f7420656e6f75676820657468657228312900000000000000000000000000600082015250565b7f6e6f7420656e6f75676820657468657200000000000000000000000000000000600082015250565b61480781614173565b811461481257600080fd5b50565b61481e81614185565b811461482957600080fd5b50565b61483581614191565b811461484057600080fd5b50565b61484c8161419b565b811461485757600080fd5b50565b614863816141f6565b811461486e57600080fd5b5056fea2646970667358221220a3c609ae1f75ab8a97429219d3155b520480370451e1cb1f8d396c9be6a5402864736f6c63430008070033

Deployed Bytecode Sourcemap

83492:5258:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43249:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44151:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50642:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50075:408;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;39902:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54281:2825;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83744:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87468:178;;;;;;;;;;;;;:::i;:::-;;83581:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57202:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84865:1160;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83880:45;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83670:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77948:528;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45544:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83847:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83611:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87654:106;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;41086:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21039:103;;;;;;;;;;;;;:::i;:::-;;87886:112;;;;;;;;;;;;;:::i;:::-;;87768:110;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81824:900;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86799:318;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;20391:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44327:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78864:2513;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83813:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51200:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57993:407;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88006:103;;;;;;;;;;;;;:::i;:::-;;77361:428;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;87125:280;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86033:758;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83706:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83639:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51591:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21297:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83776:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43249:639;43334:4;43673:10;43658:25;;:11;:25;;;;:102;;;;43750:10;43735:25;;:11;:25;;;;43658:102;:179;;;;43827:10;43812:25;;:11;:25;;;;43658:179;43638:199;;43249:639;;;:::o;44151:100::-;44205:13;44238:5;44231:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44151:100;:::o;50642:218::-;50718:7;50743:16;50751:7;50743;:16::i;:::-;50738:64;;50768:34;;;;;;;;;;;;;;50738:64;50822:15;:24;50838:7;50822:24;;;;;;;;;;;:30;;;;;;;;;;;;50815:37;;50642:218;;;:::o;50075:408::-;50164:13;50180:16;50188:7;50180;:16::i;:::-;50164:32;;50236:5;50213:28;;:19;:17;:19::i;:::-;:28;;;50209:175;;50261:44;50278:5;50285:19;:17;:19::i;:::-;50261:16;:44::i;:::-;50256:128;;50333:35;;;;;;;;;;;;;;50256:128;50209:175;50429:2;50396:15;:24;50412:7;50396:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;50467:7;50463:2;50447:28;;50456:5;50447:28;;;;;;;;;;;;50153:330;50075:408;;:::o;39902:323::-;39963:7;40191:15;:13;:15::i;:::-;40176:12;;40160:13;;:28;:46;40153:53;;39902:323;:::o;54281:2825::-;54423:27;54453;54472:7;54453:18;:27::i;:::-;54423:57;;54538:4;54497:45;;54513:19;54497:45;;;54493:86;;54551:28;;;;;;;;;;;;;;54493:86;54593:27;54622:23;54649:35;54676:7;54649:26;:35::i;:::-;54592:92;;;;54784:68;54809:15;54826:4;54832:19;:17;:19::i;:::-;54784:24;:68::i;:::-;54779:180;;54872:43;54889:4;54895:19;:17;:19::i;:::-;54872:16;:43::i;:::-;54867:92;;54924:35;;;;;;;;;;;;;;54867:92;54779:180;54990:1;54976:16;;:2;:16;;;54972:52;;;55001:23;;;;;;;;;;;;;;54972:52;55037:43;55059:4;55065:2;55069:7;55078:1;55037:21;:43::i;:::-;55173:15;55170:160;;;55313:1;55292:19;55285:30;55170:160;55710:18;:24;55729:4;55710:24;;;;;;;;;;;;;;;;55708:26;;;;;;;;;;;;55779:18;:22;55798:2;55779:22;;;;;;;;;;;;;;;;55777:24;;;;;;;;;;;56101:146;56138:2;56187:45;56202:4;56208:2;56212:19;56187:14;:45::i;:::-;36301:8;56159:73;56101:18;:146::i;:::-;56072:17;:26;56090:7;56072:26;;;;;;;;;;;:175;;;;56418:1;36301:8;56367:19;:47;:52;56363:627;;;56440:19;56472:1;56462:7;:11;56440:33;;56629:1;56595:17;:30;56613:11;56595:30;;;;;;;;;;;;:35;56591:384;;;56733:13;;56718:11;:28;56714:242;;56913:19;56880:17;:30;56898:11;56880:30;;;;;;;;;;;:52;;;;56714:242;56591:384;56421:569;56363:627;57037:7;57033:2;57018:27;;57027:4;57018:27;;;;;;;;;;;;57056:42;57077:4;57083:2;57087:7;57096:1;57056:20;:42::i;:::-;54412:2694;;;54281:2825;;;:::o;83744:25::-;;;;:::o;87468:178::-;20277:13;:11;:13::i;:::-;87550:1:::1;87526:21;:25;87518:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;87595:10;87587:28;;:51;87616:21;87587:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;87468:178::o:0;83581:23::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;57202:193::-;57348:39;57365:4;57371:2;57375:7;57348:39;;;;;;;;;;;;:16;:39::i;:::-;57202:193;;;:::o;84865:1160::-;84665:23;84677:10;84665:11;:23::i;:::-;84664:24;84656:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;84746:9;84732:23;;:10;:23;;;84724:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;85033:10:::1;85027:16;;:2;:16;;;85018:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;85099:1;85088:8;:12;85079:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;85168:1;85157:8;:12;85148:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;85253:16;;85241:8;85225:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:44;;85216:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;85348:14;;85336:8;85320:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:42;;85311:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;85437:1;85426:8;85411;:12;85420:2;85411:12;;;;;;;;;;;;;;;;:23;;;;:::i;:::-;:27;85402:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;85500:18;;;;;;;;;;;85491:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;85575:36;85588:2;85592:5;;85599:10;;85575:11;:36::i;:::-;85566:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;85667:1;85651:8;:12;85660:2;85651:12;;;;;;;;;;;;;;;;:17;85646:246;;;85735:9;;85721;;85710:8;:20;;;;:::i;:::-;85708:36;;;;:::i;:::-;85695:9;:49;;85686:84;;;;;;;;;;;;:::i;:::-;;;;;;;;;85646:246;;;85845:9;;85834:8;:20;;;;:::i;:::-;85821:9;:33;;85812:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85646:246;85934:8;85919;:12;85928:2;85919:12;;;;;;;;;;;;;;;;:23;;;;:::i;:::-;85904:8;:12;85913:2;85904:12;;;;;;;;;;;;;;;:38;;;;85953:19;85959:2;85963:8;85953:5;:19::i;:::-;85990:27;86004:2;86008:8;85990:27;;;;;;;:::i;:::-;;;;;;;;84865:1160:::0;;;;:::o;83880:45::-;;;;;;;;;;;;;;;;;:::o;83670:29::-;;;;:::o;77948:528::-;78092:23;78158:22;78183:8;;:15;;78158:40;;78213:34;78271:14;78250:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;78213:73;;78306:9;78301:125;78322:14;78317:1;:19;78301:125;;78378:32;78398:8;;78407:1;78398:11;;;;;;;:::i;:::-;;;;;;;;78378:19;:32::i;:::-;78362:10;78373:1;78362:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;78338:3;;;;;78301:125;;;;78447:10;78440:17;;;;77948:528;;;;:::o;45544:152::-;45616:7;45659:27;45678:7;45659:18;:27::i;:::-;45636:52;;45544:152;;;:::o;83847:24::-;;;;:::o;83611:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;87654:106::-;20277:13;:11;:13::i;:::-;87740:12:::1;87728:9;:24;;;;87654:106:::0;:::o;41086:233::-;41158:7;41199:1;41182:19;;:5;:19;;;41178:60;;;41210:28;;;;;;;;;;;;;;41178:60;35245:13;41256:18;:25;41275:5;41256:25;;;;;;;;;;;;;;;;:55;41249:62;;41086:233;;;:::o;21039:103::-;20277:13;:11;:13::i;:::-;21104:30:::1;21131:1;21104:18;:30::i;:::-;21039:103::o:0;87886:112::-;20277:13;:11;:13::i;:::-;87972:18:::1;;;;;;;;;;;87971:19;87950:18;;:40;;;;;;;;;;;;;;;;;;87886:112::o:0;87768:110::-;20277:13;:11;:13::i;:::-;87857::::1;87844:10;:26;;;;87768:110:::0;:::o;81824:900::-;81902:16;81956:19;81990:25;82030:22;82055:16;82065:5;82055:9;:16::i;:::-;82030:41;;82086:25;82128:14;82114:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82086:57;;82158:31;;:::i;:::-;82209:9;82221:15;:13;:15::i;:::-;82209:27;;82204:472;82253:14;82238:11;:29;82204:472;;82305:15;82318:1;82305:12;:15::i;:::-;82293:27;;82343:9;:16;;;82339:73;;;82384:8;;82339:73;82460:1;82434:28;;:9;:14;;;:28;;;82430:111;;82507:9;:14;;;82487:34;;82430:111;82584:5;82563:26;;:17;:26;;;82559:102;;;82640:1;82614:8;82623:13;;;;;;82614:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;82559:102;82204:472;82269:3;;;;;82204:472;;;;82697:8;82690:15;;;;;;;81824:900;;;:::o;86799:318::-;20277:13;:11;:13::i;:::-;86939:9:::1;;86927:8;86911:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:37;;86902:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;87002:1;86991:8;:12;86982:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;87051:19;87057:2;87061:8;87051:5;:19::i;:::-;87088:21;87096:2;87100:8;87088:21;;;;;;;:::i;:::-;;;;;;;;86799:318:::0;;:::o;20391:87::-;20437:7;20464:6;;;;;;;;;;;20457:13;;20391:87;:::o;44327:104::-;44383:13;44416:7;44409:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44327:104;:::o;78864:2513::-;79007:16;79074:4;79065:5;:13;79061:45;;79087:19;;;;;;;;;;;;;;79061:45;79121:19;79155:17;79175:14;:12;:14::i;:::-;79155:34;;79275:15;:13;:15::i;:::-;79267:5;:23;79263:87;;;79319:15;:13;:15::i;:::-;79311:23;;79263:87;79426:9;79419:4;:16;79415:73;;;79463:9;79456:16;;79415:73;79502:25;79530:16;79540:5;79530:9;:16::i;:::-;79502:44;;79724:4;79716:5;:12;79712:278;;;79749:19;79778:5;79771:4;:12;79749:34;;79820:17;79806:11;:31;79802:111;;;79882:11;79862:31;;79802:111;79730:198;79712:278;;;79973:1;79953:21;;79712:278;80004:25;80046:17;80032:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80004:60;;80104:1;80083:17;:22;80079:78;;;80133:8;80126:15;;;;;;;;80079:78;80301:31;80335:26;80355:5;80335:19;:26::i;:::-;80301:60;;80376:25;80621:9;:16;;;80616:92;;80678:9;:14;;;80658:34;;80616:92;80727:9;80739:5;80727:17;;80722:478;80751:4;80746:1;:9;;:45;;;;;80774:17;80759:11;:32;;80746:45;80722:478;;;80829:15;80842:1;80829:12;:15::i;:::-;80817:27;;80867:9;:16;;;80863:73;;;80908:8;;80863:73;80984:1;80958:28;;:9;:14;;;:28;;;80954:111;;81031:9;:14;;;81011:34;;80954:111;81108:5;81087:26;;:17;:26;;;81083:102;;;81164:1;81138:8;81147:13;;;;;;81138:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;81083:102;80722:478;80793:3;;;;;80722:478;;;;81302:11;81292:8;81285:29;81350:8;81343:15;;;;;;;;78864:2513;;;;;;:::o;83813:27::-;;;;;;;;;;;;;:::o;51200:234::-;51347:8;51295:18;:39;51314:19;:17;:19::i;:::-;51295:39;;;;;;;;;;;;;;;:49;51335:8;51295:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;51407:8;51371:55;;51386:19;:17;:19::i;:::-;51371:55;;;51417:8;51371:55;;;;;;:::i;:::-;;;;;;;;51200:234;;:::o;57993:407::-;58168:31;58181:4;58187:2;58191:7;58168:12;:31::i;:::-;58232:1;58214:2;:14;;;:19;58210:183;;58253:56;58284:4;58290:2;58294:7;58303:5;58253:30;:56::i;:::-;58248:145;;58337:40;;;;;;;;;;;;;;58248:145;58210:183;57993:407;;;;:::o;88006:103::-;20277:13;:11;:13::i;:::-;88086:15:::1;;;;;;;;;;;88085:16;88067:15;;:34;;;;;;;;;;;;;;;;;;88006:103::o:0;77361:428::-;77445:21;;:::i;:::-;77479:31;;:::i;:::-;77535:15;:13;:15::i;:::-;77525:7;:25;:54;;;;77565:14;:12;:14::i;:::-;77554:7;:25;;77525:54;77521:103;;;77603:9;77596:16;;;;;77521:103;77646:21;77659:7;77646:12;:21::i;:::-;77634:33;;77682:9;:16;;;77678:65;;;77722:9;77715:16;;;;;77678:65;77760:21;77773:7;77760:12;:21::i;:::-;77753:28;;;77361:428;;;;:::o;87125:280::-;87214:13;87248:16;87256:7;87248;:16::i;:::-;87240:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;87335:1;87316:7;87310:21;;;;;:::i;:::-;;;:26;;:87;;;;;;;;;;;;;;;;;87363:7;87372:18;:7;:16;:18::i;:::-;87346:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;87310:87;87303:94;;87125:280;;;:::o;86033:758::-;84665:23;84677:10;84665:11;:23::i;:::-;84664:24;84656:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;84746:9;84732:23;;:10;:23;;;84724:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;86163:10:::1;86157:16;;:2;:16;;;86148:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;86229:1;86218:8;:12;86209:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;86298:1;86287:8;:12;86278:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;86383:14;;86371:8;86355:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:42;;86346:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;86472:1;86461:8;86446;:12;86455:2;86446:12;;;;;;;;;;;;;;;;:23;;;;:::i;:::-;:27;86437:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;86535:15;;;;;;;;;;;86526:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;86628:9;;86617:8;:20;;;;:::i;:::-;86604:9;:33;;86595:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;86703:8;86688;:12;86697:2;86688:12;;;;;;;;;;;;;;;;:23;;;;:::i;:::-;86673:8;:12;86682:2;86673:12;;;;;;;;;;;;;;;:38;;;;86722:19;86728:2;86732:8;86722:5;:19::i;:::-;86759:24;86770:2;86774:8;86759:24;;;;;;;:::i;:::-;;;;;;;;86033:758:::0;;:::o;83706:31::-;;;;:::o;83639:24::-;;;;:::o;51591:164::-;51688:4;51712:18;:25;51731:5;51712:25;;;;;;;;;;;;;;;:35;51738:8;51712:35;;;;;;;;;;;;;;;;;;;;;;;;;51705:42;;51591:164;;;;:::o;21297:201::-;20277:13;:11;:13::i;:::-;21406:1:::1;21386:22;;:8;:22;;;;21378:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;21462:28;21481:8;21462:18;:28::i;:::-;21297:201:::0;:::o;83776:30::-;;;;;;;;;;;;;:::o;52013:282::-;52078:4;52134:7;52115:15;:13;:15::i;:::-;:26;;:66;;;;;52168:13;;52158:7;:23;52115:66;:153;;;;;52267:1;36021:8;52219:17;:26;52237:7;52219:26;;;;;;;;;;;;:44;:49;52115:153;52095:173;;52013:282;;;:::o;74321:105::-;74381:7;74408:10;74401:17;;74321:105;:::o;39418:92::-;39474:7;39418:92;:::o;46699:1275::-;46766:7;46786:12;46801:7;46786:22;;46869:4;46850:15;:13;:15::i;:::-;:23;46846:1061;;46903:13;;46896:4;:20;46892:1015;;;46941:14;46958:17;:23;46976:4;46958:23;;;;;;;;;;;;46941:40;;47075:1;36021:8;47047:6;:24;:29;47043:845;;;47712:113;47729:1;47719:6;:11;47712:113;;;47772:17;:25;47790:6;;;;;;;47772:25;;;;;;;;;;;;47763:34;;47712:113;;;47858:6;47851:13;;;;;;47043:845;46918:989;46892:1015;46846:1061;47935:31;;;;;;;;;;;;;;46699:1275;;;;:::o;53176:485::-;53278:27;53307:23;53348:38;53389:15;:24;53405:7;53389:24;;;;;;;;;;;53348:65;;53566:18;53543:41;;53623:19;53617:26;53598:45;;53528:126;53176:485;;;:::o;52404:659::-;52553:11;52718:16;52711:5;52707:28;52698:37;;52878:16;52867:9;52863:32;52850:45;;53028:15;53017:9;53014:30;53006:5;52995:9;52992:20;52989:56;52979:66;;52404:659;;;;;:::o;59062:159::-;;;;;:::o;73630:311::-;73765:7;73785:16;36425:3;73811:19;:41;;73785:68;;36425:3;73879:31;73890:4;73896:2;73900:9;73879:10;:31::i;:::-;73871:40;;:62;;73864:69;;;73630:311;;;;;:::o;48522:450::-;48602:14;48770:16;48763:5;48759:28;48750:37;;48947:5;48933:11;48908:23;48904:41;48901:52;48894:5;48891:63;48881:73;;48522:450;;;;:::o;59886:158::-;;;;;:::o;20556:132::-;20631:12;:10;:12::i;:::-;20620:23;;:7;:5;:7::i;:::-;:23;;;20612:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;20556:132::o;88536:184::-;88611:4;88628:9;88679:5;88667:18;88659:26;;88711:1;88704:4;:8;88697:15;;;88536:184;;;:::o;88323:205::-;88454:4;88478:42;88497:5;;88478:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88504:4;88510:9;88515:3;88510:4;:9::i;:::-;88478:18;:42::i;:::-;88471:49;;88323:205;;;;;;:::o;61662:2966::-;61735:20;61758:13;;61735:36;;61798:1;61786:8;:13;61782:44;;;61808:18;;;;;;;;;;;;;;61782:44;61839:61;61869:1;61873:2;61877:12;61891:8;61839:21;:61::i;:::-;62383:1;35383:2;62353:1;:26;;62352:32;62340:8;:45;62314:18;:22;62333:2;62314:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;62662:139;62699:2;62753:33;62776:1;62780:2;62784:1;62753:14;:33::i;:::-;62720:30;62741:8;62720:20;:30::i;:::-;:66;62662:18;:139::i;:::-;62628:17;:31;62646:12;62628:31;;;;;;;;;;;:173;;;;62818:16;62849:11;62878:8;62863:12;:23;62849:37;;63399:16;63395:2;63391:25;63379:37;;63771:12;63731:8;63690:1;63628:25;63569:1;63508;63481:335;64142:1;64128:12;64124:20;64082:346;64183:3;64174:7;64171:16;64082:346;;64401:7;64391:8;64388:1;64361:25;64358:1;64355;64350:59;64236:1;64227:7;64223:15;64212:26;;64082:346;;;64086:77;64473:1;64461:8;:13;64457:45;;;64483:19;;;;;;;;;;;;;;64457:45;64535:3;64519:13;:19;;;;62088:2462;;64560:60;64589:1;64593:2;64597:12;64611:8;64560:20;:60::i;:::-;61724:2904;61662:2966;;:::o;21658:191::-;21732:16;21751:6;;;;;;;;;;;21732:25;;21777:8;21768:6;;:17;;;;;;;;;;;;;;;;;;21832:8;21801:40;;21822:8;21801:40;;;;;;;;;;;;21721:128;21658:191;:::o;46147:161::-;46215:21;;:::i;:::-;46256:44;46275:17;:24;46293:5;46275:24;;;;;;;;;;;;46256:18;:44::i;:::-;46249:51;;46147:161;;;:::o;39589:103::-;39644:7;39671:13;;39664:20;;39589:103;:::o;60484:716::-;60647:4;60693:2;60668:45;;;60714:19;:17;:19::i;:::-;60735:4;60741:7;60750:5;60668:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;60664:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60968:1;60951:6;:13;:18;60947:235;;;60997:40;;;;;;;;;;;;;;60947:235;61140:6;61134:13;61125:6;61121:2;61117:15;61110:38;60664:529;60837:54;;;60827:64;;;:6;:64;;;;60820:71;;;60484:716;;;;;;:::o;45885:166::-;45955:21;;:::i;:::-;45996:47;46015:27;46034:7;46015:18;:27::i;:::-;45996:18;:47::i;:::-;45989:54;;45885:166;;;:::o;430:723::-;486:13;716:1;707:5;:10;703:53;;;734:10;;;;;;;;;;;;;;;;;;;;;703:53;766:12;781:5;766:20;;797:14;822:78;837:1;829:4;:9;822:78;;855:8;;;;;:::i;:::-;;;;886:2;878:10;;;;;:::i;:::-;;;822:78;;;910:19;942:6;932:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;910:39;;960:154;976:1;967:5;:10;960:154;;1004:1;994:11;;;;;:::i;:::-;;;1071:2;1063:5;:10;;;;:::i;:::-;1050:2;:24;;;;:::i;:::-;1037:39;;1020:6;1027;1020:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;1100:2;1091:11;;;;;:::i;:::-;;;960:154;;;1138:6;1124:21;;;;;430:723;;;;:::o;73331:147::-;73468:6;73331:147;;;;;:::o;18942:98::-;18995:7;19022:10;19015:17;;18942:98;:::o;88172:143::-;88243:7;88297:8;88280:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;88270:37;;;;;;88263:44;;88172:143;;;:::o;10757:190::-;10882:4;10935;10906:25;10919:5;10926:4;10906:12;:25::i;:::-;:33;10899:40;;10757:190;;;;;:::o;49074:324::-;49144:14;49377:1;49367:8;49364:15;49338:24;49334:46;49324:56;;49074:324;;;:::o;48073:366::-;48139:31;;:::i;:::-;48216:6;48183:9;:14;;:41;;;;;;;;;;;35904:3;48269:6;:33;;48235:9;:24;;:68;;;;;;;;;;;48361:1;36021:8;48333:6;:24;:29;;48314:9;:16;;:48;;;;;;;;;;;36425:3;48402:6;:28;;48373:9;:19;;:58;;;;;;;;;;;48073:366;;;:::o;11624:296::-;11707:7;11727:20;11750:4;11727:27;;11770:9;11765:118;11789:5;:12;11785:1;:16;11765:118;;;11838:33;11848:12;11862:5;11868:1;11862:8;;;;;;;;:::i;:::-;;;;;;;;11838:9;:33::i;:::-;11823:48;;11803:3;;;;;:::i;:::-;;;;11765:118;;;;11900:12;11893:19;;;11624:296;;;;:::o;17831:149::-;17894:7;17925:1;17921;:5;:51;;17952:20;17967:1;17970;17952:14;:20::i;:::-;17921:51;;;17929:20;17944:1;17947;17929:14;:20::i;:::-;17921:51;17914:58;;17831:149;;;;:::o;17988:268::-;18056:13;18163:1;18157:4;18150:15;18192:1;18186:4;18179:15;18233:4;18227;18217:21;18208:30;;17988:268;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:410:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:112;;;280:79;;:::i;:::-;249:112;370:41;404:6;399:3;394;370:41;:::i;:::-;90:327;7:410;;;;;:::o;423:139::-;469:5;507:6;494:20;485:29;;523:33;550:5;523:33;:::i;:::-;423:139;;;;:::o;585:568::-;658:8;668:6;718:3;711:4;703:6;699:17;695:27;685:122;;726:79;;:::i;:::-;685:122;839:6;826:20;816:30;;869:18;861:6;858:30;855:117;;;891:79;;:::i;:::-;855:117;1005:4;997:6;993:17;981:29;;1059:3;1051:4;1043:6;1039:17;1029:8;1025:32;1022:41;1019:128;;;1066:79;;:::i;:::-;1019:128;585:568;;;;;:::o;1176:::-;1249:8;1259:6;1309:3;1302:4;1294:6;1290:17;1286:27;1276:122;;1317:79;;:::i;:::-;1276:122;1430:6;1417:20;1407:30;;1460:18;1452:6;1449:30;1446:117;;;1482:79;;:::i;:::-;1446:117;1596:4;1588:6;1584:17;1572:29;;1650:3;1642:4;1634:6;1630:17;1620:8;1616:32;1613:41;1610:128;;;1657:79;;:::i;:::-;1610:128;1176:568;;;;;:::o;1750:133::-;1793:5;1831:6;1818:20;1809:29;;1847:30;1871:5;1847:30;:::i;:::-;1750:133;;;;:::o;1889:139::-;1935:5;1973:6;1960:20;1951:29;;1989:33;2016:5;1989:33;:::i;:::-;1889:139;;;;:::o;2034:137::-;2079:5;2117:6;2104:20;2095:29;;2133:32;2159:5;2133:32;:::i;:::-;2034:137;;;;:::o;2177:141::-;2233:5;2264:6;2258:13;2249:22;;2280:32;2306:5;2280:32;:::i;:::-;2177:141;;;;:::o;2337:338::-;2392:5;2441:3;2434:4;2426:6;2422:17;2418:27;2408:122;;2449:79;;:::i;:::-;2408:122;2566:6;2553:20;2591:78;2665:3;2657:6;2650:4;2642:6;2638:17;2591:78;:::i;:::-;2582:87;;2398:277;2337:338;;;;:::o;2681:139::-;2727:5;2765:6;2752:20;2743:29;;2781:33;2808:5;2781:33;:::i;:::-;2681:139;;;;:::o;2826:329::-;2885:6;2934:2;2922:9;2913:7;2909:23;2905:32;2902:119;;;2940:79;;:::i;:::-;2902:119;3060:1;3085:53;3130:7;3121:6;3110:9;3106:22;3085:53;:::i;:::-;3075:63;;3031:117;2826:329;;;;:::o;3161:474::-;3229:6;3237;3286:2;3274:9;3265:7;3261:23;3257:32;3254:119;;;3292:79;;:::i;:::-;3254:119;3412:1;3437:53;3482:7;3473:6;3462:9;3458:22;3437:53;:::i;:::-;3427:63;;3383:117;3539:2;3565:53;3610:7;3601:6;3590:9;3586:22;3565:53;:::i;:::-;3555:63;;3510:118;3161:474;;;;;:::o;3641:619::-;3718:6;3726;3734;3783:2;3771:9;3762:7;3758:23;3754:32;3751:119;;;3789:79;;:::i;:::-;3751:119;3909:1;3934:53;3979:7;3970:6;3959:9;3955:22;3934:53;:::i;:::-;3924:63;;3880:117;4036:2;4062:53;4107:7;4098:6;4087:9;4083:22;4062:53;:::i;:::-;4052:63;;4007:118;4164:2;4190:53;4235:7;4226:6;4215:9;4211:22;4190:53;:::i;:::-;4180:63;;4135:118;3641:619;;;;;:::o;4266:943::-;4361:6;4369;4377;4385;4434:3;4422:9;4413:7;4409:23;4405:33;4402:120;;;4441:79;;:::i;:::-;4402:120;4561:1;4586:53;4631:7;4622:6;4611:9;4607:22;4586:53;:::i;:::-;4576:63;;4532:117;4688:2;4714:53;4759:7;4750:6;4739:9;4735:22;4714:53;:::i;:::-;4704:63;;4659:118;4816:2;4842:53;4887:7;4878:6;4867:9;4863:22;4842:53;:::i;:::-;4832:63;;4787:118;4972:2;4961:9;4957:18;4944:32;5003:18;4995:6;4992:30;4989:117;;;5025:79;;:::i;:::-;4989:117;5130:62;5184:7;5175:6;5164:9;5160:22;5130:62;:::i;:::-;5120:72;;4915:287;4266:943;;;;;;;:::o;5215:468::-;5280:6;5288;5337:2;5325:9;5316:7;5312:23;5308:32;5305:119;;;5343:79;;:::i;:::-;5305:119;5463:1;5488:53;5533:7;5524:6;5513:9;5509:22;5488:53;:::i;:::-;5478:63;;5434:117;5590:2;5616:50;5658:7;5649:6;5638:9;5634:22;5616:50;:::i;:::-;5606:60;;5561:115;5215:468;;;;;:::o;5689:474::-;5757:6;5765;5814:2;5802:9;5793:7;5789:23;5785:32;5782:119;;;5820:79;;:::i;:::-;5782:119;5940:1;5965:53;6010:7;6001:6;5990:9;5986:22;5965:53;:::i;:::-;5955:63;;5911:117;6067:2;6093:53;6138:7;6129:6;6118:9;6114:22;6093:53;:::i;:::-;6083:63;;6038:118;5689:474;;;;;:::o;6169:849::-;6273:6;6281;6289;6297;6346:2;6334:9;6325:7;6321:23;6317:32;6314:119;;;6352:79;;:::i;:::-;6314:119;6472:1;6497:53;6542:7;6533:6;6522:9;6518:22;6497:53;:::i;:::-;6487:63;;6443:117;6599:2;6625:53;6670:7;6661:6;6650:9;6646:22;6625:53;:::i;:::-;6615:63;;6570:118;6755:2;6744:9;6740:18;6727:32;6786:18;6778:6;6775:30;6772:117;;;6808:79;;:::i;:::-;6772:117;6921:80;6993:7;6984:6;6973:9;6969:22;6921:80;:::i;:::-;6903:98;;;;6698:313;6169:849;;;;;;;:::o;7024:619::-;7101:6;7109;7117;7166:2;7154:9;7145:7;7141:23;7137:32;7134:119;;;7172:79;;:::i;:::-;7134:119;7292:1;7317:53;7362:7;7353:6;7342:9;7338:22;7317:53;:::i;:::-;7307:63;;7263:117;7419:2;7445:53;7490:7;7481:6;7470:9;7466:22;7445:53;:::i;:::-;7435:63;;7390:118;7547:2;7573:53;7618:7;7609:6;7598:9;7594:22;7573:53;:::i;:::-;7563:63;;7518:118;7024:619;;;;;:::o;7649:559::-;7735:6;7743;7792:2;7780:9;7771:7;7767:23;7763:32;7760:119;;;7798:79;;:::i;:::-;7760:119;7946:1;7935:9;7931:17;7918:31;7976:18;7968:6;7965:30;7962:117;;;7998:79;;:::i;:::-;7962:117;8111:80;8183:7;8174:6;8163:9;8159:22;8111:80;:::i;:::-;8093:98;;;;7889:312;7649:559;;;;;:::o;8214:329::-;8273:6;8322:2;8310:9;8301:7;8297:23;8293:32;8290:119;;;8328:79;;:::i;:::-;8290:119;8448:1;8473:53;8518:7;8509:6;8498:9;8494:22;8473:53;:::i;:::-;8463:63;;8419:117;8214:329;;;;:::o;8549:327::-;8607:6;8656:2;8644:9;8635:7;8631:23;8627:32;8624:119;;;8662:79;;:::i;:::-;8624:119;8782:1;8807:52;8851:7;8842:6;8831:9;8827:22;8807:52;:::i;:::-;8797:62;;8753:116;8549:327;;;;:::o;8882:349::-;8951:6;9000:2;8988:9;8979:7;8975:23;8971:32;8968:119;;;9006:79;;:::i;:::-;8968:119;9126:1;9151:63;9206:7;9197:6;9186:9;9182:22;9151:63;:::i;:::-;9141:73;;9097:127;8882:349;;;;:::o;9237:329::-;9296:6;9345:2;9333:9;9324:7;9320:23;9316:32;9313:119;;;9351:79;;:::i;:::-;9313:119;9471:1;9496:53;9541:7;9532:6;9521:9;9517:22;9496:53;:::i;:::-;9486:63;;9442:117;9237:329;;;;:::o;9572:307::-;9705:10;9726:110;9832:3;9824:6;9726:110;:::i;:::-;9868:4;9863:3;9859:14;9845:28;;9572:307;;;;:::o;9885:179::-;9954:10;9975:46;10017:3;10009:6;9975:46;:::i;:::-;10053:4;10048:3;10044:14;10030:28;;9885:179;;;;:::o;10070:108::-;10147:24;10165:5;10147:24;:::i;:::-;10142:3;10135:37;10070:108;;:::o;10184:118::-;10271:24;10289:5;10271:24;:::i;:::-;10266:3;10259:37;10184:118;;:::o;10308:157::-;10413:45;10433:24;10451:5;10433:24;:::i;:::-;10413:45;:::i;:::-;10408:3;10401:58;10308:157;;:::o;10547:988::-;10730:3;10759:86;10839:5;10759:86;:::i;:::-;10861:118;10972:6;10967:3;10861:118;:::i;:::-;10854:125;;11003:88;11085:5;11003:88;:::i;:::-;11114:7;11145:1;11130:380;11155:6;11152:1;11149:13;11130:380;;;11231:6;11225:13;11258:127;11381:3;11366:13;11258:127;:::i;:::-;11251:134;;11408:92;11493:6;11408:92;:::i;:::-;11398:102;;11190:320;11177:1;11174;11170:9;11165:14;;11130:380;;;11134:14;11526:3;11519:10;;10735:800;;;10547:988;;;;:::o;11571:732::-;11690:3;11719:54;11767:5;11719:54;:::i;:::-;11789:86;11868:6;11863:3;11789:86;:::i;:::-;11782:93;;11899:56;11949:5;11899:56;:::i;:::-;11978:7;12009:1;11994:284;12019:6;12016:1;12013:13;11994:284;;;12095:6;12089:13;12122:63;12181:3;12166:13;12122:63;:::i;:::-;12115:70;;12208:60;12261:6;12208:60;:::i;:::-;12198:70;;12054:224;12041:1;12038;12034:9;12029:14;;11994:284;;;11998:14;12294:3;12287:10;;11695:608;;;11571:732;;;;:::o;12309:99::-;12380:21;12395:5;12380:21;:::i;:::-;12375:3;12368:34;12309:99;;:::o;12414:109::-;12495:21;12510:5;12495:21;:::i;:::-;12490:3;12483:34;12414:109;;:::o;12529:118::-;12616:24;12634:5;12616:24;:::i;:::-;12611:3;12604:37;12529:118;;:::o;12653:360::-;12739:3;12767:38;12799:5;12767:38;:::i;:::-;12821:70;12884:6;12879:3;12821:70;:::i;:::-;12814:77;;12900:52;12945:6;12940:3;12933:4;12926:5;12922:16;12900:52;:::i;:::-;12977:29;12999:6;12977:29;:::i;:::-;12972:3;12968:39;12961:46;;12743:270;12653:360;;;;:::o;13019:364::-;13107:3;13135:39;13168:5;13135:39;:::i;:::-;13190:71;13254:6;13249:3;13190:71;:::i;:::-;13183:78;;13270:52;13315:6;13310:3;13303:4;13296:5;13292:16;13270:52;:::i;:::-;13347:29;13369:6;13347:29;:::i;:::-;13342:3;13338:39;13331:46;;13111:272;13019:364;;;;:::o;13389:377::-;13495:3;13523:39;13556:5;13523:39;:::i;:::-;13578:89;13660:6;13655:3;13578:89;:::i;:::-;13571:96;;13676:52;13721:6;13716:3;13709:4;13702:5;13698:16;13676:52;:::i;:::-;13753:6;13748:3;13744:16;13737:23;;13499:267;13389:377;;;;:::o;13796:845::-;13899:3;13936:5;13930:12;13965:36;13991:9;13965:36;:::i;:::-;14017:89;14099:6;14094:3;14017:89;:::i;:::-;14010:96;;14137:1;14126:9;14122:17;14153:1;14148:137;;;;14299:1;14294:341;;;;14115:520;;14148:137;14232:4;14228:9;14217;14213:25;14208:3;14201:38;14268:6;14263:3;14259:16;14252:23;;14148:137;;14294:341;14361:38;14393:5;14361:38;:::i;:::-;14421:1;14435:154;14449:6;14446:1;14443:13;14435:154;;;14523:7;14517:14;14513:1;14508:3;14504:11;14497:35;14573:1;14564:7;14560:15;14549:26;;14471:4;14468:1;14464:12;14459:17;;14435:154;;;14618:6;14613:3;14609:16;14602:23;;14301:334;;14115:520;;13903:738;;13796:845;;;;:::o;14647:366::-;14789:3;14810:67;14874:2;14869:3;14810:67;:::i;:::-;14803:74;;14886:93;14975:3;14886:93;:::i;:::-;15004:2;14999:3;14995:12;14988:19;;14647:366;;;:::o;15019:::-;15161:3;15182:67;15246:2;15241:3;15182:67;:::i;:::-;15175:74;;15258:93;15347:3;15258:93;:::i;:::-;15376:2;15371:3;15367:12;15360:19;;15019:366;;;:::o;15391:::-;15533:3;15554:67;15618:2;15613:3;15554:67;:::i;:::-;15547:74;;15630:93;15719:3;15630:93;:::i;:::-;15748:2;15743:3;15739:12;15732:19;;15391:366;;;:::o;15763:::-;15905:3;15926:67;15990:2;15985:3;15926:67;:::i;:::-;15919:74;;16002:93;16091:3;16002:93;:::i;:::-;16120:2;16115:3;16111:12;16104:19;;15763:366;;;:::o;16135:::-;16277:3;16298:67;16362:2;16357:3;16298:67;:::i;:::-;16291:74;;16374:93;16463:3;16374:93;:::i;:::-;16492:2;16487:3;16483:12;16476:19;;16135:366;;;:::o;16507:::-;16649:3;16670:67;16734:2;16729:3;16670:67;:::i;:::-;16663:74;;16746:93;16835:3;16746:93;:::i;:::-;16864:2;16859:3;16855:12;16848:19;;16507:366;;;:::o;16879:::-;17021:3;17042:67;17106:2;17101:3;17042:67;:::i;:::-;17035:74;;17118:93;17207:3;17118:93;:::i;:::-;17236:2;17231:3;17227:12;17220:19;;16879:366;;;:::o;17251:::-;17393:3;17414:67;17478:2;17473:3;17414:67;:::i;:::-;17407:74;;17490:93;17579:3;17490:93;:::i;:::-;17608:2;17603:3;17599:12;17592:19;;17251:366;;;:::o;17623:::-;17765:3;17786:67;17850:2;17845:3;17786:67;:::i;:::-;17779:74;;17862:93;17951:3;17862:93;:::i;:::-;17980:2;17975:3;17971:12;17964:19;;17623:366;;;:::o;17995:::-;18137:3;18158:67;18222:2;18217:3;18158:67;:::i;:::-;18151:74;;18234:93;18323:3;18234:93;:::i;:::-;18352:2;18347:3;18343:12;18336:19;;17995:366;;;:::o;18367:::-;18509:3;18530:67;18594:2;18589:3;18530:67;:::i;:::-;18523:74;;18606:93;18695:3;18606:93;:::i;:::-;18724:2;18719:3;18715:12;18708:19;;18367:366;;;:::o;18739:::-;18881:3;18902:67;18966:2;18961:3;18902:67;:::i;:::-;18895:74;;18978:93;19067:3;18978:93;:::i;:::-;19096:2;19091:3;19087:12;19080:19;;18739:366;;;:::o;19111:::-;19253:3;19274:67;19338:2;19333:3;19274:67;:::i;:::-;19267:74;;19350:93;19439:3;19350:93;:::i;:::-;19468:2;19463:3;19459:12;19452:19;;19111:366;;;:::o;19483:::-;19625:3;19646:67;19710:2;19705:3;19646:67;:::i;:::-;19639:74;;19722:93;19811:3;19722:93;:::i;:::-;19840:2;19835:3;19831:12;19824:19;;19483:366;;;:::o;19855:::-;19997:3;20018:67;20082:2;20077:3;20018:67;:::i;:::-;20011:74;;20094:93;20183:3;20094:93;:::i;:::-;20212:2;20207:3;20203:12;20196:19;;19855:366;;;:::o;20227:::-;20369:3;20390:67;20454:2;20449:3;20390:67;:::i;:::-;20383:74;;20466:93;20555:3;20466:93;:::i;:::-;20584:2;20579:3;20575:12;20568:19;;20227:366;;;:::o;20599:::-;20741:3;20762:67;20826:2;20821:3;20762:67;:::i;:::-;20755:74;;20838:93;20927:3;20838:93;:::i;:::-;20956:2;20951:3;20947:12;20940:19;;20599:366;;;:::o;20971:::-;21113:3;21134:67;21198:2;21193:3;21134:67;:::i;:::-;21127:74;;21210:93;21299:3;21210:93;:::i;:::-;21328:2;21323:3;21319:12;21312:19;;20971:366;;;:::o;21343:::-;21485:3;21506:67;21570:2;21565:3;21506:67;:::i;:::-;21499:74;;21582:93;21671:3;21582:93;:::i;:::-;21700:2;21695:3;21691:12;21684:19;;21343:366;;;:::o;21715:::-;21857:3;21878:67;21942:2;21937:3;21878:67;:::i;:::-;21871:74;;21954:93;22043:3;21954:93;:::i;:::-;22072:2;22067:3;22063:12;22056:19;;21715:366;;;:::o;22159:866::-;22310:4;22305:3;22301:14;22397:4;22390:5;22386:16;22380:23;22416:63;22473:4;22468:3;22464:14;22450:12;22416:63;:::i;:::-;22325:164;22581:4;22574:5;22570:16;22564:23;22600:61;22655:4;22650:3;22646:14;22632:12;22600:61;:::i;:::-;22499:172;22755:4;22748:5;22744:16;22738:23;22774:57;22825:4;22820:3;22816:14;22802:12;22774:57;:::i;:::-;22681:160;22928:4;22921:5;22917:16;22911:23;22947:61;23002:4;22997:3;22993:14;22979:12;22947:61;:::i;:::-;22851:167;22279:746;22159:866;;:::o;23103:876::-;23264:4;23259:3;23255:14;23351:4;23344:5;23340:16;23334:23;23370:63;23427:4;23422:3;23418:14;23404:12;23370:63;:::i;:::-;23279:164;23535:4;23528:5;23524:16;23518:23;23554:61;23609:4;23604:3;23600:14;23586:12;23554:61;:::i;:::-;23453:172;23709:4;23702:5;23698:16;23692:23;23728:57;23779:4;23774:3;23770:14;23756:12;23728:57;:::i;:::-;23635:160;23882:4;23875:5;23871:16;23865:23;23901:61;23956:4;23951:3;23947:14;23933:12;23901:61;:::i;:::-;23805:167;23233:746;23103:876;;:::o;23985:105::-;24060:23;24077:5;24060:23;:::i;:::-;24055:3;24048:36;23985:105;;:::o;24096:108::-;24173:24;24191:5;24173:24;:::i;:::-;24168:3;24161:37;24096:108;;:::o;24210:118::-;24297:24;24315:5;24297:24;:::i;:::-;24292:3;24285:37;24210:118;;:::o;24334:105::-;24409:23;24426:5;24409:23;:::i;:::-;24404:3;24397:36;24334:105;;:::o;24445:256::-;24557:3;24572:75;24643:3;24634:6;24572:75;:::i;:::-;24672:2;24667:3;24663:12;24656:19;;24692:3;24685:10;;24445:256;;;;:::o;24707:429::-;24884:3;24906:92;24994:3;24985:6;24906:92;:::i;:::-;24899:99;;25015:95;25106:3;25097:6;25015:95;:::i;:::-;25008:102;;25127:3;25120:10;;24707:429;;;;;:::o;25142:222::-;25235:4;25273:2;25262:9;25258:18;25250:26;;25286:71;25354:1;25343:9;25339:17;25330:6;25286:71;:::i;:::-;25142:222;;;;:::o;25370:640::-;25565:4;25603:3;25592:9;25588:19;25580:27;;25617:71;25685:1;25674:9;25670:17;25661:6;25617:71;:::i;:::-;25698:72;25766:2;25755:9;25751:18;25742:6;25698:72;:::i;:::-;25780;25848:2;25837:9;25833:18;25824:6;25780:72;:::i;:::-;25899:9;25893:4;25889:20;25884:2;25873:9;25869:18;25862:48;25927:76;25998:4;25989:6;25927:76;:::i;:::-;25919:84;;25370:640;;;;;;;:::o;26016:332::-;26137:4;26175:2;26164:9;26160:18;26152:26;;26188:71;26256:1;26245:9;26241:17;26232:6;26188:71;:::i;:::-;26269:72;26337:2;26326:9;26322:18;26313:6;26269:72;:::i;:::-;26016:332;;;;;:::o;26354:501::-;26561:4;26599:2;26588:9;26584:18;26576:26;;26648:9;26642:4;26638:20;26634:1;26623:9;26619:17;26612:47;26676:172;26843:4;26834:6;26676:172;:::i;:::-;26668:180;;26354:501;;;;:::o;26861:373::-;27004:4;27042:2;27031:9;27027:18;27019:26;;27091:9;27085:4;27081:20;27077:1;27066:9;27062:17;27055:47;27119:108;27222:4;27213:6;27119:108;:::i;:::-;27111:116;;26861:373;;;;:::o;27240:210::-;27327:4;27365:2;27354:9;27350:18;27342:26;;27378:65;27440:1;27429:9;27425:17;27416:6;27378:65;:::i;:::-;27240:210;;;;:::o;27456:222::-;27549:4;27587:2;27576:9;27572:18;27564:26;;27600:71;27668:1;27657:9;27653:17;27644:6;27600:71;:::i;:::-;27456:222;;;;:::o;27684:313::-;27797:4;27835:2;27824:9;27820:18;27812:26;;27884:9;27878:4;27874:20;27870:1;27859:9;27855:17;27848:47;27912:78;27985:4;27976:6;27912:78;:::i;:::-;27904:86;;27684:313;;;;:::o;28003:419::-;28169:4;28207:2;28196:9;28192:18;28184:26;;28256:9;28250:4;28246:20;28242:1;28231:9;28227:17;28220:47;28284:131;28410:4;28284:131;:::i;:::-;28276:139;;28003:419;;;:::o;28428:::-;28594:4;28632:2;28621:9;28617:18;28609:26;;28681:9;28675:4;28671:20;28667:1;28656:9;28652:17;28645:47;28709:131;28835:4;28709:131;:::i;:::-;28701:139;;28428:419;;;:::o;28853:::-;29019:4;29057:2;29046:9;29042:18;29034:26;;29106:9;29100:4;29096:20;29092:1;29081:9;29077:17;29070:47;29134:131;29260:4;29134:131;:::i;:::-;29126:139;;28853:419;;;:::o;29278:::-;29444:4;29482:2;29471:9;29467:18;29459:26;;29531:9;29525:4;29521:20;29517:1;29506:9;29502:17;29495:47;29559:131;29685:4;29559:131;:::i;:::-;29551:139;;29278:419;;;:::o;29703:::-;29869:4;29907:2;29896:9;29892:18;29884:26;;29956:9;29950:4;29946:20;29942:1;29931:9;29927:17;29920:47;29984:131;30110:4;29984:131;:::i;:::-;29976:139;;29703:419;;;:::o;30128:::-;30294:4;30332:2;30321:9;30317:18;30309:26;;30381:9;30375:4;30371:20;30367:1;30356:9;30352:17;30345:47;30409:131;30535:4;30409:131;:::i;:::-;30401:139;;30128:419;;;:::o;30553:::-;30719:4;30757:2;30746:9;30742:18;30734:26;;30806:9;30800:4;30796:20;30792:1;30781:9;30777:17;30770:47;30834:131;30960:4;30834:131;:::i;:::-;30826:139;;30553:419;;;:::o;30978:::-;31144:4;31182:2;31171:9;31167:18;31159:26;;31231:9;31225:4;31221:20;31217:1;31206:9;31202:17;31195:47;31259:131;31385:4;31259:131;:::i;:::-;31251:139;;30978:419;;;:::o;31403:::-;31569:4;31607:2;31596:9;31592:18;31584:26;;31656:9;31650:4;31646:20;31642:1;31631:9;31627:17;31620:47;31684:131;31810:4;31684:131;:::i;:::-;31676:139;;31403:419;;;:::o;31828:::-;31994:4;32032:2;32021:9;32017:18;32009:26;;32081:9;32075:4;32071:20;32067:1;32056:9;32052:17;32045:47;32109:131;32235:4;32109:131;:::i;:::-;32101:139;;31828:419;;;:::o;32253:::-;32419:4;32457:2;32446:9;32442:18;32434:26;;32506:9;32500:4;32496:20;32492:1;32481:9;32477:17;32470:47;32534:131;32660:4;32534:131;:::i;:::-;32526:139;;32253:419;;;:::o;32678:::-;32844:4;32882:2;32871:9;32867:18;32859:26;;32931:9;32925:4;32921:20;32917:1;32906:9;32902:17;32895:47;32959:131;33085:4;32959:131;:::i;:::-;32951:139;;32678:419;;;:::o;33103:::-;33269:4;33307:2;33296:9;33292:18;33284:26;;33356:9;33350:4;33346:20;33342:1;33331:9;33327:17;33320:47;33384:131;33510:4;33384:131;:::i;:::-;33376:139;;33103:419;;;:::o;33528:::-;33694:4;33732:2;33721:9;33717:18;33709:26;;33781:9;33775:4;33771:20;33767:1;33756:9;33752:17;33745:47;33809:131;33935:4;33809:131;:::i;:::-;33801:139;;33528:419;;;:::o;33953:::-;34119:4;34157:2;34146:9;34142:18;34134:26;;34206:9;34200:4;34196:20;34192:1;34181:9;34177:17;34170:47;34234:131;34360:4;34234:131;:::i;:::-;34226:139;;33953:419;;;:::o;34378:::-;34544:4;34582:2;34571:9;34567:18;34559:26;;34631:9;34625:4;34621:20;34617:1;34606:9;34602:17;34595:47;34659:131;34785:4;34659:131;:::i;:::-;34651:139;;34378:419;;;:::o;34803:::-;34969:4;35007:2;34996:9;34992:18;34984:26;;35056:9;35050:4;35046:20;35042:1;35031:9;35027:17;35020:47;35084:131;35210:4;35084:131;:::i;:::-;35076:139;;34803:419;;;:::o;35228:::-;35394:4;35432:2;35421:9;35417:18;35409:26;;35481:9;35475:4;35471:20;35467:1;35456:9;35452:17;35445:47;35509:131;35635:4;35509:131;:::i;:::-;35501:139;;35228:419;;;:::o;35653:::-;35819:4;35857:2;35846:9;35842:18;35834:26;;35906:9;35900:4;35896:20;35892:1;35881:9;35877:17;35870:47;35934:131;36060:4;35934:131;:::i;:::-;35926:139;;35653:419;;;:::o;36078:::-;36244:4;36282:2;36271:9;36267:18;36259:26;;36331:9;36325:4;36321:20;36317:1;36306:9;36302:17;36295:47;36359:131;36485:4;36359:131;:::i;:::-;36351:139;;36078:419;;;:::o;36503:351::-;36660:4;36698:3;36687:9;36683:19;36675:27;;36712:135;36844:1;36833:9;36829:17;36820:6;36712:135;:::i;:::-;36503:351;;;;:::o;36860:222::-;36953:4;36991:2;36980:9;36976:18;36968:26;;37004:71;37072:1;37061:9;37057:17;37048:6;37004:71;:::i;:::-;36860:222;;;;:::o;37088:129::-;37122:6;37149:20;;:::i;:::-;37139:30;;37178:33;37206:4;37198:6;37178:33;:::i;:::-;37088:129;;;:::o;37223:75::-;37256:6;37289:2;37283:9;37273:19;;37223:75;:::o;37304:307::-;37365:4;37455:18;37447:6;37444:30;37441:56;;;37477:18;;:::i;:::-;37441:56;37515:29;37537:6;37515:29;:::i;:::-;37507:37;;37599:4;37593;37589:15;37581:23;;37304:307;;;:::o;37617:164::-;37716:4;37739:3;37731:11;;37769:4;37764:3;37760:14;37752:22;;37617:164;;;:::o;37787:132::-;37854:4;37877:3;37869:11;;37907:4;37902:3;37898:14;37890:22;;37787:132;;;:::o;37925:141::-;37974:4;37997:3;37989:11;;38020:3;38017:1;38010:14;38054:4;38051:1;38041:18;38033:26;;37925:141;;;:::o;38072:146::-;38171:6;38205:5;38199:12;38189:22;;38072:146;;;:::o;38224:114::-;38291:6;38325:5;38319:12;38309:22;;38224:114;;;:::o;38344:98::-;38395:6;38429:5;38423:12;38413:22;;38344:98;;;:::o;38448:99::-;38500:6;38534:5;38528:12;38518:22;;38448:99;;;:::o;38553:145::-;38655:4;38687;38682:3;38678:14;38670:22;;38553:145;;;:::o;38704:113::-;38774:4;38806;38801:3;38797:14;38789:22;;38704:113;;;:::o;38823:216::-;38954:11;38988:6;38983:3;38976:19;39028:4;39023:3;39019:14;39004:29;;38823:216;;;;:::o;39045:184::-;39144:11;39178:6;39173:3;39166:19;39218:4;39213:3;39209:14;39194:29;;39045:184;;;;:::o;39235:168::-;39318:11;39352:6;39347:3;39340:19;39392:4;39387:3;39383:14;39368:29;;39235:168;;;;:::o;39409:169::-;39493:11;39527:6;39522:3;39515:19;39567:4;39562:3;39558:14;39543:29;;39409:169;;;;:::o;39584:148::-;39686:11;39723:3;39708:18;;39584:148;;;;:::o;39738:305::-;39778:3;39797:20;39815:1;39797:20;:::i;:::-;39792:25;;39831:20;39849:1;39831:20;:::i;:::-;39826:25;;39985:1;39917:66;39913:74;39910:1;39907:81;39904:107;;;39991:18;;:::i;:::-;39904:107;40035:1;40032;40028:9;40021:16;;39738:305;;;;:::o;40049:185::-;40089:1;40106:20;40124:1;40106:20;:::i;:::-;40101:25;;40140:20;40158:1;40140:20;:::i;:::-;40135:25;;40179:1;40169:35;;40184:18;;:::i;:::-;40169:35;40226:1;40223;40219:9;40214:14;;40049:185;;;;:::o;40240:348::-;40280:7;40303:20;40321:1;40303:20;:::i;:::-;40298:25;;40337:20;40355:1;40337:20;:::i;:::-;40332:25;;40525:1;40457:66;40453:74;40450:1;40447:81;40442:1;40435:9;40428:17;40424:105;40421:131;;;40532:18;;:::i;:::-;40421:131;40580:1;40577;40573:9;40562:20;;40240:348;;;;:::o;40594:191::-;40634:4;40654:20;40672:1;40654:20;:::i;:::-;40649:25;;40688:20;40706:1;40688:20;:::i;:::-;40683:25;;40727:1;40724;40721:8;40718:34;;;40732:18;;:::i;:::-;40718:34;40777:1;40774;40770:9;40762:17;;40594:191;;;;:::o;40791:96::-;40828:7;40857:24;40875:5;40857:24;:::i;:::-;40846:35;;40791:96;;;:::o;40893:90::-;40927:7;40970:5;40963:13;40956:21;40945:32;;40893:90;;;:::o;40989:77::-;41026:7;41055:5;41044:16;;40989:77;;;:::o;41072:149::-;41108:7;41148:66;41141:5;41137:78;41126:89;;41072:149;;;:::o;41227:126::-;41264:7;41304:42;41297:5;41293:54;41282:65;;41227:126;;;:::o;41359:91::-;41395:7;41435:8;41428:5;41424:20;41413:31;;41359:91;;;:::o;41456:77::-;41493:7;41522:5;41511:16;;41456:77;;;:::o;41539:101::-;41575:7;41615:18;41608:5;41604:30;41593:41;;41539:101;;;:::o;41646:154::-;41730:6;41725:3;41720;41707:30;41792:1;41783:6;41778:3;41774:16;41767:27;41646:154;;;:::o;41806:307::-;41874:1;41884:113;41898:6;41895:1;41892:13;41884:113;;;41983:1;41978:3;41974:11;41968:18;41964:1;41959:3;41955:11;41948:39;41920:2;41917:1;41913:10;41908:15;;41884:113;;;42015:6;42012:1;42009:13;42006:101;;;42095:1;42086:6;42081:3;42077:16;42070:27;42006:101;41855:258;41806:307;;;:::o;42119:320::-;42163:6;42200:1;42194:4;42190:12;42180:22;;42247:1;42241:4;42237:12;42268:18;42258:81;;42324:4;42316:6;42312:17;42302:27;;42258:81;42386:2;42378:6;42375:14;42355:18;42352:38;42349:84;;;42405:18;;:::i;:::-;42349:84;42170:269;42119:320;;;:::o;42445:281::-;42528:27;42550:4;42528:27;:::i;:::-;42520:6;42516:40;42658:6;42646:10;42643:22;42622:18;42610:10;42607:34;42604:62;42601:88;;;42669:18;;:::i;:::-;42601:88;42709:10;42705:2;42698:22;42488:238;42445:281;;:::o;42732:233::-;42771:3;42794:24;42812:5;42794:24;:::i;:::-;42785:33;;42840:66;42833:5;42830:77;42827:103;;;42910:18;;:::i;:::-;42827:103;42957:1;42950:5;42946:13;42939:20;;42732:233;;;:::o;42971:100::-;43010:7;43039:26;43059:5;43039:26;:::i;:::-;43028:37;;42971:100;;;:::o;43077:94::-;43116:7;43145:20;43159:5;43145:20;:::i;:::-;43134:31;;43077:94;;;:::o;43177:176::-;43209:1;43226:20;43244:1;43226:20;:::i;:::-;43221:25;;43260:20;43278:1;43260:20;:::i;:::-;43255:25;;43299:1;43289:35;;43304:18;;:::i;:::-;43289:35;43345:1;43342;43338:9;43333:14;;43177:176;;;;:::o;43359:180::-;43407:77;43404:1;43397:88;43504:4;43501:1;43494:15;43528:4;43525:1;43518:15;43545:180;43593:77;43590:1;43583:88;43690:4;43687:1;43680:15;43714:4;43711:1;43704:15;43731:180;43779:77;43776:1;43769:88;43876:4;43873:1;43866:15;43900:4;43897:1;43890:15;43917:180;43965:77;43962:1;43955:88;44062:4;44059:1;44052:15;44086:4;44083:1;44076:15;44103:180;44151:77;44148:1;44141:88;44248:4;44245:1;44238:15;44272:4;44269:1;44262:15;44289:117;44398:1;44395;44388:12;44412:117;44521:1;44518;44511:12;44535:117;44644:1;44641;44634:12;44658:117;44767:1;44764;44757:12;44781:117;44890:1;44887;44880:12;44904:117;45013:1;45010;45003:12;45027:102;45068:6;45119:2;45115:7;45110:2;45103:5;45099:14;45095:28;45085:38;;45027:102;;;:::o;45135:94::-;45168:8;45216:5;45212:2;45208:14;45187:35;;45135:94;;;:::o;45235:223::-;45375:34;45371:1;45363:6;45359:14;45352:58;45444:6;45439:2;45431:6;45427:15;45420:31;45235:223;:::o;45464:176::-;45604:28;45600:1;45592:6;45588:14;45581:52;45464:176;:::o;45646:178::-;45786:30;45782:1;45774:6;45770:14;45763:54;45646:178;:::o;45830:225::-;45970:34;45966:1;45958:6;45954:14;45947:58;46039:8;46034:2;46026:6;46022:15;46015:33;45830:225;:::o;46061:179::-;46201:31;46197:1;46189:6;46185:14;46178:55;46061:179;:::o;46246:181::-;46386:33;46382:1;46374:6;46370:14;46363:57;46246:181;:::o;46433:175::-;46573:27;46569:1;46561:6;46557:14;46550:51;46433:175;:::o;46614:169::-;46754:21;46750:1;46742:6;46738:14;46731:45;46614:169;:::o;46789:181::-;46929:33;46925:1;46917:6;46913:14;46906:57;46789:181;:::o;46976:171::-;47116:23;47112:1;47104:6;47100:14;47093:47;46976:171;:::o;47153:182::-;47293:34;47289:1;47281:6;47277:14;47270:58;47153:182;:::o;47341:167::-;47481:19;47477:1;47469:6;47465:14;47458:43;47341:167;:::o;47514:170::-;47654:22;47650:1;47642:6;47638:14;47631:46;47514:170;:::o;47690:180::-;47830:32;47826:1;47818:6;47814:14;47807:56;47690:180;:::o;47876:173::-;48016:25;48012:1;48004:6;48000:14;47993:49;47876:173;:::o;48055:170::-;48195:22;48191:1;48183:6;48179:14;48172:46;48055:170;:::o;48231:169::-;48371:21;48367:1;48359:6;48355:14;48348:45;48231:169;:::o;48406:166::-;48546:18;48542:1;48534:6;48530:14;48523:42;48406:166;:::o;48578:169::-;48718:21;48714:1;48706:6;48702:14;48695:45;48578:169;:::o;48753:166::-;48893:18;48889:1;48881:6;48877:14;48870:42;48753:166;:::o;48925:122::-;48998:24;49016:5;48998:24;:::i;:::-;48991:5;48988:35;48978:63;;49037:1;49034;49027:12;48978:63;48925:122;:::o;49053:116::-;49123:21;49138:5;49123:21;:::i;:::-;49116:5;49113:32;49103:60;;49159:1;49156;49149:12;49103:60;49053:116;:::o;49175:122::-;49248:24;49266:5;49248:24;:::i;:::-;49241:5;49238:35;49228:63;;49287:1;49284;49277:12;49228:63;49175:122;:::o;49303:120::-;49375:23;49392:5;49375:23;:::i;:::-;49368:5;49365:34;49355:62;;49413:1;49410;49403:12;49355:62;49303:120;:::o;49429:122::-;49502:24;49520:5;49502:24;:::i;:::-;49495:5;49492:35;49482:63;;49541:1;49538;49531:12;49482:63;49429:122;:::o

Swarm Source

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