ETH Price: $3,386.50 (-1.52%)
Gas: 16 Gwei

Token

Atem Pen (APEN)
 

Overview

Max Total Supply

0 APEN

Holders

1,299

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
tshwangq.eth
Balance
1 APEN
0x191ac84067db87283a1864e1c606e9d51c32f511
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Atem Pen NFT is a collection of 6,000 NFTs created by Atem Network. By holding Atem Pen NFT, holders can unlock early access of AtemReview, earn social incentives by creating content and receive future airdrops.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
AtemPen

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// Sources flattened with hardhat v2.1.2 https://hardhat.org

// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// File @openzeppelin/contracts/utils/[email protected]


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


/**
 * @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/introspection/[email protected]

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

/**
 * @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/token/ERC721/[email protected]

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


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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * 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/[email protected]

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


/**
 * @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/token/ERC721/extensions/[email protected]

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


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

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

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


// File @openzeppelin/contracts/utils/[email protected]

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


/**
 * @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/utils/[email protected]

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


/**
 * @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/utils/introspection/[email protected]

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


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


// File @openzeppelin/contracts/token/ERC721/[email protected]

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


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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: 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/[email protected]

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



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
        _burn(tokenId);
    }
}


// File @openzeppelin/contracts/access/[email protected]

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


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

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

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

    /**
     * @dev 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/cryptography/[email protected]

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


/**
 * @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 contracts/CountersWithSet.sol


/**
 * @title CountersWithSet
 * @author modified from Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library CountersWithSet {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }
    
    function setValue(Counter storage counter, uint256 newValue) internal {
        require(newValue > 0, "Counter: insufficient value");
        counter._value = newValue;
    }
}


// File contracts/PenNFT.sol

contract AtemPen is Ownable, ERC721Burnable {
    using Strings for uint256;

    using CountersWithSet for CountersWithSet.Counter;
    CountersWithSet.Counter private _supplyTracker;

    string private _baseTokenURI;
    bytes32 public whitelistRoot;
    
    uint256 immutable public maxSupply;
    uint256 immutable public maxClaimNum;
    mapping(address => uint256) _claimedNum;
    
    // numWhitelist + <num_of_public_sale> + numReserved = maxSupply
    // Minting is opened first for only whitelisted addresses. 
    // After the whitelist phrase is finished, public sale is opened. All the remaining un-reserved NFTs are available for public sale.
    bool public whitelistSale;
    bool public publicSale;

    uint256 public numWhitelist;
    uint256 public numReserved;

    uint256 private _priceWhitelist; 
    uint256 private _pricePublic;

    // Payment address
    address public platformFeeAccount;


    constructor(
        string memory name, 
        string memory symbol, 
        string memory baseTokenURI_,
        uint256 supply, 
        uint256 whitelistNum, 
        uint256 reservedNum, 
        uint256 whitelistPrice_, 
        uint256 publicPrice_,
        uint256 maxClaimNum_,
        address platformAccount,
        bytes32 merkleroot)
    ERC721(name, symbol)
    { 
        _baseTokenURI = baseTokenURI_;

        whitelistRoot = merkleroot;
        maxSupply = supply;

        whitelistSale = false;
        publicSale = false;

        numWhitelist = whitelistNum;
        numReserved = reservedNum;

        _priceWhitelist = whitelistPrice_;
        _pricePublic = publicPrice_;

        maxClaimNum = maxClaimNum_;

        platformFeeAccount = platformAccount;
    }

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

    /** Receive and withdraw */

    receive() external payable { }

    function _withdraw(address _address, uint256 _amount) private {
        if ((_address != address(0)) && (_address != address(this)) && (_amount > 0)) {
            (bool success, ) = _address.call{value: _amount}("");
            require(success, "Transfer failed.");
        }
    }

    function withdrawAll() external onlyOwner {
        _withdraw(platformFeeAccount, address(this).balance);
    }
    function withdraw(uint256 amount) external onlyOwner {
        require(address(this).balance >= amount);
        _withdraw(platformFeeAccount, amount);
    }

    /** Mint helpers */

    function _safeMint(address to, uint256 tokenId) internal override {
        _safeMint(to, tokenId, "");
    }

    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal override {
        require(_supplyTracker.current() + numReserved < maxSupply, "ATEMPen#_safeMint: sold out");
        super._safeMint(to, tokenId, _data);
        _supplyTracker.increment();
    }

    /** Mint interfaces */

    function mint(address to) onlyOwner external {
        // We cannot just use balanceOf to create the new tokenId because tokens
        // can be burned (destroyed), so we need a separate counter.
        _safeMint(to, _supplyTracker.current());
    }

    function whitelistMint(address to, bytes32[] calldata proof)
    external payable
    {
        require(whitelistSale, "ATEMPen#whitelistMint: whitelist mint is not opening");
        require(_supplyTracker.current() < numWhitelist , "ATEMPen#whitelistMint: whitelist sold out");

        require(_verify(_leaf(to), proof), "ATEMPen#whitelistMint: invalid merkle proof");
        require(checkClaimable(to, 1), "ATEMPen#whitelistMint: reached your maximum claimable number");

        require(
            whitelistPrice(1) == msg.value,
            " ATEMPen#whitelistMint: incorrect payment value"
        );

        _safeMint(to, _supplyTracker.current());
        _claimedNum[to] += 1;
    }

    function whitelistMintBatch(address to, uint256 amount, bytes32[] calldata proof)
    external payable
    {
        require(whitelistSale, "ATEMPen#whitelistMintBatch: whitelist mint is not opening");
        require(amount > 0, "ATEMPen#whiteMintBatch: invalid amount");

        require(_verify(_leaf(to), proof), "ATEMPen#whitelistMintBatch: invalid merkle proof");
        require(checkClaimable(to, amount), "ATEMPen#whitelistMintBatch: reached your maximum claimable number");

        uint256 _currentSupply = _supplyTracker.current();
        uint256 _targetSupply = _currentSupply + amount;

        require(_targetSupply <= numWhitelist, "ATEMPen#whitelistMintBatch: amount exceeds whitelist supply");
        require(
            whitelistPrice(amount) == msg.value,
            " ATEMPen#whitelistMintBatch: incorrect payment value"
        );

        while (_currentSupply < _targetSupply) {
            super._safeMint(to, _currentSupply, "");
            unchecked {
                _currentSupply += 1;
            }
        }

        _supplyTracker.setValue(_currentSupply);
        _claimedNum[to] += amount;
    }

    function publicMint(address to)
    external payable
    {
        require(publicSale, "ATEMPen#publicMint: public sale is not opening");

        require(
            publicPrice(1) == msg.value,
            " ATEMPen#publicMint: incorrect payment value"
        );

        _safeMint(to, _supplyTracker.current());
    }

    function publicMintBatch(address to, uint256 amount)
    external payable
    {
        require(publicSale, "ATEMPen#publicMintBatch: public sale is not opening");
        require(amount > 0, "ATEMPen#publicMintBatch: invalid amount");

        uint256 _currentSupply = _supplyTracker.current();
        uint256 _targetSupply = _currentSupply + amount;

        require(_targetSupply + numReserved <= maxSupply, "ATEMPen#publicMintBatch: amount exceeds supply");
        require(
            publicPrice(amount) == msg.value,
            " ATEMPen#publicMintBatch: incorrect payment value"
        );

        while (_currentSupply < _targetSupply) {
            super._safeMint(to, _currentSupply, "");
            unchecked {
                _currentSupply += 1;
            }
        }

        _supplyTracker.setValue(_currentSupply);
    }

    /** Merkle tree helpers */
    
    function _leaf(address account)
    internal pure returns (bytes32)
    {
        return keccak256(abi.encodePacked(account));
    }

    function _verify(bytes32 leaf, bytes32[] memory proof)
    internal view returns (bool)
    {
        return MerkleProof.verify(proof, whitelistRoot, leaf);
    }

    /** Setters */ 

    function setMerkleRoot(bytes32 newRoot) onlyOwner external {
        whitelistRoot = newRoot;
    }

    function setBaseTokenURI(string calldata newBaseURI) onlyOwner external {
        _baseTokenURI = newBaseURI;
    }

    function setPlatformFeeAccount(address account) onlyOwner external {
        platformFeeAccount = account;
    }

    function openWhitelistSale() onlyOwner external {
        require(!whitelistSale, "ATEMPen#openWhitelistSale: whitelist sale already opened");
        whitelistSale = true;
    }

    function closeWhitelistSale() onlyOwner external {
        require(whitelistSale, "ATEMPen#closeWhitelistSale: whitelist sale already closed");
        whitelistSale = false;
    }

    function openPublicSale() onlyOwner external {
        require(!publicSale, "ATEMPen#openPublicSale: public sale already opened");
        publicSale = true;
    }

    function closePublicSale() onlyOwner external {
        require(publicSale, "ATEMPen#closePublicSale: public sale already closed");
        publicSale = false;
    }

    function setNumWhitelist(uint256 value) onlyOwner external {
        numWhitelist = value;
    }

    function setNumReserved(uint256 value) onlyOwner external {
        numReserved = value;
    }

    function setWhitelistPrice(uint256 value) onlyOwner external {
        _priceWhitelist = value;
    }

    function setPublicPrice(uint256 value) onlyOwner external {
        _pricePublic = value;
    }

    /** Viewers */

    function checkClaimable(address account, uint256 amount) public view returns (bool) {
        return _claimedNum[account] + amount <= maxClaimNum;
    }

    function claimedNum(address account) public view returns (uint256) {
        return _claimedNum[account];
    }


    function currentSupply() public view returns (uint256) {
        return _supplyTracker.current();
    }

    function whitelistPrice(uint256 amount) public view returns (uint256) {
        require(amount > 0, "ATEMPen#whitelistPrice: invalid amount");
        return _priceWhitelist * amount;
    }

    function publicPrice(uint256 amount) public view returns (uint256) {
        require(amount > 0, "ATEMPen#publicPrice: invalid amount");
        return _pricePublic * amount;
    }

    /** ---  */

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

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    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(), ".json")) : "";
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"baseTokenURI_","type":"string"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"whitelistNum","type":"uint256"},{"internalType":"uint256","name":"reservedNum","type":"uint256"},{"internalType":"uint256","name":"whitelistPrice_","type":"uint256"},{"internalType":"uint256","name":"publicPrice_","type":"uint256"},{"internalType":"uint256","name":"maxClaimNum_","type":"uint256"},{"internalType":"address","name":"platformAccount","type":"address"},{"internalType":"bytes32","name":"merkleroot","type":"bytes32"}],"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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"checkClaimable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"claimedNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closePublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closeWhitelistSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxClaimNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numWhitelist","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openWhitelistSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFeeAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"publicMintBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"publicPrice","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":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setNumReserved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setNumWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setPlatformFeeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setPublicPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setWhitelistPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":"address","name":"to","type":"address"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistMintBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"whitelistPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040523480156200001157600080fd5b506040516200322a3803806200322a8339810160408190526200003491620001f6565b8a8a6200004133620000c4565b60016200004f83826200037e565b5060026200005e82826200037e565b50600891506200007190508a826200037e565b50600955608096909652600b805461ffff19169055600c94909455600d92909255600e55600f5560a052601080546001600160a01b0319166001600160a01b03909216919091179055506200044a915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200013c57600080fd5b81516001600160401b038082111562000159576200015962000114565b604051601f8301601f19908116603f0116810190828211818310171562000184576200018462000114565b81604052838152602092508683858801011115620001a157600080fd5b600091505b83821015620001c55785820183015181830184015290820190620001a6565b600093810190920192909252949350505050565b80516001600160a01b0381168114620001f157600080fd5b919050565b60008060008060008060008060008060006101608c8e0312156200021957600080fd5b8b516001600160401b038111156200023057600080fd5b6200023e8e828f016200012a565b60208e0151909c5090506001600160401b038111156200025d57600080fd5b6200026b8e828f016200012a565b60408e0151909b5090506001600160401b038111156200028a57600080fd5b620002988e828f016200012a565b99505060608c0151975060808c0151965060a08c0151955060c08c0151945060e08c015193506101008c01519250620002d56101208d01620001d9565b91506101408c015190509295989b509295989b9093969950565b600181811c908216806200030457607f821691505b6020821081036200032557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200037957600081815260208120601f850160051c81016020861015620003545750805b601f850160051c820191505b81811015620003755782815560010162000360565b5050505b505050565b81516001600160401b038111156200039a576200039a62000114565b620003b281620003ab8454620002ef565b846200032b565b602080601f831160018114620003ea5760008415620003d15750858301515b600019600386901b1c1916600185901b17855562000375565b600085815260208120601f198616915b828110156200041b57888601518255948401946001909101908401620003fa565b50858210156200043a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051612da562000485600039600081816106ae0152610f230152600081816107f501528181610b6a01526124e80152612da56000f3fe6080604052600436106102975760003560e01c8063717d57d31161015a578063af630c34116100c1578063c9a141c61161007a578063c9a141c6146107a3578063d597ff81146107c3578063d5abeb01146107e3578063e985e9c514610817578063eab8432214610860578063f2fde38b1461087657600080fd5b8063af630c3414610703578063b150a6f614610718578063b585209b1461072e578063b88d4fde14610743578063c627525514610763578063c87b56dd1461078357600080fd5b80638da5cb5b116101135780638da5cb5b1461064957806395d89b4114610667578063a22cb4651461067c578063a6428a5b1461069c578063a6b6e433146106d0578063ac713207146106e357600080fd5b8063717d57d3146105aa578063771282f6146105ca5780637cb64759146105df578063853828b6146105ff57806386ace87d146106145780638af2c0481461062957600080fd5b8063386bfc98116101fe57806361968951116101b757806361968951146104ec5780636352211e146105225780636a6278421461054257806370a08231146105625780637142a99a14610582578063715018a61461059557600080fd5b8063386bfc9814610428578063388d9e5a1461044c57806342842e0e1461046c57806342966c681461048c5780635b896efe146104ac5780635ef9ebe3146104cc57600080fd5b80632af89179116102505780632af89179146103875780632e1a7d4d1461039c57806330176e13146103bc57806331ffd6f1146103dc57806332a93a3a146103f657806333bc1c5c1461040957600080fd5b806301ffc9a7146102a357806306fdde03146102d8578063081812fc146102fa578063095ea7b3146103325780630a0d05931461035457806323b872dd1461036757600080fd5b3661029e57005b600080fd5b3480156102af57600080fd5b506102c36102be36600461262b565b610896565b60405190151581526020015b60405180910390f35b3480156102e457600080fd5b506102ed6108a7565b6040516102cf9190612698565b34801561030657600080fd5b5061031a6103153660046126ab565b610939565b6040516001600160a01b0390911681526020016102cf565b34801561033e57600080fd5b5061035261034d3660046126e0565b610960565b005b6103526103623660046126e0565b610a7a565b34801561037357600080fd5b5061035261038236600461270a565b610cab565b34801561039357600080fd5b50610352610cdd565b3480156103a857600080fd5b506103526103b73660046126ab565b610d65565b3480156103c857600080fd5b506103526103d7366004612746565b610d93565b3480156103e857600080fd5b50600b546102c39060ff1681565b6103526104043660046127b8565b610da8565b34801561041557600080fd5b50600b546102c390610100900460ff1681565b34801561043457600080fd5b5061043e60095481565b6040519081526020016102cf565b34801561045857600080fd5b506103526104673660046127b8565b610e95565b34801561047857600080fd5b5061035261048736600461270a565b610ebf565b34801561049857600080fd5b506103526104a73660046126ab565b610eda565b3480156104b857600080fd5b506102c36104c73660046126e0565b610f08565b3480156104d857600080fd5b506103526104e73660046126ab565b610f57565b3480156104f857600080fd5b5061043e6105073660046127b8565b6001600160a01b03166000908152600a602052604090205490565b34801561052e57600080fd5b5061031a61053d3660046126ab565b610f64565b34801561054e57600080fd5b5061035261055d3660046127b8565b610fc4565b34801561056e57600080fd5b5061043e61057d3660046127b8565b610fcc565b61035261059036600461281f565b611052565b3480156105a157600080fd5b506103526113cd565b3480156105b657600080fd5b506103526105c53660046126ab565b6113e1565b3480156105d657600080fd5b5061043e6113ee565b3480156105eb57600080fd5b506103526105fa3660046126ab565b6113fe565b34801561060b57600080fd5b5061035261140b565b34801561062057600080fd5b50610352611429565b34801561063557600080fd5b5060105461031a906001600160a01b031681565b34801561065557600080fd5b506000546001600160a01b031661031a565b34801561067357600080fd5b506102ed6114b5565b34801561068857600080fd5b50610352610697366004612879565b6114c4565b3480156106a857600080fd5b5061043e7f000000000000000000000000000000000000000000000000000000000000000081565b6103526106de3660046128b5565b6114d3565b3480156106ef57600080fd5b506103526106fe3660046126ab565b611740565b34801561070f57600080fd5b5061035261174d565b34801561072457600080fd5b5061043e600d5481565b34801561073a57600080fd5b506103526117dd565b34801561074f57600080fd5b5061035261075e36600461291e565b611869565b34801561076f57600080fd5b5061035261077e3660046126ab565b61189b565b34801561078f57600080fd5b506102ed61079e3660046126ab565b6118a8565b3480156107af57600080fd5b5061043e6107be3660046126ab565b61190f565b3480156107cf57600080fd5b5061043e6107de3660046126ab565b61197a565b3480156107ef57600080fd5b5061043e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561082357600080fd5b506102c36108323660046129fa565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b34801561086c57600080fd5b5061043e600c5481565b34801561088257600080fd5b506103526108913660046127b8565b6119e8565b60006108a182611a5e565b92915050565b6060600180546108b690612a2d565b80601f01602080910402602001604051908101604052809291908181526020018280546108e290612a2d565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b5050505050905090565b600061094482611aae565b506000908152600560205260409020546001600160a01b031690565b600061096b82610f64565b9050806001600160a01b0316836001600160a01b0316036109dd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806109f957506109f98133610832565b610a6b5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016109d4565b610a758383611b0d565b505050565b600b54610100900460ff16610aed5760405162461bcd60e51b815260206004820152603360248201527f4154454d50656e237075626c69634d696e7442617463683a207075626c69632060448201527273616c65206973206e6f74206f70656e696e6760681b60648201526084016109d4565b60008111610b4d5760405162461bcd60e51b815260206004820152602760248201527f4154454d50656e237075626c69634d696e7442617463683a20696e76616c696460448201526608185b5bdd5b9d60ca1b60648201526084016109d4565b6000610b5860075490565b90506000610b668383612a7d565b90507f0000000000000000000000000000000000000000000000000000000000000000600d5482610b979190612a7d565b1115610bfc5760405162461bcd60e51b815260206004820152602e60248201527f4154454d50656e237075626c69634d696e7442617463683a20616d6f756e742060448201526d6578636565647320737570706c7960901b60648201526084016109d4565b34610c068461190f565b14610c6d5760405162461bcd60e51b815260206004820152603160248201527f204154454d50656e237075626c69634d696e7442617463683a20696e636f7272604482015270656374207061796d656e742076616c756560781b60648201526084016109d4565b80821015610c9a57610c8f848360405180602001604052806000815250611b7b565b600182019150610c6d565b610ca5600783611bae565b50505050565b610cb6335b82611c02565b610cd25760405162461bcd60e51b81526004016109d490612a90565b610a75838383611c81565b610ce5611e1d565b600b54610100900460ff16610d585760405162461bcd60e51b815260206004820152603360248201527f4154454d50656e23636c6f73655075626c696353616c653a207075626c6963206044820152721cd85b1948185b1c9958591e4818db1bdcd959606a1b60648201526084016109d4565b600b805461ff0019169055565b610d6d611e1d565b80471015610d7a57600080fd5b601054610d90906001600160a01b031682611e77565b50565b610d9b611e1d565b6008610a75828483612b2c565b600b54610100900460ff16610e165760405162461bcd60e51b815260206004820152602e60248201527f4154454d50656e237075626c69634d696e743a207075626c69632073616c652060448201526d6973206e6f74206f70656e696e6760901b60648201526084016109d4565b34610e21600161190f565b14610e835760405162461bcd60e51b815260206004820152602c60248201527f204154454d50656e237075626c69634d696e743a20696e636f7272656374207060448201526b61796d656e742076616c756560a01b60648201526084016109d4565b610d9081610e9060075490565b611f3f565b610e9d611e1d565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b610a7583838360405180602001604052806000815250611869565b610ee333610cb0565b610eff5760405162461bcd60e51b81526004016109d490612a90565b610d9081611f59565b6001600160a01b0382166000908152600a60205260408120547f000000000000000000000000000000000000000000000000000000000000000090610f4e908490612a7d565b11159392505050565b610f5f611e1d565b600c55565b6000818152600360205260408120546001600160a01b0316806108a15760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109d4565b610e83611e1d565b60006001600160a01b0382166110365760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016109d4565b506001600160a01b031660009081526004602052604090205490565b600b5460ff166110ca5760405162461bcd60e51b815260206004820152603960248201527f4154454d50656e2377686974656c6973744d696e7442617463683a207768697460448201527f656c697374206d696e74206973206e6f74206f70656e696e670000000000000060648201526084016109d4565b600083116111295760405162461bcd60e51b815260206004820152602660248201527f4154454d50656e2377686974654d696e7442617463683a20696e76616c696420604482015265185b5bdd5b9d60d21b60648201526084016109d4565b61116e61113585611ff4565b83838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061203392505050565b6111d35760405162461bcd60e51b815260206004820152603060248201527f4154454d50656e2377686974656c6973744d696e7442617463683a20696e766160448201526f3634b21036b2b935b63290383937b7b360811b60648201526084016109d4565b6111dd8484610f08565b6112595760405162461bcd60e51b815260206004820152604160248201527f4154454d50656e2377686974656c6973744d696e7442617463683a207265616360448201527f68656420796f7572206d6178696d756d20636c61696d61626c65206e756d62656064820152603960f91b608482015260a4016109d4565b600061126460075490565b905060006112728583612a7d565b9050600c548111156112ec5760405162461bcd60e51b815260206004820152603b60248201527f4154454d50656e2377686974656c6973744d696e7442617463683a20616d6f7560448201527f6e7420657863656564732077686974656c69737420737570706c79000000000060648201526084016109d4565b346112f68661197a565b146113605760405162461bcd60e51b815260206004820152603460248201527f204154454d50656e2377686974656c6973744d696e7442617463683a20696e636044820152736f7272656374207061796d656e742076616c756560601b60648201526084016109d4565b8082101561138d57611382868360405180602001604052806000815250611b7b565b600182019150611360565b611398600783611bae565b6001600160a01b0386166000908152600a6020526040812080548792906113c0908490612a7d565b9091555050505050505050565b6113d5611e1d565b6113df6000612042565b565b6113e9611e1d565b600e55565b60006113f960075490565b905090565b611406611e1d565b600955565b611413611e1d565b6010546113df906001600160a01b031647611e77565b611431611e1d565b600b5460ff166114a95760405162461bcd60e51b815260206004820152603960248201527f4154454d50656e23636c6f736557686974656c69737453616c653a207768697460448201527f656c6973742073616c6520616c726561647920636c6f7365640000000000000060648201526084016109d4565b600b805460ff19169055565b6060600280546108b690612a2d565b6114cf338383612092565b5050565b600b5460ff166115425760405162461bcd60e51b815260206004820152603460248201527f4154454d50656e2377686974656c6973744d696e743a2077686974656c697374604482015273206d696e74206973206e6f74206f70656e696e6760601b60648201526084016109d4565b600c54600754106115a75760405162461bcd60e51b815260206004820152602960248201527f4154454d50656e2377686974656c6973744d696e743a2077686974656c697374604482015268081cdbdb19081bdd5d60ba1b60648201526084016109d4565b6115b361113584611ff4565b6116135760405162461bcd60e51b815260206004820152602b60248201527f4154454d50656e2377686974656c6973744d696e743a20696e76616c6964206d60448201526a32b935b63290383937b7b360a91b60648201526084016109d4565b61161e836001610f08565b6116905760405162461bcd60e51b815260206004820152603c60248201527f4154454d50656e2377686974656c6973744d696e743a2072656163686564207960448201527f6f7572206d6178696d756d20636c61696d61626c65206e756d6265720000000060648201526084016109d4565b3461169b600161197a565b146117005760405162461bcd60e51b815260206004820152602f60248201527f204154454d50656e2377686974656c6973744d696e743a20696e636f7272656360448201526e74207061796d656e742076616c756560881b60648201526084016109d4565b61170d83610e9060075490565b6001600160a01b0383166000908152600a60205260408120805460019290611736908490612a7d565b9091555050505050565b611748611e1d565b600d55565b611755611e1d565b600b5460ff16156117ce5760405162461bcd60e51b815260206004820152603860248201527f4154454d50656e236f70656e57686974656c69737453616c653a20776869746560448201527f6c6973742073616c6520616c7265616479206f70656e6564000000000000000060648201526084016109d4565b600b805460ff19166001179055565b6117e5611e1d565b600b54610100900460ff16156118585760405162461bcd60e51b815260206004820152603260248201527f4154454d50656e236f70656e5075626c696353616c653a207075626c69632073604482015271185b1948185b1c9958591e481bdc195b995960721b60648201526084016109d4565b600b805461ff001916610100179055565b6118733383611c02565b61188f5760405162461bcd60e51b81526004016109d490612a90565b610ca584848484612160565b6118a3611e1d565b600f55565b60606118b382611aae565b60006118bd612193565b905060008151116118dd5760405180602001604052806000815250611908565b806118e7846121a2565b6040516020016118f8929190612bed565b6040516020818303038152906040525b9392505050565b600080821161196c5760405162461bcd60e51b815260206004820152602360248201527f4154454d50656e237075626c696350726963653a20696e76616c696420616d6f6044820152621d5b9d60ea1b60648201526084016109d4565b81600f546108a19190612c2c565b60008082116119da5760405162461bcd60e51b815260206004820152602660248201527f4154454d50656e2377686974656c69737450726963653a20696e76616c696420604482015265185b5bdd5b9d60d21b60648201526084016109d4565b81600e546108a19190612c2c565b6119f0611e1d565b6001600160a01b038116611a555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109d4565b610d9081612042565b60006001600160e01b031982166380ac58cd60e01b1480611a8f57506001600160e01b03198216635b5e139f60e01b145b806108a157506301ffc9a760e01b6001600160e01b03198316146108a1565b6000818152600360205260409020546001600160a01b0316610d905760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109d4565b600081815260056020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611b4282610f64565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611b8583836122a3565b611b9260008484846123e5565b610a755760405162461bcd60e51b81526004016109d490612c43565b60008111611bfe5760405162461bcd60e51b815260206004820152601b60248201527f436f756e7465723a20696e73756666696369656e742076616c7565000000000060448201526064016109d4565b9055565b600080611c0e83610f64565b9050806001600160a01b0316846001600160a01b03161480611c5557506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b80611c795750836001600160a01b0316611c6e84610939565b6001600160a01b0316145b949350505050565b826001600160a01b0316611c9482610f64565b6001600160a01b031614611cf85760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016109d4565b6001600160a01b038216611d5a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109d4565b611d65600082611b0d565b6001600160a01b0383166000908152600460205260408120805460019290611d8e908490612c95565b90915550506001600160a01b0382166000908152600460205260408120805460019290611dbc908490612a7d565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000546001600160a01b031633146113df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d4565b6001600160a01b03821615801590611e9857506001600160a01b0382163014155b8015611ea45750600081115b156114cf576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611ef6576040519150601f19603f3d011682016040523d82523d6000602084013e611efb565b606091505b5050905080610a755760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016109d4565b6114cf8282604051806020016040528060008152506124e6565b6000611f6482610f64565b9050611f71600083611b0d565b6001600160a01b0381166000908152600460205260408120805460019290611f9a908490612c95565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6040516bffffffffffffffffffffffff19606083901b166020820152600090603401604051602081830303815290604052805190602001209050919050565b60006119088260095485612583565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b0316036120f35760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109d4565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61216b848484611c81565b612177848484846123e5565b610ca55760405162461bcd60e51b81526004016109d490612c43565b6060600880546108b690612a2d565b6060816000036121c95750506040805180820190915260018152600360fc1b602082015290565b8160005b81156121f357806121dd81612ca8565b91506121ec9050600a83612cd7565b91506121cd565b60008167ffffffffffffffff81111561220e5761220e612908565b6040519080825280601f01601f191660200182016040528015612238576020820181803683370190505b5090505b8415611c795761224d600183612c95565b915061225a600a86612ceb565b612265906030612a7d565b60f81b81838151811061227a5761227a612cff565b60200101906001600160f81b031916908160001a90535061229c600a86612cd7565b945061223c565b6001600160a01b0382166122f95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109d4565b6000818152600360205260409020546001600160a01b03161561235e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109d4565b6001600160a01b0382166000908152600460205260408120805460019290612387908490612a7d565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b156124db57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612429903390899088908890600401612d15565b6020604051808303816000875af1925050508015612464575060408051601f3d908101601f1916820190925261246191810190612d52565b60015b6124c1573d808015612492576040519150601f19603f3d011682016040523d82523d6000602084013e612497565b606091505b5080516000036124b95760405162461bcd60e51b81526004016109d490612c43565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611c79565b506001949350505050565b7f0000000000000000000000000000000000000000000000000000000000000000600d5461251360075490565b61251d9190612a7d565b1061256a5760405162461bcd60e51b815260206004820152601b60248201527f4154454d50656e235f736166654d696e743a20736f6c64206f7574000000000060448201526064016109d4565b612575838383611b7b565b610a75600780546001019055565b6000826125908584612599565b14949350505050565b600081815b84518110156125de576125ca828683815181106125bd576125bd612cff565b60200260200101516125e6565b9150806125d681612ca8565b91505061259e565b509392505050565b6000818310612602576000828152602084905260409020611908565b6000838152602083905260409020611908565b6001600160e01b031981168114610d9057600080fd5b60006020828403121561263d57600080fd5b813561190881612615565b60005b8381101561266357818101518382015260200161264b565b50506000910152565b60008151808452612684816020860160208601612648565b601f01601f19169290920160200192915050565b602081526000611908602083018461266c565b6000602082840312156126bd57600080fd5b5035919050565b80356001600160a01b03811681146126db57600080fd5b919050565b600080604083850312156126f357600080fd5b6126fc836126c4565b946020939093013593505050565b60008060006060848603121561271f57600080fd5b612728846126c4565b9250612736602085016126c4565b9150604084013590509250925092565b6000806020838503121561275957600080fd5b823567ffffffffffffffff8082111561277157600080fd5b818501915085601f83011261278557600080fd5b81358181111561279457600080fd5b8660208285010111156127a657600080fd5b60209290920196919550909350505050565b6000602082840312156127ca57600080fd5b611908826126c4565b60008083601f8401126127e557600080fd5b50813567ffffffffffffffff8111156127fd57600080fd5b6020830191508360208260051b850101111561281857600080fd5b9250929050565b6000806000806060858703121561283557600080fd5b61283e856126c4565b935060208501359250604085013567ffffffffffffffff81111561286157600080fd5b61286d878288016127d3565b95989497509550505050565b6000806040838503121561288c57600080fd5b612895836126c4565b9150602083013580151581146128aa57600080fd5b809150509250929050565b6000806000604084860312156128ca57600080fd5b6128d3846126c4565b9250602084013567ffffffffffffffff8111156128ef57600080fd5b6128fb868287016127d3565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561293457600080fd5b61293d856126c4565b935061294b602086016126c4565b925060408501359150606085013567ffffffffffffffff8082111561296f57600080fd5b818701915087601f83011261298357600080fd5b81358181111561299557612995612908565b604051601f8201601f19908116603f011681019083821181831017156129bd576129bd612908565b816040528281528a60208487010111156129d657600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215612a0d57600080fd5b612a16836126c4565b9150612a24602084016126c4565b90509250929050565b600181811c90821680612a4157607f821691505b602082108103612a6157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156108a1576108a1612a67565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b601f821115610a7557600081815260208120601f850160051c81016020861015612b055750805b601f850160051c820191505b81811015612b2457828155600101612b11565b505050505050565b67ffffffffffffffff831115612b4457612b44612908565b612b5883612b528354612a2d565b83612ade565b6000601f841160018114612b8c5760008515612b745750838201355b600019600387901b1c1916600186901b178355612be6565b600083815260209020601f19861690835b82811015612bbd5786850135825560209485019460019092019101612b9d565b5086821015612bda5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008351612bff818460208801612648565b835190830190612c13818360208801612648565b64173539b7b760d91b9101908152600501949350505050565b80820281158282048414176108a1576108a1612a67565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b818103818111156108a1576108a1612a67565b600060018201612cba57612cba612a67565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082612ce657612ce6612cc1565b500490565b600082612cfa57612cfa612cc1565b500690565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d489083018461266c565b9695505050505050565b600060208284031215612d6457600080fd5b81516119088161261556fea2646970667358221220e894f1a6c4c526a6b2a1d32c59735d730d0d94b2abf8f9ed43a0f6bc6b06155e64736f6c63430008110033000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000177000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c85754912b3bdc68151eb32b882f7a0de8a6ddae0ece95355eadc5f7de7f956090902a989a77103cb3d8d5edfe1416dbc59a280b00000000000000000000000000000000000000000000000000000000000000084174656d2050656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044150454e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d68747470733a2f2f697066732e66696c65626173652e696f2f697066732f516d51504b34615150576b6563433536516f4732334436645158474d426b456633374a6165714a465142696a64592f00000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102975760003560e01c8063717d57d31161015a578063af630c34116100c1578063c9a141c61161007a578063c9a141c6146107a3578063d597ff81146107c3578063d5abeb01146107e3578063e985e9c514610817578063eab8432214610860578063f2fde38b1461087657600080fd5b8063af630c3414610703578063b150a6f614610718578063b585209b1461072e578063b88d4fde14610743578063c627525514610763578063c87b56dd1461078357600080fd5b80638da5cb5b116101135780638da5cb5b1461064957806395d89b4114610667578063a22cb4651461067c578063a6428a5b1461069c578063a6b6e433146106d0578063ac713207146106e357600080fd5b8063717d57d3146105aa578063771282f6146105ca5780637cb64759146105df578063853828b6146105ff57806386ace87d146106145780638af2c0481461062957600080fd5b8063386bfc98116101fe57806361968951116101b757806361968951146104ec5780636352211e146105225780636a6278421461054257806370a08231146105625780637142a99a14610582578063715018a61461059557600080fd5b8063386bfc9814610428578063388d9e5a1461044c57806342842e0e1461046c57806342966c681461048c5780635b896efe146104ac5780635ef9ebe3146104cc57600080fd5b80632af89179116102505780632af89179146103875780632e1a7d4d1461039c57806330176e13146103bc57806331ffd6f1146103dc57806332a93a3a146103f657806333bc1c5c1461040957600080fd5b806301ffc9a7146102a357806306fdde03146102d8578063081812fc146102fa578063095ea7b3146103325780630a0d05931461035457806323b872dd1461036757600080fd5b3661029e57005b600080fd5b3480156102af57600080fd5b506102c36102be36600461262b565b610896565b60405190151581526020015b60405180910390f35b3480156102e457600080fd5b506102ed6108a7565b6040516102cf9190612698565b34801561030657600080fd5b5061031a6103153660046126ab565b610939565b6040516001600160a01b0390911681526020016102cf565b34801561033e57600080fd5b5061035261034d3660046126e0565b610960565b005b6103526103623660046126e0565b610a7a565b34801561037357600080fd5b5061035261038236600461270a565b610cab565b34801561039357600080fd5b50610352610cdd565b3480156103a857600080fd5b506103526103b73660046126ab565b610d65565b3480156103c857600080fd5b506103526103d7366004612746565b610d93565b3480156103e857600080fd5b50600b546102c39060ff1681565b6103526104043660046127b8565b610da8565b34801561041557600080fd5b50600b546102c390610100900460ff1681565b34801561043457600080fd5b5061043e60095481565b6040519081526020016102cf565b34801561045857600080fd5b506103526104673660046127b8565b610e95565b34801561047857600080fd5b5061035261048736600461270a565b610ebf565b34801561049857600080fd5b506103526104a73660046126ab565b610eda565b3480156104b857600080fd5b506102c36104c73660046126e0565b610f08565b3480156104d857600080fd5b506103526104e73660046126ab565b610f57565b3480156104f857600080fd5b5061043e6105073660046127b8565b6001600160a01b03166000908152600a602052604090205490565b34801561052e57600080fd5b5061031a61053d3660046126ab565b610f64565b34801561054e57600080fd5b5061035261055d3660046127b8565b610fc4565b34801561056e57600080fd5b5061043e61057d3660046127b8565b610fcc565b61035261059036600461281f565b611052565b3480156105a157600080fd5b506103526113cd565b3480156105b657600080fd5b506103526105c53660046126ab565b6113e1565b3480156105d657600080fd5b5061043e6113ee565b3480156105eb57600080fd5b506103526105fa3660046126ab565b6113fe565b34801561060b57600080fd5b5061035261140b565b34801561062057600080fd5b50610352611429565b34801561063557600080fd5b5060105461031a906001600160a01b031681565b34801561065557600080fd5b506000546001600160a01b031661031a565b34801561067357600080fd5b506102ed6114b5565b34801561068857600080fd5b50610352610697366004612879565b6114c4565b3480156106a857600080fd5b5061043e7f000000000000000000000000000000000000000000000000000000000000000281565b6103526106de3660046128b5565b6114d3565b3480156106ef57600080fd5b506103526106fe3660046126ab565b611740565b34801561070f57600080fd5b5061035261174d565b34801561072457600080fd5b5061043e600d5481565b34801561073a57600080fd5b506103526117dd565b34801561074f57600080fd5b5061035261075e36600461291e565b611869565b34801561076f57600080fd5b5061035261077e3660046126ab565b61189b565b34801561078f57600080fd5b506102ed61079e3660046126ab565b6118a8565b3480156107af57600080fd5b5061043e6107be3660046126ab565b61190f565b3480156107cf57600080fd5b5061043e6107de3660046126ab565b61197a565b3480156107ef57600080fd5b5061043e7f000000000000000000000000000000000000000000000000000000000000177081565b34801561082357600080fd5b506102c36108323660046129fa565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b34801561086c57600080fd5b5061043e600c5481565b34801561088257600080fd5b506103526108913660046127b8565b6119e8565b60006108a182611a5e565b92915050565b6060600180546108b690612a2d565b80601f01602080910402602001604051908101604052809291908181526020018280546108e290612a2d565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b5050505050905090565b600061094482611aae565b506000908152600560205260409020546001600160a01b031690565b600061096b82610f64565b9050806001600160a01b0316836001600160a01b0316036109dd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806109f957506109f98133610832565b610a6b5760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016109d4565b610a758383611b0d565b505050565b600b54610100900460ff16610aed5760405162461bcd60e51b815260206004820152603360248201527f4154454d50656e237075626c69634d696e7442617463683a207075626c69632060448201527273616c65206973206e6f74206f70656e696e6760681b60648201526084016109d4565b60008111610b4d5760405162461bcd60e51b815260206004820152602760248201527f4154454d50656e237075626c69634d696e7442617463683a20696e76616c696460448201526608185b5bdd5b9d60ca1b60648201526084016109d4565b6000610b5860075490565b90506000610b668383612a7d565b90507f0000000000000000000000000000000000000000000000000000000000001770600d5482610b979190612a7d565b1115610bfc5760405162461bcd60e51b815260206004820152602e60248201527f4154454d50656e237075626c69634d696e7442617463683a20616d6f756e742060448201526d6578636565647320737570706c7960901b60648201526084016109d4565b34610c068461190f565b14610c6d5760405162461bcd60e51b815260206004820152603160248201527f204154454d50656e237075626c69634d696e7442617463683a20696e636f7272604482015270656374207061796d656e742076616c756560781b60648201526084016109d4565b80821015610c9a57610c8f848360405180602001604052806000815250611b7b565b600182019150610c6d565b610ca5600783611bae565b50505050565b610cb6335b82611c02565b610cd25760405162461bcd60e51b81526004016109d490612a90565b610a75838383611c81565b610ce5611e1d565b600b54610100900460ff16610d585760405162461bcd60e51b815260206004820152603360248201527f4154454d50656e23636c6f73655075626c696353616c653a207075626c6963206044820152721cd85b1948185b1c9958591e4818db1bdcd959606a1b60648201526084016109d4565b600b805461ff0019169055565b610d6d611e1d565b80471015610d7a57600080fd5b601054610d90906001600160a01b031682611e77565b50565b610d9b611e1d565b6008610a75828483612b2c565b600b54610100900460ff16610e165760405162461bcd60e51b815260206004820152602e60248201527f4154454d50656e237075626c69634d696e743a207075626c69632073616c652060448201526d6973206e6f74206f70656e696e6760901b60648201526084016109d4565b34610e21600161190f565b14610e835760405162461bcd60e51b815260206004820152602c60248201527f204154454d50656e237075626c69634d696e743a20696e636f7272656374207060448201526b61796d656e742076616c756560a01b60648201526084016109d4565b610d9081610e9060075490565b611f3f565b610e9d611e1d565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b610a7583838360405180602001604052806000815250611869565b610ee333610cb0565b610eff5760405162461bcd60e51b81526004016109d490612a90565b610d9081611f59565b6001600160a01b0382166000908152600a60205260408120547f000000000000000000000000000000000000000000000000000000000000000290610f4e908490612a7d565b11159392505050565b610f5f611e1d565b600c55565b6000818152600360205260408120546001600160a01b0316806108a15760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109d4565b610e83611e1d565b60006001600160a01b0382166110365760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016109d4565b506001600160a01b031660009081526004602052604090205490565b600b5460ff166110ca5760405162461bcd60e51b815260206004820152603960248201527f4154454d50656e2377686974656c6973744d696e7442617463683a207768697460448201527f656c697374206d696e74206973206e6f74206f70656e696e670000000000000060648201526084016109d4565b600083116111295760405162461bcd60e51b815260206004820152602660248201527f4154454d50656e2377686974654d696e7442617463683a20696e76616c696420604482015265185b5bdd5b9d60d21b60648201526084016109d4565b61116e61113585611ff4565b83838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061203392505050565b6111d35760405162461bcd60e51b815260206004820152603060248201527f4154454d50656e2377686974656c6973744d696e7442617463683a20696e766160448201526f3634b21036b2b935b63290383937b7b360811b60648201526084016109d4565b6111dd8484610f08565b6112595760405162461bcd60e51b815260206004820152604160248201527f4154454d50656e2377686974656c6973744d696e7442617463683a207265616360448201527f68656420796f7572206d6178696d756d20636c61696d61626c65206e756d62656064820152603960f91b608482015260a4016109d4565b600061126460075490565b905060006112728583612a7d565b9050600c548111156112ec5760405162461bcd60e51b815260206004820152603b60248201527f4154454d50656e2377686974656c6973744d696e7442617463683a20616d6f7560448201527f6e7420657863656564732077686974656c69737420737570706c79000000000060648201526084016109d4565b346112f68661197a565b146113605760405162461bcd60e51b815260206004820152603460248201527f204154454d50656e2377686974656c6973744d696e7442617463683a20696e636044820152736f7272656374207061796d656e742076616c756560601b60648201526084016109d4565b8082101561138d57611382868360405180602001604052806000815250611b7b565b600182019150611360565b611398600783611bae565b6001600160a01b0386166000908152600a6020526040812080548792906113c0908490612a7d565b9091555050505050505050565b6113d5611e1d565b6113df6000612042565b565b6113e9611e1d565b600e55565b60006113f960075490565b905090565b611406611e1d565b600955565b611413611e1d565b6010546113df906001600160a01b031647611e77565b611431611e1d565b600b5460ff166114a95760405162461bcd60e51b815260206004820152603960248201527f4154454d50656e23636c6f736557686974656c69737453616c653a207768697460448201527f656c6973742073616c6520616c726561647920636c6f7365640000000000000060648201526084016109d4565b600b805460ff19169055565b6060600280546108b690612a2d565b6114cf338383612092565b5050565b600b5460ff166115425760405162461bcd60e51b815260206004820152603460248201527f4154454d50656e2377686974656c6973744d696e743a2077686974656c697374604482015273206d696e74206973206e6f74206f70656e696e6760601b60648201526084016109d4565b600c54600754106115a75760405162461bcd60e51b815260206004820152602960248201527f4154454d50656e2377686974656c6973744d696e743a2077686974656c697374604482015268081cdbdb19081bdd5d60ba1b60648201526084016109d4565b6115b361113584611ff4565b6116135760405162461bcd60e51b815260206004820152602b60248201527f4154454d50656e2377686974656c6973744d696e743a20696e76616c6964206d60448201526a32b935b63290383937b7b360a91b60648201526084016109d4565b61161e836001610f08565b6116905760405162461bcd60e51b815260206004820152603c60248201527f4154454d50656e2377686974656c6973744d696e743a2072656163686564207960448201527f6f7572206d6178696d756d20636c61696d61626c65206e756d6265720000000060648201526084016109d4565b3461169b600161197a565b146117005760405162461bcd60e51b815260206004820152602f60248201527f204154454d50656e2377686974656c6973744d696e743a20696e636f7272656360448201526e74207061796d656e742076616c756560881b60648201526084016109d4565b61170d83610e9060075490565b6001600160a01b0383166000908152600a60205260408120805460019290611736908490612a7d565b9091555050505050565b611748611e1d565b600d55565b611755611e1d565b600b5460ff16156117ce5760405162461bcd60e51b815260206004820152603860248201527f4154454d50656e236f70656e57686974656c69737453616c653a20776869746560448201527f6c6973742073616c6520616c7265616479206f70656e6564000000000000000060648201526084016109d4565b600b805460ff19166001179055565b6117e5611e1d565b600b54610100900460ff16156118585760405162461bcd60e51b815260206004820152603260248201527f4154454d50656e236f70656e5075626c696353616c653a207075626c69632073604482015271185b1948185b1c9958591e481bdc195b995960721b60648201526084016109d4565b600b805461ff001916610100179055565b6118733383611c02565b61188f5760405162461bcd60e51b81526004016109d490612a90565b610ca584848484612160565b6118a3611e1d565b600f55565b60606118b382611aae565b60006118bd612193565b905060008151116118dd5760405180602001604052806000815250611908565b806118e7846121a2565b6040516020016118f8929190612bed565b6040516020818303038152906040525b9392505050565b600080821161196c5760405162461bcd60e51b815260206004820152602360248201527f4154454d50656e237075626c696350726963653a20696e76616c696420616d6f6044820152621d5b9d60ea1b60648201526084016109d4565b81600f546108a19190612c2c565b60008082116119da5760405162461bcd60e51b815260206004820152602660248201527f4154454d50656e2377686974656c69737450726963653a20696e76616c696420604482015265185b5bdd5b9d60d21b60648201526084016109d4565b81600e546108a19190612c2c565b6119f0611e1d565b6001600160a01b038116611a555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109d4565b610d9081612042565b60006001600160e01b031982166380ac58cd60e01b1480611a8f57506001600160e01b03198216635b5e139f60e01b145b806108a157506301ffc9a760e01b6001600160e01b03198316146108a1565b6000818152600360205260409020546001600160a01b0316610d905760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016109d4565b600081815260056020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611b4282610f64565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611b8583836122a3565b611b9260008484846123e5565b610a755760405162461bcd60e51b81526004016109d490612c43565b60008111611bfe5760405162461bcd60e51b815260206004820152601b60248201527f436f756e7465723a20696e73756666696369656e742076616c7565000000000060448201526064016109d4565b9055565b600080611c0e83610f64565b9050806001600160a01b0316846001600160a01b03161480611c5557506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b80611c795750836001600160a01b0316611c6e84610939565b6001600160a01b0316145b949350505050565b826001600160a01b0316611c9482610f64565b6001600160a01b031614611cf85760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016109d4565b6001600160a01b038216611d5a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109d4565b611d65600082611b0d565b6001600160a01b0383166000908152600460205260408120805460019290611d8e908490612c95565b90915550506001600160a01b0382166000908152600460205260408120805460019290611dbc908490612a7d565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000546001600160a01b031633146113df5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d4565b6001600160a01b03821615801590611e9857506001600160a01b0382163014155b8015611ea45750600081115b156114cf576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611ef6576040519150601f19603f3d011682016040523d82523d6000602084013e611efb565b606091505b5050905080610a755760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016109d4565b6114cf8282604051806020016040528060008152506124e6565b6000611f6482610f64565b9050611f71600083611b0d565b6001600160a01b0381166000908152600460205260408120805460019290611f9a908490612c95565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6040516bffffffffffffffffffffffff19606083901b166020820152600090603401604051602081830303815290604052805190602001209050919050565b60006119088260095485612583565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b0316036120f35760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109d4565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61216b848484611c81565b612177848484846123e5565b610ca55760405162461bcd60e51b81526004016109d490612c43565b6060600880546108b690612a2d565b6060816000036121c95750506040805180820190915260018152600360fc1b602082015290565b8160005b81156121f357806121dd81612ca8565b91506121ec9050600a83612cd7565b91506121cd565b60008167ffffffffffffffff81111561220e5761220e612908565b6040519080825280601f01601f191660200182016040528015612238576020820181803683370190505b5090505b8415611c795761224d600183612c95565b915061225a600a86612ceb565b612265906030612a7d565b60f81b81838151811061227a5761227a612cff565b60200101906001600160f81b031916908160001a90535061229c600a86612cd7565b945061223c565b6001600160a01b0382166122f95760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109d4565b6000818152600360205260409020546001600160a01b03161561235e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109d4565b6001600160a01b0382166000908152600460205260408120805460019290612387908490612a7d565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160a01b0384163b156124db57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612429903390899088908890600401612d15565b6020604051808303816000875af1925050508015612464575060408051601f3d908101601f1916820190925261246191810190612d52565b60015b6124c1573d808015612492576040519150601f19603f3d011682016040523d82523d6000602084013e612497565b606091505b5080516000036124b95760405162461bcd60e51b81526004016109d490612c43565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611c79565b506001949350505050565b7f0000000000000000000000000000000000000000000000000000000000001770600d5461251360075490565b61251d9190612a7d565b1061256a5760405162461bcd60e51b815260206004820152601b60248201527f4154454d50656e235f736166654d696e743a20736f6c64206f7574000000000060448201526064016109d4565b612575838383611b7b565b610a75600780546001019055565b6000826125908584612599565b14949350505050565b600081815b84518110156125de576125ca828683815181106125bd576125bd612cff565b60200260200101516125e6565b9150806125d681612ca8565b91505061259e565b509392505050565b6000818310612602576000828152602084905260409020611908565b6000838152602083905260409020611908565b6001600160e01b031981168114610d9057600080fd5b60006020828403121561263d57600080fd5b813561190881612615565b60005b8381101561266357818101518382015260200161264b565b50506000910152565b60008151808452612684816020860160208601612648565b601f01601f19169290920160200192915050565b602081526000611908602083018461266c565b6000602082840312156126bd57600080fd5b5035919050565b80356001600160a01b03811681146126db57600080fd5b919050565b600080604083850312156126f357600080fd5b6126fc836126c4565b946020939093013593505050565b60008060006060848603121561271f57600080fd5b612728846126c4565b9250612736602085016126c4565b9150604084013590509250925092565b6000806020838503121561275957600080fd5b823567ffffffffffffffff8082111561277157600080fd5b818501915085601f83011261278557600080fd5b81358181111561279457600080fd5b8660208285010111156127a657600080fd5b60209290920196919550909350505050565b6000602082840312156127ca57600080fd5b611908826126c4565b60008083601f8401126127e557600080fd5b50813567ffffffffffffffff8111156127fd57600080fd5b6020830191508360208260051b850101111561281857600080fd5b9250929050565b6000806000806060858703121561283557600080fd5b61283e856126c4565b935060208501359250604085013567ffffffffffffffff81111561286157600080fd5b61286d878288016127d3565b95989497509550505050565b6000806040838503121561288c57600080fd5b612895836126c4565b9150602083013580151581146128aa57600080fd5b809150509250929050565b6000806000604084860312156128ca57600080fd5b6128d3846126c4565b9250602084013567ffffffffffffffff8111156128ef57600080fd5b6128fb868287016127d3565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561293457600080fd5b61293d856126c4565b935061294b602086016126c4565b925060408501359150606085013567ffffffffffffffff8082111561296f57600080fd5b818701915087601f83011261298357600080fd5b81358181111561299557612995612908565b604051601f8201601f19908116603f011681019083821181831017156129bd576129bd612908565b816040528281528a60208487010111156129d657600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215612a0d57600080fd5b612a16836126c4565b9150612a24602084016126c4565b90509250929050565b600181811c90821680612a4157607f821691505b602082108103612a6157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156108a1576108a1612a67565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b601f821115610a7557600081815260208120601f850160051c81016020861015612b055750805b601f850160051c820191505b81811015612b2457828155600101612b11565b505050505050565b67ffffffffffffffff831115612b4457612b44612908565b612b5883612b528354612a2d565b83612ade565b6000601f841160018114612b8c5760008515612b745750838201355b600019600387901b1c1916600186901b178355612be6565b600083815260209020601f19861690835b82811015612bbd5786850135825560209485019460019092019101612b9d565b5086821015612bda5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60008351612bff818460208801612648565b835190830190612c13818360208801612648565b64173539b7b760d91b9101908152600501949350505050565b80820281158282048414176108a1576108a1612a67565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b818103818111156108a1576108a1612a67565b600060018201612cba57612cba612a67565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082612ce657612ce6612cc1565b500490565b600082612cfa57612cfa612cc1565b500690565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d489083018461266c565b9695505050505050565b600060208284031215612d6457600080fd5b81516119088161261556fea2646970667358221220e894f1a6c4c526a6b2a1d32c59735d730d0d94b2abf8f9ed43a0f6bc6b06155e64736f6c63430008110033

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

