Token Fantom MoonCats

 

Overview ERC-721

Total Supply:
498 MCAT

Holders:
158 addresses
Balance
0 MCAT
0x0000000000000000000000000000000000000000
Loading
[ Download CSV Export  ] 
Loading
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
FantomMoonCats

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-08-26
*/

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

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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


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


pragma solidity ^0.8.0;

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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}


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


pragma solidity ^0.8.0;

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


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


pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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


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


pragma solidity ^0.8.0;

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


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


pragma solidity ^0.8.0;

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

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

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


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


pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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


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


pragma solidity ^0.8.0;

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


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


pragma solidity ^0.8.0;







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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

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

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

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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


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


pragma solidity ^0.8.0;

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

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

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


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


pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


pragma solidity ^0.8.0;


/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly 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), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}


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


pragma solidity ^0.8.0;

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}


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


pragma solidity ^0.8.0;


/**
 * @dev ERC721 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC721Pausable is ERC721, Pausable {
    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        require(!paused(), "ERC721Pausable: token transfer while paused");
    }
}


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


pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}


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


pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable is IAccessControl {
    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}


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


pragma solidity ^0.8.0;




/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


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


pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

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

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

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

        assembly {
            result := store
        }

        return result;
    }
}


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


pragma solidity ^0.8.0;



/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {grantRole} to track enumerable memberships
     */
    function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
        super.grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {revokeRole} to track enumerable memberships
     */
    function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
        super.revokeRole(role, account);
        _roleMembers[role].remove(account);
    }

    /**
     * @dev Overload {renounceRole} to track enumerable memberships
     */
    function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {
        super.renounceRole(role, account);
        _roleMembers[role].remove(account);
    }

    /**
     * @dev Overload {_setupRole} to track enumerable memberships
     */
    function _setupRole(bytes32 role, address account) internal virtual override {
        super._setupRole(role, account);
        _roleMembers[role].add(account);
    }
}


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


pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. 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 Counters {
    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 reset(Counter storage counter) internal {
        counter._value = 0;
    }
}


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


pragma solidity ^0.8.0;







/**
 * @dev {ERC721} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - a pauser role that allows to stop all token transfers
 *  - token ID and URI autogeneration
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts.
 */
