{"sources":{"Quantumoth.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: Quantumoth.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Quantumoth - 3553 Glowing quantum moth with crystal circuit wings in a futuristic lab for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 323 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 3553 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 Quantumoth is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 3553;\n    uint256 public constant FREE_SUPPLY = 323;\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(\"Quantumoth\", \"QUANTUMOTH\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"5249464694440000574542505650382088440000d04a019d012a900190013ec156a14ca7a4a3332a38dc52601809626e8891a4f581c86771a5156de38900d62480a2b86ef7cb0b927cbefedc7d3cc39d9fb977e4f507fd7b79073c87a97febfbf75bd6bfe36d8fbc6fafdf47234f6a9b50101a7e9b8b9fabe7fea0dd00ffa8fa3affc3e5bf5123c4e52cc7563a5642cd2605f0140905a22cd5619efd650bf3e25cddb9264d021804a4116a08949f8cfff1ce18ed3ea721fe3de143f1a416a79b95c8da57fcb4a1c47a5236ea6d150d3f8db799228b1c49597a7043eeaee27641f5ce4a9057a6a450c2b7c54561573f4029fc846652fe9c4fb8ed4c03659e3549c7b2cf5f519821823cdc4302e0a7a718195dce055632e836bf37e2205666dc10bd04c0fcb17b1dc7b135f98bf40460aa1c86b38aedee97c664ae688af6ef07670a962fb9faf2f7bf4969cdfb5009244dcea0ebe5e06c2517e9267f40b5c5755ca42e3010895ed62a1c5ecd4d7207bb0ef97d6c9a52d3fe3dde974b6936054c34d74751494efab58159b6c7a59a710d469864a52bbd8a75f873d83effbe84fb8eb2c3ad2a704e24d299c9da61a711f700fa1590046d2da1afc9ac3f79024659928c672e761f4e83d4a500d2837c57fe187cebae385784bb9a9c9d742d33f110d96a8caeed47794d8a9f9df00ab49bf174459032cada7ae4bf0a2caae06bf460b717a896ee023307b7c8ef7ade50e0e15e09d727e21f559500130a6f2cbb1fa692bb60fe86701003d7401f2316d9153c90aaa35facd877f3c096275d6ebedf95c51e13836e1b775a625f8d3f3410a767429853bb8f8032ad713d8453efb575aaa9157976d6dcd1a076fe483ccc56e5e0fd0232d0698c937c976d00b600ae04ead41f969c181a1b549c27dd7a45696fda4ca84de25cad130ec4b1f552f98ba8a0f700cb24f1602248bbad08933e674d9873db8b31a7f88cff277245628d3b87be48e2bfc4bbd37854b058fee29a29d09692da79967530d33b20066a03d5161d222522bff21c7e9d4d67d949f5546d5d48de81d1998b92c033fce7671895f8b41661c66eda42d9d5ffd5e1eed04a85d11008e6b0f6ab5b656e8d2a38dfbc42a04d3aba55f053a27355565c557140fc214a07b9e451a1e55acb7f35a1397bc1baee8fd7f6a43e9f818d2a295c4ba7a49ecc620e725b1c2650af8d2f1dde66c848be427769975dd10c002bd6e79f0669017a5ca82c9f67ae097d1b34a9b1d7f30a7322ab3fac8ac5577555a96805482afffa2aa7eb688c9cda4603a1d0ce21c82025c825db5903ac65b7120b3a4d27fea7c4cccb185df6a428f1703a13f7fee2cdd6ca2704e634dfde6b0984f6bff3dc78145e4fbd1a73c8775a9b50a8e34c211e5ef39de1217bac3ae3b71adbb7fd9e968cab819f2761f2a2d4665b56343068c8ac0d25c70a69366f5f828eacbfd357e81c3979b75e62950c48df4ef45eb7a73a3181d38312206436e853a6a388bda156d00445ceee990451e61b55215407ee519b48a31224cf8aa02d283713d2d9378fd685bb88b843cd102ae9b4fcf1d89ad7ec2cbe7bff45930d99c034ad4879399cbe0826bc8ab66b858604aeaad683dcd209223ed97fdf7c6581af50cbf42659fac1378ea87d20efe1b196f6faebcdb7d886f72047cff6320d8e5f701f83fbbb0277aee1e96754b7d14c66d105b82402919a2be47d11b8e8f3dfc81a50c1a192d50c9621c68e4765f1d7d6dd4134e04c1b6a960eeda0ac10cfaba6611f54dddbb96923452e999d5ea8629848d07800f2d07d89743ca09f264275fed6f3d5cbca2ab041d72a941aa8db4721b5f43a5db17782ced5220f2aff907292a184cfe95f06732ec7f5e2d5bca6ac1f720277473e7172654dc7828506b31d221eadf74e30e5f356ad6efa6f10404ce6c8a8faf9ad3203358cb5171c4e3f7ba123e9469c40f2647f632b28a2f28b4da1df57712aaeabd26650aa2b00f0a4a9e5d25b45da23c3daee82382faa57d6acef5625151c1ea9201b4f26bfc0b757e7efaec6b4b62634bb2a1cb29df8758e28652e7b7ec1046f29f8d30ee10f1c5aa2c80d03dc8f8128183d8dbabb7d289b9a2bcd073fbceb06440b579a774a81fac3996101e0873d8b1436e68e02cc93886d6d40df6971b3c224478cea0aaeb4e36706991fa26742f7d52e424a84dba96fff8ce51382ec8d95960431696d1267b9cd1d77c2d37c4fa6d2af0f9c6d2df091e9734b7c0039ba5fb6a014f02496b93484a2d27fa194b114343a7e981b856778dd87ac828db5d56767665ff74f9b42268b38982c967ef3038addd261959d6ca11bd0a51c3d71ac514ef8f89e172670a8538ac7cd76e5e6a2a62e9994ba908829a63a73d3df7956b2a221a51913294c0375deabf8f73effae40565c01fc1f0c5504c2e55309da10a9ef2e5f8cc65b28a3af01cc42c9e8dd18460a564a5d013df9bc9a6654e5b1f9e8373a7dfd55c40440c4847eb7a0f50633c7ea137ccb515926c7fdd3a6671960bb9ca2595b651bb57f09a6e6b3c8968a13a4f7f5c005a8ade1ae92b3a9512bcca2415d20e0037200e213e74b9af142abf4e94567d71b08373095c87b317de4cee0664407bcbf3e929e69e4c2d84857486a03f978c00fa9f20b100f81db1084bc1237d0ee1fff4a6a6b9536ab9b35750a3b8f980d0669af523e2c4fa85e55308a2e8429d02cf2e5d48a09fb5b12b634016e6110274a1f4357b2e9a6594ad20529bea2f5e3bb0b8defa97c0419d368f754f5d8074c14e31596257e285c96b545f3945f8adece41b533756a7fda7c4e05e12ec2893df8e839cb2ebdf537dd9920d4b04d2b2c69203a4b4d7848a17ae4649091ad3eae7dea4b61bf91e71a476cb8c7717e1abb6c0c2c14409e9a49fec6241a3ab4e305277ba78fd8a9401fb8b5646000e54b750773e42fac40f190a49d6426a5026d9c6d871dee6c38dc1fbaff834d2ebe9f63181cfb88b635f89c720cb88eb98d940337f366713be8c46e36e99ed19e49e2eb3b8c9f6c1e037b69718a7acbcd1b07f82e99b1a413fc0ef3f1959e930cd36dfbf8db03dfe7837a8f04643573a24532d4086e5c0a98b1fb99221cc90cc3c0602e4227878a3cf7513e73efb30aa68f764384fdec92909a7a30815eb866bc91e950d46d3fbe97469062c1fa4a296c25ca8027e38493f5241d238f90481c051b760ec2018373146730ccf485ffcfd65988e14a57c85778809ab4bfbfb85342a809709994b5ee6f6a77f701d4a13eed7720ff2eaac1eeb4ae53e34fc6b59977a834df73c56a8a7221c1181592d1efe2fddb1fa715b0f3838fddf1acd68195327dc6b8dc658b522393dbab7e8f0fc4868162ea32a4d82e9741ce6aa01ec053ea7b13342f54a5db1e32d9a63a3aff369975b5759519714b75290387f9545379a9b82a320cffbff101873d68cef1d74bcd33980e4df4e4c50df5b0e3124998ddfa7a491c3112e41eea183092f8a189925bf629193d0bf002a3706215e1b931f06002f42e8ec0eb012e635b1ca7c1aca8422a678ae6fbec17ca33c9570c854871476c0c81be1426e5c0bf0b1056d8837e875bc40eb28c6c55b2169725f8ce10b3e48f52e480a8511851f0777ba08633b2c3b12bfb272dd0351d5c0a73e0c315e5d5d4a775fefb952b1746e896f14e0b6ae344b93af81d04925a14f6155c5bc5573c378acc1b1ebe45f65f70490f6dcf4ab0ec2c655c5cc579705ceb0e0e7a30339ec6867c952f3a3f836bc2b06b00f65d55c7ae2303a800fef8205fe5c24199c23dfa836c6280af74f8b2ddfd9ddd1b9ee86edef6518190add139fbe241e99dc1a40a025449a43524235dcc05e9c01b2e5e263cf6ba1a09e44618aee10dab2c51886b5d357f517e954d6305f3b4a8b3667e4d10fd17313689778a48877b422ebb38ee09947a2d787b71b63db0529c557d717782685af443f1a766634af762613e949e2a4ad39a6f41184e04542e8a919b7f4bb097576ca44d586860be544d2b6af77c612b6084272ac06f4d6ceaa586007478ab340c25bf4fd3968b06ae4f3345bef92b31ae57152d8f430851efb77f603f93f4df6d18a3889b3f85f631161f7d63ea92ad1fc72d1935ae56430a2e33dee61c95fcf28146fda431afa96512d5b244d560a2596c78f7a9e684d94d3b79307d9c2584004f7780f247aa80f1eeb8667a22eeb1870e0ce59a21742404caf4cd3cf97898c93b7681f1f59338f34445d86649e13f3cef9e62bebaa0a7e90bd4212d01fbc8a5a5cadfe5c8327bbd30736a4961b97d1029642e10fe7eab4bfcb9c9c33845e744be711e63dfbdbd57290b6cc0bcca43adcc276e84f76ca9c49e3beb96fd2eeea0d2f695dd34268a170e98d143ba69733955317b5860764ad866bed90d2f4649dccf6c91492802ee48ef73472c4acd5b550a8207d10d918ac1f1a66a669a637af802524512844188c5a1b264f6da3416dace2cfcb778751b7ada60d9b80ab4c00d1c777c87c196c9e311ec474fc80e819bc4fa3665db678e4fb104cc186c511f7606fc01b7259ef33756edff6d074c701c709e46647aaf94288a8962450666588ba251486ea22c4536ec089ccf4876b0189ac81baff57685e64f6143d6aab0d8cfbf1143b01a0e04d9aeff72a908146fc53e9081f2e9ead668097ebe3b9524e3dcbc68b456a6e4ffb2e7313e542ac7d090cb6fe2577612b2f196e2fa72bc6bc1d6765c39742d5ebe294be142323c181e29b8ed80f30628831ebf5046f66707f3c79067aa61aa2d49383b799547b8d091ee59efbe0d8fe7a9453d2341f0b6a200fa3c3adefd350ba80912b36a803376f2f794b99e38eb64519c971a9dce92e3212c6b43e31a459a7c5d5e2f264a9d56fb9f352573f3ee63cd7b76992b6d6e8b63b1aaeed851ca4f93cc7275ca8af1d4418e1d88bbe4dc98b12540ef70812a9b24118ff6b1d8c08fa70aaa4d3b424d76704d8abdd3c6eec3ddd4eea14b7e2e572388b06f6817e9bc322b947b157551d566c89299e6ab233c39a91229c62e20a8aeba2509e08da53b2716302608a48786586247d9fa6f53d36cea6229d44cba7f0ccb6299eff6424eec139647ef9579c527ec25b34d15fdea317d6d68d491ca174ec41707c79f0d174112533359e17a832554d7478b83a82323faf0dbbd01e031e2dc7d712d74519b1e9ff026ad0f2959bec21937e58400ee154dbce1bdcbeeb64f4f3b692bfd8e844f9d814acee36ff66660a6d5001e9aa4d311bc60b4f5d8f2a3c07d1c40b135c8674fb7c1e95b195a9dcd24281dd4010973ee277861527feebf0002c730932d6f1569e1f96633c7438c8da265d0bd7196a36dfe6e2deef6f54f0e191da6e37b299fb2606613acac44b8f6aeb4923550c530de630eba300e69c6d9ee924f432a1df970b45adc6255dedec5281c6865b7725b64e361a17a83810d26e82c3ea3d8fc9a5f648655131ff2c799117a5683aaade0abda3bb351f565ad4791fb9d93d183d0501252201629bd0692bf3925b67867412f83a9238195f9a3b0cd75cdc07f7c1f56e9e2c4aa6deefff4fd050213b175fc57c289939b71a111ffeff5aa3d8630246135fdcbe33b1b1a9a78e3c90f6de802ee6de8e44b13f34a5ef27ebe69774340bdd0fd90cd5d2705e1ca1a5be113421d903205b3af66f72d358d24630defc99edb27ca6b1ea44356e6be7a6b4714e5f1aa6b1dc9eec213793ed00cd8ee255653a9b42b2a2fc69bc282e79c82107a24119722bb6cd538c9041d72be09621af0fce2c861a40d0ea96b8583652346687d96cb13e27d8554c00d8566d55a0720ce4d77dd458440381bb55a218664e29660d1a6c3f4bfc3861fdbe67a232b6e95c51d42867122cd5631cbf1d6cb234ce9d39546e60abd7ec8886d84221a453a2b5366e2bd92febd0235a594089d0537797af7ae4ce44728a581a258b52766291ba14c4bb63f6a6d7f05b67a4cf39dfa0ec8675c41139a5e2007768f965fa94bb26c8e90b82d56c19a59735a1163a069446165bf4d15299f42fedc40605aaf45759a1f179031e5fe689f3bef865d8dcf7a2aac49975cce15a85a2d78b14f01bcc6c0dd019cd9a6d56c65420c129e2ed5e05fecb619efe24543f83e7d3002f6633ee1746d79f760980d0633f19077a845312cdcab1838fe0c296b409d48e26378ec2a6b8299b08989ee158acbb45b0de11578f1d3545de3901197db4f2e9e8b5cc20b302e801fb6b8de5f2af6a55e221a3af70fdff382120d4279f8686942c80df5d1665c49ddb733f007cc65c62e31c4e4c736d8ea744931177b82ce3c7590e350af208cd467d7bb0d92ae6df5f4f665b841ffdb71ab6c76f814867ee4a576959e847b771404ad6bb6efe562ef6d2a3bccf2e3497ba54407d3f283a921ede4ec808367cd61932844e0e4d20c21a64f3ee2cbf95528998bc48df1a556b4b074dabc2e3080734c2ab3f35d4ead07a5a122f541142cd542770d88cc2edb6fd5e3bc8652f9ef829fd21bdf5498aeaf628ccdfd87d95928f4fe90d8f586b9edae3793d50fff9f17e0b3c973cf4e3032819ec767391d39339a63347fbfd8816e1b5198e1a830163d0cfb51c8e7c8d0ff9d7eae95cb7943797dfa9910b97e29c1a62b98400b5f37ca7bcebeedced27e46560de6b5ce7ad211fa15d439e49f5275ce42070e3692771197e4fb40ed540e13adeb592764f441532dad6e84c10263fb0286af3ecba7c154d87bf2477c02b4b476a67e0e54549a92fdd78081c0345557dac492c856e760ebd8663856b4d19a4b04421409ba5e4fc28dfdb071966d484ab39e6d2cdfe6d72fc00450158ad00de4340daf1ef7765002611c9928ed30042623f0a1f18d272eda72b3eea0b52fc2ec8c9e531eff61b0af6379b3bc69b891a85d9ec368ca8b922251dafc2414713bc2dd312f4fbaf10fa9c6c738e3e193eb8089bc852bbddc1358cb87529f2c66b153df391f492e5bee34a4b9fcadfeccc37882a3400652886c0e858f4a48c61f769013f3aec82f1a6bd8d06b123f431a893e37d34b9eceec433dd737df33452d11891b8d3a92336a41cf4d285ad342bcf3098e45e7ee51835f2d7e91d70740e958673a8c7359b574bd94412eaf8a22717f17955b40cc7ec66efc45225ff65728fe05b5c743db5c608cac50d74358887cfb1ee020a60daa489d2e561e98ae264f8578f756a25294c3887c4f1be7e6acff023a8dfea42d28c4bc1f8142d4de073c6e80e0022bd8c648f1485b7e678ee1a832b4df644bf213346595f57c356316a2207a58e8502847c9513167460c26a60161a3369d306a8bb76664892c8bcca44a6a505dfe26061d5fe124ca6aad490ba425479645e22d575c1fa8f60731742867c5d2848ac4c768cc95c2bf22d72a00e6637ff760e5e1d91fb48fefba249cd844a2c72b2e7133a180213745dd5ef9394d5730b60c12e02a0f750297afc04b03b5b170e29a1380735cae9472c2b33ceea83311b5ec7c1bccd8ef87a1e4f3d3f913b18034182393c7f6b5182ff07d30078f740469b4e7488b31667f3a2fedffb42099cc822b3d424a6b5e9fa73be3ecc51328714b903053bd918f917f132825942c46dca7252f4bcb76fb99adea956acdaefbe6ecdc1b6c277275432a77dd0e70ae08c31e0f0694956cdf10aab2dbd8945799b4305af0537059fbbdff80503f493fa89a64f7a5ae0bc0c1c7d5d3816ac2c7c5b5cf471d308180b1944177e38b65cf551cdaaba24d65fb6ddb521f6993c39771634afc9d0a000081a0db5c09b59aa709a1674c17795de43191a55b8e5a9cd1a660eac7f4d4e2a3b389130fb3f58e6e0919de15ea8e0633fe4660dc6899bf4183b8bfa08f1cf0e8def7c68b25bb590636d378e592e72eff11e7669a6cced6ee0aadf41526076a1c15c12cf2a526fc4f29c80107a9203c89e06bbecdeec2e62637ce8bb9af7e84b361904b2404978d3ec74d0b7403218d3939e025a0fbe2f375b26e9cfef43dd86c79738d5935781eda75b7010ed1a5e9392e376b8a00d1205992bbf364046982361ba7f92d0582272a858fce1e346988504a9bd0dfb4f78d3a8578f667cde59ebee0068bb2501d287787cecf39a16002bf84b5d55222fdfdad142a4b97e08b4d937a49aea1f2e914895613b24b973ee2e8114090d483c4c930faa6368751eae80f6e43f91a9bd470e1b83c73d9d9ebd1ac495d2770169f0831f557675f13e6e0ae0715ced5e655bc05995dad4f704e48d283557550a6923c179d80c7ccf0d56b24ba48714ed4b6593f82ca1939f290e2a9d7f7cc6c2201585bf9c4817d213b0bc69468d3ffff8e68cffea11e9d955f9882cce4aa12b9f04aa45b3ddf46c9e7771270fb9cb0a7d7741c6597e9ea4b68ee2c50f3e118beb476151539271d1191ddc26d9bdabac386f95261b736060901a554c3342b05cff7aec7d0b31a6c2c71b56cca2c563953ef90d4683ab419a7a60569190e00ce5fdd901f985f63da55a0d5c0da651a15d767f9b26b3f9a5d9d290bf2e5cdcfb5f22c9f7ad0184207707402a11918e517ae14de007a938ee37e83d294a435888e6bb51f038c996215fbb1a9fffe46777395c5e4b9be09fd360ccf493d7eb85fdcb9ef494eae09c9c50c0f92048fc3c7e61db529fff679c8d2ca03558a02ef3cca8e7f5cd20152015a641f28c8dfa7af7684671d78bec83c27cd6b10ed6e9c315bb300a4355be01f6f9539b4ae000ef40362ab9ec2eeb2c20c228e8511d0725ff749bfa60e648cd040ef4f2771719f7a4c17d9e013f6f0370d89716bad8e3f2b94ffb285233c3b0b031edda43e5fdcc4c2039fc58f96e36c6e3bf294d122a729d3b9b43b11d5cb7be7e33df99a1be8b14ae6c3ed2d193e8c7f8ea5a38b7bf273eb2fd6947791becc9bf91f2ac6c6033c541b8a739a1045383dbbd3201f4d30b6148303562426527514265e2919c12178dba110a47054c4c8ddc98c52a3a35b8c7bb13b55b52e671bf49063e4e8c63912705a0032c8dac75fb70ea3c824c475cac9e78c794237bd0d6741881ad8319be72937831cd74cf8595a5452eab3f600b6e371ac48f1717bfc61de0043fb37066f01b37f46a751e803f9a083ca3c83dc1f5edcf3fcb07f158e45accd3f539c84d5864da6d08b53989c02bfdd30b420dafc97ff9c8a0b894f4a2d50564edc0a846cc369bf55cf678cbd694db614be94553f3652d93757c094e776b5f22b4101e1ab55a808403754a7815b0d6079abc34c6ce6e04f2cf3b0b52b8d49bd3424f3a0651f0fbca36143e1744cb8ace9447b1e1fb9d2e4ea6b2a32d1aefd3132d3b3cf14093b5523868fce04174acb6a4c1b06584242eee0c31747a424013fe3bdfaf36b61a7d23d1a179b3e630f89cad849118104f8f49692b527e98ae9207490b4e4bb4e8fb79f24d323768a78a357db299ccf153590e40b8d8bde91091929f2bf90deb34aba0f689c23b3db1ba7baa702dc4bd2744def9898bd7aee3a96108710ee3482734cfe86c1f58e439125fe84c9fde8566e9729fed24790c340fbb31f79fdc85b8d92acf756e87eafe25620651e3a44f2566a32b8b9d50f63b882811f1a89a061592bf73b27c7221218a9fae6487a6f70b714c8469485c530d6d7c140a0cee75ddf11386056820df6cad1bf45de88cd3f5400a565db0fab13027431cd8a6fa706ca9d62b839c75f4556121bbca5f4c6f398c2549b2f37ad3d88165326cf7c5d53ae619bf9e51ed03e3673534db0714394b839ce4757954f2dcc9bc65393d9d2af245441a8d340fc46aa750db425c109c42d7f0b8593af1b4e67f165edf8d7c9b0ef3a17ab1fa3ca7e9d54808a9ab77cf2c39cea173dbdfef0a1820c44a98afb7b88e85a0e144a7eb82c862b163808ef0d960a2cd7bb957d1d0dad168e579a0beed604b26b04c65f73d3510b7070d83171b85cc505bf235245ef2d2f84795287d73e09ce36372514af52903e64dd2cfa8d6167114e606cd90dfcdfcacbc2b7ef5c7019313ed76f34b8ddb033d18031ac91de3e7708cde3212458a972567b8303147b07121e1b5436df96f38cdb6bfccc9ff44d6c4d3fbabae7ea481317f188c820d3ce7ea60b3369cfbd3ed50fca3a1a5773afb500fed01bd222f75c40aa245f566664bf16ceb026b610bae1f22f92f7700140586cd5d4022b675c5fd4edb2be5b0265a34f791bba6babd71dd1b6cc96af8bcac327c5dc003a6c3fe7eb6897c8617825f2ee38f41106bdf74b3b9cc08c13a55fbbd1933cc8fe92960745b1e6b71aca5c89398a3852327d2351a91508ad3ba50189b364716af68a049b55e2605f6fef356134b53acbfb02f4d2043e5b585889e3912f73257c0c276ac8e3a9bf287d1554b9386b982282e6358e50059396774830377f2828e10091771a407e1b1feb57305742c06ae9e270d45df78d166e1af901eed6a47b550c334b546fb37e7dfd5d718034ec48612104bfe72270672bdd59a1c503a9d541561fad437c6b18695537c71d46d9d4627e763a911380eb10fe5227edb94b77ef999e95bb024cd88cc84ad7dbb081931890280730d13821ac80b853971da9b61396408abd8118d20a41b145210e4bd5fd29f0ceb9d49d0f7f6f12f53648ba1a788e9a3187f02bf9b9849fdca0cb675e9b2a95a8619ca4e3eadc4513edc7bfca61758f9bd1eb82ebf2ee78129abaa8781e15c40273740ff530767dd9e7764ab6b6698217ef7db2d58cd4253b1cfb3bc1333329d2426c472731b31911a00f2ac73657160cdd91d80be677dad9c46bd26e9e1aa4bd6ce5fafdece2eb79ea91163dc6f6f3c6236c94023da6b1dd7cbe0750954b714b7fdb9fe2c456f3f9b6c3de5c31ef743541de71d821a40ad43d81f7983dded4e2f79f1cacd0052d2ffd190249e2b60c4f1db57a1dded8319a5088191fb212f7276a8fe5e0f4eba56fa415a75b54af3066b776b29d5f459042e7051a58bc45be92694d168885aa9db817bbd1aa54307abcd673a91458706d525139d30c3487bd3f3cd3fccfd89aedd648eafdf4efd24d6e3d4a20606b7ee987534b90880d5dbc061f2448f64a1319af3d055da8696a44f54777cefdcb06fea4b16ff252749f372e8e9a35d0692e8417a24976d5dba54594aa384d79d41374a7e6622a527e403b28dd0f5f7f2489229b7561cffd4a4e86ed8a9826c1a85307eafce761a9e07ab9d0fe955f4dec9c36628d3251126fcd2216a1d84b5601ef5fe92f2904adbd59e1ab6cc825721a6da9ca35cd5b7d8795a3dcdf1940b4e40f5674ef7f8f14a65ec3d2ac59c77c1d16f596d424da60f0feb98344fb923c3f17a04aba3c45b49e76b0b9b968d85c3f307355936a353a84990b6ffb08b42f0c1bcd22508d5eb894f9971813d71c87ec4bdb83417a09db09b6aff328fa89566030637000372adee18b97c52871bcd8be1e285efd245c5afa4802dde9b7d7fad0f834387663d7572b713c2928a3d005fc11cbabfbb877b5f76420f87a734df0eae669a0330355585285c27619ec2bf3f8c1a36f8220b19f2cc004d97799868f2569b6d19c4934a1057eb4d33f1179b723fb6ca3fd759ec8e3639dc0befccac0bad3d32bf20ae822ac925faaa0609374534f9aad206dc52ace8b00bf6d6d331947ae0c2b61cbb16110fd0d9fadba1b536c9e5d8e315a8a275b1ee850e2bb09ee6eca6c5723d0555e5671e7940d3fd01cd7f2ec51e38e0ca777826b5135893723aa37756604a3c8d738ddb1ae76ec04f186bec97eddf657b672efae9cd4950cf4878f360bc73ac18af0ebf07aa20f4d2d3f46fd0fb3e8e639841c15668e7511d786375fc9ba172ab1d2ccd99b2b10041044c05456c581174bd9cae2b88f94a99368f457c22d67fb8d19d8689e4780e7bd5ef6b74fdb0642597f5706448b882fbb1a081a14955005f895561fce285a2bb47fe3d205a60a3be27b67bd38f32efbb73e127bef2c7fdd783c5ab36ab9646f77a74df9e4afdc5258e8ae22ea40de10f8aad167ab826f4c79d3e8fb67cd7c2e9833d34ed0011e5092f0fd41d384a377910404a075d51061f79ebc634c3ef377df4285f57fdafb92c9619094ae76da85dd8b6f87d70989a136e1f9808ca71224b74fe706a70ee48bc1b961037587b0ec582e9b2549c6ba674b6a5c169fbea4ccfd90a844105d5141c8381e5cb806dc2f1829e4a3a166c4a2e63a7d481bbd1eff9960113eb7dfaeaed067146c484da6b078b9113f7f9305bb4f6747ad9a04680420f32f5669fe4d253afe97db0869701827429b99ca36dc4ea0aadd5cadd682bb761b7cba623f97f4a92d57663f60758c5c029f9967cd09e622acb6cdf27b143ced4e344e6458ec31585546431fd713db2daf40c86860c1611a05d366fe0756a3f15aa52fc7dc146a4931df695a4252e086626eee83d916c6c07da383bbb9ac2e2557930008d298ae37a24a53291424d122e0116ac454a3ba22fd9b17ade5a8f836f0f9cc2f3054024ddea1e82e28e1dfb1e691afd1ae412aa48a1c0e1be84dd68fc9445c7d8da3e541e3de07d974c9cd55ca28c235737621cb8c35070f693a9c732666ecdf202ae78615b618e1e12f5dad7fe3c37f02098c092ab384b6960af331fbfd908e26dbb2e5b693861d8ca56cedada3af4464532ad47a81d0ea659e70b00ec010a25f4af9e3bdd2369b099b12d457251ec070191d275e8d4be8f17e21dfe99f177d2aa3c33674cda111c50a958b18d114299a0c8422601044ada7a3891973229f9d0846cc957436fed4dc357092ebec9297fc2771790a337dc48cf3879d19d353f6b70939c28b325fb8ab917df39086f6fbf016b9472f496c049c593b22690f1727a518a07da010eea1d9d413691a88231a43db3a39503e1c124dea42169e110ab3f4da604e986a205a2b7badee8de8030e3348e82c64a5430a0efd1d42ac32ecfb286a774dcacf46788c443cbf7c41d5e842bee7aab80763a7dcaa5bb825e387c3707fd65dd194db36873b3b96c86d3ae63b97516f8bb24de751afec6dab931dc0e7fab44abba7ceb0e9d8433e61ca70643b368f9e594a761601d601eaaa430d3a2e55b0f086a6c186595f73e7b0b5879140826c22fca2038e6ddcdfa35fd99d152bcdcaab79ca36c58a14ccef95061271bb79e0c937e6ed65b9294b76832e5cbbde6ace53554436e3617ed5a5ca450df2887ac18ada5cceabf9c178cccd71811b72e67b517fe2779ef526d84f436ad3ee43dd6fa1e2380a9b1f12b425827d6dff96680dfb6568c88b6f37bb608a5495d57693d705b37be80d13eac9e1a7b769122282505dad617f0826214d72b4760ef4f2766ce88feb4446e4440fd1ca65107abbff8b2f84df08756e68326b8f0fbb30613d9294783e6c17b1c916143f22a0f37bee7edaf487e3971b5aad67c9d058ce0b414c19aabf3ab69bd220e766d1969c193a5508126f1c918ecc0f6128b1595f04c218b14f73cb02cd577a87c3a027cf9c2dd05b6ae28db04b4649e3ae8e02cfc1b1468dbba6932fc87bec45f79e68b9e264880ebb885027c2a5103ae05e645fe0956a97dd4d3752ee17a36db9bb6bcd68082c6c7b55275f1fc1d2a5a39439cd463193e2390e2aebf6059868ef6224eac63c751b85444f10e747a051d86f994e47bbe76df18c9119359182c9f5b83081fd9366837df8982927c486c1bb4fd96976f2fafd472e66375deddc8f6f3b426bc5bf362bb86cde116380c293fd6850cda1badc0f0b2b3cae35c8578366fdef772e4b634cd230843a17046ca91cb5d3e357b2f336faf1ebd9609c6eb96a83ef4eb91df3bc40a660e5c390d0aa229c7e4203a186cd6a99ba88b4ceb66da4e70e755d7a1490344a0cc2c956de6aba56af56ff5cd606d04b7c0e92e5df51d16c19c398b03d84f7c820426f6c7320c9821746914103b08829727ec468e6ee3baebe2ca444e0d6201d89fc6b049a1b03609a3bab53fbc39dfcea90c0d0144a56faa12b2192b4cea3be3cdba898af36a6e8fd4fbec77c515bbd7a700e49a7f0470bd0e337984625f2e320e36ed3c45686e4c9047d43b2b947349847b510df46bff9729bcc958ada1dd5927bd67c3be74327e999f0bbe129dc0e38dec3a524e7be60162c80058608d47efe3a8001461ec78466a2948899293bfc6884e02aacb74ad88b41517a6951d56e151f0b239d38e77a6f2e4332e4f8e5e42e744ccc4638b4aaebe1872746a86f5c4e2427113065452619494fedc0321362a851e971bcec4bf815dbf52fe996be814460dac2c933d6a312805e19cf5c030371f22f46e4d5ccd42cb1c3092aa90485e4a5846c489a882c1535ceb9c49c4e1a70d7ee241e524f1f4bd989a12f50608b01de2f69373d968a2588a6e0feecbe8f0291528b241cd4f833154f008ce43dbb639958b555d062e95ca3a7b95188539590214d780c7c62fd40b63d8bfb9fe37b4b60f7d6246b1afb9d67aa21781204e05f4a3722b0dd1839a573d447067a9a395b9f3e8c6fa5ed2f9f6b727189c03008162f883aa6c3132a4d3130455ecc2fa77bf53a59d3249f69987e68f0aa52d9a22910e66da757e50162b65f88bbf25db48698214a8353f5912471a525084248132d53dd72ebda2b49d2380be4324a04eeebee6e52abacbb348b6b254fbf83d8edb2bf6e19917fee43fd9e7938f70adcbda824eb205fd649edd529e39bea37d97ed36b70db87a56a9cfa97f359810a8a248887a7be5a26e6d473b0f9cfbd56baaf763f9205d9f38ef8386d0f6d70645d7733ea96ff43c0d2d4a95918728caa05c71f1cd4b8841278d9ee944dec4251c6d67f203b8d8af5990954727c07eb96c688e8a38cab507ce7d4316c515b09b65aec40a8c5f69cd8f4e581058f5d1ed0b0e06cd2fd019c99f6ee248efc1116b7e505c89e5cdf18d8e513244681b75dc67ac234be7a5a75dfa860298b4f88e774d706cfea412ec3f4542e92c9becd25112ed1fa5a163f8764255e10c94d13fb849c34cc5313ffcac76f7f1387942c2601e57516c765d0fe4c5500452ee52ff46b32b440cdae07bcc8926d86a7deb717fd7fdd67ea6bb746d76cf8dcf88b7dafcaab238cc2d46bab4b56be08c709127c0a9a4b4d824e2c45100b8eb41b4597e6da1d9390fa8afd4f0093046cb9b21e0af1c8f8c484cbfbf90fbbd9dd6c7e11a669d93b927274a5050209eb5227339d6e2b076c7c094808a7b21043a16d53228c93659cf4ed6b51c4074f2d04ce3bb9a3ed0bc6b6bccdbd2e8a9943186b6b389c4700eb6cf5bd378229d761f04e0d0a5a4ea6ccd7e4d8d32462b5c0f7c419a24145991aa35d9008650a2a6f530818455a42a0b6ceff1f8531c98b1288d4801b22e465d8f9f3bd8397022bee5335c8f21f54bcfc3245378fff7c766717bd50c9eb31f49c005d95800a5487607148b8028d1e53897a0cbca3096f3e5eeb665bed779c5e6226e7b1c76f85cab7954d847812eff79f27572db73477e87644a5883598f1e0fac79f61e1c4b2fb7b9b4f211991856b53f00290af2174d381b17bc15dc064fb63f493fa4475849cca895d118ff070e67dcd37e603907efef82fa301c9bb039a80f5d85f63bdebb860f01f2cc08fd7efb4373cb637f622d6d37493ff49b75cb1d9229a8c0ef751fe70bef1f47f9bb2a49a9e849eeac7d30e64db3429d84b197f2c086dd260a408fc77aa6326721351ecf9a6666b22f6c0d7b1b9967e37d279049e367d73e4c6f795e4dd95f376fc7493b1352faa3b02054f527d0c019dbe8852b98a508bdfc18fe6a3a3066daa680f7081bbe9ff84a0e6097675044bb0d253a0830bff3a1fedca2aa7be47cf584ed257b1825636a03b4b8dd6c4382aa1c85804d56d0c90c44ce1530c86772e62210a4f3d9bcceead867796965a18175621af208db8f5adb819baa8d11a92fc34dde97add3d7369626eb76f3b0d22e1c56b359e160c6d87350447d2e46114b89ebcbda2675d4596579c99ce2e3b785f5b83dee44ec2bcd5225fb2e3103abf9fbf7a402467dbd004a6ff8e7f433ffd0a53ff07afe18ba9562792f0a771406cc83568841b38a2b3015eff7c09497ce27ced336a0003a997f73722a62120b64f164bfb1c16d14819f5c3be0c7521590d7b2ce60a5c466e74269271730f1c6d60df08353e648c7256e8af0d3ff09d538a9132901bdddbe578fcd4395ca42cf05b595e4081f81bebad8142a5bc8980734d0b92faefb41b43b7922695cfe8019d5513164d1c1f3fe2db4f123c542f84a2dd5b5ded0f880089a10eabf299f2a778fce92e4805da32b9ecb0092e8b0ebfd87168c805d4117c1726aaeb039ed7ca5c339381313a616a1706e1326c73f4effdf411b5f476aea38428d8f1e6b859932388351063f13f8122463ae90f63b1270d10a99f07ebb93ce3490b5d5bc69188cabcada40cf18b273545a373e966545c8947ae99317973cc6ff7c77da7422016b4b4056571aca466353509c6797e4c5bc0f2a75dd468072ea9d2b6feaac6888fba73c98c08b9578d514e508be5051ef30447ffbd4d8440f718c2838ca05a0db549a14bf9e5ba82a8e3f27e83d6fcc9267d2f82b5dc5f2c5a54a6ee178c64ef6d6378ceb31a6394fb9b22f59cd111c658b42057ce0a5e1c57748a8f3e090a025ac6c84e3cc84c2f0e6c5912113e3b57e10994e98bab35f288ea8fc1cf763d43629b82b083e0064d58fd342a60a9a091c2d62dd73bdcff7708168f62600650f0b657d8818339821c32c9ce7c5b8fa0a6c14730b2f30c66c0584ff1223864458c6ba7a92df0f8c88f8d70903637fc815ed3d4380421efc9943c35bc62eb42dfa702770f8712972892f4d0ab17fa3c2f0348ab6847ed89f2dd94e74aa296bbf3889a607ad408b6583dfa2b48ff1774022fe821ef903cea25cdf0f06ee263c8cab3ac65ca49d1f56189797e3109b66062281d061befce1a3cb5fad381f45035e382b302eb42ecd63d7c637a75e325f0539cd6c46f638a1007cf930ec4ec07642383123186efca2b2c786ff909067e8649d644a1d47ef9867995e70192c47f1a531058b04784d68a025d0446a8040fb56560627db170708c44940a20658b6ff2c34fa86d1df76bf2ac07328ce20713cd9ad511f57187922bb9e5cd8169f7c59de645db83285a39b4b6a4393ed32dcdf5cf5c5869ab53f78378df775e57f404bd73537db5b9ae16a1065cc2a09d66b35824f90bbbc4f5a6337c28b0e4bfb0acee7ec14c86954cdbd6483cd75eaa79a2effd3f1b2bf6fdbd322acf76aa2efde8e326830722037f46a4b4d745b76718ed266a89e71cb85d6eaf43b9b4ef99651de7f66aa88e6d8dd05c692189e72d33c9b6fd924ec85d876987bdb4bc5e4d43e46af2eb3292819dff038bcba36b1246235c01c0500281bcd79ed7777a19b6b7eb7590939ec6e712cd35b33cbe191ce5e6d6566bca4a94046a63c4f505f942285e4ddc7059d6bb8d8f3d3d653f47f0c8ae32e02935f295cf2778ef5bace830b935fec251c079b996f72bb31acd2bbe1eda7d979aa91e8f8653640eff9f11b93b9b83c4a7ee4656000eeb0ba49ca8961419a91f8287f5e00d8928fe7ae00214a06e322edc5b94953bdae6e9f84bb37db0a1e9a156dbeb1f3cef632c29bd463bf3c452ac860f5e3c2df672ac24f2f5d50b1e824d95d3bf2932ca470b3a3f9453556eec7ca0113cc4b1a8a27772fd5a206689e45e5422916e742b53ebdbc7565ea24a686efb4c4ca4e10162d726298c661a4105e97cbd74cb06658b7fe61fe31d705536a6c9d12906a55683145f361615c13efb5da64b3c7b2d6ee44437570a822237bc0e0ef736152b5df5d60cfdffd7fc27418caaa93294dcbc2fe7def437a9ec3a0d45b03c1edff75955c585ad35920d808b0d2c61229b964d67b34465c5b04b4d90de5f6d552e3c3462545dc94fc6e7f15a4a5ef580bd9e50691ed74ff1eea9a3169ccf968815ec25efa9ac7578cce012006df104d9fa1751130283b47b7ac8895b1c91b42855cb476ce99590eeeeeec3f16a8b8672ff2a6ffc43bd2f7cacb4a9b5879f51698b59e178a8961265d661853e85ec385eadb2f232a6417e4f4a8b7aafadbf3b20afdffa11a4a979d6de3cb9daf14bc4039647dd19a3b3c16551a5041f30af4e6d40b61a5acaf991ddb224b9c0a0e625e45a79d6535390b5a1b8b5d31da4a4a2f37fe05b2fb9ea58bd3419f916e89f2ad735513fbd3adb8a7e5e793f511430975edfbd8a0423508c36bba1c7de8e9287cee5f2880483a5e54c0af596e24276cc890bc2052edef301896cb4cfba61721d9f02b9265bfc8209a5a382418a7489060b28607296d7924bffab6ed19b38f73806edf068aa823a2f0876616129a059520dfa6693f80e792b92d8611a7ca3bc6a146e28da605098c1a77f993b40e0d4d2716d227f2931c4c7c3a4c58319d22b4ee1fbdcecddd5f8bf04d05cbf7b79a5cdb851fd37e5d8ecd4e26c68b6aea79ec3dc1188c994e7b1acfa9e12543a727f6ec11da941cd232748a93a5dce0a78962891b6daccb4ec9303ac010a76664af993b580f074f71275c7017e1d737cc3657f80a5f880b8afe2877c4551fb21475ba30e944041ce4422669109934f3bd0c1ca9b051cfa9366dd59bfe987046198ebe87b0e1246972e706fcd32b1d2bfc86f927ecacab8f341fb9524881809e6c7cbd5281dcda9fd25cb0521665294384c327210bcb51f44551ac57edf5a378f992818870efcbd4168265c4e0907b7a00b211b35dc9abd80f7fb7a9e70e093b5004d508bfa968443bfea2893d7111e6b7709f26c6fa49a68e3dfe06b8697c2c8b98b0ee0051b78dbb63e42a0b4895a721d66152b5b93d9720795747ea1288b779abb7645a3c50d9fb38678f8eaf3413c84617fa1ce43f592b407eb40a0d6f247a751b2ffa66910588c5ead4f94c95bfffab7ae1bab9abfc24c0e53d4850538fddcca4902a933b8530954c0ed73a0e9abde9c196e8ea6e518a3873ad8c732d533e71585f1c20eaeb9f4fed33bfac4bba539156c4679a1376b91ec97f1e3cfacb589196188968696336531beffde06aa308f7a83564088e163b2cd86a185b763596085c9aaf229489a05a04e09c9331d7bc1950ffff2ef7b32a047e43e257ea180bc2a70330572e8a2938a46f856ced2ec32265293b51809027a906197d0c167510fb1d18ad6dc60a4c91f19242c150a3ee8e4bb7608bed030491a97defb051ca1e141fedeb9fb26ed0e73d276cae8142da799dd57a75dd1390bb5ca02b32951c567fc0ea43eb69ea5c02d77b8bae2cca6336122cfb07761913791059a2af4f12946ab533fb0870c37a136b9aeefb3695f413ff248c3d1e422db8f8e259bcf716cd15b26c9cb0371cc405de0de0343c446690e8c10a8741cf184d631e7518e0c754524d416770609eec73a251ffc1f174157ab7781fa9f1ec6d57c1b5a744692e040a7b52fffc51743aa014221fd14323d9a3f639171d305ee50d48090cf7d4369f651b9a1e48666969a5b30d3bba445d1dcf04d5690d9de8ac7e3088c5ae8066e87ff1e5cc242ac16f2b09afd9cdf1b4437d0064dcee0155c9858b0fd9381823d2fb11ab73756c597a8e76de3c6b8b6c11489d30ce31b26c615e96761c9fc4fce2eee2c7331e436b91f1cf578425bd9c405277400ee1480b189bd968c52cb781ba73029e4084384e08b0f5d9b1bbead9aa60e7b8d97f654dc4bac55a37736f2eb71f54850cb1e084e3dae4576ec92637fae8bd74c7846bd2cbda26115641b3d78e477577c475f64ef4f4c5312fc39a0196ab58293137a1a283856e78ecdce4ca825e200bb8b322bd1fa515a0de3e3c354a20e7aa16bc9151be0f432b681b5b70a7569d1d8031add4ef239c8637ff76bebb929e0c18b4a8fade82dbc790b4b45b28a1ac528044041bf8716b1c198d7ca4560015c2dc2eced64b36ba032b194c52ed4190edbcffff2415b486a3f8c2ed1bb920d7e9b542171a35926a3b409f0ae80e15d1c4881d575c7554b65b6f586a044bdc669fc387a1039810ae6420ed053d6b2806cea2e241f86284c75cbbaf1669f71fda82d5794b6637cc5f2836358ea31f5283c5cc51d0719cb84522f78f6b6d9bfe386116094096899ce474ac70180404893595f032b2aa706578962747e261ed5a3802525f9b80cab33d7c4f599c7f7679f668fc41e5b33d534d00880340dc311bd3ec198fd32a0e906af9c399c69ddf0292a150f509e93a81f27157978bfab9cd1f216b0b99c872a7db9716fb262404ee97838a57a6580039f8960409f0640d7a081228c6429f1deaa9da403590263a872bbe6fc07e22c042c7e4e6a71edd41ae1bab756bc4d6afe746982a4662a418e919cf7fa58b6015ebbd73d5d5b47187e6d1108b2bd78e609dd5a417a2631baf28fa2223d8957da7b0ad23eb5817bf34db2e7aa62698b230f59e7f3780f8cc770f0926c5fe729270e91a43a02796fb15e0c884238558ebd638b361d318616cd79117f8e239a068ad905678a6e617e89f4a78a689b71d80a4fb040a549f47f404fbf1f0a74ff05ee1381b24241d6e2613211f01ec4c624018309102f8187a63b38fc50bccc3f8390141682449c86eaff70bbf37297b3bda80658edfe32d52b9606c7645763ef4a5309d60f7381d4893f667fb2a24721c1b8e300d3a449c2151bb6af102d8990ef5237de3c071029c6b045743f9a94e81cc62919790e9b19bfbcb430ebec56551f5f14f4df3d100445df7b18202315f8178875ff368eba3ad5d8ccb45acffb7f54a286787d88ac05ae85c478d1a76023b6dfb8d290c8b2ae6e88d2c4b90e3cb6b8bc34bed1c811c3953830798c9ae1f30e00cc3043aab3ffbc6da55e7a2708a1184a58dc39017e66b9ea46a72d6cecfeafc6d5f0fffdbbafbeacf7530d05a2d2096720a17567e1cee1d2533f19baefe512e2085ef51eeb9f93da7c194094e9a56a11a9661dadfc8581d293b54c7e801c98d1ec03c55485be59b391a67dfe6d14d610d89c0400226696d416ca67fb6376ae24a14ac1227085d1ab0a39e5590d2344ac3a9539eea62b9a1914e0d60944ed864a6d2b31aa827fb731b914fc34a662737b4474905518b0aca1ea973a61bd12cf626904b32d6d97542fcc1ae66f93d49dc9d069552794abf4075cc92f476457e250227594f054752e1aa80558679d1d9e3cd8ebbf23ea36d2bef91d6c95c234d194b9e7348c9d84cdcf190d89a3648215515c25c3ba50bc726863826a80c81fc3db8134ce86bc5f6c0301d8798849f8763e1865adce588daaab354fbb495c104828ae98d2a8b1aaa1e4b54113bbafa058fe15efa00d4ba2210c35748418bff8ca0c7323eeaf677c269279c78744aaf0a147a9fa3d61d4d0223af0c4777f040e127efb137035b29c58036bb8865339d6ec27db9af6cea4b0c6bf53978db2952fbf2b4a1df16b8950e5a52b4f60364d53d601542a3f7b2780d6c048b9b4f0846defa32de13b037f421007d900afb6422f41dcb01c0741eefcd5c7ec8721502035c68a844d5a643ce7d83fb1b41d0bf527ee39158f6db5e094ef8f45c74b814207fb419c6807a9d4968347345ea97c3effc0180680e16da09b057c32c57064497759ce05cc4313be5ec93c10f74abaa5ac6f5ce542fbd16f6aa1113698c41e1cf3489eb9846452b4e4ef20ba2afbf677084c67b5b2c800e11ac94ec62e61278a303d50715973887321cbf59dcbc9078e7277970093b1429d2873a130668a61278d829a950db377e0e56d84f10f1fed8e45babfefcebfa8875985ae76c38f78360fc8b81ab986b717d3a6b45fa4fcb876076ae47f4624e600ce4704af14446621d3ac22e7eb6801a2d3b4596d5733db4cd33bc1d2cecb9609b43576d3733a9dd8882dcad90814ad01bbd9ac266ecb3e5e050a2cafebad47a3224dd51a622bcef4d24a163c8316c98a6c128876de5add018339655d8c215bd0523cacb453b83ef533e75dec0bd6cbdfef622bc4979779d087fc02a5f8272fd775eaf4b25f38534fd624af163e5780cd85130a97c9924ccb1bacb90bed7e9669a69666d06e58d0c4c63017bbe6c2901a987a3dbcdc223357c62e2eb61829a0ace51c098a6df5bfce099ba5e13a39a312a953f87242af3da7c15014c2ec1edf7168e92c0f349847007b2d9dcc25a1da026edd08fb747c592ebf2972463f467a7428be8c2919c4d31464341c0510c95cfafc33e961157b44a5b57cccaf7306ae4661791e19d8e45173b0f9a964fcaae7e98d550b9eb600c4058e24d1099bcd5e83b7de320df59930b52569fb517a9d2d1132359158979b06aac375037b67f8f78050ad3046fc24f80edfdbea346eae962e5c3b801ce86ee80cd54e5f67ae7cf1b0c5a5c9c9a4e531235e32d962f294149ed4414eaf67ace5855e486bc6c66b873473a7be68a155e021610835c1ddf41ea687227a7b8b4941ff438249d8e3093b2910b989bca50d651d763eb8d0696c93d7854bc689036c8faa64b286f52c0deac8eeab46debf5b21ba6cdf580ea16736101103453aceb04ec2f37725a172deb17645bcba84d178b22fc3a8f06d80c51202a07d1097f7f5d0a9a084864ad258117b1d64b41937da2f55e3bbf31e3ce1b80f14ac661a3151bdbc05ba3506e9402378c2091f9ea89324185076f327f7b9c07a6c821b4bbb6922f9bd78d7f7a5ff39ea1438cdeed1d0f5d17ebd50325ff1b37976f9bd00afcd462a8547ce0aa27c13869930ae54d2ec6cac77acd0408467c0b9a61dcfd6d59d1fae34b127f601fc30e4e607603c821df39020bc56e953620a591f6c6448d0663deaaecbdc61c6526c898c17e441d0b6b14cceac2bb1a026b608529b4f04eefe4dabfb3c4315c0f27fc57f7025b90250ace3d8eb957a401a059ed2ce7526e60226586915de0c2d7952347270c17aa6f0fd940510d942c6273c803ec4cd005c5b4927117bd147cbccfa3880efc192e131038e8236b5a8628a6d0fe4a00853cc98e706b40243881e5ea25f2ebe08a3121f9744e3d961f27199c211c25ad01f0aa2832e7510fa5173cd8cadce0ca20356a48157146f47ada8c6a7f5d7ab238cbd167a2547894b1030c72bae51f783eaaa8ce05eb996b16f5d372f4436751987f8d23b63c767b1854cc3243b2fa903de94f13cc58af8e6e243f458bf066ef6777aa0a9fc491ea185d691b146c02a7454fa05ef3d5e9d6d2ff054b2793bf0dc58dd7e83a5697b09ec0a26c8b0773ba157370cf00f61613b12066044fde142e88c92e0eae0ce567d593467cd3414f4cf0cde1b891b646ded6656009bdb20e9c9e55fc7af8983a393a14923ea35b659edc447303677b047ffe450a9c1c62ba3b9bc8ab290932b1926b15ab0c047496dc5d9e9cdf6ff39016f097e9718ac87f706bbeeb0fcac567fe33a2ebdf890fe5a5971168105d171d03081b1189e3ac223c563131db574cae9110ea2549d6907132fa35fcf7933c4d16e515740b2e8fdf26f9aeec4376cbe5ba1ed8e3e04f63d95925f490c3b3347a7e7d22af0baa2fb49a27b02c51c31022e145c1492d0a5cd51727a9622de59da24d69da68271e011aaaae5bfe50f8ee3ef14595c2d1203528bbe30e3a87401344846f89474843034d8e0ef00602059cc61c61e53ca41e3da6c81ef7f179f2789d171a9ceed3f287bfa1c937161ddb186e13548819f738cea5481c4480896c920bbf051393a4753dd0adafbdc7bbc861cbbd67d8b8a1d094cc743f709f506f232bfc26f7c5e4afc69843b2517d325c3ec121eb9979a06993814fbba6786671879f29ed26b30d38143f26d8dd5ae7b281ea710ae78be822fa9890e08e2d25e24bcb0b87f9a50bfb83966d3eaf73a83a4bff0adf1997a0e7379a1648747d164625aba610324ebbf77e874c297116bfb97f4f4824729d6913c2dfab9cb0911b36ec1b9af875b798b4a5e4ff6931be4d549be73d3b7604d495649e90e469f004c196402a7e6abc2e1bc992181537e0c908dc497ad9cb8ce5d940a75a2e5007e97bccbbe10749d42023a59d97cdcaea6539be132e6eca019000d9bb08730287e28e30b2ea1dfb554432dc6e064e283cb0eab1983cff72bfd9593d4b5f7cdd607c95e58d32ad55e3a0a5383d3f2385c501013a7bb87ea204c1b904bb8dbba6f7ddccd496147734be914fa0e41649623def5bcf36b84c8380ed6f8daf0fa4a375b2bd6d18039dbf5c070d46e70096e6a9b942ab7a38a818166b6b379360998e25066733505ed504d1d2741cc93ae4455383f3bcc1b1973c96b088136a7587f7e54001d4db938d94204a706082ca02654d6c8fb4c79969a018d4f649fb4172f3ac5aa25a6a9630b6356823a361d669c5b8a585e8eeff3fcf734016a5b9fd5141c0f8f464be10adea26547403ec4a0260d8df10a0e86779b4081ccb548883da3a40bc13ac24d5248e76c4389172d092013d74492c8739014dff58892d3b6079ca73d13f08501f10a16c2230359d5863989acded2b878d3107a8268f34a7665f4b9f8a07c7c33c393c4c87e45758453d73c64171fec870b2e2cbb1e1969fce409a1e8b7b81d4d2e5de3fbd3e82213f6bbf27aec670a1982626022eef0b0301a10dcd1000d97870ad0eb1dd926156ebcfbcfcfc91dccb0ed12f0e7b0a8ae3540973189ba4704dff1d3043a77bad4e676b351553f82f80ef4178a5e6343dee82489d76ba9bd96f665c1f625ab08fcd7fe90f1f429d7202af24873037c2ff6b9106c69994023a54dd2d16c1a0dac5fff79b750b6642c0e48297bf70e465e063da696179c1cc0807c5e3c1064925fb816f886fd90045084c5aa042b999421849e12450a3d7558961a8525c7be8018c9f45d5399714d467c649bc3d6251a25160c79bdeb9fc6feafddd4a4fbd71033320d380000\";\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(\"Quantumoth\", 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 [\"Quantum moth\", \"Quantum moth\", \"Quantum moth\", \"Quantum moth\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Circuit wings\", \"Circuit wings\", \"Circuit wings\", \"Circuit wings\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Blue violet rim light\", \"Blue violet rim light\", \"Blue violet rim light\", \"Blue violet rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Future lab\", \"Future lab\", \"Future lab\", \"Future lab\"];\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\":\"Quantumoth #', id.toString(),\n            '\",\"description\":\"Quantumoth is 3553 Glowing quantum moth with crystal circuit wings in a futuristic lab. 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\":\"Quantumoth\",\"description\":\"Quantumoth is 3553 Glowing quantum moth with crystal circuit wings in a futuristic lab. 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":"58039485","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T04:56:27Z","match":"exact_match","chainId":"56","address":"0x9FE22718Fb0196195263822Bd930FDb20852983f"}