ETH Price: $2,631.26 (+5.96%)
Gas: 4 Gwei

Token

Noble ape game (NAG)
 

Overview

Max Total Supply

56 NAG

Holders

27

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 NAG
0xEbf438bF424D4b034D8a209cdcd35EFb138224d5
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Nobleape

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-12-23
*/

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

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


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

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/Address.sol


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

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/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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/extensions/IERC721Enumerable.sol


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

pragma solidity ^0.8.0;


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

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 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/IERC721Metadata.sol


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens 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 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

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/ERC721.sol


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: 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 Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev 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/ERC721Enumerable.sol


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

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev 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 {
        _transferOwnership(address(0));
    }

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

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

// File: contracts/Pesetas.sol


pragma solidity ^0.8.0;



contract PESETAS is ERC20, Ownable {

  mapping(address => bool) controllers;
  
  constructor() ERC20("PESETAS", "PSTS") { }

  function mint(address to, uint256 amount) external {
    require(controllers[msg.sender], "Only controllers can mint");
    _mint(to, amount);
  }


  function burn(address from, uint256 amount) external {
    require(controllers[msg.sender], "Only controllers can burn");
    _burn(from, amount);
  }

 
  function addController(address controller) external onlyOwner {
    controllers[controller] = true;
  }

  function removeController(address controller) external onlyOwner {
    controllers[controller] = false;
  }
}
// File: contracts/Nobleape.sol


pragma solidity ^0.8.0;






