ETH Price: $3,531.27 (+4.26%)

Token

NFT20 Wei (NFT20)
 

Overview

Max Total Supply

4,055 NFT20

Holders

1,637

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
8 NFT20
0x2772075b2b2d64e031e2883a26ba220df527decd
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:
NFT20

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-06-06
*/

// SPDX-License-Identifier: MIT


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

// 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);
}
// 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/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 (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}
// 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/IERC721Metadata.sol


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

pragma solidity ^0.8.0;


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

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

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

// File: @openzeppelin/contracts/token/ERC721/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/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;
    }
}


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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.4;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {
        if (_startTokenId() <= tokenId) {
            packed = _packedOwnerships[tokenId];
            // If not burned.
            if (packed & _BITMASK_BURNED == 0) {
                // If the data at the starting slot does not exist, start the scan.
                if (packed == 0) {
                    if (tokenId >= _currentIndex) _revert(OwnerQueryForNonexistentToken.selector);
                    // Invariant:
                    // There will always be an initialized ownership slot
                    // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                    // before an unintialized ownership slot
                    // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                    // Hence, `tokenId` will not underflow.
                    //
                    // We can directly compare the packed value.
                    // If the address is zero, packed will be zero.
                    for (;;) {
                        unchecked {
                            packed = _packedOwnerships[--tokenId];
                        }
                        if (packed == 0) continue;
                        return packed;
                    }
                }
                // Otherwise, the data exists and is not burned. We can skip the scan.
                // This is possible because we have already achieved the target condition.
                // This saves 2143 gas on transfers of initialized tokens.
                return packed;
            }
        }
        _revert(OwnerQueryForNonexistentToken.selector);
    }

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

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

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

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

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     */
    function approve(address to, uint256 tokenId) public payable virtual override {
        _approve(to, tokenId, true);
    }

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

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom}
     * for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

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

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

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
        from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));

        if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector);

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

        // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
        uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
        assembly {
            // Emit the `Transfer` event.
            log4(
                0, // Start of data (0, since no data).
                0, // End of data (0, since no data).
                _TRANSFER_EVENT_SIGNATURE, // Signature.
                from, // `from`.
                toMasked, // `to`.
                tokenId // `tokenId`.
            )
        }
        if (toMasked == 0) _revert(TransferToZeroAddress.selector);

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                _revert(TransferToNonERC721ReceiverImplementer.selector);
            }
    }

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

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

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

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

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

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

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
            uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;

            if (toMasked == 0) _revert(MintToZeroAddress.selector);

            uint256 end = startTokenId + quantity;
            uint256 tokenId = startTokenId;

            do {
                assembly {
                    // Emit the `Transfer` event.
                    log4(
                        0, // Start of data (0, since no data).
                        0, // End of data (0, since no data).
                        _TRANSFER_EVENT_SIGNATURE, // Signature.
                        0, // `address(0)`.
                        toMasked, // `to`.
                        tokenId // `tokenId`.
                    )
                }
                // The `!=` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
            } while (++tokenId != end);

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @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:
     *
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        bool approvalCheck
    ) internal virtual {
        address owner = ownerOf(tokenId);

        if (approvalCheck && _msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                _revert(ApprovalCallerNotOwnerNorApproved.selector);
            }

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev For more efficient reverts.
     */
    function _revert(bytes4 errorSelector) internal pure {
        assembly {
            mstore(0x00, errorSelector)
            revert(0x00, 0x04)
        }
    }
}



// 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);
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}
pragma solidity ^0.8.0;
/// @title EIP-721 Metadata Update Extension
interface IERC4906 is IERC721A {
    /// @dev This event emits when the metadata of a token is changed.
    /// Third-party platforms such as NFT marketplaces can listen to
    /// the event and auto-update the tokens in their apps.
    event MetadataUpdate(uint256 _tokenId);
}


pragma solidity ^0.8.18;

library utils {
    function uint2str(
        uint _i
    ) internal pure returns (string memory _uintAsString) {
        if (_i == 0) {
            return "0";
        }
        uint j = _i;
        uint len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint k = len;
        while (_i != 0) {
            k = k - 1;
            uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            _i /= 10;
        }
        return string(bstr);
    }

    // 
    function random(uint input, uint min, uint max) internal pure returns (uint) {
        uint randRange = max - min;
        return max - (uint(keccak256(abi.encodePacked(input + 2023))) % randRange) - 1;
    }

}



pragma solidity ^0.8.18;

library svgInfo {

    function renderSvg(uint amtValues,uint tokenId) internal pure returns (string memory svg) {
        svg = '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 350 350"><style>.base { fill: white; font-family: serif; font-size: 20px; }</style><rect width="100%" height="100%" fill="black"/><text x="20" y="60" class="base">{</text><text x="40" y="110" class="base">&quot;p&quot;: &quot;nft-20&quot;,</text><text x="40" y="160" class="base">&quot;id&quot;: &quot;';
        return string(abi.encodePacked(
                svg, 
                utils.uint2str(tokenId),
                '&quot;,</text>  <text x="40" y="210" class="base">&quot;ticket&quot;: &quot;wei&quot;,</text><text x="40" y="260" class="base">&quot;amt&quot;: &quot;',
                utils.uint2str(amtValues), 
                '&quot;</text><text x="20" y="310" class="base">}</text></svg>'));
    }
}
pragma solidity ^0.8.18;