contract ERC721PresetMinterPauserAutoId is
    Context,
    AccessControlEnumerable,
    ERC721Enumerable,
    ERC721Burnable,
    ERC721Pausable
{
    using Counters for Counters.Counter;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    Counters.Counter private _tokenIdTracker;

    string private _baseTokenURI;

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
     * account that deploys the contract.
     *
     * Token URIs will be autogenerated based on `baseURI` and their token IDs.
     * See {ERC721-tokenURI}.
     */
    constructor(
        string memory name,
        string memory symbol,
        string memory baseTokenURI
    ) ERC721(name, symbol) {
        _baseTokenURI = baseTokenURI;

        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());
    }

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

    /**
     * @dev Creates a new token for `to`. Its token ID will be automatically
     * assigned (and available on the emitted {IERC721-Transfer} event), and the token
     * URI autogenerated based on the base URI passed at construction.
     *
     * See {ERC721-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");

        // We cannot just use balanceOf to create the new tokenId because tokens
        // can be burned (destroyed), so we need a separate counter.
        _mint(to, _tokenIdTracker.current());
        _tokenIdTracker.increment();
    }

    /**
     * @dev Pauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_pause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function pause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
        _pause();
    }

    /**
     * @dev Unpauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_unpause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function unpause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause");
        _unpause();
    }

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

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


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


pragma solidity ^0.8.0;


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


pragma solidity ^0.8.0;

/**
 * @dev Interface for the NFT Royalty Standard
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Called with the sale price to determine how much royalty is owed and to whom.
     * @param tokenId - the NFT asset queried for royalty information
     * @param salePrice - the sale price of the NFT asset specified by `tokenId`
     * @return receiver - address of who should be sent the royalty payment
     * @return royaltyAmount - the royalty payment amount for `salePrice`
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}


// File contracts/FantomMoonCats.sol

pragma solidity ^0.8.7;

// import '@openzeppelin/contracts/token/ERC721/IERC721.sol';



contract FantomMoonCats is ERC721PresetMinterPauserAutoId, IERC2981, Ownable {
    using Counters for Counters.Counter;

    uint256 public constant MAX_CATS = 500;
    uint256 public constant MINT_PRICE = 300 ether;
    uint8 public constant MINT_PER_TX = 10;
    uint256 public constant ROYALTY = 500; // base 10000, 5%

    Counters.Counter private _tokenIds;
    address private paymentManager;
    bool private mintable = false;

    /// @notice set the base URI and payment manager
    constructor(string memory _baseTokenURI, address _paymentManager)
        ERC721PresetMinterPauserAutoId('Fantom MoonCats', 'MCAT', _baseTokenURI)
    {
        // set the royalty manager
        paymentManager = _paymentManager;
    }

    /// @notice Mint some cats
    function mintCat(uint8 _quantity) public payable {
        require(mintable, 'Moon cats are not mintable yet.');
        require(_quantity <= MINT_PER_TX, 'Too many moon cats for this transaction.');
        require(msg.value == MINT_PRICE * _quantity, 'Not the right payment for all these moon cats.');

        // mint the cats
        for (uint256 _i = 0; _i < _quantity; _i++) {
            _tokenIds.increment();
            _mint(msg.sender, _tokenIds.current());
        }
    }

    function veryImportantCat(address _to) external onlyOwner {
        require(!mintable, 'Very important moon cats are not mintable anymore.');
        _tokenIds.increment();
        _mint(_to, _tokenIds.current());
    }

    /// @dev override to check the max supply when minting
    function _mint(address to, uint256 _id) internal override {
        require(_id < MAX_CATS, 'All the moon cats are minted.');
        super._mint(to, _id);
    }

    /// @notice Set the mintable state
    function enableMinting() external onlyOwner {
        mintable = true;
    }

    /// @dev Support for IERC-2981, royalties
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(IERC165, ERC721PresetMinterPauserAutoId)
        returns (bool)
    {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /// @notice Calculate the royalty payment
    function royaltyInfo(uint256, uint256 _salePrice)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        return (paymentManager, (_salePrice * ROYALTY) / 10000);
    }

    /// @notice Withdraw funds from this contract and send to the payment manager
    function withdraw() external {
        payable(paymentManager).transfer(address(this).balance);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_baseTokenURI","type":"string"},{"internalType":"address","name":"_paymentManager","type":"address"}],"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_CATS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PER_TX","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROYALTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_quantity","type":"uint8"}],"name":"mintCat","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"veryImportantCat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526011805460ff60a01b191690553480156200001e57600080fd5b506040516200377338038062003773833981016040819052620000419162000401565b6040518060400160405280600f81526020016e46616e746f6d204d6f6f6e4361747360881b815250604051806040016040528060048152602001631350d05560e21b8152508382828160029080519060200190620000a19291906200033e565b508051620000b79060039060208401906200033e565b5050600c805460ff19169055508051620000d990600e9060208401906200033e565b50620000e760003362000187565b620001137f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63362000187565b6200013f7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3362000187565b5050506200015c620001566200018360201b60201c565b620001ca565b601180546001600160a01b0319166001600160a01b03929092169190911790555062000545565b3390565b6200019e82826200021c60201b6200186a1760201c565b6000828152600160209081526040909120620001c5918390620018746200022c821b17901c565b505050565b600f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200022882826200024c565b5050565b600062000243836001600160a01b038416620002ec565b90505b92915050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000228576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620002a83390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054620003355750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000246565b50600062000246565b8280546200034c90620004f2565b90600052602060002090601f016020900481019282620003705760008555620003bb565b82601f106200038b57805160ff1916838001178555620003bb565b82800160010185558215620003bb579182015b82811115620003bb5782518255916020019190600101906200039e565b50620003c9929150620003cd565b5090565b5b80821115620003c95760008155600101620003ce565b80516001600160a01b0381168114620003fc57600080fd5b919050565b600080604083850312156200041557600080fd5b82516001600160401b03808211156200042d57600080fd5b818501915085601f8301126200044257600080fd5b8151818111156200045757620004576200052f565b604051601f8201601f19908116603f011681019083821181831017156200048257620004826200052f565b816040528281526020935088848487010111156200049f57600080fd5b600091505b82821015620004c35784820184015181830185015290830190620004a4565b82821115620004d55760008484830101525b9550620004e7915050858201620003e4565b925050509250929050565b600181811c908216806200050757607f821691505b602082108114156200052957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b61321e80620005556000396000f3fe6080604052600436106102dc5760003560e01c8063715018a611610184578063b91d286c116100d6578063d547741f1161008a578063e985e9c511610064578063e985e9c5146107fb578063ed967e1a14610844578063f2fde38b1461086b57600080fd5b8063d547741f14610792578063e63ab1e9146107b2578063e797ec1b146107e657600080fd5b8063c87b56dd116100bb578063c87b56dd1461071e578063ca15c8731461073e578063d53913931461075e57600080fd5b8063b91d286c146106e1578063c002d23d1461070157600080fd5b80639010d07c11610138578063a217fddf11610112578063a217fddf1461068c578063a22cb465146106a1578063b88d4fde146106c157600080fd5b80639010d07c1461061357806391d148541461063357806395d89b411461067757600080fd5b80638456cb59116101695780638456cb59146105e05780638704a208146103b15780638da5cb5b146105f557600080fd5b8063715018a6146105b8578063718c0637146105cd57600080fd5b80632f745c591161023d57806342966c68116101f15780636352211e116101cb5780636352211e146105585780636a6278421461057857806370a082311461059857600080fd5b806342966c68146105005780634f6ccce7146105205780635c975abb1461054057600080fd5b80633ccfd60b116102225780633ccfd60b146104b65780633f4ba83a146104cb57806342842e0e146104e057600080fd5b80632f745c591461047657806336568abe1461049657600080fd5b80631e2fa5cd11610294578063248a9ca311610279578063248a9ca3146103e75780632a55205a146104175780632f2ff15d1461045657600080fd5b80631e2fa5cd146103b157806323b872dd146103c757600080fd5b8063081812fc116102c5578063081812fc14610338578063095ea7b31461037057806318160ddd1461039257600080fd5b806301ffc9a7146102e157806306fdde0314610316575b600080fd5b3480156102ed57600080fd5b506103016102fc366004612ecd565b61088b565b60405190151581526020015b60405180910390f35b34801561032257600080fd5b5061032b6108cf565b60405161030d9190613042565b34801561034457600080fd5b50610358610353366004612e6f565b610961565b6040516001600160a01b03909116815260200161030d565b34801561037c57600080fd5b5061039061038b366004612e45565b6109fb565b005b34801561039e57600080fd5b50600a545b60405190815260200161030d565b3480156103bd57600080fd5b506103a36101f481565b3480156103d357600080fd5b506103906103e2366004612cf1565b610b2d565b3480156103f357600080fd5b506103a3610402366004612e6f565b60009081526020819052604090206001015490565b34801561042357600080fd5b50610437610432366004612eab565b610bb5565b604080516001600160a01b03909316835260208301919091520161030d565b34801561046257600080fd5b50610390610471366004612e88565b610bea565b34801561048257600080fd5b506103a3610491366004612e45565b610c0c565b3480156104a257600080fd5b506103906104b1366004612e88565b610cb4565b3480156104c257600080fd5b50610390610cd6565b3480156104d757600080fd5b50610390610d12565b3480156104ec57600080fd5b506103906104fb366004612cf1565b610dba565b34801561050c57600080fd5b5061039061051b366004612e6f565b610dd5565b34801561052c57600080fd5b506103a361053b366004612e6f565b610e59565b34801561054c57600080fd5b50600c5460ff16610301565b34801561056457600080fd5b50610358610573366004612e6f565b610efd565b34801561058457600080fd5b50610390610593366004612ca3565b610f88565b3480156105a457600080fd5b506103a36105b3366004612ca3565b611044565b3480156105c457600080fd5b506103906110de565b6103906105db366004612f07565b611142565b3480156105ec57600080fd5b506103906112de565b34801561060157600080fd5b50600f546001600160a01b0316610358565b34801561061f57600080fd5b5061035861062e366004612eab565b611382565b34801561063f57600080fd5b5061030161064e366004612e88565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b34801561068357600080fd5b5061032b6113a1565b34801561069857600080fd5b506103a3600081565b3480156106ad57600080fd5b506103906106bc366004612e09565b6113b0565b3480156106cd57600080fd5b506103906106dc366004612d2d565b611475565b3480156106ed57600080fd5b506103906106fc366004612ca3565b611503565b34801561070d57600080fd5b506103a3681043561a882930000081565b34801561072a57600080fd5b5061032b610739366004612e6f565b6115f8565b34801561074a57600080fd5b506103a3610759366004612e6f565b6116e0565b34801561076a57600080fd5b506103a37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b34801561079e57600080fd5b506103906107ad366004612e88565b6116f7565b3480156107be57600080fd5b506103a37f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b3480156107f257600080fd5b50610390611701565b34801561080757600080fd5b50610301610816366004612cbe565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561085057600080fd5b50610859600a81565b60405160ff909116815260200161030d565b34801561087757600080fd5b50610390610886366004612ca3565b61178b565b60006001600160e01b031982167f2a55205a0000000000000000000000000000000000000000000000000000000014806108c957506108c982611889565b92915050565b6060600280546108de906130fa565b80601f016020809104026020016040519081016040528092919081815260200182805461090a906130fa565b80156109575780601f1061092c57610100808354040283529160200191610957565b820191906000526020600020905b81548152906001019060200180831161093a57829003601f168201915b5050505050905090565b6000818152600460205260408120546001600160a01b03166109df5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610a0682610efd565b9050806001600160a01b0316836001600160a01b03161415610a905760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016109d6565b336001600160a01b0382161480610aac5750610aac8133610816565b610b1e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016109d6565b610b288383611894565b505050565b610b38335b82611902565b610baa5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016109d6565b610b288383836119f9565b60115460009081906001600160a01b0316612710610bd56101f486613081565b610bdf919061306d565b915091509250929050565b610bf48282611bd1565b6000828152600160205260409020610b289082611874565b6000610c1783611044565b8210610c8b5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016109d6565b506001600160a01b03919091166000908152600860209081526040808320938352929052205490565b610cbe8282611bf7565b6000828152600160205260409020610b289082611c7f565b6011546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610d0f573d6000803e3d6000fd5b50565b610d3c7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3361064e565b610db0576040805162461bcd60e51b81526020600482015260248101919091527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f20756e706175736560648201526084016109d6565b610db8611c94565b565b610b2883838360405180602001604052806000815250611475565b610dde33610b32565b610e505760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f7665640000000000000000000000000000000060648201526084016109d6565b610d0f81611d30565b6000610e64600a5490565b8210610ed85760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016109d6565b600a8281548110610eeb57610eeb6131a6565b90600052602060002001549050919050565b6000818152600460205260408120546001600160a01b0316806108c95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016109d6565b610fb27f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63361064e565b6110245760405162461bcd60e51b815260206004820152603d60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d7573742068617665206d696e74657220726f6c6520746f206d696e7400000060648201526084016109d6565b61103681611031600d5490565b611dd7565b610d0f600d80546001019055565b60006001600160a01b0382166110c25760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016109d6565b506001600160a01b031660009081526005602052604090205490565b600f546001600160a01b031633146111385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d6565b610db86000611e32565b601154600160a01b900460ff1661119b5760405162461bcd60e51b815260206004820152601f60248201527f4d6f6f6e206361747320617265206e6f74206d696e7461626c65207965742e0060448201526064016109d6565b600a60ff821611156112155760405162461bcd60e51b815260206004820152602860248201527f546f6f206d616e79206d6f6f6e206361747320666f722074686973207472616e60448201527f73616374696f6e2e00000000000000000000000000000000000000000000000060648201526084016109d6565b61122b60ff8216681043561a8829300000613081565b341461129f5760405162461bcd60e51b815260206004820152602e60248201527f4e6f7420746865207269676874207061796d656e7420666f7220616c6c20746860448201527f657365206d6f6f6e20636174732e00000000000000000000000000000000000060648201526084016109d6565b60005b8160ff168110156112da576112bb601080546001019055565b6112c83361103160105490565b806112d281613135565b9150506112a2565b5050565b6113087f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3361064e565b61137a5760405162461bcd60e51b815260206004820152603e60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f207061757365000060648201526084016109d6565b610db8611e84565b600082815260016020526040812061139a9083611f0c565b9392505050565b6060600380546108de906130fa565b6001600160a01b0382163314156114095760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109d6565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61147f3383611902565b6114f15760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016109d6565b6114fd84848484611f18565b50505050565b600f546001600160a01b0316331461155d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d6565b601154600160a01b900460ff16156115dd5760405162461bcd60e51b815260206004820152603260248201527f5665727920696d706f7274616e74206d6f6f6e206361747320617265206e6f7460448201527f206d696e7461626c6520616e796d6f72652e000000000000000000000000000060648201526084016109d6565b6115eb601080546001019055565b610d0f8161103160105490565b6000818152600460205260409020546060906001600160a01b03166116855760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e000000000000000000000000000000000060648201526084016109d6565b600061168f611fa1565b905060008151116116af576040518060200160405280600081525061139a565b806116b984611fb0565b6040516020016116ca929190612f56565b6040516020818303038152906040529392505050565b60008181526001602052604081206108c9906120ae565b610cbe82826120b8565b600f546001600160a01b0316331461175b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d6565b601180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b179055565b600f546001600160a01b031633146117e55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109d6565b6001600160a01b0381166118615760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109d6565b610d0f81611e32565b6112da82826120de565b600061139a836001600160a01b03841661217c565b60006108c9826121cb565b600081815260066020526040902080546001600160a01b0319166001600160a01b03841690811790915581906118c982610efd565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600460205260408120546001600160a01b031661197b5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016109d6565b600061198683610efd565b9050806001600160a01b0316846001600160a01b031614806119c15750836001600160a01b03166119b684610961565b6001600160a01b0316145b806119f157506001600160a01b0380821660009081526007602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611a0c82610efd565b6001600160a01b031614611a885760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016109d6565b6001600160a01b038216611b035760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109d6565b611b0e838383612209565b611b19600082611894565b6001600160a01b0383166000908152600560205260408120805460019290611b429084906130a0565b90915550506001600160a01b0382166000908152600560205260408120805460019290611b70908490613055565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600082815260208190526040902060010154611bed8133612214565b610b2883836120de565b6001600160a01b0381163314611c755760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016109d6565b6112da8282612292565b600061139a836001600160a01b038416612311565b600c5460ff16611ce65760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016109d6565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000611d3b82610efd565b9050611d4981600084612209565b611d54600083611894565b6001600160a01b0381166000908152600560205260408120805460019290611d7d9084906130a0565b909155505060008281526004602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6101f48110611e285760405162461bcd60e51b815260206004820152601d60248201527f416c6c20746865206d6f6f6e206361747320617265206d696e7465642e00000060448201526064016109d6565b6112da8282612404565b600f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600c5460ff1615611ed75760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016109d6565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611d133390565b600061139a8383612552565b611f238484846119f9565b611f2f8484848461257c565b6114fd5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109d6565b6060600e80546108de906130fa565b606081611fd45750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611ffe5780611fe881613135565b9150611ff79050600a8361306d565b9150611fd8565b60008167ffffffffffffffff811115612019576120196131bc565b6040519080825280601f01601f191660200182016040528015612043576020820181803683370190505b5090505b84156119f1576120586001836130a0565b9150612065600a86613150565b612070906030613055565b60f81b818381518110612085576120856131a6565b60200101906001600160f81b031916908160001a9053506120a7600a8661306d565b9450612047565b60006108c9825490565b6000828152602081905260409020600101546120d48133612214565b610b288383612292565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166112da576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556121383390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008181526001830160205260408120546121c3575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108c9565b5060006108c9565b60006001600160e01b031982167f780e9d630000000000000000000000000000000000000000000000000000000014806108c957506108c9826126df565b610b28838383612751565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166112da57612250816001600160a01b031660146127d5565b61225b8360206127d5565b60405160200161226c929190612f85565b60408051601f198184030181529082905262461bcd60e51b82526109d691600401613042565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16156112da576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600081815260018301602052604081205480156123fa5760006123356001836130a0565b8554909150600090612349906001906130a0565b90508181146123ae576000866000018281548110612369576123696131a6565b906000526020600020015490508087600001848154811061238c5761238c6131a6565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806123bf576123bf613190565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108c9565b60009150506108c9565b6001600160a01b03821661245a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109d6565b6000818152600460205260409020546001600160a01b0316156124bf5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109d6565b6124cb60008383612209565b6001600160a01b03821660009081526005602052604081208054600192906124f4908490613055565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000826000018281548110612569576125696131a6565b9060005260206000200154905092915050565b60006001600160a01b0384163b156126d457604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906125c0903390899088908890600401613006565b602060405180830381600087803b1580156125da57600080fd5b505af192505050801561260a575060408051601f3d908101601f1916820190925261260791810190612eea565b60015b6126ba573d808015612638576040519150601f19603f3d011682016040523d82523d6000602084013e61263d565b606091505b5080516126b25760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109d6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506119f1565b506001949350505050565b60006001600160e01b031982167f80ac58cd00000000000000000000000000000000000000000000000000000000148061274257506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806108c957506108c98261299a565b61275c8383836129d8565b600c5460ff1615610b285760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201527f68696c652070617573656400000000000000000000000000000000000000000060648201526084016109d6565b606060006127e4836002613081565b6127ef906002613055565b67ffffffffffffffff811115612807576128076131bc565b6040519080825280601f01601f191660200182016040528015612831576020820181803683370190505b509050600360fc1b8160008151811061284c5761284c6131a6565b60200101906001600160f81b031916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612897576128976131a6565b60200101906001600160f81b031916908160001a90535060006128bb846002613081565b6128c6906001613055565b90505b600181111561294b577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110612907576129076131a6565b1a60f81b82828151811061291d5761291d6131a6565b60200101906001600160f81b031916908160001a90535060049490941c93612944816130e3565b90506128c9565b50831561139a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109d6565b60006001600160e01b031982167f5a05180f0000000000000000000000000000000000000000000000000000000014806108c957506108c982612a90565b6001600160a01b038316612a3357612a2e81600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b612a56565b816001600160a01b0316836001600160a01b031614612a5657612a568382612af7565b6001600160a01b038216612a6d57610b2881612b94565b826001600160a01b0316826001600160a01b031614610b2857610b288282612c43565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806108c957507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146108c9565b60006001612b0484611044565b612b0e91906130a0565b600083815260096020526040902054909150808214612b61576001600160a01b03841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b5060009182526009602090815260408084208490556001600160a01b039094168352600881528383209183525290812055565b600a54600090612ba6906001906130a0565b6000838152600b6020526040812054600a8054939450909284908110612bce57612bce6131a6565b9060005260206000200154905080600a8381548110612bef57612bef6131a6565b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a805480612c2757612c27613190565b6001900381819060005260206000200160009055905550505050565b6000612c4e83611044565b6001600160a01b039093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b80356001600160a01b0381168114612c9e57600080fd5b919050565b600060208284031215612cb557600080fd5b61139a82612c87565b60008060408385031215612cd157600080fd5b612cda83612c87565b9150612ce860208401612c87565b90509250929050565b600080600060608486031215612d0657600080fd5b612d0f84612c87565b9250612d1d60208501612c87565b9150604084013590509250925092565b60008060008060808587031215612d4357600080fd5b612d4c85612c87565b9350612d5a60208601612c87565b925060408501359150606085013567ffffffffffffffff80821115612d7e57600080fd5b818701915087601f830112612d9257600080fd5b813581811115612da457612da46131bc565b604051601f8201601f19908116603f01168101908382118183101715612dcc57612dcc6131bc565b816040528281528a6020848701011115612de557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215612e1c57600080fd5b612e2583612c87565b915060208301358015158114612e3a57600080fd5b809150509250929050565b60008060408385031215612e5857600080fd5b612e6183612c87565b946020939093013593505050565b600060208284031215612e8157600080fd5b5035919050565b60008060408385031215612e9b57600080fd5b82359150612ce860208401612c87565b60008060408385031215612ebe57600080fd5b50508035926020909101359150565b600060208284031215612edf57600080fd5b813561139a816131d2565b600060208284031215612efc57600080fd5b815161139a816131d2565b600060208284031215612f1957600080fd5b813560ff8116811461139a57600080fd5b60008151808452612f428160208601602086016130b7565b601f01601f19169290920160200192915050565b60008351612f688184602088016130b7565b835190830190612f7c8183602088016130b7565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612fbd8160178501602088016130b7565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351612ffa8160288401602088016130b7565b01602801949350505050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526130386080830184612f2a565b9695505050505050565b60208152600061139a6020830184612f2a565b6000821982111561306857613068613164565b500190565b60008261307c5761307c61317a565b500490565b600081600019048311821515161561309b5761309b613164565b500290565b6000828210156130b2576130b2613164565b500390565b60005b838110156130d25781810151838201526020016130ba565b838111156114fd5750506000910152565b6000816130f2576130f2613164565b506000190190565b600181811c9082168061310e57607f821691505b6020821081141561312f57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561314957613149613164565b5060010190565b60008261315f5761315f61317a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610d0f57600080fdfea2646970667358221220f76de31396fc7d838f2f81e9a5f1b30b4cc6e3d69b692a81e6b40f7d4f5bd86c64736f6c63430008070033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000096d6391a0f1300883ed030fbb185a3a9bde78b85000000000000000000000000000000000000000000000000000000000000002e68747470733a2f2f7777772e6d6f6f6e63617466616e746f6d2e636f6d2f6170692f6d657461646174613f69643d000000000000000000000000000000000000

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

000000000000000000000000000000000000000000000000000000000000004000000000000000000000000096d6391a0f1300883ed030fbb185a3a9bde78b85000000000000000000000000000000000000000000000000000000000000002e68747470733a2f2f7777772e6d6f6f6e63617466616e746f6d2e636f6d2f6170692f6d657461646174613f69643d000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _baseTokenURI (string): https://www.mooncatfantom.com/api/metadata?id=
Arg [1] : _paymentManager (address): 0x96d6391a0f1300883ed030fbb185a3a9bde78b85

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 00000000000000000000000096d6391a0f1300883ed030fbb185a3a9bde78b85
Arg [2] : 000000000000000000000000000000000000000000000000000000000000002e
Arg [3] : 68747470733a2f2f7777772e6d6f6f6e63617466616e746f6d2e636f6d2f6170
Arg [4] : 692f6d657461646174613f69643d000000000000000000000000000000000000


Deployed ByteCode Sourcemap

80385:2686:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82309:272;;;;;;;;;;-1:-1:-1;82309:272:0;;;;;:::i;:::-;;:::i;:::-;;;7413:14:1;;7406:22;7388:41;;7376:2;7361:18;82309:272:0;;;;;;;;24013:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;25572:221::-;;;;;;;;;;-1:-1:-1;25572:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;6363:55:1;;;6345:74;;6333:2;6318:18;25572:221:0;6199:226:1;25095:411:0;;;;;;;;;;-1:-1:-1;25095:411:0;;;;;:::i;:::-;;:::i;:::-;;37760:113;;;;;;;;;;-1:-1:-1;37848:10:0;:17;37760:113;;;7586:25:1;;;7574:2;7559:18;37760:113:0;7440:177:1;80513:38:0;;;;;;;;;;;;80548:3;80513:38;;26462:339;;;;;;;;;;-1:-1:-1;26462:339:0;;;;;:::i;:::-;;:::i;55247:123::-;;;;;;;;;;-1:-1:-1;55247:123:0;;;;;:::i;:::-;55313:7;55340:12;;;;;;;;;;:22;;;;55247:123;82636:238;;;;;;;;;;-1:-1:-1;82636:238:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;7138:55:1;;;7120:74;;7225:2;7210:18;;7203:34;;;;7093:18;82636:238:0;6946:297:1;72828:196:0;;;;;;;;;;-1:-1:-1;72828:196:0;;;;;:::i;:::-;;:::i;37428:256::-;;;;;;;;;;-1:-1:-1;37428:256:0;;;;;:::i;:::-;;:::i;73413:205::-;;;;;;;;;;-1:-1:-1;73413:205:0;;;;;:::i;:::-;;:::i;82965:103::-;;;;;;;;;;;;;:::i;78625:185::-;;;;;;;;;;;;;:::i;26872:::-;;;;;;;;;;-1:-1:-1;26872:185:0;;;;;:::i;:::-;;:::i;43729:245::-;;;;;;;;;;-1:-1:-1;43729:245:0;;;;;:::i;:::-;;:::i;37950:233::-;;;;;;;;;;-1:-1:-1;37950:233:0;;;;;:::i;:::-;;:::i;45059:86::-;;;;;;;;;;-1:-1:-1;45130:7:0;;;;45059:86;;23707:239;;;;;;;;;;-1:-1:-1;23707:239:0;;;;;:::i;:::-;;:::i;77605:407::-;;;;;;;;;;-1:-1:-1;77605:407:0;;;;;:::i;:::-;;:::i;23437:208::-;;;;;;;;;;-1:-1:-1;23437:208:0;;;;;:::i;:::-;;:::i;2593:94::-;;;;;;;;;;;;;:::i;81170:495::-;;;;;;:::i;:::-;;:::i;78227:179::-;;;;;;;;;;;;;:::i;1942:87::-;;;;;;;;;;-1:-1:-1;2015:6:0;;-1:-1:-1;;;;;2015:6:0;1942:87;;72283:145;;;;;;;;;;-1:-1:-1;72283:145:0;;;;;:::i;:::-;;:::i;54132:139::-;;;;;;;;;;-1:-1:-1;54132:139:0;;;;;:::i;:::-;54210:4;54234:12;;;;;;;;;;;-1:-1:-1;;;;;54234:29:0;;;;;;;;;;;;;;;54132:139;24182:104;;;;;;;;;;;;;:::i;53223:49::-;;;;;;;;;;-1:-1:-1;53223:49:0;53268:4;53223:49;;25865:295;;;;;;;;;;-1:-1:-1;25865:295:0;;;;;:::i;:::-;;:::i;27128:328::-;;;;;;;;;;-1:-1:-1;27128:328:0;;;;;:::i;:::-;;:::i;81673:223::-;;;;;;;;;;-1:-1:-1;81673:223:0;;;;;:::i;:::-;;:::i;80558:46::-;;;;;;;;;;;;80595:9;80558:46;;24357:334;;;;;;;;;;-1:-1:-1;24357:334:0;;;;;:::i;:::-;;:::i;72602:134::-;;;;;;;;;;-1:-1:-1;72602:134:0;;;;;:::i;:::-;;:::i;76268:62::-;;;;;;;;;;;;76306:24;76268:62;;73117:201;;;;;;;;;;-1:-1:-1;73117:201:0;;;;;:::i;:::-;;:::i;76337:62::-;;;;;;;;;;;;76375:24;76337:62;;82176:78;;;;;;;;;;;;;:::i;26231:164::-;;;;;;;;;;-1:-1:-1;26231:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;26352:25:0;;;26328:4;26352:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;26231:164;80611:38;;;;;;;;;;;;80647:2;80611:38;;;;;20962:4:1;20950:17;;;20932:36;;20920:2;20905:18;80611:38:0;20790:184:1;2842:192:0;;;;;;;;;;-1:-1:-1;2842:192:0;;;;;:::i;:::-;;:::i;82309:272::-;82463:4;-1:-1:-1;;;;;;82492:41:0;;82507:26;82492:41;;:81;;;82537:36;82561:11;82537:23;:36::i;:::-;82485:88;82309:272;-1:-1:-1;;82309:272:0:o;24013:100::-;24067:13;24100:5;24093:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24013:100;:::o;25572:221::-;25648:7;29055:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29055:16:0;25668:73;;;;-1:-1:-1;;;25668:73:0;;15447:2:1;25668:73:0;;;15429:21:1;15486:2;15466:18;;;15459:30;15525:34;15505:18;;;15498:62;-1:-1:-1;;;15576:18:1;;;15569:42;15628:19;;25668:73:0;;;;;;;;;-1:-1:-1;25761:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;25761:24:0;;25572:221::o;25095:411::-;25176:13;25192:23;25207:7;25192:14;:23::i;:::-;25176:39;;25240:5;-1:-1:-1;;;;;25234:11:0;:2;-1:-1:-1;;;;;25234:11:0;;;25226:57;;;;-1:-1:-1;;;25226:57:0;;17466:2:1;25226:57:0;;;17448:21:1;17505:2;17485:18;;;17478:30;17544:34;17524:18;;;17517:62;17615:3;17595:18;;;17588:31;17636:19;;25226:57:0;17264:397:1;25226:57:0;806:10;-1:-1:-1;;;;;25318:21:0;;;;:62;;-1:-1:-1;25343:37:0;25360:5;806:10;26231:164;:::i;25343:37::-;25296:168;;;;-1:-1:-1;;;25296:168:0;;13840:2:1;25296:168:0;;;13822:21:1;13879:2;13859:18;;;13852:30;13918:34;13898:18;;;13891:62;13989:26;13969:18;;;13962:54;14033:19;;25296:168:0;13638:420:1;25296:168:0;25477:21;25486:2;25490:7;25477:8;:21::i;:::-;25165:341;25095:411;;:::o;26462:339::-;26657:41;806:10;26676:12;26690:7;26657:18;:41::i;:::-;26649:103;;;;-1:-1:-1;;;26649:103:0;;17868:2:1;26649:103:0;;;17850:21:1;17907:2;17887:18;;;17880:30;17946:34;17926:18;;;17919:62;18017:19;17997:18;;;17990:47;18054:19;;26649:103:0;17666:413:1;26649:103:0;26765:28;26775:4;26781:2;26785:7;26765:9;:28::i;82636:238::-;82819:14;;82754:16;;;;-1:-1:-1;;;;;82819:14:0;82860:5;82836:20;80690:3;82836:10;:20;:::i;:::-;82835:30;;;;:::i;:::-;82811:55;;;;82636:238;;;;;:::o;72828:196::-;72944:30;72960:4;72966:7;72944:15;:30::i;:::-;72985:18;;;;:12;:18;;;;;:31;;73008:7;72985:22;:31::i;37428:256::-;37525:7;37561:23;37578:5;37561:16;:23::i;:::-;37553:5;:31;37545:87;;;;-1:-1:-1;;;37545:87:0;;9528:2:1;37545:87:0;;;9510:21:1;9567:2;9547:18;;;9540:30;9606:34;9586:18;;;9579:62;9677:13;9657:18;;;9650:41;9708:19;;37545:87:0;9326:407:1;37545:87:0;-1:-1:-1;;;;;;37650:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;37428:256::o;73413:205::-;73532:33;73551:4;73557:7;73532:18;:33::i;:::-;73576:18;;;;:12;:18;;;;;:34;;73602:7;73576:25;:34::i;82965:103::-;83013:14;;83005:55;;-1:-1:-1;;;;;83013:14:0;;;;83038:21;83005:55;;;;;83013:14;83005:55;83013:14;83005:55;83038:21;83013:14;83005:55;;;;;;;;;;;;;;;;;;;;;82965:103::o;78625:185::-;78678:34;76375:24;806:10;54132:139;:::i;78678:34::-;78670:111;;;;;-1:-1:-1;;;78670:111:0;;19546:2:1;78670:111:0;;;19528:21:1;19565:18;;;19558:30;;;;19624:34;19604:18;;;19597:62;19695:34;19675:18;;;19668:62;19747:19;;78670:111:0;19344:428:1;78670:111:0;78792:10;:8;:10::i;:::-;78625:185::o;26872:::-;27010:39;27027:4;27033:2;27037:7;27010:39;;;;;;;;;;;;:16;:39::i;43729:245::-;43847:41;806:10;43866:12;726:98;43847:41;43839:102;;;;-1:-1:-1;;;43839:102:0;;19129:2:1;43839:102:0;;;19111:21:1;19168:2;19148:18;;;19141:30;19207:34;19187:18;;;19180:62;19278:18;19258;;;19251:46;19314:19;;43839:102:0;18927:412:1;43839:102:0;43952:14;43958:7;43952:5;:14::i;37950:233::-;38025:7;38061:30;37848:10;:17;;37760:113;38061:30;38053:5;:38;38045:95;;;;-1:-1:-1;;;38045:95:0;;18286:2:1;38045:95:0;;;18268:21:1;18325:2;18305:18;;;18298:30;18364:34;18344:18;;;18337:62;18435:14;18415:18;;;18408:42;18467:19;;38045:95:0;18084:408:1;38045:95:0;38158:10;38169:5;38158:17;;;;;;;;:::i;:::-;;;;;;;;;38151:24;;37950:233;;;:::o;23707:239::-;23779:7;23815:16;;;:7;:16;;;;;;-1:-1:-1;;;;;23815:16:0;23850:19;23842:73;;;;-1:-1:-1;;;23842:73:0;;14676:2:1;23842:73:0;;;14658:21:1;14715:2;14695:18;;;14688:30;14754:34;14734:18;;;14727:62;14825:11;14805:18;;;14798:39;14854:19;;23842:73:0;14474:405:1;77605:407:0;77665:34;76306:24;806:10;54132:139;:::i;77665:34::-;77657:108;;;;-1:-1:-1;;;77657:108:0;;18699:2:1;77657:108:0;;;18681:21:1;18738:2;18718:18;;;18711:30;18777:34;18757:18;;;18750:62;18848:31;18828:18;;;18821:59;18897:19;;77657:108:0;18497:425:1;77657:108:0;77930:36;77936:2;77940:25;:15;74802:14;;74710:114;77940:25;77930:5;:36::i;:::-;77977:27;:15;74921:19;;74939:1;74921:19;;;74832:127;23437:208;23509:7;-1:-1:-1;;;;;23537:19:0;;23529:74;;;;-1:-1:-1;;;23529:74:0;;14265:2:1;23529:74:0;;;14247:21:1;14304:2;14284:18;;;14277:30;14343:34;14323:18;;;14316:62;14414:12;14394:18;;;14387:40;14444:19;;23529:74:0;14063:406:1;23529:74:0;-1:-1:-1;;;;;;23621:16:0;;;;;:9;:16;;;;;;;23437:208::o;2593:94::-;2015:6;;-1:-1:-1;;;;;2015:6:0;806:10;2162:23;2154:68;;;;-1:-1:-1;;;2154:68:0;;15860:2:1;2154:68:0;;;15842:21:1;;;15879:18;;;15872:30;15938:34;15918:18;;;15911:62;15990:18;;2154:68:0;15658:356:1;2154:68:0;2658:21:::1;2676:1;2658:9;:21::i;81170:495::-:0;81238:8;;-1:-1:-1;;;81238:8:0;;;;81230:52;;;;-1:-1:-1;;;81230:52:0;;10766:2:1;81230:52:0;;;10748:21:1;10805:2;10785:18;;;10778:30;10844:33;10824:18;;;10817:61;10895:18;;81230:52:0;10564:355:1;81230:52:0;80647:2;81301:24;;;;;81293:77;;;;-1:-1:-1;;;81293:77:0;;11483:2:1;81293:77:0;;;11465:21:1;11522:2;11502:18;;;11495:30;11561:34;11541:18;;;11534:62;11632:10;11612:18;;;11605:38;11660:19;;81293:77:0;11281:404:1;81293:77:0;81402:22;;;;80595:9;81402:22;:::i;:::-;81389:9;:35;81381:94;;;;-1:-1:-1;;;81381:94:0;;19979:2:1;81381:94:0;;;19961:21:1;20018:2;19998:18;;;19991:30;20057:34;20037:18;;;20030:62;20128:16;20108:18;;;20101:44;20162:19;;81381:94:0;19777:410:1;81381:94:0;81519:10;81514:144;81540:9;81535:14;;:2;:14;81514:144;;;81572:21;:9;74921:19;;74939:1;74921:19;;;74832:127;81572:21;81608:38;81614:10;81626:19;:9;74802:14;;74710:114;81608:38;81551:4;;;;:::i;:::-;;;;81514:144;;;;81170:495;:::o;78227:179::-;78278:34;76375:24;806:10;54132:139;:::i;78278:34::-;78270:109;;;;-1:-1:-1;;;78270:109:0;;11892:2:1;78270:109:0;;;11874:21:1;11931:2;11911:18;;;11904:30;11970:34;11950:18;;;11943:62;12041:32;12021:18;;;12014:60;12091:19;;78270:109:0;11690:426:1;78270:109:0;78390:8;:6;:8::i;72283:145::-;72365:7;72392:18;;;:12;:18;;;;;:28;;72414:5;72392:21;:28::i;:::-;72385:35;72283:145;-1:-1:-1;;;72283:145:0:o;24182:104::-;24238:13;24271:7;24264:14;;;;;:::i;25865:295::-;-1:-1:-1;;;;;25968:24:0;;806:10;25968:24;;25960:62;;;;-1:-1:-1;;;25960:62:0;;12728:2:1;25960:62:0;;;12710:21:1;12767:2;12747:18;;;12740:30;12806:27;12786:18;;;12779:55;12851:18;;25960:62:0;12526:349:1;25960:62:0;806:10;26035:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;26035:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;26035:53:0;;;;;;;;;;26104:48;;7388:41:1;;;26035:42:0;;806:10;26104:48;;7361:18:1;26104:48:0;;;;;;;25865:295;;:::o;27128:328::-;27303:41;806:10;27336:7;27303:18;:41::i;:::-;27295:103;;;;-1:-1:-1;;;27295:103:0;;17868:2:1;27295:103:0;;;17850:21:1;17907:2;17887:18;;;17880:30;17946:34;17926:18;;;17919:62;18017:19;17997:18;;;17990:47;18054:19;;27295:103:0;17666:413:1;27295:103:0;27409:39;27423:4;27429:2;27433:7;27442:5;27409:13;:39::i;:::-;27128:328;;;;:::o;81673:223::-;2015:6;;-1:-1:-1;;;;;2015:6:0;806:10;2162:23;2154:68;;;;-1:-1:-1;;;2154:68:0;;15860:2:1;2154:68:0;;;15842:21:1;;;15879:18;;;15872:30;15938:34;15918:18;;;15911:62;15990:18;;2154:68:0;15658:356:1;2154:68:0;81751:8:::1;::::0;-1:-1:-1;;;81751:8:0;::::1;;;81750:9;81742:72;;;::::0;-1:-1:-1;;;81742:72:0;;16221:2:1;81742:72:0::1;::::0;::::1;16203:21:1::0;16260:2;16240:18;;;16233:30;16299:34;16279:18;;;16272:62;16370:20;16350:18;;;16343:48;16408:19;;81742:72:0::1;16019:414:1::0;81742:72:0::1;81825:21;:9;74921:19:::0;;74939:1;74921:19;;;74832:127;81825:21:::1;81857:31;81863:3;81868:19;:9;74802:14:::0;;74710:114;24357:334;29031:4;29055:16;;;:7;:16;;;;;;24430:13;;-1:-1:-1;;;;;29055:16:0;24456:76;;;;-1:-1:-1;;;24456:76:0;;17050:2:1;24456:76:0;;;17032:21:1;17089:2;17069:18;;;17062:30;17128:34;17108:18;;;17101:62;17199:17;17179:18;;;17172:45;17234:19;;24456:76:0;16848:411:1;24456:76:0;24545:21;24569:10;:8;:10::i;:::-;24545:34;;24621:1;24603:7;24597:21;:25;:86;;;;;;;;;;;;;;;;;24649:7;24658:18;:7;:16;:18::i;:::-;24632:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;24590:93;24357:334;-1:-1:-1;;;24357:334:0:o;72602:134::-;72674:7;72701:18;;;:12;:18;;;;;:27;;:25;:27::i;73117:201::-;73234:31;73251:4;73257:7;73234:16;:31::i;82176:78::-;2015:6;;-1:-1:-1;;;;;2015:6:0;806:10;2162:23;2154:68;;;;-1:-1:-1;;;2154:68:0;;15860:2:1;2154:68:0;;;15842:21:1;;;15879:18;;;15872:30;15938:34;15918:18;;;15911:62;15990:18;;2154:68:0;15658:356:1;2154:68:0;82231:8:::1;:15:::0;;;::::1;-1:-1:-1::0;;;82231:15:0::1;::::0;;82176:78::o;2842:192::-;2015:6;;-1:-1:-1;;;;;2015:6:0;806:10;2162:23;2154:68;;;;-1:-1:-1;;;2154:68:0;;15860:2:1;2154:68:0;;;15842:21:1;;;15879:18;;;15872:30;15938:34;15918:18;;;15911:62;15990:18;;2154:68:0;15658:356:1;2154:68:0;-1:-1:-1;;;;;2931:22:0;::::1;2923:73;;;::::0;-1:-1:-1;;;2923:73:0;;10359:2:1;2923:73:0::1;::::0;::::1;10341:21:1::0;10398:2;10378:18;;;10371:30;10437:34;10417:18;;;10410:62;10508:8;10488:18;;;10481:36;10534:19;;2923:73:0::1;10157:402:1::0;2923:73:0::1;3007:19;3017:8;3007:9;:19::i;57481:112::-:0;57560:25;57571:4;57577:7;57560:10;:25::i;66268:152::-;66338:4;66362:50;66367:3;-1:-1:-1;;;;;66387:23:0;;66362:4;:50::i;79129:254::-;79310:4;79339:36;79363:11;79339:23;:36::i;32948:174::-;33023:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;33023:29:0;-1:-1:-1;;;;;33023:29:0;;;;;;;;:24;;33077:23;33023:24;33077:14;:23::i;:::-;-1:-1:-1;;;;;33068:46:0;;;;;;;;;;;32948:174;;:::o;29260:348::-;29353:4;29055:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29055:16:0;29370:73;;;;-1:-1:-1;;;29370:73:0;;13082:2:1;29370:73:0;;;13064:21:1;13121:2;13101:18;;;13094:30;13160:34;13140:18;;;13133:62;-1:-1:-1;;;13211:18:1;;;13204:42;13263:19;;29370:73:0;12880:408:1;29370:73:0;29454:13;29470:23;29485:7;29470:14;:23::i;:::-;29454:39;;29523:5;-1:-1:-1;;;;;29512:16:0;:7;-1:-1:-1;;;;;29512:16:0;;:51;;;;29556:7;-1:-1:-1;;;;;29532:31:0;:20;29544:7;29532:11;:20::i;:::-;-1:-1:-1;;;;;29532:31:0;;29512:51;:87;;;-1:-1:-1;;;;;;26352:25:0;;;26328:4;26352:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;29567:32;29504:96;29260:348;-1:-1:-1;;;;29260:348:0:o;32252:578::-;32411:4;-1:-1:-1;;;;;32384:31:0;:23;32399:7;32384:14;:23::i;:::-;-1:-1:-1;;;;;32384:31:0;;32376:85;;;;-1:-1:-1;;;32376:85:0;;16640:2:1;32376:85:0;;;16622:21:1;16679:2;16659:18;;;16652:30;16718:34;16698:18;;;16691:62;16789:11;16769:18;;;16762:39;16818:19;;32376:85:0;16438:405:1;32376:85:0;-1:-1:-1;;;;;32480:16:0;;32472:65;;;;-1:-1:-1;;;32472:65:0;;12323:2:1;32472:65:0;;;12305:21:1;12362:2;12342:18;;;12335:30;12401:34;12381:18;;;12374:62;12472:6;12452:18;;;12445:34;12496:19;;32472:65:0;12121:400:1;32472:65:0;32550:39;32571:4;32577:2;32581:7;32550:20;:39::i;:::-;32654:29;32671:1;32675:7;32654:8;:29::i;:::-;-1:-1:-1;;;;;32696:15:0;;;;;;:9;:15;;;;;:20;;32715:1;;32696:15;:20;;32715:1;;32696:20;:::i;:::-;;;;-1:-1:-1;;;;;;;32727:13:0;;;;;;:9;:13;;;;;:18;;32744:1;;32727:13;:18;;32744:1;;32727:18;:::i;:::-;;;;-1:-1:-1;;32756:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;32756:21:0;-1:-1:-1;;;;;32756:21:0;;;;;;;;;32795:27;;32756:16;;32795:27;;;;;;;32252:578;;;:::o;55632:147::-;55313:7;55340:12;;;;;;;;;;:22;;;53714:30;53725:4;806:10;53714;:30::i;:::-;55746:25:::1;55757:4;55763:7;55746:10;:25::i;56680:218::-:0;-1:-1:-1;;;;;56776:23:0;;806:10;56776:23;56768:83;;;;-1:-1:-1;;;56768:83:0;;20394:2:1;56768:83:0;;;20376:21:1;20433:2;20413:18;;;20406:30;20472:34;20452:18;;;20445:62;20543:17;20523:18;;;20516:45;20578:19;;56768:83:0;20192:411:1;56768:83:0;56864:26;56876:4;56882:7;56864:11;:26::i;66596:158::-;66669:4;66693:53;66701:3;-1:-1:-1;;;;;66721:23:0;;66693:7;:53::i;46118:120::-;45130:7;;;;45654:41;;;;-1:-1:-1;;;45654:41:0;;9179:2:1;45654:41:0;;;9161:21:1;9218:2;9198:18;;;9191:30;9257:22;9237:18;;;9230:50;9297:18;;45654:41:0;8977:344:1;45654:41:0;46177:7:::1;:15:::0;;-1:-1:-1;;46177:15:0::1;::::0;;46208:22:::1;806:10:::0;46217:12:::1;46208:22;::::0;-1:-1:-1;;;;;6363:55:1;;;6345:74;;6333:2;6318:18;46208:22:0::1;;;;;;;46118:120::o:0;31555:360::-;31615:13;31631:23;31646:7;31631:14;:23::i;:::-;31615:39;;31667:48;31688:5;31703:1;31707:7;31667:20;:48::i;:::-;31756:29;31773:1;31777:7;31756:8;:29::i;:::-;-1:-1:-1;;;;;31798:16:0;;;;;;:9;:16;;;;;:21;;31818:1;;31798:16;:21;;31818:1;;31798:21;:::i;:::-;;;;-1:-1:-1;;31837:16:0;;;;:7;:16;;;;;;31830:23;;-1:-1:-1;;;;;;31830:23:0;;;31871:36;31845:7;;31837:16;-1:-1:-1;;;;;31871:36:0;;;;;31837:16;;31871:36;31604:311;31555:360;:::o;81964:164::-;80548:3;82041;:14;82033:56;;;;-1:-1:-1;;;82033:56:0;;8048:2:1;82033:56:0;;;8030:21:1;8087:2;8067:18;;;8060:30;8126:31;8106:18;;;8099:59;8175:18;;82033:56:0;7846:353:1;82033:56:0;82100:20;82112:2;82116:3;82100:11;:20::i;3042:173::-;3117:6;;;-1:-1:-1;;;;;3134:17:0;;;-1:-1:-1;;;;;;3134:17:0;;;;;;;3167:40;;3117:6;;;3134:17;3117:6;;3167:40;;3098:16;;3167:40;3087:128;3042:173;:::o;45859:118::-;45130:7;;;;45384:9;45376:38;;;;-1:-1:-1;;;45376:38:0;;13495:2:1;45376:38:0;;;13477:21:1;13534:2;13514:18;;;13507:30;13573:18;13553;;;13546:46;13609:18;;45376:38:0;13293:340:1;45376:38:0;45919:7:::1;:14:::0;;-1:-1:-1;;45919:14:0::1;45929:4;45919:14;::::0;;45949:20:::1;45956:12;806:10:::0;;726:98;67564:158;67638:7;67689:22;67693:3;67705:5;67689:3;:22::i;28338:315::-;28495:28;28505:4;28511:2;28515:7;28495:9;:28::i;:::-;28542:48;28565:4;28571:2;28575:7;28584:5;28542:22;:48::i;:::-;28534:111;;;;-1:-1:-1;;;28534:111:0;;9940:2:1;28534:111:0;;;9922:21:1;9979:2;9959:18;;;9952:30;10018:34;9998:18;;;9991:62;10089:20;10069:18;;;10062:48;10127:19;;28534:111:0;9738:414:1;77103:114:0;77163:13;77196;77189:20;;;;;:::i;19007:723::-;19063:13;19284:10;19280:53;;-1:-1:-1;;19311:10:0;;;;;;;;;;;;-1:-1:-1;;;19311:10:0;;;;;19007:723::o;19280:53::-;19358:5;19343:12;19399:78;19406:9;;19399:78;;19432:8;;;;:::i;:::-;;-1:-1:-1;19455:10:0;;-1:-1:-1;19463:2:0;19455:10;;:::i;:::-;;;19399:78;;;19487:19;19519:6;19509:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19509:17:0;;19487:39;;19537:154;19544:10;;19537:154;;19571:11;19581:1;19571:11;;:::i;:::-;;-1:-1:-1;19640:10:0;19648:2;19640:5;:10;:::i;:::-;19627:24;;:2;:24;:::i;:::-;19614:39;;19597:6;19604;19597:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;19597:56:0;;;;;;;;-1:-1:-1;19668:11:0;19677:2;19668:11;;:::i;:::-;;;19537:154;;67093:117;67156:7;67183:19;67191:3;62577:18;;62494:109;56024:149;55313:7;55340:12;;;;;;;;;;:22;;;53714:30;53725:4;806:10;53714;:30::i;:::-;56139:26:::1;56151:4;56157:7;56139:11;:26::i;57984:229::-:0;54210:4;54234:12;;;;;;;;;;;-1:-1:-1;;;;;54234:29:0;;;;;;;;;;;;58054:152;;58098:6;:12;;;;;;;;;;;-1:-1:-1;;;;;58098:29:0;;;;;;;;;:36;;-1:-1:-1;;58098:36:0;58130:4;58098:36;;;58181:12;806:10;;726:98;58181:12;-1:-1:-1;;;;;58154:40:0;58172:7;-1:-1:-1;;;;;58154:40:0;58166:4;58154:40;;;;;;;;;;57984:229;;:::o;60183:414::-;60246:4;62376:19;;;:12;;;:19;;;;;;60263:327;;-1:-1:-1;60306:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;60489:18;;60467:19;;;:12;;;:19;;;;;;:40;;;;60522:11;;60263:327;-1:-1:-1;60573:5:0;60566:12;;37120:224;37222:4;-1:-1:-1;;;;;;37246:50:0;;37261:35;37246:50;;:90;;;37300:36;37324:11;37300:23;:36::i;78818:239::-;79004:45;79031:4;79037:2;79041:7;79004:26;:45::i;54561:497::-;54210:4;54234:12;;;;;;;;;;;-1:-1:-1;;;;;54234:29:0;;;;;;;;;;;;54637:414;;54830:41;54858:7;-1:-1:-1;;;;;54830:41:0;54868:2;54830:19;:41::i;:::-;54944:38;54972:4;54979:2;54944:19;:38::i;:::-;54735:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;54735:270:0;;;;;;;;;;-1:-1:-1;;;54681:358:0;;;;;;;:::i;58221:230::-;54210:4;54234:12;;;;;;;;;;;-1:-1:-1;;;;;54234:29:0;;;;;;;;;;;;58292:152;;;58367:5;58335:12;;;;;;;;;;;-1:-1:-1;;;;;58335:29:0;;;;;;;;;;:37;;-1:-1:-1;;58335:37:0;;;58392:40;806:10;;58335:12;;58392:40;;58367:5;58392:40;58221:230;;:::o;60773:1420::-;60839:4;60978:19;;;:12;;;:19;;;;;;61014:15;;61010:1176;;61389:21;61413:14;61426:1;61413:10;:14;:::i;:::-;61462:18;;61389:38;;-1:-1:-1;61442:17:0;;61462:22;;61483:1;;61462:22;:::i;:::-;61442:42;;61518:13;61505:9;:26;61501:405;;61552:17;61572:3;:11;;61584:9;61572:22;;;;;;;;:::i;:::-;;;;;;;;;61552:42;;61726:9;61697:3;:11;;61709:13;61697:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;61811:23;;;:12;;;:23;;;;;:36;;;61501:405;61987:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;62082:3;:12;;:19;62095:5;62082:19;;;;;;;;;;;62075:26;;;62125:4;62118:11;;;;;;;61010:1176;62169:5;62162:12;;;;;30944:382;-1:-1:-1;;;;;31024:16:0;;31016:61;;;;-1:-1:-1;;;31016:61:0;;15086:2:1;31016:61:0;;;15068:21:1;;;15105:18;;;15098:30;15164:34;15144:18;;;15137:62;15216:18;;31016:61:0;14884:356:1;31016:61:0;29031:4;29055:16;;;:7;:16;;;;;;-1:-1:-1;;;;;29055:16:0;:30;31088:58;;;;-1:-1:-1;;;31088:58:0;;11126:2:1;31088:58:0;;;11108:21:1;11165:2;11145:18;;;11138:30;11204;11184:18;;;11177:58;11252:18;;31088:58:0;10924:352:1;31088:58:0;31159:45;31188:1;31192:2;31196:7;31159:20;:45::i;:::-;-1:-1:-1;;;;;31217:13:0;;;;;;:9;:13;;;;;:18;;31234:1;;31217:13;:18;;31234:1;;31217:18;:::i;:::-;;;;-1:-1:-1;;31246:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;31246:21:0;-1:-1:-1;;;;;31246:21:0;;;;;;;;31285:33;;31246:16;;;31285:33;;31246:16;;31285:33;30944:382;;:::o;62957:120::-;63024:7;63051:3;:11;;63063:5;63051:18;;;;;;;;:::i;:::-;;;;;;;;;63044:25;;62957:120;;;;:::o;33687:799::-;33842:4;-1:-1:-1;;;;;33863:13:0;;11682:20;11730:8;33859:620;;33899:72;;-1:-1:-1;;;33899:72:0;;-1:-1:-1;;;;;33899:36:0;;;;;:72;;806:10;;33950:4;;33956:7;;33965:5;;33899:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33899:72:0;;;;;;;;-1:-1:-1;;33899:72:0;;;;;;;;;;;;:::i;:::-;;;33895:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34141:13:0;;34137:272;;34184:60;;-1:-1:-1;;;34184:60:0;;9940:2:1;34184:60:0;;;9922:21:1;9979:2;9959:18;;;9952:30;10018:34;9998:18;;;9991:62;10089:20;10069:18;;;10062:48;10127:19;;34184:60:0;9738:414:1;34137:272:0;34359:6;34353:13;34344:6;34340:2;34336:15;34329:38;33895:529;-1:-1:-1;;;;;;34022:51:0;-1:-1:-1;;;34022:51:0;;-1:-1:-1;34015:58:0;;33859:620;-1:-1:-1;34463:4:0;33687:799;;;;;;:::o;23068:305::-;23170:4;-1:-1:-1;;;;;;23207:40:0;;23222:25;23207:40;;:105;;-1:-1:-1;;;;;;;23264:48:0;;23279:33;23264:48;23207:105;:158;;;;23329:36;23353:11;23329:23;:36::i;46848:275::-;46992:45;47019:4;47025:2;47029:7;46992:26;:45::i;:::-;45130:7;;;;47058:9;47050:65;;;;-1:-1:-1;;;47050:65:0;;8767:2:1;47050:65:0;;;8749:21:1;8806:2;8786:18;;;8779:30;8845:34;8825:18;;;8818:62;8916:13;8896:18;;;8889:41;8947:19;;47050:65:0;8565:407:1;20308:451:0;20383:13;20409:19;20441:10;20445:6;20441:1;:10;:::i;:::-;:14;;20454:1;20441:14;:::i;:::-;20431:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20431:25:0;;20409:47;;-1:-1:-1;;;20467:6:0;20474:1;20467:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20467:15:0;;;;;;;;;20493;:6;20500:1;20493:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20493:15:0;;;;;;;;-1:-1:-1;20524:9:0;20536:10;20540:6;20536:1;:10;:::i;:::-;:14;;20549:1;20536:14;:::i;:::-;20524:26;;20519:135;20556:1;20552;:5;20519:135;;;20591:12;20604:5;20612:3;20604:11;20591:25;;;;;;;:::i;:::-;;;;20579:6;20586:1;20579:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;20579:37:0;;;;;;;;-1:-1:-1;20641:1:0;20631:11;;;;;20559:3;;;:::i;:::-;;;20519:135;;;-1:-1:-1;20672:10:0;;20664:55;;;;-1:-1:-1;;;20664:55:0;;8406:2:1;20664:55:0;;;8388:21:1;;;8425:18;;;8418:30;8484:34;8464:18;;;8457:62;8536:18;;20664:55:0;8204:356:1;71470:214:0;71555:4;-1:-1:-1;;;;;;71579:57:0;;71594:42;71579:57;;:97;;;71640:36;71664:11;71640:23;:36::i;38796:589::-;-1:-1:-1;;;;;39002:18:0;;38998:187;;39037:40;39069:7;40212:10;:17;;40185:24;;;;:15;:24;;;;;:44;;;40240:24;;;;;;;;;;;;40108:164;39037:40;38998:187;;;39107:2;-1:-1:-1;;;;;39099:10:0;:4;-1:-1:-1;;;;;39099:10:0;;39095:90;;39126:47;39159:4;39165:7;39126:32;:47::i;:::-;-1:-1:-1;;;;;39199:16:0;;39195:183;;39232:45;39269:7;39232:36;:45::i;39195:183::-;39305:4;-1:-1:-1;;;;;39299:10:0;:2;-1:-1:-1;;;;;39299:10:0;;39295:83;;39326:40;39354:2;39358:7;39326:27;:40::i;53836:204::-;53921:4;-1:-1:-1;;;;;;53945:47:0;;53960:32;53945:47;;:87;;-1:-1:-1;21692:25:0;-1:-1:-1;;;;;;21677:40:0;;;53996:36;21568:157;40899:988;41165:22;41215:1;41190:22;41207:4;41190:16;:22::i;:::-;:26;;;;:::i;:::-;41227:18;41248:26;;;:17;:26;;;;;;41165:51;;-1:-1:-1;41381:28:0;;;41377:328;;-1:-1:-1;;;;;41448:18:0;;41426:19;41448:18;;;:12;:18;;;;;;;;:34;;;;;;;;;41499:30;;;;;;:44;;;41616:30;;:17;:30;;;;;:43;;;41377:328;-1:-1:-1;41801:26:0;;;;:17;:26;;;;;;;;41794:33;;;-1:-1:-1;;;;;41845:18:0;;;;;:12;:18;;;;;:34;;;;;;;41838:41;40899:988::o;42182:1079::-;42460:10;:17;42435:22;;42460:21;;42480:1;;42460:21;:::i;:::-;42492:18;42513:24;;;:15;:24;;;;;;42886:10;:26;;42435:46;;-1:-1:-1;42513:24:0;;42435:46;;42886:26;;;;;;:::i;:::-;;;;;;;;;42864:48;;42950:11;42925:10;42936;42925:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;43030:28;;;:15;:28;;;;;;;:41;;;43202:24;;;;;43195:31;43237:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;42253:1008;;;42182:1079;:::o;39686:221::-;39771:14;39788:20;39805:2;39788:16;:20::i;:::-;-1:-1:-1;;;;;39819:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;39864:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;39686:221:0:o;14:196:1:-;82:20;;-1:-1:-1;;;;;131:54:1;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;406:260::-;474:6;482;535:2;523:9;514:7;510:23;506:32;503:52;;;551:1;548;541:12;503:52;574:29;593:9;574:29;:::i;:::-;564:39;;622:38;656:2;645:9;641:18;622:38;:::i;:::-;612:48;;406:260;;;;;:::o;671:328::-;748:6;756;764;817:2;805:9;796:7;792:23;788:32;785:52;;;833:1;830;823:12;785:52;856:29;875:9;856:29;:::i;:::-;846:39;;904:38;938:2;927:9;923:18;904:38;:::i;:::-;894:48;;989:2;978:9;974:18;961:32;951:42;;671:328;;;;;:::o;1004:1138::-;1099:6;1107;1115;1123;1176:3;1164:9;1155:7;1151:23;1147:33;1144:53;;;1193:1;1190;1183:12;1144:53;1216:29;1235:9;1216:29;:::i;:::-;1206:39;;1264:38;1298:2;1287:9;1283:18;1264:38;:::i;:::-;1254:48;;1349:2;1338:9;1334:18;1321:32;1311:42;;1404:2;1393:9;1389:18;1376:32;1427:18;1468:2;1460:6;1457:14;1454:34;;;1484:1;1481;1474:12;1454:34;1522:6;1511:9;1507:22;1497:32;;1567:7;1560:4;1556:2;1552:13;1548:27;1538:55;;1589:1;1586;1579:12;1538:55;1625:2;1612:16;1647:2;1643;1640:10;1637:36;;;1653:18;;:::i;:::-;1728:2;1722:9;1696:2;1782:13;;-1:-1:-1;;1778:22:1;;;1802:2;1774:31;1770:40;1758:53;;;1826:18;;;1846:22;;;1823:46;1820:72;;;1872:18;;:::i;:::-;1912:10;1908:2;1901:22;1947:2;1939:6;1932:18;1987:7;1982:2;1977;1973;1969:11;1965:20;1962:33;1959:53;;;2008:1;2005;1998:12;1959:53;2064:2;2059;2055;2051:11;2046:2;2038:6;2034:15;2021:46;2109:1;2104:2;2099;2091:6;2087:15;2083:24;2076:35;2130:6;2120:16;;;;;;;1004:1138;;;;;;;:::o;2147:347::-;2212:6;2220;2273:2;2261:9;2252:7;2248:23;2244:32;2241:52;;;2289:1;2286;2279:12;2241:52;2312:29;2331:9;2312:29;:::i;:::-;2302:39;;2391:2;2380:9;2376:18;2363:32;2438:5;2431:13;2424:21;2417:5;2414:32;2404:60;;2460:1;2457;2450:12;2404:60;2483:5;2473:15;;;2147:347;;;;;:::o;2499:254::-;2567:6;2575;2628:2;2616:9;2607:7;2603:23;2599:32;2596:52;;;2644:1;2641;2634:12;2596:52;2667:29;2686:9;2667:29;:::i;:::-;2657:39;2743:2;2728:18;;;;2715:32;;-1:-1:-1;;;2499:254:1:o;2758:180::-;2817:6;2870:2;2858:9;2849:7;2845:23;2841:32;2838:52;;;2886:1;2883;2876:12;2838:52;-1:-1:-1;2909:23:1;;2758:180;-1:-1:-1;2758:180:1:o;2943:254::-;3011:6;3019;3072:2;3060:9;3051:7;3047:23;3043:32;3040:52;;;3088:1;3085;3078:12;3040:52;3124:9;3111:23;3101:33;;3153:38;3187:2;3176:9;3172:18;3153:38;:::i;3202:248::-;3270:6;3278;3331:2;3319:9;3310:7;3306:23;3302:32;3299:52;;;3347:1;3344;3337:12;3299:52;-1:-1:-1;;3370:23:1;;;3440:2;3425:18;;;3412:32;;-1:-1:-1;3202:248:1:o;3455:245::-;3513:6;3566:2;3554:9;3545:7;3541:23;3537:32;3534:52;;;3582:1;3579;3572:12;3534:52;3621:9;3608:23;3640:30;3664:5;3640:30;:::i;3705:249::-;3774:6;3827:2;3815:9;3806:7;3802:23;3798:32;3795:52;;;3843:1;3840;3833:12;3795:52;3875:9;3869:16;3894:30;3918:5;3894:30;:::i;4397:269::-;4454:6;4507:2;4495:9;4486:7;4482:23;4478:32;4475:52;;;4523:1;4520;4513:12;4475:52;4562:9;4549:23;4612:4;4605:5;4601:16;4594:5;4591:27;4581:55;;4632:1;4629;4622:12;4671:257;4712:3;4750:5;4744:12;4777:6;4772:3;4765:19;4793:63;4849:6;4842:4;4837:3;4833:14;4826:4;4819:5;4815:16;4793:63;:::i;:::-;4910:2;4889:15;-1:-1:-1;;4885:29:1;4876:39;;;;4917:4;4872:50;;4671:257;-1:-1:-1;;4671:257:1:o;4933:470::-;5112:3;5150:6;5144:13;5166:53;5212:6;5207:3;5200:4;5192:6;5188:17;5166:53;:::i;:::-;5282:13;;5241:16;;;;5304:57;5282:13;5241:16;5338:4;5326:17;;5304:57;:::i;:::-;5377:20;;4933:470;-1:-1:-1;;;;4933:470:1:o;5408:786::-;5819:25;5814:3;5807:38;5789:3;5874:6;5868:13;5890:62;5945:6;5940:2;5935:3;5931:12;5924:4;5916:6;5912:17;5890:62;:::i;:::-;6016:19;6011:2;5971:16;;;6003:11;;;5996:40;6061:13;;6083:63;6061:13;6132:2;6124:11;;6117:4;6105:17;;6083:63;:::i;:::-;6166:17;6185:2;6162:26;;5408:786;-1:-1:-1;;;;5408:786:1:o;6430:511::-;6624:4;-1:-1:-1;;;;;6734:2:1;6726:6;6722:15;6711:9;6704:34;6786:2;6778:6;6774:15;6769:2;6758:9;6754:18;6747:43;;6826:6;6821:2;6810:9;6806:18;6799:34;6869:3;6864:2;6853:9;6849:18;6842:31;6890:45;6930:3;6919:9;6915:19;6907:6;6890:45;:::i;:::-;6882:53;6430:511;-1:-1:-1;;;;;;6430:511:1:o;7622:219::-;7771:2;7760:9;7753:21;7734:4;7791:44;7831:2;7820:9;7816:18;7808:6;7791:44;:::i;20979:128::-;21019:3;21050:1;21046:6;21043:1;21040:13;21037:39;;;21056:18;;:::i;:::-;-1:-1:-1;21092:9:1;;20979:128::o;21112:120::-;21152:1;21178;21168:35;;21183:18;;:::i;:::-;-1:-1:-1;21217:9:1;;21112:120::o;21237:168::-;21277:7;21343:1;21339;21335:6;21331:14;21328:1;21325:21;21320:1;21313:9;21306:17;21302:45;21299:71;;;21350:18;;:::i;:::-;-1:-1:-1;21390:9:1;;21237:168::o;21410:125::-;21450:4;21478:1;21475;21472:8;21469:34;;;21483:18;;:::i;:::-;-1:-1:-1;21520:9:1;;21410:125::o;21540:258::-;21612:1;21622:113;21636:6;21633:1;21630:13;21622:113;;;21712:11;;;21706:18;21693:11;;;21686:39;21658:2;21651:10;21622:113;;;21753:6;21750:1;21747:13;21744:48;;;-1:-1:-1;;21788:1:1;21770:16;;21763:27;21540:258::o;21803:136::-;21842:3;21870:5;21860:39;;21879:18;;:::i;:::-;-1:-1:-1;;;21915:18:1;;21803:136::o;21944:437::-;22023:1;22019:12;;;;22066;;;22087:61;;22141:4;22133:6;22129:17;22119:27;;22087:61;22194:2;22186:6;22183:14;22163:18;22160:38;22157:218;;;-1:-1:-1;;;22228:1:1;22221:88;22332:4;22329:1;22322:15;22360:4;22357:1;22350:15;22157:218;;21944:437;;;:::o;22386:135::-;22425:3;-1:-1:-1;;22446:17:1;;22443:43;;;22466:18;;:::i;:::-;-1:-1:-1;22513:1:1;22502:13;;22386:135::o;22526:112::-;22558:1;22584;22574:35;;22589:18;;:::i;:::-;-1:-1:-1;22623:9:1;;22526:112::o;22643:184::-;-1:-1:-1;;;22692:1:1;22685:88;22792:4;22789:1;22782:15;22816:4;22813:1;22806:15;22832:184;-1:-1:-1;;;22881:1:1;22874:88;22981:4;22978:1;22971:15;23005:4;23002:1;22995:15;23021:184;-1:-1:-1;;;23070:1:1;23063:88;23170:4;23167:1;23160:15;23194:4;23191:1;23184:15;23210:184;-1:-1:-1;;;23259:1:1;23252:88;23359:4;23356:1;23349:15;23383:4;23380:1;23373:15;23399:184;-1:-1:-1;;;23448:1:1;23441:88;23548:4;23545:1;23538:15;23572:4;23569:1;23562:15;23588:177;-1:-1:-1;;;;;;23666:5:1;23662:78;23655:5;23652:89;23642:117;;23755:1;23752;23745:12

Swarm Source

ipfs://f76de31396fc7d838f2f81e9a5f1b30b4cc6e3d69b692a81e6b40f7d4f5bd86c
Loading