contract Nobleape is ERC721Enumerable, Ownable, Pausable {
    uint16 public constant MAX_TOKENS = 50000;
    uint16 public constant EXPANSION_TOKENS = 10000;
    string public baseExtension = ".json";
    string public notRevealedUri;

    uint256 public constant PRESALE_MINT_PRICE = .069 ether;
    uint256 public constant PUBLICSALE_MINT_PRICE = .08 ether;
    uint256 public constant PESTAS_MINT_COST = 40000 ether;

    uint256 public presaleTime = 0;
    uint256 public presaleClose = 0;
    uint256 public mainsaleTime = 1640282400;// 1640282400;
    uint16  public phase_presale_max_tokens = 0;  
    uint16  public phase_max_tokens = 3888;

    mapping(address => bool) whitelist;

    string private baseURI;
    bool public revealed = false;

    PESETAS private pesetas;

    constructor(address _pesetas, string memory _initNotRevealedUri) ERC721("Noble ape game", "NAG") {
        pesetas = PESETAS(_pesetas);
        setNotRevealedURI(_initNotRevealedUri);
    }

    modifier isMainsaleOpen
    {
         require(block.timestamp >= mainsaleTime, "sale has not started yet");
         _;
    }
    modifier isPresaleOpen
    {
         require(block.timestamp >= presaleTime && block.timestamp <= presaleClose, "Presale closed!");
         _;
    }

    function mintPre(uint8 amount) external payable whenNotPaused isPresaleOpen {
        uint256 minted = totalSupply();
        require(amIWhiteListed(), "You are not Whitelisted");
        require(amount > 0 && amount <= 3, "Invalid mint amount");
        require(minted + amount <= phase_presale_max_tokens, "max presale tokens minted");
        require(minted + amount <= EXPANSION_TOKENS, "max expansion tokens minted");
        require(amount * PRESALE_MINT_PRICE == msg.value, "Invalid ether amount");

        for (uint8 i = 0; i < amount; i++) {
            minted++;
            _safeMint(_msgSender(), minted);
        }
    }

    function mintMain(uint8 amount) external payable whenNotPaused isMainsaleOpen {
        uint256 minted = totalSupply();
        require(tx.origin == _msgSender(), "Only EOA");
        require(minted + amount <= phase_max_tokens, "max tokens minted");
        require(amount > 0 && amount <= 10, "Invalid mint amount");
        if (minted < EXPANSION_TOKENS) {
            require(
                minted + amount <= EXPANSION_TOKENS,
                "All expansion tokens already minted"
            );
            require(
                amount * PUBLICSALE_MINT_PRICE == msg.value,
                "Invalid ether amount"
            );
        } else {
            require(msg.value == 0, "no ether required");
            uint256 cost =  minted + amount < 20000 ? PESTAS_MINT_COST : PESTAS_MINT_COST * 2;
            pesetas.burn(_msgSender(), cost * amount);
        }
        for (uint256 i = 0; i < amount; i++) {
            minted++;
            _safeMint(_msgSender(), minted);
        }
    }

    function setPaused(bool _paused) external onlyOwner {
        if (_paused) _pause();
        else _unpause();
    }

    function amIWhiteListed() public view returns (bool) {
        return whitelist[msg.sender];
    }

    function addToWhiteList(address[] memory _whitelist) public onlyOwner {
        for (uint16 i; i < _whitelist.length; i++) {
            whitelist[_whitelist[i]] = true;
        }
    }

    function reveal(bool _revealed) external onlyOwner {
        revealed = _revealed;
    }

    function setMainsaletime(uint256 time) external onlyOwner {
        mainsaleTime = time;
    }
    
    function setPresaletime(uint256 time) external onlyOwner {
        presaleTime = time;
    }

    function setPresaleclosetime(uint256 time) external onlyOwner {
        presaleClose = time;
    }

    function updatePsts(address psts) external onlyOwner {
        pesetas = PESETAS(psts);
    }

    function setPhaseMaxTokens(uint16 max) external onlyOwner {
        require( max > 0 && max <= MAX_TOKENS, "50000 is a hard cap");
        phase_max_tokens = max;
    }
      function setPhasePresaleMaxTokens(uint16 max) external onlyOwner {
        require( max > 0 && max <= MAX_TOKENS, "50000 is a hard cap");
        phase_presale_max_tokens = max;
    }
      function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
        notRevealedUri = _notRevealedURI;
    }

    function setBaseURI(string memory newBaseURI) external onlyOwner {
        baseURI = newBaseURI;
    }

    function withdraw() external onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }
      function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }

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

        if (!revealed) {
            return notRevealedUri;
        } else {
            string memory currentBaseURI = _baseURI();
            return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI,Strings.toString(tokenId), baseExtension)) : "";
        }  
        }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_pesetas","type":"address"},{"internalType":"string","name":"_initNotRevealedUri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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":"EXPANSION_TOKENS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PESTAS_MINT_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLICSALE_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_whitelist","type":"address[]"}],"name":"addToWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"amIWhiteListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainsaleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"amount","type":"uint8"}],"name":"mintMain","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"amount","type":"uint8"}],"name":"mintPre","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phase_max_tokens","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phase_presale_max_tokens","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleClose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_revealed","type":"bool"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setMainsaletime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"max","type":"uint16"}],"name":"setPhaseMaxTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"max","type":"uint16"}],"name":"setPhasePresaleMaxTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setPresaleclosetime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setPresaletime","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":"uri","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":[{"internalType":"address","name":"psts","type":"address"}],"name":"updatePsts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040526005608081905264173539b7b760d91b60a09081526200002891600b91906200021a565b506000600d819055600e556361c4b920600f556010805463ffffffff1916630f3000001790556013805460ff191690553480156200006557600080fd5b5060405162003337380380620033378339810160408190526200008891620002c0565b604080518082018252600e81526d4e6f626c65206170652067616d6560901b6020808301918252835180850190945260038452624e414760e81b908401528151919291620000d9916000916200021a565b508051620000ef9060019060208401906200021a565b5050506200010c620001066200014c60201b60201c565b62000150565b600a805460ff60a01b1916905560138054610100600160a81b0319166101006001600160a01b038516021790556200014481620001a2565b505062000413565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a546001600160a01b03163314620002015760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640160405180910390fd5b80516200021690600c9060208401906200021a565b5050565b8280546200022890620003c0565b90600052602060002090601f0160209004810192826200024c576000855562000297565b82601f106200026757805160ff191683800117855562000297565b8280016001018555821562000297579182015b82811115620002975782518255916020019190600101906200027a565b50620002a5929150620002a9565b5090565b5b80821115620002a55760008155600101620002aa565b60008060408385031215620002d457600080fd5b82516001600160a01b0381168114620002ec57600080fd5b602084810151919350906001600160401b03808211156200030c57600080fd5b818601915086601f8301126200032157600080fd5b815181811115620003365762000336620003fd565b604051601f8201601f19908116603f01168101908382118183101715620003615762000361620003fd565b8160405282815289868487010111156200037a57600080fd5b600093505b828410156200039e57848401860151818501870152928501926200037f565b82841115620003b05760008684830101525b8096505050505050509250929050565b600181811c90821680620003d557607f821691505b60208210811415620003f757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b612f1480620004236000396000f3fe6080604052600436106102935760003560e01c806357c539d21161015a5780639694229b116100c1578063c87b56dd1161007a578063c87b56dd14610797578063e06fd356146107b7578063e985e9c5146107d3578063f2c4ce1e1461081c578063f2fde38b1461083c578063f47c84c51461085c57600080fd5b80639694229b146106f6578063a22cb4651461070c578063b3bc9f291461072c578063b88d4fde1461074c578063c66828621461076c578063c6e62e0b1461078157600080fd5b8063715018a611610113578063715018a614610658578063740d73f31461066d5780638da5cb5b1461068d5780638f52dd9d146106ab578063940cd05b146106c157806395d89b41146106e157600080fd5b806357c539d2146105a55780635c975abb146105b857806361b2616d146105d75780636352211e146105f85780636d5ee8e41461061857806370a082311461063857600080fd5b80632a234e57116101fe5780633dce49c8116101b75780633dce49c8146104f55780633eda00381461050b57806342842e0e1461052b5780634f6ccce71461054b578063518302271461056b57806355f804b31461058557600080fd5b80632a234e57146104325780632f745c591461044d57806330a266f21461046d5780633803d7d0146104925780633b9a627f146104b25780633ccfd60b146104e057600080fd5b806315ef586f1161025057806315ef586f1461038a57806316c38b3c146103aa57806317f3e7cc146103ca57806318160ddd146103ea5780631a1769c2146103ff57806323b872dd1461041257600080fd5b806301ffc9a71461029857806302f8e077146102cd57806306fdde03146102f9578063081812fc1461031b578063081c8c4414610353578063095ea7b314610368575b600080fd5b3480156102a457600080fd5b506102b86102b33660046129ca565b610872565b60405190151581526020015b60405180910390f35b3480156102d957600080fd5b506102eb690878678326eac900000081565b6040519081526020016102c4565b34801561030557600080fd5b5061030e61089d565b6040516102c49190612bda565b34801561032757600080fd5b5061033b610336366004612a71565b61092f565b6040516001600160a01b0390911681526020016102c4565b34801561035f57600080fd5b5061030e6109c9565b34801561037457600080fd5b506103886103833660046128d1565b610a57565b005b34801561039657600080fd5b506103886103a5366004612a71565b610b6d565b3480156103b657600080fd5b506103886103c53660046129af565b610b9c565b3480156103d657600080fd5b506103886103e5366004612a71565b610bdf565b3480156103f657600080fd5b506008546102eb565b61038861040d366004612a8a565b610c0e565b34801561041e57600080fd5b5061038861042d3660046127ef565b610f9c565b34801561043e57600080fd5b506102eb66f523226980800081565b34801561045957600080fd5b506102eb6104683660046128d1565b610fcd565b34801561047957600080fd5b503360009081526011602052604090205460ff166102b8565b34801561049e57600080fd5b506103886104ad366004612a4d565b611063565b3480156104be57600080fd5b506010546104cd9061ffff1681565b60405161ffff90911681526020016102c4565b3480156104ec57600080fd5b50610388611101565b34801561050157600080fd5b506102eb600f5481565b34801561051757600080fd5b506103886105263660046127a1565b611164565b34801561053757600080fd5b506103886105463660046127ef565b6111b6565b34801561055757600080fd5b506102eb610566366004612a71565b6111d1565b34801561057757600080fd5b506013546102b89060ff1681565b34801561059157600080fd5b506103886105a0366004612a04565b611264565b6103886105b3366004612a8a565b6112a5565b3480156105c457600080fd5b50600a54600160a01b900460ff166102b8565b3480156105e357600080fd5b506010546104cd9062010000900461ffff1681565b34801561060457600080fd5b5061033b610613366004612a71565b61153f565b34801561062457600080fd5b50610388610633366004612a4d565b6115b6565b34801561064457600080fd5b506102eb6106533660046127a1565b61165c565b34801561066457600080fd5b506103886116e3565b34801561067957600080fd5b506103886106883660046128fb565b611719565b34801561069957600080fd5b50600a546001600160a01b031661033b565b3480156106b757600080fd5b506104cd61271081565b3480156106cd57600080fd5b506103886106dc3660046129af565b6117b3565b3480156106ed57600080fd5b5061030e6117f0565b34801561070257600080fd5b506102eb600e5481565b34801561071857600080fd5b506103886107273660046128a7565b6117ff565b34801561073857600080fd5b50610388610747366004612a71565b61180a565b34801561075857600080fd5b5061038861076736600461282b565b611839565b34801561077857600080fd5b5061030e611871565b34801561078d57600080fd5b506102eb600d5481565b3480156107a357600080fd5b5061030e6107b2366004612a71565b61187e565b3480156107c357600080fd5b506102eb67011c37937e08000081565b3480156107df57600080fd5b506102b86107ee3660046127bc565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561082857600080fd5b50610388610837366004612a04565b6119fd565b34801561084857600080fd5b506103886108573660046127a1565b611a3a565b34801561086857600080fd5b506104cd61c35081565b60006001600160e01b0319821663780e9d6360e01b1480610897575061089782611ad2565b92915050565b6060600080546108ac90612dae565b80601f01602080910402602001604051908101604052809291908181526020018280546108d890612dae565b80156109255780601f106108fa57610100808354040283529160200191610925565b820191906000526020600020905b81548152906001019060200180831161090857829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166109ad5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600c80546109d690612dae565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0290612dae565b8015610a4f5780601f10610a2457610100808354040283529160200191610a4f565b820191906000526020600020905b815481529060010190602001808311610a3257829003601f168201915b505050505081565b6000610a628261153f565b9050806001600160a01b0316836001600160a01b03161415610ad05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016109a4565b336001600160a01b0382161480610aec5750610aec81336107ee565b610b5e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016109a4565b610b688383611b22565b505050565b600a546001600160a01b03163314610b975760405162461bcd60e51b81526004016109a490612c69565b600f55565b600a546001600160a01b03163314610bc65760405162461bcd60e51b81526004016109a490612c69565b8015610bd757610bd4611b90565b50565b610bd4611c12565b600a546001600160a01b03163314610c095760405162461bcd60e51b81526004016109a490612c69565b600e55565b600a54600160a01b900460ff1615610c385760405162461bcd60e51b81526004016109a490612c3f565b600f54421015610c8a5760405162461bcd60e51b815260206004820152601860248201527f73616c6520686173206e6f74207374617274656420796574000000000000000060448201526064016109a4565b6000610c9560085490565b9050323314610cd15760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b60448201526064016109a4565b60105462010000900461ffff16610ceb60ff841683612d20565b1115610d2d5760405162461bcd60e51b81526020600482015260116024820152701b585e081d1bdad95b9cc81b5a5b9d1959607a1b60448201526064016109a4565b60008260ff16118015610d445750600a8260ff1611155b610d865760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b60448201526064016109a4565b612710811015610e5957612710610da060ff841683612d20565b1115610dfa5760405162461bcd60e51b815260206004820152602360248201527f416c6c20657870616e73696f6e20746f6b656e7320616c7265616479206d696e6044820152621d195960ea1b60648201526084016109a4565b34610e1067011c37937e08000060ff8516612d4c565b14610e545760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908195d1a195c88185b5bdd5b9d60621b60448201526064016109a4565b610f5f565b3415610e9b5760405162461bcd60e51b81526020600482015260116024820152701b9bc8195d1a195c881c995c5d5a5c9959607a1b60448201526064016109a4565b6000614e20610ead60ff851684612d20565b10610ecc57610ec7690878678326eac90000006002612d4c565b610ed8565b690878678326eac90000005b60135490915061010090046001600160a01b0316639dc29fac33610eff60ff871685612d4c565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b50505050505b60005b8260ff16811015610b685781610f7781612e0b565b925050610f8a610f843390565b83611c96565b80610f9481612e0b565b915050610f62565b610fa63382611cb0565b610fc25760405162461bcd60e51b81526004016109a490612c9e565b610b68838383611da7565b6000610fd88361165c565b821061103a5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016109a4565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b0316331461108d5760405162461bcd60e51b81526004016109a490612c69565b60008161ffff161180156110a7575061c35061ffff821611155b6110e95760405162461bcd60e51b815260206004820152601360248201527203530303030206973206120686172642063617606c1b60448201526064016109a4565b6010805461ffff191661ffff92909216919091179055565b600a546001600160a01b0316331461112b5760405162461bcd60e51b81526004016109a490612c69565b600a546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610bd4573d6000803e3d6000fd5b600a546001600160a01b0316331461118e5760405162461bcd60e51b81526004016109a490612c69565b601380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b610b6883838360405180602001604052806000815250611839565b60006111dc60085490565b821061123f5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016109a4565b6008828154811061125257611252612e9c565b90600052602060002001549050919050565b600a546001600160a01b0316331461128e5760405162461bcd60e51b81526004016109a490612c69565b80516112a1906012906020840190612689565b5050565b600a54600160a01b900460ff16156112cf5760405162461bcd60e51b81526004016109a490612c3f565b600d5442101580156112e35750600e544211155b6113215760405162461bcd60e51b815260206004820152600f60248201526e50726573616c6520636c6f7365642160881b60448201526064016109a4565b600061132c60085490565b90506113473360009081526011602052604090205460ff1690565b6113935760405162461bcd60e51b815260206004820152601760248201527f596f7520617265206e6f742057686974656c697374656400000000000000000060448201526064016109a4565b60008260ff161180156113aa575060038260ff1611155b6113ec5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b60448201526064016109a4565b60105461ffff1661140060ff841683612d20565b111561144e5760405162461bcd60e51b815260206004820152601960248201527f6d61782070726573616c6520746f6b656e73206d696e7465640000000000000060448201526064016109a4565b61271061145e60ff841683612d20565b11156114ac5760405162461bcd60e51b815260206004820152601b60248201527f6d617820657870616e73696f6e20746f6b656e73206d696e746564000000000060448201526064016109a4565b346114c166f523226980800060ff8516612d4c565b146115055760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908195d1a195c88185b5bdd5b9d60621b60448201526064016109a4565b60005b8260ff168160ff161015610b68578161152081612e0b565b92505061152d610f843390565b8061153781612e26565b915050611508565b6000818152600260205260408120546001600160a01b0316806108975760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016109a4565b600a546001600160a01b031633146115e05760405162461bcd60e51b81526004016109a490612c69565b60008161ffff161180156115fa575061c35061ffff821611155b61163c5760405162461bcd60e51b815260206004820152601360248201527203530303030206973206120686172642063617606c1b60448201526064016109a4565b6010805461ffff909216620100000263ffff000019909216919091179055565b60006001600160a01b0382166116c75760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016109a4565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b0316331461170d5760405162461bcd60e51b81526004016109a490612c69565b6117176000611f52565b565b600a546001600160a01b031633146117435760405162461bcd60e51b81526004016109a490612c69565b60005b81518161ffff1610156112a157600160116000848461ffff168151811061176f5761176f612e9c565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806117ab81612de9565b915050611746565b600a546001600160a01b031633146117dd5760405162461bcd60e51b81526004016109a490612c69565b6013805460ff1916911515919091179055565b6060600180546108ac90612dae565b6112a1338383611fa4565b600a546001600160a01b031633146118345760405162461bcd60e51b81526004016109a490612c69565b600d55565b6118433383611cb0565b61185f5760405162461bcd60e51b81526004016109a490612c9e565b61186b84848484612073565b50505050565b600b80546109d690612dae565b6000818152600260205260409020546060906001600160a01b03166118fd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016109a4565b60135460ff1661199957600c805461191490612dae565b80601f016020809104026020016040519081016040528092919081815260200182805461194090612dae565b801561198d5780601f106119625761010080835404028352916020019161198d565b820191906000526020600020905b81548152906001019060200180831161197057829003601f168201915b50505050509050919050565b60006119a36120a6565b905060008151116119c357604051806020016040528060008152506119f1565b806119cd846120b5565b600b6040516020016119e193929190612ad9565b6040516020818303038152906040525b9392505050565b919050565b600a546001600160a01b03163314611a275760405162461bcd60e51b81526004016109a490612c69565b80516112a190600c906020840190612689565b600a546001600160a01b03163314611a645760405162461bcd60e51b81526004016109a490612c69565b6001600160a01b038116611ac95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109a4565b610bd481611f52565b60006001600160e01b031982166380ac58cd60e01b1480611b0357506001600160e01b03198216635b5e139f60e01b145b8061089757506301ffc9a760e01b6001600160e01b0319831614610897565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611b578261153f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600160a01b900460ff1615611bba5760405162461bcd60e51b81526004016109a490612c3f565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611bf53390565b6040516001600160a01b03909116815260200160405180910390a1565b600a54600160a01b900460ff16611c625760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109a4565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611bf5565b6112a18282604051806020016040528060008152506121b3565b6000818152600260205260408120546001600160a01b0316611d295760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016109a4565b6000611d348361153f565b9050806001600160a01b0316846001600160a01b03161480611d6f5750836001600160a01b0316611d648461092f565b6001600160a01b0316145b80611d9f57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611dba8261153f565b6001600160a01b031614611e225760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016109a4565b6001600160a01b038216611e845760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109a4565b611e8f8383836121e6565b611e9a600082611b22565b6001600160a01b0383166000908152600360205260408120805460019290611ec3908490612d6b565b90915550506001600160a01b0382166000908152600360205260408120805460019290611ef1908490612d20565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031614156120065760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109a4565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61207e848484611da7565b61208a8484848461229e565b61186b5760405162461bcd60e51b81526004016109a490612bed565b6060601280546108ac90612dae565b6060816120d95750506040805180820190915260018152600360fc1b602082015290565b8160005b811561210357806120ed81612e0b565b91506120fc9050600a83612d38565b91506120dd565b60008167ffffffffffffffff81111561211e5761211e612eb2565b6040519080825280601f01601f191660200182016040528015612148576020820181803683370190505b5090505b8415611d9f5761215d600183612d6b565b915061216a600a86612e46565b612175906030612d20565b60f81b81838151811061218a5761218a612e9c565b60200101906001600160f81b031916908160001a9053506121ac600a86612d38565b945061214c565b6121bd83836123ab565b6121ca600084848461229e565b610b685760405162461bcd60e51b81526004016109a490612bed565b6001600160a01b0383166122415761223c81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612264565b816001600160a01b0316836001600160a01b0316146122645761226483826124f9565b6001600160a01b03821661227b57610b6881612596565b826001600160a01b0316826001600160a01b031614610b6857610b688282612645565b60006001600160a01b0384163b156123a057604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906122e2903390899088908890600401612b9d565b602060405180830381600087803b1580156122fc57600080fd5b505af192505050801561232c575060408051601f3d908101601f19168201909252612329918101906129e7565b60015b612386573d80801561235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50805161237e5760405162461bcd60e51b81526004016109a490612bed565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d9f565b506001949350505050565b6001600160a01b0382166124015760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109a4565b6000818152600260205260409020546001600160a01b0316156124665760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109a4565b612472600083836121e6565b6001600160a01b038216600090815260036020526040812080546001929061249b908490612d20565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016125068461165c565b6125109190612d6b565b600083815260076020526040902054909150808214612563576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906125a890600190612d6b565b600083815260096020526040812054600880549394509092849081106125d0576125d0612e9c565b9060005260206000200154905080600883815481106125f1576125f1612e9c565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061262957612629612e86565b6001900381819060005260206000200160009055905550505050565b60006126508361165c565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461269590612dae565b90600052602060002090601f0160209004810192826126b757600085556126fd565b82601f106126d057805160ff19168380011785556126fd565b828001600101855582156126fd579182015b828111156126fd5782518255916020019190600101906126e2565b5061270992915061270d565b5090565b5b80821115612709576000815560010161270e565b600067ffffffffffffffff83111561273c5761273c612eb2565b61274f601f8401601f1916602001612cef565b905082815283838301111561276357600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b03811681146119f857600080fd5b803580151581146119f857600080fd5b6000602082840312156127b357600080fd5b6119f18261277a565b600080604083850312156127cf57600080fd5b6127d88361277a565b91506127e66020840161277a565b90509250929050565b60008060006060848603121561280457600080fd5b61280d8461277a565b925061281b6020850161277a565b9150604084013590509250925092565b6000806000806080858703121561284157600080fd5b61284a8561277a565b93506128586020860161277a565b925060408501359150606085013567ffffffffffffffff81111561287b57600080fd5b8501601f8101871361288c57600080fd5b61289b87823560208401612722565b91505092959194509250565b600080604083850312156128ba57600080fd5b6128c38361277a565b91506127e660208401612791565b600080604083850312156128e457600080fd5b6128ed8361277a565b946020939093013593505050565b6000602080838503121561290e57600080fd5b823567ffffffffffffffff8082111561292657600080fd5b818501915085601f83011261293a57600080fd5b81358181111561294c5761294c612eb2565b8060051b915061295d848301612cef565b8181528481019084860184860187018a101561297857600080fd5b600095505b838610156129a25761298e8161277a565b83526001959095019491860191860161297d565b5098975050505050505050565b6000602082840312156129c157600080fd5b6119f182612791565b6000602082840312156129dc57600080fd5b81356119f181612ec8565b6000602082840312156129f957600080fd5b81516119f181612ec8565b600060208284031215612a1657600080fd5b813567ffffffffffffffff811115612a2d57600080fd5b8201601f81018413612a3e57600080fd5b611d9f84823560208401612722565b600060208284031215612a5f57600080fd5b813561ffff811681146119f157600080fd5b600060208284031215612a8357600080fd5b5035919050565b600060208284031215612a9c57600080fd5b813560ff811681146119f157600080fd5b60008151808452612ac5816020860160208601612d82565b601f01601f19169290920160200192915050565b600084516020612aec8285838a01612d82565b855191840191612aff8184848a01612d82565b8554920191600090600181811c9080831680612b1c57607f831692505b858310811415612b3a57634e487b7160e01b85526022600452602485fd5b808015612b4e5760018114612b5f57612b8c565b60ff19851688528388019550612b8c565b60008b81526020902060005b85811015612b845781548a820152908401908801612b6b565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612bd090830184612aad565b9695505050505050565b6020815260006119f16020830184612aad565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715612d1857612d18612eb2565b604052919050565b60008219821115612d3357612d33612e5a565b500190565b600082612d4757612d47612e70565b500490565b6000816000190483118215151615612d6657612d66612e5a565b500290565b600082821015612d7d57612d7d612e5a565b500390565b60005b83811015612d9d578181015183820152602001612d85565b8381111561186b5750506000910152565b600181811c90821680612dc257607f821691505b60208210811415612de357634e487b7160e01b600052602260045260246000fd5b50919050565b600061ffff80831681811415612e0157612e01612e5a565b6001019392505050565b6000600019821415612e1f57612e1f612e5a565b5060010190565b600060ff821660ff811415612e3d57612e3d612e5a565b60010192915050565b600082612e5557612e55612e70565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610bd457600080fdfea264697066735822122070abf15d369a77d49f88c4060aee96c9d888234c966e3b5b529afe8e3b125b2364736f6c63430008070033000000000000000000000000317988572736ac9ea66340023b112cce2366fbb800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d5153556d5a446869474c4b67736347644e4e4e6d475241517a42734a6f5a724b4841644e42565a345735684d0000000000000000000000