contract NFT20 is ERC721A, Ownable, IERC4906 {

    uint public price = 1000000000000000; //.001 eth
    bool public iscombineTransfer = false;
    uint256 public maxSupply = 20000; //max_supply
    uint256 public maxPublicSupply = 19000; //max_supply
    uint256 public maxFreeSupply = 4000;
    bool public mintEnabled = false;
    uint256 public maxFreePerTx = 2; 
    uint256 public maxPerTx = 20; 


    mapping(uint => uint) transferIn;
    mapping(uint => uint) transferOut;
    mapping(uint => uint) amtValues;
    mapping(uint => bool) isBurned;
    mapping(address => uint256) private _mintedFreeAmount;

    constructor() ERC721A("NFT20 Wei", "NFT20") {}

    function mint(uint quantity, uint amt) public payable {
        require(amt % 1000 == 0 && amt > 0  && amt <= 10000, "wrong amt");
        require(tx.origin == msg.sender);
        uint amtq = amt / 1000;
        require(msg.value >= quantity * price * amtq, "not enough eth");
        for (uint i = totalSupply(); i < totalSupply() + quantity; i++) {
            amtValues[i + 1] = amt;
        }
        handleMint(msg.sender, quantity);
    }

    function freeMint(uint quantity) public {
        require(_mintedFreeAmount[msg.sender] + quantity <= maxFreePerTx,"limit free amounts");
        require(quantity <= maxFreePerTx, "limit free per tx");
        require(totalSupply() + quantity < maxFreeSupply + 1, "not enough free mints");
        require(tx.origin == msg.sender);
        for (uint i = totalSupply(); i < totalSupply() + quantity; i++) {
            amtValues[i + 1] = 1000;
        }
        _mintedFreeAmount[msg.sender] += quantity;
        handleMint(msg.sender, quantity);
    }

    function handleMint(address recipient, uint quantity) internal {
        require(mintEnabled, "minting is closed.");
        require(totalSupply() + quantity < maxPublicSupply + 1, "no more left");
        _mint(recipient, quantity);
    }

    function teamMint(uint quantity, uint amt, address recipient) public onlyOwner{
        require(totalSupply() + quantity < maxSupply + 1, "no more left");
        require(amt % 1000 == 0 && amt > 0  && amt <= 10000, "wrong amt");
        for (uint i = totalSupply(); i < totalSupply() + quantity; i++) {
            amtValues[i + 1] = amt;
        }
        _mint(recipient, quantity);
    }
    
    function combineTransfer(uint from, uint to, uint value) public{
        require(iscombineTransfer, "transfer not active");
        require(_exists(from) && _exists(to),"non-existent id");
        require(getValue(from) >= value,"no sufficient balance");
        require(ownerOf(from) == msg.sender, "must own token");
        transferOut[from] +=  1;
        amtValues[from] -= value;
        amtValues[to] += value;
        transferOut[to] +=  1;
    }

    function getValue(uint256 tokenId) public view returns (uint) {
        if (!_exists(tokenId)) {
            return 0;
        } else {
            return amtValues[tokenId];
        } 
    }

    function tokenURI(uint256 tokenId) public view virtual override(ERC721A, IERC721A) returns (string memory) {
        uint value = amtValues[tokenId];
        return getMetadata(tokenId, value, transferIn[tokenId], transferOut[tokenId]);
    }

    function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }

    function flipMint() external onlyOwner {
        mintEnabled = !mintEnabled;
    }

    function getMetadata(uint tokenId, uint value, uint tIn, uint tOut) internal pure returns (string memory) {
        string memory json;
        json = string(abi.encodePacked(
            '{"name": "Wei#',
            utils.uint2str(tokenId),
            '", "description": "An experimental standard. On-chain nft20_wei token.", "attributes":[{"trait_type": "TokenId", "value": "',
            utils.uint2str(tokenId),
            '"},{"trait_type": "Number of transfers out", "value": "',
            utils.uint2str(tOut),
            '"},{"trait_type": "Number of transfers in", "value": "',
            utils.uint2str(tIn),
            '"}], "image": "data:image/svg+xml;base64,',
            Base64.encode(bytes(svgInfo.renderSvg(value,tokenId))),
            '"}'
        ));
        return string(abi.encodePacked(
            "data:application/json;base64,",
            Base64.encode(bytes(json))
        ));
    }

    function mintCount() public view returns (uint) {
        return _totalMinted();
    }

    function burned() public view returns (uint) {
        return _totalMinted();
    }

    function toggleCombineTransfer() public onlyOwner {
        iscombineTransfer = !iscombineTransfer;
    }

    function withdraw() external onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }


}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"combineTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iscombineTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFreePerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFreeSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPublicSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"quantity","type":"uint256"},{"internalType":"uint256","name":"amt","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleCombineTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405266038d7ea4c680006009556000600a60006101000a81548160ff021916908315150217905550614e20600b55614a38600c55610fa0600d556000600e60006101000a81548160ff0219169083151502179055506002600f5560146010553480156200006e57600080fd5b506040518060400160405280600981526020017f4e465432302057656900000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f4e465432300000000000000000000000000000000000000000000000000000008152508160029081620000ec91906200048e565b508060039081620000fe91906200048e565b506200010f6200013d60201b60201c565b6000819055505050620001376200012b6200014660201b60201c565b6200014e60201b60201c565b62000575565b60006001905090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200029657607f821691505b602082108103620002ac57620002ab6200024e565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620002d7565b620003228683620002d7565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200036f6200036962000363846200033a565b62000344565b6200033a565b9050919050565b6000819050919050565b6200038b836200034e565b620003a36200039a8262000376565b848454620002e4565b825550505050565b600090565b620003ba620003ab565b620003c781848462000380565b505050565b5b81811015620003ef57620003e3600082620003b0565b600181019050620003cd565b5050565b601f8211156200043e576200040881620002b2565b6200041384620002c7565b8101602085101562000423578190505b6200043b6200043285620002c7565b830182620003cc565b50505b505050565b600082821c905092915050565b6000620004636000198460080262000443565b1980831691505092915050565b60006200047e838362000450565b9150826002028217905092915050565b620004998262000214565b67ffffffffffffffff811115620004b557620004b46200021f565b5b620004c182546200027d565b620004ce828285620003f3565b600060209050601f831160018114620005065760008415620004f1578287015190505b620004fd858262000470565b8655506200056d565b601f1984166200051686620002b2565b60005b82811015620005405784890151825560018201915060208501945060208101905062000519565b868310156200056057848901516200055c601f89168262000450565b8355505b6001600288020188555050505b505050505050565b613e0c80620005856000396000f3fe6080604052600436106102045760003560e01c806373f4256111610118578063b88d4fde116100a0578063d5abeb011161006f578063d5abeb01146106f0578063da71573a1461071b578063e985e9c514610732578063f2fde38b1461076f578063f968adbe1461079857610204565b8063b88d4fde14610655578063c87b56dd14610671578063d1239730146106ae578063d2ed5c59146106d957610204565b806395d89b41116100e757806395d89b41146105825780639659867e146105ad578063a035b1fe146105d8578063a22cb46514610603578063b01e88b91461062c57610204565b806373f42561146104d85780637c928fe9146105035780637dc949b21461052c5780638da5cb5b1461055757610204565b80631b2ef1ca1161019b57806342842e0e1161016a57806342842e0e14610400578063475133341461041c5780636352211e1461044757806370a0823114610484578063715018a6146104c157610204565b80631b2ef1ca1461038657806323b872dd146103a257806326a74d8e146103be5780633ccfd60b146103e957610204565b8063095ea7b3116101d7578063095ea7b3146102d957806309681267146102f55780630ff4c9161461031e57806318160ddd1461035b57610204565b806301e7678c1461020957806301ffc9a71461023457806306fdde0314610271578063081812fc1461029c575b600080fd5b34801561021557600080fd5b5061021e6107c3565b60405161022b9190612702565b60405180910390f35b34801561024057600080fd5b5061025b60048036038101906102569190612789565b6107d6565b6040516102689190612702565b60405180910390f35b34801561027d57600080fd5b50610286610868565b6040516102939190612846565b60405180910390f35b3480156102a857600080fd5b506102c360048036038101906102be919061289e565b6108fa565b6040516102d0919061290c565b60405180910390f35b6102f360048036038101906102ee9190612953565b610958565b005b34801561030157600080fd5b5061031c60048036038101906103179190612993565b610968565b005b34801561032a57600080fd5b506103456004803603810190610340919061289e565b610b1e565b60405161035291906129f5565b60405180910390f35b34801561036757600080fd5b50610370610b52565b60405161037d91906129f5565b60405180910390f35b6103a0600480360381019061039b9190612a10565b610b69565b005b6103bc60048036038101906103b79190612a50565b610ce6565b005b3480156103ca57600080fd5b506103d3610fa7565b6040516103e091906129f5565b60405180910390f35b3480156103f557600080fd5b506103fe610fad565b005b61041a60048036038101906104159190612a50565b611069565b005b34801561042857600080fd5b50610431611089565b60405161043e91906129f5565b60405180910390f35b34801561045357600080fd5b5061046e6004803603810190610469919061289e565b61108f565b60405161047b919061290c565b60405180910390f35b34801561049057600080fd5b506104ab60048036038101906104a69190612aa3565b6110a1565b6040516104b891906129f5565b60405180910390f35b3480156104cd57600080fd5b506104d6611138565b005b3480156104e457600080fd5b506104ed6111c0565b6040516104fa91906129f5565b60405180910390f35b34801561050f57600080fd5b5061052a6004803603810190610525919061289e565b6111cf565b005b34801561053857600080fd5b50610541611401565b60405161054e91906129f5565b60405180910390f35b34801561056357600080fd5b5061056c611407565b604051610579919061290c565b60405180910390f35b34801561058e57600080fd5b50610597611431565b6040516105a49190612846565b60405180910390f35b3480156105b957600080fd5b506105c26114c3565b6040516105cf91906129f5565b60405180910390f35b3480156105e457600080fd5b506105ed6114d2565b6040516105fa91906129f5565b60405180910390f35b34801561060f57600080fd5b5061062a60048036038101906106259190612afc565b6114d8565b005b34801561063857600080fd5b50610653600480360381019061064e9190612b3c565b6115e3565b005b61066f600480360381019061066a9190612cc4565b6117fb565b005b34801561067d57600080fd5b506106986004803603810190610693919061289e565b61184d565b6040516106a59190612846565b60405180910390f35b3480156106ba57600080fd5b506106c36118a1565b6040516106d09190612702565b60405180910390f35b3480156106e557600080fd5b506106ee6118b4565b005b3480156106fc57600080fd5b5061070561195c565b60405161071291906129f5565b60405180910390f35b34801561072757600080fd5b50610730611962565b005b34801561073e57600080fd5b5061075960048036038101906107549190612d47565b611a0a565b6040516107669190612702565b60405180910390f35b34801561077b57600080fd5b5061079660048036038101906107919190612aa3565b611a9e565b005b3480156107a457600080fd5b506107ad611b95565b6040516107ba91906129f5565b60405180910390f35b600a60009054906101000a900460ff1681565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083157506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108615750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461087790612db6565b80601f01602080910402602001604051908101604052809291908181526020018280546108a390612db6565b80156108f05780601f106108c5576101008083540402835291602001916108f0565b820191906000526020600020905b8154815290600101906020018083116108d357829003601f168201915b5050505050905090565b600061090582611b9b565b61091a5761091963cf4700e460e01b611bfa565b5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61096482826001611c04565b5050565b610970611d33565b73ffffffffffffffffffffffffffffffffffffffff1661098e611407565b73ffffffffffffffffffffffffffffffffffffffff16146109e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109db90612e33565b60405180910390fd5b6001600b546109f39190612e82565b836109fc610b52565b610a069190612e82565b10610a46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3d90612f02565b60405180910390fd5b60006103e883610a569190612f51565b148015610a635750600082115b8015610a7157506127108211155b610ab0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa790612fce565b60405180910390fd5b6000610aba610b52565b90505b83610ac6610b52565b610ad09190612e82565b811015610b0e578260136000600184610ae99190612e82565b8152602001908152602001600020819055508080610b0690612fee565b915050610abd565b50610b198184611d3b565b505050565b6000610b2982611b9b565b610b365760009050610b4d565b601360008381526020019081526020016000205490505b919050565b6000610b5c611e9e565b6001546000540303905090565b60006103e882610b799190612f51565b148015610b865750600081115b8015610b9457506127108111155b610bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bca90612fce565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610c0b57600080fd5b60006103e882610c1b9190613036565b90508060095484610c2c9190613067565b610c369190613067565b341015610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906130f5565b60405180910390fd5b6000610c82610b52565b90505b83610c8e610b52565b610c989190612e82565b811015610cd6578260136000600184610cb19190612e82565b8152602001908152602001600020819055508080610cce90612fee565b915050610c85565b50610ce13384611ea7565b505050565b6000610cf182611f66565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d6657610d6563a114810060e01b611bfa565b5b600080610d728461201c565b91509150610d888187610d83612043565b61204b565b610db357610d9d86610d98612043565b611a0a565b610db257610db16359c896be60e01b611bfa565b5b5b610dc0868686600161208f565b8015610dcb57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e9985610e75888887612095565b7c0200000000000000000000000000000000000000000000000000000000176120bd565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610f1f5760006001850190506000600460008381526020019081526020016000205403610f1d576000548114610f1c578360046000838152602001908152602001600020819055505b5b505b600073ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460008103610f9157610f9063ea553b3460e01b611bfa565b5b610f9e87878760016120e8565b50505050505050565b600c5481565b610fb5611d33565b73ffffffffffffffffffffffffffffffffffffffff16610fd3611407565b73ffffffffffffffffffffffffffffffffffffffff1614611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102090612e33565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061106757600080fd5b565b611084838383604051806020016040528060008152506117fb565b505050565b600d5481565b600061109a82611f66565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036110e7576110e6638f4eb60460e01b611bfa565b5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611140611d33565b73ffffffffffffffffffffffffffffffffffffffff1661115e611407565b73ffffffffffffffffffffffffffffffffffffffff16146111b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ab90612e33565b60405180910390fd5b6111be60006120ee565b565b60006111ca6121b4565b905090565b600f5481601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461121d9190612e82565b111561125e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125590613161565b60405180910390fd5b600f548111156112a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129a906131cd565b60405180910390fd5b6001600d546112b29190612e82565b816112bb610b52565b6112c59190612e82565b10611305576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fc90613239565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161461133d57600080fd5b6000611347610b52565b90505b81611353610b52565b61135d9190612e82565b81101561139d576103e8601360006001846113789190612e82565b815260200190815260200160002081905550808061139590612fee565b91505061134a565b5080601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113ed9190612e82565b925050819055506113fe3382611ea7565b50565b600f5481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461144090612db6565b80601f016020809104026020016040519081016040528092919081815260200182805461146c90612db6565b80156114b95780601f1061148e576101008083540402835291602001916114b9565b820191906000526020600020905b81548152906001019060200180831161149c57829003601f168201915b5050505050905090565b60006114cd6121b4565b905090565b60095481565b80600760006114e5612043565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611592612043565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115d79190612702565b60405180910390a35050565b600a60009054906101000a900460ff16611632576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611629906132a5565b60405180910390fd5b61163b83611b9b565b801561164c575061164b82611b9b565b5b61168b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168290613311565b60405180910390fd5b8061169584610b1e565b10156116d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cd9061337d565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166116f68461108f565b73ffffffffffffffffffffffffffffffffffffffff161461174c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611743906133e9565b60405180910390fd5b60016012600085815260200190815260200160002060008282546117709190612e82565b925050819055508060136000858152602001908152602001600020600082825461179a9190613409565b92505081905550806013600084815260200190815260200160002060008282546117c49190612e82565b9250508190555060016012600084815260200190815260200160002060008282546117ef9190612e82565b92505081905550505050565b611806848484610ce6565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461184757611831848484846121c7565b6118465761184563d1a57ed660e01b611bfa565b5b5b50505050565b60606000601360008481526020019081526020016000205490506118998382601160008781526020019081526020016000205460126000888152602001908152602001600020546122f6565b915050919050565b600e60009054906101000a900460ff1681565b6118bc611d33565b73ffffffffffffffffffffffffffffffffffffffff166118da611407565b73ffffffffffffffffffffffffffffffffffffffff1614611930576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192790612e33565b60405180910390fd5b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b600b5481565b61196a611d33565b73ffffffffffffffffffffffffffffffffffffffff16611988611407565b73ffffffffffffffffffffffffffffffffffffffff16146119de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d590612e33565b60405180910390fd5b600a60009054906101000a900460ff1615600a60006101000a81548160ff021916908315150217905550565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611aa6611d33565b73ffffffffffffffffffffffffffffffffffffffff16611ac4611407565b73ffffffffffffffffffffffffffffffffffffffff1614611b1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1190612e33565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b80906134af565b60405180910390fd5b611b92816120ee565b50565b60105481565b600081611ba6611e9e565b11158015611bb5575060005482105b8015611bf3575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b8060005260046000fd5b6000611c0f8361108f565b9050818015611c5157508073ffffffffffffffffffffffffffffffffffffffff16611c38612043565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611c7d57611c6781611c62612043565b611a0a565b611c7c57611c7b63cfb3b94260e01b611bfa565b5b5b836006600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b600033905090565b60008054905060008203611d5a57611d5963b562e8dd60e01b611bfa565b5b611d67600084838561208f565b611d8783611d786000866000612095565b611d8185612387565b176120bd565b6004600083815260200190815260200160002081905550600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff1616905060008103611e3f57611e3e632e07630060e01b611bfa565b5b6000838301905060008390505b808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4818160010191508103611e4c5781600081905550505050611e9960008483856120e8565b505050565b60006001905090565b600e60009054906101000a900460ff16611ef6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eed9061351b565b60405180910390fd5b6001600c54611f059190612e82565b81611f0e610b52565b611f189190612e82565b10611f58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f4f90612f02565b60405180910390fd5b611f628282611d3b565b5050565b600081611f71611e9e565b11612006576004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036120055760008103612000576000548210611fd557611fd463df2d9b4260e01b611bfa565b5b5b60046000836001900393508381526020019081526020016000205490506000810361201757611fd6565b612017565b5b61201663df2d9b4260e01b611bfa565b5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86120ac868684612397565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006121be611e9e565b60005403905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026121ed612043565b8786866040518563ffffffff1660e01b815260040161220f9493929190613590565b6020604051808303816000875af192505050801561224b57506040513d601f19601f8201168201806040525081019061224891906135f1565b60015b6122a3573d806000811461227b576040519150601f19603f3d011682016040523d82523d6000602084013e612280565b606091505b50600081510361229b5761229a63d1a57ed660e01b611bfa565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606080612302866123a0565b61230b876123a0565b612314856123a0565b61231d876123a0565b61232f61232a8a8c612528565b612584565b604051602001612343959493929190613906565b604051602081830303815290604052905061235d81612584565b60405160200161236d91906139df565b604051602081830303815290604052915050949350505050565b60006001821460e11b9050919050565b60009392505050565b6060600082036123e7576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612523565b600082905060005b6000821461241957808061240290612fee565b915050600a826124129190613036565b91506123ef565b60008167ffffffffffffffff81111561243557612434612b99565b5b6040519080825280601f01601f1916602001820160405280156124675781602001600182028036833780820191505090505b50905060008290505b6000861461251b576001816124859190613409565b90506000600a80886124979190613036565b6124a19190613067565b876124ac9190613409565b60306124b89190613a0e565b905060008160f81b9050808484815181106124d6576124d5613a43565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a886125129190613036565b97505050612470565b819450505050505b919050565b6060604051806101c001604052806101878152602001613c106101879139905080612552836123a0565b61255b856123a0565b60405160200161256d93929190613bc8565b604051602081830303815290604052905092915050565b606060008251036125a6576040518060200160405280600081525090506126e2565b6000604051806060016040528060408152602001613d9760409139905060006003600285516125d59190612e82565b6125df9190613036565b60046125eb9190613067565b67ffffffffffffffff81111561260457612603612b99565b5b6040519080825280601f01601f1916602001820160405280156126365781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126a2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845360018401935050612647565b50506003865106600181146126be57600281146126d1576126d9565b603d6001830353603d60028303536126d9565b603d60018303535b50505080925050505b919050565b60008115159050919050565b6126fc816126e7565b82525050565b600060208201905061271760008301846126f3565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61276681612731565b811461277157600080fd5b50565b6000813590506127838161275d565b92915050565b60006020828403121561279f5761279e612727565b5b60006127ad84828501612774565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156127f05780820151818401526020810190506127d5565b60008484015250505050565b6000601f19601f8301169050919050565b6000612818826127b6565b61282281856127c1565b93506128328185602086016127d2565b61283b816127fc565b840191505092915050565b60006020820190508181036000830152612860818461280d565b905092915050565b6000819050919050565b61287b81612868565b811461288657600080fd5b50565b60008135905061289881612872565b92915050565b6000602082840312156128b4576128b3612727565b5b60006128c284828501612889565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006128f6826128cb565b9050919050565b612906816128eb565b82525050565b600060208201905061292160008301846128fd565b92915050565b612930816128eb565b811461293b57600080fd5b50565b60008135905061294d81612927565b92915050565b6000806040838503121561296a57612969612727565b5b60006129788582860161293e565b925050602061298985828601612889565b9150509250929050565b6000806000606084860312156129ac576129ab612727565b5b60006129ba86828701612889565b93505060206129cb86828701612889565b92505060406129dc8682870161293e565b9150509250925092565b6129ef81612868565b82525050565b6000602082019050612a0a60008301846129e6565b92915050565b60008060408385031215612a2757612a26612727565b5b6000612a3585828601612889565b9250506020612a4685828601612889565b9150509250929050565b600080600060608486031215612a6957612a68612727565b5b6000612a778682870161293e565b9350506020612a888682870161293e565b9250506040612a9986828701612889565b9150509250925092565b600060208284031215612ab957612ab8612727565b5b6000612ac78482850161293e565b91505092915050565b612ad9816126e7565b8114612ae457600080fd5b50565b600081359050612af681612ad0565b92915050565b60008060408385031215612b1357612b12612727565b5b6000612b218582860161293e565b9250506020612b3285828601612ae7565b9150509250929050565b600080600060608486031215612b5557612b54612727565b5b6000612b6386828701612889565b9350506020612b7486828701612889565b9250506040612b8586828701612889565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612bd1826127fc565b810181811067ffffffffffffffff82111715612bf057612bef612b99565b5b80604052505050565b6000612c0361271d565b9050612c0f8282612bc8565b919050565b600067ffffffffffffffff821115612c2f57612c2e612b99565b5b612c38826127fc565b9050602081019050919050565b82818337600083830152505050565b6000612c67612c6284612c14565b612bf9565b905082815260208101848484011115612c8357612c82612b94565b5b612c8e848285612c45565b509392505050565b600082601f830112612cab57612caa612b8f565b5b8135612cbb848260208601612c54565b91505092915050565b60008060008060808587031215612cde57612cdd612727565b5b6000612cec8782880161293e565b9450506020612cfd8782880161293e565b9350506040612d0e87828801612889565b925050606085013567ffffffffffffffff811115612d2f57612d2e61272c565b5b612d3b87828801612c96565b91505092959194509250565b60008060408385031215612d5e57612d5d612727565b5b6000612d6c8582860161293e565b9250506020612d7d8582860161293e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612dce57607f821691505b602082108103612de157612de0612d87565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e1d6020836127c1565b9150612e2882612de7565b602082019050919050565b60006020820190508181036000830152612e4c81612e10565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612e8d82612868565b9150612e9883612868565b9250828201905080821115612eb057612eaf612e53565b5b92915050565b7f6e6f206d6f7265206c6566740000000000000000000000000000000000000000600082015250565b6000612eec600c836127c1565b9150612ef782612eb6565b602082019050919050565b60006020820190508181036000830152612f1b81612edf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612f5c82612868565b9150612f6783612868565b925082612f7757612f76612f22565b5b828206905092915050565b7f77726f6e6720616d740000000000000000000000000000000000000000000000600082015250565b6000612fb86009836127c1565b9150612fc382612f82565b602082019050919050565b60006020820190508181036000830152612fe781612fab565b9050919050565b6000612ff982612868565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361302b5761302a612e53565b5b600182019050919050565b600061304182612868565b915061304c83612868565b92508261305c5761305b612f22565b5b828204905092915050565b600061307282612868565b915061307d83612868565b925082820261308b81612868565b915082820484148315176130a2576130a1612e53565b5b5092915050565b7f6e6f7420656e6f75676820657468000000000000000000000000000000000000600082015250565b60006130df600e836127c1565b91506130ea826130a9565b602082019050919050565b6000602082019050818103600083015261310e816130d2565b9050919050565b7f6c696d6974206672656520616d6f756e74730000000000000000000000000000600082015250565b600061314b6012836127c1565b915061315682613115565b602082019050919050565b6000602082019050818103600083015261317a8161313e565b9050919050565b7f6c696d6974206672656520706572207478000000000000000000000000000000600082015250565b60006131b76011836127c1565b91506131c282613181565b602082019050919050565b600060208201905081810360008301526131e6816131aa565b9050919050565b7f6e6f7420656e6f7567682066726565206d696e74730000000000000000000000600082015250565b60006132236015836127c1565b915061322e826131ed565b602082019050919050565b6000602082019050818103600083015261325281613216565b9050919050565b7f7472616e73666572206e6f742061637469766500000000000000000000000000600082015250565b600061328f6013836127c1565b915061329a82613259565b602082019050919050565b600060208201905081810360008301526132be81613282565b9050919050565b7f6e6f6e2d6578697374656e742069640000000000000000000000000000000000600082015250565b60006132fb600f836127c1565b9150613306826132c5565b602082019050919050565b6000602082019050818103600083015261332a816132ee565b9050919050565b7f6e6f2073756666696369656e742062616c616e63650000000000000000000000600082015250565b60006133676015836127c1565b915061337282613331565b602082019050919050565b600060208201905081810360008301526133968161335a565b9050919050565b7f6d757374206f776e20746f6b656e000000000000000000000000000000000000600082015250565b60006133d3600e836127c1565b91506133de8261339d565b602082019050919050565b60006020820190508181036000830152613402816133c6565b9050919050565b600061341482612868565b915061341f83612868565b925082820390508181111561343757613436612e53565b5b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006134996026836127c1565b91506134a48261343d565b604082019050919050565b600060208201905081810360008301526134c88161348c565b9050919050565b7f6d696e74696e6720697320636c6f7365642e0000000000000000000000000000600082015250565b60006135056012836127c1565b9150613510826134cf565b602082019050919050565b60006020820190508181036000830152613534816134f8565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006135628261353b565b61356c8185613546565b935061357c8185602086016127d2565b613585816127fc565b840191505092915050565b60006080820190506135a560008301876128fd565b6135b260208301866128fd565b6135bf60408301856129e6565b81810360608301526135d18184613557565b905095945050505050565b6000815190506135eb8161275d565b92915050565b60006020828403121561360757613606612727565b5b6000613615848285016135dc565b91505092915050565b600081905092915050565b7f7b226e616d65223a202257656923000000000000000000000000000000000000600082015250565b600061365f600e8361361e565b915061366a82613629565b600e82019050919050565b6000613680826127b6565b61368a818561361e565b935061369a8185602086016127d2565b80840191505092915050565b7f222c20226465736372697074696f6e223a2022416e206578706572696d656e7460008201527f616c207374616e646172642e204f6e2d636861696e206e667432305f7765692060208201527f746f6b656e2e222c202261747472696275746573223a5b7b2274726169745f7460408201527f797065223a2022546f6b656e4964222c202276616c7565223a20220000000000606082015250565b600061374e607b8361361e565b9150613759826136a6565b607b82019050919050565b7f227d2c7b2274726169745f74797065223a20224e756d626572206f662074726160008201527f6e7366657273206f7574222c202276616c7565223a2022000000000000000000602082015250565b60006137c060378361361e565b91506137cb82613764565b603782019050919050565b7f227d2c7b2274726169745f74797065223a20224e756d626572206f662074726160008201527f6e736665727320696e222c202276616c7565223a202200000000000000000000602082015250565b600061383260368361361e565b915061383d826137d6565b603682019050919050565b7f227d5d2c2022696d616765223a2022646174613a696d6167652f7376672b786d60008201527f6c3b6261736536342c0000000000000000000000000000000000000000000000602082015250565b60006138a460298361361e565b91506138af82613848565b602982019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006138f060028361361e565b91506138fb826138ba565b600282019050919050565b600061391182613652565b915061391d8288613675565b915061392882613741565b91506139348287613675565b915061393f826137b3565b915061394b8286613675565b915061395682613825565b91506139628285613675565b915061396d82613897565b91506139798284613675565b9150613984826138e3565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006139c9601d8361361e565b91506139d482613993565b601d82019050919050565b60006139ea826139bc565b91506139f68284613675565b915081905092915050565b600060ff82169050919050565b6000613a1982613a01565b9150613a2483613a01565b9250828201905060ff811115613a3d57613a3c612e53565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f2671756f743b2c3c2f746578743e20203c7465787420783d2234302220793d2260008201527f3231302220636c6173733d2262617365223e2671756f743b7469636b6574267160208201527f756f743b3a202671756f743b7765692671756f743b2c3c2f746578743e3c746560408201527f787420783d2234302220793d223236302220636c6173733d2262617365223e2660608201527f71756f743b616d742671756f743b3a202671756f743b00000000000000000000608082015250565b6000613b4060968361361e565b9150613b4b82613a72565b609682019050919050565b7f2671756f743b3c2f746578743e3c7465787420783d2232302220793d2233313060008201527f2220636c6173733d2262617365223e7d3c2f746578743e3c2f7376673e000000602082015250565b6000613bb2603d8361361e565b9150613bbd82613b56565b603d82019050919050565b6000613bd48286613675565b9150613be08285613675565b9150613beb82613b33565b9150613bf78284613675565b9150613c0282613ba5565b915081905094935050505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e2e62617365207b2066696c6c3a2077686974653b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20323070783b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d22626c61636b222f3e3c7465787420783d2232302220793d2236302220636c6173733d2262617365223e7b3c2f746578743e3c7465787420783d2234302220793d223131302220636c6173733d2262617365223e2671756f743b702671756f743b3a202671756f743b6e66742d32302671756f743b2c3c2f746578743e3c7465787420783d2234302220793d223136302220636c6173733d2262617365223e2671756f743b69642671756f743b3a202671756f743b4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220accd7a6466e2e7621d9c5cd75425733564f06d92171226835a26afd0cecc91c964736f6c63430008120033

