{"sources":{"Wispuff.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\n// File: @openzeppelin/contracts/utils/introspection/IERC165.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/IERC721.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\n\n\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\n     *   {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\n     *   a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the address zero.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)\n\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be\n     * reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\n\n\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n\n// File: @openzeppelin/contracts/utils/Context.sol\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n\n// File: @openzeppelin/contracts/utils/math/Math.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\n\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Muldiv operation overflow.\n     */\n    error MathOverflowedMulDiv();\n\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            return a / b;\n        }\n\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                revert MathOverflowedMulDiv();\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n\n// File: @openzeppelin/contracts/utils/math/SignedMath.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)\n\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n\n// File: @openzeppelin/contracts/utils/Strings.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)\n\n\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant HEX_DIGITS = \"0123456789abcdef\";\n    uint8 private constant ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev The `value` string doesn't fit in the specified `length`.\n     */\n    error StringsInsufficientHexLength(uint256 value, uint256 length);\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toStringSigned(int256 value) internal pure returns (string memory) {\n        return string.concat(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value)));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        uint256 localValue = value;\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = HEX_DIGITS[localValue & 0xf];\n            localValue >>= 4;\n        }\n        if (localValue != 0) {\n            revert StringsInsufficientHexLength(value, length);\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal\n     * representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n\n// File: @openzeppelin/contracts/utils/introspection/ERC165.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\n\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n\n// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n\n// File: @openzeppelin/contracts/token/ERC721/ERC721.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)\n\n\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\nabstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {\n    using Strings for uint256;\n\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    mapping(uint256 tokenId => address) private _owners;\n\n    mapping(address owner => uint256) private _balances;\n\n    mapping(uint256 tokenId => address) private _tokenApprovals;\n\n    mapping(address owner => mapping(address operator => bool)) private _operatorApprovals;\n\n    /**\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return\n            interfaceId == type(IERC721).interfaceId ||\n            interfaceId == type(IERC721Metadata).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */\n    function balanceOf(address owner) public view virtual returns (uint256) {\n        if (owner == address(0)) {\n            revert ERC721InvalidOwner(address(0));\n        }\n        return _balances[owner];\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual returns (address) {\n        return _requireOwned(tokenId);\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual returns (string memory) {\n        _requireOwned(tokenId);\n\n        string memory baseURI = _baseURI();\n        return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : \"\";\n    }\n\n    /**\n     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n     * by default, can be overridden in child contracts.\n     */\n    function _baseURI() internal view virtual returns (string memory) {\n        return \"\";\n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */\n    function approve(address to, uint256 tokenId) public virtual {\n        _approve(to, tokenId, _msgSender());\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */\n    function getApproved(uint256 tokenId) public view virtual returns (address) {\n        _requireOwned(tokenId);\n\n        return _getApproved(tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual {\n        _setApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */\n    function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public virtual {\n        if (to == address(0)) {\n            revert ERC721InvalidReceiver(address(0));\n        }\n        // Setting an \"auth\" arguments enables the `_isAuthorized` check which verifies that the token exists\n        // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.\n        address previousOwner = _update(to, tokenId, _msgSender());\n        if (previousOwner != from) {\n            revert ERC721IncorrectOwner(from, tokenId, previousOwner);\n        }\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {\n        transferFrom(from, to, tokenId);\n        _checkOnERC721Received(from, to, tokenId, data);\n    }\n\n    /**\n     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n     *\n     * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the\n     * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances\n     * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by\n     * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.\n     */\n    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n        return _owners[tokenId];\n    }\n\n    /**\n     * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.\n     */\n    function _getApproved(uint256 tokenId) internal view virtual returns (address) {\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in\n     * particular (ignoring whether it is owned by `owner`).\n     *\n     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\n     * assumption.\n     */\n    function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {\n        return\n            spender != address(0) &&\n            (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);\n    }\n\n    /**\n     * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.\n     * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets\n     * the `spender` for the specific `tokenId`.\n     *\n     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\n     * assumption.\n     */\n    function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {\n        if (!_isAuthorized(owner, spender, tokenId)) {\n            if (owner == address(0)) {\n                revert ERC721NonexistentToken(tokenId);\n            } else {\n                revert ERC721InsufficientApproval(spender, tokenId);\n            }\n        }\n    }\n\n    /**\n     * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n     *\n     * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that\n     * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.\n     *\n     * WARNING: Increasing an account's balance using this function tends to be paired with an override of the\n     * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership\n     * remain consistent with one another.\n     */\n    function _increaseBalance(address account, uint128 value) internal virtual {\n        unchecked {\n            _balances[account] += value;\n        }\n    }\n\n    /**\n     * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner\n     * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.\n     *\n     * The `auth` argument is optional. If the value passed is non 0, then this function will check that\n     * `auth` is either the owner of the token, or approved to operate on the token (by the owner).\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.\n     */\n    function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {\n        address from = _ownerOf(tokenId);\n\n        // Perform (optional) operator check\n        if (auth != address(0)) {\n            _checkAuthorized(from, auth, tokenId);\n        }\n\n        // Execute the update\n        if (from != address(0)) {\n            // Clear approval. No need to re-authorize or emit the Approval event\n            _approve(address(0), tokenId, address(0), false);\n\n            unchecked {\n                _balances[from] -= 1;\n            }\n        }\n\n        if (to != address(0)) {\n            unchecked {\n                _balances[to] += 1;\n            }\n        }\n\n        _owners[tokenId] = to;\n\n        emit Transfer(from, to, tokenId);\n\n        return from;\n    }\n\n    /**\n     * @dev Mints `tokenId` and transfers it to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - `to` cannot be the zero address.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _mint(address to, uint256 tokenId) internal {\n        if (to == address(0)) {\n            revert ERC721InvalidReceiver(address(0));\n        }\n        address previousOwner = _update(to, tokenId, address(0));\n        if (previousOwner != address(0)) {\n            revert ERC721InvalidSender(address(0));\n        }\n    }\n\n    /**\n     * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeMint(address to, uint256 tokenId) internal {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n        _mint(to, tokenId);\n        _checkOnERC721Received(address(0), to, tokenId, data);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     * This is an internal function that does not check if the sender is authorized to operate on the token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal {\n        address previousOwner = _update(address(0), tokenId, address(0));\n        if (previousOwner == address(0)) {\n            revert ERC721NonexistentToken(tokenId);\n        }\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 tokenId) internal {\n        if (to == address(0)) {\n            revert ERC721InvalidReceiver(address(0));\n        }\n        address previousOwner = _update(to, tokenId, address(0));\n        if (previousOwner == address(0)) {\n            revert ERC721NonexistentToken(tokenId);\n        } else if (previousOwner != from) {\n            revert ERC721IncorrectOwner(from, tokenId, previousOwner);\n        }\n    }\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients\n     * are aware of the ERC721 standard to prevent tokens from being forever locked.\n     *\n     * `data` is additional data, it has no specified format and it is sent in call to `to`.\n     *\n     * This internal function is like {safeTransferFrom} in the sense that it invokes\n     * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\n     *\n     * Requirements:\n     *\n     * - `tokenId` token must exist and be owned by `from`.\n     * - `to` cannot be the zero address.\n     * - `from` cannot be the zero address.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId) internal {\n        _safeTransfer(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n        _transfer(from, to, tokenId);\n        _checkOnERC721Received(from, to, tokenId, data);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is\n     * either the owner of the token, or approved to operate on all tokens held by this owner.\n     *\n     * Emits an {Approval} event.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address to, uint256 tokenId, address auth) internal {\n        _approve(to, tokenId, auth, true);\n    }\n\n    /**\n     * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not\n     * emitted in the context of transfers.\n     */\n    function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {\n        // Avoid reading the owner unless necessary\n        if (emitEvent || auth != address(0)) {\n            address owner = _requireOwned(tokenId);\n\n            // We do not use _isAuthorized because single-token approvals should not be able to call approve\n            if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {\n                revert ERC721InvalidApprover(auth);\n            }\n\n            if (emitEvent) {\n                emit Approval(owner, to, tokenId);\n            }\n        }\n\n        _tokenApprovals[tokenId] = to;\n    }\n\n    /**\n     * @dev Approve `operator` to operate on all of `owner` tokens\n     *\n     * Requirements:\n     * - operator can't be the address zero.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n        if (operator == address(0)) {\n            revert ERC721InvalidOperator(operator);\n        }\n        _operatorApprovals[owner][operator] = approved;\n        emit ApprovalForAll(owner, operator, approved);\n    }\n\n    /**\n     * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).\n     * Returns the owner.\n     *\n     * Overrides to ownership logic should be done to {_ownerOf}.\n     */\n    function _requireOwned(uint256 tokenId) internal view returns (address) {\n        address owner = _ownerOf(tokenId);\n        if (owner == address(0)) {\n            revert ERC721NonexistentToken(tokenId);\n        }\n        return owner;\n    }\n\n    /**\n     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the\n     * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param data bytes optional data to send along with the call\n     */\n    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {\n        if (to.code.length > 0) {\n            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n                if (retval != IERC721Receiver.onERC721Received.selector) {\n                    revert ERC721InvalidReceiver(to);\n                }\n            } catch (bytes memory reason) {\n                if (reason.length == 0) {\n                    revert ERC721InvalidReceiver(to);\n                } else {\n                    /// @solidity memory-safe-assembly\n                    assembly {\n                        revert(add(32, reason), mload(reason))\n                    }\n                }\n            }\n        }\n    }\n}\n\n// File: @openzeppelin/contracts/interfaces/IERC2981.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol)\n\n\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n */\ninterface IERC2981 is IERC165 {\n    /**\n     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n     */\n    function royaltyInfo(\n        uint256 tokenId,\n        uint256 salePrice\n    ) external view returns (address receiver, uint256 royaltyAmount);\n}\n\n// File: @openzeppelin/contracts/token/common/ERC2981.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol)\n\n\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n */\nabstract contract ERC2981 is IERC2981, ERC165 {\n    struct RoyaltyInfo {\n        address receiver;\n        uint96 royaltyFraction;\n    }\n\n    RoyaltyInfo private _defaultRoyaltyInfo;\n    mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n    /**\n     * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1).\n     */\n    error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);\n\n    /**\n     * @dev The default royalty receiver is invalid.\n     */\n    error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);\n\n    /**\n     * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).\n     */\n    error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);\n\n    /**\n     * @dev The royalty receiver for `tokenId` is invalid.\n     */\n    error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {\n        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @inheritdoc IERC2981\n     */\n    function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256) {\n        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n        if (royalty.receiver == address(0)) {\n            royalty = _defaultRoyaltyInfo;\n        }\n\n        uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n        return (royalty.receiver, royaltyAmount);\n    }\n\n    /**\n     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n     * override.\n     */\n    function _feeDenominator() internal pure virtual returns (uint96) {\n        return 10000;\n    }\n\n    /**\n     * @dev Sets the royalty information that all ids in this contract will default to.\n     *\n     * Requirements:\n     *\n     * - `receiver` cannot be the zero address.\n     * - `feeNumerator` cannot be greater than the fee denominator.\n     */\n    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n        uint256 denominator = _feeDenominator();\n        if (feeNumerator > denominator) {\n            // Royalty fee will exceed the sale price\n            revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);\n        }\n        if (receiver == address(0)) {\n            revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));\n        }\n\n        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n    }\n\n    /**\n     * @dev Removes default royalty information.\n     */\n    function _deleteDefaultRoyalty() internal virtual {\n        delete _defaultRoyaltyInfo;\n    }\n\n    /**\n     * @dev Sets the royalty information for a specific token id, overriding the global default.\n     *\n     * Requirements:\n     *\n     * - `receiver` cannot be the zero address.\n     * - `feeNumerator` cannot be greater than the fee denominator.\n     */\n    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n        uint256 denominator = _feeDenominator();\n        if (feeNumerator > denominator) {\n            // Royalty fee will exceed the sale price\n            revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator);\n        }\n        if (receiver == address(0)) {\n            revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));\n        }\n\n        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n    }\n\n    /**\n     * @dev Resets royalty information for the token id back to the global default.\n     */\n    function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n        delete _tokenRoyaltyInfo[tokenId];\n    }\n}\n\n// File: @openzeppelin/contracts/access/Ownable.sol\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\n\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n\n// File: @openzeppelin/contracts/utils/Base64.sol\n// OpenZeppelin Contracts (last updated v5.0.2) (utils/Base64.sol)\n\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n */\nlibrary Base64 {\n    /**\n     * @dev Base64 Encoding/Decoding Table\n     */\n    string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n    /**\n     * @dev Converts a `bytes` to its Bytes64 `string` representation.\n     */\n    function encode(bytes memory data) internal pure returns (string memory) {\n        /**\n         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n         */\n        if (data.length == 0) return \"\";\n\n        // Loads the table into memory\n        string memory table = _TABLE;\n\n        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n        // and split into 4 numbers of 6 bits.\n        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n        // - `data.length + 2`  -> Round up\n        // - `/ 3`              -> Number of 3-bytes chunks\n        // - `4 *`              -> 4 characters for each chunk\n        string memory result = new string(4 * ((data.length + 2) / 3));\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Prepare the lookup table (skip the first \"length\" byte)\n            let tablePtr := add(table, 1)\n\n            // Prepare result pointer, jump over length\n            let resultPtr := add(result, 0x20)\n            let dataPtr := data\n            let endPtr := add(data, mload(data))\n\n            // In some cases, the last iteration will read bytes after the end of the data. We cache the value, and\n            // set it to zero to make sure no dirty bytes are read in that section.\n            let afterPtr := add(endPtr, 0x20)\n            let afterCache := mload(afterPtr)\n            mstore(afterPtr, 0x00)\n\n            // Run over the input, 3 bytes at a time\n            for {\n\n            } lt(dataPtr, endPtr) {\n\n            } {\n                // Advance 3 bytes\n                dataPtr := add(dataPtr, 3)\n                let input := mload(dataPtr)\n\n                // To write each character, shift the 3 byte (24 bits) chunk\n                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n                // and apply logical AND with 0x3F to bitmask the least significant 6 bits.\n                // Use this as an index into the lookup table, mload an entire word\n                // so the desired character is in the least significant byte, and\n                // mstore8 this least significant byte into the result and continue.\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n            }\n\n            // Reset the value that was cached\n            mstore(afterPtr, afterCache)\n\n            // When data `bytes` is not exactly 3 bytes long\n            // it is padded with `=` characters at the end\n            switch mod(mload(data), 3)\n            case 1 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n                mstore8(sub(resultPtr, 2), 0x3d)\n            }\n            case 2 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n            }\n        }\n\n        return result;\n    }\n}\n\n// File: Wispuff.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Wispuff - 3388 Cute glowing ghost kid in a tiny witch hat hugging a jack-o-lantern in a moonlit haunted forest for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 340 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 3388 total. Collectible only, not an investment.\n/// @dev Art and metadata are generated fully on-chain from each token id. No IPFS, no reveal, nothing to set after deploy.\ncontract Wispuff is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 3388;\n    uint256 public constant FREE_SUPPLY = 340;\n    uint256 public constant FREE_PER_WALLET = 1;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00005 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Wispuff\", \"WISPUFF\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"524946462c3900005745425056503820203900003056019d012a900190013ec154a34da7a42b2928139d49601809626bfdd75b3fa5c4ebf5ea2a89553fec657214c01b238310da481499db241bae43b0f2cce37f17017ddc9ecbf3b7d9d7fe1f5dbb863cdef9b37a9cfedde8cdd543e89fd341fda71ece623e45d95fe4f88f7e4685ae8f318bced9e08e78ee04cb4fe14e188cc2c5d36f9dca4f5876c824c11f8faab44b99d9f769a7a775241aaed1f159d966cc9b11ad7815066b52f23b3c9b43f7a39ca428ee131c302799b49ca6d2448d054cd426b509b94da93e7d98c6d4f813a5c1aaf2336bdf607c1fa8be85a4e2cb994a16b692a9fda1d04cf547e0ea20725d1f6d30bd3791077800ab85cd80eefa1a699ef683ca13e0f09fe622f965ef05d7252a01147691982ec9960c4065c19ab5a82e43038c8771c05b2449a500a7643d2e600249a6dccf458ebab713e2f3522b0d6156d9674841d9255d932df9cd57da87715eddcbdb5059542d2bf293c0ee8d855fcf80cb494a0b44798c429b2ac658bc511864e538638de823325c37f06b938b61037d45b10fefda94ac698f1aa38fb42bb9c97b7abe3334ff6a949404662ad4e3728b6a2c7cb2f8f46a9198f57c7700d29f70cffad78de9dd3d4a12a3c1c4fc2cb660c7e6ef0cd59220417c3412c3f423adf1ae9edc60dee094881da701520c22be870e7d4c7b504980b651b8b7cc9c17af4ccab499de62278dcc19a986d0d799329d5ffe2bbc461a1164cad9e5bffd8a41100a9f7b081e294bae53577c2c05a3653ea07951e0ed685d010e1327db18b6a7dfcbbb2953b858b9be41907f3bddb442e7f15f4ee69e04894946dce3d808573cf22002f2b09d7865927f4895fe1ccc5bbcb6163765bb57150ec781f18cf5433ec07af813edfd8d3c7f3437fc5fb30630afd39ca50b578ade30de0c57333a523d499ae7b4219f4535c410d5d714d2ee38c22beef68803cd732ce1290fec74d981d8101d5ab2dc1c325a3892ef3d39c5486a4940cdce7389305985e146b85bc0f857049d90f7f73770f56bbe7ee4aff2bda7416d6b8acdc2c40d616ff5d56ce29d662ef9808f2f46bc7dddfe1c03faa2d40b765f180b447c4adcbbf6220283df40ccb2e868a5119460ac1e44e633c15c5e1dd13b30d23b4c039df7d6f7e5a7bd380a19a3684dab3a3cf779af362aef5683fb0064efb3d9818b144835b4df0998eae193438900e99c2630ecdfb503a3d6e1c7c38af6bed57398d1001859b2b7c98a3b8ae5fb138cc17ae3dc35d413c711f8ddddce2d919badac238eefab0a14e9ce5b1d9061a8952e6c5a6fe82ee2d1f30e97bc98d0b5aff42e74d2ca2759022c82b2026024e52d4c1c69b821cdcfff7f6eb9cde2675d4c56d09ef8bc9ba67d0355f3a3b4d397436fcc151174452e19f393ea5909ddd2d69009ef890c2df4a17f8fb85e590714a6288fe9da986a96cc258d0829b9efc199d72c9e478fa292c82777e46f204dee2edde42541b7af9560b88a6e75d2c762fbddfc18a5181453e653aebf2517cf55aa9c86523f410d9d32381714882aa5e62f525ae57e841a6a67ac4abff2eae57fa28ecb9360339684ad005d2f30720d1ffa695cd800afd92a0249a8f2e52510377b69ca0accc46d92f27b98af211b76b05dddfebab18fc2aee364af4a1d8ac4b63c618aff8d05481f936caf7545837348b24ea15cffadf9bf02307437d03c0b2f27ff06afb49a53d185539275da2503a38c1e24dcb209728126735c495a39c488949f217193ac244e62f6dd36e4baf1b032d59d8a03f2c3b1d2e37d5d1056eddb5a8ebe963ec93b894f8dbd85af5c456558124887214980361a6c387310a6bddcfae17a2bcb49d4b20f130d83550b6d68df8e59a94265f04371b80d632e954a71c1d8f8cda5a4eda76f43b643bfe23eaf88a3a73a15e526a475bd29bfcec1e59f5fb314b7c8b13e042dc3353156ff1e1e6a0ec3099b410d476969309345c8f8baa124b80871762de8ffe6ab44aada1de3fa1104e45b491902f940554a172a5ff72c2ac2512aff6057d4a0d2fb77c7320714f9268c27aa583c0d095d1c32e573d6473ad57bcbbad488cbc40b64c755d70acc9d230b96117dbceeb11d806b9b28c304ac4564a55d94ddac3f8d17e43be87f07e777f7885f875ea77a27ce74b58a672b55fe2f82641abbf2ea61d50452b92d94c80665689947de5a0ab8ccc6a037816880faac54e6f90e3ba5fc4877b0367b200d349fd453bb1da043f2b6cdf3c03d7ac852e54c027fb732397f618e8387a6584eb427fc4636669922ef24117b7683de9e1739db87ec121a2434981e04aef18ca97d33cf41df4b1166d870e9ee45ff00de05efb0e8136e3accb107fa8ba5219fcf27dcb80a74232c115f298e108a5dbd9313d9ee0b354359bed421dddd3da95d1bfa0a8cf470c8109456777903456b4f5f33ce37189c70a056ce0ea81887c76dc74d91a3a72d11fce739984b930abbfdd177cd70c3416ad75e4d4f77eda648955b81da7c586ef327e749025000939a0e1ba039ec45d9cd5a67b1e0f38e08d6bdb76df3c099b4db5e12b10332f8d5bc145a71b5b91887432a594a457f47c3b9aee7ce283cdf72e4dd443dda8013d8262da4df3ff15b42bfe44c0bbe0e529245917eb5c10c9537426a0165106964344ffeca94ae16a239f2529f02852633f5da3271e7c4103784d9182b2ea82eee352902424507ea8408e72cbebbd382814957c37194f8d37a50eb8f43bea11877811a04cbe5aa3ddb4af7fc8efab31579a0449fe0590897cb19a03ef02bb5a71a2a560ec3bb4dd6e52af61c8715bc6b67b776de06bcb9ceed9a7804eda4a99852d05618a23d88e8505421902b754d6571a234f9d8adefd69d8f49950b11ee605d2858abe2dff6b53323ecbf63903090f827c49cbddc57e36fe323ea60755e059bfc1c965222ea7edb20cc66e6556d01074bcb7876dae258c65aa218870c9deeabd81ee968d7a8dc8471ed83d684634c1a85a9d60d1c631dbdad335159dd8be0207e1901c489257fc7b9888c4b04c2fa7304afa1edb67fb03dcaca735df9106717ee357acf62d42bbc59622ab2ba3eb56ccacb69be5bec77de38b4f1850e9b73bffbb6d6266c9180eda129271513a2dae93ecdf380a4faf6543dd60d4ce1fc2a1d31d39d9619346e54d65aefcb16064c60acbed335ef1448a07f2e14990fa5b01555e139d05feae2ece6455515cd17509f9da00335abd9e369a7048337999a441c0e318460870fa638007004bdb8f05f442333c5386f7a97511eaa0ed3de77081cfa99f4d7c2bdb38db6901b5158e80fb670a4295b7c729156c4cbb8af21e9f352599cd2575f388c7525de326508fe96860c40b2161b80755477606b1ce3f669fe8d6833d9e67e86db52c61a2f8cb8343b947721606a9ae5fb751e82239fc69bd256ee04d20a039e1fa25241eda45dea4471c48599f181d025479f5aa75baf2a6c7cabda676fb959451b6789df80bde74f7c732e1333faac1a7ecf6b9e584b7c3f0bfa64f49d78508afa824067b34b237a38d00342b66ac31524e2b0d397ea2615bbd2028a19f04c056b35c56fe33bdda4959f5d2ccc1a61af657fee6970eb616f19e8ea451ac4bdf9700cdb9e50a93f1a96508e5805bcdbebed3c1a051f8681d6c56e3881e44d3c7fa224e44bdc06c03342b32c2e2b696a237271149d18af8daf11abf2762bdd6e5f50b9ba469eb421de1c889271a1b2d6cb9bf4c13c16394b2c831a245c901b5c80fb6775cfe3ca8fd29b7f4e85b34ce44b142ee30ab4a7e7d27159d574da55d7d9b7a652ef81f524124abfd4149cfa5b52719f37bbdc07355c4d56c072d6f8b0b707175afc044b25718b0d96eca320cf8c3aaa5c3b34d8dcaf0de49c14e000fd562b4ac8c0a2e27069ed40831d1d5405d1abf63a5656f9144de9c1723c8d24222836b53d5022002ad5ed888f567e5f33f060b255e2cd6ac7da87c45755112ebdc76a64113e042a506a6652c898c750a3fb67f81a3f699f2be688e2b06711bd5a8f659af6d5f2020c37c38255bc6cd29529ca285ac989c8339fda572ffb6ecfea17a2782230567d3125596fb4a6df573f4573bdad5c8f71ee814b86344efae6737f0745e30dda0bc10bc8c81794af61f8107b4b181dc06b2b7e9a9e158709c926e2a7d25e964de9f80078e6b97554b90d242689465bdcd79c20cf2add702de7fd32ede94da73822341881af104cd16a87f70551bc2e15cb8fb93e57be00bb565ddb08c3f36a49816a10f3ddc184e4e910bc1e199d2894b208e5d44155dd97b28efd76a3c373d65d2654af81b01e1ba76895c2c4a31685641d06264b26325cb57a1ce56074335b279b7be5496d9ff8b6e53229f5c41745cca4af20271261cd47f89a5a4157b85d0c1dcacb2b3966177aa524c01da278c8d1e8281f248397d7467d7dfb60f5a06694dd5492abf5b092fa74fce56ee1c4ee86b12769a5ee6d07919894363e8d4608f6c38159a6510f4b3a9b9939db1a768b9c50fd018a59075506ada3b5477245d086ae3c8d451abfb92bf8c8003de920dc807ef682c43ea82058068010f05dfec3a79f7f5111f15ff6dc4527df598083799e7d1798fee80a82eb1b8627795c1036498dcc89084b9023ea18cfe84cfb043c1dc1c2ec3855c763f59061605abb8f3c45bac949ee90309e7a0537c6d216635fbf477ce0b46974cd80bbe94a8018dc1c3d6f511f57575b3e88ce38a3972a9a1bb97e2ef00c3c5469addf86fe75672f176a52f498db8534b79c5c1808c799911b021fb63a42fd36c7b445c3cd53a1c5db72b6eb9fd05ec3b8810c68f148fffa17fe28de7d0bb5edfb1925f20176b8770ebdcfb6ea02c6e888cac6f8e973fb24486d38fa18e1971233e40f6b7e7f9fc6e7663bfd544373a8b9bb254934944425b3e87a1e7bfa6d3a0edf7223f45328d25eea6d8adfb5900143e61fd4d6baa3a6b8b5de6b88d1533fa1358f2a7f7516213c02c5bc9b711c5000ac5f14c24608642a7cdd5da901d39689024d0cfc3630606e937498ecf02215d79ec725ea1026272056b5e80de97f98857f77c52fe33d446cb66f7eea7f64ebe975536b0ecdfde8ee66593264e845ef62ff3c0e647ee9042f5ed33d31c76cac804d882031ababc9a6de7c26592ed6e8dd8f0e062ae01db265038bc4fcaffbe2a6e8c66efcf953c1532d104d96fbd18fdfa6aaf5a49b25907307924d31e1a77ef59480348669ed1000ec2fef45d2e84f99bd3f76666286187c85d4fa5bacf560b11d1344cf5e8d39cc704e0141988e38380b4773471c6fd60bb577064ac13ff64b17251d38c3bf610f6d1e3287181c4052f0dc83fc00c126db1258d2a30f3736f1dd382e6507eb6c5ba03d69b2f9e19b227fd82f0d3c1587df09426e0eb6f7ca7f8136aa7e01be87501fb9ac4e490d48551b28bbbf11deb3f3ca6a25aec1cd64cf8fe489c9df831a63c4375243f77785ad19e083d8a8fb8790aee4386aa33a92feade2b7e36ff24dc3528cb9b4572861c76bde7b1a1628c2bde4459625cc9b3209ba3749b69307c0beae6ffeae62904b786388d0953b76574da0f8a33dcfb94901a3593f60e0cbf8fc5e120ef99defe473e69f101821e0f80cda595589ffb0c241d3e0af953799c9db51dc8afce3449e44cf3b8961c819f20ac7f3c9818b19e2fbbd482b1827bbce424f78f1885fe2425a923cbbe324979222d7302156fe2de3207c61e234d551498e0e3bcac06d7b8a997310773b0efd8af42df06bffda650b8ce029682fc12b682c57c64bc67275a9e0ffa716e7ad8e693c70908d01ccc5106f7ee2617ae58a4c9f5e99b5a74db2b659294940228899b32559ae11df1fa32f573e388beabec3bf8d56fa8ec9855c486de2d8c701577124b84e1f57e8922505412b4d4f5708d854cd56c7b58c1f46c3649ca459fc69dea44110838579ae7d995a441dc16e837f227550e1b495541b0653901973955f0c1be67ef7ec85c7e71d72ef4e70bb2470bd28ecbfb8242c64fcb824b57ef263ee6bfe767ea396ef765b14b7c72b940054ce1f3da408efce48b3aaf96ea178b708bdae543f348f23ac9a2e7863946cd6b88a87e3a3bcf65e31509fcf393a7b26d367705e00a07c4493cee124c2dac3f827cd6f22849a95d8fd8349e28b142cbfcb59869197bdc6dc8f8e25e944b00fca5c6776c0b70a81aa19dfa26198c796b7042ce2a36de58a66d1747c321d9f51120de7eb4c1cc60c605aae0133819f63e8604d663b3d4d7a336708f336f196142ee10a86eedda76a0aecf6f854a06c2535f54288b7475a44f10f780a126fa0865f7c13f5ce9075bb74ac9b802d2210445e991bdcebb61e62805defee1ec230e3f39b28324830594435705cb2848cdf93559dcdc7a771ef1053516e0167c50989ec31e2293849a51229d9725b2f8e29b1fcb63d168e57bf07f52f7a276f29c1f2fa2dd235b5a76bc82a39860e3418b905939159b33e0e0e74767c4b17d45d793739e353a77f034f9aee8e27a46171eeacdc91081fbb434a96e515301d5a6bd93c6a0c8dbca3e57e1020209f195a93e993b279baa0246a088e1fc64e1b02cebc8ad90ddb3deaf9df16a1fdf80e5fedee50e318927a6ce5237d1d39a8858e8fe930b2267f8502a63f4a55f86eb12d7f28a9e99c3d008ccf66d69e3b6462d6ac9fc0706ddd0711c067254ebfe2601a3c7aaae75b0625a9b6d9ab3dc31def76eee5f6e595975101232e5da7c1b9f6c8cee74e275ec8ac506ee6257669a8db7b38d659c2688c137ce8f5ca14a7c3611b910beeae560f8034711be0b1e6506a43a32f74fa5fcd0e311f1b515d8603bb623f68f6ee47de6edcd4d8c9b0ff045f9e2fd21b2ae6bc7caffd5d0b0fd5d41a90298cadbe03e6cc6036ad5f8598e5b0b1e314622b72c13e54f1e1ccc58b8a353ac63e1919a58d1548c1064f67d822b3b2d9261be27c9645d1e05c28e4d084955636c9d8e1f20b414c034432fedfbed1cc90c568e5e04c3fd116732e131e775d239a54e645e8ac87999dce5d476e32721aae96179634500d4069e1918525971e7764b3aa0c129b25e253d293e834ab871f99a740817ed8e206c61325c81a345332d143ce6cb3d1239b3e68645c92b58629a6f3b2afbde888663d6d1fd18c1f3a274cca22752160f6c88d758615dc02c9c3e6000d0b4b0e20083706b3606e1e950822264c266644e87706808deef010c93229f40147b71d8af23477fc42db5b0be6db3722f2c90c5db8b568067ad8206cac81e9d7929be931fbd9b08293ce29a4d2fc61fd1cf8f8660d1fcac1854363a35ef89ccdc7ee98010ee5e14a4dfba94cd3e0edd81409906030c600810af913aed20cad175295e49dc3130a503a4a60b6e1cc049162b4be7d72626a07e6e8f1942e05b90e25fc07693e1c07f0383d78ce11cc18535484dec84774702f186a01c4568728fcd0e19a257f5a02ea081a0841bf8b91cd81bbef63e2ffc81fc9a9023df563676411f198c904030dc17949f1d99075d9bc946f34b7655a813157f135da7195e1cb3583fd61c6ba5e09faf6f33630df170cd6bec56ade1b0b6a46cf51c80d8c78e043eda9f70c12c1c60113797e19d3b7437aacf50f368999e3956b53f08b1ff44301337a09d8ade35110937dd16fff30009190f4cfa559ce467f9faf9a0e6d7bd405ec9bbb73aba7a58daeb5b0dd16fc0269925630694ef1c08f95e8ce379d2f3f2b1cd2fa30c7478f6ae8e90854a40023fa3e06a789e62e8014ef987733739558216b829fc950fa41ed2906562c255ba43730bfec97e0c8c6460692ac6af53a31f47cdcaa82bc049a9ef63bb47cb982853df994865803bd612457c33177258a603356681af46ff7615de2d6149fff4783d11104c3e68516f6ffe6ae39cf9a8aadcc830c6d643e2fd6841622ee61c6e65bf045fa9ef04aa1f97c816b7a566fda10d5c546e589306f8e4f9e3170ecd1e7f5da09d9741c1536346e052269de2c9a8108f276888a9aa201c3a46f1521a6d15cd5408000ef5424469e69b8e3bc056fe3425be538a7e3866406838c49284d2a23069915270c4c9e458ad7092000d3b47484ea797f2c6306b6aaf6f767db4b1558418c41b09d2d0763f156fb90306cdf224b11b7e21733a1976a01e96b2d700a0be7f0eee0a0f04084155ce98c2f89a9cbec3d2067ccf251c32ec5ed855f99b51465d08279e813ebecbcdb4eeb035af69af39ef7ed48eef4d7e25b9b1989ebbd46d93f33cb1a3e931b16dc0def45486b502589b5b6ff064366d15c19478b2938aa61cce1e41f21e9e3fe1ba09db3402e4901ad564d441acc2925b52904e25b038e9f36f6a800e62b7541b0b7cdc01c5cb26216c53360d171ae1129385e0a1dca0875a4ae9881782601a52efb7b3078551e0b74def002730d45bb080177ac4a5a3f2247cd87cf77e6b4650af6e5f595749135bc401b8d64901fa8123ac9d1231bcd7951188893499df79a1be8f93ca5283e3a9b5e0319cd44287794d46d5ec649558264db39e74d74cced4a9b1268a035f5f6aed27d3fd21952b6c2bc07d71b23d71ca11c49b11f85f300b436f595a2737bd863b6e12aed70774310839b7f1305ab44cf9b4c17dcbd29a208c84c92c41bb76327ac1b553c9699726d32cb15ad16ca345bf9a8ffa57a6b38070653881ed1aff8c8a09d0087e53333b4707a3170895654a7d022380f082fda577506b5c6e9466746a72bd3fac9c1e9885c08e8d1e8f411812dc0b952be9c1fda0731782c6d24a061e3f4bb3e062f999020cf2abc683f23624858d197664b72b45f70a78cf9143eddfd2a6452cfaf894507d652c9fd7fd3275e50c59532d172dc1e1133ff6881ab3d11579b7b865a168ba2212ecb4b3205d90942d0a208e873dfc4a604b79af341cd28ad0f0cb1f336198e3092de864420e209bfff7ea5be9a06f91a1dce1f43588f139284a3b0c8b137090bd172c4f38d35bba534c90a58eba507d1c500393864fa42b54dc76d1cbb495a2edfc5cd6282b2be355ba6fc0709fa4e0c57d2fe376bbf197f53fbe591bbe4f2737a7c2cccc13f0f2a378e2c238cf9c839bb0d627a32f2f9c4f552c639902daaff814ac868bc484c6972818aef489116b91e7a1a0951a92fdbf8d770d3812e587eba8070d930eb07a16d0ab32dacb8d7b9a1411054d5bc059d0825c7ed9fc67bf1774750122818f68cc354873274772b78d7c9021dcdd5fccf7038d0a1c09cd047da5999d2f2ad455c1bd27baf9a6eeddb4891bb2fcd95bcdc391f86e0ec47cfe75f967d74c4471458b3b3ea33b772da60c18009ba899aa0298af5a65d8a98d537b60f62e771ce17aded61addaf792fb755f740376eff7911228e5903ecfd439228e1c75fd9bf53bec13f76268cae65af33ab3a33e4b01fb7f54476227bdeeeef7a8d18b7270a75e93c6348d6368d4ea149fe90b9af6f729c4b253de6b331ed18684cd6df4a61cbccd61919efd4a0720cd48c459e82c23f1b8bc7e564a757bf29ae78f49b466fe563958ba01ee168af05a8f0dbf5beca3c30466979eb603f29eb41d4a0baf68a73f2ad8fece0961bc357da6b334f8f1f6f17e198fb3bf19752f5b738a7384ff4552ce3be1fa5d122b21884587f29cc75277ee3446d3120600e6c3f1f71a39b34c0c01de515436a357c59c29ba19d027b531d88099984ff0e8e34aeb559fcbabf6af4e81575fb61720cdb02234254326e43a9ab2484ba3b47131a12e963a67e5c28dd8445190c695e297e428f97ba1f08c51475dabc7e6dc20d9f9cf9ce674834e34baaf89aa77c37ba22bc5bbfbb77b995808109c4e47b4dcda48d55fee68e9222f9ad80e9a5764eea1e3116ef39a37af9e563a260dcf10f95266e6e3faf0a6e09060b0bd8008e6393f9238bc3a3a57fb8fe09c9dbb2e29b4884060f2ef2dc659a9e6c28c7153ae840fc15eaa7fcc74e05866d67c8fb73c577d639599fbc45ff5bc17888d06e50c31839d5007d2003dd517649b9d420a5a8a2eae80f9827295861d75d8d1e8d159e52727ad021b7bd5f9916fbde57167bb991f94a167f44bbcbb114c75ccb3e62195f567c53060150a825e5636973b4337b5d3d863c5214de6a24ba575a2d8a8f5bde3c830ca41bd83346a9655477ed2e00a67233c582f4144baf81779b85c34ab9cdd4a13f6b011af305dafe71241b229a46f784841090814aa969524b0f5274350ee0c581e924b00ddbe36c4caaf2d4bc868921537a62644aa627ffe297b2797426982d6cc0556f760a914025691c411bd68e8dfa955cd811fa1113b536f429c64cb9f5904f2bcfcf693c7c57382e493405c30e07a50857c7869fe0da9e96f6951ee09ad5239604edf0eda4dacfa04b6fe9c3c8f04fb9901ee494c369210ef0c1279971fd6635c22f7dea54d8c30be9a844ad16390c5c93dcef31ee431194750bd080c6c0bb2b45a855706f8d1e7fa91fc9e6cde27f75dd6a2dd1fc034537877584a209cb93193f50eee9a7e39f80bb58048557c5d80ef0d2a0ec66b7e94e4bd9b08ab53e2804c200d6ebe7e220686c077cfb006daa325401a02ca4838a52feaf390cbf52a83f19b2e581b8a80c9fa4f5250f66175a4f61a0e4e0a2488fd911a19502be7d208dae994d64e20074cc2595bc20a7eb69e7aaa0fa040d6e71645e568a0e3b2a73431f5411b7b5170c129cfb7b1692e25f16f204452d1165cd515d79eb714266132f90f6a3b4f23bf323ae4317388f0747914d1e833d34e8eee2851bf2e055088150e5157b6ad12547bcac85f657f9bddd3d706e45c239011e73ab52533799e14de7972731c7d325901d8f2b6d0d7e3b989a95b9e65ddd2e978f914e24428f6319d34adb973859babdf1996308bf5c1c3edc0877f8ef27a7dd43543f978edb75be11450faf7f6910093a3e75e5470cc5060ff2ec60fe204f42d53308ff051b2d045becf5c74b53c19832a6d1a2d2084a2267d49799106a823e4d10314f76524ef45c72fc91f4476f675741d9f8ed7e2d4b9b54f3e4b2bef2a11664664506c069e19b2daefad7fa3c7b6c1ca4d3cc84838fdd6eec16e3a600903bc7a7f855aae7549e483957e4c901ee0e32cc9aaa58ad5e2c0c8c1c5368c03cafc32052a059307f16fc8dfcf5aa03cd8bf5e3be3ea0ba4e3a741045549308aa8a041f866a3e509fe5137c2e710a79ab0f404b0fe6e4cef78a47e2fadac534406cb238cd37556265088fb815d97a7186233289f5f025dd13e9ca2651b5ae921b635001ec7055d4662f8995bfcf4332d5c5241e280fa11627a58263e2effeacb6ee702dc0a2496faef88d05cbd01cec800aa1b4021727af4b315f7250b13bdb29dcd25774b1944358c88fdb3f7671a9d6a8393d7042873837ecd827261bc416f647f7eb951df4d08531bbee69ab24e3e3b39c54bbec21cb3a4e5945faaa3d9ebe1ce402b7879d5f3c1ef1619a4e1be11bc9e273be36c99b339b29fd89f7ffd8116b7122e9b857041ee2a680cefcfd65b8b43657503ec7fe6972dd7545fffa84d12b697921105dc710f9572c212f3f8c1376d37a6abd611b93792374f2bd597a2108f8afc385d4b204d6dd0b2f71f337d696d78d81e0685615a9d85b32e981c6ab6afa20a95bc7eb52957d91bb337edb3a72518eefeeb882bef76b7238cdfddfb2c1c554ba563da21aa9989160eff417401cc6a98196754751acb8751e49bce79078f7c83de2f2c9306fc7b1798d008a172babd2bf4e299e1b6240afef7ecb7ff60ef137c7afa6fee806217af98f4f787d5bf7d9d0c8b281952770ae55d1fea3385390c42a87415add997da2437fc5aa51c99cda383237c3b086182787476064c1df7baf4e622e57972e115debce145c0d36a3b9fa5d6edc6a28062144a8a85052de11376a633f310a92ab2f360170d5243e19d24c81f3decc5c61258cf349656534ed7d3b5e335deb727020cf462ad8ded21892357ed16518ced27c9cee01fbd5692b949d47dae656c6073c692b36ad947d8431092f876b6b359596c3dc36466087eb14987e76760dca4043f7b3bc0bea568c77e9a3ab7fc75044fa996314a1063f743af8836a01b7b46bc3be188e475f3e8cf28b53a0611ca5f393cf15c9e0d5e5eab12ebedba65dcdd2edccc3afc3110add1b4bd4f992079fa05e83ab0d7ac76e3b6a1ae2d1404750cee25f1d63993f85be72a3e6f4deca0fbe914319c44edc6ed49c4f8842362b300a144d233a61308221ba3ef56be3fe896116f30b124284bee525b9d22cfcf9c388706783a2024cac908391fa705aba6af4732e26a0c0503ddae4edb3d8aa1e6ad38b709aa03b03f8096de03ddbe4d8b0c0fe2b08cdc58a41e87791ab5135a74a9783bdd06301036710615c9b063b8fe259cb88440f9b4c0075b6dce145bf45d4a11e00f2f124ed2aea364045cf074f512550e35bb2b71fbb39b8ac09eb8dba60cdf8e6f85730be66c0784266f4f148200e71e801d074115c2365b665ceb288c8ee59c405d594128d20982eea69b6e3851b342dd5844e73e4ff9eb5ffea5d76618abf741803ae66389a09b534700ef7b18cd66920be39be4cd338a32916ee310679b679de2fd7e6a6187eeefa8ced3966039f8a2d4f1dab22a780ce21f16c49fcf29df56b25dd9d72632326531f58c45094531458b122652171bc67a2ecb68a3ebd88da012d00e1f0de1e959c391fbd96e267cc1b7df822c0afdaacfb0e669a82c199db3557e7991e44661deb40cf44ed7904a72f416dd483fcba5e2b800f045d2743d0f6fbf5e3c55b8314ca88223cc7e208098a2f25ee908300bfb2cf85d6740cf6a51982537935e24b57d6aa86f8f373548bda70656502fc98160904e71d49d5736df07458b3535b22949a9718fc1b8bf9d1f9f8533c8d4eb20094906ab9a5dcb589210b21d7dc35dc32141879bc3753bfabee403cc1d4b51d7178552e25976a15a3458ad7e601bd43bc57038ade56698b419b61af36237908820b9700bf8d1eab8441f840f7df844213f5f7181a629f18cdecd45a89b65f10e60ba95ac58c78083ffb14800299952cdc995bc822071d0c147c790c620f44c7effa855de9dda6b29bd4fc9d90d771cd1d008f786136845afde9036921cfe0bf9c479d832a16b8d7be12483659a7cfabb327902f6cf7a50a939cbe39cd14e601f28a4a86e07eaf4931c3cfc63fae27f677ce674f5ec7bbb0d525d8cf4ed6585c3ee5435d2c604a63f79a9b38e9f708d594bc5c67aa8edf6594d7f1f4c7327be224f8118524c8d7dea3f3ee1e1ae903f56b75ef7961db2e3d28e0a9dc35ba615f25d86de566d3596b2067b9310abaa6b897ceedb2a49cc1aecb9c2aab75d738694949df075b1a949aaa7e579a8219c89c799cab50d25845bf6f32d0be458717c9c59819aa1613089fa908092723342bf78520d9013e6d06bf24005c2819d6dce7de13f269a090cf9ad6a501a73671c9d9e53a562eac5c75767951fca67c6e4dd98768e481795c113ae25566edcf257d1ea85e40089d0351bab4d29b0c312a1acda3fc00bb34d623fbc5cf8e9b9f0972f484d70bb4aba790a1b20f73c29a67fbc43ab45f2cb3a284b11492073efb5d7c05c142be6c1304b12f2aa19a5872e9cf2091af70ea755d1be941db773ff043af90f60df594b641c8d7e303718c1ba173220fd30607ea0364f9296704c60e1148233f36f6a56394cdaa09496bdb94b4271802b79e0ae14906d1fcc2abd04c2f3114befbd41219992bd0e5edf3656ae81bd06b389b0ff29feb2ae2eda2cd80c078fdc0a265a926e43887f71b1019d44a9a29001442494d2d4474e4a22b8e4e87e037187b9555fa2286015bb875d4a3a4aab068bdfa55ff83b8483310b75f5299c975bcf479446bc5d997717d3720852c3028ace236e4627e067c3ab0b052db4db983dea69d750b28ab9011922e35f971b75627e897c6cd618f6f5d4505e43d3fe6b1592dcee5cc2b2ebf477451bd0f1df27a0e37fd8d74dea232f8d84d4b7b2642ab7ad7d43c8c5d9933a4d422d79e663a6ec1b93040bdff37fe0bec93955226e9c8574e9c003be109a5678f168490ee102d9875b28415eb503ecffdf882d0879347102a68bb884b705c6edcdbbb6c03b560a50204a74ba071d5da5b18c054ad291a024b26393e6e8352fdff1dfa68dd6ec7035abdf467dc50d9e4d1678398b5a1453edc1452094fc08122562cc61f8df33e9f8a6cb9e49cac401221b045b06c34c83cd1cce676f177acabc08bbf82985c840c6095a60f25d1b30800f4c16184240c9bde5050e882f6da96c334e374d64bb98a983adb29282f234f6aa9fd1710a31088aa727e72bc265840d23a87ce6011c7ce96c16355f05bce7eccbdbd201a1e37d17b70f232df9b2d0c32e0fb3b54d172ddd3056cb7889d8cf7b38a29e9ba6230fabd5bfc71f463ecb84a73f9247feca712410e6d6a2b83fc65f2b7da0e162110c64d7d89b75bd46bf0aab42d24fc49abf2c4f521d4579283e476bad5bc015cc5a21f0797dddcdac2649c458928e3d5635956ae2df34366dafe6df79ba8ee7d653eea898b197ad291f9f74bd05e156d5bd7dd3ab46c5729d21ae1f7173707383af1e2beedd55c654741460fbd0474c989bd8b67aaedbf16858d1eac8f63767ea65ed161b1398b07b3733259bbe29aae00e0fd07ef9616a5797af8d8f56d920641a2b74f2631249c6df3925bbfcd8b632ceaaa0afb0cac5076693a0b7f5f801c16d50e3926893eed5977c7b872b67a697c694369d32f97df34c4ef3d04974a68b81eb6196fbb19454e9a9ff712557a3e4077d777ec55d512793d67181384db9d398cb634f9692b2427af15b151c4056d49d7d0bee147c641e2ca4645557cc23239ae74662669874872208d1a31d267aa0644aac97139e7a00bca880d237b4408bff0d8486424022e86ab710ea4527546b0208dcc85861fc79a03451d8a1c9f189bb9affd116aad69a2ae1dff198d87241e995321ef3520a16725c07ea4a7ce9b805a8ee062280c2b13ba1f3fdef7810f51459d4357c3048b070f155d93912d04830bf37094b2a4c99bc298b7770cddacc5455c58a05a392397b2e40e35ebea50897c31135847ebdfb9806a35fcdadf822a16e642c0cfb67d3cab46f4202e79755dfb82816bdcc212fd799e2ec1ac81e12c5ab5d3a9ffef90632059488343137c32db59bca5b3b3d5f43cc9adaeccc01850f721953b98c664d372dac037830467e3460e5bdea7fa2f7ed8425a458648ea749aeeb54c22d660625dbd4ca98f1b7e45475f2a0ffb82c40ea417bfeca020df601ffb9779f9ab56f3ee934ccb9332fa40ed14a23024efdf30e6289148a812f2db160703572858db52adb83e383bf4dea53ec3b2cd6bdb30367a4db01e51d1c7b80f4acfc1c7905ccf5d0828cb02db2ce1dc2e78382595fef14ceb360b35631b2205e4399153899fb471f113d86c493fd569188f421767c057ff6104cf915418684e0a59c0ad6d0486029d46594750320cd13503f31cb03e4252572197960453ae2fe3f29a2498f6ef8316098656c8d80fd7702ee501ed464734a811aac2c1936fe36df136c1b517cebc87b5da39cd42197d3ee4b2457e2747dd9298bb0a9de50313072a45cb869cd84a2390328a1e8ed53a186632a6cca5dd7985cf6a238558c2f6d74d52e41680715a56d08f7b755e10b2c2fc29300a01c89fab2c86e7105e3b1a89ee58b9d0737d3521552839581cf06c83bbf147ddaf6c99118f212c6c29239e80bbbcb76c6c094656bb5178e0c331850ca33d6c4d907d214a40067551c6ffe0360346395265262ceff44d7586d953dbfed212dbf7b6ee0a4669c6de53533095cd722b165b49815c818c957ce60ac81125b208bb86cfeba7ee0732caf42ce0ba7611e108e114c185427c4d787e642bd5a977b2ff822cc668d7429a5b1f432b1a0281a9c30edcc711bcba7db8c295a95ce9fc7228d4844325d08c36b0de1ca2766142a96cdf757cd1c7834b229e722ec60c18209771aef1df65f65eb7e61ecbe344d79d425d295d3843bbdb448c7987764d6501776781b3920eea6c0fc60d1e7cfd493432da9f55a9eab798b96c32f6441c0ee12e1a42942762e43c2f2ea62887da869ed11a77dd7f7f062f9855c2daee39dc7f04791594185b59fe8afde0aed42f3dc701fe5f98b958d16f57c70ada101a49a28219a61b999f652c902514cf7622e1034acba63680ee5ff37340be34b3457bd32b3ebf647fc8bb7d2915c6ffd6679835ad9528cfd617fb67b9aa7294dd2e43499a1eaadcd92ba3752e8091984f29cb0aba3759e16554b298c1c5b46b9c4f0233f7110db43be9de7d542f5bb33d284ba319238a51572625600b9b598ed32fa6e45408de8fd98b231daed45035eb6fc15419d255f221432a250963bbd92227adca506191211d7ef8a855f02976505c26a06d94aa4f66f7cb3505e94d6c1cff24f2f8e0332e5bef0403461a31e6c1c0d8cdc7031ec6b10981d66b0bb8f636cb49e79f51a8a4f9c4fef27e4f281ba3465243f3bc710528981d408d333344bf2ef9df5edb1cac3831bdc7f70de447905347caf1afb15afe96d71124431a0003b0d211ac36c4f85e7e0212eabf4610c831fa8190c0e323e4cc64bd1d3b10cac98e31231b8fd364b30ccebb8ed7bcc6b46bd27959e7d4bc936fcfa39ab666225b0e97f73d327c08186ac5cd4e2a0dfe88eb4378b1007083f1b55cb8b13801a82195d7c8d3a575604fa55bdcd80b33245f79c83564ecec122b93a6bc04e4b458bd7d69d66b936262c67f4409bcaf2a0772a329c538324f4e8e4dcd1277a15beeeb21e9fada15611ebd619c13caf8c920dd1d61b8fd4767db5898e09ce60cf6de5f0f231bf292d6bbb1bb0ac2b11049a68e8b09a91fac9a5c0c42c92f858c2c4cb2ddc36357bf4149cc60cba946176a9df32d30e6d06e0b7e3e519b93fad82edda9239b98556a999252df0821827ebcfc38703b367670d7658fb44a313ac418281b39bb353482f409884edd633637d03f1aa2e9120d858d9ff4ba87ad6c9edce395161680fcbdd57a40085d430a3a8933e71274ee5e86f3e2180a135fb009a4f92c571a9f4b0191cad2db872166416f837746795a31fba7a38309e1208cb5bff20d5dfe829d3e4181ddb739641a8d8e50b2465b20c9506e6002f7c71a9c73575e50df9d22877939df37b5b68b92ce71a7fd3be4e26e306814dffa54b1ee93b3a897dcbbf922bdc889b524e78a53c0263613d80778f2e7d3ddc341075929f5c88b8c9b924d99ac5d2d481a0cae140f98f7a66bd11848bf6e64f0a25f6c342dfbca79d68763f446fba5c1518b97beebdecd0db118e8a7648b41300e969bb607b45f6c0701f98bcd28c18d5ae8635abab614b9d5422074fe5578bebdc250d2bbfda3583510e4e1570b4ef1d98dee5a558e67ddbfe6b02b4df860505a3d1e02646f019d2c16a7f1bec77ae77e1816688b8388da70bed28dd218d1c40b30681f204c15b385dd619195ba46d6ff1f59393bd06b86a9e8bba8952d3ab21a54896a610fea3de768b44dcb3c5ff15ec95a0e7c50d280a1f159a44eaee52f7e1db0609634f97b31500e2df00678473902d0edb10845bbf4475a2444de331022333e626797c554b642fc483638097e37441a0fc7a1ca4365cb551508689b52190d2f8ceb35d1edf7706914d3fc58a8b7696b1dc34b89db87ef9a3a62cfdf2f4a1b979ee7a775ec5efbadd5d313ca28773bd6b4d93c6532b2f0a8c0333d89d3b42c3da7e2f6fa630c76db1f3e0e725a2b6e68246dedf1edb65e3e163077a4d103353abdcfdf64fd8151addd60c125ec1cd17f3445027e3d18549374a7107bbe7674be0a2fee586aef163889789795ac543caf70a18a06bf82980b21368c0a8f0f2889f9d8afb733dd467c2a8c6b15082ee6cc48ba8c25efc677b64fdf37407bce98de0631709d01b3b9a97ed9f025f4bb696aae16c6cd3b0adeffd54f746d5a1fd1232727935d65dbc83291e7559134208969e93805eb107069f6358d14b07765784c7a9db32753851191732922495f835a620cebf102bf1e10ff55093bd5b07c26609aceaf6ad0e7415aa3c14c83716458198cb68a686f086296eea4ea2e659e11f2771e32401db0bd9e2555d6598a2c88d9f61b0769e51c508ac467209d34a91a83156a838a6def93ab832a3ce631a2e9a981a87f806c09585c1648e25a290627f95d0e9087bec01945bb7fdec1ec785ec9e8b4207b0f21c2e5d56bc529b835036f8d7d2972a363801bd9a575f38da8d143d96daed435f5aeae7442f3a7e1cff68388913f79bb61d37d523b5603b2d580b2ceff1682056a9524d911ddefc0c05062a8a2ec9916388ff47efcbfcd122629f8748db4bc2ca214bcffdebce8ad46fd5b2453151f0d5cf7444a4b9bc3da270e0824919df246cf7091a5480d07a91bf90998ae2c1532391cb009e94b697ae64ac5f32fe08a6011d8daca59262bfae66557a353ba9d18620d0b636e01842d82ff665ba62afa57c7768096e1577f63199e451ab3b961cc33ebeded799ff12c8d9e4e2b55fc0ea9f2fff2165031142a13ce984d2ffb2ba5cf43527ac7bea269e6fa596b3b1962a983284b368c14a3d199d1cde044d63f6f2a3ad66a8f9c264b2deb942f95c433b7d738ed22b14f926b1ca38757e26f0e28fe40b28bad04b2db7e611f1bfa4200aea2693c20a34a1ff150a722ae17057f1c67f5888b880399d1de49d3ae729c695417a99bb96a16ea8992c57e3d97f86156ff9603d3b7cde5d474ac0b90e930d888317d915d8ebec459bc78c0daafac68db013e11e962851b0ca50fd0b0db33e3805f196f1361c305c4d7b0d9d746fd815eea251a0eadb5d94ae721072f0aa69aa89fe354228a1fb4c9bccb7ce077c1151c4f229de58cc283c6485ce4d3e841f9d013232c265d215b73d0c2b61c939158590fe252e2d3ca1f088c6ce9eb5b026d8e1ea3b2f411ea571c0f31a9842b89e57f24fa24d0def3233f1194634792f64a6688b549a83a57c0746060331f60b11ca62a33405eefe40b2ec416a4a636b35fb39c6eea5a2792bd1ec5dfefb26798a0cc3e3e80d5468bb29c592b498d19c87c37ea3f6769577f4401a0307b56bd766e107a2b67e74b65a7b26299fe33fb174d5e757798b7fb2feeaa4116e91dcc3198a930c93755b8e8443937839475a631a9bbf7fbe0ab4bae0c7f571ed4afa357fc53bf7382f44d4b7cd044012170b4153d0a86bedb0f0b3809456b7158db64a7af63ca96f56ce4e2236cb5c303d9216e9c9c97d3e6b7b8f063a8a21c90347262cf45a3efd1ca4d93b897c2bc8cfd09d861c738acff782ba84a59f20c697fccdeab7d76d74725ad72e797757d06e72d86a1d9cee82df0d40e2b1a41b9acd103d33f265da84c8f9a25501ec7c03ddf83acf7bf840188f0f6aa6efc5b86ffdcc15546a4161bfaaf76a0cccbe0acfd4d30b5ce294ea87bd689ef9e0b62d3b09abf44916597795e6790eb5b6a364078feb9e386fbe029e72cb08d7638b8cb5f3766e98daef0e7e653d678f87ad3b3276eaa79d894921bea85235368c8935e4bfb4adc94547694b52727a31dda1d46ae49907f18436057ce3c74b37e167fca366fba74246f6920f97a2f61caa82d2e0ec950ff83c12654c394e836c517d7909c028e151ac8acd9d4e2b1847f8b2e3422bc0fb8b22db355531aa5dd11985a460a707eda506ab3377c2f52710b60782d0ffef46d2133064a916d3fa723d74494f0c7b50dff9e9785c22ecbf8535249b799df364a5cd74ad9bce76de51d6a9ec0830e273c13e45161d4c1e6bd17ecdd41e6cdbd1df0b75ab7cdc6865d372b692c517358b02b5f0660b676aee1f228458f4f47f4be503cf12fee1a007aac4a2aeed91032166dfc408ed23bd982493731bbd4c19be0a228e472660d9b0abaaffe57ffeebaab3954d7d8e0511eb152a5af2565d03d4c6682d0f8ba2dfde4a8cf6d99e2be8b1615dc990f55ae1cc5275215496e0b217ceeb76e30fc8786ad192b993d7d5300ccc669389cedf6c2faffe72e697fe09ecd7d1fb59a694cf2b0a96faaf61198ce21a9d72ec871d33d01d9b3b3cbb3c9bed5811a1a3fb90046c867f0b485b9e7a13d74ad5b5693245fb9b979fd03417a8986c909eec6f05c17f63234b182881b95e44a1c82bd13df603a024dd8ea0a74d5e66403b9c8ab559f574623c63c57ba037cba494dee05c00bcd5bf2afeab3a3eb4c6aec6521f397f8cf52dbeca016a7933cb1616c81c37cb720b7fa33c87d649c449b4a666167d3b4f008eeed56a2edd3d6591108acabfcf0f551922eba38ba80de1cb5053200033cd1154eeb7137ad05f771878652aebe9688a3ca97eeb2d0144a026a0592c465578ad80123cd781454639b55dc9af746264448692ac12aebb442cb49b767f9ffb9e9f6e467b68ed9e8ff4d0042240a18f491ca6d25a63630fe04532443ef6d2b4a38ff80d1783e616609699ba2b4979f0df0edbc58a73d036ff58606812f9ea158c8626f529ad0344f5953eb4d45a16cd7cae8b9debba4f7d2bc244f5326c57859130440ab9fe556863d4541ad9815d2d408340b0a0051df72e08649ca23a13cd0bc23e4985a81bf6336ae782790030605a6314cd25fe6844a18beda610a04d7f13050d61190ef461e99ef6386367150e1611f3592bc55034b58a75069df9a57b926953ab8005b5f4a59cf9bfa8e716b0000000\";\n        uint256 len = image_.length + 1;\n        require(len <= 24576, \"image too big\");\n        bytes memory code = abi.encodePacked(hex\"61\", uint16(len), hex\"80600c6000396000f300\", image_);\n        address a;\n        assembly {\n            a := create(0, add(code, 32), mload(code))\n        }\n        require(a != address(0), \"image store failed\");\n        IMAGE = a;\n        _setDefaultRoyalty(initialOwner, 500); // 5%\n    }\n\n    /// @notice How many of `qty` mints would be free for this wallet right now.\n    function freeFor(address wallet, uint256 qty) public view returns (uint256 n) {\n        uint256 w = FREE_PER_WALLET - freeUsed[wallet];\n        uint256 p = FREE_SUPPLY - freeClaimed;\n        n = w < p ? w : p;\n        if (qty < n) n = qty;\n    }\n\n    /// @notice Free mints this wallet still has (limited by the remaining free pool).\n    function freeLeft(address wallet) external view returns (uint256) {\n        return freeFor(wallet, FREE_PER_WALLET);\n    }\n\n    /// @notice Exact BNB (wei) a wallet must send to mint qty.\n    function quote(address wallet, uint256 qty) public view returns (uint256) {\n        return (qty - freeFor(wallet, qty)) * PRICE;\n    }\n\n    function mint(uint256 qty) external payable {\n        if (msg.sender != tx.origin) revert OnlyWallets();\n        if (!mintOpen) revert MintClosed();\n        if (qty == 0) revert BadQuantity();\n        if (totalSupply + qty > MAX_SUPPLY) revert SoldOut();\n        if (mintedBy[msg.sender] + qty > MAX_PER_WALLET) revert WalletLimit();\n        string memory handle;\n        try AGENT_ID.handleOf(msg.sender) returns (string memory h) {\n            handle = h;\n        } catch {\n            revert NoAgentId();\n        }\n        if (bytes(handle).length == 0) revert NoAgentId();\n        uint256 free = freeFor(msg.sender, qty);\n        if (msg.value != (qty - free) * PRICE) revert WrongPayment();\n\n        if (free > 0) {\n            freeUsed[msg.sender] += free;\n            freeClaimed += free;\n        }\n        mintedBy[msg.sender] += qty;\n        for (uint256 i; i < qty; ++i) {\n            uint256 id = ++totalSupply;\n            _mint(msg.sender, id);\n            emit Launched(msg.sender, id, handle);\n        }\n    }\n\n    // ---------------- on-chain art ----------------\n\n    function _seed(uint256 id) internal pure returns (uint256) {\n        return uint256(keccak256(abi.encodePacked(\"Wispuff\", id)));\n    }\n\n    function _r(uint256 s, uint256 i) internal pure returns (uint256) {\n        return uint256(keccak256(abi.encodePacked(s, i)));\n    }\n\n    /// @dev HSL (h 0-359, s and l 0-100) to an rgb() string, which every SVG renderer reads.\n    function _hsl(uint256 h, uint256 s, uint256 l) internal pure returns (string memory) {\n        h %= 360;\n        int256 c = (100 - _abs(int256(2 * l) - 100)) * int256(s) * 255 / 10000;\n        int256 x = c * (60 - _abs(int256(h % 120) - 60)) / 60;\n        int256 m = int256(l) * 255 / 100 - c / 2;\n        int256 r; int256 g; int256 b;\n        if (h < 60) (r, g, b) = (c, x, 0);\n        else if (h < 120) (r, g, b) = (x, c, 0);\n        else if (h < 180) (r, g, b) = (0, c, x);\n        else if (h < 240) (r, g, b) = (0, x, c);\n        else if (h < 300) (r, g, b) = (x, 0, c);\n        else (r, g, b) = (c, 0, x);\n        return string.concat(\"rgb(\", _u(r + m), \",\", _u(g + m), \",\", _u(b + m), \")\");\n    }\n\n    function _abs(int256 v) internal pure returns (int256) {\n        return v < 0 ? -v : v;\n    }\n\n    function _u(int256 v) internal pure returns (string memory) {\n        if (v < 0) v = 0;\n        if (v > 255) v = 255;\n        return uint256(v).toString();\n    }\n\n    function _pick(string[4] memory names, uint256 r) internal pure returns (string memory) {\n        return names[r % 4];\n    }\n\n    function _T1() internal pure returns (string[4] memory) {\n        return [\"Ghost kid\", \"Ghost kid\", \"Ghost kid\", \"Ghost kid\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Witch hat\", \"Witch hat\", \"Witch hat\", \"Witch hat\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Orange lantern rim light\", \"Orange lantern rim light\", \"Orange lantern rim light\", \"Orange lantern rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Moonlit haunted forest\", \"Moonlit haunted forest\", \"Moonlit haunted forest\", \"Moonlit haunted forest\"];\n    }\n\n\n    /// @notice Raw artwork bytes read from the IMAGE data contract.\n    function _img() internal view returns (bytes memory b) {\n        address a = IMAGE;\n        uint256 n = a.code.length - 1;\n        b = new bytes(n);\n        assembly {\n            extcodecopy(a, add(b, 32), 1, n)\n        }\n    }\n\n    function _svg(uint256) internal view returns (string memory) {\n        return string.concat('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\"><image width=\"400\" height=\"400\" href=\"data:image/webp;base64,', Base64.encode(_img()), '\"/></svg>');\n    }\n\n    function _attributes(uint256 s) internal pure returns (string memory) {\n        return string.concat(\n            '[{\"trait_type\":\"Character\",\"value\":\"', _pick(_T1(), s), '\"},',\n            '{\"trait_type\":\"Outfit\",\"value\":\"', _pick(_T2(), s >> 8), '\"},',\n            '{\"trait_type\":\"Light\",\"value\":\"', _pick(_T3(), s >> 16), '\"},',\n            '{\"trait_type\":\"Background\",\"value\":\"', _pick(_T4(), s >> 80), '\"}]'\n        );\n    }\n\n    /// @notice The token's SVG image.\n    function image(uint256 id) public view returns (string memory) {\n        _requireOwned(id);\n        return _svg(_seed(id));\n    }\n\n    function tokenURI(uint256 id) public view override returns (string memory) {\n        _requireOwned(id);\n        uint256 s = _seed(id);\n        string memory json = string.concat(\n            '{\"name\":\"Wispuff #', id.toString(),\n            '\",\"description\":\"Wispuff is 3388 Cute glowing ghost kid in a tiny witch hat hugging a jack-o-lantern in a moonlit haunted forest. Art generated fully on-chain on BNB Chain. Minted by .ai Agent ID holders.\",',\n            '\"image\":\"data:image/svg+xml;base64,', Base64.encode(bytes(_svg(s))),\n            '\",\"attributes\":', _attributes(s), '}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    /// @notice Collection-level metadata for marketplaces.\n    function contractURI() external pure returns (string memory) {\n        string memory json = string.concat(\n            '{\"name\":\"Wispuff\",\"description\":\"Wispuff is 3388 Cute glowing ghost kid in a tiny witch hat hugging a jack-o-lantern in a moonlit haunted forest. Art generated fully on-chain on BNB Chain. Mint is gated to .ai Agent ID holders.\",',\n            '\"seller_fee_basis_points\":500}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    // ---------------- owner ----------------\n\n    function setMintOpen(bool open) external onlyOwner {\n        mintOpen = open;\n    }\n\n    function setRoyalty(address receiver, uint96 feeBps) external onlyOwner {\n        _setDefaultRoyalty(receiver, feeBps);\n    }\n\n    function withdraw() external onlyOwner {\n        (bool ok,) = owner().call{value: address(this).balance}(\"\");\n        if (!ok) revert WithdrawFailed();\n    }\n\n    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) {\n        return super.supportsInterface(interfaceId);\n    }\n}"}},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"BadQuantity","type":"error","inputs":[]},{"name":"ERC2981InvalidDefaultRoyalty","type":"error","inputs":[{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC2981InvalidTokenRoyalty","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721IncorrectOwner","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InsufficientApproval","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"ERC721InvalidApprover","type":"error","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOperator","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InvalidReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidSender","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"name":"ERC721NonexistentToken","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"MintClosed","type":"error","inputs":[]},{"name":"NoAgentId","type":"error","inputs":[]},{"name":"OnlyWallets","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"WalletLimit","type":"error","inputs":[]},{"name":"WithdrawFailed","type":"error","inputs":[]},{"name":"WrongPayment","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"ApprovalForAll","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Launched","type":"event","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"agent","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentIdRegistry"}],"stateMutability":"view"},{"name":"FREE_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"IMAGE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"freeClaimed","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeFor","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"n","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeLeft","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeUsed","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"image","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"royaltyInfo","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"salePrice","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMintOpen","type":"function","inputs":[{"name":"open","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setRoyalty","type":"function","inputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"feeBps","type":"uint96","internalType":"uint96"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"58043497","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T05:56:02Z","match":"exact_match","chainId":"56","address":"0x693777E674fa13a8318821919296d52E90898191"}