ETH Price: $3,013.64 (+0.02%)
Gas: 6 Gwei

Private Jet Pyjama Party Baby Owls (PJPPBABY)
 

Overview

TokenID

2310

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

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:
PJPP_Babies

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
// 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/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/Context.sol


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

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


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

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

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

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

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

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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


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

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

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


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

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

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

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


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

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: contracts/PJPP_Babies.sol



pragma solidity >=0.7.0 <0.9.0;





contract PJPP {
    function walletOfOwner(address)public view returns (uint256[] memory){}
}

contract PJPP_Babies is ERC721Enumerable, Ownable {
    using Strings for uint256;
    string public baseURI;
    string public baseExtension = ".json";
    string public notRevealedUri;
    uint256 public cost = 0.19 ether;
    uint256 public maxSupply = 6666;
    uint256 public maxSupplyFree = 3333;
    uint256 public maxSupplyPaid = 3333;
    uint256 public maxLimitPublic = 10;
    uint256 public maxWhitelistLimit = 5;
    uint256 public totalSupplyFree;
    uint256 public totalSupplyPaid;
    bool public paused = false;
    bool public revealed = false;

    mapping(address => uint256) public whiteListMinted;
    mapping(address => uint256) public publicMinted;
    mapping(address => uint256) public mintedBalance;
    mapping(uint256 => bool) public usedFemaleNfts;
    mapping(uint256 => bool) public usedMaleNfts;

    bytes32 public merkleRoot;
    bool public publicSale = false;

    PJPP maleOwlsContract = PJPP(0x3598Fff0f78Dd8b497e12a3aD91FeBcFC8F49d9E);
    PJPP femaleOwlsContract = PJPP(0xdA74Aeb14546b4272036121AeD3A97515c84F317);

    constructor(
        string memory _name,
        string memory _symbol
    ) ERC721(_name, _symbol) {
    }

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

    function setPublicSale(bool _publicSale) external onlyOwner {
        publicSale = _publicSale;
    }

    function isValidMerkleProof(bytes32[] calldata merkleProof, bytes32 root)
        internal
        view
        returns (bool)
    {
        return
            MerkleProof.verify(
                merkleProof,
                root,
                keccak256(abi.encodePacked(msg.sender))
            );
    }

    function mint(bytes32[] calldata merkleProof, uint256 _amount)
        public
        payable
    {
        require(!paused, "minting is paused");
        uint256 supply = totalSupply();
        require(supply + _amount <= maxSupply, "max NFT limit exceeded");
        if (isValidMerkleProof(merkleProof, merkleRoot)&&!publicSale) {
            uint256 freeMints = getFreeMints(msg.sender);
            uint256 whitelistMints = maxWhitelistLimit-whiteListMinted[msg.sender];
            if(freeMints+totalSupplyFree>maxSupplyFree){
                freeMints = maxSupplyFree - totalSupplyFree;
            }
            require(_amount<=freeMints+whitelistMints,"cannot mint more than limit");
            if(freeMints>0){
                if(_amount<=freeMints){
                    require(msg.value == 0, "price value should be 0 for free mint");
                    require(totalSupplyFree + _amount <= maxSupplyFree, "free NFT limit exceeded");
                    freeMints = _amount;
                }else{
                    require(totalSupplyFree + freeMints <= maxSupplyFree, "free NFT limit exceeded");
                    require(totalSupplyPaid + _amount-freeMints <= maxSupplyPaid, "NFT max limit exceeded");
                    require(_amount-freeMints <= maxWhitelistLimit, "whitelist NFT limit exceeded");
                    require(msg.value == cost * (_amount-freeMints), "pay price of nft");
                }
                mintTokens(msg.sender,_amount);
                claimTokens(msg.sender, freeMints);
                totalSupplyFree += freeMints;
                totalSupplyPaid += _amount-freeMints;
                mintedBalance[msg.sender] += _amount;
                whiteListMinted[msg.sender]+= _amount-freeMints;
            }else{
                require(msg.value == cost * _amount, "pay price of nft");
                mintTokens(msg.sender, _amount);
                totalSupplyPaid += _amount;
                whiteListMinted[msg.sender]+= _amount;
                mintedBalance[msg.sender] += _amount;
            }
        }
        else {
            require(totalSupplyPaid + _amount <= maxSupplyPaid, "NFT max limit exceeded");
            require(_amount+ publicMinted[msg.sender]<=maxLimitPublic, "cannot mint more than limit");
            require(publicSale == true, "Public sale is not open");
            require(
                publicMinted[msg.sender] + _amount <= maxLimitPublic,
                "cannot mint more than limit"
            );
            require(msg.value == cost * _amount, "pay price of nft");
            totalSupplyPaid += _amount;
            mintTokens(msg.sender, _amount);
            mintedBalance[msg.sender] += _amount;
            publicMinted[msg.sender] += _amount;
        }
    }

    function claimTokens(address _minter, uint256 _amount) internal {
        uint256[] memory maleOwls = getUnusedMaleNfts(_minter);
        uint256[] memory femaleOwls = getUnusedFemaleNfts(_minter);
        for(uint256 i=0; i<_amount; i++){
            usedMaleNfts[maleOwls[i]]=true;
            usedFemaleNfts[femaleOwls[i]]=true;
        }
    }

    function mintTokens(address _minter, uint256 _amount) internal {
        uint256 supply = totalSupply();
        for (uint256 i = 1; i <= _amount; i++) {
            _safeMint(_minter, supply + i);
        }
    }

    function getFreeMints(address _minter) public view returns(uint256){
        uint256[] memory maleOwls = getUnusedMaleNfts(_minter);
        uint256[] memory femaleOwls = getUnusedFemaleNfts(_minter);
        uint256 freeMints = 0;
        if(maleOwls.length>0&&femaleOwls.length>0){
        if(maleOwls.length<=femaleOwls.length){
            freeMints = maleOwls.length;
        }else{
            freeMints = femaleOwls.length;
        }
        }
        return freeMints;
    }

    function getWhitelistMints (address _minter)public view returns(uint256){
        return maxWhitelistLimit - whiteListMinted[_minter];
    }

    function getUnusedMaleNfts(address _minter) public view returns(uint256[] memory){
        uint256[] memory maleOwls = maleOwlsContract.walletOfOwner(_minter);
        uint256 index = 0;
        for(uint256 i=0; i<maleOwls.length; i++){
            uint256 id = maleOwls[i];
            if(!usedMaleNfts[id]){
                index++;
            }
        }

        uint256[] memory male= new uint256[](index);
        index = 0;
        for(uint256 i=0; i<maleOwls.length; i++){
            uint256 id = maleOwls[i];
            if(!usedMaleNfts[id]){
                male[index] = id;
                index++;
            }
        }
        return male;
    }

    function getUnusedFemaleNfts(address _minter) public view returns(uint256[] memory){
        uint256[] memory femaleOwls = femaleOwlsContract.walletOfOwner(_minter);
        uint256 index = 0;
        for(uint256 i=0; i<femaleOwls.length; i++){
            uint256 id = femaleOwls[i];
            if(!usedFemaleNfts[id]){
                index++;
            }
        }
        uint256[] memory female= new uint256[](index);
        index = 0;
        for(uint256 i=0; i<femaleOwls.length; i++){
            uint256 id = femaleOwls[i];
            if(!usedFemaleNfts[id]){
                female[index] = id;
                index++;
            }
        }
        return female;
    }

    function ownerMint(address _to, uint256 _mintAmount) public onlyOwner {
        uint256 supply = totalSupply();
        require(_mintAmount > 0);
        require(_mintAmount+totalSupplyFree<=maxSupplyFree,"Free mint limit exceeded");
        require(supply + _mintAmount <= maxSupply);
        totalSupplyFree += _mintAmount;
        mintedBalance[_to]+=_mintAmount;
        for (uint256 i = 1; i <= _mintAmount; i++) {
            _safeMint(_to, supply + i);
        }
    }

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

    function walletOfOwner(address _owner)
        public
        view
        returns (uint256[] memory)
    {
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory tokenIds = new uint256[](ownerTokenCount);
        for (uint256 i; i < ownerTokenCount; i++) {
            tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
        }
        return tokenIds;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        if (revealed == false) {
            return notRevealedUri;
        }

        string memory currentBaseURI = _baseURI();
        return
            bytes(currentBaseURI).length > 0
                ? string(
                    abi.encodePacked(
                        currentBaseURI,
                        tokenId.toString(),
                        baseExtension
                    )
                )
                : "";
    }

    function reveal() public onlyOwner {
        revealed = true;
    }

    function setCost(uint256 _newCost) public onlyOwner {
        cost = _newCost;
    }

    function setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }

    function setBaseExtension(string memory _newBaseExtension)
        public
        onlyOwner
    {
        baseExtension = _newBaseExtension;
    }

    function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
        notRevealedUri = _notRevealedURI;
    }

    function pause(bool _state) public onlyOwner {
        paused = _state;
    }

    function setmaxLimitPublic(uint256 _limit) public onlyOwner {
        maxLimitPublic = _limit;
    }

    function setmaxLimitWhitelist(uint256 _limit) public onlyOwner {
        maxWhitelistLimit = _limit;
    }


    function setMaxSupply(uint256 _supply) public onlyOwner {
        maxSupply = _supply;
    }

    function setMaxSupplyFree(uint256 _supply) public onlyOwner {
        maxSupplyFree = _supply;
    }


    function setMaxSupplyPaid(uint256 _supply) public onlyOwner {
        maxSupplyPaid = _supply;
    }

    function getInfo(address _minter) public view returns(uint,uint, uint,uint,uint){
        return (getFreeMints(_minter),getWhitelistMints(_minter),mintedBalance[_minter],totalSupply(),maxSupplyPaid-totalSupplyPaid);
    }

    function withdraw() public payable onlyOwner {
        uint256 amount = address(this).balance;
        require(amount > 0, "Ether balance is 0 in contract");
        payable(address(owner())).transfer(amount);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"getFreeMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"getInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"getUnusedFemaleNfts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"getUnusedMaleNfts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"getWhitelistMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLimitPublic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyFree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWhitelistLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintedBalance","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":"notRevealedUri","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":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"setMaxSupplyFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"name":"setMaxSupplyPaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_publicSale","type":"bool"}],"name":"setPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setmaxLimitPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setmaxLimitWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyFree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"usedFemaleNfts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"usedMaleNfts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whiteListMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

60c06040526005608081905264173539b7b760d91b60a09081526200002891600c919062000184565b506702a303fe4b530000600e55611a0a600f55610d056010819055601155600a60125560056013556016805461ffff19169055601d8054743598fff0f78dd8b497e12a3ad91febcfc8f49d9e006001600160a81b0319909116179055601e80546001600160a01b03191673da74aeb14546b4272036121aed3a97515c84f317179055348015620000b757600080fd5b5060405162003abc38038062003abc833981016040819052620000da91620002dd565b815182908290620000f390600090602085019062000184565b5080516200010990600190602084019062000184565b50505062000126620001206200012e60201b60201c565b62000132565b505062000397565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001929062000344565b90600052602060002090601f016020900481019282620001b6576000855562000201565b82601f10620001d157805160ff191683800117855562000201565b8280016001018555821562000201579182015b8281111562000201578251825591602001919060010190620001e4565b506200020f92915062000213565b5090565b5b808211156200020f576000815560010162000214565b600082601f8301126200023b578081fd5b81516001600160401b038082111562000258576200025862000381565b604051601f8301601f19908116603f0116810190828211818310171562000283576200028362000381565b816040528381526020925086838588010111156200029f578485fd5b8491505b83821015620002c25785820183015181830184015290820190620002a3565b83821115620002d357848385830101525b9695505050505050565b60008060408385031215620002f0578182fd5b82516001600160401b038082111562000307578384fd5b62000315868387016200022a565b935060208501519150808211156200032b578283fd5b506200033a858286016200022a565b9150509250929050565b600181811c908216806200035957607f821691505b602082108114156200037b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b61371580620003a76000396000f3fe6080604052600436106103a25760003560e01c80636352211e116101e7578063c66828621161010d578063e8405881116100a0578063f2fde38b1161006f578063f2fde38b14610a98578063f43bb15f14610ab8578063f703b77114610ae8578063ffdd5cf114610b0857600080fd5b8063e8405881146109ef578063e985e9c514610a0f578063efee356814610a58578063f2c4ce1e14610a7857600080fd5b8063d8deb591116100dc578063d8deb5911461096c578063da3ef23f14610982578063df6b6c29146109a2578063e051b416146109c257600080fd5b8063c66828621461090b578063c87b56dd14610920578063c945cf1014610940578063d5abeb011461095657600080fd5b80637cb6475911610185578063a41af60511610154578063a41af605146108a0578063a475b5dd146108c0578063b88d4fde146108d5578063c3cc4222146108f557600080fd5b80637cb647591461082d5780638da5cb5b1461084d57806395d89b411461086b578063a22cb4651461088057600080fd5b80636fff3a3b116101c15780636fff3a3b146107b857806370954de6146107d857806370a08231146107f8578063715018a61461081857600080fd5b80636352211e146107635780636c0360eb146107835780636f8b44b01461079857600080fd5b8063332543e0116102cc57806345de0d9b1161026a57806355f804b31161023957806355f804b3146106f35780635aca1bb6146107135780635ae2f02b146107335780635c975abb1461074957600080fd5b806345de0d9b14610681578063484b973c146106945780634f6ccce7146106b457806351830227146106d457600080fd5b80633ed50bb3116102a65780633ed50bb3146105e757806342842e0e14610614578063438b63001461063457806344a0d68a1461066157600080fd5b8063332543e01461059557806333bc1c5c146105c55780633ccfd60b146105df57600080fd5b806313faede6116103445780632eb4a7ab116103135780632eb4a7ab146105295780632f745c591461053f578063309aedb51461055f57806330a5ce931461057557600080fd5b806313faede6146104c857806318160ddd146104de57806323b872dd146104f35780632b45a8091461051357600080fd5b8063081812fc11610380578063081812fc14610420578063081c8c4414610458578063095ea7b31461046d5780631015805b1461048d57600080fd5b806301ffc9a7146103a757806302329a29146103dc57806306fdde03146103fe575b600080fd5b3480156103b357600080fd5b506103c76103c236600461325d565b610b50565b60405190151581526020015b60405180910390f35b3480156103e857600080fd5b506103fc6103f736600461322b565b610b7b565b005b34801561040a57600080fd5b50610413610b96565b6040516103d3919061344a565b34801561042c57600080fd5b5061044061043b366004613245565b610c28565b6040516001600160a01b0390911681526020016103d3565b34801561046457600080fd5b50610413610c4f565b34801561047957600080fd5b506103fc6104883660046130e4565b610cdd565b34801561049957600080fd5b506104ba6104a8366004612fbb565b60186020526000908152604090205481565b6040519081526020016103d3565b3480156104d457600080fd5b506104ba600e5481565b3480156104ea57600080fd5b506008546104ba565b3480156104ff57600080fd5b506103fc61050e366004613007565b610df8565b34801561051f57600080fd5b506104ba60155481565b34801561053557600080fd5b506104ba601c5481565b34801561054b57600080fd5b506104ba61055a3660046130e4565b610e29565b34801561056b57600080fd5b506104ba60105481565b34801561058157600080fd5b506103fc610590366004613245565b610ebf565b3480156105a157600080fd5b506103c76105b0366004613245565b601a6020526000908152604090205460ff1681565b3480156105d157600080fd5b50601d546103c79060ff1681565b6103fc610ecc565b3480156105f357600080fd5b506104ba610602366004612fbb565b60176020526000908152604090205481565b34801561062057600080fd5b506103fc61062f366004613007565b610f60565b34801561064057600080fd5b5061065461064f366004612fbb565b610f7b565b6040516103d39190613406565b34801561066d57600080fd5b506103fc61067c366004613245565b611039565b6103fc61068f36600461310d565b611046565b3480156106a057600080fd5b506103fc6106af3660046130e4565b6116ad565b3480156106c057600080fd5b506104ba6106cf366004613245565b6117b9565b3480156106e057600080fd5b506016546103c790610100900460ff1681565b3480156106ff57600080fd5b506103fc61070e366004613295565b61185a565b34801561071f57600080fd5b506103fc61072e36600461322b565b611875565b34801561073f57600080fd5b506104ba60145481565b34801561075557600080fd5b506016546103c79060ff1681565b34801561076f57600080fd5b5061044061077e366004613245565b611890565b34801561078f57600080fd5b506104136118f0565b3480156107a457600080fd5b506103fc6107b3366004613245565b6118fd565b3480156107c457600080fd5b506103fc6107d3366004613245565b61190a565b3480156107e457600080fd5b506104ba6107f3366004612fbb565b611917565b34801561080457600080fd5b506104ba610813366004612fbb565b61193d565b34801561082457600080fd5b506103fc6119c3565b34801561083957600080fd5b506103fc610848366004613245565b6119d7565b34801561085957600080fd5b50600a546001600160a01b0316610440565b34801561087757600080fd5b506104136119e4565b34801561088c57600080fd5b506103fc61089b3660046130bb565b6119f3565b3480156108ac57600080fd5b506106546108bb366004612fbb565b6119fe565b3480156108cc57600080fd5b506103fc611c06565b3480156108e157600080fd5b506103fc6108f0366004613042565b611c1f565b34801561090157600080fd5b506104ba60115481565b34801561091757600080fd5b50610413611c51565b34801561092c57600080fd5b5061041361093b366004613245565b611c5e565b34801561094c57600080fd5b506104ba60125481565b34801561096257600080fd5b506104ba600f5481565b34801561097857600080fd5b506104ba60135481565b34801561098e57600080fd5b506103fc61099d366004613295565b611ddd565b3480156109ae57600080fd5b506103fc6109bd366004613245565b611df8565b3480156109ce57600080fd5b506104ba6109dd366004612fbb565b60196020526000908152604090205481565b3480156109fb57600080fd5b506103fc610a0a366004613245565b611e05565b348015610a1b57600080fd5b506103c7610a2a366004612fd5565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610a6457600080fd5b506104ba610a73366004612fbb565b611e12565b348015610a8457600080fd5b506103fc610a93366004613295565b611e62565b348015610aa457600080fd5b506103fc610ab3366004612fbb565b611e7d565b348015610ac457600080fd5b506103c7610ad3366004613245565b601b6020526000908152604090205460ff1681565b348015610af457600080fd5b50610654610b03366004612fbb565b611ef6565b348015610b1457600080fd5b50610b28610b23366004612fbb565b6120ee565b604080519586526020860194909452928401919091526060830152608082015260a0016103d3565b60006001600160e01b0319821663780e9d6360e01b1480610b755750610b7582612146565b92915050565b610b83612196565b6016805460ff1916911515919091179055565b606060008054610ba59061361d565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd19061361d565b8015610c1e5780601f10610bf357610100808354040283529160200191610c1e565b820191906000526020600020905b815481529060010190602001808311610c0157829003601f168201915b5050505050905090565b6000610c33826121f0565b506000908152600460205260409020546001600160a01b031690565b600d8054610c5c9061361d565b80601f0160208091040260200160405190810160405280929190818152602001828054610c889061361d565b8015610cd55780601f10610caa57610100808354040283529160200191610cd5565b820191906000526020600020905b815481529060010190602001808311610cb857829003601f168201915b505050505081565b6000610ce882611890565b9050806001600160a01b0316836001600160a01b03161415610d5b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610d775750610d778133610a2a565b610de95760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610d52565b610df3838361224f565b505050565b610e0233826122bd565b610e1e5760405162461bcd60e51b8152600401610d5290613510565b610df383838361233b565b6000610e348361193d565b8210610e965760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d52565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610ec7612196565b601355565b610ed4612196565b4780610f225760405162461bcd60e51b815260206004820152601e60248201527f45746865722062616c616e6365206973203020696e20636f6e747261637400006044820152606401610d52565b600a546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610f5c573d6000803e3d6000fd5b5050565b610df383838360405180602001604052806000815250611c1f565b60606000610f888361193d565b905060008167ffffffffffffffff811115610fb357634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610fdc578160200160208202803683370190505b50905060005b8281101561103157610ff48582610e29565b82828151811061101457634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061102981613658565b915050610fe2565b509392505050565b611041612196565b600e55565b60165460ff161561108d5760405162461bcd60e51b81526020600482015260116024820152701b5a5b9d1a5b99c81a5cc81c185d5cd959607a1b6044820152606401610d52565b600061109860085490565b600f549091506110a8838361358f565b11156110ef5760405162461bcd60e51b81526020600482015260166024820152751b585e08139195081b1a5b5a5d08195e18d95959195960521b6044820152606401610d52565b6110fc8484601c546124e2565b801561110b5750601d5460ff16155b156114ea57600061111b33611e12565b33600090815260176020526040812054601354929350909161113d91906135da565b905060105460145483611150919061358f565b11156111695760145460105461116691906135da565b91505b611173818361358f565b8411156111925760405162461bcd60e51b8152600401610d52906134d9565b811561144d5781841161125c5734156111fb5760405162461bcd60e51b815260206004820152602560248201527f70726963652076616c75652073686f756c64206265203020666f722066726565604482015264081b5a5b9d60da1b6064820152608401610d52565b6010548460145461120c919061358f565b11156112545760405162461bcd60e51b8152602060048201526017602482015276199c995948139195081b1a5b5a5d08195e18d959591959604a1b6044820152606401610d52565b8391506113a8565b6010548260145461126d919061358f565b11156112b55760405162461bcd60e51b8152602060048201526017602482015276199c995948139195081b1a5b5a5d08195e18d959591959604a1b6044820152606401610d52565b60115482856015546112c7919061358f565b6112d191906135da565b11156113185760405162461bcd60e51b8152602060048201526016602482015275139195081b585e081b1a5b5a5d08195e18d95959195960521b6044820152606401610d52565b60135461132583866135da565b11156113735760405162461bcd60e51b815260206004820152601c60248201527f77686974656c697374204e4654206c696d6974206578636565646564000000006044820152606401610d52565b61137d82856135da565b600e5461138a91906135bb565b34146113a85760405162461bcd60e51b8152600401610d52906134af565b6113b23385612556565b6113bc338361258d565b81601460008282546113ce919061358f565b909155506113de905082856135da565b601560008282546113ef919061358f565b9091555050336000908152601960205260408120805486929061141390849061358f565b90915550611423905082856135da565b336000908152601760205260408120805490919061144290849061358f565b909155506114e39050565b83600e5461145b91906135bb565b34146114795760405162461bcd60e51b8152600401610d52906134af565b6114833385612556565b8360156000828254611495919061358f565b909155505033600090815260176020526040812080548692906114b990849061358f565b909155505033600090815260196020526040812080548692906114dd90849061358f565b90915550505b50506116a7565b601154826015546114fb919061358f565b11156115425760405162461bcd60e51b8152602060048201526016602482015275139195081b585e081b1a5b5a5d08195e18d95959195960521b6044820152606401610d52565b6012543360009081526018602052604090205461155f908461358f565b111561157d5760405162461bcd60e51b8152600401610d52906134d9565b601d5460ff1615156001146115d45760405162461bcd60e51b815260206004820152601760248201527f5075626c69632073616c65206973206e6f74206f70656e0000000000000000006044820152606401610d52565b601254336000908152601860205260409020546115f290849061358f565b11156116105760405162461bcd60e51b8152600401610d52906134d9565b81600e5461161e91906135bb565b341461163c5760405162461bcd60e51b8152600401610d52906134af565b816015600082825461164e919061358f565b9091555061165e90503383612556565b336000908152601960205260408120805484929061167d90849061358f565b909155505033600090815260186020526040812080548492906116a190849061358f565b90915550505b50505050565b6116b5612196565b60006116c060085490565b9050600082116116cf57600080fd5b6010546014546116df908461358f565b111561172d5760405162461bcd60e51b815260206004820152601860248201527f46726565206d696e74206c696d697420657863656564656400000000000000006044820152606401610d52565b600f5461173a838361358f565b111561174557600080fd5b8160146000828254611757919061358f565b90915550506001600160a01b0383166000908152601960205260408120805484929061178490849061358f565b90915550600190505b8281116116a7576117a7846117a2838561358f565b612672565b806117b181613658565b91505061178d565b60006117c460085490565b82106118275760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d52565b6008828154811061184857634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b611862612196565b8051610f5c90600b906020840190612e9e565b61187d612196565b601d805460ff1916911515919091179055565b6000818152600260205260408120546001600160a01b031680610b755760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d52565b600b8054610c5c9061361d565b611905612196565b600f55565b611912612196565b601055565b6001600160a01b038116600090815260176020526040812054601354610b7591906135da565b60006001600160a01b0382166119a75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610d52565b506001600160a01b031660009081526003602052604090205490565b6119cb612196565b6119d5600061268c565b565b6119df612196565b601c55565b606060018054610ba59061361d565b610f5c3383836126de565b601d5460405162438b6360e81b81526001600160a01b0383811660048301526060926000926101009091049091169063438b63009060240160006040518083038186803b158015611a4e57600080fd5b505afa158015611a62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a8a9190810190613183565b90506000805b8251811015611b02576000838281518110611abb57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601b90925260409091205490915060ff16611aef5782611aeb81613658565b9350505b5080611afa81613658565b915050611a90565b5060008167ffffffffffffffff811115611b2c57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b55578160200160208202803683370190505b5090506000915060005b8351811015611bfd576000848281518110611b8a57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601b90925260409091205490915060ff16611bea5780838581518110611bd157634e487b7160e01b600052603260045260246000fd5b602090810291909101015283611be681613658565b9450505b5080611bf581613658565b915050611b5f565b50949350505050565b611c0e612196565b6016805461ff001916610100179055565b611c2933836122bd565b611c455760405162461bcd60e51b8152600401610d5290613510565b6116a7848484846127ad565b600c8054610c5c9061361d565b6000818152600260205260409020546060906001600160a01b0316611cdd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610d52565b601654610100900460ff16611d7e57600d8054611cf99061361d565b80601f0160208091040260200160405190810160405280929190818152602001828054611d259061361d565b8015611d725780601f10611d4757610100808354040283529160200191611d72565b820191906000526020600020905b815481529060010190602001808311611d5557829003601f168201915b50505050509050919050565b6000611d886127e0565b90506000815111611da85760405180602001604052806000815250611dd6565b80611db2846127ef565b600c604051602001611dc693929190613307565b6040516020818303038152906040525b9392505050565b611de5612196565b8051610f5c90600c906020840190612e9e565b611e00612196565b601255565b611e0d612196565b601155565b600080611e1e836119fe565b90506000611e2b84611ef6565b90506000808351118015611e40575060008251115b15611e5a578151835111611e5657508151611e5a565b5080515b949350505050565b611e6a612196565b8051610f5c90600d906020840190612e9e565b611e85612196565b6001600160a01b038116611eea5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d52565b611ef38161268c565b50565b601e5460405162438b6360e81b81526001600160a01b03838116600483015260609260009291169063438b63009060240160006040518083038186803b158015611f3f57600080fd5b505afa158015611f53573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f7b9190810190613183565b90506000805b8251811015611ff3576000838281518110611fac57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601a90925260409091205490915060ff16611fe05782611fdc81613658565b9350505b5080611feb81613658565b915050611f81565b5060008167ffffffffffffffff81111561201d57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612046578160200160208202803683370190505b5090506000915060005b8351811015611bfd57600084828151811061207b57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601a90925260409091205490915060ff166120db57808385815181106120c257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152836120d781613658565b9450505b50806120e681613658565b915050612050565b60008060008060006120ff86611e12565b61210887611917565b6001600160a01b03881660009081526019602052604090205460085460155460115461213491906135da565b939a9299509097509550909350915050565b60006001600160e01b031982166380ac58cd60e01b148061217757506001600160e01b03198216635b5e139f60e01b145b80610b7557506301ffc9a760e01b6001600160e01b0319831614610b75565b600a546001600160a01b031633146119d55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d52565b6000818152600260205260409020546001600160a01b0316611ef35760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d52565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061228482611890565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806122c983611890565b9050806001600160a01b0316846001600160a01b0316148061231057506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611e5a5750836001600160a01b031661232984610c28565b6001600160a01b031614949350505050565b826001600160a01b031661234e82611890565b6001600160a01b0316146123b25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610d52565b6001600160a01b0382166124145760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d52565b61241f838383612909565b61242a60008261224f565b6001600160a01b03831660009081526003602052604081208054600192906124539084906135da565b90915550506001600160a01b038216600090815260036020526040812080546001929061248190849061358f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000611e5a848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516bffffffffffffffffffffffff193360601b1660208201528692506034019050604051602081830303815290604052805190602001206129c1565b600061256160085490565b905060015b8281116116a75761257b846117a2838561358f565b8061258581613658565b915050612566565b6000612598836119fe565b905060006125a584611ef6565b905060005b8381101561266b576001601b60008584815181106125d857634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601a600084848151811061262b57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550808061266390613658565b9150506125aa565b5050505050565b610f5c8282604051806020016040528060008152506129d7565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031614156127405760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d52565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6127b884848461233b565b6127c484848484612a0a565b6116a75760405162461bcd60e51b8152600401610d529061345d565b6060600b8054610ba59061361d565b6060816128135750506040805180820190915260018152600360fc1b602082015290565b8160005b811561283d578061282781613658565b91506128369050600a836135a7565b9150612817565b60008167ffffffffffffffff81111561286657634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612890576020820181803683370190505b5090505b8415611e5a576128a56001836135da565b91506128b2600a86613673565b6128bd90603061358f565b60f81b8183815181106128e057634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612902600a866135a7565b9450612894565b6001600160a01b0383166129645761295f81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612987565b816001600160a01b0316836001600160a01b031614612987576129878382612b17565b6001600160a01b03821661299e57610df381612bb4565b826001600160a01b0316826001600160a01b031614610df357610df38282612c8d565b6000826129ce8584612cd1565b14949350505050565b6129e18383612d24565b6129ee6000848484612a0a565b610df35760405162461bcd60e51b8152600401610d529061345d565b60006001600160a01b0384163b15612b0c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a4e9033908990889088906004016133c9565b602060405180830381600087803b158015612a6857600080fd5b505af1925050508015612a98575060408051601f3d908101601f19168201909252612a9591810190613279565b60015b612af2573d808015612ac6576040519150601f19603f3d011682016040523d82523d6000602084013e612acb565b606091505b508051612aea5760405162461bcd60e51b8152600401610d529061345d565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611e5a565b506001949350505050565b60006001612b248461193d565b612b2e91906135da565b600083815260076020526040902054909150808214612b81576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612bc6906001906135da565b60008381526009602052604081205460088054939450909284908110612bfc57634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508060088381548110612c2b57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612c7157634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b6000612c988361193d565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b600081815b845181101561103157612d1082868381518110612d0357634e487b7160e01b600052603260045260246000fd5b6020026020010151612e72565b915080612d1c81613658565b915050612cd6565b6001600160a01b038216612d7a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d52565b6000818152600260205260409020546001600160a01b031615612ddf5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d52565b612deb60008383612909565b6001600160a01b0382166000908152600360205260408120805460019290612e1490849061358f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000818310612e8e576000828152602084905260409020611dd6565b5060009182526020526040902090565b828054612eaa9061361d565b90600052602060002090601f016020900481019282612ecc5760008555612f12565b82601f10612ee557805160ff1916838001178555612f12565b82800160010185558215612f12579182015b82811115612f12578251825591602001919060010190612ef7565b50612f1e929150612f22565b5090565b5b80821115612f1e5760008155600101612f23565b600067ffffffffffffffff831115612f5157612f516136b3565b612f64601f8401601f191660200161355e565b9050828152838383011115612f7857600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612fa657600080fd5b919050565b80358015158114612fa657600080fd5b600060208284031215612fcc578081fd5b611dd682612f8f565b60008060408385031215612fe7578081fd5b612ff083612f8f565b9150612ffe60208401612f8f565b90509250929050565b60008060006060848603121561301b578081fd5b61302484612f8f565b925061303260208501612f8f565b9150604084013590509250925092565b60008060008060808587031215613057578081fd5b61306085612f8f565b935061306e60208601612f8f565b925060408501359150606085013567ffffffffffffffff811115613090578182fd5b8501601f810187136130a0578182fd5b6130af87823560208401612f37565b91505092959194509250565b600080604083850312156130cd578182fd5b6130d683612f8f565b9150612ffe60208401612fab565b600080604083850312156130f6578182fd5b6130ff83612f8f565b946020939093013593505050565b600080600060408486031215613121578283fd5b833567ffffffffffffffff80821115613138578485fd5b818601915086601f83011261314b578485fd5b813581811115613159578586fd5b8760208260051b850101111561316d578586fd5b6020928301989097509590910135949350505050565b60006020808385031215613195578182fd5b825167ffffffffffffffff808211156131ac578384fd5b818501915085601f8301126131bf578384fd5b8151818111156131d1576131d16136b3565b8060051b91506131e284830161355e565b8181528481019084860184860187018a10156131fc578788fd5b8795505b8386101561321e578051835260019590950194918601918601613200565b5098975050505050505050565b60006020828403121561323c578081fd5b611dd682612fab565b600060208284031215613256578081fd5b5035919050565b60006020828403121561326e578081fd5b8135611dd6816136c9565b60006020828403121561328a578081fd5b8151611dd6816136c9565b6000602082840312156132a6578081fd5b813567ffffffffffffffff8111156132bc578182fd5b8201601f810184136132cc578182fd5b611e5a84823560208401612f37565b600081518084526132f38160208601602086016135f1565b601f01601f19169290920160200192915050565b60008451602061331a8285838a016135f1565b85519184019161332d8184848a016135f1565b85549201918390600181811c908083168061334957607f831692505b85831081141561336757634e487b7160e01b88526022600452602488fd5b80801561337b576001811461338c576133b8565b60ff198516885283880195506133b8565b60008b815260209020895b858110156133b05781548a820152908401908801613397565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906133fc908301846132db565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561343e57835183529284019291840191600101613422565b50909695505050505050565b602081526000611dd660208301846132db565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f1c185e481c1c9a58d9481bd9881b999d60821b604082015260600190565b6020808252601b908201527f63616e6e6f74206d696e74206d6f7265207468616e206c696d69740000000000604082015260600190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613587576135876136b3565b604052919050565b600082198211156135a2576135a2613687565b500190565b6000826135b6576135b661369d565b500490565b60008160001904831182151516156135d5576135d5613687565b500290565b6000828210156135ec576135ec613687565b500390565b60005b8381101561360c5781810151838201526020016135f4565b838111156116a75750506000910152565b600181811c9082168061363157607f821691505b6020821081141561365257634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561366c5761366c613687565b5060010190565b6000826136825761368261369d565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114611ef357600080fdfea264697066735822122000264136630256ba27b3ae8ef0bb816f81f82f82c8d4a8ba3eb5071cd6b4dd2364736f6c63430008040033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002250726976617465204a65742050796a616d612050617274792042616279204f776c730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008504a505042414259000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103a25760003560e01c80636352211e116101e7578063c66828621161010d578063e8405881116100a0578063f2fde38b1161006f578063f2fde38b14610a98578063f43bb15f14610ab8578063f703b77114610ae8578063ffdd5cf114610b0857600080fd5b8063e8405881146109ef578063e985e9c514610a0f578063efee356814610a58578063f2c4ce1e14610a7857600080fd5b8063d8deb591116100dc578063d8deb5911461096c578063da3ef23f14610982578063df6b6c29146109a2578063e051b416146109c257600080fd5b8063c66828621461090b578063c87b56dd14610920578063c945cf1014610940578063d5abeb011461095657600080fd5b80637cb6475911610185578063a41af60511610154578063a41af605146108a0578063a475b5dd146108c0578063b88d4fde146108d5578063c3cc4222146108f557600080fd5b80637cb647591461082d5780638da5cb5b1461084d57806395d89b411461086b578063a22cb4651461088057600080fd5b80636fff3a3b116101c15780636fff3a3b146107b857806370954de6146107d857806370a08231146107f8578063715018a61461081857600080fd5b80636352211e146107635780636c0360eb146107835780636f8b44b01461079857600080fd5b8063332543e0116102cc57806345de0d9b1161026a57806355f804b31161023957806355f804b3146106f35780635aca1bb6146107135780635ae2f02b146107335780635c975abb1461074957600080fd5b806345de0d9b14610681578063484b973c146106945780634f6ccce7146106b457806351830227146106d457600080fd5b80633ed50bb3116102a65780633ed50bb3146105e757806342842e0e14610614578063438b63001461063457806344a0d68a1461066157600080fd5b8063332543e01461059557806333bc1c5c146105c55780633ccfd60b146105df57600080fd5b806313faede6116103445780632eb4a7ab116103135780632eb4a7ab146105295780632f745c591461053f578063309aedb51461055f57806330a5ce931461057557600080fd5b806313faede6146104c857806318160ddd146104de57806323b872dd146104f35780632b45a8091461051357600080fd5b8063081812fc11610380578063081812fc14610420578063081c8c4414610458578063095ea7b31461046d5780631015805b1461048d57600080fd5b806301ffc9a7146103a757806302329a29146103dc57806306fdde03146103fe575b600080fd5b3480156103b357600080fd5b506103c76103c236600461325d565b610b50565b60405190151581526020015b60405180910390f35b3480156103e857600080fd5b506103fc6103f736600461322b565b610b7b565b005b34801561040a57600080fd5b50610413610b96565b6040516103d3919061344a565b34801561042c57600080fd5b5061044061043b366004613245565b610c28565b6040516001600160a01b0390911681526020016103d3565b34801561046457600080fd5b50610413610c4f565b34801561047957600080fd5b506103fc6104883660046130e4565b610cdd565b34801561049957600080fd5b506104ba6104a8366004612fbb565b60186020526000908152604090205481565b6040519081526020016103d3565b3480156104d457600080fd5b506104ba600e5481565b3480156104ea57600080fd5b506008546104ba565b3480156104ff57600080fd5b506103fc61050e366004613007565b610df8565b34801561051f57600080fd5b506104ba60155481565b34801561053557600080fd5b506104ba601c5481565b34801561054b57600080fd5b506104ba61055a3660046130e4565b610e29565b34801561056b57600080fd5b506104ba60105481565b34801561058157600080fd5b506103fc610590366004613245565b610ebf565b3480156105a157600080fd5b506103c76105b0366004613245565b601a6020526000908152604090205460ff1681565b3480156105d157600080fd5b50601d546103c79060ff1681565b6103fc610ecc565b3480156105f357600080fd5b506104ba610602366004612fbb565b60176020526000908152604090205481565b34801561062057600080fd5b506103fc61062f366004613007565b610f60565b34801561064057600080fd5b5061065461064f366004612fbb565b610f7b565b6040516103d39190613406565b34801561066d57600080fd5b506103fc61067c366004613245565b611039565b6103fc61068f36600461310d565b611046565b3480156106a057600080fd5b506103fc6106af3660046130e4565b6116ad565b3480156106c057600080fd5b506104ba6106cf366004613245565b6117b9565b3480156106e057600080fd5b506016546103c790610100900460ff1681565b3480156106ff57600080fd5b506103fc61070e366004613295565b61185a565b34801561071f57600080fd5b506103fc61072e36600461322b565b611875565b34801561073f57600080fd5b506104ba60145481565b34801561075557600080fd5b506016546103c79060ff1681565b34801561076f57600080fd5b5061044061077e366004613245565b611890565b34801561078f57600080fd5b506104136118f0565b3480156107a457600080fd5b506103fc6107b3366004613245565b6118fd565b3480156107c457600080fd5b506103fc6107d3366004613245565b61190a565b3480156107e457600080fd5b506104ba6107f3366004612fbb565b611917565b34801561080457600080fd5b506104ba610813366004612fbb565b61193d565b34801561082457600080fd5b506103fc6119c3565b34801561083957600080fd5b506103fc610848366004613245565b6119d7565b34801561085957600080fd5b50600a546001600160a01b0316610440565b34801561087757600080fd5b506104136119e4565b34801561088c57600080fd5b506103fc61089b3660046130bb565b6119f3565b3480156108ac57600080fd5b506106546108bb366004612fbb565b6119fe565b3480156108cc57600080fd5b506103fc611c06565b3480156108e157600080fd5b506103fc6108f0366004613042565b611c1f565b34801561090157600080fd5b506104ba60115481565b34801561091757600080fd5b50610413611c51565b34801561092c57600080fd5b5061041361093b366004613245565b611c5e565b34801561094c57600080fd5b506104ba60125481565b34801561096257600080fd5b506104ba600f5481565b34801561097857600080fd5b506104ba60135481565b34801561098e57600080fd5b506103fc61099d366004613295565b611ddd565b3480156109ae57600080fd5b506103fc6109bd366004613245565b611df8565b3480156109ce57600080fd5b506104ba6109dd366004612fbb565b60196020526000908152604090205481565b3480156109fb57600080fd5b506103fc610a0a366004613245565b611e05565b348015610a1b57600080fd5b506103c7610a2a366004612fd5565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b348015610a6457600080fd5b506104ba610a73366004612fbb565b611e12565b348015610a8457600080fd5b506103fc610a93366004613295565b611e62565b348015610aa457600080fd5b506103fc610ab3366004612fbb565b611e7d565b348015610ac457600080fd5b506103c7610ad3366004613245565b601b6020526000908152604090205460ff1681565b348015610af457600080fd5b50610654610b03366004612fbb565b611ef6565b348015610b1457600080fd5b50610b28610b23366004612fbb565b6120ee565b604080519586526020860194909452928401919091526060830152608082015260a0016103d3565b60006001600160e01b0319821663780e9d6360e01b1480610b755750610b7582612146565b92915050565b610b83612196565b6016805460ff1916911515919091179055565b606060008054610ba59061361d565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd19061361d565b8015610c1e5780601f10610bf357610100808354040283529160200191610c1e565b820191906000526020600020905b815481529060010190602001808311610c0157829003601f168201915b5050505050905090565b6000610c33826121f0565b506000908152600460205260409020546001600160a01b031690565b600d8054610c5c9061361d565b80601f0160208091040260200160405190810160405280929190818152602001828054610c889061361d565b8015610cd55780601f10610caa57610100808354040283529160200191610cd5565b820191906000526020600020905b815481529060010190602001808311610cb857829003601f168201915b505050505081565b6000610ce882611890565b9050806001600160a01b0316836001600160a01b03161415610d5b5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b0382161480610d775750610d778133610a2a565b610de95760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610d52565b610df3838361224f565b505050565b610e0233826122bd565b610e1e5760405162461bcd60e51b8152600401610d5290613510565b610df383838361233b565b6000610e348361193d565b8210610e965760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d52565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610ec7612196565b601355565b610ed4612196565b4780610f225760405162461bcd60e51b815260206004820152601e60248201527f45746865722062616c616e6365206973203020696e20636f6e747261637400006044820152606401610d52565b600a546040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015610f5c573d6000803e3d6000fd5b5050565b610df383838360405180602001604052806000815250611c1f565b60606000610f888361193d565b905060008167ffffffffffffffff811115610fb357634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610fdc578160200160208202803683370190505b50905060005b8281101561103157610ff48582610e29565b82828151811061101457634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061102981613658565b915050610fe2565b509392505050565b611041612196565b600e55565b60165460ff161561108d5760405162461bcd60e51b81526020600482015260116024820152701b5a5b9d1a5b99c81a5cc81c185d5cd959607a1b6044820152606401610d52565b600061109860085490565b600f549091506110a8838361358f565b11156110ef5760405162461bcd60e51b81526020600482015260166024820152751b585e08139195081b1a5b5a5d08195e18d95959195960521b6044820152606401610d52565b6110fc8484601c546124e2565b801561110b5750601d5460ff16155b156114ea57600061111b33611e12565b33600090815260176020526040812054601354929350909161113d91906135da565b905060105460145483611150919061358f565b11156111695760145460105461116691906135da565b91505b611173818361358f565b8411156111925760405162461bcd60e51b8152600401610d52906134d9565b811561144d5781841161125c5734156111fb5760405162461bcd60e51b815260206004820152602560248201527f70726963652076616c75652073686f756c64206265203020666f722066726565604482015264081b5a5b9d60da1b6064820152608401610d52565b6010548460145461120c919061358f565b11156112545760405162461bcd60e51b8152602060048201526017602482015276199c995948139195081b1a5b5a5d08195e18d959591959604a1b6044820152606401610d52565b8391506113a8565b6010548260145461126d919061358f565b11156112b55760405162461bcd60e51b8152602060048201526017602482015276199c995948139195081b1a5b5a5d08195e18d959591959604a1b6044820152606401610d52565b60115482856015546112c7919061358f565b6112d191906135da565b11156113185760405162461bcd60e51b8152602060048201526016602482015275139195081b585e081b1a5b5a5d08195e18d95959195960521b6044820152606401610d52565b60135461132583866135da565b11156113735760405162461bcd60e51b815260206004820152601c60248201527f77686974656c697374204e4654206c696d6974206578636565646564000000006044820152606401610d52565b61137d82856135da565b600e5461138a91906135bb565b34146113a85760405162461bcd60e51b8152600401610d52906134af565b6113b23385612556565b6113bc338361258d565b81601460008282546113ce919061358f565b909155506113de905082856135da565b601560008282546113ef919061358f565b9091555050336000908152601960205260408120805486929061141390849061358f565b90915550611423905082856135da565b336000908152601760205260408120805490919061144290849061358f565b909155506114e39050565b83600e5461145b91906135bb565b34146114795760405162461bcd60e51b8152600401610d52906134af565b6114833385612556565b8360156000828254611495919061358f565b909155505033600090815260176020526040812080548692906114b990849061358f565b909155505033600090815260196020526040812080548692906114dd90849061358f565b90915550505b50506116a7565b601154826015546114fb919061358f565b11156115425760405162461bcd60e51b8152602060048201526016602482015275139195081b585e081b1a5b5a5d08195e18d95959195960521b6044820152606401610d52565b6012543360009081526018602052604090205461155f908461358f565b111561157d5760405162461bcd60e51b8152600401610d52906134d9565b601d5460ff1615156001146115d45760405162461bcd60e51b815260206004820152601760248201527f5075626c69632073616c65206973206e6f74206f70656e0000000000000000006044820152606401610d52565b601254336000908152601860205260409020546115f290849061358f565b11156116105760405162461bcd60e51b8152600401610d52906134d9565b81600e5461161e91906135bb565b341461163c5760405162461bcd60e51b8152600401610d52906134af565b816015600082825461164e919061358f565b9091555061165e90503383612556565b336000908152601960205260408120805484929061167d90849061358f565b909155505033600090815260186020526040812080548492906116a190849061358f565b90915550505b50505050565b6116b5612196565b60006116c060085490565b9050600082116116cf57600080fd5b6010546014546116df908461358f565b111561172d5760405162461bcd60e51b815260206004820152601860248201527f46726565206d696e74206c696d697420657863656564656400000000000000006044820152606401610d52565b600f5461173a838361358f565b111561174557600080fd5b8160146000828254611757919061358f565b90915550506001600160a01b0383166000908152601960205260408120805484929061178490849061358f565b90915550600190505b8281116116a7576117a7846117a2838561358f565b612672565b806117b181613658565b91505061178d565b60006117c460085490565b82106118275760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d52565b6008828154811061184857634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b611862612196565b8051610f5c90600b906020840190612e9e565b61187d612196565b601d805460ff1916911515919091179055565b6000818152600260205260408120546001600160a01b031680610b755760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d52565b600b8054610c5c9061361d565b611905612196565b600f55565b611912612196565b601055565b6001600160a01b038116600090815260176020526040812054601354610b7591906135da565b60006001600160a01b0382166119a75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610d52565b506001600160a01b031660009081526003602052604090205490565b6119cb612196565b6119d5600061268c565b565b6119df612196565b601c55565b606060018054610ba59061361d565b610f5c3383836126de565b601d5460405162438b6360e81b81526001600160a01b0383811660048301526060926000926101009091049091169063438b63009060240160006040518083038186803b158015611a4e57600080fd5b505afa158015611a62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a8a9190810190613183565b90506000805b8251811015611b02576000838281518110611abb57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601b90925260409091205490915060ff16611aef5782611aeb81613658565b9350505b5080611afa81613658565b915050611a90565b5060008167ffffffffffffffff811115611b2c57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b55578160200160208202803683370190505b5090506000915060005b8351811015611bfd576000848281518110611b8a57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601b90925260409091205490915060ff16611bea5780838581518110611bd157634e487b7160e01b600052603260045260246000fd5b602090810291909101015283611be681613658565b9450505b5080611bf581613658565b915050611b5f565b50949350505050565b611c0e612196565b6016805461ff001916610100179055565b611c2933836122bd565b611c455760405162461bcd60e51b8152600401610d5290613510565b6116a7848484846127ad565b600c8054610c5c9061361d565b6000818152600260205260409020546060906001600160a01b0316611cdd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610d52565b601654610100900460ff16611d7e57600d8054611cf99061361d565b80601f0160208091040260200160405190810160405280929190818152602001828054611d259061361d565b8015611d725780601f10611d4757610100808354040283529160200191611d72565b820191906000526020600020905b815481529060010190602001808311611d5557829003601f168201915b50505050509050919050565b6000611d886127e0565b90506000815111611da85760405180602001604052806000815250611dd6565b80611db2846127ef565b600c604051602001611dc693929190613307565b6040516020818303038152906040525b9392505050565b611de5612196565b8051610f5c90600c906020840190612e9e565b611e00612196565b601255565b611e0d612196565b601155565b600080611e1e836119fe565b90506000611e2b84611ef6565b90506000808351118015611e40575060008251115b15611e5a578151835111611e5657508151611e5a565b5080515b949350505050565b611e6a612196565b8051610f5c90600d906020840190612e9e565b611e85612196565b6001600160a01b038116611eea5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d52565b611ef38161268c565b50565b601e5460405162438b6360e81b81526001600160a01b03838116600483015260609260009291169063438b63009060240160006040518083038186803b158015611f3f57600080fd5b505afa158015611f53573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f7b9190810190613183565b90506000805b8251811015611ff3576000838281518110611fac57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601a90925260409091205490915060ff16611fe05782611fdc81613658565b9350505b5080611feb81613658565b915050611f81565b5060008167ffffffffffffffff81111561201d57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612046578160200160208202803683370190505b5090506000915060005b8351811015611bfd57600084828151811061207b57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516000818152601a90925260409091205490915060ff166120db57808385815181106120c257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152836120d781613658565b9450505b50806120e681613658565b915050612050565b60008060008060006120ff86611e12565b61210887611917565b6001600160a01b03881660009081526019602052604090205460085460155460115461213491906135da565b939a9299509097509550909350915050565b60006001600160e01b031982166380ac58cd60e01b148061217757506001600160e01b03198216635b5e139f60e01b145b80610b7557506301ffc9a760e01b6001600160e01b0319831614610b75565b600a546001600160a01b031633146119d55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610d52565b6000818152600260205260409020546001600160a01b0316611ef35760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610d52565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061228482611890565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806122c983611890565b9050806001600160a01b0316846001600160a01b0316148061231057506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80611e5a5750836001600160a01b031661232984610c28565b6001600160a01b031614949350505050565b826001600160a01b031661234e82611890565b6001600160a01b0316146123b25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610d52565b6001600160a01b0382166124145760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d52565b61241f838383612909565b61242a60008261224f565b6001600160a01b03831660009081526003602052604081208054600192906124539084906135da565b90915550506001600160a01b038216600090815260036020526040812080546001929061248190849061358f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000611e5a848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040516bffffffffffffffffffffffff193360601b1660208201528692506034019050604051602081830303815290604052805190602001206129c1565b600061256160085490565b905060015b8281116116a75761257b846117a2838561358f565b8061258581613658565b915050612566565b6000612598836119fe565b905060006125a584611ef6565b905060005b8381101561266b576001601b60008584815181106125d857634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff0219169083151502179055506001601a600084848151811061262b57634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550808061266390613658565b9150506125aa565b5050505050565b610f5c8282604051806020016040528060008152506129d7565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031614156127405760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d52565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6127b884848461233b565b6127c484848484612a0a565b6116a75760405162461bcd60e51b8152600401610d529061345d565b6060600b8054610ba59061361d565b6060816128135750506040805180820190915260018152600360fc1b602082015290565b8160005b811561283d578061282781613658565b91506128369050600a836135a7565b9150612817565b60008167ffffffffffffffff81111561286657634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612890576020820181803683370190505b5090505b8415611e5a576128a56001836135da565b91506128b2600a86613673565b6128bd90603061358f565b60f81b8183815181106128e057634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612902600a866135a7565b9450612894565b6001600160a01b0383166129645761295f81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612987565b816001600160a01b0316836001600160a01b031614612987576129878382612b17565b6001600160a01b03821661299e57610df381612bb4565b826001600160a01b0316826001600160a01b031614610df357610df38282612c8d565b6000826129ce8584612cd1565b14949350505050565b6129e18383612d24565b6129ee6000848484612a0a565b610df35760405162461bcd60e51b8152600401610d529061345d565b60006001600160a01b0384163b15612b0c57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a4e9033908990889088906004016133c9565b602060405180830381600087803b158015612a6857600080fd5b505af1925050508015612a98575060408051601f3d908101601f19168201909252612a9591810190613279565b60015b612af2573d808015612ac6576040519150601f19603f3d011682016040523d82523d6000602084013e612acb565b606091505b508051612aea5760405162461bcd60e51b8152600401610d529061345d565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611e5a565b506001949350505050565b60006001612b248461193d565b612b2e91906135da565b600083815260076020526040902054909150808214612b81576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612bc6906001906135da565b60008381526009602052604081205460088054939450909284908110612bfc57634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508060088381548110612c2b57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612c7157634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b6000612c988361193d565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b600081815b845181101561103157612d1082868381518110612d0357634e487b7160e01b600052603260045260246000fd5b6020026020010151612e72565b915080612d1c81613658565b915050612cd6565b6001600160a01b038216612d7a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d52565b6000818152600260205260409020546001600160a01b031615612ddf5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d52565b612deb60008383612909565b6001600160a01b0382166000908152600360205260408120805460019290612e1490849061358f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000818310612e8e576000828152602084905260409020611dd6565b5060009182526020526040902090565b828054612eaa9061361d565b90600052602060002090601f016020900481019282612ecc5760008555612f12565b82601f10612ee557805160ff1916838001178555612f12565b82800160010185558215612f12579182015b82811115612f12578251825591602001919060010190612ef7565b50612f1e929150612f22565b5090565b5b80821115612f1e5760008155600101612f23565b600067ffffffffffffffff831115612f5157612f516136b3565b612f64601f8401601f191660200161355e565b9050828152838383011115612f7857600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612fa657600080fd5b919050565b80358015158114612fa657600080fd5b600060208284031215612fcc578081fd5b611dd682612f8f565b60008060408385031215612fe7578081fd5b612ff083612f8f565b9150612ffe60208401612f8f565b90509250929050565b60008060006060848603121561301b578081fd5b61302484612f8f565b925061303260208501612f8f565b9150604084013590509250925092565b60008060008060808587031215613057578081fd5b61306085612f8f565b935061306e60208601612f8f565b925060408501359150606085013567ffffffffffffffff811115613090578182fd5b8501601f810187136130a0578182fd5b6130af87823560208401612f37565b91505092959194509250565b600080604083850312156130cd578182fd5b6130d683612f8f565b9150612ffe60208401612fab565b600080604083850312156130f6578182fd5b6130ff83612f8f565b946020939093013593505050565b600080600060408486031215613121578283fd5b833567ffffffffffffffff80821115613138578485fd5b818601915086601f83011261314b578485fd5b813581811115613159578586fd5b8760208260051b850101111561316d578586fd5b6020928301989097509590910135949350505050565b60006020808385031215613195578182fd5b825167ffffffffffffffff808211156131ac578384fd5b818501915085601f8301126131bf578384fd5b8151818111156131d1576131d16136b3565b8060051b91506131e284830161355e565b8181528481019084860184860187018a10156131fc578788fd5b8795505b8386101561321e578051835260019590950194918601918601613200565b5098975050505050505050565b60006020828403121561323c578081fd5b611dd682612fab565b600060208284031215613256578081fd5b5035919050565b60006020828403121561326e578081fd5b8135611dd6816136c9565b60006020828403121561328a578081fd5b8151611dd6816136c9565b6000602082840312156132a6578081fd5b813567ffffffffffffffff8111156132bc578182fd5b8201601f810184136132cc578182fd5b611e5a84823560208401612f37565b600081518084526132f38160208601602086016135f1565b601f01601f19169290920160200192915050565b60008451602061331a8285838a016135f1565b85519184019161332d8184848a016135f1565b85549201918390600181811c908083168061334957607f831692505b85831081141561336757634e487b7160e01b88526022600452602488fd5b80801561337b576001811461338c576133b8565b60ff198516885283880195506133b8565b60008b815260209020895b858110156133b05781548a820152908401908801613397565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906133fc908301846132db565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b8181101561343e57835183529284019291840191600101613422565b50909695505050505050565b602081526000611dd660208301846132db565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f1c185e481c1c9a58d9481bd9881b999d60821b604082015260600190565b6020808252601b908201527f63616e6e6f74206d696e74206d6f7265207468616e206c696d69740000000000604082015260600190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613587576135876136b3565b604052919050565b600082198211156135a2576135a2613687565b500190565b6000826135b6576135b661369d565b500490565b60008160001904831182151516156135d5576135d5613687565b500290565b6000828210156135ec576135ec613687565b500390565b60005b8381101561360c5781810151838201526020016135f4565b838111156116a75750506000910152565b600181811c9082168061363157607f821691505b6020821081141561365257634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561366c5761366c613687565b5060010190565b6000826136825761368261369d565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114611ef357600080fdfea264697066735822122000264136630256ba27b3ae8ef0bb816f81f82f82c8d4a8ba3eb5071cd6b4dd2364736f6c63430008040033

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

000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002250726976617465204a65742050796a616d612050617274792042616279204f776c730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008504a505042414259000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Private Jet Pyjama Party Baby Owls
Arg [1] : _symbol (string): PJPPBABY

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000022
Arg [3] : 50726976617465204a65742050796a616d612050617274792042616279204f77
Arg [4] : 6c73000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [6] : 504a505042414259000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

55100:10644:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48768:224;;;;;;;;;;-1:-1:-1;48768:224:0;;;;;:::i;:::-;;:::i;:::-;;;9699:14:1;;9692:22;9674:41;;9662:2;9647:18;48768:224:0;;;;;;;;64652:79;;;;;;;;;;-1:-1:-1;64652:79:0;;;;;:::i;:::-;;:::i;:::-;;35502:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;37015:171::-;;;;;;;;;;-1:-1:-1;37015:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;8357:32:1;;;8339:51;;8327:2;8312:18;37015:171:0;8294:102:1;55261:28:0;;;;;;;;;;;;;:::i;36532:417::-;;;;;;;;;;-1:-1:-1;36532:417:0;;;;;:::i;:::-;;:::i;55742:47::-;;;;;;;;;;-1:-1:-1;55742:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;9872:25:1;;;9860:2;9845:18;55742:47:0;9827:76:1;55296:32:0;;;;;;;;;;;;;;;;49408:113;;;;;;;;;;-1:-1:-1;49496:10:0;:17;49408:113;;37715:336;;;;;;;;;;-1:-1:-1;37715:336:0;;;;;:::i;:::-;;:::i;55578:30::-;;;;;;;;;;;;;;;;55957:25;;;;;;;;;;;;;;;;49076:256;;;;;;;;;;-1:-1:-1;49076:256:0;;;;;:::i;:::-;;:::i;55373:35::-;;;;;;;;;;;;;;;;64849:108;;;;;;;;;;-1:-1:-1;64849:108:0;;;;;:::i;:::-;;:::i;55851:46::-;;;;;;;;;;-1:-1:-1;55851:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;55989:30;;;;;;;;;;-1:-1:-1;55989:30:0;;;;;;;;65522:219;;;:::i;55685:50::-;;;;;;;;;;-1:-1:-1;55685:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;38122:185;;;;;;;;;;-1:-1:-1;38122:185:0;;;;;:::i;:::-;;:::i;62945:390::-;;;;;;;;;;-1:-1:-1;62945:390:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;64153:86::-;;;;;;;;;;-1:-1:-1;64153:86:0;;;;;:::i;:::-;;:::i;56863:2821::-;;;;;;:::i;:::-;;:::i;62338:485::-;;;;;;;;;;-1:-1:-1;62338:485:0;;;;;:::i;:::-;;:::i;49598:233::-;;;;;;;;;;-1:-1:-1;49598:233:0;;;;;:::i;:::-;;:::i;55648:28::-;;;;;;;;;;-1:-1:-1;55648:28:0;;;;;;;;;;;64247:104;;;;;;;;;;-1:-1:-1;64247:104:0;;;;;:::i;:::-;;:::i;56426:103::-;;;;;;;;;;-1:-1:-1;56426:103:0;;;;;:::i;:::-;;:::i;55541:30::-;;;;;;;;;;;;;;;;55615:26;;;;;;;;;;-1:-1:-1;55615:26:0;;;;;;;;35213:222;;;;;;;;;;-1:-1:-1;35213:222:0;;;;;:::i;:::-;;:::i;55189:21::-;;;;;;;;;;;;;:::i;64967:94::-;;;;;;;;;;-1:-1:-1;64967:94:0;;;;;:::i;:::-;;:::i;65069:102::-;;;;;;;;;;-1:-1:-1;65069:102:0;;;;;:::i;:::-;;:::i;60782:142::-;;;;;;;;;;-1:-1:-1;60782:142:0;;;;;:::i;:::-;;:::i;34944:207::-;;;;;;;;;;-1:-1:-1;34944:207:0;;;;;:::i;:::-;;:::i;14031:103::-;;;;;;;;;;;;;:::i;62831:106::-;;;;;;;;;;-1:-1:-1;62831:106:0;;;;;:::i;:::-;;:::i;13383:87::-;;;;;;;;;;-1:-1:-1;13456:6:0;;-1:-1:-1;;;;;13456:6:0;13383:87;;35671:104;;;;;;;;;;;;;:::i;37258:155::-;;;;;;;;;;-1:-1:-1;37258:155:0;;;;;:::i;:::-;;:::i;60932:684::-;;;;;;;;;;-1:-1:-1;60932:684:0;;;;;:::i;:::-;;:::i;64076:69::-;;;;;;;;;;;;;:::i;38378:323::-;;;;;;;;;;-1:-1:-1;38378:323:0;;;;;:::i;:::-;;:::i;55415:35::-;;;;;;;;;;;;;;;;55217:37;;;;;;;;;;;;;:::i;63343:725::-;;;;;;;;;;-1:-1:-1;63343:725:0;;;;;:::i;:::-;;:::i;55457:34::-;;;;;;;;;;;;;;;;55335:31;;;;;;;;;;;;;;;;55498:36;;;;;;;;;;;;;;;;64359:151;;;;;;;;;;-1:-1:-1;64359:151:0;;;;;:::i;:::-;;:::i;64739:102::-;;;;;;;;;;-1:-1:-1;64739:102:0;;;;;:::i;:::-;;:::i;55796:48::-;;;;;;;;;;-1:-1:-1;55796:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;65181:102;;;;;;;;;;-1:-1:-1;65181:102:0;;;;;:::i;:::-;;:::i;37484:164::-;;;;;;;;;;-1:-1:-1;37484:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;37605:25:0;;;37581:4;37605:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;37484:164;60280:494;;;;;;;;;;-1:-1:-1;60280:494:0;;;;;:::i;:::-;;:::i;64518:126::-;;;;;;;;;;-1:-1:-1;64518:126:0;;;;;:::i;:::-;;:::i;14289:201::-;;;;;;;;;;-1:-1:-1;14289:201:0;;;;;:::i;:::-;;:::i;55904:44::-;;;;;;;;;;-1:-1:-1;55904:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;61624:706;;;;;;;;;;-1:-1:-1;61624:706:0;;;;;:::i;:::-;;:::i;65291:223::-;;;;;;;;;;-1:-1:-1;65291:223:0;;;;;:::i;:::-;;:::i;:::-;;;;20823:25:1;;;20879:2;20864:18;;20857:34;;;;20907:18;;;20900:34;;;;20965:2;20950:18;;20943:34;21008:3;20993:19;;20986:35;20810:3;20795:19;65291:223:0;20777:250:1;48768:224:0;48870:4;-1:-1:-1;;;;;;48894:50:0;;-1:-1:-1;;;48894:50:0;;:90;;;48948:36;48972:11;48948:23;:36::i;:::-;48887:97;48768:224;-1:-1:-1;;48768:224:0:o;64652:79::-;13269:13;:11;:13::i;:::-;64708:6:::1;:15:::0;;-1:-1:-1;;64708:15:0::1;::::0;::::1;;::::0;;;::::1;::::0;;64652:79::o;35502:100::-;35556:13;35589:5;35582:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35502:100;:::o;37015:171::-;37091:7;37111:23;37126:7;37111:14;:23::i;:::-;-1:-1:-1;37154:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;37154:24:0;;37015:171::o;55261:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;36532:417::-;36613:13;36629:23;36644:7;36629:14;:23::i;:::-;36613:39;;36677:5;-1:-1:-1;;;;;36671:11:0;:2;-1:-1:-1;;;;;36671:11:0;;;36663:57;;;;-1:-1:-1;;;36663:57:0;;17597:2:1;36663:57:0;;;17579:21:1;17636:2;17616:18;;;17609:30;17675:34;17655:18;;;17648:62;-1:-1:-1;;;17726:18:1;;;17719:31;17767:19;;36663:57:0;;;;;;;;;12014:10;-1:-1:-1;;;;;36755:21:0;;;;:62;;-1:-1:-1;36780:37:0;36797:5;12014:10;37484:164;:::i;36780:37::-;36733:174;;;;-1:-1:-1;;;36733:174:0;;15318:2:1;36733:174:0;;;15300:21:1;15357:2;15337:18;;;15330:30;15396:34;15376:18;;;15369:62;15467:32;15447:18;;;15440:60;15517:19;;36733:174:0;15290:252:1;36733:174:0;36920:21;36929:2;36933:7;36920:8;:21::i;:::-;36532:417;;;:::o;37715:336::-;37910:41;12014:10;37943:7;37910:18;:41::i;:::-;37902:100;;;;-1:-1:-1;;;37902:100:0;;;;;;;:::i;:::-;38015:28;38025:4;38031:2;38035:7;38015:9;:28::i;49076:256::-;49173:7;49209:23;49226:5;49209:16;:23::i;:::-;49201:5;:31;49193:87;;;;-1:-1:-1;;;49193:87:0;;10334:2:1;49193:87:0;;;10316:21:1;10373:2;10353:18;;;10346:30;10412:34;10392:18;;;10385:62;-1:-1:-1;;;10463:18:1;;;10456:41;10514:19;;49193:87:0;10306:233:1;49193:87:0;-1:-1:-1;;;;;;49298:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;49076:256::o;64849:108::-;13269:13;:11;:13::i;:::-;64923:17:::1;:26:::0;64849:108::o;65522:219::-;13269:13;:11;:13::i;:::-;65595:21:::1;65635:10:::0;65627:53:::1;;;::::0;-1:-1:-1;;;65627:53:0;;14608:2:1;65627:53:0::1;::::0;::::1;14590:21:1::0;14647:2;14627:18;;;14620:30;14686:32;14666:18;;;14659:60;14736:18;;65627:53:0::1;14580:180:1::0;65627:53:0::1;13456:6:::0;;65691:42:::1;::::0;-1:-1:-1;;;;;13456:6:0;;;;65691:42;::::1;;;::::0;65726:6;;65691:42:::1;::::0;;;65726:6;13456;65691:42;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;13293:1;65522:219::o:0;38122:185::-;38260:39;38277:4;38283:2;38287:7;38260:39;;;;;;;;;;;;:16;:39::i;62945:390::-;63032:16;63066:23;63092:17;63102:6;63092:9;:17::i;:::-;63066:43;;63120:25;63162:15;63148:30;;;;;;-1:-1:-1;;;63148:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63148:30:0;;63120:58;;63194:9;63189:113;63209:15;63205:1;:19;63189:113;;;63260:30;63280:6;63288:1;63260:19;:30::i;:::-;63246:8;63255:1;63246:11;;;;;;-1:-1:-1;;;63246:11:0;;;;;;;;;;;;;;;;;;:44;63226:3;;;;:::i;:::-;;;;63189:113;;;-1:-1:-1;63319:8:0;62945:390;-1:-1:-1;;;62945:390:0:o;64153:86::-;13269:13;:11;:13::i;:::-;64216:4:::1;:15:::0;64153:86::o;56863:2821::-;56984:6;;;;56983:7;56975:37;;;;-1:-1:-1;;;56975:37:0;;17999:2:1;56975:37:0;;;17981:21:1;18038:2;18018:18;;;18011:30;-1:-1:-1;;;18057:18:1;;;18050:47;18114:18;;56975:37:0;17971:167:1;56975:37:0;57023:14;57040:13;49496:10;:17;;49408:113;57040:13;57092:9;;57023:30;;-1:-1:-1;57072:16:0;57081:7;57023:30;57072:16;:::i;:::-;:29;;57064:64;;;;-1:-1:-1;;;57064:64:0;;14967:2:1;57064:64:0;;;14949:21:1;15006:2;14986:18;;;14979:30;-1:-1:-1;;;15025:18:1;;;15018:52;15087:18;;57064:64:0;14939:172:1;57064:64:0;57143:43;57162:11;;57175:10;;57143:18;:43::i;:::-;:56;;;;-1:-1:-1;57189:10:0;;;;57188:11;57143:56;57139:2538;;;57216:17;57236:24;57249:10;57236:12;:24::i;:::-;57334:10;57275:22;57318:27;;;:15;:27;;;;;;57300:17;;57216:44;;-1:-1:-1;57275:22:0;;57300:45;;57318:27;57300:45;:::i;:::-;57275:70;;57389:13;;57373:15;;57363:9;:25;;;;:::i;:::-;:39;57360:121;;;57450:15;;57434:13;;:31;;;;:::i;:::-;57422:43;;57360:121;57512:24;57522:14;57512:9;:24;:::i;:::-;57503:7;:33;;57495:72;;;;-1:-1:-1;;;57495:72:0;;;;;;;:::i;:::-;57585:11;;57582:1377;;57628:9;57619:7;:18;57616:702;;57669:9;:14;57661:64;;;;-1:-1:-1;;;57661:64:0;;13439:2:1;57661:64:0;;;13421:21:1;13478:2;13458:18;;;13451:30;13517:34;13497:18;;;13490:62;-1:-1:-1;;;13568:18:1;;;13561:35;13613:19;;57661:64:0;13411:227:1;57661:64:0;57785:13;;57774:7;57756:15;;:25;;;;:::i;:::-;:42;;57748:78;;;;-1:-1:-1;;;57748:78:0;;19465:2:1;57748:78:0;;;19447:21:1;19504:2;19484:18;;;19477:30;-1:-1:-1;;;19523:18:1;;;19516:53;19586:18;;57748:78:0;19437:173:1;57748:78:0;57861:7;57849:19;;57616:702;;;57954:13;;57941:9;57923:15;;:27;;;;:::i;:::-;:44;;57915:80;;;;-1:-1:-1;;;57915:80:0;;19465:2:1;57915:80:0;;;19447:21:1;19504:2;19484:18;;;19477:30;-1:-1:-1;;;19523:18:1;;;19516:53;19586:18;;57915:80:0;19437:173:1;57915:80:0;58065:13;;58052:9;58044:7;58026:15;;:25;;;;:::i;:::-;:35;;;;:::i;:::-;:52;;58018:87;;;;-1:-1:-1;;;58018:87:0;;19114:2:1;58018:87:0;;;19096:21:1;19153:2;19133:18;;;19126:30;-1:-1:-1;;;19172:18:1;;;19165:52;19234:18;;58018:87:0;19086:172:1;58018:87:0;58157:17;;58136;58144:9;58136:7;:17;:::i;:::-;:38;;58128:79;;;;-1:-1:-1;;;58128:79:0;;17240:2:1;58128:79:0;;;17222:21:1;17279:2;17259:18;;;17252:30;17318;17298:18;;;17291:58;17366:18;;58128:79:0;17212:178:1;58128:79:0;58259:17;58267:9;58259:7;:17;:::i;:::-;58251:4;;:26;;;;:::i;:::-;58238:9;:39;58230:68;;;;-1:-1:-1;;;58230:68:0;;;;;;;:::i;:::-;58336:30;58347:10;58358:7;58336:10;:30::i;:::-;58385:34;58397:10;58409:9;58385:11;:34::i;:::-;58457:9;58438:15;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;58504:17:0;;-1:-1:-1;58512:9:0;58504:7;:17;:::i;:::-;58485:15;;:36;;;;;;;:::i;:::-;;;;-1:-1:-1;;58554:10:0;58540:25;;;;:13;:25;;;;;:36;;58569:7;;58540:25;:36;;58569:7;;58540:36;:::i;:::-;;;;-1:-1:-1;58625:17:0;;-1:-1:-1;58633:9:0;58625:7;:17;:::i;:::-;58611:10;58595:27;;;;:15;:27;;;;;:47;;:27;;;:47;;;;;:::i;:::-;;;;-1:-1:-1;57582:1377:0;;-1:-1:-1;57582:1377:0;;58709:7;58702:4;;:14;;;;:::i;:::-;58689:9;:27;58681:56;;;;-1:-1:-1;;;58681:56:0;;;;;;;:::i;:::-;58756:31;58767:10;58779:7;58756:10;:31::i;:::-;58825:7;58806:15;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;;58867:10:0;58851:27;;;;:15;:27;;;;;:37;;58881:7;;58851:27;:37;;58881:7;;58851:37;:::i;:::-;;;;-1:-1:-1;;58921:10:0;58907:25;;;;:13;:25;;;;;:36;;58936:7;;58907:25;:36;;58936:7;;58907:36;:::i;:::-;;;;-1:-1:-1;;57582:1377:0;57139:2538;;;;;59037:13;;59026:7;59008:15;;:25;;;;:::i;:::-;:42;;59000:77;;;;-1:-1:-1;;;59000:77:0;;19114:2:1;59000:77:0;;;19096:21:1;19153:2;19133:18;;;19126:30;-1:-1:-1;;;19172:18:1;;;19165:52;19234:18;;59000:77:0;19086:172:1;59000:77:0;59135:14;;59122:10;59109:24;;;;:12;:24;;;;;;59100:33;;:7;:33;:::i;:::-;:49;;59092:89;;;;-1:-1:-1;;;59092:89:0;;;;;;;:::i;:::-;59204:10;;;;:18;;:10;:18;59196:54;;;;-1:-1:-1;;;59196:54:0;;20232:2:1;59196:54:0;;;20214:21:1;20271:2;20251:18;;;20244:30;20310:25;20290:18;;;20283:53;20353:18;;59196:54:0;20204:173:1;59196:54:0;59329:14;;59304:10;59291:24;;;;:12;:24;;;;;;:34;;59318:7;;59291:34;:::i;:::-;:52;;59265:141;;;;-1:-1:-1;;;59265:141:0;;;;;;;:::i;:::-;59449:7;59442:4;;:14;;;;:::i;:::-;59429:9;:27;59421:56;;;;-1:-1:-1;;;59421:56:0;;;;;;;:::i;:::-;59511:7;59492:15;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;59533:31:0;;-1:-1:-1;59544:10:0;59556:7;59533:10;:31::i;:::-;59593:10;59579:25;;;;:13;:25;;;;;:36;;59608:7;;59579:25;:36;;59608:7;;59579:36;:::i;:::-;;;;-1:-1:-1;;59643:10:0;59630:24;;;;:12;:24;;;;;:35;;59658:7;;59630:24;:35;;59658:7;;59630:35;:::i;:::-;;;;-1:-1:-1;;57139:2538:0;56863:2821;;;;:::o;62338:485::-;13269:13;:11;:13::i;:::-;62419:14:::1;62436:13;49496:10:::0;:17;;49408:113;62436:13:::1;62419:30;;62482:1;62468:11;:15;62460:24;;;::::0;::::1;;62532:13;::::0;62515:15:::1;::::0;62503:27:::1;::::0;:11;:27:::1;:::i;:::-;:42;;62495:78;;;::::0;-1:-1:-1;;;62495:78:0;;13845:2:1;62495:78:0::1;::::0;::::1;13827:21:1::0;13884:2;13864:18;;;13857:30;13923:26;13903:18;;;13896:54;13967:18;;62495:78:0::1;13817:174:1::0;62495:78:0::1;62616:9;::::0;62592:20:::1;62601:11:::0;62592:6;:20:::1;:::i;:::-;:33;;62584:42;;;::::0;::::1;;62656:11;62637:15;;:30;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;62678:18:0;::::1;;::::0;;;:13:::1;:18;::::0;;;;:31;;62698:11;;62678:18;:31:::1;::::0;62698:11;;62678:31:::1;:::i;:::-;::::0;;;-1:-1:-1;62737:1:0::1;::::0;-1:-1:-1;62720:96:0::1;62745:11;62740:1;:16;62720:96;;62778:26;62788:3:::0;62793:10:::1;62802:1:::0;62793:6;:10:::1;:::i;:::-;62778:9;:26::i;:::-;62758:3:::0;::::1;::::0;::::1;:::i;:::-;;;;62720:96;;49598:233:::0;49673:7;49709:30;49496:10;:17;;49408:113;49709:30;49701:5;:38;49693:95;;;;-1:-1:-1;;;49693:95:0;;18701:2:1;49693:95:0;;;18683:21:1;18740:2;18720:18;;;18713:30;18779:34;18759:18;;;18752:62;-1:-1:-1;;;18830:18:1;;;18823:42;18882:19;;49693:95:0;18673:234:1;49693:95:0;49806:10;49817:5;49806:17;;;;;;-1:-1:-1;;;49806:17:0;;;;;;;;;;;;;;;;;49799:24;;49598:233;;;:::o;64247:104::-;13269:13;:11;:13::i;:::-;64322:21;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;56426:103::-:0;13269:13;:11;:13::i;:::-;56497:10:::1;:24:::0;;-1:-1:-1;;56497:24:0::1;::::0;::::1;;::::0;;;::::1;::::0;;56426:103::o;35213:222::-;35285:7;35321:16;;;:7;:16;;;;;;-1:-1:-1;;;;;35321:16:0;35356:19;35348:56;;;;-1:-1:-1;;;35348:56:0;;16887:2:1;35348:56:0;;;16869:21:1;16926:2;16906:18;;;16899:30;-1:-1:-1;;;16945:18:1;;;16938:54;17009:18;;35348:56:0;16859:174:1;55189:21:0;;;;;;;:::i;64967:94::-;13269:13;:11;:13::i;:::-;65034:9:::1;:19:::0;64967:94::o;65069:102::-;13269:13;:11;:13::i;:::-;65140::::1;:23:::0;65069:102::o;60782:142::-;-1:-1:-1;;;;;60892:24:0;;60846:7;60892:24;;;:15;:24;;;;;;60872:17;;:44;;60892:24;60872:44;:::i;34944:207::-;35016:7;-1:-1:-1;;;;;35044:19:0;;35036:73;;;;-1:-1:-1;;;35036:73:0;;14198:2:1;35036:73:0;;;14180:21:1;14237:2;14217:18;;;14210:30;14276:34;14256:18;;;14249:62;-1:-1:-1;;;14327:18:1;;;14320:39;14376:19;;35036:73:0;14170:231:1;35036:73:0;-1:-1:-1;;;;;;35127:16:0;;;;;:9;:16;;;;;;;34944:207::o;14031:103::-;13269:13;:11;:13::i;:::-;14096:30:::1;14123:1;14096:18;:30::i;:::-;14031:103::o:0;62831:106::-;13269:13;:11;:13::i;:::-;62905:10:::1;:24:::0;62831:106::o;35671:104::-;35727:13;35760:7;35753:14;;;;;:::i;37258:155::-;37353:52;12014:10;37386:8;37396;37353:18;:52::i;60932:684::-;61052:16;;:39;;-1:-1:-1;;;61052:39:0;;-1:-1:-1;;;;;8357:32:1;;;61052:39:0;;;8339:51:1;60996:16:0;;61024:25;;61052:16;;;;;;;;:30;;8312:18:1;;61052:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61052:39:0;;;;;;;;;;;;:::i;:::-;61024:67;;61102:13;61134:9;61130:168;61149:8;:15;61147:1;:17;61130:168;;;61185:10;61198:8;61207:1;61198:11;;;;;;-1:-1:-1;;;61198:11:0;;;;;;;;;;;;;;;;;;;;61228:16;;;;:12;:16;;;;;;;;61198:11;;-1:-1:-1;61228:16:0;;61224:63;;61264:7;;;;:::i;:::-;;;;61224:63;-1:-1:-1;61166:3:0;;;;:::i;:::-;;;;61130:168;;;;61310:21;61347:5;61333:20;;;;;;-1:-1:-1;;;61333:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61333:20:0;;61310:43;;61372:1;61364:9;;61388;61384:203;61403:8;:15;61401:1;:17;61384:203;;;61439:10;61452:8;61461:1;61452:11;;;;;;-1:-1:-1;;;61452:11:0;;;;;;;;;;;;;;;;;;;;61482:16;;;;:12;:16;;;;;;;;61452:11;;-1:-1:-1;61482:16:0;;61478:98;;61532:2;61518:4;61523:5;61518:11;;;;;;-1:-1:-1;;;61518:11:0;;;;;;;;;;;;;;;;;;:16;61553:7;;;;:::i;:::-;;;;61478:98;-1:-1:-1;61420:3:0;;;;:::i;:::-;;;;61384:203;;;-1:-1:-1;61604:4:0;60932:684;-1:-1:-1;;;;60932:684:0:o;64076:69::-;13269:13;:11;:13::i;:::-;64122:8:::1;:15:::0;;-1:-1:-1;;64122:15:0::1;;;::::0;;64076:69::o;38378:323::-;38552:41;12014:10;38585:7;38552:18;:41::i;:::-;38544:100;;;;-1:-1:-1;;;38544:100:0;;;;;;;:::i;:::-;38655:38;38669:4;38675:2;38679:7;38688:4;38655:13;:38::i;55217:37::-;;;;;;;:::i;63343:725::-;40273:4;40297:16;;;:7;:16;;;;;;63461:13;;-1:-1:-1;;;;;40297:16:0;63492:113;;;;-1:-1:-1;;;63492:113:0;;16471:2:1;63492:113:0;;;16453:21:1;16510:2;16490:18;;;16483:30;16549:34;16529:18;;;16522:62;-1:-1:-1;;;16600:18:1;;;16593:45;16655:19;;63492:113:0;16443:237:1;63492:113:0;63622:8;;;;;;;63618:71;;63663:14;63656:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63343:725;;;:::o;63618:71::-;63701:28;63732:10;:8;:10::i;:::-;63701:41;;63804:1;63779:14;63773:28;:32;:287;;;;;;;;;;;;;;;;;63897:14;63938:18;:7;:16;:18::i;:::-;63983:13;63854:165;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63773:287;63753:307;63343:725;-1:-1:-1;;;63343:725:0:o;64359:151::-;13269:13;:11;:13::i;:::-;64469:33;;::::1;::::0;:13:::1;::::0;:33:::1;::::0;::::1;::::0;::::1;:::i;64739:102::-:0;13269:13;:11;:13::i;:::-;64810:14:::1;:23:::0;64739:102::o;65181:::-;13269:13;:11;:13::i;:::-;65252::::1;:23:::0;65181:102::o;60280:494::-;60339:7;60358:25;60386:26;60404:7;60386:17;:26::i;:::-;60358:54;;60423:27;60453:28;60473:7;60453:19;:28::i;:::-;60423:58;;60492:17;60543:1;60527:8;:15;:17;:38;;;;;60564:1;60546:10;:17;:19;60527:38;60524:216;;;60597:10;:17;60580:8;:15;:34;60577:152;;-1:-1:-1;60642:15:0;;60577:152;;;-1:-1:-1;60700:17:0;;60577:152;60757:9;60280:494;-1:-1:-1;;;;60280:494:0:o;64518:126::-;13269:13;:11;:13::i;:::-;64604:32;;::::1;::::0;:14:::1;::::0;:32:::1;::::0;::::1;::::0;::::1;:::i;14289:201::-:0;13269:13;:11;:13::i;:::-;-1:-1:-1;;;;;14378:22:0;::::1;14370:73;;;::::0;-1:-1:-1;;;14370:73:0;;11165:2:1;14370:73:0::1;::::0;::::1;11147:21:1::0;11204:2;11184:18;;;11177:30;11243:34;11223:18;;;11216:62;-1:-1:-1;;;11294:18:1;;;11287:36;11340:19;;14370:73:0::1;11137:228:1::0;14370:73:0::1;14454:28;14473:8;14454:18;:28::i;:::-;14289:201:::0;:::o;61624:706::-;61748:18;;:41;;-1:-1:-1;;;61748:41:0;;-1:-1:-1;;;;;8357:32:1;;;61748:41:0;;;8339:51:1;61690:16:0;;61718:27;;61748:18;;;:32;;8312:18:1;;61748:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61748:41:0;;;;;;;;;;;;:::i;:::-;61718:71;;61800:13;61832:9;61828:174;61847:10;:17;61845:1;:19;61828:174;;;61885:10;61898;61909:1;61898:13;;;;;;-1:-1:-1;;;61898:13:0;;;;;;;;;;;;;;;;;;;;61930:18;;;;:14;:18;;;;;;;;61898:13;;-1:-1:-1;61930:18:0;;61926:65;;61968:7;;;;:::i;:::-;;;;61926:65;-1:-1:-1;61866:3:0;;;;:::i;:::-;;;;61828:174;;;;62012:23;62051:5;62037:20;;;;;;-1:-1:-1;;;62037:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62037:20:0;;62012:45;;62076:1;62068:9;;62092;62088:211;62107:10;:17;62105:1;:19;62088:211;;;62145:10;62158;62169:1;62158:13;;;;;;-1:-1:-1;;;62158:13:0;;;;;;;;;;;;;;;;;;;;62190:18;;;;:14;:18;;;;;;;;62158:13;;-1:-1:-1;62190:18:0;;62186:102;;62244:2;62228:6;62235:5;62228:13;;;;;;-1:-1:-1;;;62228:13:0;;;;;;;;;;;;;;;;;;:18;62265:7;;;;:::i;:::-;;;;62186:102;-1:-1:-1;62126:3:0;;;;:::i;:::-;;;;62088:211;;65291:223;65345:4;65350;65356;65361;65366;65390:21;65403:7;65390:12;:21::i;:::-;65412:26;65430:7;65412:17;:26::i;:::-;-1:-1:-1;;;;;65439:22:0;;;;;;:13;:22;;;;;;49496:10;:17;65490:15;;65476:13;;:29;;;;:::i;:::-;65382:124;;;;-1:-1:-1;65382:124:0;;-1:-1:-1;65382:124:0;-1:-1:-1;65382:124:0;;-1:-1:-1;65291:223:0;-1:-1:-1;;65291:223:0:o;34575:305::-;34677:4;-1:-1:-1;;;;;;34714:40:0;;-1:-1:-1;;;34714:40:0;;:105;;-1:-1:-1;;;;;;;34771:48:0;;-1:-1:-1;;;34771:48:0;34714:105;:158;;;-1:-1:-1;;;;;;;;;;26346:40:0;;;34836:36;26237:157;13548:132;13456:6;;-1:-1:-1;;;;;13456:6:0;12014:10;13612:23;13604:68;;;;-1:-1:-1;;;13604:68:0;;16110:2:1;13604:68:0;;;16092:21:1;;;16129:18;;;16122:30;16188:34;16168:18;;;16161:62;16240:18;;13604:68:0;16082:182:1;44990:135:0;40273:4;40297:16;;;:7;:16;;;;;;-1:-1:-1;;;;;40297:16:0;45064:53;;;;-1:-1:-1;;;45064:53:0;;16887:2:1;45064:53:0;;;16869:21:1;16926:2;16906:18;;;16899:30;-1:-1:-1;;;16945:18:1;;;16938:54;17009:18;;45064:53:0;16859:174:1;44269::0;44344:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;44344:29:0;-1:-1:-1;;;;;44344:29:0;;;;;;;;:24;;44398:23;44344:24;44398:14;:23::i;:::-;-1:-1:-1;;;;;44389:46:0;;;;;;;;;;;44269:174;;:::o;40502:264::-;40595:4;40612:13;40628:23;40643:7;40628:14;:23::i;:::-;40612:39;;40681:5;-1:-1:-1;;;;;40670:16:0;:7;-1:-1:-1;;;;;40670:16:0;;:52;;;-1:-1:-1;;;;;;37605:25:0;;;37581:4;37605:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;40690:32;40670:87;;;;40750:7;-1:-1:-1;;;;;40726:31:0;:20;40738:7;40726:11;:20::i;:::-;-1:-1:-1;;;;;40726:31:0;;40662:96;40502:264;-1:-1:-1;;;;40502:264:0:o;43525:625::-;43684:4;-1:-1:-1;;;;;43657:31:0;:23;43672:7;43657:14;:23::i;:::-;-1:-1:-1;;;;;43657:31:0;;43649:81;;;;-1:-1:-1;;;43649:81:0;;11917:2:1;43649:81:0;;;11899:21:1;11956:2;11936:18;;;11929:30;11995:34;11975:18;;;11968:62;-1:-1:-1;;;12046:18:1;;;12039:35;12091:19;;43649:81:0;11889:227:1;43649:81:0;-1:-1:-1;;;;;43749:16:0;;43741:65;;;;-1:-1:-1;;;43741:65:0;;12680:2:1;43741:65:0;;;12662:21:1;12719:2;12699:18;;;12692:30;12758:34;12738:18;;;12731:62;-1:-1:-1;;;12809:18:1;;;12802:34;12853:19;;43741:65:0;12652:226:1;43741:65:0;43819:39;43840:4;43846:2;43850:7;43819:20;:39::i;:::-;43923:29;43940:1;43944:7;43923:8;:29::i;:::-;-1:-1:-1;;;;;43965:15:0;;;;;;:9;:15;;;;;:20;;43984:1;;43965:15;:20;;43984:1;;43965:20;:::i;:::-;;;;-1:-1:-1;;;;;;;43996:13:0;;;;;;:9;:13;;;;;:18;;44013:1;;43996:13;:18;;44013:1;;43996:18;:::i;:::-;;;;-1:-1:-1;;44025:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;44025:21:0;-1:-1:-1;;;;;44025:21:0;;;;;;;;;44064:27;;44025:16;;44064:27;;;;;;;36532:417;;;:::o;56537:318::-;56661:4;56703:144;56740:11;;56703:144;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56803:28:0;;-1:-1:-1;;56820:10:0;6572:2:1;6568:15;6564:53;56803:28:0;;;6552:66:1;56770:4:0;;-1:-1:-1;6634:12:1;;;-1:-1:-1;56803:28:0;;;;;;;;;;;;56793:39;;;;;;56703:18;:144::i;60054:218::-;60128:14;60145:13;49496:10;:17;;49408:113;60145:13;60128:30;-1:-1:-1;60186:1:0;60169:96;60194:7;60189:1;:12;60169:96;;60223:30;60233:7;60242:10;60251:1;60242:6;:10;:::i;60223:30::-;60203:3;;;;:::i;:::-;;;;60169:96;;59692:354;59767:25;59795:26;59813:7;59795:17;:26::i;:::-;59767:54;;59832:27;59862:28;59882:7;59862:19;:28::i;:::-;59832:58;;59905:9;59901:138;59920:7;59918:1;:9;59901:138;;;59974:4;59948:12;:25;59961:8;59970:1;59961:11;;;;;;-1:-1:-1;;;59961:11:0;;;;;;;;;;;;;;;59948:25;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;60023:4;59993:14;:29;60008:10;60019:1;60008:13;;;;;;-1:-1:-1;;;60008:13:0;;;;;;;;;;;;;;;59993:29;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;59929:3;;;;;:::i;:::-;;;;59901:138;;;;59692:354;;;;:::o;41108:110::-;41184:26;41194:2;41198:7;41184:26;;;;;;;;;;;;:9;:26::i;14650:191::-;14743:6;;;-1:-1:-1;;;;;14760:17:0;;;-1:-1:-1;;;;;;14760:17:0;;;;;;;14793:40;;14743:6;;;14760:17;14743:6;;14793:40;;14724:16;;14793:40;14650:191;;:::o;44586:315::-;44741:8;-1:-1:-1;;;;;44732:17:0;:5;-1:-1:-1;;;;;44732:17:0;;;44724:55;;;;-1:-1:-1;;;44724:55:0;;13085:2:1;44724:55:0;;;13067:21:1;13124:2;13104:18;;;13097:30;13163:27;13143:18;;;13136:55;13208:18;;44724:55:0;13057:175:1;44724:55:0;-1:-1:-1;;;;;44790:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;44790:46:0;;;;;;;;;;44852:41;;9674::1;;;44852::0;;9647:18:1;44852:41:0;;;;;;;44586:315;;;:::o;39582:313::-;39738:28;39748:4;39754:2;39758:7;39738:9;:28::i;:::-;39785:47;39808:4;39814:2;39818:7;39827:4;39785:22;:47::i;:::-;39777:110;;;;-1:-1:-1;;;39777:110:0;;;;;;;:::i;56310:108::-;56370:13;56403:7;56396:14;;;;;:::i;9188:723::-;9244:13;9465:10;9461:53;;-1:-1:-1;;9492:10:0;;;;;;;;;;;;-1:-1:-1;;;9492:10:0;;;;;9188:723::o;9461:53::-;9539:5;9524:12;9580:78;9587:9;;9580:78;;9613:8;;;;:::i;:::-;;-1:-1:-1;9636:10:0;;-1:-1:-1;9644:2:0;9636:10;;:::i;:::-;;;9580:78;;;9668:19;9700:6;9690:17;;;;;;-1:-1:-1;;;9690:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9690:17:0;;9668:39;;9718:154;9725:10;;9718:154;;9752:11;9762:1;9752:11;;:::i;:::-;;-1:-1:-1;9821:10:0;9829:2;9821:5;:10;:::i;:::-;9808:24;;:2;:24;:::i;:::-;9795:39;;9778:6;9785;9778:14;;;;;;-1:-1:-1;;;9778:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;9778:56:0;;;;;;;;-1:-1:-1;9849:11:0;9858:2;9849:11;;:::i;:::-;;;9718:154;;50444:589;-1:-1:-1;;;;;50650:18:0;;50646:187;;50685:40;50717:7;51860:10;:17;;51833:24;;;;:15;:24;;;;;:44;;;51888:24;;;;;;;;;;;;51756:164;50685:40;50646:187;;;50755:2;-1:-1:-1;;;;;50747:10:0;:4;-1:-1:-1;;;;;50747:10:0;;50743:90;;50774:47;50807:4;50813:7;50774:32;:47::i;:::-;-1:-1:-1;;;;;50847:16:0;;50843:183;;50880:45;50917:7;50880:36;:45::i;50843:183::-;50953:4;-1:-1:-1;;;;;50947:10:0;:2;-1:-1:-1;;;;;50947:10:0;;50943:83;;50974:40;51002:2;51006:7;50974:27;:40::i;1252:190::-;1377:4;1430;1401:25;1414:5;1421:4;1401:12;:25::i;:::-;:33;;1252:190;-1:-1:-1;;;;1252:190:0:o;41445:319::-;41574:18;41580:2;41584:7;41574:5;:18::i;:::-;41625:53;41656:1;41660:2;41664:7;41673:4;41625:22;:53::i;:::-;41603:153;;;;-1:-1:-1;;;41603:153:0;;;;;;;:::i;45689:853::-;45843:4;-1:-1:-1;;;;;45864:13:0;;16376:19;:23;45860:675;;45900:71;;-1:-1:-1;;;45900:71:0;;-1:-1:-1;;;;;45900:36:0;;;;;:71;;12014:10;;45951:4;;45957:7;;45966:4;;45900:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45900:71:0;;;;;;;;-1:-1:-1;;45900:71:0;;;;;;;;;;;;:::i;:::-;;;45896:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46141:13:0;;46137:328;;46184:60;;-1:-1:-1;;;46184:60:0;;;;;;;:::i;46137:328::-;46415:6;46409:13;46400:6;46396:2;46392:15;46385:38;45896:584;-1:-1:-1;;;;;;46022:51:0;-1:-1:-1;;;46022:51:0;;-1:-1:-1;46015:58:0;;45860:675;-1:-1:-1;46519:4:0;45689:853;;;;;;:::o;52547:988::-;52813:22;52863:1;52838:22;52855:4;52838:16;:22::i;:::-;:26;;;;:::i;:::-;52875:18;52896:26;;;:17;:26;;;;;;52813:51;;-1:-1:-1;53029:28:0;;;53025:328;;-1:-1:-1;;;;;53096:18:0;;53074:19;53096:18;;;:12;:18;;;;;;;;:34;;;;;;;;;53147:30;;;;;;:44;;;53264:30;;:17;:30;;;;;:43;;;53025:328;-1:-1:-1;53449:26:0;;;;:17;:26;;;;;;;;53442:33;;;-1:-1:-1;;;;;53493:18:0;;;;;:12;:18;;;;;:34;;;;;;;53486:41;52547:988::o;53830:1079::-;54108:10;:17;54083:22;;54108:21;;54128:1;;54108:21;:::i;:::-;54140:18;54161:24;;;:15;:24;;;;;;54534:10;:26;;54083:46;;-1:-1:-1;54161:24:0;;54083:46;;54534:26;;;;-1:-1:-1;;;54534:26:0;;;;;;;;;;;;;;;;;54512:48;;54598:11;54573:10;54584;54573:22;;;;;;-1:-1:-1;;;54573:22:0;;;;;;;;;;;;;;;;;;;;:36;;;;54678:28;;;:15;:28;;;;;;;:41;;;54850:24;;;;;54843:31;54885:10;:16;;;;;-1:-1:-1;;;54885:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;53830:1079;;;;:::o;51334:221::-;51419:14;51436:20;51453:2;51436:16;:20::i;:::-;-1:-1:-1;;;;;51467:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;51512:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;51334:221:0:o;2119:296::-;2202:7;2245:4;2202:7;2260:118;2284:5;:12;2280:1;:16;2260:118;;;2333:33;2343:12;2357:5;2363:1;2357:8;;;;;;-1:-1:-1;;;2357:8:0;;;;;;;;;;;;;;;2333:9;:33::i;:::-;2318:48;-1:-1:-1;2298:3:0;;;;:::i;:::-;;;;2260:118;;42100:439;-1:-1:-1;;;;;42180:16:0;;42172:61;;;;-1:-1:-1;;;42172:61:0;;15749:2:1;42172:61:0;;;15731:21:1;;;15768:18;;;15761:30;15827:34;15807:18;;;15800:62;15879:18;;42172:61:0;15721:182:1;42172:61:0;40273:4;40297:16;;;:7;:16;;;;;;-1:-1:-1;;;;;40297:16:0;:30;42244:58;;;;-1:-1:-1;;;42244:58:0;;12323:2:1;42244:58:0;;;12305:21:1;12362:2;12342:18;;;12335:30;12401;12381:18;;;12374:58;12449:18;;42244:58:0;12295:178:1;42244:58:0;42315:45;42344:1;42348:2;42352:7;42315:20;:45::i;:::-;-1:-1:-1;;;;;42373:13:0;;;;;;:9;:13;;;;;:18;;42390:1;;42373:13;:18;;42390:1;;42373:18;:::i;:::-;;;;-1:-1:-1;;42402:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;42402:21:0;-1:-1:-1;;;;;42402:21:0;;;;;;;;42441:33;;42402:16;;;42441:33;;42402:16;;42441:33;65691:42:::1;13293:1;65522:219::o:0;8326:149::-;8389:7;8420:1;8416;:5;:51;;8551:13;8645:15;;;8681:4;8674:15;;;8728:4;8712:21;;8416:51;;;-1:-1:-1;8551:13:0;8645:15;;;8681:4;8674:15;8728:4;8712:21;;;8326:149::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:2;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:2;;;309:1;306;299:12;268:2;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;88:332;;;;;:::o;425:173::-;493:20;;-1:-1:-1;;;;;542:31:1;;532:42;;522:2;;588:1;585;578:12;522:2;474:124;;;:::o;603:160::-;668:20;;724:13;;717:21;707:32;;697:2;;753:1;750;743:12;768:196;827:6;880:2;868:9;859:7;855:23;851:32;848:2;;;901:6;893;886:22;848:2;929:29;948:9;929:29;:::i;969:270::-;1037:6;1045;1098:2;1086:9;1077:7;1073:23;1069:32;1066:2;;;1119:6;1111;1104:22;1066:2;1147:29;1166:9;1147:29;:::i;:::-;1137:39;;1195:38;1229:2;1218:9;1214:18;1195:38;:::i;:::-;1185:48;;1056:183;;;;;:::o;1244:338::-;1321:6;1329;1337;1390:2;1378:9;1369:7;1365:23;1361:32;1358:2;;;1411:6;1403;1396:22;1358:2;1439:29;1458:9;1439:29;:::i;:::-;1429:39;;1487:38;1521:2;1510:9;1506:18;1487:38;:::i;:::-;1477:48;;1572:2;1561:9;1557:18;1544:32;1534:42;;1348:234;;;;;:::o;1587:696::-;1682:6;1690;1698;1706;1759:3;1747:9;1738:7;1734:23;1730:33;1727:2;;;1781:6;1773;1766:22;1727:2;1809:29;1828:9;1809:29;:::i;:::-;1799:39;;1857:38;1891:2;1880:9;1876:18;1857:38;:::i;:::-;1847:48;;1942:2;1931:9;1927:18;1914:32;1904:42;;1997:2;1986:9;1982:18;1969:32;2024:18;2016:6;2013:30;2010:2;;;2061:6;2053;2046:22;2010:2;2089:22;;2142:4;2134:13;;2130:27;-1:-1:-1;2120:2:1;;2176:6;2168;2161:22;2120:2;2204:73;2269:7;2264:2;2251:16;2246:2;2242;2238:11;2204:73;:::i;:::-;2194:83;;;1717:566;;;;;;;:::o;2288:264::-;2353:6;2361;2414:2;2402:9;2393:7;2389:23;2385:32;2382:2;;;2435:6;2427;2420:22;2382:2;2463:29;2482:9;2463:29;:::i;:::-;2453:39;;2511:35;2542:2;2531:9;2527:18;2511:35;:::i;2557:264::-;2625:6;2633;2686:2;2674:9;2665:7;2661:23;2657:32;2654:2;;;2707:6;2699;2692:22;2654:2;2735:29;2754:9;2735:29;:::i;:::-;2725:39;2811:2;2796:18;;;;2783:32;;-1:-1:-1;;;2644:177:1:o;2826:739::-;2921:6;2929;2937;2990:2;2978:9;2969:7;2965:23;2961:32;2958:2;;;3011:6;3003;2996:22;2958:2;3056:9;3043:23;3085:18;3126:2;3118:6;3115:14;3112:2;;;3147:6;3139;3132:22;3112:2;3190:6;3179:9;3175:22;3165:32;;3235:7;3228:4;3224:2;3220:13;3216:27;3206:2;;3262:6;3254;3247:22;3206:2;3307;3294:16;3333:2;3325:6;3322:14;3319:2;;;3354:6;3346;3339:22;3319:2;3414:7;3407:4;3397:6;3394:1;3390:14;3386:2;3382:23;3378:34;3375:47;3372:2;;;3440:6;3432;3425:22;3372:2;3476:4;3468:13;;;;3500:6;;-1:-1:-1;3538:20:1;;;;3525:34;;2948:617;-1:-1:-1;;;;2948:617:1:o;3570:992::-;3665:6;3696:2;3739;3727:9;3718:7;3714:23;3710:32;3707:2;;;3760:6;3752;3745:22;3707:2;3798:9;3792:16;3827:18;3868:2;3860:6;3857:14;3854:2;;;3889:6;3881;3874:22;3854:2;3932:6;3921:9;3917:22;3907:32;;3977:7;3970:4;3966:2;3962:13;3958:27;3948:2;;4004:6;3996;3989:22;3948:2;4038;4032:9;4060:2;4056;4053:10;4050:2;;;4066:18;;:::i;:::-;4112:2;4109:1;4105:10;4095:20;;4135:28;4159:2;4155;4151:11;4135:28;:::i;:::-;4197:15;;;4228:12;;;;4260:11;;;4290;;;4286:20;;4283:33;-1:-1:-1;4280:2:1;;;4334:6;4326;4319:22;4280:2;4361:6;4352:15;;4376:156;4390:2;4387:1;4384:9;4376:156;;;4447:10;;4435:23;;4408:1;4401:9;;;;;4478:12;;;;4510;;4376:156;;;-1:-1:-1;4551:5:1;3676:886;-1:-1:-1;;;;;;;;3676:886:1:o;4567:190::-;4623:6;4676:2;4664:9;4655:7;4651:23;4647:32;4644:2;;;4697:6;4689;4682:22;4644:2;4725:26;4741:9;4725:26;:::i;4762:190::-;4821:6;4874:2;4862:9;4853:7;4849:23;4845:32;4842:2;;;4895:6;4887;4880:22;4842:2;-1:-1:-1;4923:23:1;;4832:120;-1:-1:-1;4832:120:1:o;4957:255::-;5015:6;5068:2;5056:9;5047:7;5043:23;5039:32;5036:2;;;5089:6;5081;5074:22;5036:2;5133:9;5120:23;5152:30;5176:5;5152:30;:::i;5217:259::-;5286:6;5339:2;5327:9;5318:7;5314:23;5310:32;5307:2;;;5360:6;5352;5345:22;5307:2;5397:9;5391:16;5416:30;5440:5;5416:30;:::i;5481:480::-;5550:6;5603:2;5591:9;5582:7;5578:23;5574:32;5571:2;;;5624:6;5616;5609:22;5571:2;5669:9;5656:23;5702:18;5694:6;5691:30;5688:2;;;5739:6;5731;5724:22;5688:2;5767:22;;5820:4;5812:13;;5808:27;-1:-1:-1;5798:2:1;;5854:6;5846;5839:22;5798:2;5882:73;5947:7;5942:2;5929:16;5924:2;5920;5916:11;5882:73;:::i;6161:257::-;6202:3;6240:5;6234:12;6267:6;6262:3;6255:19;6283:63;6339:6;6332:4;6327:3;6323:14;6316:4;6309:5;6305:16;6283:63;:::i;:::-;6400:2;6379:15;-1:-1:-1;;6375:29:1;6366:39;;;;6407:4;6362:50;;6210:208;-1:-1:-1;;6210:208:1:o;6657:1531::-;6881:3;6919:6;6913:13;6945:4;6958:51;7002:6;6997:3;6992:2;6984:6;6980:15;6958:51;:::i;:::-;7072:13;;7031:16;;;;7094:55;7072:13;7031:16;7116:15;;;7094:55;:::i;:::-;7240:13;;7171:20;;;7211:3;;7300:1;7322:18;;;;7375;;;;7402:2;;7480:4;7470:8;7466:19;7454:31;;7402:2;7543;7533:8;7530:16;7510:18;7507:40;7504:2;;;-1:-1:-1;;;7570:33:1;;7626:4;7623:1;7616:15;7656:4;7577:3;7644:17;7504:2;7687:18;7714:110;;;;7838:1;7833:330;;;;7680:483;;7714:110;-1:-1:-1;;7749:24:1;;7735:39;;7794:20;;;;-1:-1:-1;7714:110:1;;7833:330;21359:4;21378:17;;;21428:4;21412:21;;7928:3;7944:169;7958:8;7955:1;7952:15;7944:169;;;8040:14;;8025:13;;;8018:37;8083:16;;;;7975:10;;7944:169;;;7948:3;;8144:8;8137:5;8133:20;8126:27;;7680:483;-1:-1:-1;8179:3:1;;6889:1299;-1:-1:-1;;;;;;;;;;;6889:1299:1:o;8401:488::-;-1:-1:-1;;;;;8670:15:1;;;8652:34;;8722:15;;8717:2;8702:18;;8695:43;8769:2;8754:18;;8747:34;;;8817:3;8812:2;8797:18;;8790:31;;;8595:4;;8838:45;;8863:19;;8855:6;8838:45;:::i;:::-;8830:53;8604:285;-1:-1:-1;;;;;;8604:285:1:o;8894:635::-;9065:2;9117:21;;;9187:13;;9090:18;;;9209:22;;;9036:4;;9065:2;9288:15;;;;9262:2;9247:18;;;9036:4;9334:169;9348:6;9345:1;9342:13;9334:169;;;9409:13;;9397:26;;9478:15;;;;9443:12;;;;9370:1;9363:9;9334:169;;;-1:-1:-1;9520:3:1;;9045:484;-1:-1:-1;;;;;;9045:484:1:o;9908:219::-;10057:2;10046:9;10039:21;10020:4;10077:44;10117:2;10106:9;10102:18;10094:6;10077:44;:::i;10544:414::-;10746:2;10728:21;;;10785:2;10765:18;;;10758:30;10824:34;10819:2;10804:18;;10797:62;-1:-1:-1;;;10890:2:1;10875:18;;10868:48;10948:3;10933:19;;10718:240::o;11370:340::-;11572:2;11554:21;;;11611:2;11591:18;;;11584:30;-1:-1:-1;;;11645:2:1;11630:18;;11623:46;11701:2;11686:18;;11544:166::o;18143:351::-;18345:2;18327:21;;;18384:2;18364:18;;;18357:30;18423:29;18418:2;18403:18;;18396:57;18485:2;18470:18;;18317:177::o;19615:410::-;19817:2;19799:21;;;19856:2;19836:18;;;19829:30;19895:34;19890:2;19875:18;;19868:62;-1:-1:-1;;;19961:2:1;19946:18;;19939:44;20015:3;20000:19;;19789:236::o;21032:275::-;21103:2;21097:9;21168:2;21149:13;;-1:-1:-1;;21145:27:1;21133:40;;21203:18;21188:34;;21224:22;;;21185:62;21182:2;;;21250:18;;:::i;:::-;21286:2;21279:22;21077:230;;-1:-1:-1;21077:230:1:o;21444:128::-;21484:3;21515:1;21511:6;21508:1;21505:13;21502:2;;;21521:18;;:::i;:::-;-1:-1:-1;21557:9:1;;21492:80::o;21577:120::-;21617:1;21643;21633:2;;21648:18;;:::i;:::-;-1:-1:-1;21682:9:1;;21623:74::o;21702:168::-;21742:7;21808:1;21804;21800:6;21796:14;21793:1;21790:21;21785:1;21778:9;21771:17;21767:45;21764:2;;;21815:18;;:::i;:::-;-1:-1:-1;21855:9:1;;21754:116::o;21875:125::-;21915:4;21943:1;21940;21937:8;21934:2;;;21948:18;;:::i;:::-;-1:-1:-1;21985:9:1;;21924:76::o;22005:258::-;22077:1;22087:113;22101:6;22098:1;22095:13;22087:113;;;22177:11;;;22171:18;22158:11;;;22151:39;22123:2;22116:10;22087:113;;;22218:6;22215:1;22212:13;22209:2;;;-1:-1:-1;;22253:1:1;22235:16;;22228:27;22058:205::o;22268:380::-;22347:1;22343:12;;;;22390;;;22411:2;;22465:4;22457:6;22453:17;22443:27;;22411:2;22518;22510:6;22507:14;22487:18;22484:38;22481:2;;;22564:10;22559:3;22555:20;22552:1;22545:31;22599:4;22596:1;22589:15;22627:4;22624:1;22617:15;22481:2;;22323:325;;;:::o;22653:135::-;22692:3;-1:-1:-1;;22713:17:1;;22710:2;;;22733:18;;:::i;:::-;-1:-1:-1;22780:1:1;22769:13;;22700:88::o;22793:112::-;22825:1;22851;22841:2;;22856:18;;:::i;:::-;-1:-1:-1;22890:9:1;;22831:74::o;22910:127::-;22971:10;22966:3;22962:20;22959:1;22952:31;23002:4;22999:1;22992:15;23026:4;23023:1;23016:15;23042:127;23103:10;23098:3;23094:20;23091:1;23084:31;23134:4;23131:1;23124:15;23158:4;23155:1;23148:15;23174:127;23235:10;23230:3;23226:20;23223:1;23216:31;23266:4;23263:1;23256:15;23290:4;23287:1;23280:15;23306:131;-1:-1:-1;;;;;;23380:32:1;;23370:43;;23360:2;;23427:1;23424;23417:12

Swarm Source

ipfs://00264136630256ba27b3ae8ef0bb816f81f82f82c8d4a8ba3eb5071cd6b4dd23
Loading...
Loading
Loading...
Loading
[ 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.