Deployed Bytecode

0x6080604052600436106102045760003560e01c806373f4256111610118578063b88d4fde116100a0578063d5abeb011161006f578063d5abeb01146106f0578063da71573a1461071b578063e985e9c514610732578063f2fde38b1461076f578063f968adbe1461079857610204565b8063b88d4fde14610655578063c87b56dd14610671578063d1239730146106ae578063d2ed5c59146106d957610204565b806395d89b41116100e757806395d89b41146105825780639659867e146105ad578063a035b1fe146105d8578063a22cb46514610603578063b01e88b91461062c57610204565b806373f42561146104d85780637c928fe9146105035780637dc949b21461052c5780638da5cb5b1461055757610204565b80631b2ef1ca1161019b57806342842e0e1161016a57806342842e0e14610400578063475133341461041c5780636352211e1461044757806370a0823114610484578063715018a6146104c157610204565b80631b2ef1ca1461038657806323b872dd146103a257806326a74d8e146103be5780633ccfd60b146103e957610204565b8063095ea7b3116101d7578063095ea7b3146102d957806309681267146102f55780630ff4c9161461031e57806318160ddd1461035b57610204565b806301e7678c1461020957806301ffc9a71461023457806306fdde0314610271578063081812fc1461029c575b600080fd5b34801561021557600080fd5b5061021e6107c3565b60405161022b9190612702565b60405180910390f35b34801561024057600080fd5b5061025b60048036038101906102569190612789565b6107d6565b6040516102689190612702565b60405180910390f35b34801561027d57600080fd5b50610286610868565b6040516102939190612846565b60405180910390f35b3480156102a857600080fd5b506102c360048036038101906102be919061289e565b6108fa565b6040516102d0919061290c565b60405180910390f35b6102f360048036038101906102ee9190612953565b610958565b005b34801561030157600080fd5b5061031c60048036038101906103179190612993565b610968565b005b34801561032a57600080fd5b506103456004803603810190610340919061289e565b610b1e565b60405161035291906129f5565b60405180910390f35b34801561036757600080fd5b50610370610b52565b60405161037d91906129f5565b60405180910390f35b6103a0600480360381019061039b9190612a10565b610b69565b005b6103bc60048036038101906103b79190612a50565b610ce6565b005b3480156103ca57600080fd5b506103d3610fa7565b6040516103e091906129f5565b60405180910390f35b3480156103f557600080fd5b506103fe610fad565b005b61041a60048036038101906104159190612a50565b611069565b005b34801561042857600080fd5b50610431611089565b60405161043e91906129f5565b60405180910390f35b34801561045357600080fd5b5061046e6004803603810190610469919061289e565b61108f565b60405161047b919061290c565b60405180910390f35b34801561049057600080fd5b506104ab60048036038101906104a69190612aa3565b6110a1565b6040516104b891906129f5565b60405180910390f35b3480156104cd57600080fd5b506104d6611138565b005b3480156104e457600080fd5b506104ed6111c0565b6040516104fa91906129f5565b60405180910390f35b34801561050f57600080fd5b5061052a6004803603810190610525919061289e565b6111cf565b005b34801561053857600080fd5b50610541611401565b60405161054e91906129f5565b60405180910390f35b34801561056357600080fd5b5061056c611407565b604051610579919061290c565b60405180910390f35b34801561058e57600080fd5b50610597611431565b6040516105a49190612846565b60405180910390f35b3480156105b957600080fd5b506105c26114c3565b6040516105cf91906129f5565b60405180910390f35b3480156105e457600080fd5b506105ed6114d2565b6040516105fa91906129f5565b60405180910390f35b34801561060f57600080fd5b5061062a60048036038101906106259190612afc565b6114d8565b005b34801561063857600080fd5b50610653600480360381019061064e9190612b3c565b6115e3565b005b61066f600480360381019061066a9190612cc4565b6117fb565b005b34801561067d57600080fd5b506106986004803603810190610693919061289e565b61184d565b6040516106a59190612846565b60405180910390f35b3480156106ba57600080fd5b506106c36118a1565b6040516106d09190612702565b60405180910390f35b3480156106e557600080fd5b506106ee6118b4565b005b3480156106fc57600080fd5b5061070561195c565b60405161071291906129f5565b60405180910390f35b34801561072757600080fd5b50610730611962565b005b34801561073e57600080fd5b5061075960048036038101906107549190612d47565b611a0a565b6040516107669190612702565b60405180910390f35b34801561077b57600080fd5b5061079660048036038101906107919190612aa3565b611a9e565b005b3480156107a457600080fd5b506107ad611b95565b6040516107ba91906129f5565b60405180910390f35b600a60009054906101000a900460ff1681565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061083157506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806108615750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461087790612db6565b80601f01602080910402602001604051908101604052809291908181526020018280546108a390612db6565b80156108f05780601f106108c5576101008083540402835291602001916108f0565b820191906000526020600020905b8154815290600101906020018083116108d357829003601f168201915b5050505050905090565b600061090582611b9b565b61091a5761091963cf4700e460e01b611bfa565b5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b61096482826001611c04565b5050565b610970611d33565b73ffffffffffffffffffffffffffffffffffffffff1661098e611407565b73ffffffffffffffffffffffffffffffffffffffff16146109e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109db90612e33565b60405180910390fd5b6001600b546109f39190612e82565b836109fc610b52565b610a069190612e82565b10610a46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3d90612f02565b60405180910390fd5b60006103e883610a569190612f51565b148015610a635750600082115b8015610a7157506127108211155b610ab0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa790612fce565b60405180910390fd5b6000610aba610b52565b90505b83610ac6610b52565b610ad09190612e82565b811015610b0e578260136000600184610ae99190612e82565b8152602001908152602001600020819055508080610b0690612fee565b915050610abd565b50610b198184611d3b565b505050565b6000610b2982611b9b565b610b365760009050610b4d565b601360008381526020019081526020016000205490505b919050565b6000610b5c611e9e565b6001546000540303905090565b60006103e882610b799190612f51565b148015610b865750600081115b8015610b9457506127108111155b610bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bca90612fce565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610c0b57600080fd5b60006103e882610c1b9190613036565b90508060095484610c2c9190613067565b610c369190613067565b341015610c78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6f906130f5565b60405180910390fd5b6000610c82610b52565b90505b83610c8e610b52565b610c989190612e82565b811015610cd6578260136000600184610cb19190612e82565b8152602001908152602001600020819055508080610cce90612fee565b915050610c85565b50610ce13384611ea7565b505050565b6000610cf182611f66565b905073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff161693508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610d6657610d6563a114810060e01b611bfa565b5b600080610d728461201c565b91509150610d888187610d83612043565b61204b565b610db357610d9d86610d98612043565b611a0a565b610db257610db16359c896be60e01b611bfa565b5b5b610dc0868686600161208f565b8015610dcb57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610e9985610e75888887612095565b7c0200000000000000000000000000000000000000000000000000000000176120bd565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610f1f5760006001850190506000600460008381526020019081526020016000205403610f1d576000548114610f1c578360046000838152602001908152602001600020819055505b5b505b600073ffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff161690508481887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a460008103610f9157610f9063ea553b3460e01b611bfa565b5b610f9e87878760016120e8565b50505050505050565b600c5481565b610fb5611d33565b73ffffffffffffffffffffffffffffffffffffffff16610fd3611407565b73ffffffffffffffffffffffffffffffffffffffff1614611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161102090612e33565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061106757600080fd5b565b611084838383604051806020016040528060008152506117fb565b505050565b600d5481565b600061109a82611f66565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036110e7576110e6638f4eb60460e01b611bfa565b5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b611140611d33565b73ffffffffffffffffffffffffffffffffffffffff1661115e611407565b73ffffffffffffffffffffffffffffffffffffffff16146111b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ab90612e33565b60405180910390fd5b6111be60006120ee565b565b60006111ca6121b4565b905090565b600f5481601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461121d9190612e82565b111561125e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125590613161565b60405180910390fd5b600f548111156112a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129a906131cd565b60405180910390fd5b6001600d546112b29190612e82565b816112bb610b52565b6112c59190612e82565b10611305576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112fc90613239565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff161461133d57600080fd5b6000611347610b52565b90505b81611353610b52565b61135d9190612e82565b81101561139d576103e8601360006001846113789190612e82565b815260200190815260200160002081905550808061139590612fee565b91505061134a565b5080601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113ed9190612e82565b925050819055506113fe3382611ea7565b50565b600f5481565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606003805461144090612db6565b80601f016020809104026020016040519081016040528092919081815260200182805461146c90612db6565b80156114b95780601f1061148e576101008083540402835291602001916114b9565b820191906000526020600020905b81548152906001019060200180831161149c57829003601f168201915b5050505050905090565b60006114cd6121b4565b905090565b60095481565b80600760006114e5612043565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611592612043565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115d79190612702565b60405180910390a35050565b600a60009054906101000a900460ff16611632576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611629906132a5565b60405180910390fd5b61163b83611b9b565b801561164c575061164b82611b9b565b5b61168b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168290613311565b60405180910390fd5b8061169584610b1e565b10156116d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cd9061337d565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166116f68461108f565b73ffffffffffffffffffffffffffffffffffffffff161461174c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611743906133e9565b60405180910390fd5b60016012600085815260200190815260200160002060008282546117709190612e82565b925050819055508060136000858152602001908152602001600020600082825461179a9190613409565b92505081905550806013600084815260200190815260200160002060008282546117c49190612e82565b9250508190555060016012600084815260200190815260200160002060008282546117ef9190612e82565b92505081905550505050565b611806848484610ce6565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461184757611831848484846121c7565b6118465761184563d1a57ed660e01b611bfa565b5b5b50505050565b60606000601360008481526020019081526020016000205490506118998382601160008781526020019081526020016000205460126000888152602001908152602001600020546122f6565b915050919050565b600e60009054906101000a900460ff1681565b6118bc611d33565b73ffffffffffffffffffffffffffffffffffffffff166118da611407565b73ffffffffffffffffffffffffffffffffffffffff1614611930576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192790612e33565b60405180910390fd5b600e60009054906101000a900460ff1615600e60006101000a81548160ff021916908315150217905550565b600b5481565b61196a611d33565b73ffffffffffffffffffffffffffffffffffffffff16611988611407565b73ffffffffffffffffffffffffffffffffffffffff16146119de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d590612e33565b60405180910390fd5b600a60009054906101000a900460ff1615600a60006101000a81548160ff021916908315150217905550565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611aa6611d33565b73ffffffffffffffffffffffffffffffffffffffff16611ac4611407565b73ffffffffffffffffffffffffffffffffffffffff1614611b1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1190612e33565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b80906134af565b60405180910390fd5b611b92816120ee565b50565b60105481565b600081611ba6611e9e565b11158015611bb5575060005482105b8015611bf3575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b8060005260046000fd5b6000611c0f8361108f565b9050818015611c5157508073ffffffffffffffffffffffffffffffffffffffff16611c38612043565b73ffffffffffffffffffffffffffffffffffffffff1614155b15611c7d57611c6781611c62612043565b611a0a565b611c7c57611c7b63cfb3b94260e01b611bfa565b5b5b836006600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a450505050565b600033905090565b60008054905060008203611d5a57611d5963b562e8dd60e01b611bfa565b5b611d67600084838561208f565b611d8783611d786000866000612095565b611d8185612387565b176120bd565b6004600083815260200190815260200160002081905550600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550600073ffffffffffffffffffffffffffffffffffffffff8473ffffffffffffffffffffffffffffffffffffffff1616905060008103611e3f57611e3e632e07630060e01b611bfa565b5b6000838301905060008390505b808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4818160010191508103611e4c5781600081905550505050611e9960008483856120e8565b505050565b60006001905090565b600e60009054906101000a900460ff16611ef6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eed9061351b565b60405180910390fd5b6001600c54611f059190612e82565b81611f0e610b52565b611f189190612e82565b10611f58576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f4f90612f02565b60405180910390fd5b611f628282611d3b565b5050565b600081611f71611e9e565b11612006576004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036120055760008103612000576000548210611fd557611fd463df2d9b4260e01b611bfa565b5b5b60046000836001900393508381526020019081526020016000205490506000810361201757611fd6565b612017565b5b61201663df2d9b4260e01b611bfa565b5b919050565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e86120ac868684612397565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006121be611e9e565b60005403905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026121ed612043565b8786866040518563ffffffff1660e01b815260040161220f9493929190613590565b6020604051808303816000875af192505050801561224b57506040513d601f19601f8201168201806040525081019061224891906135f1565b60015b6122a3573d806000811461227b576040519150601f19603f3d011682016040523d82523d6000602084013e612280565b606091505b50600081510361229b5761229a63d1a57ed660e01b611bfa565b5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b606080612302866123a0565b61230b876123a0565b612314856123a0565b61231d876123a0565b61232f61232a8a8c612528565b612584565b604051602001612343959493929190613906565b604051602081830303815290604052905061235d81612584565b60405160200161236d91906139df565b604051602081830303815290604052915050949350505050565b60006001821460e11b9050919050565b60009392505050565b6060600082036123e7576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612523565b600082905060005b6000821461241957808061240290612fee565b915050600a826124129190613036565b91506123ef565b60008167ffffffffffffffff81111561243557612434612b99565b5b6040519080825280601f01601f1916602001820160405280156124675781602001600182028036833780820191505090505b50905060008290505b6000861461251b576001816124859190613409565b90506000600a80886124979190613036565b6124a19190613067565b876124ac9190613409565b60306124b89190613a0e565b905060008160f81b9050808484815181106124d6576124d5613a43565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a886125129190613036565b97505050612470565b819450505050505b919050565b6060604051806101c001604052806101878152602001613c106101879139905080612552836123a0565b61255b856123a0565b60405160200161256d93929190613bc8565b604051602081830303815290604052905092915050565b606060008251036125a6576040518060200160405280600081525090506126e2565b6000604051806060016040528060408152602001613d9760409139905060006003600285516125d59190612e82565b6125df9190613036565b60046125eb9190613067565b67ffffffffffffffff81111561260457612603612b99565b5b6040519080825280601f01601f1916602001820160405280156126365781602001600182028036833780820191505090505b509050600182016020820185865187015b808210156126a2576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845360018401935050612647565b50506003865106600181146126be57600281146126d1576126d9565b603d6001830353603d60028303536126d9565b603d60018303535b50505080925050505b919050565b60008115159050919050565b6126fc816126e7565b82525050565b600060208201905061271760008301846126f3565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61276681612731565b811461277157600080fd5b50565b6000813590506127838161275d565b92915050565b60006020828403121561279f5761279e612727565b5b60006127ad84828501612774565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156127f05780820151818401526020810190506127d5565b60008484015250505050565b6000601f19601f8301169050919050565b6000612818826127b6565b61282281856127c1565b93506128328185602086016127d2565b61283b816127fc565b840191505092915050565b60006020820190508181036000830152612860818461280d565b905092915050565b6000819050919050565b61287b81612868565b811461288657600080fd5b50565b60008135905061289881612872565b92915050565b6000602082840312156128b4576128b3612727565b5b60006128c284828501612889565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006128f6826128cb565b9050919050565b612906816128eb565b82525050565b600060208201905061292160008301846128fd565b92915050565b612930816128eb565b811461293b57600080fd5b50565b60008135905061294d81612927565b92915050565b6000806040838503121561296a57612969612727565b5b60006129788582860161293e565b925050602061298985828601612889565b9150509250929050565b6000806000606084860312156129ac576129ab612727565b5b60006129ba86828701612889565b93505060206129cb86828701612889565b92505060406129dc8682870161293e565b9150509250925092565b6129ef81612868565b82525050565b6000602082019050612a0a60008301846129e6565b92915050565b60008060408385031215612a2757612a26612727565b5b6000612a3585828601612889565b9250506020612a4685828601612889565b9150509250929050565b600080600060608486031215612a6957612a68612727565b5b6000612a778682870161293e565b9350506020612a888682870161293e565b9250506040612a9986828701612889565b9150509250925092565b600060208284031215612ab957612ab8612727565b5b6000612ac78482850161293e565b91505092915050565b612ad9816126e7565b8114612ae457600080fd5b50565b600081359050612af681612ad0565b92915050565b60008060408385031215612b1357612b12612727565b5b6000612b218582860161293e565b9250506020612b3285828601612ae7565b9150509250929050565b600080600060608486031215612b5557612b54612727565b5b6000612b6386828701612889565b9350506020612b7486828701612889565b9250506040612b8586828701612889565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612bd1826127fc565b810181811067ffffffffffffffff82111715612bf057612bef612b99565b5b80604052505050565b6000612c0361271d565b9050612c0f8282612bc8565b919050565b600067ffffffffffffffff821115612c2f57612c2e612b99565b5b612c38826127fc565b9050602081019050919050565b82818337600083830152505050565b6000612c67612c6284612c14565b612bf9565b905082815260208101848484011115612c8357612c82612b94565b5b612c8e848285612c45565b509392505050565b600082601f830112612cab57612caa612b8f565b5b8135612cbb848260208601612c54565b91505092915050565b60008060008060808587031215612cde57612cdd612727565b5b6000612cec8782880161293e565b9450506020612cfd8782880161293e565b9350506040612d0e87828801612889565b925050606085013567ffffffffffffffff811115612d2f57612d2e61272c565b5b612d3b87828801612c96565b91505092959194509250565b60008060408385031215612d5e57612d5d612727565b5b6000612d6c8582860161293e565b9250506020612d7d8582860161293e565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612dce57607f821691505b602082108103612de157612de0612d87565b5b50919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612e1d6020836127c1565b9150612e2882612de7565b602082019050919050565b60006020820190508181036000830152612e4c81612e10565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612e8d82612868565b9150612e9883612868565b9250828201905080821115612eb057612eaf612e53565b5b92915050565b7f6e6f206d6f7265206c6566740000000000000000000000000000000000000000600082015250565b6000612eec600c836127c1565b9150612ef782612eb6565b602082019050919050565b60006020820190508181036000830152612f1b81612edf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612f5c82612868565b9150612f6783612868565b925082612f7757612f76612f22565b5b828206905092915050565b7f77726f6e6720616d740000000000000000000000000000000000000000000000600082015250565b6000612fb86009836127c1565b9150612fc382612f82565b602082019050919050565b60006020820190508181036000830152612fe781612fab565b9050919050565b6000612ff982612868565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361302b5761302a612e53565b5b600182019050919050565b600061304182612868565b915061304c83612868565b92508261305c5761305b612f22565b5b828204905092915050565b600061307282612868565b915061307d83612868565b925082820261308b81612868565b915082820484148315176130a2576130a1612e53565b5b5092915050565b7f6e6f7420656e6f75676820657468000000000000000000000000000000000000600082015250565b60006130df600e836127c1565b91506130ea826130a9565b602082019050919050565b6000602082019050818103600083015261310e816130d2565b9050919050565b7f6c696d6974206672656520616d6f756e74730000000000000000000000000000600082015250565b600061314b6012836127c1565b915061315682613115565b602082019050919050565b6000602082019050818103600083015261317a8161313e565b9050919050565b7f6c696d6974206672656520706572207478000000000000000000000000000000600082015250565b60006131b76011836127c1565b91506131c282613181565b602082019050919050565b600060208201905081810360008301526131e6816131aa565b9050919050565b7f6e6f7420656e6f7567682066726565206d696e74730000000000000000000000600082015250565b60006132236015836127c1565b915061322e826131ed565b602082019050919050565b6000602082019050818103600083015261325281613216565b9050919050565b7f7472616e73666572206e6f742061637469766500000000000000000000000000600082015250565b600061328f6013836127c1565b915061329a82613259565b602082019050919050565b600060208201905081810360008301526132be81613282565b9050919050565b7f6e6f6e2d6578697374656e742069640000000000000000000000000000000000600082015250565b60006132fb600f836127c1565b9150613306826132c5565b602082019050919050565b6000602082019050818103600083015261332a816132ee565b9050919050565b7f6e6f2073756666696369656e742062616c616e63650000000000000000000000600082015250565b60006133676015836127c1565b915061337282613331565b602082019050919050565b600060208201905081810360008301526133968161335a565b9050919050565b7f6d757374206f776e20746f6b656e000000000000000000000000000000000000600082015250565b60006133d3600e836127c1565b91506133de8261339d565b602082019050919050565b60006020820190508181036000830152613402816133c6565b9050919050565b600061341482612868565b915061341f83612868565b925082820390508181111561343757613436612e53565b5b92915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006134996026836127c1565b91506134a48261343d565b604082019050919050565b600060208201905081810360008301526134c88161348c565b9050919050565b7f6d696e74696e6720697320636c6f7365642e0000000000000000000000000000600082015250565b60006135056012836127c1565b9150613510826134cf565b602082019050919050565b60006020820190508181036000830152613534816134f8565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006135628261353b565b61356c8185613546565b935061357c8185602086016127d2565b613585816127fc565b840191505092915050565b60006080820190506135a560008301876128fd565b6135b260208301866128fd565b6135bf60408301856129e6565b81810360608301526135d18184613557565b905095945050505050565b6000815190506135eb8161275d565b92915050565b60006020828403121561360757613606612727565b5b6000613615848285016135dc565b91505092915050565b600081905092915050565b7f7b226e616d65223a202257656923000000000000000000000000000000000000600082015250565b600061365f600e8361361e565b915061366a82613629565b600e82019050919050565b6000613680826127b6565b61368a818561361e565b935061369a8185602086016127d2565b80840191505092915050565b7f222c20226465736372697074696f6e223a2022416e206578706572696d656e7460008201527f616c207374616e646172642e204f6e2d636861696e206e667432305f7765692060208201527f746f6b656e2e222c202261747472696275746573223a5b7b2274726169745f7460408201527f797065223a2022546f6b656e4964222c202276616c7565223a20220000000000606082015250565b600061374e607b8361361e565b9150613759826136a6565b607b82019050919050565b7f227d2c7b2274726169745f74797065223a20224e756d626572206f662074726160008201527f6e7366657273206f7574222c202276616c7565223a2022000000000000000000602082015250565b60006137c060378361361e565b91506137cb82613764565b603782019050919050565b7f227d2c7b2274726169745f74797065223a20224e756d626572206f662074726160008201527f6e736665727320696e222c202276616c7565223a202200000000000000000000602082015250565b600061383260368361361e565b915061383d826137d6565b603682019050919050565b7f227d5d2c2022696d616765223a2022646174613a696d6167652f7376672b786d60008201527f6c3b6261736536342c0000000000000000000000000000000000000000000000602082015250565b60006138a460298361361e565b91506138af82613848565b602982019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006138f060028361361e565b91506138fb826138ba565b600282019050919050565b600061391182613652565b915061391d8288613675565b915061392882613741565b91506139348287613675565b915061393f826137b3565b915061394b8286613675565b915061395682613825565b91506139628285613675565b915061396d82613897565b91506139798284613675565b9150613984826138e3565b91508190509695505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b60006139c9601d8361361e565b91506139d482613993565b601d82019050919050565b60006139ea826139bc565b91506139f68284613675565b915081905092915050565b600060ff82169050919050565b6000613a1982613a01565b9150613a2483613a01565b9250828201905060ff811115613a3d57613a3c612e53565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f2671756f743b2c3c2f746578743e20203c7465787420783d2234302220793d2260008201527f3231302220636c6173733d2262617365223e2671756f743b7469636b6574267160208201527f756f743b3a202671756f743b7765692671756f743b2c3c2f746578743e3c746560408201527f787420783d2234302220793d223236302220636c6173733d2262617365223e2660608201527f71756f743b616d742671756f743b3a202671756f743b00000000000000000000608082015250565b6000613b4060968361361e565b9150613b4b82613a72565b609682019050919050565b7f2671756f743b3c2f746578743e3c7465787420783d2232302220793d2233313060008201527f2220636c6173733d2262617365223e7d3c2f746578743e3c2f7376673e000000602082015250565b6000613bb2603d8361361e565b9150613bbd82613b56565b603d82019050919050565b6000613bd48286613675565b9150613be08285613675565b9150613beb82613b33565b9150613bf78284613675565b9150613c0282613ba5565b915081905094935050505056fe3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f73766722207072657365727665417370656374526174696f3d22784d696e594d696e206d656574222076696577426f783d223020302033353020333530223e3c7374796c653e2e62617365207b2066696c6c3a2077686974653b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20323070783b207d3c2f7374796c653e3c726563742077696474683d223130302522206865696768743d2231303025222066696c6c3d22626c61636b222f3e3c7465787420783d2232302220793d2236302220636c6173733d2262617365223e7b3c2f746578743e3c7465787420783d2234302220793d223131302220636c6173733d2262617365223e2671756f743b702671756f743b3a202671756f743b6e66742d32302671756f743b2c3c2f746578743e3c7465787420783d2234302220793d223136302220636c6173733d2262617365223e2671756f743b69642671756f743b3a202671756f743b4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220accd7a6466e2e7621d9c5cd75425733564f06d92171226835a26afd0cecc91c964736f6c63430008120033