Deployed Bytecode

0x6080604052600436106102935760003560e01c806357c539d21161015a5780639694229b116100c1578063c87b56dd1161007a578063c87b56dd14610797578063e06fd356146107b7578063e985e9c5146107d3578063f2c4ce1e1461081c578063f2fde38b1461083c578063f47c84c51461085c57600080fd5b80639694229b146106f6578063a22cb4651461070c578063b3bc9f291461072c578063b88d4fde1461074c578063c66828621461076c578063c6e62e0b1461078157600080fd5b8063715018a611610113578063715018a614610658578063740d73f31461066d5780638da5cb5b1461068d5780638f52dd9d146106ab578063940cd05b146106c157806395d89b41146106e157600080fd5b806357c539d2146105a55780635c975abb146105b857806361b2616d146105d75780636352211e146105f85780636d5ee8e41461061857806370a082311461063857600080fd5b80632a234e57116101fe5780633dce49c8116101b75780633dce49c8146104f55780633eda00381461050b57806342842e0e1461052b5780634f6ccce71461054b578063518302271461056b57806355f804b31461058557600080fd5b80632a234e57146104325780632f745c591461044d57806330a266f21461046d5780633803d7d0146104925780633b9a627f146104b25780633ccfd60b146104e057600080fd5b806315ef586f1161025057806315ef586f1461038a57806316c38b3c146103aa57806317f3e7cc146103ca57806318160ddd146103ea5780631a1769c2146103ff57806323b872dd1461041257600080fd5b806301ffc9a71461029857806302f8e077146102cd57806306fdde03146102f9578063081812fc1461031b578063081c8c4414610353578063095ea7b314610368575b600080fd5b3480156102a457600080fd5b506102b86102b33660046129ca565b610872565b60405190151581526020015b60405180910390f35b3480156102d957600080fd5b506102eb690878678326eac900000081565b6040519081526020016102c4565b34801561030557600080fd5b5061030e61089d565b6040516102c49190612bda565b34801561032757600080fd5b5061033b610336366004612a71565b61092f565b6040516001600160a01b0390911681526020016102c4565b34801561035f57600080fd5b5061030e6109c9565b34801561037457600080fd5b506103886103833660046128d1565b610a57565b005b34801561039657600080fd5b506103886103a5366004612a71565b610b6d565b3480156103b657600080fd5b506103886103c53660046129af565b610b9c565b3480156103d657600080fd5b506103886103e5366004612a71565b610bdf565b3480156103f657600080fd5b506008546102eb565b61038861040d366004612a8a565b610c0e565b34801561041e57600080fd5b5061038861042d3660046127ef565b610f9c565b34801561043e57600080fd5b506102eb66f523226980800081565b34801561045957600080fd5b506102eb6104683660046128d1565b610fcd565b34801561047957600080fd5b503360009081526011602052604090205460ff166102b8565b34801561049e57600080fd5b506103886104ad366004612a4d565b611063565b3480156104be57600080fd5b506010546104cd9061ffff1681565b60405161ffff90911681526020016102c4565b3480156104ec57600080fd5b50610388611101565b34801561050157600080fd5b506102eb600f5481565b34801561051757600080fd5b506103886105263660046127a1565b611164565b34801561053757600080fd5b506103886105463660046127ef565b6111b6565b34801561055757600080fd5b506102eb610566366004612a71565b6111d1565b34801561057757600080fd5b506013546102b89060ff1681565b34801561059157600080fd5b506103886105a0366004612a04565b611264565b6103886105b3366004612a8a565b6112a5565b3480156105c457600080fd5b50600a54600160a01b900460ff166102b8565b3480156105e357600080fd5b506010546104cd9062010000900461ffff1681565b34801561060457600080fd5b5061033b610613366004612a71565b61153f565b34801561062457600080fd5b50610388610633366004612a4d565b6115b6565b34801561064457600080fd5b506102eb6106533660046127a1565b61165c565b34801561066457600080fd5b506103886116e3565b34801561067957600080fd5b506103886106883660046128fb565b611719565b34801561069957600080fd5b50600a546001600160a01b031661033b565b3480156106b757600080fd5b506104cd61271081565b3480156106cd57600080fd5b506103886106dc3660046129af565b6117b3565b3480156106ed57600080fd5b5061030e6117f0565b34801561070257600080fd5b506102eb600e5481565b34801561071857600080fd5b506103886107273660046128a7565b6117ff565b34801561073857600080fd5b50610388610747366004612a71565b61180a565b34801561075857600080fd5b5061038861076736600461282b565b611839565b34801561077857600080fd5b5061030e611871565b34801561078d57600080fd5b506102eb600d5481565b3480156107a357600080fd5b5061030e6107b2366004612a71565b61187e565b3480156107c357600080fd5b506102eb67011c37937e08000081565b3480156107df57600080fd5b506102b86107ee3660046127bc565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561082857600080fd5b50610388610837366004612a04565b6119fd565b34801561084857600080fd5b506103886108573660046127a1565b611a3a565b34801561086857600080fd5b506104cd61c35081565b60006001600160e01b0319821663780e9d6360e01b1480610897575061089782611ad2565b92915050565b6060600080546108ac90612dae565b80601f01602080910402602001604051908101604052809291908181526020018280546108d890612dae565b80156109255780601f106108fa57610100808354040283529160200191610925565b820191906000526020600020905b81548152906001019060200180831161090857829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166109ad5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600c80546109d690612dae565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0290612dae565b8015610a4f5780601f10610a2457610100808354040283529160200191610a4f565b820191906000526020600020905b815481529060010190602001808311610a3257829003601f168201915b505050505081565b6000610a628261153f565b9050806001600160a01b0316836001600160a01b03161415610ad05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016109a4565b336001600160a01b0382161480610aec5750610aec81336107ee565b610b5e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016109a4565b610b688383611b22565b505050565b600a546001600160a01b03163314610b975760405162461bcd60e51b81526004016109a490612c69565b600f55565b600a546001600160a01b03163314610bc65760405162461bcd60e51b81526004016109a490612c69565b8015610bd757610bd4611b90565b50565b610bd4611c12565b600a546001600160a01b03163314610c095760405162461bcd60e51b81526004016109a490612c69565b600e55565b600a54600160a01b900460ff1615610c385760405162461bcd60e51b81526004016109a490612c3f565b600f54421015610c8a5760405162461bcd60e51b815260206004820152601860248201527f73616c6520686173206e6f74207374617274656420796574000000000000000060448201526064016109a4565b6000610c9560085490565b9050323314610cd15760405162461bcd60e51b81526020600482015260086024820152674f6e6c7920454f4160c01b60448201526064016109a4565b60105462010000900461ffff16610ceb60ff841683612d20565b1115610d2d5760405162461bcd60e51b81526020600482015260116024820152701b585e081d1bdad95b9cc81b5a5b9d1959607a1b60448201526064016109a4565b60008260ff16118015610d445750600a8260ff1611155b610d865760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b60448201526064016109a4565b612710811015610e5957612710610da060ff841683612d20565b1115610dfa5760405162461bcd60e51b815260206004820152602360248201527f416c6c20657870616e73696f6e20746f6b656e7320616c7265616479206d696e6044820152621d195960ea1b60648201526084016109a4565b34610e1067011c37937e08000060ff8516612d4c565b14610e545760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908195d1a195c88185b5bdd5b9d60621b60448201526064016109a4565b610f5f565b3415610e9b5760405162461bcd60e51b81526020600482015260116024820152701b9bc8195d1a195c881c995c5d5a5c9959607a1b60448201526064016109a4565b6000614e20610ead60ff851684612d20565b10610ecc57610ec7690878678326eac90000006002612d4c565b610ed8565b690878678326eac90000005b60135490915061010090046001600160a01b0316639dc29fac33610eff60ff871685612d4c565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015610f4557600080fd5b505af1158015610f59573d6000803e3d6000fd5b50505050505b60005b8260ff16811015610b685781610f7781612e0b565b925050610f8a610f843390565b83611c96565b80610f9481612e0b565b915050610f62565b610fa63382611cb0565b610fc25760405162461bcd60e51b81526004016109a490612c9e565b610b68838383611da7565b6000610fd88361165c565b821061103a5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016109a4565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b0316331461108d5760405162461bcd60e51b81526004016109a490612c69565b60008161ffff161180156110a7575061c35061ffff821611155b6110e95760405162461bcd60e51b815260206004820152601360248201527203530303030206973206120686172642063617606c1b60448201526064016109a4565b6010805461ffff191661ffff92909216919091179055565b600a546001600160a01b0316331461112b5760405162461bcd60e51b81526004016109a490612c69565b600a546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610bd4573d6000803e3d6000fd5b600a546001600160a01b0316331461118e5760405162461bcd60e51b81526004016109a490612c69565b601380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b610b6883838360405180602001604052806000815250611839565b60006111dc60085490565b821061123f5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016109a4565b6008828154811061125257611252612e9c565b90600052602060002001549050919050565b600a546001600160a01b0316331461128e5760405162461bcd60e51b81526004016109a490612c69565b80516112a1906012906020840190612689565b5050565b600a54600160a01b900460ff16156112cf5760405162461bcd60e51b81526004016109a490612c3f565b600d5442101580156112e35750600e544211155b6113215760405162461bcd60e51b815260206004820152600f60248201526e50726573616c6520636c6f7365642160881b60448201526064016109a4565b600061132c60085490565b90506113473360009081526011602052604090205460ff1690565b6113935760405162461bcd60e51b815260206004820152601760248201527f596f7520617265206e6f742057686974656c697374656400000000000000000060448201526064016109a4565b60008260ff161180156113aa575060038260ff1611155b6113ec5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b60448201526064016109a4565b60105461ffff1661140060ff841683612d20565b111561144e5760405162461bcd60e51b815260206004820152601960248201527f6d61782070726573616c6520746f6b656e73206d696e7465640000000000000060448201526064016109a4565b61271061145e60ff841683612d20565b11156114ac5760405162461bcd60e51b815260206004820152601b60248201527f6d617820657870616e73696f6e20746f6b656e73206d696e746564000000000060448201526064016109a4565b346114c166f523226980800060ff8516612d4c565b146115055760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908195d1a195c88185b5bdd5b9d60621b60448201526064016109a4565b60005b8260ff168160ff161015610b68578161152081612e0b565b92505061152d610f843390565b8061153781612e26565b915050611508565b6000818152600260205260408120546001600160a01b0316806108975760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016109a4565b600a546001600160a01b031633146115e05760405162461bcd60e51b81526004016109a490612c69565b60008161ffff161180156115fa575061c35061ffff821611155b61163c5760405162461bcd60e51b815260206004820152601360248201527203530303030206973206120686172642063617606c1b60448201526064016109a4565b6010805461ffff909216620100000263ffff000019909216919091179055565b60006001600160a01b0382166116c75760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016109a4565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b0316331461170d5760405162461bcd60e51b81526004016109a490612c69565b6117176000611f52565b565b600a546001600160a01b031633146117435760405162461bcd60e51b81526004016109a490612c69565b60005b81518161ffff1610156112a157600160116000848461ffff168151811061176f5761176f612e9c565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806117ab81612de9565b915050611746565b600a546001600160a01b031633146117dd5760405162461bcd60e51b81526004016109a490612c69565b6013805460ff1916911515919091179055565b6060600180546108ac90612dae565b6112a1338383611fa4565b600a546001600160a01b031633146118345760405162461bcd60e51b81526004016109a490612c69565b600d55565b6118433383611cb0565b61185f5760405162461bcd60e51b81526004016109a490612c9e565b61186b84848484612073565b50505050565b600b80546109d690612dae565b6000818152600260205260409020546060906001600160a01b03166118fd5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016109a4565b60135460ff1661199957600c805461191490612dae565b80601f016020809104026020016040519081016040528092919081815260200182805461194090612dae565b801561198d5780601f106119625761010080835404028352916020019161198d565b820191906000526020600020905b81548152906001019060200180831161197057829003601f168201915b50505050509050919050565b60006119a36120a6565b905060008151116119c357604051806020016040528060008152506119f1565b806119cd846120b5565b600b6040516020016119e193929190612ad9565b6040516020818303038152906040525b9392505050565b919050565b600a546001600160a01b03163314611a275760405162461bcd60e51b81526004016109a490612c69565b80516112a190600c906020840190612689565b600a546001600160a01b03163314611a645760405162461bcd60e51b81526004016109a490612c69565b6001600160a01b038116611ac95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109a4565b610bd481611f52565b60006001600160e01b031982166380ac58cd60e01b1480611b0357506001600160e01b03198216635b5e139f60e01b145b8061089757506301ffc9a760e01b6001600160e01b0319831614610897565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611b578261153f565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600160a01b900460ff1615611bba5760405162461bcd60e51b81526004016109a490612c3f565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611bf53390565b6040516001600160a01b03909116815260200160405180910390a1565b600a54600160a01b900460ff16611c625760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109a4565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33611bf5565b6112a18282604051806020016040528060008152506121b3565b6000818152600260205260408120546001600160a01b0316611d295760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016109a4565b6000611d348361153f565b9050806001600160a01b0316846001600160a01b03161480611d6f5750836001600160a01b0316611d648461092f565b6001600160a01b0316145b80611d9f57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611dba8261153f565b6001600160a01b031614611e225760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016109a4565b6001600160a01b038216611e845760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109a4565b611e8f8383836121e6565b611e9a600082611b22565b6001600160a01b0383166000908152600360205260408120805460019290611ec3908490612d6b565b90915550506001600160a01b0382166000908152600360205260408120805460019290611ef1908490612d20565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031614156120065760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109a4565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61207e848484611da7565b61208a8484848461229e565b61186b5760405162461bcd60e51b81526004016109a490612bed565b6060601280546108ac90612dae565b6060816120d95750506040805180820190915260018152600360fc1b602082015290565b8160005b811561210357806120ed81612e0b565b91506120fc9050600a83612d38565b91506120dd565b60008167ffffffffffffffff81111561211e5761211e612eb2565b6040519080825280601f01601f191660200182016040528015612148576020820181803683370190505b5090505b8415611d9f5761215d600183612d6b565b915061216a600a86612e46565b612175906030612d20565b60f81b81838151811061218a5761218a612e9c565b60200101906001600160f81b031916908160001a9053506121ac600a86612d38565b945061214c565b6121bd83836123ab565b6121ca600084848461229e565b610b685760405162461bcd60e51b81526004016109a490612bed565b6001600160a01b0383166122415761223c81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612264565b816001600160a01b0316836001600160a01b0316146122645761226483826124f9565b6001600160a01b03821661227b57610b6881612596565b826001600160a01b0316826001600160a01b031614610b6857610b688282612645565b60006001600160a01b0384163b156123a057604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906122e2903390899088908890600401612b9d565b602060405180830381600087803b1580156122fc57600080fd5b505af192505050801561232c575060408051601f3d908101601f19168201909252612329918101906129e7565b60015b612386573d80801561235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50805161237e5760405162461bcd60e51b81526004016109a490612bed565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d9f565b506001949350505050565b6001600160a01b0382166124015760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109a4565b6000818152600260205260409020546001600160a01b0316156124665760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109a4565b612472600083836121e6565b6001600160a01b038216600090815260036020526040812080546001929061249b908490612d20565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060016125068461165c565b6125109190612d6b565b600083815260076020526040902054909150808214612563576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b6008546000906125a890600190612d6b565b600083815260096020526040812054600880549394509092849081106125d0576125d0612e9c565b9060005260206000200154905080600883815481106125f1576125f1612e9c565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061262957612629612e86565b6001900381819060005260206000200160009055905550505050565b60006126508361165c565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461269590612dae565b90600052602060002090601f0160209004810192826126b757600085556126fd565b82601f106126d057805160ff19168380011785556126fd565b828001600101855582156126fd579182015b828111156126fd5782518255916020019190600101906126e2565b5061270992915061270d565b5090565b5b80821115612709576000815560010161270e565b600067ffffffffffffffff83111561273c5761273c612eb2565b61274f601f8401601f1916602001612cef565b905082815283838301111561276357600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b03811681146119f857600080fd5b803580151581146119f857600080fd5b6000602082840312156127b357600080fd5b6119f18261277a565b600080604083850312156127cf57600080fd5b6127d88361277a565b91506127e66020840161277a565b90509250929050565b60008060006060848603121561280457600080fd5b61280d8461277a565b925061281b6020850161277a565b9150604084013590509250925092565b6000806000806080858703121561284157600080fd5b61284a8561277a565b93506128586020860161277a565b925060408501359150606085013567ffffffffffffffff81111561287b57600080fd5b8501601f8101871361288c57600080fd5b61289b87823560208401612722565b91505092959194509250565b600080604083850312156128ba57600080fd5b6128c38361277a565b91506127e660208401612791565b600080604083850312156128e457600080fd5b6128ed8361277a565b946020939093013593505050565b6000602080838503121561290e57600080fd5b823567ffffffffffffffff8082111561292657600080fd5b818501915085601f83011261293a57600080fd5b81358181111561294c5761294c612eb2565b8060051b915061295d848301612cef565b8181528481019084860184860187018a101561297857600080fd5b600095505b838610156129a25761298e8161277a565b83526001959095019491860191860161297d565b5098975050505050505050565b6000602082840312156129c157600080fd5b6119f182612791565b6000602082840312156129dc57600080fd5b81356119f181612ec8565b6000602082840312156129f957600080fd5b81516119f181612ec8565b600060208284031215612a1657600080fd5b813567ffffffffffffffff811115612a2d57600080fd5b8201601f81018413612a3e57600080fd5b611d9f84823560208401612722565b600060208284031215612a5f57600080fd5b813561ffff811681146119f157600080fd5b600060208284031215612a8357600080fd5b5035919050565b600060208284031215612a9c57600080fd5b813560ff811681146119f157600080fd5b60008151808452612ac5816020860160208601612d82565b601f01601f19169290920160200192915050565b600084516020612aec8285838a01612d82565b855191840191612aff8184848a01612d82565b8554920191600090600181811c9080831680612b1c57607f831692505b858310811415612b3a57634e487b7160e01b85526022600452602485fd5b808015612b4e5760018114612b5f57612b8c565b60ff19851688528388019550612b8c565b60008b81526020902060005b85811015612b845781548a820152908401908801612b6b565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612bd090830184612aad565b9695505050505050565b6020815260006119f16020830184612aad565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715612d1857612d18612eb2565b604052919050565b60008219821115612d3357612d33612e5a565b500190565b600082612d4757612d47612e70565b500490565b6000816000190483118215151615612d6657612d66612e5a565b500290565b600082821015612d7d57612d7d612e5a565b500390565b60005b83811015612d9d578181015183820152602001612d85565b8381111561186b5750506000910152565b600181811c90821680612dc257607f821691505b60208210811415612de357634e487b7160e01b600052602260045260246000fd5b50919050565b600061ffff80831681811415612e0157612e01612e5a565b6001019392505050565b6000600019821415612e1f57612e1f612e5a565b5060010190565b600060ff821660ff811415612e3d57612e3d612e5a565b60010192915050565b600082612e5557612e55612e70565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610bd457600080fdfea264697066735822122070abf15d369a77d49f88c4060aee96c9d888234c966e3b5b529afe8e3b125b2364736f6c63430008070033

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

