{"sources":{"Gongxibao.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: Gongxibao.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Gongxibao - 7788 Cheerful white rabbit mascot in a red gold silk jacket holding a red envelope on a lantern street for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 327 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 7788 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 Gongxibao is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 7788;\n    uint256 public constant FREE_SUPPLY = 327;\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(\"Gongxibao\", \"GONGXIBAO\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646b44100005745425056503820a84100009062019d012a900190013ec156a44da7a4a3a92755cc91201809666d79ced63b23f82fc6db3fcb46b8e37620d2cd618d69d9044ba2ee33f806727d56e8b7e2ff89f588fec78231f8b607a62f321fd88ea51e703cd2fd4fff66f520fec5d58de901d331fd8fcdbb4e5e623e39d93a145811e30f4424a8f9424f8d66c3baffcbe59b51b2e2d6231341fa3bc27b6882161f60fb86ca9a92ef967af3fb1ae3464c430c30c30c2f4d4881b2d8a6fd03dae3e6da4f7f1e7763935decd7d025377310826966211b1f663ac1a4a4476738cb3330d80d18abcdff411cc099cd2ba3d57c7fc56f256bae71c62f1e8c9efd7b51f42343fe3b20a779bc530e3eabab4912c5d43c8a92017072e31408d4328f682514ff43ec88ab174d495ab00ddf326282dde857c4f5d715278cf6dccc4c0b77342dee5218b8baf6bf14db06b7fdae4c76a0796eb7ee03a03b5f0cc4f824c6ee012d7781be3436590f49946830455f5d3b8f93d62737e5e9702cf41cf68b065e1c73ea8251153290ea5b4062fd31ea00111188acf926ebcd94b52e201f8e69acf40456d1227167d46f74c269c5b319fd38f071b088388759788534261c0dffc5e1c64521f91f9770675f87473a13e5120c411bdf9034eb61c6e20baed80a250d24561dc055c22c868aafaca5a1cf123213a6925fc28ddf8a22cc310a0a1a24b0cc907c47a384fa6c64fc4538c73a78ccb75c36752c59eed7247ce59642cc94eea175fdc476150e8cee4174e9aa95049880ace7f172a0d9e3fb9ba7d306e5156bf292c3de22097d4d5c5e1d22862e64eb1b23ea8cf31753fc8a980c532919beba3b7e7ef103a3cac4fb06ea6ebc59bda7168b8f3e78d7e73e8357ee9fd2d20905024439445a1bf7a6f7439f23e2bb25656d69d9c25912d20643cda571795a1706ca08cd6f6f075dfef062666e52cd8abfc02d7f0e0bb1d73bb0c7e7f3162de8ff537fc1d4013e3c9b74163aec3d3e8d832675a6f23b4442a691f77095bcc46ccecb9ce5ae5b935b67a5dfb56a0096e38e7bcbef3b446630a770b70a8412d4a56956710562923c25ee36dc5732e5aeb4b7e5e77eb41afddb8e210fe11569a790cbd03e338d01fa72fbee66829a45daff0c4cd4bf370e9e7ab94a2bebbf3b57628ffb733ee312c361958168f67d4ac6f92240fca5afafcae7cb799c6a797d826044002c0bb5de27e1045f53899658db8b05b253b1be5f201402c3c266e6e635567c451dd77675a4bda926ca150a9798efd969bddec7a89cffdf4fda7a9f362d829257c4c1f309ac33dce7f3f0ce0bfe6d5a6589c97c99b8295c4bd2d3eb5af2d2bc29799f1ec6c69064efbae15b43c35d954a8d9121c0bd296729431f876ffd83fb27675ccfc2b80048bc8be077bbf240e1ae8120a5b45c633cabb5a2705168fdfbf1bfd8bcd0c6484704c25f99ce2521b5ac273eaa136c8cae00138803f0c9308419f576c48e1e96e7f6da8418a545a47e17b9caa32be028e10c5e4ba7a01447265195da20935a373f41cc074ade4dd35abe3672f4a80e9866ae78a4f27700bee3f76367f55630f7f5fb22a63df8edc04b734d52f24c762c5e985fae031348500375c8d70fb5750a7147ca79f4fd691b8e75acee3934e1689da55dd2ed9b85c6a7d1005a721cf50447a333ffa770190fdca5108dea2def3de02b51deddea976fb1e19799c226eb7381b9053acaa1aa52adfac9d7eb634af02c69a62ead84534af564584309488e9be7ad56914a3a0ccd5006a91e919523850e5130972427635da911ce91df18ecd2c2fd9919d715dffb64c1281e29f120ae55933c67f1825ea7e3a6b265309138e3e5e0e6025d4621add743eb7dcd5a96cbaee64e515bbf724606fc9a6386f193381b3529abd5dfb0e3ceec2afae1fe527f7a0ed22e591ff9c3fb200dbd29a3c1c2bec50579e95aed8d6a06d67d981c8f660488d016610262ebc5a7475f0e08e6f31168f39126e55562153ead1eae5be76e9942b1322d9c11a33d924b277604686cf590fa2ce05112a951129e2a51c998267be9eb4167f298ba5e1ad28ab5421ba85e34947d2d7be8db96e6ae87f52b8506cfdfb91e77a2aa29a65a200c6058719cb66070c9b89d9d05cd63b7bf0518b6f830de47df8797b42bc9ae4bbfdd08d55504cf0a50c1f0f01a4e966431ecaf49458e1913f67bdc5bd2670fb3acd84e3e43c9d8f95198cf93f044d1b012ee4916e72d4e4a1bdaa84385bcc6848239b7bffe4a48d52686347fcb8812563e45d463af1c41b3d83c480b1750ed14fe3941d175ab755f80fc8ffd593ed9391ef3a154feb71a4329beff07f1fb9266045a7387362a2d0f3f090d5c210a2037b5625610fd43bafe467dcc6346bda98693a0b17e71a32c2e91e13457ab5e0c6f6a4c0e0dffd7463582b20b14b90f5d1490d9af931dd15012a99134261ea94182b726fbb73faf696e27759fff3c40efb89b43f9d99646caec90dc94a2b233ffc5fc494698eefd13b699adb0fd0237a6a8b4f4953dc19584d3f206dc6bdf8356523fad1d0c065cfbe20bb48f129abc2dbaf91200b633e9281271dc6110dc05a6b206f60c40047bc267b8301a425c35f2fd2f6acb3e5167f12d8ae071f323a6a7c3b9fd4af7f9675a3176f13fd7b14a970f87cea217be0fb66445323358d42bcb5cf3dac7c49f3c334195c83cfe9bf94314926c46220cd5b72c0f70410dae7be784fc566204546c00dd7367c6514cf24882de8412f2f6c6a34e6013fe95f026b99321441c929c6e9b32fc23b2838790bc8112920fd0cb5cce0d99b6f77b8c6f82c4a13e7ae52c717d51c811ca6154ec8793b425c504845c05fafe7d1df48491781e8ce2dab37e527c6834fd8a6c5c42f4484f4777b78aa1e3350896f4da7302155ed89cdf860bd7675b9c84f681e763d163fc2b91887d2258464eb8a6b7840c51578934d83825b2296dae22b9ae4aa476ce2eda5ca2d591e0c7fa951b19f34471a1a42933ccd5b551bc23a61f735ba3ba83e95175bb48ec52835bdfb0f6ea7a6c933491991c556713b136d5d53544503175d68d30f1afb9605b0a891f7590ae68002609cfd6bf564817c4068e7c0781a1549fc180b4ee4176430a22f097a99af0350c03018ea3581ca100848611786922b12d52682031e88339aeaa7fb34cdd4584aa5e95154637071408b7034d268fb3ee6b391d9867a36c500af21ee06a1daebcf67bca654c29661f5026436597d966d9c9248b805739643fef8fc0527fc7270effa69bd0b38252a3ce9e5a4f45fddf555948dce37fcc2b0bcbf5d2b2cf6be72ac5d56b5938b6a74c6b11280527db42c68afc9206a73414b8f5f91366861207c6c85e02e9aa6afa467dfa4a15e058c6118e7a41bfee17603ffc842121cf0ee11bd29a602539ede6dc747f389ae360f644d1af81c9a4163f5ccf482963841b8415665881bc78e7738e1db053dda137b5a1532e48fbeed83146623daf37def8dedca15091ad57576150d97c07b32ffdbc004090f91412071d74c07232aa7cc0ac9ed56cd09bf73d71645eac00a057e8ea4f42e73b59f6c18f9ce3f4787bcfba9148c3f0579e5810a06a6190d9e76e04a4a5a62c03e4c230cbf1d728160c69cbb7685706126c41789bfb2a90a7e6b7cc9ad4cd0d7261c7905ba9d7e2a7c10f65c9df7c1e62112335834babf2081c1358f0b2fc7ce51b6981df1c7a488bc8a7ff5f23853d5de8379f15993262b3b79c0dde0079768a738aeef4eb71bd01c3636c5a12b3297f36c15389ec16e8fefc9b228d7b11b0b1cf6cbd953fd1d5ceb84855db255d56e92f0d58121d4d9485529c7e25121ea930319d5bea50cd7dd04bf6368fa208d5e510dc5529644aa4ce95ce65b8c52e2c9f408d034c6fa35acfaf7872bbe72edfacf62094a2837621662a824a38f281c91283dc2f2978ddcef1bada0e2a8a34d8c0626f2caee6fd073bfd4f1b301b945e5d190b5401665070da347b18024ba7d028d6ef69be8d5f71425a4afe569fa00a310e47da62aa7f81fe420dc000fef75d3192f962464bd1a67e463c9462c4903d38f5c3ef510b7d4ad60e6b64aef19fe21a89dd2638fbbffe7dc3f92d812605f8a009e8d6f532bce6ee7c8804071b09614d7338d662f636c87fa82fde47e79168d89b14bac39feab07e7d55358cd790abff86d20d4fa1b88b18257cf0dfcbcf0d0f44359c753282f27e07214e77574048bf424c24a8b040a72b025ed12c1d2956e809c89d4952bf17806497476d77fd735b281948e340a8319f8641594757fe1083aa50818bb7a8ee79ed5da283f103749421871a84c408a991ed85e09e87c09029d05ada350063971ce0f5071f254e044ea4a3290131c096dc5f0e114e357aefae36867a2d8bc62b485de1315b35057c83ea5f14e29dce052d08f72eecad50c67b026cfd08266e47600feb13497b1051364649feeaacb8fa8d9d593b7dffb1a0a5472c955012ab1feb674bfc5c1dc692f74aa4e8fdf88c436d1d60df38e881f4a57c2bd02f68ea9fdae33249030ccb366e58c05655079bdb67f3d5f7ce7080789ec226ea17533bab38eebb8a1c56eb73d09b3258530dc917ab0058f01cd6d46f8b2ff266e7e516e25d8865467b9fbbc030f6f62188fcad33aaf3bbed3b6b0f90498cddb8e7c6116b6ef2ede00a24d6cef78c5e23ad645b36848a250f81a60906a50dc155592795ec8c2a3d3f6a3ed8f52e5846778c6fe763f0dc489216066e395d243f9620d51a4391388493a42328cfa2aff1cf14d66389d95ce2189a823d922e1b1e3ff2c3eb00269474a0b7144ce445b1c4cf508438c7485cd005345c6676aba02fb004c67457c3bffdb0bbd88c9b8dbe8b2dd2009903c8c5db54061676021c09e84126e7f9af257db150784f7a8ff37c10894824e4084f4028454a918bdc2bf98a5129d1a32faeb677af508fd6971c6a3ad7453a83ff452b7deaa2fe4eec6bd202ce71bcb920f5da8e55604e3db3dc42d953b3a2dde9a427958c8da940d2c67ad2fd6aa07eb24a341ef16c22fe60c62e5ff72b55e948a9510f4b346e5b58ee235eab4dbf47eaa514e82e7a71800e531fac866817d6218655a12c4ecc1ccb320d071b18d5d17d438ff01b5b2da3a35adcb2b73ac5fb5f2032519ee9a2407736a4047c8ac243bd71c51bfc86cfaba59678c0d5013b20ef4e84112d27d2e2a3eaaf9dd66322c40a007500762686a854684d69bd8667562c5ff389d2b68a3344c14f9805f233f634f0c8b1d8fdab12658cc787cc990fa8d8c134c9599c168f38d99bcb037be7c80401bd836c5a2099eb0994fd4f31666aa87d38f3d7003b773a4e1e584d0176cd76ca54cd369e0868f54d9e489b6ee010cdcbb053c911981873618dfe92b6c20ab37706478037d1592450bef63d2a8d16b9e51d49a91630b37998d1d9a5105efe45b709dcfb2aa31328610e79d4c68ea99a0118cb1fb0dcead652e1bcfca2431f32180f35512646685e8afd87932ba5532613965ccd91d5d6e50223734210d735c03e5b4f2ce1cca61316fdc3d4197c0dc955a372cf0ac40dbb1d10c101238b1c7bac7f0784360b6b3bf477e12b13ca177f9753035c116596934a4533c54f1260d300a5ffd78621316caa6c0e26b9dec469571e47d866c9b36f1e7d28bbc74cbe4b429cb02dcc1ad874bee7586ff4cd2433e4effd6f7d38801ef985358eca3ff54ec155e1e6adea747783407b8d62753049a10c4f091a538cabc92a5580605be79ae47d12ae4849cca0d2839613e7d8ad00390bf3d103d3084b3683f2cbe7294ac6d9e633b35e92f00d35d5790704cf1b78a01852eff0d4229c5729054d45a40bc14a3e5dba35b5384754a1faeedda39a966bcd444c3b1be34470b8dc370cbaad51ff93c7b3a8a801aa5712e3a86acec6f6476ef4cb7c057cf5e4efbdd43cb1a0e96dbd752185416bb15defc9eae4d3ec038b6e2599310efb1578d242ff369ca9ca9c79a60b36bfa50bcf520eef6bd908e32002a6715467ed9856f5a80a562ecd951ca2ed51a1952164f14f04af514f29f3f7c61e96073bf2ba99f1e4381287714d420c0e93fb2560d1c719251563114728161aae479201afd69458917b5775678a7ed4b90e3328de74384c28282fa94c3d12a1d3216c27b74082e9dd0f10e047a9104cf294c32a8723a2f28bc914285b52e010cbd3c0eb84a482749b15899657e6821b08967c8a53688dc616ecc683a93461338507014a95ea2667aab54e1a05c2edc5ee8ebe0abb1e632d045bfbf7ae94904b152f23e3544d62156fb07ff63d6a33eec62505b38fa634a8993be047133e5d263e2c5d20485bb5a895368fbe6b8274ba458230da82f0931ec7f5d9927b94b4b6ce0637e793000a42c7a8fb730a2f031c40ddbdc0c82cda4f0a7e54e60f88bf73cf73885aa2d2cca0a8eeb70326882187b338499dcdaa85a40a3050f0e1fcf25535a1fb39be83d101b3d6dbbbf86588da97b1f6083c607f462460bdada9eb47b8913cbacab4fa44ab530c04be90b6981a101b70a6de742da2decf1763b18f263bf1b92e2c23bbdea154b2ff137a72c27dcffdaa9a5c0426ad14af080918bb059c5aadd23e4e6a6ac003c17f54aa2fb845a854b24856c3673e1fb4ced3d38272715a63f249c43b920fed91625a6d5d853332d88a8e2390d34abc131a852ba79eebbb21e757504e9135563612ed36c33a1d3684134b6474146ba70163f193407d425e08713f3b0742215894a05fbdf460f1bc5aa0c24eef9a3ae88c31d81b5c6fe5e9bd01b8b559862e21eb2f1eb118746a00edae2e7b1b7504e22f5612b91940b39df33c6d69c397ad75be45d6f8b81a5bd8f8cad89707db65201c857b595c1a25cd09d833a5d8e2774309e52ca6aa7546fd11be9d87ea2963ad30cd288d2b96fa5b3cf7fe30e32f391e1f2a2f5d596760b3d39d4f07a48840a5f56cd22de429c72306e2956b453ae9a044b4123659bb6efd87346aa8c2e444322a1665d2759856ffbfd565e265f5dbbf8873752d142807db70b07de42265a54fb3f0439931531fa40341a99b444a2314375aee3a98701306d69eae98f3af9c873eee0bfeffa4eb4951431f66cc8b017cb9f7a2b136cfc607879942382aedaf4873111b0af452821fcf96d9084d3de3aaae3c93ddb421971165ef268a0aa95884cb050d59a46fd990cc2bf0456dae38897e93ce78f29607d8f2a5dbeddfae96b29c6f78947203c35d000636dd0727a3a56a4990f48d89ef8bd35db9e87dd83e1c786e729f1513b8ff933ce7cf8de235e5c7a66e562afffe8501c08a0d93d97782a2733dbb0c621f1cd4c59534ab7e312864b2c5f11ae9f2358dcc46c96b04dda2d7bc6b72539c8c8a32a2a0b5860c83759d7e07ba312564cea258afef38d340239567ed0a7b6b535124878ef49b6a9b8984e343bd17862437f570915f764366242fdea196ea82f2017efac0a50ebf83a41402a625c4a854ef28260fc1b31ba246478a56335f0998bb11ff05f6067e00eb019b7f105bf1b7b6f73c00b69d465822ac4ab31911faec61eb0699250ee6a27c796d3523286c51882a130c274f1e858178a0f9a0e8b939b1881969b647196c2892d97208d945e8db1dc3bf14a5836e15b20f31c31973f3233379ac50ba519e9a22510849a29212e8fa322e03fcf2cf36207971c058199ec48a76dba3e37a8bca71f5c1037e59c3a177193cbb335ef19d05613d83f00753e33294ecc3d452e18d695622ad64c42eda353c075dffeb3c5b1e234eb12624d435093471b0722f07a8569b004954b3dde44348a59ca45f345c5071602b78c93aed552b0ac77b7db653fcc048ef3bc7ccdaae9a31b054b0d9704ab1a0a560d4fd40c12a64f5651a555a7a30f8e02e057ac8f8159bae464f2bcc38a7f8b3c5f153b18022347800e672aaf29c05baf4c5aff534e8bcd08e2ffada727055e61c91cc41ec0285b7daf532d4f45ae22e0df06dd3d79d82d5a379335c26459bf2ec955bbb8d12e8e810624e8ed6e02b48958572144ed6155e8ce12828564e14a219cf763fc605c22cc15151dfdf2926fe5331a0c9420f40d47ac9c1fad89e3c37a9dade163cc5409d041f6f75d8d251cf153c00511f30035cba3edcfcca0ad84c82ea797349c941fb5ea4fea567748633cc2ff636daa6fa32010eecaf41e0ae3f2f95431a407eb5ba906f5bdfe05fdd59c3c5df32d171e0eb4d4234e478c2790ab777cc13d70e819e16df03b19f1f6b86600b962dc16f318907809abc92e2861fcf05f2ad474d6f908a1751c2194e926a3cb5d869b7bde48449bb0f543df0082ca2bdf11cbdf86870c034c5b06cb63d574dfa000f5555d41e598050425148c65bfaf0b3af873b6209f0842f16efce6d7e95220611e757bc825d4d9df06b2da2bf580a2d84eb4d08823549beed639de3d8f8ba12b57dd19e4d555fb502a9124e0af1b7959c26c4cf98e9e139a9180fa6a9164efe27cf625b38050d6ac13f500f30e9611bb305f4bafb04bbfb8389ad974671e32c6bb19306fecfc0179e3c9fe41cce8754458c2b5abcd58980fcb2e26a50b462df53bfbe30a746db875a40fdcaf8015dbcd677659298845fee5de80050e091896a45b910a3db2803eaf4237f25e2aa16420c6f800c569d86b40e7955f6e9f4250fa2afe7df409b6c42f9cfa0b2048b470eb083efb6eaedbe60af1b3d3dd378bee8617cf14f8c8d59a7c36491f73033b0c46bdc43857da47df2380164616a32866383855b01c6f7f9d514e21002c54770f1ade35107a4ad94fd02e543164eda841aa2b9f5e5ef9b33942e25f8527881bbf126442f8b20fa11b5d60da881db1c8d38a9264fa189ad07f35e8a89dc20be8f316e3296ee1f9af4b601fe0a474cfcfb2cf11ad88d9daa5c3360b0660e616126558be82167e3ca319995be257281f7e3d7d1f0add7763f319a8df47da2f3cded1af5735a669f5f8636987c4f1dd445c923c816cf5312e872db889c0b314c2e3ad3b5f70fc6c3a9a18bca4b69596d823f9c38cd98b02ab88c747a6a72a2f5f26545fd1128ee88ee1fad641331ccbba2d077dfed53a32e423fc7f2f2fcf6a779ee3ab3a9efd3a0fc1a4013b8c2b695aa740717183d5c9fa035ee55ae2847e8c5a3c7193dfb5186c81a9cfde410d4a55cbd85a84aba0052e47dcffd3b9bcb99941e5d7b054bd47834c191e60ff967593471e49c32727a216320c4b69d53eeb84e6dbbfbbaf5372862b5ecdb32fb172f6eb2bd97f9204087976475e3c610ed20eb12158c8c1b8090f0aa6e63e1165c301d693d247da2c73e327561005d9fd1221e95316ec11a93d42c5a24c874019136d4043f509d5e37a82d3c4203fedb4598ca77e8d056d4d73f60f54001013cf2b093362a04e2ce866a2320c1d28de7b990b34d598f15ff605cb17df5c6a9a02769633fdd6e0f3ad4a6aa8a0bd8e36da47d648688f3a2d1f148bf964b7b53a743e95e608416ced542692797f60b2e3154ba9f555179c08c859a58b760c15e3be810bdb5f1ab8bb522f9178140dcab40bde31ba42b050f803aa02bda130216c1da5f404494a6356e64c957f295d4d911e36d549c32cd03c8a3f42d611b00b60ed39596e5642a89a616a89d92c54687944611a757ffcd21bbc6fdbf44b20cd5f1bf37e4900fa560b9b51b83426658d2e853b832a2ff23f577fcb44c518450cc6a47f7f6b3abd53da3323e0af2866640139b606c0afe4abbbce49a937192fbf36dfa509cecff724c88f4961eebd81d1061abd4901387d89dfaddd7505df88fb9cf50b0041b4bd1e4970c76dd3c103ad80e75b9ba12ff2d2ede5fd7a7e2cfd8f3b37815bb86211699138614804318b2ac68d8ef9631b729ab54c399a29a4e36e6f722d7da397a5905340b297113bb31b8fcf5b48e9c45127d30f7806d9019f16beadf153a32ee9c7b863f1c4f8aa1ece991512b5c79bd3aed826d429929872909d697104366755a7c581eaabb65feae43c1426986f3b0ae7d5ed772e674058ffdae2a64e5aa943527f19ddb427bd84a794841e0221b69a165d62328915492aa92b624d493eda301e8e9fa918f630d29a92b2141605c44a180486420135291c17b5c1438a9b74731c5eeb3d7247a57f66de18ae37860e990d2f92358d38729ea6628e48c830575f6eca5d2356cecee7d0a21b04dbe6094129676f3dfa0b6f4ecfbe6feab77bfbc374f2370b8ffa65df20446e32698b72bb032c39bf75c8101ae16de799c17d50817bd889da222d088be52ea6950f736984d377e42f91403ab5721b72e4f62c49fc2bac3e9de658cc0fd61b8f5e6e1de94aab3b26f2a0b737583074896b7146b559cf87b3032fc837c488f47ce441fa2149def4331411275f1704c9082e66a2343a736df9e4c14094046b78326e752264f9c56b750cfe46d773aee00eb8c05cbc1fe1b3cfd40ddbe848ca7e3175c71aa00faaf145e0300dfe00acdf295bef0b151f173098000d9e2b207e4fb7f3b944e5c816335370a832f047fa69763f046852d3203f25d4bd80654e117965f518e51545d2137860ce6fb4c114f6f0d7139b8598a08b15ae7d24859fc76d06753cdccc0ce702fed047b76eccc0de8ec0e27e91d3906c1d952b496d0a335f1331f4901ffb8f6ca8cce17c6aa202a46d87081507abfee53563d754e8f53884f43ded81f33c90bddf6e988d350ef5a8f63614154858d5c0b998beb167eaf7de24b85045361f8290a63a2a7d00ce979451fa0f3adbb3e836f32b1083e42701fec92e122c58da17f0c4dc5895812e467959b920983058918c56c445cbfa36ec79a4c29183bb8209576a1954b208ea8799832d4e59a0f34c057b11fbb5c30f3a8dbbb595f46e456cbf569eb36c133df3dbfe68cd5ac304c35c43f37c81506500b52237aa34ac860c4b92467254e8647e6dd39d659fe4450c6181ce6d72554a91b1e5c38f6b3051ba315fc1bfe157fa17bfb2c9ab289ad8663aaa63e3825af456e8b26f36c42fbc8eca23e43006c393787721bdb74adeacd4b0bad1aabe1476499d6e1a9e8960195bffbbf91c0d805b039cf153cf79846213a03f817724d31001907a66cdfc32926cc1ec35d3ad9a238725bd2bef9130bf062c591866dbafa7129af265ae845bf378df574814c88dcf724b14373eb58561833bac685e05ae833c6b139ca3d1042d6df0d70cb7ccbc33929d1a33d4c950cccbd464068e2c1ee68225a0d272d57b261c6261658eb67f365178d75eaffd6083ca7da4777702ba09a6fa8f039d5e491c9f1faf79ea0b72a97bd287ea2f86d0167610c96c6daa9f6bc9aeb9e440c8c19ced3b212d46a2438e16375cac60e7c698febf30e729a57041b9e4b3171bdc051ebe256bce4ada07d7962927f4ba502b8019cdcf5648d58f161192b88ee245b564b38c4299b5b5b8817c7595f3740f69368cfa2849ae3de9bd8716f07bfeecc0347941467f95d112e09b3c68bdd9692936e0d1691b38f972452908f7fc1205fcb1d6fa7c3db42c5eb7095b5d69e970e7d580ffa7b3aba9c22e21891eeb3dc2c4a92798598febd6b554ffd4fa79de9ad42a98f9328e779201437288482c3540cc9debaee106549cbc8f904cf39f33dcb96a4f19e5568a249463182c330db51dcd5e4ace6cc4168c96c845122e0a896486d9f38da787d9d212eef5c009055912c2ef682eafc5f415724e003130ebfb37f39dd8544be0179557216bf3500ea7d19aa0e32e486e62c133fbb33cd25771d0d4d5bd5cd2317baa0d88f96326dcaf323567dbde98ed43719ea32d0304feb1ef04f7230daf27cd67b0de6a91576c2875ffa7a3baa825616ab3195535a0142268a90460c58f67383a69321bcb7a2e049a9dd4f5582f64b746f4fb8c25291fbf9958c5ba78d3b8c296d58778f2de4a73d005a5794703e109fbf36123529bf0a4232987492a15eec9cd9e28722d37edc913cb1fa2524edf1cc7c03777892a47ff61c2dbcacf0fd3e9c1d4a0c5b45e263dea2f5c9a78beab98e7c5f9708ad3bfc03f80aff7bd15bb9aeed13666520b91d30f1d090eed33fd7998fce1895e92e549243ab153f129cf293d4c217b6482bee1f9947d42c621a1e04dfc742554111ae6ea772164f08f66fb2e090ee6c385b6dc30ddd2828f6a0c3b8943cf500d68545b17ff09a886e27831258b542a47a3595c95cf3980e52e45e5940afb5699651c5a5ea0a43020dbb43fce8344d3cf47080c6086f7062f4c7a2e8334ede1c97e96cb19e79f3dd7871226fc5cffc9eae574089a6ddd466e2616b8c3e17bb6a1309c3f6fc1eb46dd50fd8657e5ffae97ddecc1b922dd66594ae22b9dff5c1b5636698cef7e4cd153e585ec199521dfc137efed9cdf349120373b0644e32f543f359f6d55b55968d8bd9f70061b8cb01274f7f44f149acae79bd48e207bdfba0daeb4f904336d8ba5b6c2a61417e9e8c0296743a59febddca814d799846c53382b8406d7a14ba619ffc04dc6540eb697e926eab10fe8695ddd853f01e82a1111f89a82cac202de1c48c19212eda7667e9385b466c29ba332e4885fea67be20f31594a9a6cc735aaf12199c5935c3aa5dcdbde55f2ee871de1d63b355c406b7aa8a8808baf0d61d6e0a3b7d352b5cdcb7bf0f01e07fb337cc7da72a777a00d81bece1d2b68a1a393e6df6e54006f0c17af114f3b8ea93680dbbd708ed1bf1dd79c4efe9ae1e18849c8af73de8227e66c14054fabe9596549c104d46ed23900b2ec4f920a45ff797901616a01be89c96df58df45715cf0470f1557b8f53bc8418be9ba62d22f45ea24a92a565e59e52232e00c19e3a1630a5bd45d413406c349415a7b2ee69f0bc15fdf5099e8bcb9f9ffcf424c27d4325cd11dd5ebceebbf029be9a29699faf5e6be7ef8e0e92671f2b91d9788596abca157163650586b2de49669934c6fabe76fea8fba0daa2b57e0ff432e44e51564e163a06adfc0825b17822a1a0357887233403aa2db6524de494f729276dc95fdf1cec4b5925cfb33f1ce44d5fd146e355b956bd5e774a1522a3966433f54d400ecbd5f503028b47c1e47488b71f90348eb62741561931800e9d4cb37a51c43de932b437b09317cf59e38329b694ba5c606a0f840e4db0f333fae785fe8060c68fcbefda315be93c1179982db32d2a1a8212e9443177a2d39d89b2301382fce5e53a7868e24d4d05231bd53d0dac38d66ea0f1b4753b1197fedde968ca718be98e126e9e8fdea2cde6198ac849c298e2640eed6fc49890fe0287b5980fdb5ffdc653207fb91c704da986cc94261893f6f79ae0681f14202f1f74d4c7458976c94cd10e4ab96b8e377b65f347088b96d3bbd5d1054f4a2dfc18b7125d86432d2299188afe38907e79b7024d68e66d516d7ac5fb7e9e6b37613e4486faac3cddcfaf3388e722d9c7a910349f65685a63ae5714daa450a5a276c6efafdbddbfa8e49254cadbcd6fe2a2dc327f548a0b9e05be75b40c31fc6ce376a297969b001f39607877b3ad8f6f3cc61945734dcf572b301b51702a1f47351a3a587eb8af2dd418a147f5caf886fb8a6ddf418785667accd1e58485bd77fc3893588e9d370b4d68c802c15db827f1311bd753bff6c3dab1aa03d97448f921e8453434a5c486b38167f66ae3df4e3439b8d74c9f65b0f638ce271d058dc07ec072525f92d6d4b2475dd640f1e89923a959187e55a2689b542748414f223f0e747ac32dffd53bb2fb26e379a0e78200df617a03b582c10fd3ec0cca1dd84dd08263aa1546140a4a646e43957fb2f65488db258906e8a4f4d9f4801afd7a59f4315589239ab2a57e76907ef03ec2dbc04f99dd07f3331daa6fbb49437ff35347886a98cdc58d4cd33b3e7dbff5a92cbfd7f816f1dd10c7359d9b33e1f28099f7700b7b789b769af1bec35654b975a72e0c3f7581083287cad7649f45a2ca86239bb83d67e863f8ad53f98e9e81927a8796c646ead668da043d37e3e05b7ec2200d69c54c241f9b0c237dd3c8cd3cc1b709ac76e223b2359a3d0a815fb598f99232edd014e04fc7f7b389ca5343b66b9908edaac9a582a2e636d397e3dc80c713a11df63aafcca23a0d46e7c8ffc0ec75582c52abf92254ee3aa12baeb815f6f034ff5701227366dea645f9277a059dbba7800be6e5f27c315709712d12fc522559757c655e91e947c1a43390d36679dc74426fa09c99dcd3f90245668fa2abe5a8cbe311f8aba5edf97c753545087c8af17eac41e94f5fe975fa82f822bbe42edc5cb110f87b3148993796b1b091b943effe591a2862bd2ebaf8b292514ea6fcf55e442ac72804611e4d0f21385b3bedb4d4b3421d97430c90295805ee85508ff34ae644f9e0d9f660ec7a979c7076887401a977eb2cc84d831f4937fc0a1c3e974c3ddbea709d4bfb728830a30a5a56f9f032a60fb913ebe8a16f82350d6749ffb0f7454ef3c7aee12c12e49e52a4b0908b213a419bc8a22163ab7411d61c3c75626a06550f660ad5c58d78187d58ceee4a46ac23c7890a55cda9a0a8e7f3ad4e24440eeeab89789614f1b8cb076c432aa6759d09e5b1c5432ce50c08e7051f64b03bf27bd39587dbdb7143367ed98e3eeef650d976da6f3778cd6ee00c060c67c54c44a0b004ae5f67b29aaeb3869a3423891a63795f2921525220e8930ecba073e73448f6ef33db6e71296f13658c7fe280d41b1955c125d30084fd3bdd53f81eb02148484f89f5f60078d528f8d7b55a496a956f7e5f612d59b51e7a862c344399109dd7a42a345159539bb6ecdad96989dd2ac531bf948190b0e2350ff0942ca7f6c857cc0f6ba22bd17f1f27edc32bdc431487e7983e2c4231a15b35883be69e1b848e5698634d2d38627c5631fb8bb13ea71a72e4890eb70e08b9853c46734b39851498307e08e26ef664115e60314a7a0ad2fb56a335484dafc4a660905f55f372a139840400ccaa046bce25129c3a09a45100799aca6ee72faad3c0ed469ce681c3a9420f72b55280c3736a27d3aa10fcc2a1d1a9a0e76ebc374661d037e1d26a94e99c3c67f1e345f5de4a45446855e07a2abf11c6ad87f79de3cd971c5c72d66ddf071dbd8c8f43651f7105327490d132723e5ff0e5ee6b0215430a9c3a5e536a73ea3155e3b80f0a2ca952c58a2c592d078855fc54c33bb26852321a9e18123fb6f4c4d8453c617207bf6d655b3e9475bfe3338166f38f9d620db094ae31d3cff118709fe479e97f5ecc9b89726e4aea76f4bb1b49cd420be9d98a7cf8c9a8e1a9dc58e484ba5e6913a90096cf15b45ece92b4ac79ad3612cde7cb37b21aa07b77e3aae6e972b82398208367c2fa8e33ba1ff051c8fdf19ab788fb4fd7721ee85345e7419813b7f70cc6d51598438a746eb95096f5f601f6ab6957958bb84ff8e2893df4160af9e46f452dad057e7ebc6cb0d36b72fefe15052b4498fe92b98672ea3b80a38228fa52820ccc52319a2d76fae75dce0b5ce7e783f80069cd33f7aa98e393157c81051f4cef31c50ebc0df8143942c70bc2082aacd42916a056114138a4c9a06749ac88234a67a22479aa4b5c0b329b5ab3d236a95c1f0e562865329ebd09d13701b4c0edc5795a12af99386c235cb1cc2bff1ac7a55e273d9526d82c6e0d1427f8bdc66d708453ab3c823d040ef3c7603b56f01cf6ec97a79d5e2000e2ce3851281f2c5f363747d63c1b60079e71d9272b0c45ad8b99e027e6132c3e244de3efb419291568279279d5dec3f78b7d72ba97301ef8e35492b9fe08ef3961410f7c8a0262ab41c8d5a916ef84cfe74810e25d54eee24e30c67ab430f21368d60c720373ca572ad661ac58f0853be3abc243737a46bc2855e16668cb41b38044ca382ed6425fbb72bf9d8da31693fca164c3806252857eda3fef6693a800d97bfc005c2d256d5db58fc706690ec27aeee630ed4e4d8cc735767e22229d3dfb35f29cdfae1c0b137398f6655fa591c7e6f7f04d5dbdf60e1903bf86bc7a7e9d85dfc7cb42f7f9a43b2af0ce3fdbbccdc0607c3bc3e323dbff5cc75b8361459c2dd5b13eb84817c397800e5135be2972fcd385a8134e145dc77f1db6c475e81c684f315e0067a524c18f1237d23dabb1932f66bd7d7bcfceb9f9f80b28ac68b86f1d7d0c1356cf44fe1ca38918e6fa615c79f56cd3965461e5f296f3c15f9519170b46e73827926d38f0748d8e6079816ae2bd47b05339b35ba694a25150651430ec9ed0bc90b1cbbb72576caa546dd74c64238ae823feed7e21ec019a4eda93497cb917d0190c1b67c18a9f04e2f078430f4fb6620ce366757d52ea24f4393098273b09a44407299d9395f9bf6c5be0e67839abbb8d4a1e1d4f666f49f770ee3085d2889e9f2a78939aee521dec0ccf73743888582807f2556e9f9ffc8d01aaf20b44f04861de6cd41936dbbcf57a9112aafae0f34e21fd889ff4a39a8a1b3752f1fc455958b419ccdc5c93f3f165ed3a40960d09b966fb9ec83901545e4377fc9a685831334fda1107b4efa82ab8283c1e270089d519fc0844daee8bbe717bd6659ac9980ee0a7493514d9fa564b3ca4d2dd1732feca321d96d5dbfe69ce64c10de29df116c098a21d6d329cefb10b2d42258cf7a2d74d031cc40b8a2f5fc13746fe41387b5faaeee486fd826ef32b492af2728face7f845796170ea1c625a923bb21ba65a8095c74532029fc4910d6ce53f9241e00ea7a5463f85cb4c76cc113c208f26ef9ea17540760f7354873894820b83e8a9ac6754a87e4075723c425e7ff7d082052e9ba70d216ab754f78902818ca2f3d97f3e272038c62b6a0e827e75d4122a039d75ace2d81481d9f371a51cee4918490aeac15a9a4e9dbf8b23400c348680d289e2964b7e811a93ecb1c6413b17ab2793a323fcd7526bb6f836307f7aaaa00b4a088604bd1a3ce226e3ed3115d2b1c5808206e504b6a00ef075e9b5d4fb8a3db684051c8b1baebbdc13769333a03aaa6378e5ec35fd552812b3c4a781c9b9bf17e26b7d2c118560a39a0045cf0f6fa394d486ee06efb0e4697c3419a5a1387fc9f1c8ebc5e2261e4d05bbfc9f23ecb377b95c115bd8dfab4beec6b7e177dd44d619e25eb6793ab57ab40de94b8f2120f41ef3a48ea277dca3663bb6866adab062dd579d87f6906524dc03ceced86da065aa027a54d89842d43137917daca75f7b88821e66cf96cd5ab5a6dec6ddd65f9130fedaee0fd87573efe3c00b4404948357f565444f1f42e78d84ee21de61a90f8cb99a96a46aebe1670fb3a15bc862024f1bb777b8382e8c118d457c24524b05db6b858b0d765fe2e7d8dbc54ffbd71a53ebb4f186232cfb5a17efea50d3c780b2b9cca5c34f1555d45f3af00994cf15afa50a16ac2baa3ab44cdd20118c60e1be26f7bfe24954d264fc7b378a08eb7dfe4a92f2f4dab2c08ce4af3a42c27bd30ccb5494fc398d947df65a50fad31b3462ead19b31572038cd76c5403d903ab846bbbc2f81dfe319498da11a28cc16bf9fab7cb6e8bb658ebd31eef8eb76e39bebfb9035870a1ed2f1a0ac48f02b435fdf75c0ad43625f31f35f839d0ce738779781ac99289ac572bc7fddd5dd3d521e3ef655d58003dcce829c9df1f7c875b9ce42427191d7268908b9650fccb0e9d2168730d9538d5b61f6a0b3bb95d7f1f991090a522e117d337a106c05df3526f8c1cb91f3c6fe50455cbec7e393120babfabf77d1137c52117759ce1e4031f89faf16df83f9cebac2b6bc4b28ac768f2bdc3fa24d985cde051d0a3f9b68c1fbffe4912aeae1b4e84ffbbef12b081baff8dfb8bf0f9a7deea9704d4c5c8944b7f0b5e96542b5506a4092c51161bda32f48e9610f57ece5e8ec25e2f0fe961a5349e51c81801485f0f3a3bd15e90cc1b632e088d6639233fe266dcb743f5e831d1abf168fcb30a5e4e0ae2e1bcfa4624fab9aac387cf369e55c6e8c8d06bd79ac462c918e6f05d6a2082aba3327831689e62094b57c0ce2d0ad869aa1e9b5322cafb8e5dbc9220aed1817eed9775e141f48f1702444bc6bfb3da8bdb3ffb2ef1e8cd435dd7bc043612bf6c5975a542c7323a2e97d683af948462f1239fbe69d3db65eec6334c3f34c61fe00c6de6b6a2630ba8b0b8248bbf917f82c6473a3d68bba7408f093e760ee56363a9af78e3b85958e84898ca8d8a2783220de23b26100f2e24c4b5865bb89af9c42d5558805021060f694aaf1345e3ae6a47807937e1282416b5444ed8430ff144d2760b69b5b32b16b2dcc36a8d97264eef4ef421a6d18c5ca750be4d5b1d8e280cc035eaf45034e4eac1ae19a1acda12b8a22090a5d759cced0b466c5777b914354b494f0811c538be6816cbca354630efb37ee8c752131cc68d1f8b50d6566f52efabee5a19a6a3011411bf6b806570743f094a93e0ed67311ea11ddfa687acff546cf809d305f51beb07a5f33723501e0bbe3b36ec71571bc292f1a81050df9349cb80377ced7f5867e6bc7f86c1f168fd49bfab2d31399b133168599881474c5033ad5e5e6d1c990781da6a2d8067851d86be118edb5b0c184cab686a5cd506b948d6fa3d4dfd59384fe3a2f6c22136ff0324cc64550e58d918cbe4da04d1703b1c0696ced5f6f61b1b20ebacb943b1658e6e8a5c00bf1ba3be112cb03efa6427a926ddca1a67af9bfd0142bb3b46e056368b14bee8fee2503e6d56bca963ccf831c9865840309a9557b47524ad8af65306bb579c2b110477875ef0d24f12529160f59a5eab70e9d4bd72042222f222d9615f092686b034a16ee43ae03cf29513df5d4ad42af5476703fd359477e1d5f0b669e1cd8fd735158b995ccf13728e4296d37af28f68dc859f4400a9d5d13ee378211375f46ca15ec826d646655f94f014fc8f619d37beace6ee9786c6d789e583e54405d317f5eb6931993a2c6e9bff4ddd939e84d2b36dd59c201ad95888692d3b1e258a280ed961f4398f03e532761a0d8793dd51ff631380734fbd5fbcae90a3a5fe83b7e979cf8b630c6b4a8daf547e581e2431b7a674e12bbd45fcf65e1e6a4dc5231bad514abff0590110e231c6ea1027698568a66ce46681d1ec4de33da7f319bc835dd8eb75f5c3c11e39aa442821f259172964714b40f8fa518403d8432a7e8410482df720153d2b7964959390a4e94e35ade2d3f426c07f142f9861f4e6e64248fbe1f5f66daf6bc812cc257f61167112d97b618ca0d116b22f102fa62de34ddfa698d177b44eacaf12eda4fbf76c0b0d5648b615c6cff188e58ffa9c8ae6913480192cb4a4d1e86634095494b4b7145aad4bfcec527640f698f8820ee06990fb935fc4917732c96456fe057c525cede3936a4ca87fce74702f20a077d56d94f19f81a177cb3681e700294d62e39700a1e7f211ca71a1f960d1d5f24ae4bd4e9e2030583c5dc5d555d236d1124d7fb819c2a8fc4287b0f3815c8286a98b611691753000fec708b8c3fd86edbab15e88ef8c40c552f84d60725f0f9557d74a0a4370846270b56cc57c1d1079c511aa7e9d5ef556e3e1ecf5a7a31185d27aa724cd14b3fc5192ce393a9ff0a8d13b7a37aa1cf697094f1a31a123079521f967610b309831b77b9b738aa0930e5c70a02a0bdf37f25aa9aef0d311aedda1fa2cc4b6a4266a0fff764a8cb736e8c9c9e8cb254c87d8596cd7d67b2051353501bd8ae9123c2a4aa08ed603837694ca2ced817cd04d63df2329afa33544e9df9c00a995fa18b7ccae07e933ff5c53bfbd64f87d84024a30c513f3375f7e518fdb544efcd4d1710b169184eab46c1a66576ae847898fbfbfb39b84d4aa12c4143d5110469e454c11c0667fec53b51f8308e1e3954d7725522feee4b577f7a62d3ed5b3cc9c708a474ccea881250527b9b3e7e388b62a151a0459313e9422153ad7bd0670fac7f52d78099a6cb3bc7b302078994b21ac89c5eb7076e34661b57a40b619a31f2d4d02749a0411b489bf2fbce6e325ecb93d5ade80987f43ee8f80045f0f6ef1753e3485901ae9741fef888326fd8de8c3f9e37560ab882ede9ca4f6493fa370d8edbd8c54fa9bc7289ce93ca924ba2fca9ab0f8e1d40018cfc91da0b51c1b933b6a70905d5d7841e891eba47cac850b105840a85cc9ef7b1b3df1af4b161410e6957fea76d3a5b21cd1ce8572ce690a7755a262bc544ec151d6c6439b135fd177c34dac1a96bcfe5b5852fe9cab56f246bec0f33056ddd97fb13b17fe5a6f935f23959ca0bdaf09eaafce3c183d9a7869ec0b20a2b073c9798872cf384b7cb666139ab723af1ef481c2a423c3d673436a764cc97e09e50c47ff19ec88457495437760a92a2d3a0e66006822928c4cfa550d8264b3038a7ab3f26fbc05b6af6ac40bab6f0c4e254666bf7d08350fed2d020bfd6790c7cb0574098d84978651f32f6bb08e558ca2d6b45b059bb669abbf367e3b9ea9368b110465b6d953af92e3d631689d443f786e065e8215e3f3283c5350d5e38c393d2ece0fd2632de0be562612eb762622a347f9c738a41c7cbcf41886e35da3917616632f3e1d6489e4896405afb01a7d1ea470eb2a7e60026bd9e5ce4b5b8225c570744245fa03259bf89ed53df252d712f696d03afd8c346397591b0ad7eda42be8a5a96a7e99c326d8d72cc654d892f9e10d5c9869d4da9d9c58972b1b44b65bb2e85b4d864ac2606f06aedc3ea4feda3dbe0ea5929e38c560484cb4975587e6cd3acfb9386d30c64a089e1ff556ddc03562375e54a69a001c7b205531da710146b22141c05e5279c0309365f5235e002a9bbbc92052a1e0775e86d40a8d0c352d87851da91d31368828b2e19135771932a49e49e86633cdfadc73e8354ff25d126bd9917223f5c9041e1a7a2a90e4b0cdeffef49f2ee5cb53ec851be1962b6b67ac73fbef0979bc196235a7db8e338b150329f1c63a2b6fa223795f10f0eb66b775536f12a950926e8edf658ecdc0ef102730c470d4ee629fbbe9216465cd745bec4dacb2ce21a90a82fe5fb550d71f893a01da0c9e77004167837417d8990667ca647ca7c461281fea0d0e58774c73619e8cf40646e0c6a7dbdb15c9d45d5c1c51724a960c86d3ee21726c55ef676076b62ea1f0319c6a2dea82d5d32e54a0abd6a8db64399fe328bbbd4baac0f9ca26afc0af54e13e8fe5783d72c980d63ecb05a9b2d2539cd6306f2173dd8293c4dd3f9c2fe037d5147e5732e97091e5a0ab66987b9e82f63b450fa7f462108dce34b0a8131d2d4877f13a2e9da28a0ed10dbbfe894f221f6f47581039b7a76523069d3bdfc6156f90b235465720c0153b32154c622705d88d7146456ee931da9c52cc0ece0a2dd804453eddf9935be4fc6406ff12b3d6e8f96278be71ab0e7e5efb4019adf287ffdbc36efcb5163a45b17c42b443585632e1f21bbe7343909dae747c0e797ff1e2968359c2520d36c7ec9be52e866c886ac67c243aa85eedbb4ba80c923dfec9f60532a46d41124657e8eaed483bef8aed068213da3d3f23f42cb720f181a44bfbd12c99e605ea9dece290feddb5cf2769fcdd6b9b8bac068b536bf0dc21a3b1d10e30fc637e5e78b2763d92ab6c3268a7f08aac47fc24154c2abbfb14d5200b1c8d2c75c8766208859fdc2475b5ccae482be0812964f30577c20da6b41ef1eaa60ed7d8a96f42846d45bc500c39f0cf39dd6b6bfa0163cf46bc1aaadc11cd54e2c2515c04789405008c6c5b05de37402aeb019028caf23a895f2526a139e00fd0ceae67ce7d2066f8def8f3f9fdc5da1d9e2119a447c12432389cb91c32fbb4107592b61e2444c6a2078e3a47c6016630e662fa84a5482ed104601577655f50b41b7421449443bb7fe32a1b307601cae2d1dbf7d0bafbb3676a2249e26b009735e6bc358ea4ee386cbc459202efb7d9c71b8ca594110d6e83f69d70ef0835782f4faaa7497235eb643d943437aafc90a5f31e4645605be0e18bbca5d2546363946725b01dd895f48d74a5a02236f59ffb357e5fa032a60afd24a874cfae68acb2e6c778bc5fe65371c733df0b2e74444f78c966927a8043a12691d0170ff60b57c45521f3e8387b4807b121c0234e93d2156100687ba8de95232f8d96c084441a74bbdfdf1c7dc0cff4cf6b193c0efb465bf5ad8297417a2a51f7bee8e04d3b2a81017dbafee8c4e69ab0d34fc3b596938032e0bc7169f8806a985bbc132056d5a6aab60ae5aff7590ce92e28cb4bb347a183d3eae169ff1ef47ddffe5c451d8b1b6f6db9b916e9b1849a3288657f91f5fc9bf721e57a303d9e8d65dc5c66bd48a2e5600c08a10894cfaa0c3c002e478ec1061c4373fab19e5f53e13f083099481b9ef745f0c341c09be4467d401e5146285d60747d4d53ca11b3fbff646eeb2350bd628e85b75eb5136159d3554c4b668dda4ce2df497424f7f6a109b7a02d718fe775a066b199a8fe41209358c14b3295961c0a78bf47cd21ef40f0a6eec03edd2c12d9c556d836dab4b2d251ce8a65606c5d4b40583c68a2edd1dce4cc65060ae87abc9d31e76c7b0af873a4dc940e8155fb56dcd3229cc34c3d21037865c4a7e4c923c25cfea1cc20b9cdc14fb0c35b7d83285ee6a946721701e08abd571fc02354446cea305b8c1def1ca49a6b6068738715c17188ab8aaef65cd20b34347c2ff0763a00403c4f6cb5238f80ab7138b64ec17a58432419b3692b737e98ac00a20ab88d21110d79106fe7f7774c2c2a697bb52c1a11155fe9b3fe77a042126ba2d0913d2d7306e9bc19046479317ab02dde0657e6a118ec841f638ee12a0bec4113e131678ecbdc091ce30b348ce6c0c0eed1c902c22db8d47741e40539d826238c87b0e14992f5343cba4e8df8f479a570264bd4dbb322069dafaa3fedbe27949b99bc270e0742090a2afe65af43dc5b2b9d6dbc3ea62bce67ba3e55002a8842e22c321723521d92e65b6b44c7a9588d23e4b069e8ae0da096ea189830f31a4f9684b267f97cef08b9e0e4af5c0e381a1e86248b57734e5edb03954607d4e9597bca978d994e357db84a43fbe1f11147d50db8471b7a6309aa70890c706a362005d21608050bc3796e266b4341bf219d5463856ca5d0bb45e028c890f5e81bf77effdf884e52bbba0568d5b91b41e242dea4d67d1ddc54bd10d682e1da6f7732fc6a3e6542a8906641f06d46d26fe68f23b21d1721b962ab4062f4444bf27b580e05c67ea984723fbfb18ec7d0e24212fadbf29677e3eafd4535ce1a94a53d2be5508c8131632bcfdeadffdd5d741ce3825cbc2057356d378b770a56184202f311dc445d41b3d9bdd279a698c6e05d3e82fba8d4eda897d617f911850af92aee508f721776da36e253b5e1a57fa29c78fd1b878772d0d42d8897c5e04546b94d8c9b0f5d83104d62e0423202cf0cfdb4f6b1cbee505cce975dfd58be1346f4cb08ae679da567950fb6a25e1bd999ff82914a715d175a2eee9cce40b3f65638e0c2e6e570636b1de03cb65a1314588c6f2506fab54500e5aba920a8373043df6efa475832ac74df8832333a991cc542afecd49c44c65504a28233f9d922aabd8b5050e046d8a149ab395a20a16e3ebd45704710c19a11ff7218811760a997a63c30feb553ed7079916b769c4c5442bef65806e464b9110cbbda516212d492c4bfd0cba67247881a2df0a94bced97ac1f78e3ef6d7e37894ce8c0ea691761b8369be5ce80d86f1c54fa23b4d390a4b0543bf1fc551d3bbd159025057b939ba2008aa536828044f93d8e1efa40aa432bca30ffc8257142da2af6848749a49968c8081999e1c83026150ec1794611e52eaba45d590ab15930bfaf26e7fd5f30a81db800000\";\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(\"Gongxibao\", 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 [\"Lucky rabbit\", \"Lucky rabbit\", \"Lucky rabbit\", \"Lucky rabbit\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Red gold silk jacket\", \"Red gold silk jacket\", \"Red gold silk jacket\", \"Red gold silk jacket\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Gold rim light\", \"Gold rim light\", \"Gold rim light\", \"Gold rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Lantern street\", \"Lantern street\", \"Lantern street\", \"Lantern street\"];\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\":\"Gongxibao #', id.toString(),\n            '\",\"description\":\"Gongxibao is 7788 Cheerful white rabbit mascot in a red gold silk jacket holding a red envelope on a lantern street. 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\":\"Gongxibao\",\"description\":\"Gongxibao is 7788 Cheerful white rabbit mascot in a red gold silk jacket holding a red envelope on a lantern street. 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":"58051542","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T07:54:57Z","match":"exact_match","chainId":"56","address":"0xD8501C1FF155466854Ba037a9ecf8031DA290BE7"}