Deployed Bytecode Sourcemap

81470:4887:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81578:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38527:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39429:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45856:227;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45573:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83443:398;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84324:197;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35171:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82161:454;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49504:3523;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81674:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86236:114;;;;;;;;;;;;;:::i;:::-;;53123:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81732:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40831:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36355:242;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74817:103;;;;;;;;;;;;;:::i;:::-;;86028:85;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82623:561;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81812:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74166:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39605:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85932:88;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81524:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46423:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83853:463;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53914:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;84529:245;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81774:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84891:84;;;;;;;;;;;;;:::i;:::-;;81622:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86121:107;;;;;;;;;;;;;:::i;:::-;;46814:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75075:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81851:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81578:37;;;;;;;;;;;;;:::o;38527:639::-;38612:4;38951:10;38936:25;;:11;:25;;;;:102;;;;39028:10;39013:25;;:11;:25;;;;38936:102;:179;;;;39105:10;39090:25;;:11;:25;;;;38936:179;38916:199;;38527:639;;;:::o;39429:100::-;39483:13;39516:5;39509:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39429:100;:::o;45856:227::-;45932:7;45957:16;45965:7;45957;:16::i;:::-;45952:73;;45975:50;45983:41;;;45975:7;:50::i;:::-;45952:73;46045:15;:24;46061:7;46045:24;;;;;;;;;;;:30;;;;;;;;;;;;46038:37;;45856:227;;;:::o;45573:124::-;45662:27;45671:2;45675:7;45684:4;45662:8;:27::i;:::-;45573:124;;:::o;83443:398::-;74397:12;:10;:12::i;:::-;74386:23;;:7;:5;:7::i;:::-;:23;;;74378:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;83579:1:::1;83567:9;;:13;;;;:::i;:::-;83556:8;83540:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:40;83532:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;83630:1;83622:4;83616:3;:10;;;;:::i;:::-;:15;:26;;;;;83641:1;83635:3;:7;83616:26;:43;;;;;83654:5;83647:3;:12;;83616:43;83608:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;83689:6;83698:13;:11;:13::i;:::-;83689:22;;83684:113;83733:8;83717:13;:11;:13::i;:::-;:24;;;;:::i;:::-;83713:1;:28;83684:113;;;83782:3;83763:9;:16;83777:1;83773;:5;;;;:::i;:::-;83763:16;;;;;;;;;;;:22;;;;83743:3;;;;;:::i;:::-;;;;83684:113;;;;83807:26;83813:9;83824:8;83807:5;:26::i;:::-;83443:398:::0;;;:::o;84324:197::-;84380:4;84402:16;84410:7;84402;:16::i;:::-;84397:116;;84442:1;84435:8;;;;84397:116;84483:9;:18;84493:7;84483:18;;;;;;;;;;;;84476:25;;84324:197;;;;:::o;35171:323::-;35232:7;35460:15;:13;:15::i;:::-;35445:12;;35429:13;;:28;:46;35422:53;;35171:323;:::o;82161:454::-;82248:1;82240:4;82234:3;:10;;;;:::i;:::-;:15;:26;;;;;82259:1;82253:3;:7;82234:26;:43;;;;;82272:5;82265:3;:12;;82234:43;82226:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;82323:10;82310:23;;:9;:23;;;82302:32;;;;;;82345:9;82363:4;82357:3;:10;;;;:::i;:::-;82345:22;;82418:4;82410:5;;82399:8;:16;;;;:::i;:::-;:23;;;;:::i;:::-;82386:9;:36;;82378:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;82457:6;82466:13;:11;:13::i;:::-;82457:22;;82452:113;82501:8;82485:13;:11;:13::i;:::-;:24;;;;:::i;:::-;82481:1;:28;82452:113;;;82550:3;82531:9;:16;82545:1;82541;:5;;;;:::i;:::-;82531:16;;;;;;;;;;;:22;;;;82511:3;;;;;:::i;:::-;;;;82452:113;;;;82575:32;82586:10;82598:8;82575:10;:32::i;:::-;82215:400;82161:454;;:::o;49504:3523::-;49646:27;49676;49695:7;49676:18;:27::i;:::-;49646:57;;31972:14;49847:4;49831:22;;:41;49808:66;;49932:4;49891:45;;49907:19;49891:45;;;49887:95;;49938:44;49946:35;;;49938:7;:44::i;:::-;49887:95;49996:27;50025:23;50052:35;50079:7;50052:26;:35::i;:::-;49995:92;;;;50187:68;50212:15;50229:4;50235:19;:17;:19::i;:::-;50187:24;:68::i;:::-;50182:189;;50275:43;50292:4;50298:19;:17;:19::i;:::-;50275:16;:43::i;:::-;50270:101;;50320:51;50328:42;;;50320:7;:51::i;:::-;50270:101;50182:189;50384:43;50406:4;50412:2;50416:7;50425:1;50384:21;:43::i;:::-;50520:15;50517:160;;;50660:1;50639:19;50632:30;50517:160;51057:18;:24;51076:4;51057:24;;;;;;;;;;;;;;;;51055:26;;;;;;;;;;;;51126:18;:22;51145:2;51126:22;;;;;;;;;;;;;;;;51124:24;;;;;;;;;;;51448:146;51485:2;51534:45;51549:4;51555:2;51559:19;51534:14;:45::i;:::-;31570:8;51506:73;51448:18;:146::i;:::-;51419:17;:26;51437:7;51419:26;;;;;;;;;;;:175;;;;51765:1;31570:8;51714:19;:47;:52;51710:627;;51787:19;51819:1;51809:7;:11;51787:33;;51976:1;51942:17;:30;51960:11;51942:30;;;;;;;;;;;;:35;51938:384;;52080:13;;52065:11;:28;52061:242;;52260:19;52227:17;:30;52245:11;52227:30;;;;;;;;;;;:52;;;;52061:242;51938:384;51768:569;51710:627;52450:16;31972:14;52485:2;52469:20;;:39;52450:58;;52849:7;52813:8;52779:4;52721:25;52666:1;52609;52586:299;52922:1;52910:8;:13;52906:58;;52925:39;52933:30;;;52925:7;:39::i;:::-;52906:58;52977:42;52998:4;53004:2;53008:7;53017:1;52977:20;:42::i;:::-;49635:3392;;;;49504:3523;;;:::o;81674:38::-;;;;:::o;86236:114::-;74397:12;:10;:12::i;:::-;74386:23;;:7;:5;:7::i;:::-;:23;;;74378:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;86302:10:::1;86294:24;;:47;86319:21;86294:47;;;;;;;;;;;;;;;;;;;;;;;86286:56;;;::::0;::::1;;86236:114::o:0;53123:193::-;53269:39;53286:4;53292:2;53296:7;53269:39;;;;;;;;;;;;:16;:39::i;:::-;53123:193;;;:::o;81732:35::-;;;;:::o;40831:152::-;40903:7;40946:27;40965:7;40946:18;:27::i;:::-;40923:52;;40831:152;;;:::o;36355:242::-;36427:7;36468:1;36451:19;;:5;:19;;;36447:69;;36472:44;36480:35;;;36472:7;:44::i;:::-;36447:69;30514:13;36534:18;:25;36553:5;36534:25;;;;;;;;;;;;;;;;:55;36527:62;;36355:242;;;:::o;74817:103::-;74397:12;:10;:12::i;:::-;74386:23;;:7;:5;:7::i;:::-;:23;;;74378:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;74882:30:::1;74909:1;74882:18;:30::i;:::-;74817:103::o:0;86028:85::-;86067:4;86091:14;:12;:14::i;:::-;86084:21;;86028:85;:::o;82623:561::-;82726:12;;82714:8;82682:17;:29;82700:10;82682:29;;;;;;;;;;;;;;;;:40;;;;:::i;:::-;:56;;82674:86;;;;;;;;;;;;:::i;:::-;;;;;;;;;82791:12;;82779:8;:24;;82771:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;82887:1;82871:13;;:17;;;;:::i;:::-;82860:8;82844:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:44;82836:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;82946:10;82933:23;;:9;:23;;;82925:32;;;;;;82973:6;82982:13;:11;:13::i;:::-;82973:22;;82968:114;83017:8;83001:13;:11;:13::i;:::-;:24;;;;:::i;:::-;82997:1;:28;82968:114;;;83066:4;83047:9;:16;83061:1;83057;:5;;;;:::i;:::-;83047:16;;;;;;;;;;;:23;;;;83027:3;;;;;:::i;:::-;;;;82968:114;;;;83125:8;83092:17;:29;83110:10;83092:29;;;;;;;;;;;;;;;;:41;;;;;;;:::i;:::-;;;;;;;;83144:32;83155:10;83167:8;83144:10;:32::i;:::-;82623:561;:::o;81812:31::-;;;;:::o;74166:87::-;74212:7;74239:6;;;;;;;;;;;74232:13;;74166:87;:::o;39605:104::-;39661:13;39694:7;39687:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39605:104;:::o;85932:88::-;85974:4;85998:14;:12;:14::i;:::-;85991:21;;85932:88;:::o;81524:36::-;;;;:::o;46423:234::-;46570:8;46518:18;:39;46537:19;:17;:19::i;:::-;46518:39;;;;;;;;;;;;;;;:49;46558:8;46518:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;46630:8;46594:55;;46609:19;:17;:19::i;:::-;46594:55;;;46640:8;46594:55;;;;;;:::i;:::-;;;;;;;;46423:234;;:::o;83853:463::-;83935:17;;;;;;;;;;;83927:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;83995:13;84003:4;83995:7;:13::i;:::-;:28;;;;;84012:11;84020:2;84012:7;:11::i;:::-;83995:28;83987:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;84079:5;84061:14;84070:4;84061:8;:14::i;:::-;:23;;84053:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;84145:10;84128:27;;:13;84136:4;84128:7;:13::i;:::-;:27;;;84120:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;84207:1;84185:11;:17;84197:4;84185:17;;;;;;;;;;;;:23;;;;;;;:::i;:::-;;;;;;;;84238:5;84219:9;:15;84229:4;84219:15;;;;;;;;;;;;:24;;;;;;;:::i;:::-;;;;;;;;84271:5;84254:9;:13;84264:2;84254:13;;;;;;;;;;;;:22;;;;;;;:::i;:::-;;;;;;;;84307:1;84287:11;:15;84299:2;84287:15;;;;;;;;;;;;:21;;;;;;;:::i;:::-;;;;;;;;83853:463;;;:::o;53914:416::-;54089:31;54102:4;54108:2;54112:7;54089:12;:31::i;:::-;54153:1;54135:2;:14;;;:19;54131:192;;54174:56;54205:4;54211:2;54215:7;54224:5;54174:30;:56::i;:::-;54169:154;;54251:56;54259:47;;;54251:7;:56::i;:::-;54169:154;54131:192;53914:416;;;;:::o;84529:245::-;84621:13;84647:10;84660:9;:18;84670:7;84660:18;;;;;;;;;;;;84647:31;;84696:70;84708:7;84717:5;84724:10;:19;84735:7;84724:19;;;;;;;;;;;;84745:11;:20;84757:7;84745:20;;;;;;;;;;;;84696:11;:70::i;:::-;84689:77;;;84529:245;;;:::o;81774:31::-;;;;;;;;;;;;;:::o;84891:84::-;74397:12;:10;:12::i;:::-;74386:23;;:7;:5;:7::i;:::-;:23;;;74378:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;84956:11:::1;;;;;;;;;;;84955:12;84941:11;;:26;;;;;;;;;;;;;;;;;;84891:84::o:0;81622:32::-;;;;:::o;86121:107::-;74397:12;:10;:12::i;:::-;74386:23;;:7;:5;:7::i;:::-;:23;;;74378:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;86203:17:::1;;;;;;;;;;;86202:18;86182:17;;:38;;;;;;;;;;;;;;;;;;86121:107::o:0;46814:164::-;46911:4;46935:18;:25;46954:5;46935:25;;;;;;;;;;;;;;;:35;46961:8;46935:35;;;;;;;;;;;;;;;;;;;;;;;;;46928:42;;46814:164;;;;:::o;75075:201::-;74397:12;:10;:12::i;:::-;74386:23;;:7;:5;:7::i;:::-;:23;;;74378:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;75184:1:::1;75164:22;;:8;:22;;::::0;75156:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;75240:28;75259:8;75240:18;:28::i;:::-;75075:201:::0;:::o;81851:28::-;;;;:::o;47236:282::-;47301:4;47357:7;47338:15;:13;:15::i;:::-;:26;;:66;;;;;47391:13;;47381:7;:23;47338:66;:153;;;;;47490:1;31290:8;47442:17;:26;47460:7;47442:26;;;;;;;;;;;;:44;:49;47338:153;47318:173;;47236:282;;;:::o;72928:165::-;73029:13;73023:4;73016:27;73070:4;73064;73057:18;64361:474;64490:13;64506:16;64514:7;64506;:16::i;:::-;64490:32;;64539:13;:45;;;;;64579:5;64556:28;;:19;:17;:19::i;:::-;:28;;;;64539:45;64535:201;;;64604:44;64621:5;64628:19;:17;:19::i;:::-;64604:16;:44::i;:::-;64599:137;;64669:51;64677:42;;;64669:7;:51::i;:::-;64599:137;64535:201;64781:2;64748:15;:24;64764:7;64748:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;64819:7;64815:2;64799:28;;64808:5;64799:28;;;;;;;;;;;;64479:356;64361:474;;;:::o;19991:98::-;20044:7;20071:10;20064:17;;19991:98;:::o;57567:2305::-;57640:20;57663:13;;57640:36;;57703:1;57691:8;:13;57687:53;;57706:34;57714:25;;;57706:7;:34::i;:::-;57687:53;57753:61;57783:1;57787:2;57791:12;57805:8;57753:21;:61::i;:::-;58287:139;58324:2;58378:33;58401:1;58405:2;58409:1;58378:14;:33::i;:::-;58345:30;58366:8;58345:20;:30::i;:::-;:66;58287:18;:139::i;:::-;58253:17;:31;58271:12;58253:31;;;;;;;;;;;:173;;;;58713:1;30652:2;58683:1;:26;;58682:32;58670:8;:45;58644:18;:22;58663:2;58644:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;58826:16;31972:14;58861:2;58845:20;;:39;58826:58;;58917:1;58905:8;:13;58901:54;;58920:35;58928:26;;;58920:7;:35::i;:::-;58901:54;58972:11;59001:8;58986:12;:23;58972:37;;59024:15;59042:12;59024:30;;59071:676;59490:7;59446:8;59401:1;59335:25;59272:1;59207;59176:358;59742:3;59729:9;;;;;;:16;59071:676;;59779:3;59763:13;:19;;;;58002:1792;;;59804:60;59833:1;59837:2;59841:12;59855:8;59804:20;:60::i;:::-;57629:2243;57567:2305;;:::o;84782:101::-;84847:7;84874:1;84867:8;;84782:101;:::o;83192:243::-;83274:11;;;;;;;;;;;83266:42;;;;;;;;;;;;:::i;:::-;;;;;;;;;83372:1;83354:15;;:19;;;;:::i;:::-;83343:8;83327:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:46;83319:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;83401:26;83407:9;83418:8;83401:5;:26::i;:::-;83192:243;;:::o;41986:1730::-;42053:14;42103:7;42084:15;:13;:15::i;:::-;:26;42080:1571;;42136:17;:26;42154:7;42136:26;;;;;;;;;;;;42127:35;;42240:1;31290:8;42212:6;:24;:29;42208:1432;;42361:1;42351:6;:11;42347:990;;42402:13;;42391:7;:24;42387:77;;42417:47;42425:38;;;42417:7;:47::i;:::-;42387:77;43061:257;43147:17;:28;43165:9;;;;;;;43147:28;;;;;;;;;;;;43138:37;;43243:1;43233:6;:11;43281:13;43229:25;43061:257;;42347:990;43611:13;;42208:1432;42080:1571;43661:47;43669:38;;;43661:7;:47::i;:::-;41986:1730;;;;:::o;48399:485::-;48501:27;48530:23;48571:38;48612:15;:24;48628:7;48612:24;;;;;;;;;;;48571:65;;48789:18;48766:41;;48846:19;48840:26;48821:45;;48751:126;48399:485;;;:::o;70909:105::-;70969:7;70996:10;70989:17;;70909:105;:::o;47627:659::-;47776:11;47941:16;47934:5;47930:28;47921:37;;48101:16;48090:9;48086:32;48073:45;;48251:15;48240:9;48237:30;48229:5;48218:9;48215:20;48212:56;48202:66;;47627:659;;;;;:::o;54992:159::-;;;;;:::o;70218:311::-;70353:7;70373:16;31694:3;70399:19;:41;;70373:68;;31694:3;70467:31;70478:4;70484:2;70488:9;70467:10;:31::i;:::-;70459:40;;:62;;70452:69;;;70218:311;;;;;:::o;44264:450::-;44344:14;44512:16;44505:5;44501:28;44492:37;;44689:5;44675:11;44650:23;44646:41;44643:52;44636:5;44633:63;44623:73;;44264:450;;;;:::o;55816:158::-;;;;;:::o;75436:191::-;75510:16;75529:6;;;;;;;;;;;75510:25;;75555:8;75546:6;;:17;;;;;;;;;;;;;;;;;;75610:8;75579:40;;75600:8;75579:40;;;;;;;;;;;;75499:128;75436:191;:::o;35592:296::-;35647:7;35854:15;:13;:15::i;:::-;35838:13;;:31;35831:38;;35592:296;:::o;56414:691::-;56577:4;56623:2;56598:45;;;56644:19;:17;:19::i;:::-;56665:4;56671:7;56680:5;56598:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;56594:504;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56898:1;56881:6;:13;:18;56877:115;;56920:56;56928:47;;;56920:7;:56::i;:::-;56877:115;57064:6;57058:13;57049:6;57045:2;57041:15;57034:38;56594:504;56767:54;;;56757:64;;;:6;:64;;;;56750:71;;;56414:691;;;;;;:::o;84983:941::-;85074:13;85100:18;85205:23;85220:7;85205:14;:23::i;:::-;85383;85398:7;85383:14;:23::i;:::-;85493:20;85508:4;85493:14;:20::i;:::-;85599:19;85614:3;85599:14;:19::i;:::-;85691:54;85711:32;85729:5;85735:7;85711:17;:32::i;:::-;85691:13;:54::i;:::-;85143:632;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;85129:647;;85878:26;85898:4;85878:13;:26::i;:::-;85801:114;;;;;;;;:::i;:::-;;;;;;;;;;;;;85787:129;;;84983:941;;;;;;:::o;44816:324::-;44886:14;45119:1;45109:8;45106:15;45080:24;45076:46;45066:56;;44816:324;;;:::o;69919:147::-;70056:6;69919:147;;;;;:::o;79636:593::-;79702:27;79752:1;79746:2;:7;79742:50;;79770:10;;;;;;;;;;;;;;;;;;;;;79742:50;79802:6;79811:2;79802:11;;79824:8;79843:69;79855:1;79850;:6;79843:69;;79873:5;;;;;:::i;:::-;;;;79898:2;79893:7;;;;;:::i;:::-;;;79843:69;;;79922:17;79952:3;79942:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79922:34;;79967:6;79976:3;79967:12;;79990:202;80003:1;79997:2;:7;79990:202;;80029:1;80025;:5;;;;:::i;:::-;80021:9;;80045:10;80087:2;80081;80076;:7;;;;:::i;:::-;80075:14;;;;:::i;:::-;80070:2;:19;;;;:::i;:::-;80059:2;:31;;;;:::i;:::-;80045:46;;80106:9;80125:4;80118:12;;80106:24;;80155:2;80145:4;80150:1;80145:7;;;;;;;;:::i;:::-;;;;;:12;;;;;;;;;;;80178:2;80172:8;;;;;:::i;:::-;;;80006:186;;79990:202;;;80216:4;80202:19;;;;;;79636:593;;;;:::o;80523:914::-;80594:17;80624:399;;;;;;;;;;;;;;;;;;;81083:3;81106:23;81121:7;81106:14;:23::i;:::-;81319:25;81334:9;81319:14;:25::i;:::-;81048:380;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;81034:395;;80523:914;;;;:::o;76125:3097::-;76183:13;76435:1;76420:4;:11;:16;76416:31;;76438:9;;;;;;;;;;;;;;;;76416:31;76500:19;76522:6;;;;;;;;;;;;;;;;;76500:28;;76939:20;76998:1;76993;76979:4;:11;:15;;;;:::i;:::-;76978:21;;;;:::i;:::-;76973:1;:27;;;;:::i;:::-;76962:39;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76939:62;;77181:1;77174:5;77170:13;77285:2;77277:6;77273:15;77396:4;77448;77442:11;77436:4;77432:22;77358:1432;77482:6;77473:7;77470:19;77358:1432;;;77588:1;77579:7;77575:15;77564:26;;77627:7;77621:14;78280:4;78272:5;78268:2;78264:14;78260:25;78250:8;78246:40;78240:47;78229:9;78221:67;78334:1;78323:9;78319:17;78306:30;;78426:4;78418:5;78414:2;78410:14;78406:25;78396:8;78392:40;78386:47;78375:9;78367:67;78480:1;78469:9;78465:17;78452:30;;78571:4;78563:5;78560:1;78556:13;78552:24;78542:8;78538:39;78532:46;78521:9;78513:66;78625:1;78614:9;78610:17;78597:30;;78708:4;78701:5;78697:16;78687:8;78683:31;78677:38;78666:9;78658:58;78762:1;78751:9;78747:17;78734:30;;77509:1281;77358:1432;;;77362:107;;78952:1;78945:4;78939:11;78935:19;78973:1;78968:123;;;;79110:1;79105:73;;;;78928:250;;78968:123;79021:4;79017:1;79006:9;79002:17;78994:32;79071:4;79067:1;79056:9;79052:17;79044:32;78968:123;;79105:73;79158:4;79154:1;79143:9;79139:17;79131:32;78928:250;;77067:2122;;79208:6;79201:13;;;;76125:3097;;;;:::o;7:90:1:-;41:7;84:5;77:13;70:21;59:32;;7:90;;;:::o;103:109::-;184:21;199:5;184:21;:::i;:::-;179:3;172:34;103:109;;:::o;218:210::-;305:4;343:2;332:9;328:18;320:26;;356:65;418:1;407:9;403:17;394:6;356:65;:::i;:::-;218:210;;;;:::o;434:75::-;467:6;500:2;494:9;484:19;;434:75;:::o;515:117::-;624:1;621;614:12;638:117;747:1;744;737:12;761:149;797:7;837:66;830:5;826:78;815:89;;761:149;;;:::o;916:120::-;988:23;1005:5;988:23;:::i;:::-;981:5;978:34;968:62;;1026:1;1023;1016:12;968:62;916:120;:::o;1042:137::-;1087:5;1125:6;1112:20;1103:29;;1141:32;1167:5;1141:32;:::i;:::-;1042:137;;;;:::o;1185:327::-;1243:6;1292:2;1280:9;1271:7;1267:23;1263:32;1260:119;;;1298:79;;:::i;:::-;1260:119;1418:1;1443:52;1487:7;1478:6;1467:9;1463:22;1443:52;:::i;:::-;1433:62;;1389:116;1185:327;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:619::-;4967:6;4975;4983;5032:2;5020:9;5011:7;5007:23;5003:32;5000:119;;;5038:79;;:::i;:::-;5000:119;5158:1;5183:53;5228:7;5219:6;5208:9;5204:22;5183:53;:::i;:::-;5173:63;;5129:117;5285:2;5311:53;5356:7;5347:6;5336:9;5332:22;5311:53;:::i;:::-;5301:63;;5256:118;5413:2;5439:53;5484:7;5475:6;5464:9;5460:22;5439:53;:::i;:::-;5429:63;;5384:118;4890:619;;;;;:::o;5515:118::-;5602:24;5620:5;5602:24;:::i;:::-;5597:3;5590:37;5515:118;;:::o;5639:222::-;5732:4;5770:2;5759:9;5755:18;5747:26;;5783:71;5851:1;5840:9;5836:17;5827:6;5783:71;:::i;:::-;5639:222;;;;:::o;5867:474::-;5935:6;5943;5992:2;5980:9;5971:7;5967:23;5963:32;5960:119;;;5998:79;;:::i;:::-;5960:119;6118:1;6143:53;6188:7;6179:6;6168:9;6164:22;6143:53;:::i;:::-;6133:63;;6089:117;6245:2;6271:53;6316:7;6307:6;6296:9;6292:22;6271:53;:::i;:::-;6261:63;;6216:118;5867:474;;;;;:::o;6347:619::-;6424:6;6432;6440;6489:2;6477:9;6468:7;6464:23;6460:32;6457:119;;;6495:79;;:::i;:::-;6457:119;6615:1;6640:53;6685:7;6676:6;6665:9;6661:22;6640:53;:::i;:::-;6630:63;;6586:117;6742:2;6768:53;6813:7;6804:6;6793:9;6789:22;6768:53;:::i;:::-;6758:63;;6713:118;6870:2;6896:53;6941:7;6932:6;6921:9;6917:22;6896:53;:::i;:::-;6886:63;;6841:118;6347:619;;;;;:::o;6972:329::-;7031:6;7080:2;7068:9;7059:7;7055:23;7051:32;7048:119;;;7086:79;;:::i;:::-;7048:119;7206:1;7231:53;7276:7;7267:6;7256:9;7252:22;7231:53;:::i;:::-;7221:63;;7177:117;6972:329;;;;:::o;7307:116::-;7377:21;7392:5;7377:21;:::i;:::-;7370:5;7367:32;7357:60;;7413:1;7410;7403:12;7357:60;7307:116;:::o;7429:133::-;7472:5;7510:6;7497:20;7488:29;;7526:30;7550:5;7526:30;:::i;:::-;7429:133;;;;:::o;7568:468::-;7633:6;7641;7690:2;7678:9;7669:7;7665:23;7661:32;7658:119;;;7696:79;;:::i;:::-;7658:119;7816:1;7841:53;7886:7;7877:6;7866:9;7862:22;7841:53;:::i;:::-;7831:63;;7787:117;7943:2;7969:50;8011:7;8002:6;7991:9;7987:22;7969:50;:::i;:::-;7959:60;;7914:115;7568:468;;;;;:::o;8042:619::-;8119:6;8127;8135;8184:2;8172:9;8163:7;8159:23;8155:32;8152:119;;;8190:79;;:::i;:::-;8152:119;8310:1;8335:53;8380:7;8371:6;8360:9;8356:22;8335:53;:::i;:::-;8325:63;;8281:117;8437:2;8463:53;8508:7;8499:6;8488:9;8484:22;8463:53;:::i;:::-;8453:63;;8408:118;8565:2;8591:53;8636:7;8627:6;8616:9;8612:22;8591:53;:::i;:::-;8581:63;;8536:118;8042:619;;;;;:::o;8667:117::-;8776:1;8773;8766:12;8790:117;8899:1;8896;8889:12;8913:180;8961:77;8958:1;8951:88;9058:4;9055:1;9048:15;9082:4;9079:1;9072:15;9099:281;9182:27;9204:4;9182:27;:::i;:::-;9174:6;9170:40;9312:6;9300:10;9297:22;9276:18;9264:10;9261:34;9258:62;9255:88;;;9323:18;;:::i;:::-;9255:88;9363:10;9359:2;9352:22;9142:238;9099:281;;:::o;9386:129::-;9420:6;9447:20;;:::i;:::-;9437:30;;9476:33;9504:4;9496:6;9476:33;:::i;:::-;9386:129;;;:::o;9521:307::-;9582:4;9672:18;9664:6;9661:30;9658:56;;;9694:18;;:::i;:::-;9658:56;9732:29;9754:6;9732:29;:::i;:::-;9724:37;;9816:4;9810;9806:15;9798:23;;9521:307;;;:::o;9834:146::-;9931:6;9926:3;9921;9908:30;9972:1;9963:6;9958:3;9954:16;9947:27;9834:146;;;:::o;9986:423::-;10063:5;10088:65;10104:48;10145:6;10104:48;:::i;:::-;10088:65;:::i;:::-;10079:74;;10176:6;10169:5;10162:21;10214:4;10207:5;10203:16;10252:3;10243:6;10238:3;10234:16;10231:25;10228:112;;;10259:79;;:::i;:::-;10228:112;10349:54;10396:6;10391:3;10386;10349:54;:::i;:::-;10069:340;9986:423;;;;;:::o;10428:338::-;10483:5;10532:3;10525:4;10517:6;10513:17;10509:27;10499:122;;10540:79;;:::i;:::-;10499:122;10657:6;10644:20;10682:78;10756:3;10748:6;10741:4;10733:6;10729:17;10682:78;:::i;:::-;10673:87;;10489:277;10428:338;;;;:::o;10772:943::-;10867:6;10875;10883;10891;10940:3;10928:9;10919:7;10915:23;10911:33;10908:120;;;10947:79;;:::i;:::-;10908:120;11067:1;11092:53;11137:7;11128:6;11117:9;11113:22;11092:53;:::i;:::-;11082:63;;11038:117;11194:2;11220:53;11265:7;11256:6;11245:9;11241:22;11220:53;:::i;:::-;11210:63;;11165:118;11322:2;11348:53;11393:7;11384:6;11373:9;11369:22;11348:53;:::i;:::-;11338:63;;11293:118;11478:2;11467:9;11463:18;11450:32;11509:18;11501:6;11498:30;11495:117;;;11531:79;;:::i;:::-;11495:117;11636:62;11690:7;11681:6;11670:9;11666:22;11636:62;:::i;:::-;11626:72;;11421:287;10772:943;;;;;;;:::o;11721:474::-;11789:6;11797;11846:2;11834:9;11825:7;11821:23;11817:32;11814:119;;;11852:79;;:::i;:::-;11814:119;11972:1;11997:53;12042:7;12033:6;12022:9;12018:22;11997:53;:::i;:::-;11987:63;;11943:117;12099:2;12125:53;12170:7;12161:6;12150:9;12146:22;12125:53;:::i;:::-;12115:63;;12070:118;11721:474;;;;;:::o;12201:180::-;12249:77;12246:1;12239:88;12346:4;12343:1;12336:15;12370:4;12367:1;12360:15;12387:320;12431:6;12468:1;12462:4;12458:12;12448:22;;12515:1;12509:4;12505:12;12536:18;12526:81;;12592:4;12584:6;12580:17;12570:27;;12526:81;12654:2;12646:6;12643:14;12623:18;12620:38;12617:84;;12673:18;;:::i;:::-;12617:84;12438:269;12387:320;;;:::o;12713:182::-;12853:34;12849:1;12841:6;12837:14;12830:58;12713:182;:::o;12901:366::-;13043:3;13064:67;13128:2;13123:3;13064:67;:::i;:::-;13057:74;;13140:93;13229:3;13140:93;:::i;:::-;13258:2;13253:3;13249:12;13242:19;;12901:366;;;:::o;13273:419::-;13439:4;13477:2;13466:9;13462:18;13454:26;;13526:9;13520:4;13516:20;13512:1;13501:9;13497:17;13490:47;13554:131;13680:4;13554:131;:::i;:::-;13546:139;;13273:419;;;:::o;13698:180::-;13746:77;13743:1;13736:88;13843:4;13840:1;13833:15;13867:4;13864:1;13857:15;13884:191;13924:3;13943:20;13961:1;13943:20;:::i;:::-;13938:25;;13977:20;13995:1;13977:20;:::i;:::-;13972:25;;14020:1;14017;14013:9;14006:16;;14041:3;14038:1;14035:10;14032:36;;;14048:18;;:::i;:::-;14032:36;13884:191;;;;:::o;14081:162::-;14221:14;14217:1;14209:6;14205:14;14198:38;14081:162;:::o;14249:366::-;14391:3;14412:67;14476:2;14471:3;14412:67;:::i;:::-;14405:74;;14488:93;14577:3;14488:93;:::i;:::-;14606:2;14601:3;14597:12;14590:19;;14249:366;;;:::o;14621:419::-;14787:4;14825:2;14814:9;14810:18;14802:26;;14874:9;14868:4;14864:20;14860:1;14849:9;14845:17;14838:47;14902:131;15028:4;14902:131;:::i;:::-;14894:139;;14621:419;;;:::o;15046:180::-;15094:77;15091:1;15084:88;15191:4;15188:1;15181:15;15215:4;15212:1;15205:15;15232:176;15264:1;15281:20;15299:1;15281:20;:::i;:::-;15276:25;;15315:20;15333:1;15315:20;:::i;:::-;15310:25;;15354:1;15344:35;;15359:18;;:::i;:::-;15344:35;15400:1;15397;15393:9;15388:14;;15232:176;;;;:::o;15414:159::-;15554:11;15550:1;15542:6;15538:14;15531:35;15414:159;:::o;15579:365::-;15721:3;15742:66;15806:1;15801:3;15742:66;:::i;:::-;15735:73;;15817:93;15906:3;15817:93;:::i;:::-;15935:2;15930:3;15926:12;15919:19;;15579:365;;;:::o;15950:419::-;16116:4;16154:2;16143:9;16139:18;16131:26;;16203:9;16197:4;16193:20;16189:1;16178:9;16174:17;16167:47;16231:131;16357:4;16231:131;:::i;:::-;16223:139;;15950:419;;;:::o;16375:233::-;16414:3;16437:24;16455:5;16437:24;:::i;:::-;16428:33;;16483:66;16476:5;16473:77;16470:103;;16553:18;;:::i;:::-;16470:103;16600:1;16593:5;16589:13;16582:20;;16375:233;;;:::o;16614:185::-;16654:1;16671:20;16689:1;16671:20;:::i;:::-;16666:25;;16705:20;16723:1;16705:20;:::i;:::-;16700:25;;16744:1;16734:35;;16749:18;;:::i;:::-;16734:35;16791:1;16788;16784:9;16779:14;;16614:185;;;;:::o;16805:410::-;16845:7;16868:20;16886:1;16868:20;:::i;:::-;16863:25;;16902:20;16920:1;16902:20;:::i;:::-;16897:25;;16957:1;16954;16950:9;16979:30;16997:11;16979:30;:::i;:::-;16968:41;;17158:1;17149:7;17145:15;17142:1;17139:22;17119:1;17112:9;17092:83;17069:139;;17188:18;;:::i;:::-;17069:139;16853:362;16805:410;;;;:::o;17221:164::-;17361:16;17357:1;17349:6;17345:14;17338:40;17221:164;:::o;17391:366::-;17533:3;17554:67;17618:2;17613:3;17554:67;:::i;:::-;17547:74;;17630:93;17719:3;17630:93;:::i;:::-;17748:2;17743:3;17739:12;17732:19;;17391:366;;;:::o;17763:419::-;17929:4;17967:2;17956:9;17952:18;17944:26;;18016:9;18010:4;18006:20;18002:1;17991:9;17987:17;17980:47;18044:131;18170:4;18044:131;:::i;:::-;18036:139;;17763:419;;;:::o;18188:168::-;18328:20;18324:1;18316:6;18312:14;18305:44;18188:168;:::o;18362:366::-;18504:3;18525:67;18589:2;18584:3;18525:67;:::i;:::-;18518:74;;18601:93;18690:3;18601:93;:::i;:::-;18719:2;18714:3;18710:12;18703:19;;18362:366;;;:::o;18734:419::-;18900:4;18938:2;18927:9;18923:18;18915:26;;18987:9;18981:4;18977:20;18973:1;18962:9;18958:17;18951:47;19015:131;19141:4;19015:131;:::i;:::-;19007:139;;18734:419;;;:::o;19159:167::-;19299:19;19295:1;19287:6;19283:14;19276:43;19159:167;:::o;19332:366::-;19474:3;19495:67;19559:2;19554:3;19495:67;:::i;:::-;19488:74;;19571:93;19660:3;19571:93;:::i;:::-;19689:2;19684:3;19680:12;19673:19;;19332:366;;;:::o;19704:419::-;19870:4;19908:2;19897:9;19893:18;19885:26;;19957:9;19951:4;19947:20;19943:1;19932:9;19928:17;19921:47;19985:131;20111:4;19985:131;:::i;:::-;19977:139;;19704:419;;;:::o;20129:171::-;20269:23;20265:1;20257:6;20253:14;20246:47;20129:171;:::o;20306:366::-;20448:3;20469:67;20533:2;20528:3;20469:67;:::i;:::-;20462:74;;20545:93;20634:3;20545:93;:::i;:::-;20663:2;20658:3;20654:12;20647:19;;20306:366;;;:::o;20678:419::-;20844:4;20882:2;20871:9;20867:18;20859:26;;20931:9;20925:4;20921:20;20917:1;20906:9;20902:17;20895:47;20959:131;21085:4;20959:131;:::i;:::-;20951:139;;20678:419;;;:::o;21103:169::-;21243:21;21239:1;21231:6;21227:14;21220:45;21103:169;:::o;21278:366::-;21420:3;21441:67;21505:2;21500:3;21441:67;:::i;:::-;21434:74;;21517:93;21606:3;21517:93;:::i;:::-;21635:2;21630:3;21626:12;21619:19;;21278:366;;;:::o;21650:419::-;21816:4;21854:2;21843:9;21839:18;21831:26;;21903:9;21897:4;21893:20;21889:1;21878:9;21874:17;21867:47;21931:131;22057:4;21931:131;:::i;:::-;21923:139;;21650:419;;;:::o;22075:165::-;22215:17;22211:1;22203:6;22199:14;22192:41;22075:165;:::o;22246:366::-;22388:3;22409:67;22473:2;22468:3;22409:67;:::i;:::-;22402:74;;22485:93;22574:3;22485:93;:::i;:::-;22603:2;22598:3;22594:12;22587:19;;22246:366;;;:::o;22618:419::-;22784:4;22822:2;22811:9;22807:18;22799:26;;22871:9;22865:4;22861:20;22857:1;22846:9;22842:17;22835:47;22899:131;23025:4;22899:131;:::i;:::-;22891:139;;22618:419;;;:::o;23043:171::-;23183:23;23179:1;23171:6;23167:14;23160:47;23043:171;:::o;23220:366::-;23362:3;23383:67;23447:2;23442:3;23383:67;:::i;:::-;23376:74;;23459:93;23548:3;23459:93;:::i;:::-;23577:2;23572:3;23568:12;23561:19;;23220:366;;;:::o;23592:419::-;23758:4;23796:2;23785:9;23781:18;23773:26;;23845:9;23839:4;23835:20;23831:1;23820:9;23816:17;23809:47;23873:131;23999:4;23873:131;:::i;:::-;23865:139;;23592:419;;;:::o;24017:164::-;24157:16;24153:1;24145:6;24141:14;24134:40;24017:164;:::o;24187:366::-;24329:3;24350:67;24414:2;24409:3;24350:67;:::i;:::-;24343:74;;24426:93;24515:3;24426:93;:::i;:::-;24544:2;24539:3;24535:12;24528:19;;24187:366;;;:::o;24559:419::-;24725:4;24763:2;24752:9;24748:18;24740:26;;24812:9;24806:4;24802:20;24798:1;24787:9;24783:17;24776:47;24840:131;24966:4;24840:131;:::i;:::-;24832:139;;24559:419;;;:::o;24984:194::-;25024:4;25044:20;25062:1;25044:20;:::i;:::-;25039:25;;25078:20;25096:1;25078:20;:::i;:::-;25073:25;;25122:1;25119;25115:9;25107:17;;25146:1;25140:4;25137:11;25134:37;;;25151:18;;:::i;:::-;25134:37;24984:194;;;;:::o;25184:225::-;25324:34;25320:1;25312:6;25308:14;25301:58;25393:8;25388:2;25380:6;25376:15;25369:33;25184:225;:::o;25415:366::-;25557:3;25578:67;25642:2;25637:3;25578:67;:::i;:::-;25571:74;;25654:93;25743:3;25654:93;:::i;:::-;25772:2;25767:3;25763:12;25756:19;;25415:366;;;:::o;25787:419::-;25953:4;25991:2;25980:9;25976:18;25968:26;;26040:9;26034:4;26030:20;26026:1;26015:9;26011:17;26004:47;26068:131;26194:4;26068:131;:::i;:::-;26060:139;;25787:419;;;:::o;26212:168::-;26352:20;26348:1;26340:6;26336:14;26329:44;26212:168;:::o;26386:366::-;26528:3;26549:67;26613:2;26608:3;26549:67;:::i;:::-;26542:74;;26625:93;26714:3;26625:93;:::i;:::-;26743:2;26738:3;26734:12;26727:19;;26386:366;;;:::o;26758:419::-;26924:4;26962:2;26951:9;26947:18;26939:26;;27011:9;27005:4;27001:20;26997:1;26986:9;26982:17;26975:47;27039:131;27165:4;27039:131;:::i;:::-;27031:139;;26758:419;;;:::o;27183:98::-;27234:6;27268:5;27262:12;27252:22;;27183:98;;;:::o;27287:168::-;27370:11;27404:6;27399:3;27392:19;27444:4;27439:3;27435:14;27420:29;;27287:168;;;;:::o;27461:373::-;27547:3;27575:38;27607:5;27575:38;:::i;:::-;27629:70;27692:6;27687:3;27629:70;:::i;:::-;27622:77;;27708:65;27766:6;27761:3;27754:4;27747:5;27743:16;27708:65;:::i;:::-;27798:29;27820:6;27798:29;:::i;:::-;27793:3;27789:39;27782:46;;27551:283;27461:373;;;;:::o;27840:640::-;28035:4;28073:3;28062:9;28058:19;28050:27;;28087:71;28155:1;28144:9;28140:17;28131:6;28087:71;:::i;:::-;28168:72;28236:2;28225:9;28221:18;28212:6;28168:72;:::i;:::-;28250;28318:2;28307:9;28303:18;28294:6;28250:72;:::i;:::-;28369:9;28363:4;28359:20;28354:2;28343:9;28339:18;28332:48;28397:76;28468:4;28459:6;28397:76;:::i;:::-;28389:84;;27840:640;;;;;;;:::o;28486:141::-;28542:5;28573:6;28567:13;28558:22;;28589:32;28615:5;28589:32;:::i;:::-;28486:141;;;;:::o;28633:349::-;28702:6;28751:2;28739:9;28730:7;28726:23;28722:32;28719:119;;;28757:79;;:::i;:::-;28719:119;28877:1;28902:63;28957:7;28948:6;28937:9;28933:22;28902:63;:::i;:::-;28892:73;;28848:127;28633:349;;;;:::o;28988:148::-;29090:11;29127:3;29112:18;;28988:148;;;;:::o;29142:214::-;29282:66;29278:1;29270:6;29266:14;29259:90;29142:214;:::o;29362:402::-;29522:3;29543:85;29625:2;29620:3;29543:85;:::i;:::-;29536:92;;29637:93;29726:3;29637:93;:::i;:::-;29755:2;29750:3;29746:12;29739:19;;29362:402;;;:::o;29770:390::-;29876:3;29904:39;29937:5;29904:39;:::i;:::-;29959:89;30041:6;30036:3;29959:89;:::i;:::-;29952:96;;30057:65;30115:6;30110:3;30103:4;30096:5;30092:16;30057:65;:::i;:::-;30147:6;30142:3;30138:16;30131:23;;29880:280;29770:390;;;;:::o;30166:485::-;30306:66;30302:1;30294:6;30290:14;30283:90;30407:34;30402:2;30394:6;30390:15;30383:59;30476:66;30471:2;30463:6;30459:15;30452:91;30577:66;30572:2;30564:6;30560:15;30553:91;30166:485;:::o;30657:404::-;30817:3;30838:86;30920:3;30915;30838:86;:::i;:::-;30831:93;;30933;31022:3;30933:93;:::i;:::-;31051:3;31046;31042:13;31035:20;;30657:404;;;:::o;31067:315::-;31207:66;31203:1;31195:6;31191:14;31184:90;31308:66;31303:2;31295:6;31291:15;31284:91;31067:315;:::o;31388:402::-;31548:3;31569:85;31651:2;31646:3;31569:85;:::i;:::-;31562:92;;31663:93;31752:3;31663:93;:::i;:::-;31781:2;31776:3;31772:12;31765:19;;31388:402;;;:::o;31796:315::-;31936:66;31932:1;31924:6;31920:14;31913:90;32037:66;32032:2;32024:6;32020:15;32013:91;31796:315;:::o;32117:402::-;32277:3;32298:85;32380:2;32375:3;32298:85;:::i;:::-;32291:92;;32392:93;32481:3;32392:93;:::i;:::-;32510:2;32505:3;32501:12;32494:19;;32117:402;;;:::o;32525:260::-;32665:66;32661:1;32653:6;32649:14;32642:90;32766:11;32761:2;32753:6;32749:15;32742:36;32525:260;:::o;32791:402::-;32951:3;32972:85;33054:2;33049:3;32972:85;:::i;:::-;32965:92;;33066:93;33155:3;33066:93;:::i;:::-;33184:2;33179:3;33175:12;33168:19;;32791:402;;;:::o;33199:214::-;33339:66;33335:1;33327:6;33323:14;33316:90;33199:214;:::o;33419:400::-;33579:3;33600:84;33682:1;33677:3;33600:84;:::i;:::-;33593:91;;33693:93;33782:3;33693:93;:::i;:::-;33811:1;33806:3;33802:11;33795:18;;33419:400;;;:::o;33825:2511::-;34755:3;34777:148;34921:3;34777:148;:::i;:::-;34770:155;;34942:95;35033:3;35024:6;34942:95;:::i;:::-;34935:102;;35054:148;35198:3;35054:148;:::i;:::-;35047:155;;35219:95;35310:3;35301:6;35219:95;:::i;:::-;35212:102;;35331:148;35475:3;35331:148;:::i;:::-;35324:155;;35496:95;35587:3;35578:6;35496:95;:::i;:::-;35489:102;;35608:148;35752:3;35608:148;:::i;:::-;35601:155;;35773:95;35864:3;35855:6;35773:95;:::i;:::-;35766:102;;35885:148;36029:3;35885:148;:::i;:::-;35878:155;;36050:95;36141:3;36132:6;36050:95;:::i;:::-;36043:102;;36162:148;36306:3;36162:148;:::i;:::-;36155:155;;36327:3;36320:10;;33825:2511;;;;;;;;:::o;36342:179::-;36482:31;36478:1;36470:6;36466:14;36459:55;36342:179;:::o;36527:402::-;36687:3;36708:85;36790:2;36785:3;36708:85;:::i;:::-;36701:92;;36802:93;36891:3;36802:93;:::i;:::-;36920:2;36915:3;36911:12;36904:19;;36527:402;;;:::o;36935:541::-;37168:3;37190:148;37334:3;37190:148;:::i;:::-;37183:155;;37355:95;37446:3;37437:6;37355:95;:::i;:::-;37348:102;;37467:3;37460:10;;36935:541;;;;:::o;37482:86::-;37517:7;37557:4;37550:5;37546:16;37535:27;;37482:86;;;:::o;37574:188::-;37612:3;37631:18;37647:1;37631:18;:::i;:::-;37626:23;;37663:18;37679:1;37663:18;:::i;:::-;37658:23;;37704:1;37701;37697:9;37690:16;;37727:4;37722:3;37719:13;37716:39;;;37735:18;;:::i;:::-;37716:39;37574:188;;;;:::o;37768:180::-;37816:77;37813:1;37806:88;37913:4;37910:1;37903:15;37937:4;37934:1;37927:15;37954:545;38094:66;38090:1;38082:6;38078:14;38071:90;38195:66;38190:2;38182:6;38178:15;38171:91;38296:34;38291:2;38283:6;38279:15;38272:59;38365:66;38360:2;38352:6;38348:15;38341:91;38467:24;38461:3;38453:6;38449:16;38442:50;37954:545;:::o;38505:404::-;38665:3;38686:86;38768:3;38763;38686:86;:::i;:::-;38679:93;;38781;38870:3;38781:93;:::i;:::-;38899:3;38894;38890:13;38883:20;;38505:404;;;:::o;38915:315::-;39055:66;39051:1;39043:6;39039:14;39032:90;39156:66;39151:2;39143:6;39139:15;39132:91;38915:315;:::o;39236:402::-;39396:3;39417:85;39499:2;39494:3;39417:85;:::i;:::-;39410:92;;39511:93;39600:3;39511:93;:::i;:::-;39629:2;39624:3;39620:12;39613:19;;39236:402;;;:::o;39644:1127::-;40074:3;40096:95;40187:3;40178:6;40096:95;:::i;:::-;40089:102;;40208:95;40299:3;40290:6;40208:95;:::i;:::-;40201:102;;40320:148;40464:3;40320:148;:::i;:::-;40313:155;;40485:95;40576:3;40567:6;40485:95;:::i;:::-;40478:102;;40597:148;40741:3;40597:148;:::i;:::-;40590:155;;40762:3;40755:10;;39644:1127;;;;;;:::o

Swarm Source

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