000000000000000000000000317988572736ac9ea66340023b112cce2366fbb800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d5153556d5a446869474c4b67736347644e4e4e6d475241517a42734a6f5a724b4841644e42565a345735684d0000000000000000000000

-----Decoded View---------------
Arg [0] : _pesetas (address): 0x317988572736ac9Ea66340023b112CCE2366FBB8
Arg [1] : _initNotRevealedUri (string): ipfs://QmQSUmZDhiGLKgscGdNNNmGRAQzBsJoZrKHAdNBVZ4W5hM

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000317988572736ac9ea66340023b112cce2366fbb8
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000035
Arg [3] : 697066733a2f2f516d5153556d5a446869474c4b67736347644e4e4e6d475241
Arg [4] : 517a42734a6f5a724b4841644e42565a345735684d0000000000000000000000


Deployed Bytecode Sourcemap

63275:5318:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53777:224;;;;;;;;;;-1:-1:-1;53777:224:0;;;;;:::i;:::-;;:::i;:::-;;;8533:14:1;;8526:22;8508:41;;8496:2;8481:18;53777:224:0;;;;;;;;63648:54;;;;;;;;;;;;63691:11;63648:54;;;;;21260:25:1;;;21248:2;21233:18;63648:54:0;21114:177:1;41271:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;42830:221::-;;;;;;;;;;-1:-1:-1;42830:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7552:32:1;;;7534:51;;7522:2;7507:18;42830:221:0;7388:203:1;63485:28:0;;;;;;;;;;;;;:::i;42353:411::-;;;;;;;;;;-1:-1:-1;42353:411:0;;;;;:::i;:::-;;:::i;:::-;;66802:96;;;;;;;;;;-1:-1:-1;66802:96:0;;;;;:::i;:::-;;:::i;66273:118::-;;;;;;;;;;-1:-1:-1;66273:118:0;;;;;:::i;:::-;;:::i;67012:100::-;;;;;;;;;;-1:-1:-1;67012:100:0;;;;;:::i;:::-;;:::i;54417:113::-;;;;;;;;;;-1:-1:-1;54505:10:0;:17;54417:113;;65239:1026;;;;;;:::i;:::-;;:::i;43580:339::-;;;;;;;;;;-1:-1:-1;43580:339:0;;;;;:::i;:::-;;:::i;63522:55::-;;;;;;;;;;;;63567:10;63522:55;;54085:256;;;;;;;;;;-1:-1:-1;54085:256:0;;;;;:::i;:::-;;:::i;66399:100::-;;;;;;;;;;-1:-1:-1;66480:10:0;66446:4;66470:21;;;:9;:21;;;;;;;;66399:100;;67402:186;;;;;;;;;;-1:-1:-1;67402:186:0;;;;;:::i;:::-;;:::i;63847:43::-;;;;;;;;;;-1:-1:-1;63847:43:0;;;;;;;;;;;21095:6:1;21083:19;;;21065:38;;21053:2;21038:18;63847:43:0;20921:188:1;67842:106:0;;;;;;;;;;;;;:::i;63786:40::-;;;;;;;;;;;;;;;;67120:95;;;;;;;;;;-1:-1:-1;67120:95:0;;;;;:::i;:::-;;:::i;43990:185::-;;;;;;;;;;-1:-1:-1;43990:185:0;;;;;:::i;:::-;;:::i;54607:233::-;;;;;;;;;;-1:-1:-1;54607:233:0;;;;;:::i;:::-;;:::i;64018:28::-;;;;;;;;;;-1:-1:-1;64018:28:0;;;;;;;;67730:104;;;;;;;;;;-1:-1:-1;67730:104:0;;;;;:::i;:::-;;:::i;64585:646::-;;;;;;:::i;:::-;;:::i;37748:86::-;;;;;;;;;;-1:-1:-1;37819:7:0;;-1:-1:-1;;;37819:7:0;;;;37748:86;;63899:38;;;;;;;;;;-1:-1:-1;63899:38:0;;;;;;;;;;;40965:239;;;;;;;;;;-1:-1:-1;40965:239:0;;;;;:::i;:::-;;:::i;67223:171::-;;;;;;;;;;-1:-1:-1;67223:171:0;;;;;:::i;:::-;;:::i;40695:208::-;;;;;;;;;;-1:-1:-1;40695:208:0;;;;;:::i;:::-;;:::i;61638:103::-;;;;;;;;;;;;;:::i;66507:189::-;;;;;;;;;;-1:-1:-1;66507:189:0;;;;;:::i;:::-;;:::i;60987:87::-;;;;;;;;;;-1:-1:-1;61060:6:0;;-1:-1:-1;;;;;61060:6:0;60987:87;;63387:47;;;;;;;;;;;;63429:5;63387:47;;66704:90;;;;;;;;;;-1:-1:-1;66704:90:0;;;;;:::i;:::-;;:::i;41440:104::-;;;;;;;;;;;;;:::i;63748:31::-;;;;;;;;;;;;;;;;43123:155;;;;;;;;;;-1:-1:-1;43123:155:0;;;;;:::i;:::-;;:::i;66910:94::-;;;;;;;;;;-1:-1:-1;66910:94:0;;;;;:::i;:::-;;:::i;44246:328::-;;;;;;;;;;-1:-1:-1;44246:328:0;;;;;:::i;:::-;;:::i;63441:37::-;;;;;;;;;;;;;:::i;63711:30::-;;;;;;;;;;;;;;;;68072:518;;;;;;;;;;-1:-1:-1;68072:518:0;;;;;:::i;:::-;;:::i;63584:57::-;;;;;;;;;;;;63632:9;63584:57;;43349:164;;;;;;;;;;-1:-1:-1;43349:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;43470:25:0;;;43446:4;43470:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;43349:164;67596:126;;;;;;;;;;-1:-1:-1;67596:126:0;;;;;:::i;:::-;;:::i;61896:201::-;;;;;;;;;;-1:-1:-1;61896:201:0;;;;;:::i;:::-;;:::i;63339:41::-;;;;;;;;;;;;63375:5;63339:41;;53777:224;53879:4;-1:-1:-1;;;;;;53903:50:0;;-1:-1:-1;;;53903:50:0;;:90;;;53957:36;53981:11;53957:23;:36::i;:::-;53896:97;53777:224;-1:-1:-1;;53777:224:0:o;41271:100::-;41325:13;41358:5;41351:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41271:100;:::o;42830:221::-;42906:7;46173:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46173:16:0;42926:73;;;;-1:-1:-1;;;42926:73:0;;17247:2:1;42926:73:0;;;17229:21:1;17286:2;17266:18;;;17259:30;17325:34;17305:18;;;17298:62;-1:-1:-1;;;17376:18:1;;;17369:42;17428:19;;42926:73:0;;;;;;;;;-1:-1:-1;43019:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;43019:24:0;;42830:221::o;63485:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;42353:411::-;42434:13;42450:23;42465:7;42450:14;:23::i;:::-;42434:39;;42498:5;-1:-1:-1;;;;;42492:11:0;:2;-1:-1:-1;;;;;42492:11:0;;;42484:57;;;;-1:-1:-1;;;42484:57:0;;19542:2:1;42484:57:0;;;19524:21:1;19581:2;19561:18;;;19554:30;19620:34;19600:18;;;19593:62;-1:-1:-1;;;19671:18:1;;;19664:31;19712:19;;42484:57:0;19340:397:1;42484:57:0;24390:10;-1:-1:-1;;;;;42576:21:0;;;;:62;;-1:-1:-1;42601:37:0;42618:5;24390:10;43349:164;:::i;42601:37::-;42554:168;;;;-1:-1:-1;;;42554:168:0;;15286:2:1;42554:168:0;;;15268:21:1;15325:2;15305:18;;;15298:30;15364:34;15344:18;;;15337:62;15435:26;15415:18;;;15408:54;15479:19;;42554:168:0;15084:420:1;42554:168:0;42735:21;42744:2;42748:7;42735:8;:21::i;:::-;42423:341;42353:411;;:::o;66802:96::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;66871:12:::1;:19:::0;66802:96::o;66273:118::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;66340:7:::1;66336:47;;;66349:8;:6;:8::i;:::-;66273:118:::0;:::o;66336:47::-:1;66373:10;:8;:10::i;67012:100::-:0;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;67085:12:::1;:19:::0;67012:100::o;65239:1026::-;37819:7;;-1:-1:-1;;;37819:7:0;;;;38073:9;38065:38;;;;-1:-1:-1;;;38065:38:0;;;;;;;:::i;:::-;64355:12:::1;;64336:15;:31;;64328:68;;;::::0;-1:-1:-1;;;64328:68:0;;13067:2:1;64328:68:0::1;::::0;::::1;13049:21:1::0;13106:2;13086:18;;;13079:30;13145:26;13125:18;;;13118:54;13189:18;;64328:68:0::1;12865:348:1::0;64328:68:0::1;65328:14:::2;65345:13;54505:10:::0;:17;;54417:113;65345:13:::2;65328:30:::0;-1:-1:-1;65377:9:0::2;24390:10:::0;65377:25:::2;65369:46;;;::::0;-1:-1:-1;;;65369:46:0;;11276:2:1;65369:46:0::2;::::0;::::2;11258:21:1::0;11315:1;11295:18;;;11288:29;-1:-1:-1;;;11333:18:1;;;11326:38;11381:18;;65369:46:0::2;11074:331:1::0;65369:46:0::2;65453:16;::::0;;;::::2;;;65434:15;;::::0;::::2;:6:::0;:15:::2;:::i;:::-;:35;;65426:65;;;::::0;-1:-1:-1;;;65426:65:0;;8986:2:1;65426:65:0::2;::::0;::::2;8968:21:1::0;9025:2;9005:18;;;8998:30;-1:-1:-1;;;9044:18:1;;;9037:47;9101:18;;65426:65:0::2;8784:341:1::0;65426:65:0::2;65519:1;65510:6;:10;;;:26;;;;;65534:2;65524:6;:12;;;;65510:26;65502:58;;;::::0;-1:-1:-1;;;65502:58:0;;20362:2:1;65502:58:0::2;::::0;::::2;20344:21:1::0;20401:2;20381:18;;;20374:30;-1:-1:-1;;;20420:18:1;;;20413:49;20479:18;;65502:58:0::2;20160:343:1::0;65502:58:0::2;63429:5;65575:25:::0;::::2;65571:559;;;63429:5;65643:15;;::::0;::::2;:6:::0;:15:::2;:::i;:::-;:35;;65617:132;;;::::0;-1:-1:-1;;;65617:132:0;;13833:2:1;65617:132:0::2;::::0;::::2;13815:21:1::0;13872:2;13852:18;;;13845:30;13911:34;13891:18;;;13884:62;-1:-1:-1;;;13962:18:1;;;13955:33;14005:19;;65617:132:0::2;13631:399:1::0;65617:132:0::2;65824:9;65790:30;63632:9;65790:30;::::0;::::2;;:::i;:::-;:43;65764:125;;;::::0;-1:-1:-1;;;65764:125:0;;19193:2:1;65764:125:0::2;::::0;::::2;19175:21:1::0;19232:2;19212:18;;;19205:30;-1:-1:-1;;;19251:18:1;;;19244:50;19311:18;;65764:125:0::2;18991:344:1::0;65764:125:0::2;65571:559;;;65930:9;:14:::0;65922:44:::2;;;::::0;-1:-1:-1;;;65922:44:0;;18021:2:1;65922:44:0::2;::::0;::::2;18003:21:1::0;18060:2;18040:18;;;18033:30;-1:-1:-1;;;18079:18:1;;;18072:47;18136:18;;65922:44:0::2;17819:341:1::0;65922:44:0::2;65981:12;66015:5;65997:15;;::::0;::::2;:6:::0;:15:::2;:::i;:::-;:23;:65;;66042:20;63691:11;66061:1;66042:20;:::i;:::-;65997:65;;;63691:11;65997:65;66077:7;::::0;65981:81;;-1:-1:-1;66077:7:0::2;::::0;::::2;-1:-1:-1::0;;;;;66077:7:0::2;:12;24390:10:::0;66104:13:::2;;::::0;::::2;:4:::0;:13:::2;:::i;:::-;66077:41;::::0;-1:-1:-1;;;;;;66077:41:0::2;::::0;;;;;;-1:-1:-1;;;;;8281:32:1;;;66077:41:0::2;::::0;::::2;8263:51:1::0;8330:18;;;8323:34;8236:18;;66077:41:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;65907:223;65571:559;66145:9;66140:118;66164:6;66160:10;;:1;:10;66140:118;;;66192:8:::0;::::2;::::0;::::2;:::i;:::-;;;;66215:31;66225:12;24390:10:::0;;24310:98;66225:12:::2;66239:6;66215:9;:31::i;:::-;66172:3:::0;::::2;::::0;::::2;:::i;:::-;;;;66140:118;;43580:339:::0;43775:41;24390:10;43808:7;43775:18;:41::i;:::-;43767:103;;;;-1:-1:-1;;;43767:103:0;;;;;;;:::i;:::-;43883:28;43893:4;43899:2;43903:7;43883:9;:28::i;54085:256::-;54182:7;54218:23;54235:5;54218:16;:23::i;:::-;54210:5;:31;54202:87;;;;-1:-1:-1;;;54202:87:0;;9681:2:1;54202:87:0;;;9663:21:1;9720:2;9700:18;;;9693:30;9759:34;9739:18;;;9732:62;-1:-1:-1;;;9810:18:1;;;9803:41;9861:19;;54202:87:0;9479:407:1;54202:87:0;-1:-1:-1;;;;;;54307:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;54085:256::o;67402:186::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;67493:1:::1;67487:3;:7;;;:28;;;;-1:-1:-1::0;63375:5:0::1;67498:17;::::0;::::1;;;67487:28;67478:61;;;::::0;-1:-1:-1;;;67478:61:0;;14938:2:1;67478:61:0::1;::::0;::::1;14920:21:1::0;14977:2;14957:18;;;14950:30;-1:-1:-1;;;14996:18:1;;;14989:49;15055:18;;67478:61:0::1;14736:343:1::0;67478:61:0::1;67550:24;:30:::0;;-1:-1:-1;;67550:30:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;67402:186::o;67842:106::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;61060:6;;67892:48:::1;::::0;-1:-1:-1;;;;;61060:6:0;;;;67918:21:::1;67892:48:::0;::::1;;;::::0;::::1;::::0;;;67918:21;61060:6;67892:48;::::1;;;;;;;;;;;;;::::0;::::1;;;;67120:95:::0;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;67184:7:::1;:23:::0;;-1:-1:-1;;;;;67184:23:0;;::::1;;;-1:-1:-1::0;;;;;;67184:23:0;;::::1;::::0;;;::::1;::::0;;67120:95::o;43990:185::-;44128:39;44145:4;44151:2;44155:7;44128:39;;;;;;;;;;;;:16;:39::i;54607:233::-;54682:7;54718:30;54505:10;:17;;54417:113;54718:30;54710:5;:38;54702:95;;;;-1:-1:-1;;;54702:95:0;;20710:2:1;54702:95:0;;;20692:21:1;20749:2;20729:18;;;20722:30;20788:34;20768:18;;;20761:62;-1:-1:-1;;;20839:18:1;;;20832:42;20891:19;;54702:95:0;20508:408:1;54702:95:0;54815:10;54826:5;54815:17;;;;;;;;:::i;:::-;;;;;;;;;54808:24;;54607:233;;;:::o;67730:104::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;67806:20;;::::1;::::0;:7:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;:::-;;67730:104:::0;:::o;64585:646::-;37819:7;;-1:-1:-1;;;37819:7:0;;;;38073:9;38065:38;;;;-1:-1:-1;;;38065:38:0;;;;;;;:::i;:::-;64490:11:::1;;64471:15;:30;;:65;;;;;64524:12;;64505:15;:31;;64471:65;64463:93;;;::::0;-1:-1:-1;;;64463:93:0;;12723:2:1;64463:93:0::1;::::0;::::1;12705:21:1::0;12762:2;12742:18;;;12735:30;-1:-1:-1;;;12781:18:1;;;12774:45;12836:18;;64463:93:0::1;12521:339:1::0;64463:93:0::1;64672:14:::2;64689:13;54505:10:::0;:17;;54417:113;64689:13:::2;64672:30;;64721:16;66480:10:::0;66446:4;66470:21;;;:9;:21;;;;;;;;;66399:100;64721:16:::2;64713:52;;;::::0;-1:-1:-1;;;64713:52:0;;11612:2:1;64713:52:0::2;::::0;::::2;11594:21:1::0;11651:2;11631:18;;;11624:30;11690:25;11670:18;;;11663:53;11733:18;;64713:52:0::2;11410:347:1::0;64713:52:0::2;64793:1;64784:6;:10;;;:25;;;;;64808:1;64798:6;:11;;;;64784:25;64776:57;;;::::0;-1:-1:-1;;;64776:57:0;;20362:2:1;64776:57:0::2;::::0;::::2;20344:21:1::0;20401:2;20381:18;;;20374:30;-1:-1:-1;;;20420:18:1;;;20413:49;20479:18;;64776:57:0::2;20160:343:1::0;64776:57:0::2;64871:24;::::0;::::2;;64852:15;;::::0;::::2;:6:::0;:15:::2;:::i;:::-;:43;;64844:81;;;::::0;-1:-1:-1;;;64844:81:0;;15711:2:1;64844:81:0::2;::::0;::::2;15693:21:1::0;15750:2;15730:18;;;15723:30;15789:27;15769:18;;;15762:55;15834:18;;64844:81:0::2;15509:349:1::0;64844:81:0::2;63429:5;64944:15;;::::0;::::2;:6:::0;:15:::2;:::i;:::-;:35;;64936:75;;;::::0;-1:-1:-1;;;64936:75:0;;14582:2:1;64936:75:0::2;::::0;::::2;14564:21:1::0;14621:2;14601:18;;;14594:30;14660:29;14640:18;;;14633:57;14707:18;;64936:75:0::2;14380:351:1::0;64936:75:0::2;65061:9;65030:27;63567:10;65030:27;::::0;::::2;;:::i;:::-;:40;65022:73;;;::::0;-1:-1:-1;;;65022:73:0;;19193:2:1;65022:73:0::2;::::0;::::2;19175:21:1::0;19232:2;19212:18;;;19205:30;-1:-1:-1;;;19251:18:1;;;19244:50;19311:18;;65022:73:0::2;18991:344:1::0;65022:73:0::2;65113:7;65108:116;65130:6;65126:10;;:1;:10;;;65108:116;;;65158:8:::0;::::2;::::0;::::2;:::i;:::-;;;;65181:31;65191:12;24390:10:::0;;24310:98;65181:31:::2;65138:3:::0;::::2;::::0;::::2;:::i;:::-;;;;65108:116;;40965:239:::0;41037:7;41073:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41073:16:0;41108:19;41100:73;;;;-1:-1:-1;;;41100:73:0;;16476:2:1;41100:73:0;;;16458:21:1;16515:2;16495:18;;;16488:30;16554:34;16534:18;;;16527:62;-1:-1:-1;;;16605:18:1;;;16598:39;16654:19;;41100:73:0;16274:405:1;67223:171:0;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;67307:1:::1;67301:3;:7;;;:28;;;;-1:-1:-1::0;63375:5:0::1;67312:17;::::0;::::1;;;67301:28;67292:61;;;::::0;-1:-1:-1;;;67292:61:0;;14938:2:1;67292:61:0::1;::::0;::::1;14920:21:1::0;14977:2;14957:18;;;14950:30;-1:-1:-1;;;14996:18:1;;;14989:49;15055:18;;67292:61:0::1;14736:343:1::0;67292:61:0::1;67364:16;:22:::0;;::::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;67364:22:0;;::::1;::::0;;;::::1;::::0;;67223:171::o;40695:208::-;40767:7;-1:-1:-1;;;;;40795:19:0;;40787:74;;;;-1:-1:-1;;;40787:74:0;;16065:2:1;40787:74:0;;;16047:21:1;16104:2;16084:18;;;16077:30;16143:34;16123:18;;;16116:62;-1:-1:-1;;;16194:18:1;;;16187:40;16244:19;;40787:74:0;15863:406:1;40787:74:0;-1:-1:-1;;;;;;40879:16:0;;;;;:9;:16;;;;;;;40695:208::o;61638:103::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;61703:30:::1;61730:1;61703:18;:30::i;:::-;61638:103::o:0;66507:189::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;66593:8:::1;66588:101;66607:10;:17;66603:1;:21;;;66588:101;;;66673:4;66646:9;:24;66656:10;66667:1;66656:13;;;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;66646:24:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;66646:24:0;:31;;-1:-1:-1;;66646:31:0::1;::::0;::::1;;::::0;;;::::1;::::0;;66626:3;::::1;::::0;::::1;:::i;:::-;;;;66588:101;;66704:90:::0;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;66766:8:::1;:20:::0;;-1:-1:-1;;66766:20:0::1;::::0;::::1;;::::0;;;::::1;::::0;;66704:90::o;41440:104::-;41496:13;41529:7;41522:14;;;;;:::i;43123:155::-;43218:52;24390:10;43251:8;43261;43218:18;:52::i;66910:94::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;66978:11:::1;:18:::0;66910:94::o;44246:328::-;44421:41;24390:10;44454:7;44421:18;:41::i;:::-;44413:103;;;;-1:-1:-1;;;44413:103:0;;;;;;;:::i;:::-;44527:39;44541:4;44547:2;44551:7;44560:5;44527:13;:39::i;:::-;44246:328;;;;:::o;63441:37::-;;;;;;;:::i;68072:518::-;46149:4;46173:16;;;:7;:16;;;;;;68173:17;;-1:-1:-1;;;;;46173:16:0;68208:76;;;;-1:-1:-1;;;68208:76:0;;18777:2:1;68208:76:0;;;18759:21:1;18816:2;18796:18;;;18789:30;18855:34;18835:18;;;18828:62;-1:-1:-1;;;18906:18:1;;;18899:45;18961:19;;68208:76:0;18575:411:1;68208:76:0;68302:8;;;;68297:280;;68334:14;68327:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68072:518;;;:::o;68297:280::-;68381:28;68412:10;:8;:10::i;:::-;68381:41;;68475:1;68450:14;68444:28;:32;:121;;;;;;;;;;;;;;;;;68503:14;68518:25;68535:7;68518:16;:25::i;:::-;68545:13;68486:73;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;68444:121;68437:128;68072:518;-1:-1:-1;;;68072:518:0:o;68297:280::-;68072:518;;;:::o;67596:126::-;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;67682:32;;::::1;::::0;:14:::1;::::0;:32:::1;::::0;::::1;::::0;::::1;:::i;61896:201::-:0;61060:6;;-1:-1:-1;;;;;61060:6:0;24390:10;61207:23;61199:68;;;;-1:-1:-1;;;61199:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;61985:22:0;::::1;61977:73;;;::::0;-1:-1:-1;;;61977:73:0;;10512:2:1;61977:73:0::1;::::0;::::1;10494:21:1::0;10551:2;10531:18;;;10524:30;10590:34;10570:18;;;10563:62;-1:-1:-1;;;10641:18:1;;;10634:36;10687:19;;61977:73:0::1;10310:402:1::0;61977:73:0::1;62061:28;62080:8;62061:18;:28::i;40326:305::-:0;40428:4;-1:-1:-1;;;;;;40465:40:0;;-1:-1:-1;;;40465:40:0;;:105;;-1:-1:-1;;;;;;;40522:48:0;;-1:-1:-1;;;40522:48:0;40465:105;:158;;;-1:-1:-1;;;;;;;;;;16828:40:0;;;40587:36;16719:157;50066:174;50141:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;50141:29:0;-1:-1:-1;;;;;50141:29:0;;;;;;;;:24;;50195:23;50141:24;50195:14;:23::i;:::-;-1:-1:-1;;;;;50186:46:0;;;;;;;;;;;50066:174;;:::o;38548:118::-;37819:7;;-1:-1:-1;;;37819:7:0;;;;38073:9;38065:38;;;;-1:-1:-1;;;38065:38:0;;;;;;;:::i;:::-;38608:7:::1;:14:::0;;-1:-1:-1;;;;38608:14:0::1;-1:-1:-1::0;;;38608:14:0::1;::::0;;38638:20:::1;38645:12;24390:10:::0;;24310:98;38645:12:::1;38638:20;::::0;-1:-1:-1;;;;;7552:32:1;;;7534:51;;7522:2;7507:18;38638:20:0::1;;;;;;;38548:118::o:0;38807:120::-;37819:7;;-1:-1:-1;;;37819:7:0;;;;38343:41;;;;-1:-1:-1;;;38343:41:0;;9332:2:1;38343:41:0;;;9314:21:1;9371:2;9351:18;;;9344:30;-1:-1:-1;;;9390:18:1;;;9383:50;9450:18;;38343:41:0;9130:344:1;38343:41:0;38866:7:::1;:15:::0;;-1:-1:-1;;;;38866:15:0::1;::::0;;38897:22:::1;24390:10:::0;38906:12:::1;24310:98:::0;47068:110;47144:26;47154:2;47158:7;47144:26;;;;;;;;;;;;:9;:26::i;46378:348::-;46471:4;46173:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46173:16:0;46488:73;;;;-1:-1:-1;;;46488:73:0;;13420:2:1;46488:73:0;;;13402:21:1;13459:2;13439:18;;;13432:30;13498:34;13478:18;;;13471:62;-1:-1:-1;;;13549:18:1;;;13542:42;13601:19;;46488:73:0;13218:408:1;46488:73:0;46572:13;46588:23;46603:7;46588:14;:23::i;:::-;46572:39;;46641:5;-1:-1:-1;;;;;46630:16:0;:7;-1:-1:-1;;;;;46630:16:0;;:51;;;;46674:7;-1:-1:-1;;;;;46650:31:0;:20;46662:7;46650:11;:20::i;:::-;-1:-1:-1;;;;;46650:31:0;;46630:51;:87;;;-1:-1:-1;;;;;;43470:25:0;;;43446:4;43470:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;46685:32;46622:96;46378:348;-1:-1:-1;;;;46378:348:0:o;49370:578::-;49529:4;-1:-1:-1;;;;;49502:31:0;:23;49517:7;49502:14;:23::i;:::-;-1:-1:-1;;;;;49502:31:0;;49494:85;;;;-1:-1:-1;;;49494:85:0;;18367:2:1;49494:85:0;;;18349:21:1;18406:2;18386:18;;;18379:30;18445:34;18425:18;;;18418:62;-1:-1:-1;;;18496:18:1;;;18489:39;18545:19;;49494:85:0;18165:405:1;49494:85:0;-1:-1:-1;;;;;49598:16:0;;49590:65;;;;-1:-1:-1;;;49590:65:0;;11964:2:1;49590:65:0;;;11946:21:1;12003:2;11983:18;;;11976:30;12042:34;12022:18;;;12015:62;-1:-1:-1;;;12093:18:1;;;12086:34;12137:19;;49590:65:0;11762:400:1;49590:65:0;49668:39;49689:4;49695:2;49699:7;49668:20;:39::i;:::-;49772:29;49789:1;49793:7;49772:8;:29::i;:::-;-1:-1:-1;;;;;49814:15:0;;;;;;:9;:15;;;;;:20;;49833:1;;49814:15;:20;;49833:1;;49814:20;:::i;:::-;;;;-1:-1:-1;;;;;;;49845:13:0;;;;;;:9;:13;;;;;:18;;49862:1;;49845:13;:18;;49862:1;;49845:18;:::i;:::-;;;;-1:-1:-1;;49874:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;49874:21:0;-1:-1:-1;;;;;49874:21:0;;;;;;;;;49913:27;;49874:16;;49913:27;;;;;;;49370:578;;;:::o;62257:191::-;62350:6;;;-1:-1:-1;;;;;62367:17:0;;;-1:-1:-1;;;;;;62367:17:0;;;;;;;62400:40;;62350:6;;;62367:17;62350:6;;62400:40;;62331:16;;62400:40;62320:128;62257:191;:::o;50382:315::-;50537:8;-1:-1:-1;;;;;50528:17:0;:5;-1:-1:-1;;;;;50528:17:0;;;50520:55;;;;-1:-1:-1;;;50520:55:0;;12369:2:1;50520:55:0;;;12351:21:1;12408:2;12388:18;;;12381:30;12447:27;12427:18;;;12420:55;12492:18;;50520:55:0;12167:349:1;50520:55:0;-1:-1:-1;;;;;50586:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;50586:46:0;;;;;;;;;;50648:41;;8508::1;;;50648::0;;8481:18:1;50648:41:0;;;;;;;50382:315;;;:::o;45456:::-;45613:28;45623:4;45629:2;45633:7;45613:9;:28::i;:::-;45660:48;45683:4;45689:2;45693:7;45702:5;45660:22;:48::i;:::-;45652:111;;;;-1:-1:-1;;;45652:111:0;;;;;;;:::i;67956:108::-;68016:13;68049:7;68042:14;;;;;:::i;3996:723::-;4052:13;4273:10;4269:53;;-1:-1:-1;;4300:10:0;;;;;;;;;;;;-1:-1:-1;;;4300:10:0;;;;;3996:723::o;4269:53::-;4347:5;4332:12;4388:78;4395:9;;4388:78;;4421:8;;;;:::i;:::-;;-1:-1:-1;4444:10:0;;-1:-1:-1;4452:2:0;4444:10;;:::i;:::-;;;4388:78;;;4476:19;4508:6;4498:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4498:17:0;;4476:39;;4526:154;4533:10;;4526:154;;4560:11;4570:1;4560:11;;:::i;:::-;;-1:-1:-1;4629:10:0;4637:2;4629:5;:10;:::i;:::-;4616:24;;:2;:24;:::i;:::-;4603:39;;4586:6;4593;4586:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;4586:56:0;;;;;;;;-1:-1:-1;4657:11:0;4666:2;4657:11;;:::i;:::-;;;4526:154;;47405:321;47535:18;47541:2;47545:7;47535:5;:18::i;:::-;47586:54;47617:1;47621:2;47625:7;47634:5;47586:22;:54::i;:::-;47564:154;;;;-1:-1:-1;;;47564:154:0;;;;;;;:::i;55453:589::-;-1:-1:-1;;;;;55659:18:0;;55655:187;;55694:40;55726:7;56869:10;:17;;56842:24;;;;:15;:24;;;;;:44;;;56897:24;;;;;;;;;;;;56765:164;55694:40;55655:187;;;55764:2;-1:-1:-1;;;;;55756:10:0;:4;-1:-1:-1;;;;;55756:10:0;;55752:90;;55783:47;55816:4;55822:7;55783:32;:47::i;:::-;-1:-1:-1;;;;;55856:16:0;;55852:183;;55889:45;55926:7;55889:36;:45::i;55852:183::-;55962:4;-1:-1:-1;;;;;55956:10:0;:2;-1:-1:-1;;;;;55956:10:0;;55952:83;;55983:40;56011:2;56015:7;55983:27;:40::i;51262:799::-;51417:4;-1:-1:-1;;;;;51438:13:0;;6898:20;6946:8;51434:620;;51474:72;;-1:-1:-1;;;51474:72:0;;-1:-1:-1;;;;;51474:36:0;;;;;:72;;24390:10;;51525:4;;51531:7;;51540:5;;51474:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51474:72:0;;;;;;;;-1:-1:-1;;51474:72:0;;;;;;;;;;;;:::i;:::-;;;51470:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51716:13:0;;51712:272;;51759:60;;-1:-1:-1;;;51759:60:0;;;;;;;:::i;51712:272::-;51934:6;51928:13;51919:6;51915:2;51911:15;51904:38;51470:529;-1:-1:-1;;;;;;51597:51:0;-1:-1:-1;;;51597:51:0;;-1:-1:-1;51590:58:0;;51434:620;-1:-1:-1;52038:4:0;51262:799;;;;;;:::o;48062:382::-;-1:-1:-1;;;;;48142:16:0;;48134:61;;;;-1:-1:-1;;;48134:61:0;;16886:2:1;48134:61:0;;;16868:21:1;;;16905:18;;;16898:30;16964:34;16944:18;;;16937:62;17016:18;;48134:61:0;16684:356:1;48134:61:0;46149:4;46173:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46173:16:0;:30;48206:58;;;;-1:-1:-1;;;48206:58:0;;10919:2:1;48206:58:0;;;10901:21:1;10958:2;10938:18;;;10931:30;10997;10977:18;;;10970:58;11045:18;;48206:58:0;10717:352:1;48206:58:0;48277:45;48306:1;48310:2;48314:7;48277:20;:45::i;:::-;-1:-1:-1;;;;;48335:13:0;;;;;;:9;:13;;;;;:18;;48352:1;;48335:13;:18;;48352:1;;48335:18;:::i;:::-;;;;-1:-1:-1;;48364:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;48364:21:0;-1:-1:-1;;;;;48364:21:0;;;;;;;;48403:33;;48364:16;;;48403:33;;48364:16;;48403:33;48062:382;;:::o;57556:988::-;57822:22;57872:1;57847:22;57864:4;57847:16;:22::i;:::-;:26;;;;:::i;:::-;57884:18;57905:26;;;:17;:26;;;;;;57822:51;;-1:-1:-1;58038:28:0;;;58034:328;;-1:-1:-1;;;;;58105:18:0;;58083:19;58105:18;;;:12;:18;;;;;;;;:34;;;;;;;;;58156:30;;;;;;:44;;;58273:30;;:17;:30;;;;;:43;;;58034:328;-1:-1:-1;58458:26:0;;;;:17;:26;;;;;;;;58451:33;;;-1:-1:-1;;;;;58502:18:0;;;;;:12;:18;;;;;:34;;;;;;;58495:41;57556:988::o;58839:1079::-;59117:10;:17;59092:22;;59117:21;;59137:1;;59117:21;:::i;:::-;59149:18;59170:24;;;:15;:24;;;;;;59543:10;:26;;59092:46;;-1:-1:-1;59170:24:0;;59092:46;;59543:26;;;;;;:::i;:::-;;;;;;;;;59521:48;;59607:11;59582:10;59593;59582:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;59687:28;;;:15;:28;;;;;;;:41;;;59859:24;;;;;59852:31;59894:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;58910:1008;;;58839:1079;:::o;56343:221::-;56428:14;56445:20;56462:2;56445:16;:20::i;:::-;-1:-1:-1;;;;;56476:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;56521:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;56343:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:45;;;309:1;306;299:12;268:45;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;14:406;;;;;:::o;425:173::-;493:20;;-1:-1:-1;;;;;542:31:1;;532:42;;522:70;;588:1;585;578:12;603:160;668:20;;724:13;;717:21;707:32;;697:60;;753:1;750;743:12;768:186;827:6;880:2;868:9;859:7;855:23;851:32;848:52;;;896:1;893;886:12;848:52;919:29;938:9;919:29;:::i;959:260::-;1027:6;1035;1088:2;1076:9;1067:7;1063:23;1059:32;1056:52;;;1104:1;1101;1094:12;1056:52;1127:29;1146:9;1127:29;:::i;:::-;1117:39;;1175:38;1209:2;1198:9;1194:18;1175:38;:::i;:::-;1165:48;;959:260;;;;;:::o;1224:328::-;1301:6;1309;1317;1370:2;1358:9;1349:7;1345:23;1341:32;1338:52;;;1386:1;1383;1376:12;1338:52;1409:29;1428:9;1409:29;:::i;:::-;1399:39;;1457:38;1491:2;1480:9;1476:18;1457:38;:::i;:::-;1447:48;;1542:2;1531:9;1527:18;1514:32;1504:42;;1224:328;;;;;:::o;1557:666::-;1652:6;1660;1668;1676;1729:3;1717:9;1708:7;1704:23;1700:33;1697:53;;;1746:1;1743;1736:12;1697:53;1769:29;1788:9;1769:29;:::i;:::-;1759:39;;1817:38;1851:2;1840:9;1836:18;1817:38;:::i;:::-;1807:48;;1902:2;1891:9;1887:18;1874:32;1864:42;;1957:2;1946:9;1942:18;1929:32;1984:18;1976:6;1973:30;1970:50;;;2016:1;2013;2006:12;1970:50;2039:22;;2092:4;2084:13;;2080:27;-1:-1:-1;2070:55:1;;2121:1;2118;2111:12;2070:55;2144:73;2209:7;2204:2;2191:16;2186:2;2182;2178:11;2144:73;:::i;:::-;2134:83;;;1557:666;;;;;;;:::o;2228:254::-;2293:6;2301;2354:2;2342:9;2333:7;2329:23;2325:32;2322:52;;;2370:1;2367;2360:12;2322:52;2393:29;2412:9;2393:29;:::i;:::-;2383:39;;2441:35;2472:2;2461:9;2457:18;2441:35;:::i;2487:254::-;2555:6;2563;2616:2;2604:9;2595:7;2591:23;2587:32;2584:52;;;2632:1;2629;2622:12;2584:52;2655:29;2674:9;2655:29;:::i;:::-;2645:39;2731:2;2716:18;;;;2703:32;;-1:-1:-1;;;2487:254:1:o;2746:963::-;2830:6;2861:2;2904;2892:9;2883:7;2879:23;2875:32;2872:52;;;2920:1;2917;2910:12;2872:52;2960:9;2947:23;2989:18;3030:2;3022:6;3019:14;3016:34;;;3046:1;3043;3036:12;3016:34;3084:6;3073:9;3069:22;3059:32;;3129:7;3122:4;3118:2;3114:13;3110:27;3100:55;;3151:1;3148;3141:12;3100:55;3187:2;3174:16;3209:2;3205;3202:10;3199:36;;;3215:18;;:::i;:::-;3261:2;3258:1;3254:10;3244:20;;3284:28;3308:2;3304;3300:11;3284:28;:::i;:::-;3346:15;;;3377:12;;;;3409:11;;;3439;;;3435:20;;3432:33;-1:-1:-1;3429:53:1;;;3478:1;3475;3468:12;3429:53;3500:1;3491:10;;3510:169;3524:2;3521:1;3518:9;3510:169;;;3581:23;3600:3;3581:23;:::i;:::-;3569:36;;3542:1;3535:9;;;;;3625:12;;;;3657;;3510:169;;;-1:-1:-1;3698:5:1;2746:963;-1:-1:-1;;;;;;;;2746:963:1:o;3714:180::-;3770:6;3823:2;3811:9;3802:7;3798:23;3794:32;3791:52;;;3839:1;3836;3829:12;3791:52;3862:26;3878:9;3862:26;:::i;3899:245::-;3957:6;4010:2;3998:9;3989:7;3985:23;3981:32;3978:52;;;4026:1;4023;4016:12;3978:52;4065:9;4052:23;4084:30;4108:5;4084:30;:::i;4149:249::-;4218:6;4271:2;4259:9;4250:7;4246:23;4242:32;4239:52;;;4287:1;4284;4277:12;4239:52;4319:9;4313:16;4338:30;4362:5;4338:30;:::i;4403:450::-;4472:6;4525:2;4513:9;4504:7;4500:23;4496:32;4493:52;;;4541:1;4538;4531:12;4493:52;4581:9;4568:23;4614:18;4606:6;4603:30;4600:50;;;4646:1;4643;4636:12;4600:50;4669:22;;4722:4;4714:13;;4710:27;-1:-1:-1;4700:55:1;;4751:1;4748;4741:12;4700:55;4774:73;4839:7;4834:2;4821:16;4816:2;4812;4808:11;4774:73;:::i;4858:272::-;4916:6;4969:2;4957:9;4948:7;4944:23;4940:32;4937:52;;;4985:1;4982;4975:12;4937:52;5024:9;5011:23;5074:6;5067:5;5063:18;5056:5;5053:29;5043:57;;5096:1;5093;5086:12;5135:180;5194:6;5247:2;5235:9;5226:7;5222:23;5218:32;5215:52;;;5263:1;5260;5253:12;5215:52;-1:-1:-1;5286:23:1;;5135:180;-1:-1:-1;5135:180:1:o;5320:269::-;5377:6;5430:2;5418:9;5409:7;5405:23;5401:32;5398:52;;;5446:1;5443;5436:12;5398:52;5485:9;5472:23;5535:4;5528:5;5524:16;5517:5;5514:27;5504:55;;5555:1;5552;5545:12;5594:257;5635:3;5673:5;5667:12;5700:6;5695:3;5688:19;5716:63;5772:6;5765:4;5760:3;5756:14;5749:4;5742:5;5738:16;5716:63;:::i;:::-;5833:2;5812:15;-1:-1:-1;;5808:29:1;5799:39;;;;5840:4;5795:50;;5594:257;-1:-1:-1;;5594:257:1:o;5856:1527::-;6080:3;6118:6;6112:13;6144:4;6157:51;6201:6;6196:3;6191:2;6183:6;6179:15;6157:51;:::i;:::-;6271:13;;6230:16;;;;6293:55;6271:13;6230:16;6315:15;;;6293:55;:::i;:::-;6437:13;;6370:20;;;6410:1;;6497;6519:18;;;;6572;;;;6599:93;;6677:4;6667:8;6663:19;6651:31;;6599:93;6740:2;6730:8;6727:16;6707:18;6704:40;6701:167;;;-1:-1:-1;;;6767:33:1;;6823:4;6820:1;6813:15;6853:4;6774:3;6841:17;6701:167;6884:18;6911:110;;;;7035:1;7030:328;;;;6877:481;;6911:110;-1:-1:-1;;6946:24:1;;6932:39;;6991:20;;;;-1:-1:-1;6911:110:1;;7030:328;21649:1;21642:14;;;21686:4;21673:18;;7125:1;7139:169;7153:8;7150:1;7147:15;7139:169;;;7235:14;;7220:13;;;7213:37;7278:16;;;;7170:10;;7139:169;;;7143:3;;7339:8;7332:5;7328:20;7321:27;;6877:481;-1:-1:-1;7374:3:1;;5856:1527;-1:-1:-1;;;;;;;;;;;5856:1527:1:o;7596:488::-;-1:-1:-1;;;;;7865:15:1;;;7847:34;;7917:15;;7912:2;7897:18;;7890:43;7964:2;7949:18;;7942:34;;;8012:3;8007:2;7992:18;;7985:31;;;7790:4;;8033:45;;8058:19;;8050:6;8033:45;:::i;:::-;8025:53;7596:488;-1:-1:-1;;;;;;7596:488:1:o;8560:219::-;8709:2;8698:9;8691:21;8672:4;8729:44;8769:2;8758:9;8754:18;8746:6;8729:44;:::i;9891:414::-;10093:2;10075:21;;;10132:2;10112:18;;;10105:30;10171:34;10166:2;10151:18;;10144:62;-1:-1:-1;;;10237:2:1;10222:18;;10215:48;10295:3;10280:19;;9891:414::o;14035:340::-;14237:2;14219:21;;;14276:2;14256:18;;;14249:30;-1:-1:-1;;;14310:2:1;14295:18;;14288:46;14366:2;14351:18;;14035:340::o;17458:356::-;17660:2;17642:21;;;17679:18;;;17672:30;17738:34;17733:2;17718:18;;17711:62;17805:2;17790:18;;17458:356::o;19742:413::-;19944:2;19926:21;;;19983:2;19963:18;;;19956:30;20022:34;20017:2;20002:18;;19995:62;-1:-1:-1;;;20088:2:1;20073:18;;20066:47;20145:3;20130:19;;19742:413::o;21296:275::-;21367:2;21361:9;21432:2;21413:13;;-1:-1:-1;;21409:27:1;21397:40;;21467:18;21452:34;;21488:22;;;21449:62;21446:88;;;21514:18;;:::i;:::-;21550:2;21543:22;21296:275;;-1:-1:-1;21296:275:1:o;21702:128::-;21742:3;21773:1;21769:6;21766:1;21763:13;21760:39;;;21779:18;;:::i;:::-;-1:-1:-1;21815:9:1;;21702:128::o;21835:120::-;21875:1;21901;21891:35;;21906:18;;:::i;:::-;-1:-1:-1;21940:9:1;;21835:120::o;21960:168::-;22000:7;22066:1;22062;22058:6;22054:14;22051:1;22048:21;22043:1;22036:9;22029:17;22025:45;22022:71;;;22073:18;;:::i;:::-;-1:-1:-1;22113:9:1;;21960:168::o;22133:125::-;22173:4;22201:1;22198;22195:8;22192:34;;;22206:18;;:::i;:::-;-1:-1:-1;22243:9:1;;22133:125::o;22263:258::-;22335:1;22345:113;22359:6;22356:1;22353:13;22345:113;;;22435:11;;;22429:18;22416:11;;;22409:39;22381:2;22374:10;22345:113;;;22476:6;22473:1;22470:13;22467:48;;;-1:-1:-1;;22511:1:1;22493:16;;22486:27;22263:258::o;22526:380::-;22605:1;22601:12;;;;22648;;;22669:61;;22723:4;22715:6;22711:17;22701:27;;22669:61;22776:2;22768:6;22765:14;22745:18;22742:38;22739:161;;;22822:10;22817:3;22813:20;22810:1;22803:31;22857:4;22854:1;22847:15;22885:4;22882:1;22875:15;22739:161;;22526:380;;;:::o;22911:197::-;22949:3;22977:6;23018:2;23011:5;23007:14;23045:2;23036:7;23033:15;23030:41;;;23051:18;;:::i;:::-;23100:1;23087:15;;22911:197;-1:-1:-1;;;22911:197:1:o;23113:135::-;23152:3;-1:-1:-1;;23173:17:1;;23170:43;;;23193:18;;:::i;:::-;-1:-1:-1;23240:1:1;23229:13;;23113:135::o;23253:175::-;23290:3;23334:4;23327:5;23323:16;23363:4;23354:7;23351:17;23348:43;;;23371:18;;:::i;:::-;23420:1;23407:15;;23253:175;-1:-1:-1;;23253:175:1:o;23433:112::-;23465:1;23491;23481:35;;23496:18;;:::i;:::-;-1:-1:-1;23530:9:1;;23433:112::o;23550:127::-;23611:10;23606:3;23602:20;23599:1;23592:31;23642:4;23639:1;23632:15;23666:4;23663:1;23656:15;23682:127;23743:10;23738:3;23734:20;23731:1;23724:31;23774:4;23771:1;23764:15;23798:4;23795:1;23788:15;23814:127;23875:10;23870:3;23866:20;23863:1;23856:31;23906:4;23903:1;23896:15;23930:4;23927:1;23920:15;23946:127;24007:10;24002:3;23998:20;23995:1;23988:31;24038:4;24035:1;24028:15;24062:4;24059:1;24052:15;24078:127;24139:10;24134:3;24130:20;24127:1;24120:31;24170:4;24167:1;24160:15;24194:4;24191:1;24184:15;24210:131;-1:-1:-1;;;;;;24284:32:1;;24274:43;;24264:71;;24331:1;24328;24321:12

Swarm Source

ipfs://70abf15d369a77d49f88c4060aee96c9d888234c966e3b5b529afe8e3b125b23
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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