000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000177000000000000000000000000000000000000000000000000000000000000007d000000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c85754912b3bdc68151eb32b882f7a0de8a6ddae0ece95355eadc5f7de7f956090902a989a77103cb3d8d5edfe1416dbc59a280b00000000000000000000000000000000000000000000000000000000000000084174656d2050656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044150454e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d68747470733a2f2f697066732e66696c65626173652e696f2f697066732f516d51504b34615150576b6563433536516f4732334436645158474d426b456633374a6165714a465142696a64592f00000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): Atem Pen
Arg [1] : symbol (string): APEN
Arg [2] : baseTokenURI_ (string): https://ipfs.filebase.io/ipfs/QmQPK4aQPWkecC56QoG23D6dQXGMBkEf37JaeqJFQBijdY/
Arg [3] : supply (uint256): 6000
Arg [4] : whitelistNum (uint256): 2000
Arg [5] : reservedNum (uint256): 1000
Arg [6] : whitelistPrice_ (uint256): 0
Arg [7] : publicPrice_ (uint256): 30000000000000000
Arg [8] : maxClaimNum_ (uint256): 2
Arg [9] : platformAccount (address): 0xc85754912B3bDC68151EB32B882F7a0De8A6DDAE
Arg [10] : merkleroot (bytes32): 0x0ece95355eadc5f7de7f956090902a989a77103cb3d8d5edfe1416dbc59a280b

-----Encoded View---------------
19 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000001770
Arg [4] : 00000000000000000000000000000000000000000000000000000000000007d0
Arg [5] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 000000000000000000000000000000000000000000000000006a94d74f430000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [9] : 000000000000000000000000c85754912b3bdc68151eb32b882f7a0de8a6ddae
Arg [10] : 0ece95355eadc5f7de7f956090902a989a77103cb3d8d5edfe1416dbc59a280b
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [12] : 4174656d2050656e000000000000000000000000000000000000000000000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [14] : 4150454e00000000000000000000000000000000000000000000000000000000
Arg [15] : 000000000000000000000000000000000000000000000000000000000000004d
Arg [16] : 68747470733a2f2f697066732e66696c65626173652e696f2f697066732f516d
Arg [17] : 51504b34615150576b6563433536516f4732334436645158474d426b45663337
Arg [18] : 4a6165714a465142696a64592f00000000000000000000000000000000000000


Deployed Bytecode Sourcemap

48863:9764:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58165:161;;;;;;;;;;-1:-1:-1;58165:161:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;58165:161:0;;;;;;;;22921:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;24434:171::-;;;;;;;;;;-1:-1:-1;24434:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;24434:171:0;1533:203:1;23951:417:0;;;;;;;;;;-1:-1:-1;23951:417:0;;;;;:::i;:::-;;:::i;:::-;;54390:867;;;;;;:::i;:::-;;:::i;25134:336::-;;;;;;;;;;-1:-1:-1;25134:336:0;;;;;:::i;:::-;;:::i;56554:168::-;;;;;;;;;;;;;:::i;51266:160::-;;;;;;;;;;-1:-1:-1;51266:160:0;;;;;:::i;:::-;;:::i;55753:117::-;;;;;;;;;;-1:-1:-1;55753:117:0;;;;;:::i;:::-;;:::i;49543:25::-;;;;;;;;;;-1:-1:-1;49543:25:0;;;;;;;;54049:333;;;;;;:::i;:::-;;:::i;49575:22::-;;;;;;;;;;-1:-1:-1;49575:22:0;;;;;;;;;;;49094:28;;;;;;;;;;;;;;;;;;;3445:25:1;;;3433:2;3418:18;49094:28:0;3299:177:1;55878:114:0;;;;;;;;;;-1:-1:-1;55878:114:0;;;;;:::i;:::-;;:::i;25541:185::-;;;;;;;;;;-1:-1:-1;25541:185:0;;;;;:::i;:::-;;:::i;35696:243::-;;;;;;;;;;-1:-1:-1;35696:243:0;;;;;:::i;:::-;;:::i;57178:154::-;;;;;;;;;;-1:-1:-1;57178:154:0;;;;;:::i;:::-;;:::i;56730:98::-;;;;;;;;;;-1:-1:-1;56730:98:0;;;;;:::i;:::-;;:::i;57340:113::-;;;;;;;;;;-1:-1:-1;57340:113:0;;;;;:::i;:::-;-1:-1:-1;;;;;57425:20:0;57398:7;57425:20;;;:11;:20;;;;;;;57340:113;22632:222;;;;;;;;;;-1:-1:-1;22632:222:0;;;;;:::i;:::-;;:::i;51896:255::-;;;;;;;;;;-1:-1:-1;51896:255:0;;;;;:::i;:::-;;:::i;22363:207::-;;;;;;;;;;-1:-1:-1;22363:207:0;;;;;:::i;:::-;;:::i;52879:1162::-;;;;;;:::i;:::-;;:::i;37811:103::-;;;;;;;;;;;;;:::i;56940:::-;;;;;;;;;;-1:-1:-1;56940:103:0;;;;;:::i;:::-;;:::i;57463:105::-;;;;;;;;;;;;;:::i;55644:101::-;;;;;;;;;;-1:-1:-1;55644:101:0;;;;;:::i;:::-;;:::i;51147:113::-;;;;;;;;;;;;;:::i;56189:183::-;;;;;;;;;;;;;:::i;49775:33::-;;;;;;;;;;-1:-1:-1;49775:33:0;;;;-1:-1:-1;;;;;49775:33:0;;;37163:87;;;;;;;;;;-1:-1:-1;37209:7:0;37236:6;-1:-1:-1;;;;;37236:6:0;37163:87;;23090:104;;;;;;;;;;;;;:::i;24677:155::-;;;;;;;;;;-1:-1:-1;24677:155:0;;;;;:::i;:::-;;:::i;49176:36::-;;;;;;;;;;;;;;;52159:712;;;;;;:::i;:::-;;:::i;56836:96::-;;;;;;;;;;-1:-1:-1;56836:96:0;;;;;:::i;:::-;;:::i;56000:181::-;;;;;;;;;;;;;:::i;49640:26::-;;;;;;;;;;;;;;;;56380:166;;;;;;;;;;;;;:::i;25797:323::-;;;;;;;;;;-1:-1:-1;25797:323:0;;;;;:::i;:::-;;:::i;57051:97::-;;;;;;;;;;-1:-1:-1;57051:97:0;;;;;:::i;:::-;;:::i;58334:290::-;;;;;;;;;;-1:-1:-1;58334:290:0;;;;;:::i;:::-;;:::i;57776:183::-;;;;;;;;;;-1:-1:-1;57776:183:0;;;;;:::i;:::-;;:::i;57576:192::-;;;;;;;;;;-1:-1:-1;57576:192:0;;;;;:::i;:::-;;:::i;49135:34::-;;;;;;;;;;;;;;;24903:164;;;;;;;;;;-1:-1:-1;24903:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;25024:25:0;;;25000:4;25024:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;24903:164;49606:27;;;;;;;;;;;;;;;;38069:201;;;;;;;;;;-1:-1:-1;38069:201:0;;;;;:::i;:::-;;:::i;58165:161::-;58258:4;58282:36;58306:11;58282:23;:36::i;:::-;58275:43;58165:161;-1:-1:-1;;58165:161:0:o;22921:100::-;22975:13;23008:5;23001:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22921:100;:::o;24434:171::-;24510:7;24530:23;24545:7;24530:14;:23::i;:::-;-1:-1:-1;24573:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;24573:24:0;;24434:171::o;23951:417::-;24032:13;24048:23;24063:7;24048:14;:23::i;:::-;24032:39;;24096:5;-1:-1:-1;;;;;24090:11:0;:2;-1:-1:-1;;;;;24090:11:0;;24082:57;;;;-1:-1:-1;;;24082:57:0;;7799:2:1;24082:57:0;;;7781:21:1;7838:2;7818:18;;;7811:30;7877:34;7857:18;;;7850:62;-1:-1:-1;;;7928:18:1;;;7921:31;7969:19;;24082:57:0;;;;;;;;;19472:10;-1:-1:-1;;;;;24174:21:0;;;;:62;;-1:-1:-1;24199:37:0;24216:5;19472:10;24903:164;:::i;24199:37::-;24152:174;;;;-1:-1:-1;;;24152:174:0;;8201:2:1;24152:174:0;;;8183:21:1;8240:2;8220:18;;;8213:30;8279:34;8259:18;;;8252:62;8350:32;8330:18;;;8323:60;8400:19;;24152:174:0;7999:426:1;24152:174:0;24339:21;24348:2;24352:7;24339:8;:21::i;:::-;24021:347;23951:417;;:::o;54390:867::-;54489:10;;;;;;;54481:74;;;;-1:-1:-1;;;54481:74:0;;8632:2:1;54481:74:0;;;8614:21:1;8671:2;8651:18;;;8644:30;8710:34;8690:18;;;8683:62;-1:-1:-1;;;8761:18:1;;;8754:49;8820:19;;54481:74:0;8430:415:1;54481:74:0;54583:1;54574:6;:10;54566:62;;;;-1:-1:-1;;;54566:62:0;;9052:2:1;54566:62:0;;;9034:21:1;9091:2;9071:18;;;9064:30;9130:34;9110:18;;;9103:62;-1:-1:-1;;;9181:18:1;;;9174:37;9228:19;;54566:62:0;8850:403:1;54566:62:0;54641:22;54666:24;:14;48233;;48141:114;54666:24;54641:49;-1:-1:-1;54701:21:0;54725:23;54742:6;54641:49;54725:23;:::i;:::-;54701:47;;54800:9;54785:11;;54769:13;:27;;;;:::i;:::-;:40;;54761:99;;;;-1:-1:-1;;;54761:99:0;;9722:2:1;54761:99:0;;;9704:21:1;9761:2;9741:18;;;9734:30;9800:34;9780:18;;;9773:62;-1:-1:-1;;;9851:18:1;;;9844:44;9905:19;;54761:99:0;9520:410:1;54761:99:0;54916:9;54893:19;54905:6;54893:11;:19::i;:::-;:32;54871:131;;;;-1:-1:-1;;;54871:131:0;;10137:2:1;54871:131:0;;;10119:21:1;10176:2;10156:18;;;10149:30;10215:34;10195:18;;;10188:62;-1:-1:-1;;;10266:18:1;;;10259:47;10323:19;;54871:131:0;9935:413:1;54871:131:0;55039:13;55022:14;:30;55015:183;;;55069:39;55085:2;55089:14;55069:39;;;;;;;;;;;;:15;:39::i;:::-;55170:1;55152:19;;;;55015:183;;;55210:39;:14;55234;55210:23;:39::i;:::-;54470:787;;54390:867;;:::o;25134:336::-;25329:41;19472:10;25348:12;25362:7;25329:18;:41::i;:::-;25321:100;;;;-1:-1:-1;;;25321:100:0;;;;;;;:::i;:::-;25434:28;25444:4;25450:2;25454:7;25434:9;:28::i;56554:168::-;37049:13;:11;:13::i;:::-;56619:10:::1;::::0;::::1;::::0;::::1;;;56611:74;;;::::0;-1:-1:-1;;;56611:74:0;;10970:2:1;56611:74:0::1;::::0;::::1;10952:21:1::0;11009:2;10989:18;;;10982:30;11048:34;11028:18;;;11021:62;-1:-1:-1;;;11099:18:1;;;11092:49;11158:19;;56611:74:0::1;10768:415:1::0;56611:74:0::1;56696:10;:18:::0;;-1:-1:-1;;56696:18:0::1;::::0;;56554:168::o;51266:160::-;37049:13;:11;:13::i;:::-;51363:6:::1;51338:21;:31;;51330:40;;;::::0;::::1;;51391:18;::::0;51381:37:::1;::::0;-1:-1:-1;;;;;51391:18:0::1;51411:6:::0;51381:9:::1;:37::i;:::-;51266:160:::0;:::o;55753:117::-;37049:13;:11;:13::i;:::-;55836::::1;:26;55852:10:::0;;55836:13;:26:::1;:::i;54049:333::-:0;54127:10;;;;;;;54119:69;;;;-1:-1:-1;;;54119:69:0;;13448:2:1;54119:69:0;;;13430:21:1;13487:2;13467:18;;;13460:30;13526:34;13506:18;;;13499:62;-1:-1:-1;;;13577:18:1;;;13570:44;13631:19;;54119:69:0;13246:410:1;54119:69:0;54241:9;54223:14;54235:1;54223:11;:14::i;:::-;:27;54201:121;;;;-1:-1:-1;;;54201:121:0;;13863:2:1;54201:121:0;;;13845:21:1;13902:2;13882:18;;;13875:30;13941:34;13921:18;;;13914:62;-1:-1:-1;;;13992:18:1;;;13985:42;14044:19;;54201:121:0;13661:408:1;54201:121:0;54335:39;54345:2;54349:24;:14;48233;;48141:114;54349:24;54335:9;:39::i;55878:114::-;37049:13;:11;:13::i;:::-;55956:18:::1;:28:::0;;-1:-1:-1;;;;;;55956:28:0::1;-1:-1:-1::0;;;;;55956:28:0;;;::::1;::::0;;;::::1;::::0;;55878:114::o;25541:185::-;25679:39;25696:4;25702:2;25706:7;25679:39;;;;;;;;;;;;:16;:39::i;35696:243::-;35814:41;19472:10;35833:12;19392:98;35814:41;35806:100;;;;-1:-1:-1;;;35806:100:0;;;;;;;:::i;:::-;35917:14;35923:7;35917:5;:14::i;57178:154::-;-1:-1:-1;;;;;57280:20:0;;57256:4;57280:20;;;:11;:20;;;;;;57313:11;;57280:29;;57303:6;;57280:29;:::i;:::-;:44;;;57178:154;-1:-1:-1;;;57178:154:0:o;56730:98::-;37049:13;:11;:13::i;:::-;56800:12:::1;:20:::0;56730:98::o;22632:222::-;22704:7;22740:16;;;:7;:16;;;;;;-1:-1:-1;;;;;22740:16:0;;22767:56;;;;-1:-1:-1;;;22767:56:0;;14276:2:1;22767:56:0;;;14258:21:1;14315:2;14295:18;;;14288:30;-1:-1:-1;;;14334:18:1;;;14327:54;14398:18;;22767:56:0;14074:348:1;51896:255:0;37049:13;:11;:13::i;22363:207::-;22435:7;-1:-1:-1;;;;;22463:19:0;;22455:73;;;;-1:-1:-1;;;22455:73:0;;14629:2:1;22455:73:0;;;14611:21:1;14668:2;14648:18;;;14641:30;14707:34;14687:18;;;14680:62;-1:-1:-1;;;14758:18:1;;;14751:39;14807:19;;22455:73:0;14427:405:1;22455:73:0;-1:-1:-1;;;;;;22546:16:0;;;;;:9;:16;;;;;;;22363:207::o;52879:1162::-;53007:13;;;;52999:83;;;;-1:-1:-1;;;52999:83:0;;15039:2:1;52999:83:0;;;15021:21:1;15078:2;15058:18;;;15051:30;15117:34;15097:18;;;15090:62;15188:27;15168:18;;;15161:55;15233:19;;52999:83:0;14837:421:1;52999:83:0;53110:1;53101:6;:10;53093:61;;;;-1:-1:-1;;;53093:61:0;;15465:2:1;53093:61:0;;;15447:21:1;15504:2;15484:18;;;15477:30;15543:34;15523:18;;;15516:62;-1:-1:-1;;;15594:18:1;;;15587:36;15640:19;;53093:61:0;15263:402:1;53093:61:0;53175:25;53183:9;53189:2;53183:5;:9::i;:::-;53194:5;;53175:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53175:7:0;;-1:-1:-1;;;53175:25:0:i;:::-;53167:86;;;;-1:-1:-1;;;53167:86:0;;15872:2:1;53167:86:0;;;15854:21:1;15911:2;15891:18;;;15884:30;15950:34;15930:18;;;15923:62;-1:-1:-1;;;16001:18:1;;;15994:46;16057:19;;53167:86:0;15670:412:1;53167:86:0;53272:26;53287:2;53291:6;53272:14;:26::i;:::-;53264:104;;;;-1:-1:-1;;;53264:104:0;;16289:2:1;53264:104:0;;;16271:21:1;16328:2;16308:18;;;16301:30;16367:34;16347:18;;;16340:62;16438:34;16418:18;;;16411:62;-1:-1:-1;;;16489:19:1;;;16482:32;16531:19;;53264:104:0;16087:469:1;53264:104:0;53381:22;53406:24;:14;48233;;48141:114;53406:24;53381:49;-1:-1:-1;53441:21:0;53465:23;53482:6;53381:49;53465:23;:::i;:::-;53441:47;;53526:12;;53509:13;:29;;53501:101;;;;-1:-1:-1;;;53501:101:0;;16763:2:1;53501:101:0;;;16745:21:1;16802:2;16782:18;;;16775:30;16841:34;16821:18;;;16814:62;16912:29;16892:18;;;16885:57;16959:19;;53501:101:0;16561:423:1;53501:101:0;53661:9;53635:22;53650:6;53635:14;:22::i;:::-;:35;53613:137;;;;-1:-1:-1;;;53613:137:0;;17191:2:1;53613:137:0;;;17173:21:1;17230:2;17210:18;;;17203:30;17269:34;17249:18;;;17242:62;-1:-1:-1;;;17320:18:1;;;17313:50;17380:19;;53613:137:0;16989:416:1;53613:137:0;53787:13;53770:14;:30;53763:183;;;53817:39;53833:2;53837:14;53817:39;;;;;;;;;;;;:15;:39::i;:::-;53918:1;53900:19;;;;53763:183;;;53958:39;:14;53982;53958:23;:39::i;:::-;-1:-1:-1;;;;;54008:15:0;;;;;;:11;:15;;;;;:25;;54027:6;;54008:15;:25;;54027:6;;54008:25;:::i;:::-;;;;-1:-1:-1;;;;;;;;52879:1162:0:o;37811:103::-;37049:13;:11;:13::i;:::-;37876:30:::1;37903:1;37876:18;:30::i;:::-;37811:103::o:0;56940:::-;37049:13;:11;:13::i;:::-;57012:15:::1;:23:::0;56940:103::o;57463:105::-;57509:7;57536:24;:14;48233;;48141:114;57536:24;57529:31;;57463:105;:::o;55644:101::-;37049:13;:11;:13::i;:::-;55714::::1;:23:::0;55644:101::o;51147:113::-;37049:13;:11;:13::i;:::-;51210:18:::1;::::0;51200:52:::1;::::0;-1:-1:-1;;;;;51210:18:0::1;51230:21;51200:9;:52::i;56189:183::-:0;37049:13;:11;:13::i;:::-;56257::::1;::::0;::::1;;56249:83;;;::::0;-1:-1:-1;;;56249:83:0;;17612:2:1;56249:83:0::1;::::0;::::1;17594:21:1::0;17651:2;17631:18;;;17624:30;17690:34;17670:18;;;17663:62;17761:27;17741:18;;;17734:55;17806:19;;56249:83:0::1;17410:421:1::0;56249:83:0::1;56343:13;:21:::0;;-1:-1:-1;;56343:21:0::1;::::0;;56189:183::o;23090:104::-;23146:13;23179:7;23172:14;;;;;:::i;24677:155::-;24772:52;19472:10;24805:8;24815;24772:18;:52::i;:::-;24677:155;;:::o;52159:712::-;52266:13;;;;52258:78;;;;-1:-1:-1;;;52258:78:0;;18038:2:1;52258:78:0;;;18020:21:1;18077:2;18057:18;;;18050:30;18116:34;18096:18;;;18089:62;-1:-1:-1;;;18167:18:1;;;18160:50;18227:19;;52258:78:0;17836:416:1;52258:78:0;52382:12;;52355:14;48233;52355:39;52347:94;;;;-1:-1:-1;;;52347:94:0;;18459:2:1;52347:94:0;;;18441:21:1;18498:2;18478:18;;;18471:30;18537:34;18517:18;;;18510:62;-1:-1:-1;;;18588:18:1;;;18581:39;18637:19;;52347:94:0;18257:405:1;52347:94:0;52462:25;52470:9;52476:2;52470:5;:9::i;52462:25::-;52454:81;;;;-1:-1:-1;;;52454:81:0;;18869:2:1;52454:81:0;;;18851:21:1;18908:2;18888:18;;;18881:30;18947:34;18927:18;;;18920:62;-1:-1:-1;;;18998:18:1;;;18991:41;19049:19;;52454:81:0;18667:407:1;52454:81:0;52554:21;52569:2;52573:1;52554:14;:21::i;:::-;52546:94;;;;-1:-1:-1;;;52546:94:0;;19281:2:1;52546:94:0;;;19263:21:1;19320:2;19300:18;;;19293:30;19359:34;19339:18;;;19332:62;19430:30;19410:18;;;19403:58;19478:19;;52546:94:0;19079:424:1;52546:94:0;52696:9;52675:17;52690:1;52675:14;:17::i;:::-;:30;52653:127;;;;-1:-1:-1;;;52653:127:0;;19710:2:1;52653:127:0;;;19692:21:1;19749:2;19729:18;;;19722:30;19788:34;19768:18;;;19761:62;-1:-1:-1;;;19839:18:1;;;19832:45;19894:19;;52653:127:0;19508:411:1;52653:127:0;52793:39;52803:2;52807:24;:14;48233;;48141:114;52793:39;-1:-1:-1;;;;;52843:15:0;;;;;;:11;:15;;;;;:20;;52862:1;;52843:15;:20;;52862:1;;52843:20;:::i;:::-;;;;-1:-1:-1;;;;;52159:712:0:o;56836:96::-;37049:13;:11;:13::i;:::-;56905:11:::1;:19:::0;56836:96::o;56000:181::-;37049:13;:11;:13::i;:::-;56068::::1;::::0;::::1;;56067:14;56059:83;;;::::0;-1:-1:-1;;;56059:83:0;;20126:2:1;56059:83:0::1;::::0;::::1;20108:21:1::0;20165:2;20145:18;;;20138:30;20204:34;20184:18;;;20177:62;20275:26;20255:18;;;20248:54;20319:19;;56059:83:0::1;19924:420:1::0;56059:83:0::1;56153:13;:20:::0;;-1:-1:-1;;56153:20:0::1;56169:4;56153:20;::::0;;56000:181::o;56380:166::-;37049:13;:11;:13::i;:::-;56445:10:::1;::::0;::::1;::::0;::::1;;;56444:11;56436:74;;;::::0;-1:-1:-1;;;56436:74:0;;20551:2:1;56436:74:0::1;::::0;::::1;20533:21:1::0;20590:2;20570:18;;;20563:30;20629:34;20609:18;;;20602:62;-1:-1:-1;;;20680:18:1;;;20673:48;20738:19;;56436:74:0::1;20349:414:1::0;56436:74:0::1;56521:10;:17:::0;;-1:-1:-1;;56521:17:0::1;;;::::0;;56380:166::o;25797:323::-;25971:41;19472:10;26004:7;25971:18;:41::i;:::-;25963:100;;;;-1:-1:-1;;;25963:100:0;;;;;;;:::i;:::-;26074:38;26088:4;26094:2;26098:7;26107:4;26074:13;:38::i;57051:97::-;37049:13;:11;:13::i;:::-;57120:12:::1;:20:::0;57051:97::o;58334:290::-;58407:13;58433:23;58448:7;58433:14;:23::i;:::-;58469:21;58493:10;:8;:10::i;:::-;58469:34;;58545:1;58527:7;58521:21;:25;:95;;;;;;;;;;;;;;;;;58573:7;58582:18;:7;:16;:18::i;:::-;58556:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58521:95;58514:102;58334:290;-1:-1:-1;;;58334:290:0:o;57776:183::-;57834:7;57871:1;57862:6;:10;57854:58;;;;-1:-1:-1;;;57854:58:0;;21638:2:1;57854:58:0;;;21620:21:1;21677:2;21657:18;;;21650:30;21716:34;21696:18;;;21689:62;-1:-1:-1;;;21767:18:1;;;21760:33;21810:19;;57854:58:0;21436:399:1;57854:58:0;57945:6;57930:12;;:21;;;;:::i;57576:192::-;57637:7;57674:1;57665:6;:10;57657:61;;;;-1:-1:-1;;;57657:61:0;;22215:2:1;57657:61:0;;;22197:21:1;22254:2;22234:18;;;22227:30;22293:34;22273:18;;;22266:62;-1:-1:-1;;;22344:18:1;;;22337:36;22390:19;;57657:61:0;22013:402:1;57657:61:0;57754:6;57736:15;;:24;;;;:::i;38069:201::-;37049:13;:11;:13::i;:::-;-1:-1:-1;;;;;38158:22:0;::::1;38150:73;;;::::0;-1:-1:-1;;;38150:73:0;;22622:2:1;38150:73:0::1;::::0;::::1;22604:21:1::0;22661:2;22641:18;;;22634:30;22700:34;22680:18;;;22673:62;-1:-1:-1;;;22751:18:1;;;22744:36;22797:19;;38150:73:0::1;22420:402:1::0;38150:73:0::1;38234:28;38253:8;38234:18;:28::i;21994:305::-:0;22096:4;-1:-1:-1;;;;;;22133:40:0;;-1:-1:-1;;;22133:40:0;;:105;;-1:-1:-1;;;;;;;22190:48:0;;-1:-1:-1;;;22190:48:0;22133:105;:158;;;-1:-1:-1;;;;;;;;;;20562:40:0;;;22255:36;20453:157;32409:135;27692:4;27716:16;;;:7;:16;;;;;;-1:-1:-1;;;;;27716:16:0;32483:53;;;;-1:-1:-1;;;32483:53:0;;14276:2:1;32483:53:0;;;14258:21:1;14315:2;14295:18;;;14288:30;-1:-1:-1;;;14334:18:1;;;14327:54;14398:18;;32483:53:0;14074:348:1;31688:174:0;31763:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;31763:29:0;-1:-1:-1;;;;;31763:29:0;;;;;;;;:24;;31817:23;31763:24;31817:14;:23::i;:::-;-1:-1:-1;;;;;31808:46:0;;;;;;;;;;;31688:174;;:::o;28864:319::-;28993:18;28999:2;29003:7;28993:5;:18::i;:::-;29044:53;29075:1;29079:2;29083:7;29092:4;29044:22;:53::i;:::-;29022:153;;;;-1:-1:-1;;;29022:153:0;;;;;;;:::i;48645:177::-;48745:1;48734:8;:12;48726:52;;;;-1:-1:-1;;;48726:52:0;;23448:2:1;48726:52:0;;;23430:21:1;23487:2;23467:18;;;23460:30;23526:29;23506:18;;;23499:57;23573:18;;48726:52:0;23246:351:1;48726:52:0;48789:25;;48645:177::o;27921:264::-;28014:4;28031:13;28047:23;28062:7;28047:14;:23::i;:::-;28031:39;;28100:5;-1:-1:-1;;;;;28089:16:0;:7;-1:-1:-1;;;;;28089:16:0;;:52;;;-1:-1:-1;;;;;;25024:25:0;;;25000:4;25024:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;28109:32;28089:87;;;;28169:7;-1:-1:-1;;;;;28145:31:0;:20;28157:7;28145:11;:20::i;:::-;-1:-1:-1;;;;;28145:31:0;;28089:87;28081:96;27921:264;-1:-1:-1;;;;27921:264:0:o;30944:625::-;31103:4;-1:-1:-1;;;;;31076:31:0;:23;31091:7;31076:14;:23::i;:::-;-1:-1:-1;;;;;31076:31:0;;31068:81;;;;-1:-1:-1;;;31068:81:0;;23804:2:1;31068:81:0;;;23786:21:1;23843:2;23823:18;;;23816:30;23882:34;23862:18;;;23855:62;-1:-1:-1;;;23933:18:1;;;23926:35;23978:19;;31068:81:0;23602:401:1;31068:81:0;-1:-1:-1;;;;;31168:16:0;;31160:65;;;;-1:-1:-1;;;31160:65:0;;24210:2:1;31160:65:0;;;24192:21:1;24249:2;24229:18;;;24222:30;24288:34;24268:18;;;24261:62;-1:-1:-1;;;24339:18:1;;;24332:34;24383:19;;31160:65:0;24008:400:1;31160:65:0;31342:29;31359:1;31363:7;31342:8;:29::i;:::-;-1:-1:-1;;;;;31384:15:0;;;;;;:9;:15;;;;;:20;;31403:1;;31384:15;:20;;31403:1;;31384:20;:::i;:::-;;;;-1:-1:-1;;;;;;;31415:13:0;;;;;;:9;:13;;;;;:18;;31432:1;;31415:13;:18;;31432:1;;31415:18;:::i;:::-;;;;-1:-1:-1;;31444:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;31444:21:0;-1:-1:-1;;;;;31444:21:0;;;;;;;;;31483:27;;31444:16;;31483:27;;;;;;;24021:347;23951:417;;:::o;37328:132::-;37209:7;37236:6;-1:-1:-1;;;;;37236:6:0;19472:10;37392:23;37384:68;;;;-1:-1:-1;;;37384:68:0;;24748:2:1;37384:68:0;;;24730:21:1;;;24767:18;;;24760:30;24826:34;24806:18;;;24799:62;24878:18;;37384:68:0;24546:356:1;50851:288:0;-1:-1:-1;;;;;50929:22:0;;;;;;50928:55;;-1:-1:-1;;;;;;50957:25:0;;50977:4;50957:25;;50928:55;:72;;;;;50998:1;50988:7;:11;50928:72;50924:208;;;51018:12;51036:8;-1:-1:-1;;;;;51036:13:0;51057:7;51036:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51017:52;;;51092:7;51084:36;;;;-1:-1:-1;;;51084:36:0;;25319:2:1;51084:36:0;;;25301:21:1;25358:2;25338:18;;;25331:30;-1:-1:-1;;;25377:18:1;;;25370:46;25433:18;;51084:36:0;25117:340:1;51461:111:0;51538:26;51548:2;51552:7;51538:26;;;;;;;;;;;;:9;:26::i;30187:420::-;30247:13;30263:23;30278:7;30263:14;:23::i;:::-;30247:39;;30388:29;30405:1;30409:7;30388:8;:29::i;:::-;-1:-1:-1;;;;;30430:16:0;;;;;;:9;:16;;;;;:21;;30450:1;;30430:16;:21;;30450:1;;30430:21;:::i;:::-;;;;-1:-1:-1;;30469:16:0;;;;:7;:16;;;;;;30462:23;;-1:-1:-1;;;;;;30462:23:0;;;30503:36;30477:7;;30469:16;-1:-1:-1;;;;;30503:36:0;;;;;30469:16;;30503:36;24677:155;;:::o;55303:136::-;55405:25;;-1:-1:-1;;25611:2:1;25607:15;;;25603:53;55405:25:0;;;25591:66:1;55363:7:0;;25673:12:1;;55405:25:0;;;;;;;;;;;;55395:36;;;;;;55388:43;;55303:136;;;:::o;55447:166::-;55530:4;55559:46;55578:5;55585:13;;55600:4;55559:18;:46::i;38430:191::-;38504:16;38523:6;;-1:-1:-1;;;;;38540:17:0;;;-1:-1:-1;;;;;;38540:17:0;;;;;;38573:40;;38523:6;;;;;;;38573:40;;38504:16;38573:40;38493:128;38430:191;:::o;32005:315::-;32160:8;-1:-1:-1;;;;;32151:17:0;:5;-1:-1:-1;;;;;32151:17:0;;32143:55;;;;-1:-1:-1;;;32143:55:0;;25898:2:1;32143:55:0;;;25880:21:1;25937:2;25917:18;;;25910:30;25976:27;25956:18;;;25949:55;26021:18;;32143:55:0;25696:349:1;32143:55:0;-1:-1:-1;;;;;32209:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;32209:46:0;;;;;;;;;;32271:41;;540::1;;;32271::0;;513:18:1;32271:41:0;;;;;;;32005:315;;;:::o;27001:313::-;27157:28;27167:4;27173:2;27177:7;27157:9;:28::i;:::-;27204:47;27227:4;27233:2;27237:7;27246:4;27204:22;:47::i;:::-;27196:110;;;;-1:-1:-1;;;27196:110:0;;;;;;;:::i;50648:122::-;50716:13;50749;50742:20;;;;;:::i;537:723::-;593:13;814:5;823:1;814:10;810:53;;-1:-1:-1;;841:10:0;;;;;;;;;;;;-1:-1:-1;;;841:10:0;;;;;537:723::o;810:53::-;888:5;873:12;929:78;936:9;;929:78;;962:8;;;;:::i;:::-;;-1:-1:-1;985:10:0;;-1:-1:-1;993:2:0;985:10;;:::i;:::-;;;929:78;;;1017:19;1049:6;1039:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1039:17:0;;1017:39;;1067:154;1074:10;;1067:154;;1101:11;1111:1;1101:11;;:::i;:::-;;-1:-1:-1;1170:10:0;1178:2;1170:5;:10;:::i;:::-;1157:24;;:2;:24;:::i;:::-;1144:39;;1127:6;1134;1127:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;1127:56:0;;;;;;;;-1:-1:-1;1198:11:0;1207:2;1198:11;;:::i;:::-;;;1067:154;;29519:439;-1:-1:-1;;;;;29599:16:0;;29591:61;;;;-1:-1:-1;;;29591:61:0;;26898:2:1;29591:61:0;;;26880:21:1;;;26917:18;;;26910:30;26976:34;26956:18;;;26949:62;27028:18;;29591:61:0;26696:356:1;29591:61:0;27692:4;27716:16;;;:7;:16;;;;;;-1:-1:-1;;;;;27716:16:0;:30;29663:58;;;;-1:-1:-1;;;29663:58:0;;27259:2:1;29663:58:0;;;27241:21:1;27298:2;27278:18;;;27271:30;27337;27317:18;;;27310:58;27385:18;;29663:58:0;27057:352:1;29663:58:0;-1:-1:-1;;;;;29792:13:0;;;;;;:9;:13;;;;;:18;;29809:1;;29792:13;:18;;29809:1;;29792:18;:::i;:::-;;;;-1:-1:-1;;29821:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;29821:21:0;-1:-1:-1;;;;;29821:21:0;;;;;;;;29860:33;;29821:16;;;29860:33;;29821:16;;29860:33;24677:155;;:::o;33108:853::-;33262:4;-1:-1:-1;;;;;33283:13:0;;11704:19;:23;33279:675;;33319:71;;-1:-1:-1;;;33319:71:0;;-1:-1:-1;;;;;33319:36:0;;;;;:71;;19472:10;;33370:4;;33376:7;;33385:4;;33319:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33319:71:0;;;;;;;;-1:-1:-1;;33319:71:0;;;;;;;;;;;;:::i;:::-;;;33315:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33560:6;:13;33577:1;33560:18;33556:328;;33603:60;;-1:-1:-1;;;33603:60:0;;;;;;;:::i;33556:328::-;33834:6;33828:13;33819:6;33815:2;33811:15;33804:38;33315:584;-1:-1:-1;;;;;;33441:51:0;-1:-1:-1;;;33441:51:0;;-1:-1:-1;33434:58:0;;33279:675;-1:-1:-1;33938:4:0;33108:853;;;;;;:::o;51580:278::-;51726:9;51712:11;;51685:24;:14;48233;;48141:114;51685:24;:38;;;;:::i;:::-;:50;51677:90;;;;-1:-1:-1;;;51677:90:0;;28364:2:1;51677:90:0;;;28346:21:1;28403:2;28383:18;;;28376:30;28442:29;28422:18;;;28415:57;28489:18;;51677:90:0;28162:351:1;51677:90:0;51778:35;51794:2;51798:7;51807:5;51778:15;:35::i;:::-;51824:26;:14;48352:19;;48370:1;48352:19;;;48263:127;39831:190;39956:4;40009;39980:25;39993:5;40000:4;39980:12;:25::i;:::-;:33;;39831:190;-1:-1:-1;;;;39831:190:0:o;40698:296::-;40781:7;40824:4;40781:7;40839:118;40863:5;:12;40859:1;:16;40839:118;;;40912:33;40922:12;40936:5;40942:1;40936:8;;;;;;;;:::i;:::-;;;;;;;40912:9;:33::i;:::-;40897:48;-1:-1:-1;40877:3:0;;;;:::i;:::-;;;;40839:118;;;-1:-1:-1;40974:12:0;40698:296;-1:-1:-1;;;40698:296:0:o;46905:149::-;46968:7;46999:1;46995;:5;:51;;47130:13;47224:15;;;47260:4;47253:15;;;47307:4;47291:21;;46995:51;;;47130:13;47224:15;;;47260:4;47253:15;;;47307:4;47291:21;;47003:20;47062:268;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:1;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:1:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:1;;1348:180;-1:-1:-1;1348:180:1:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:1;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:1:o;2178:328::-;2255:6;2263;2271;2324:2;2312:9;2303:7;2299:23;2295:32;2292:52;;;2340:1;2337;2330:12;2292:52;2363:29;2382:9;2363:29;:::i;:::-;2353:39;;2411:38;2445:2;2434:9;2430:18;2411:38;:::i;:::-;2401:48;;2496:2;2485:9;2481:18;2468:32;2458:42;;2178:328;;;;;:::o;2511:592::-;2582:6;2590;2643:2;2631:9;2622:7;2618:23;2614:32;2611:52;;;2659:1;2656;2649:12;2611:52;2699:9;2686:23;2728:18;2769:2;2761:6;2758:14;2755:34;;;2785:1;2782;2775:12;2755:34;2823:6;2812:9;2808:22;2798:32;;2868:7;2861:4;2857:2;2853:13;2849:27;2839:55;;2890:1;2887;2880:12;2839:55;2930:2;2917:16;2956:2;2948:6;2945:14;2942:34;;;2972:1;2969;2962:12;2942:34;3017:7;3012:2;3003:6;2999:2;2995:15;2991:24;2988:37;2985:57;;;3038:1;3035;3028:12;2985:57;3069:2;3061:11;;;;;3091:6;;-1:-1:-1;2511:592:1;;-1:-1:-1;;;;2511:592:1:o;3108:186::-;3167:6;3220:2;3208:9;3199:7;3195:23;3191:32;3188:52;;;3236:1;3233;3226:12;3188:52;3259:29;3278:9;3259:29;:::i;3663:367::-;3726:8;3736:6;3790:3;3783:4;3775:6;3771:17;3767:27;3757:55;;3808:1;3805;3798:12;3757:55;-1:-1:-1;3831:20:1;;3874:18;3863:30;;3860:50;;;3906:1;3903;3896:12;3860:50;3943:4;3935:6;3931:17;3919:29;;4003:3;3996:4;3986:6;3983:1;3979:14;3971:6;3967:27;3963:38;3960:47;3957:67;;;4020:1;4017;4010:12;3957:67;3663:367;;;;;:::o;4035:579::-;4139:6;4147;4155;4163;4216:2;4204:9;4195:7;4191:23;4187:32;4184:52;;;4232:1;4229;4222:12;4184:52;4255:29;4274:9;4255:29;:::i;:::-;4245:39;;4331:2;4320:9;4316:18;4303:32;4293:42;;4386:2;4375:9;4371:18;4358:32;4413:18;4405:6;4402:30;4399:50;;;4445:1;4442;4435:12;4399:50;4484:70;4546:7;4537:6;4526:9;4522:22;4484:70;:::i;:::-;4035:579;;;;-1:-1:-1;4573:8:1;-1:-1:-1;;;;4035:579:1:o;4804:347::-;4869:6;4877;4930:2;4918:9;4909:7;4905:23;4901:32;4898:52;;;4946:1;4943;4936:12;4898:52;4969:29;4988:9;4969:29;:::i;:::-;4959:39;;5048:2;5037:9;5033:18;5020:32;5095:5;5088:13;5081:21;5074:5;5071:32;5061:60;;5117:1;5114;5107:12;5061:60;5140:5;5130:15;;;4804:347;;;;;:::o;5156:511::-;5251:6;5259;5267;5320:2;5308:9;5299:7;5295:23;5291:32;5288:52;;;5336:1;5333;5326:12;5288:52;5359:29;5378:9;5359:29;:::i;:::-;5349:39;;5439:2;5428:9;5424:18;5411:32;5466:18;5458:6;5455:30;5452:50;;;5498:1;5495;5488:12;5452:50;5537:70;5599:7;5590:6;5579:9;5575:22;5537:70;:::i;:::-;5156:511;;5626:8;;-1:-1:-1;5511:96:1;;-1:-1:-1;;;;5156:511:1:o;5672:127::-;5733:10;5728:3;5724:20;5721:1;5714:31;5764:4;5761:1;5754:15;5788:4;5785:1;5778:15;5804:1138;5899:6;5907;5915;5923;5976:3;5964:9;5955:7;5951:23;5947:33;5944:53;;;5993:1;5990;5983:12;5944:53;6016:29;6035:9;6016:29;:::i;:::-;6006:39;;6064:38;6098:2;6087:9;6083:18;6064:38;:::i;:::-;6054:48;;6149:2;6138:9;6134:18;6121:32;6111:42;;6204:2;6193:9;6189:18;6176:32;6227:18;6268:2;6260:6;6257:14;6254:34;;;6284:1;6281;6274:12;6254:34;6322:6;6311:9;6307:22;6297:32;;6367:7;6360:4;6356:2;6352:13;6348:27;6338:55;;6389:1;6386;6379:12;6338:55;6425:2;6412:16;6447:2;6443;6440:10;6437:36;;;6453:18;;:::i;:::-;6528:2;6522:9;6496:2;6582:13;;-1:-1:-1;;6578:22:1;;;6602:2;6574:31;6570:40;6558:53;;;6626:18;;;6646:22;;;6623:46;6620:72;;;6672:18;;:::i;:::-;6712:10;6708:2;6701:22;6747:2;6739:6;6732:18;6787:7;6782:2;6777;6773;6769:11;6765:20;6762:33;6759:53;;;6808:1;6805;6798:12;6759:53;6864:2;6859;6855;6851:11;6846:2;6838:6;6834:15;6821:46;6909:1;6904:2;6899;6891:6;6887:15;6883:24;6876:35;6930:6;6920:16;;;;;;;5804:1138;;;;;;;:::o;6947:260::-;7015:6;7023;7076:2;7064:9;7055:7;7051:23;7047:32;7044:52;;;7092:1;7089;7082:12;7044:52;7115:29;7134:9;7115:29;:::i;:::-;7105:39;;7163:38;7197:2;7186:9;7182:18;7163:38;:::i;:::-;7153:48;;6947:260;;;;;:::o;7212:380::-;7291:1;7287:12;;;;7334;;;7355:61;;7409:4;7401:6;7397:17;7387:27;;7355:61;7462:2;7454:6;7451:14;7431:18;7428:38;7425:161;;7508:10;7503:3;7499:20;7496:1;7489:31;7543:4;7540:1;7533:15;7571:4;7568:1;7561:15;7425:161;;7212:380;;;:::o;9258:127::-;9319:10;9314:3;9310:20;9307:1;9300:31;9350:4;9347:1;9340:15;9374:4;9371:1;9364:15;9390:125;9455:9;;;9476:10;;;9473:36;;;9489:18;;:::i;10353:410::-;10555:2;10537:21;;;10594:2;10574:18;;;10567:30;10633:34;10628:2;10613:18;;10606:62;-1:-1:-1;;;10699:2:1;10684:18;;10677:44;10753:3;10738:19;;10353:410::o;11314:545::-;11416:2;11411:3;11408:11;11405:448;;;11452:1;11477:5;11473:2;11466:17;11522:4;11518:2;11508:19;11592:2;11580:10;11576:19;11573:1;11569:27;11563:4;11559:38;11628:4;11616:10;11613:20;11610:47;;;-1:-1:-1;11651:4:1;11610:47;11706:2;11701:3;11697:12;11694:1;11690:20;11684:4;11680:31;11670:41;;11761:82;11779:2;11772:5;11769:13;11761:82;;;11824:17;;;11805:1;11794:13;11761:82;;;11765:3;;;11314:545;;;:::o;12035:1206::-;12159:18;12154:3;12151:27;12148:53;;;12181:18;;:::i;:::-;12210:94;12300:3;12260:38;12292:4;12286:11;12260:38;:::i;:::-;12254:4;12210:94;:::i;:::-;12330:1;12355:2;12350:3;12347:11;12372:1;12367:616;;;;13027:1;13044:3;13041:93;;;-1:-1:-1;13100:19:1;;;13087:33;13041:93;-1:-1:-1;;11992:1:1;11988:11;;;11984:24;11980:29;11970:40;12016:1;12012:11;;;11967:57;13147:78;;12340:895;;12367:616;11261:1;11254:14;;;11298:4;11285:18;;-1:-1:-1;;12403:17:1;;;12504:9;12526:229;12540:7;12537:1;12534:14;12526:229;;;12629:19;;;12616:33;12601:49;;12736:4;12721:20;;;;12689:1;12677:14;;;;12556:12;12526:229;;;12530:3;12783;12774:7;12771:16;12768:159;;;12907:1;12903:6;12897:3;12891;12888:1;12884:11;12880:21;12876:34;12872:39;12859:9;12854:3;12850:19;12837:33;12833:79;12825:6;12818:95;12768:159;;;12970:1;12964:3;12961:1;12957:11;12953:19;12947:4;12940:33;12340:895;;;12035:1206;;;:::o;20768:663::-;21048:3;21086:6;21080:13;21102:66;21161:6;21156:3;21149:4;21141:6;21137:17;21102:66;:::i;:::-;21231:13;;21190:16;;;;21253:70;21231:13;21190:16;21300:4;21288:17;;21253:70;:::i;:::-;-1:-1:-1;;;21345:20:1;;21374:22;;;21423:1;21412:13;;20768:663;-1:-1:-1;;;;20768:663:1:o;21840:168::-;21913:9;;;21944;;21961:15;;;21955:22;;21941:37;21931:71;;21982:18;;:::i;22827:414::-;23029:2;23011:21;;;23068:2;23048:18;;;23041:30;23107:34;23102:2;23087:18;;23080:62;-1:-1:-1;;;23173:2:1;23158:18;;23151:48;23231:3;23216:19;;22827:414::o;24413:128::-;24480:9;;;24501:11;;;24498:37;;;24515:18;;:::i;26050:135::-;26089:3;26110:17;;;26107:43;;26130:18;;:::i;:::-;-1:-1:-1;26177:1:1;26166:13;;26050:135::o;26190:127::-;26251:10;26246:3;26242:20;26239:1;26232:31;26282:4;26279:1;26272:15;26306:4;26303:1;26296:15;26322:120;26362:1;26388;26378:35;;26393:18;;:::i;:::-;-1:-1:-1;26427:9:1;;26322:120::o;26447:112::-;26479:1;26505;26495:35;;26510:18;;:::i;:::-;-1:-1:-1;26544:9:1;;26447:112::o;26564:127::-;26625:10;26620:3;26616:20;26613:1;26606:31;26656:4;26653:1;26646:15;26680:4;26677:1;26670:15;27414:489;-1:-1:-1;;;;;27683:15:1;;;27665:34;;27735:15;;27730:2;27715:18;;27708:43;27782:2;27767:18;;27760:34;;;27830:3;27825:2;27810:18;;27803:31;;;27608:4;;27851:46;;27877:19;;27869:6;27851:46;:::i;:::-;27843:54;27414:489;-1:-1:-1;;;;;;27414:489:1:o;27908:249::-;27977:6;28030:2;28018:9;28009:7;28005:23;28001:32;27998:52;;;28046:1;28043;28036:12;27998:52;28078:9;28072:16;28097:30;28121:5;28097:30;:::i

Swarm Source

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

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