{"sources":{"Mobaiko.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: Mobaiko.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Mobaiko - 1991 Mobai red panda bowing in worship in a red silk jacket on a lantern lit temple street for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 309 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 1991 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 Mobaiko is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 1991;\n    uint256 public constant FREE_SUPPLY = 309;\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(\"Mobaiko\", \"MOBAIKO\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646803b00005745425056503820743b00007052019d012a900190013ec156a44da7a4a32927d49c91201809624019a7d3a72d58cc1556a9c8146d46419ac299f25adffaa7e6aa3ef90fc4707f788bd67a78dc81e75fcd2b4f7298c6623e3fd90c37ff3c6697bb3526f8a9a7be775efecf9b50f964e26cf7807f7c58ebdff0206e8f85c52259e85efc1ff81a69ae8cb5adcf9874b5ab9d5abf49d5b3f22b26a7307d9b267af7862f759aae9d8f3e1ec738e90453a33e603f2367e40ba70853b82c3638b2e2f807d7a0864a7f72413f8c8b537afca6bfe354a7cc79a14fcc63d2be5deca4c76b7c21ac4d5b1cdec97de60660184b4d7ced0142e304c447b9097779344bad87d628f4ecafeaed63ee3a9064b5c3ae2a948a91fc1de49c5f38a04b22b47543aa9e7c9cd05164f1e1f9bc5ada39f5ee1d3cd3c2d21c82645eecca1cd9b8bd3ae52fad5ae3a5e5eb760df907e95c4fbae252126ecbecbc934fa2a1524429d0b34c102096f4469c4165b512bff646d1c95fb8c612783dd5870a65e6c887c661d203e8e6decbbd165d004fa7155cd45ebbef890cdb9099ba43ca74c8c97f3addbfd58421b55dfc7d87a6776316442494b5e4218c4eb450002fd2a6f6e87e9db08dee803321550fc67ffe5adf8fe42f6f24568425ef0b8ec93d96a2ccdf278a875f36556fe19617a06c5305e052eac39cbbfc4ffca4df8f6bd870b8e0fc27cc447d073a33217f3c261fe6b31f6ed5036d033c5c44aba05fd29f7487e5b0a8d1075016666a44b51b06698fba578779e0cf1502e898c139cf0333072d612445e13229e653b918b06e862eaf737202ac3af5840adf0c4226561484b3e3b0133783946e35a2e003f779e45e0f08a8134e7ee439f50b1f3a03870ebd79cd48e4bd1680832b92d58f205b20bb960b08373d1f5b50ec0897f6819729a023e36ae8926845bfece8da49be3a62c6bafe259b77ef888719109d930a8cee8534538bdd5efd46c64ab44f5a7bddb711007a6b64a6656fb9a4683109e777a19c1bedef7d6c087f6c360c1b71c4849b5ecbf76746223864d2331afc9e5cfd2165178daad1bcefbfd888a05e0c29de1bc97c6967c43845183f84f26cf08588cd5b9c266a80bd45710edd82df6169db7da82a4c7cc20bda9cb54a6c9ab8bbb7b82943b612cb3273e08894a53ade19502f35bf2f5481fa6e81bd31dd3ce8d325827000cc8c6cf8aeb53e17088a97eacf9dbaff885296f2e689aa10c05a0ec54794cb179167152df93ddf442f3a806b97aaf3a23f449a7beed9e54f321c706d81675e57af2ea4966b1e5530568b7be60678fdfd342b3d1d7d1281717dd6ca0346156591ba2aac72efd139b68025bb0415c9ae5bdcbd42bf2fa5fb63ddc048032390664b2cfc5b07185f1f8eff5d339c3028ca21d0da76a1d336c43dadd96d8079927133daa791dc9adf4417e47ec355e8e9fa42993108d977b6a8eb81c0e6049faebdd748235b587286ebea70800a96ccd49c59529c299d72844da110949ca49756157ec6295cd9becc0a981e6c13cc40bf91cab1e1fcaa644a278f7538379eff9bb109f3ecf1326a9e555d4e915f1ef6a2419513e300e914c281588b597b0578ab3d42a1ad7aab86edbc5fa3739e3221cbf3cf0271dc0fb94b4a122602d63212e69b5a5269fa32565281d4ab16645d16c9e2f057530b8ec6edb3a4225800c18b574a387358701e2b63c0324e5725423f4db05dd706de17008389a232655f12b49c23d0a52ccbaa6de39e1e636e2677e12783ba9e83e4000a586141b344c90a82a8205919832a0e555916f5ef8809fa6f24653f2ab102731efbb077e1babdd4133a820669257506d04387208c217468954dbbfd60363a6ecf9e5a694d22b931ad424b77912138accebb7ef077a61d632b0665debdcf53b7db74484cc33f1f0559f62e76e3b95e870a7ba68aa988adacda14ebd22b90fddd7dc29b29c73a81b71bfcc10ec9b58ddf949ad757477a3c93b2bccafced1ab724a0347b24217a94a21dbdc69d516781822e47e28a5afac443a73b39f64a879361be0105b06353f290ba69cc4f4a5ecf66a164847fff22f8cd61482ab791e0589630d984aa379068b8d088011b3ffc9a0cab902dbb6f1caa59459d8a4b9101c1e94be90ebf25c1c13a9575eb6e02bbe8a82d218c11ae5b20e3e04cfece3ee526189430f80ab4d2ffb8cbf050fcc0c3120f5ab71d5c475eb61ed5939e19218267834ba13b5a8d0e3d6c672d4c46a20e236ba99695e9a07ecb345c7aee4fd3c90ad2880a11b777f9613f830354934d934ffaece05a33dd16f153345ecaf7cd675f78d92c29e550a175966f9c22bf385e305a5d93eec18b72534796464af4ea0728096da3f4d7694a8f5803a352940c26a4d14f8ce24b13588b048380d8f8bc6425bc00d99334cb52796cf0a74e5004543fb91b8141403eb697ec5b408b383f3a979da6cf527c91debf72a36fd8001036efe4593347d0e15e472d1392382a81ba3d032fdcd73f8658cc474d3853e7a125e7cfcff2a1f499bda08a93aa2588a6df353280084350cc054240cb7ba502dac651515262c7a5124a9bcf994e61424b49bb82329e6e5ac6edb1a5fc4c029fb86af792b7577750173f66eb177ac21a079fea92a95c096967dd1374dd385efcffa38c4c35a3b03ebb825747eb01297622127843f045aed3c77ae6f22f2059e03bb199e60b9c7bbbadf35652fa2547408aad0fde5d95e4ed1e9981a5204e9f6b2afc8e7ae968ff38aa2256c970d082167339d39820eb91f813d22a2c68161c37f717d81a49c835e7e0316ccc687f6de0421109a9de2d71c91af4da36fcb1b7600c448d013472e7740c04735dda038cc5f1f79335c093e9c712be3737b424851939b816f3b504dc927a5e9684f375c49bb08ae498296164ac09e72e9e127f5b68352dc3b2cc239a8f67f3f14969e313eb2e30c5d1aaf793ecceee7de46e5a23d1641dd1db6e0a315e15d23322e7e0bd6282680c1c715da182fb860a0c7d73ee55d5b66860e31d74c15d686e742741214e8ab74440f175f19d67b5a2a74c8747ff20a5fe3f78e3e94c3c2ac48591d4cdd5a0549482823a0e8bc58a8669ac565c94efbaaed92ff0b7f3d065aacc62c3fc7012b628eb52904ddb6bbd3bb6ad7e660b23050affe9513986b4b5c4769f5b67997dc2fb546633d794bcf6dcb4717296da3d9512bddef1485c4b4c07b204dbd3200ef99047fa0eb5017154d924d34aa031c9850666a596d7ed0fc05aed65fbfe000b4545993be1fe475943f1ab012fe00409085e175007194da87147f70dc4a05bc27813c3188be242ad9b9812c1cbfb76392b6c53d90e3e4d4e98447b8de73effc5d61671875a988e5141ff065c2b1d1088f0879544e4271a8b4ce000fdb83ee1f2e13b4408ac2e41ff0b0544c4d98e8b678a4a925717a175254339a95df341971eba262c51b9d323e950670fc505e8ec78ef0d4d3452cf583905ab0907ca54bef20a16c37dde74e765abefc98c68fc34744767b19f60ac08d23912453eedb1a326d5f55b64bf9ccadf0fa17b3f28c57546db135b2bc66ffdca9a87c094f8b130998284cb7dc5648e722fe7dfe9f4d29789edba70b9abc474ba52dd7f0b8d785d8ea23697135c8c0d0080459bd129172225dd976486f39dac78c9ebdc1d9594d7c7ec627335e19393745208500fe92bf73ef62d311c7d6e1c3cc671871f97af5fae7a3af648b2b6603333539c2a83574041c6b501d15bd98289dd9fe40abd86986bd4b194a120014670501c192149946e32f91d33d10824b6dd970215e7f050ef222b9d03b0f1c38fc69a8a937c0c1cc8d5c6a4f20e11952a3976711f62f690600000fef9697710db10bffa2610b6849f71e3f3c046e25fccfb93f26c941763aa9935c8420de2475e814bcb3aa88fdd219741266831161b29a3a68ab36ad00619329260d354f336dc0d42a420680eacf2c99d3fec7d4038ee089c05ac03fa01d0a0534e7e0a39a4bd3499f65544a9406ffcb00113366e23ba76e55d6bf0636e197e5458f3c91442d14d79024132066743a8b676d0f46987a0e34632ae16c86f89fc59bb09b784e9a5fcfa5d71003bc971c9bf23999ce6c76e3673735ff9d57a0bce0b6371f4c08635ac7a8949210c614349553dd4c72b8f7164061c018e80a32e001b0a6b406b81b58d840b687134a44458ce8dc500946f3a53f740d173d6dacf610d585c86377be3aa102f0295ec3cc6bd8564de87471fcb5422e16fcb7e5ea7cc943d1ef15028439d2a843741d0f0d3051287e87553e392513078a45a0d9c369addb5b4c3fa91d51f7ccb51155cccd2e0e9f9df585f3ac5b9cbcb73e9d5ecb12a1dcb09c0bc6dad9ef04560a6b1d511cf6c641225e063fb678f7f928184750836a56f11f0b2714581eee05f281bec41895cd657914b86e0cf37df3c06e6539db9f72e07f69c109362df92e2ca235a49902a00d33051c14000001fc6f4a32e4deb55d5c40392758aae079f22dbfa0dde41af60c031f98f52ae1ee717d5cc92487a61415196d208929bc830f0261a2683b6d0bc362869736189d825cab46d088db3c967c798b3a2fb65c3e5f5cb4244942a151e85dd086de74e407685107f77283e72337763cf6cace4092dd7fa7d00faf843074cbeddbe29778ff1d2aa610e3a3d5ad754f4f31d911f80110efd6c15699d7efecefb430d51d784cf3e6611eaf378774078e0c69027f7c09298ae858c0f7239257b12e786f22288f933cace1b9b816a6ad340c0ee9b3aee95c5305f82c24073f47a27f2fb39167e32f546ba4c934c6c21946895614ff99ecee6a0dcccc9238ffdf14614d5405aaa68ec12c9d99c9775c1844dfd5645fe831a7d12447a2511e231f9f77ee14f0f4e2ee4c2a9d2a88f2123669a7439cb4fdce19b808b2cf2601360bb52c16d87cf2af638cf89f4f8eed0d3bd7c1d1e8e161a78dcf6e2bdb353414a061c672e350a4c2b7872efa829d2fdfe66c2fa2a0d337c870baceaec890c46a3a145a4e23a2f4502d61ed7ca8e27402ed07b4d9a5a1229f4a3c5e48ff71dc8e4af479e35a49c536c2f7780c2489f8b767e7096a5a21578c95f417dc2e004d00c0acd23b3eb80709e44adc7a50a36aa1fb6b1f1f8d42b37824e292424d4c287bf57d5217c04b176dbf4cba1114d6e0fe9698f24d57b33b5d07bd7395ad0077c440fca5b5ff81f9a7ff2302d06b08a3365f4af48535b69814dd17527bb8f02de4a3cdb3b3c3c49094528f44b6ce6f10b44ca4df6fcfe0d848abc08c5b1f70f2479125da1bd6f092f6c446fca5b8ae26e1ba8ebdcc57482a704159d9f99a082843d858c108810157ce99de746d54da435590634ab1afcfcf4187d1becf0cda6faed4eeb8796c61a6fe93c5668d0d1f5db3c613873c314ca4ae2d8a4e5f502a58c77aeca220c2d2f1e9c591bf297882bc7e89336adc50375be132f7a1d725c2552141e0e81785159a465b8e5feabbb1ccd8a4a1e6095b44fe8ccfb640b19d3cb590011626468da1e60f4b46b5eb8697374d7f16ddefc029f588b5c29d7b02026fbddde7ebe076570599e967ff80588a6d536b1241e06f9a252b6a140c4570231df9d47cf2cc89c0c9d667fbfe7fafe1930f83dc2a7121c1f0e7eb5441bad5098dece17f9e57e504e0025db80244ad86ad495c1e80ba7387fa668aec8f6147e35af3372a28e8b1b82c7070773d0ebfff28022492893b2a050a6b941df3f4e17e0f9eaf449e1aee42a286eee67d10ba58068a937188f686a492bcadeb903cf858ab27720867c3aa138787c7c946310877e608f24fc26c54ed67c5df8a8c47f5056680b9828d37bdab1d3ef8d6c574eadc75f76a2d1976a622875dc9aca697531c933524e162c8d2ac4bacf1ad101b0f2afb8931d4fb65bde125675f411cf3c9b43bb6a8eb9b1d430ca8bf521f0c466ed570bbeea34003f6347fb398796c84fd628d7d815739984d3ab733be0c8dfe723102e6cb68108831cfd536e8122f9c435f4de4f9163027213fd8f7ab31054e510b6bbe4f1ef68f444345fb0ecd67101751336a44d30a26a6e0dd3667af5848aeb47639a0b567271d2e6422ce281d7f656d4155e190982d65877ae44673dc8764f823b68c182ee869dbb0424095c8dd4e9d6e737a72b1d9b4eef5a7ffd19093a50eedaaa0051126a2004a3ace1ca34d4c933e09558bd96e0f299ada7ac98fb42ef6c3ced648ebbfa09e0f72fa4f4c69439c855656ba7cb16ab66ed55f10ac1f82df913154505907079424936666f578cfc8dce482d423eba10d1e59cc2a1af243121e5fd74208fcc9d7cd90f503233b4c49ffdaaf9648d4a9efd2ff4e51255049b88c34ec5fe06371bab5833159237e8bb0c90bab18ac5b3ee8fee76d9234418210d6e0cf9adcb3cf5a0a87822af479784d90db6aa0a98bd720424e66ac2b074c2f70deab9186bc5e27c39d27a522c7dae44dedeb74bdcb21baf7de70600ad290b28c040497f5f2a06db56b7d7e9c56cfe769531d47d4d1b2f1591f7e39bb654b2894f0f6a6583147fad024c73b7bdae53ec622482d348ccc8596e20f9e577814e38ccdc226db57b9668322f5dd8ef65271bced30449a2fd7852e1f5c1fbc870da5ea7eacd0fc4b0c50e016c40c30a71374aaa268a3521736ba93581a19d540de8a63d134bce91bdcf040819e3e1bc21b7d017fc17c4efdac8ad746abfbe568fbdf26802ac9b2051bde81ea21c0a8910023d4e04ce0f6749164e45c1eba40dd946def1804298ae816687b53347eaf7194c2fd44f51a245bf8c10d451c91527e08703dde0cfb0e382d6779eb6db8dda505a0ecde20a9d7b87fd8f92b2bc560597f25928d7c5d3020515f81e301f865d5d1f5f2bac789063b65b4df0cf4c3b3b1038e99195b96afdfa5adb214901c6e977c2567eb61796f78788c26001b83b17c89cef072a2fa7ee3cfedea15c76192a2859930b6d713431ef821ad0029d6060552b095ed7914dc20565a8e9a9248dc6a62a9188f43192d2796869c05523d75d5254ae9bfc9659fe67da8b0c16eba764a742df0158ccc29aa5f4ff0cf4d07c1e7a79c4b3df31deea17347f87f2b053f8c2b50e91bc4ce67c6adcb2fdbcac0e5001256f615e9729d541ad4c2ca446e45fdadc5dca9084f79ab107cb327b2fdb08d0675b021a242206f2e0049f9efc825ecf03f380833670d7f89e30582f330dcfc904b7bf704dc6e9538dab09fc14d2666a2f0772d7251ff055fe2f6adfebc92a23b2979403b9f001ae83151689239589efc066527dc8a0823e1cacbe30b55ab71f6f25e8819776f91272a2dd6330edb93c6de76fa8d646cf8d30f552a99aede3df152725cb40942f3ff7ccc02b63ff459eb1a355e0dd308d0dcb6c51b198c9b7b64bd852ff6d54beb7e3bfca0dba40a7e295b9c88035adb7657827ee61121afa288862625cd32c24f6333771590b7df7b67d37dc67fcdf18b80ea8aca9515035ad3a6f3d67c533aae5ac03f8a874dd9d916c803c8e08fede9d4a874092c91a18d514514ccd5dbecae67052426fcc7881c0ea1add9c2cc7b867d64d2ae5a27841a9b0ecd8c968650a9b24be068b5e2618fab4269bcbea4cf2f765c819148dbad6e39f9390d3916bd50608f42f762ce9281f2270ffee8be8b4e5cb14bc74924e80ddacf4825fe6e38f34b3f7c185c60b248477146d3f25246f1c7138f70eaee2651b7a1c4b85ace8e90fa3e047c04d948c5b131ed87e5f7d88d7be3b68f4b8b9cec9082ecc08bac99ea8f898161e20ef16f648e4110e2b6bff1e1c542de0c5a724b675f05cbdce48a343fe56cb54daab273b5b5f91f7e9742438c443101e2f03c4c7488f57e83fb5eca16358cd41fc5fe1a00690526aedecca0b480b5ffd7eb946607f6b168ac2c3bdebdbe11400372bc3c15265669d33b7206a5d6a71712b1a54d3af06f67ef32a3190bbaeb9f4e204cbd36ec0991d8aec0fe87dee7be714fa083195626a67819269ffaab34324383f816a863f85ff1a647b70c14e58c877a2d2b945a7e6e4dc9b1df8ef7ef550737bf6e46e1686248a65f773ca1dcedf89b7aed996156a494058c4e18ad7bcb6a4bf4e1a2b7af9c3ce610d635d2058c14bf09e41ba7d7c207af29fd2d97d081ad4b9398ccec862cea8b4a744e09945190479949370aa40353d559d6eac736351a48d6df235fc852735a4a7c4764964fabaa4c95421dd3badf0724fdceb8533152f1a32e663aad675165b17916ff3d067dd70d642146f869034cfda5c4ae94bcfd9cc792c350104c2d31a415565f820058256a433dd837556b15be1fb8edbd77feab3298bd7f8ae9df8437aa59a66afe2b3bfb4dd5af7f92d6e11fcc1395873667ad44bcbd881dc43dc7131f5e60a966b90c7d580a987923e44c07724afe4b7e6265c9ab6c6c521039749b490dac073b7644157b9f6e64461b014065162482a4caf07993d3ca5fd8c066e6d8086618a3b8c489770aa574282eed7271b48bc3ee2abfc098b7ac1b3aaa524ee4103d9a16c9d5fb3197bc1ce86fef3d656dae7eb224d83b3976543e72616a45b6fcd264eda3767bbe5c8280326d3b3c3ed2db5fd90c96573054731952ac07560bf323a9f4b70c2813665fc56e2fb5b15d274459891a5a9101cc4973a62ae67f6181fb0874b3542c902da8e98c6123709201541d8169c3c5807bbdcc5c73fad9e0877894f12c9b689ab232cf9bc70473e5f98e750dc6657d5b74827db0817edf4fe6dc065670253194cc5db1a11bdab8a6a82b9f633b5f9f095a2e1c9a5c1e79c2763a2f78b0a892ad311db7fad6467c988394c33368bd9b4b1a01dc00339fbea14a0ef8cd1708b59e0209a8c24b858ab946a2c2bed3112f4d23c2c506fb1c84b01b36161e517e8d1ae4ff5e2df7d27612df753890825f1aabcf4ab204946b4859193936e4bea183c2a00ffc4728533c5b2b28f6b615de493224c5a5b5a822e6c3e6fcc84d78b04cd77ec146d70949c07b6cf4cc9e93f8c6acacbf7c96260c0b390fc39920080314fa5192eed2760e55fdc1258f30353dd76c3bf9f57183093b619ab5d99a7e4a90fc092f3ec022725c42a9180567b7842951f222d9cf5675a1c9693e8e6552c2bc38e85474ed95e15cd605fab581403d7b8a9031dec5dcef98c5d952b470141d7c4d52584c3d6426c76700bbd7ec2730b63b46d59b902ac47c5b6a91b2db6d2c6daa692aad7f240c8232f78779792e4c5b0f3ddbe20311654b4b3fa91bb217a4ccede41aeb08db1a4e10ac177744e9aebbf81caf24eb684cec7248aba23f196fa5b352de89044c035bd59c1c655bd7fecfba476106058aa40aef88543407d2bafa06bc65e5f1c37a3cad4bfe81152a0f542345d3f094f404287835d7e06962541b835d42437fded2e79b59ff9591f35800bd358e924f45cc16e4ce094cda5501a21fabe5f5c8aaed84cf304e6414ed20d3bdc0a2294e56ae8675400b8fdaa3394976042627ccd58961b13f41601794e1494f39cb7f2eacdc2e1e723a89f19aeb63812c35f099df893e2e2dd70596de9635275c713c7391bd2cf5dd55b1cd8c4c457b493d220ec0ddcf4448b064c98387b1d2a664412728e5af671ecd8f54f41cbb2c4d6b9826d275419745e172b23ea00940826fefe48b0adc94a8e1568c51dfcc9775c435af19425d5bd8781bf1c0acc58d3ecfda97e12112d273d2e2112d1124f26053a7e1c4b81c228ee6ed3fa253d7e4a98db35efa657f60611add3172f9e18e8137d4451885273b40041c270503d0111534b462fb590dc9bdfb704ee6c306b2f8272fad09bbaff21f4ef8b57ad0800e5447f6a36e8ebf0d0d6df21fb232a4ed99f170cef6bdc6a3f32ed2bbaf44f24d41fafdd30db57037ba3d58a8bd2c169ed3ff339930754a641238ee32110d29c5eedd94e6e0f0e6cfca1863421b5385e1ee5a29b7b741c222981887ed2155dbffeadb554481efe9dd90e0355c73efe866dda087823265f5b4cb8f045eb071c0e591306235beb94bc5d7388404b21c4b3ccbb274b3c1a08d05ac0f2df81c5e3494292dea15e427109bd837d85b3331bc0ec55f6e1c084d4d84170c8177a577da074c4d5a797305828b0829527c5387d9d788aaa8d11182f9883c1528184db36a779b3d60e97d25d934ad72d9feeb1600336438a10c678b1edf18d15a745b96dfe3a5d8debbe7dfe81172f6c32c4599b3a833038a30aed2da56cc05d6ad85feb0af40611eafc047516ccca5e47a1cdb7ed4e120051f967f53e129058befaf51eb490467cd939e420a18e19675c4d882679f9585175ced66aaddb098958e1dffc6ff3c9e92d626a1670f2f6e8a17facf1089a8d7e9f8c53f38c45dbb11b126acd317e7ce4142e901bb91571be9f9be9d10c36ec36c2f80400f9956f1f9e7e57552cd751b5c5cc9b0d0f8e6941da0be4a2c66525787a1024eca4b38102a77a7166dd295ebfb2956fbba0a63743ec0f63b89d1056f47715d9757e8b2412f3673c188aa3d5e76add6e15953d1d0da382548875ecd7df6e39a5eece4bd6b3eac346dee39aee34a5cab1f159f19397c9873da1b82b96e72a66ce52e712af7e522a3e052dcfdb6ac2621ede32e04dea373395816faf4b53d2dfe743c04e63e4e00c86264dd1dbaf9dddd4ca4ce31f668649e7a39fd4f94c486331afc90a85874fb4ca67c61179e2f2deffa026efc8d91c429e3df223f14c7058408187698306f8376b081a7ce14c172dbbc6a4adc025ee7a36c8b1dddcc797e2e5dce3bbf5fe906c3c8fc6d8fcb19a4af5aeb5f6c0d910c647cb5e4e270eed79d383fbbf27605221b7b9d1b724d17fa54f6ae0d8ac8ee19f82dc0f2d5aff1d75d0562d03eae575fac4e3f14590e65c69c2866e2565c9217a8776ac5624f6d0137a1fa763d075531b1c14175b499a2717fa205b06ca512a507e3ce303fcfe3b36be567605a0f286469a990b164ee4809f8e0d0ce1c64e6945af2001c7c25d7b585beac2225803744f85ca1e1ada48ccb6a909d05e712c774adba88e5796bc31b5b587f06b18f4512a05415ea87436c3ee53bbe0a0f9272b0bdb4a305f307e496629d8131a37c64ee7e936442fabb8e7326659dfec862d24dfd4b0cda29a6c20959db12b39a517ec6429cc7397b0f76a7a277ae440b971dd4cfaf720d5178043a7dcb0f5407ddc47e594d619c076a338f5ade02e467260a236ab77ce46c79d77e254f6d884be779a94834f3005b39b42553083010df90313d6ddb26cbc6a89ee80574a610b7784b38e7fa6d0b5aee73c5461962ac89f8cc0ac8715e3b5d2fb38989c062421fae2fa09003eb70f9733bdc3fb45e9d384cea12f4e9741eeca9189e44eef21fd3641a1dfb32b20734c8e78fd20599a5078ae74ff6b89eb42fb11cb40ae95942955a0e5ae5bb9ada8a6f2e3fe0ade452926ef2d3344579311a70a38f5d7b53b1017aa525b4996e28cedeecde0bfae19fe05bea5b5ec1c951fb60d5f1e3121e36446b4903aa59ea8ffefb20be45bea721b398f87b6518e18d517431018dc61838ecabd4b4c14cc543986d1287476741d64e081b3dd85b707a3a77629d1201deaf47a1c537ac88b9c39434c21d49803dcce8105b1ca38dd5d5b13fb4f1e7142613c483df60d83a1f4df8969b4683541af62dc4e6b4dd4fa94876d12284a79ce81262224f2a9f0fedcc8bc7f61b79bf6289f93b19fde8a8be5357b12f8894fe1e6086d43246eef820bd525e0636e53f134eca05969ea1d412257afa1fae1db044c4c057351992da10f96aeb64e5a9a439f49217f13c60625b43bd60ca2ea411e332000660e19056fe9b2ca40cb7236d3739d35d880bf42eeaec7d049e720bdeceabc1368cbe4081b1b60df5ac579c29b4a3c7b8fd91d28dda5aa02b6de13aa3b5bb3c550d2a23a65de3f6a2a93d50dd914fd044274d3a7ea8d892bfc888920fcaa92cf20367ea1c49030d3b22249a1c268cf2fb2de99364ee227f753c78a8af906255307ce2df1a8454de3b751c552ef73198dfebdbc30ba8f5e4ed12117e0cd72b0e39f35dc785961307ecf5f9d403650a84b327ee4a201531d4c7c29746b984fe6e2548892db7c454ddeaf0ae89c5c0db612efa71194219276f61e92f21c0ffc64e6dc43c7ce180dfeee7b42391a4507a653db509bf3bd7495b862ef70d6cd670230c5355f7e44cb577f5b585815ce714eb654281048d137abbbdc27aaf60fd1c1ebf8f590a7aea1566dc45f32ffa97571efce671c65b2227e965c54f123efefc4fbb0b3fce0fa4cc17892e17da146adf755053d2528c8a1367a8b3a788c65686f0047808a50158129c31a41eee6207dbee2e8f455c4264974ccc3bc4fb1fd1c272444b6faa38b0540e96be48daeb4fccda7c67f759f259bd3b874255facf6cc0c482d0aeb2e6a11b36a6c5f74e2062253b8be9c69b9ee550fa331195b8678a29d0f72e78696250120fc0f7bb5d9d042658941f422a3af802a0171af0ba3fc5f42c6902dec55292f9f229e2ed19c1321cdf169377302fec4d381f6626f34d207044f48bb77b21f46f485886aa37dd54ddeec93133ab7e8e9f342359779b57276f3b481809c98c7360765c0b95c21087d6197cf6d518e5841f5364135a411b1999285a8dbc889d9bf80896b58352c876a2fde6348c69892d68c23ee12348516a7e87d167c532cff1107f589e2db481ec3c6ecb16cb2b4e6f3aa018f35bef1eea8dfa85da3493789f01eb724c6f8af7d4cf56ce873d2047eb5658343329151e419a433c44b454d215ae0925b76344dc304b69853386d8b079e13c9bb0049d989795c64e820459853de732084af8d46006372d8dbbf85c2e68b49ab324dee350823b6c087d2209d95685419ba4fcfa7ca80aaf3dede3fb221ffa4f96d7bb6d4ff2d599a807d2854093b8ddc8ce6473e38a61064da6a331890775ec27991405514c678dbfb94b1b2d74d7d42d96cac1b5e849d9f95c7ee1d8915786ff26c1f79d5014a000593236d3eb4af9549b892fddb3b0eef844b233edc15a7919b6fdb6cc25f4eda2bdcbd3637ae343fe3e75b5867bb439abc6f0f407e74cdc1e61968d54554b35f8fdceeba91dda22782a79b2034996f47898baec17c08c988ba45a1b648fc7e9e69aae6c5fddfb4d5269814f86db95810395de61a3b894e2182174c9e005185c72733d6ca9ca4f78a8560f4fc3511fcc4799d9b1b1385b9dae658cb4c5d44c009508f8adbaa51429e0248592918ca359356642c428a234298ae9e7bb0ec1c0258af8bcbac1ed01c5d57e4daaa9e1f6bd659e933a27a78c40cec96983e6e8934a205aedd28fb5dc5f54a59e3da3d1a7b13087a28c5e0c107493d6ceac1116c8712d8ede8db0527b9653a8f7fadea03b585db21acf30b18cd22b4b2cd9bbc84f94ea3b4775e34c56e8a3c9284187e8f56315a09f5bb5161a2822ccde3a17a922fe137e0280a1816be10f845621bd6cfc2bc0b118b59470dde5551182c920e978d21f130dac4944f4b948111da1a6ea1fe179e5e8211007d04673d9b5121d45e1f653173c7d53f18470b6d4a9f031859bdee325745d82eaa6a4348090a8f317dacd774eb6b331402c882a6d256fb30ed3e9056d51e93ae2aaf52f0e3466e8db20cd39cb5be0e831602ab43e329481231b3ac647c36adabfe707117c316bc0a4dbbebfc70109b3f1a85e44a0b21abf19914eb1390001c51f4e5b9312c0759245b9a02dac4ddd637f685f88a41147b59ce56cc8cf66e0936318339184a236b0a4f6a904365b5255d87c31f15f18547dd8ad1add29a829eb391056b3b652d7aaadd28310b77c9066da80c14335611caee45ce4a0f2490aca2899dcd52f2ff2ec866d05cb0d11429ff589c9a5046ac26454cdcfe2b24a75755e1fd781e742838cdf2270141c57688a8d83a4d9dd1fa2ae8be0dd72bd124d98203584b3551309c74258970765b2ad2afed6e2c2c021522bd9f6c5d154768be7915dd879e30eb7caac954d6ab0725a94766e816d037d93d99f504f711614acc35263ce1606f8b177d061e6917ac932f9888b9f08738a5b5870ced976ae5680265016155610ed9ec9e0892ca6be68b60fa3f208ca22308ef9cf863f57d48688fcb70ceee3e17cd3931f6daa6d6f7d87f7a769093466bba017f34154e8ce98421e84025262325300a2f8285fa5051d3bd0960adf5f5980f04be879bb90b72fafe9d062074c2bc6d89289135eead54f4a336d8d9ea021a11e9357f54abafe61b34066a6d2d98a68c1f6732b0af031ca3b7b6917a9767f1c0ab651b518b1370740290f582e997363912764ac0edba8df43205937d438198b1c6c4f02eb3ca38e9156ae71e653e6dd572538c6561d63a37adfdb8c20d3136d11ed9ed3af26d91141ae4b0475fb72a51dc1f6c245a9275674dea8ab20dd9b879ca5dfe81a2b34b98060f0bace5ff2ab98c26fb76698bc2c32d1b5e06923e786a7af1192b9cb89eb163cf9f0a2d4d9e60494c069ce2f41cf0e2fdf06573e7758b2e9fa48a0ce84f65f98601232167a4df5b76c38000b11c0d6db03a9cd1629cecbb0ff66779a24c2a2fb0bce810dcfed550e67903172627205b18d17544ad7aadce1aa192b821e28e2e7a2d9a10b4b38a7b1e2798b939538176ac40fed8747c9446206ab22479dd2d9af6417259826859c0cfbdfd65b150dd4d5c7c8580253df142f5507fe47ba7f3bad7b66ecfb901810c9f5847f4c2ad8e2b1c832840d85d295ec9f719e0d188e596cb5e8361d0d9e7cb3011bfd9dc553a2552525255b8abde540751191a93daa7bc14b930965d6c66202555cf394546b466d76b2be45a349d3f68674f17bc092d02ae46ea4fbae198bdaaad62fbb89c1e764374fd9b661c7067bc37e0160c390f7a86da45eebdbd21ce8e85409fcd7b5bc834918c87a42e915cd0416c208b7237f8e14c926c4226445298270d2cf76d9364bc3d822c8a6b9cd429db31098af4be1869f37d641215bb499fb3e1794d25790a7d16db7425e504b33e49d2a467a77735d584dbf11debee1f85e57cecb0aafbcc785e7c39111ff6c1db85bbade1825dab33da7ebb8136c16aa533b954deb7bf484536342965cb2f9c7e52a2ec5853eee934438b2809ba65df88356640eade6fa3fad071a476b272c4990ab73f705b09fdb55b7c5697fb8f649bb715ff7545368c9789ad6983f3cd2b3f254af46ba6c1520afd7b82cdccd1983fbe7ab21ce4ea28133ef14298ac60ac7bbaeb7afc10783d09b393890e27cfa960176f48c9630eec1b1775607a01e3060b98f356e1357954ea35324c0ec4b2f96df44c960fb772717fb11e80a5d9f6852d2d47e8ae3f503169cc574435bb019bb6c11380498e85027e94ed3465ae7f6656ce235ac7ed2daf8be1eeebec2f282c8380b1a7be9f1a18cf4f4b3d130f73650a87e4359cd0cef699ea4b4c9e610d62fe3b3d2cb2b9779a3493878d1d03cc940b9955c74c5b0f977fbbc7ac14851402e8d211de662d4a2010ac7257cd1995265354fcf4219f2154e94f08886cd50b4ad68aaf7a4356e8094d233f46824d48008759edce653769cd68604b47d30f83e61fbc6bd23e0cf1fe51da2ece316098fa0a8de901c53f644bde34a29af4b9fabb1b10b5fc3746c199fa4930a1efb41a11bdf61e56c96b5ca45d92494e8be9f82dc5bbca5bf0508e6e4ec5272e536dbf816926c349afa4585cf1af01bf22b5dfa58312ed78153ae9dda557652d5cad830c54ed5dea9963cf8532923a4ca83fef7a935c0642b710f846a5a676c28044e0113fb4b868b4d116e2a1dc300f473f4a0068fa53947a7c1a8b6c645b611cb1dc97fa5c30be31ee7ab3b01ff43a94a84fe4c6d597b00640038a877628055f4d56eb7728b3b9b68afcd01173fb539f6d58c846fd366aa4fff808f37596a88f714f0d06eb14166445c23affc33e89717a47a94237d9f7ceeb1bbdafdaf7937988e1a2d963e0be3271e52ce5dcf5e8701774d81222b293d4c63bd11818b9d4cf4947d30b4be5a89ab9aa710bfff507c20303892860ba48449d39f744e20e911723b3a5d6c65ef0385be96828df148229bca1ef935638d2997299e36b528e027d314a0a402259d5c3beba3bf95b636584006ba1d17ce088c5c39dfac8bf16e5a27baeb9fef463fdfdd729e58c438e4cf45119fd0efcb9d207e0d7441197b56853d43064b3b8cc46cc3d8a25c62278c95f1c10907236969b0cc38c2cd4b8a55c22597db019b4223ac6f6944f342e6bcea7c10486a0dc608024edc23460d5af4adb4cb3879dd9e6efcc8238d6b3b01a9181b204197333d4f3299bfbe1bad524ccc3c6998619db7269c2837f805165eafd534de20100e644eb78039e02ba7893a5b74d393d67396eb99eb32d8d103ea9955cbbaec27db07f6b89c9fc464a5015bc8db1c607d358dc25d2b2b0f4294b4e4eeb5620b88a53a447a27f5e52b8465c5a7812dcb11425da50c52c1d9ce47c405cb7676f5bc79be5748f602b8a166cf68801335720ed361783f39c5813b2fc6348852bcb2bc727256f5aec2a762044630e18e77916448e678938b872adae62981a0705315c43be3be6c3809e43093690411f89a055e5fb0fba59d6d15d9fefc5e5ae866c516159c48abd829a89025b65ee43477d10ae638a5787102ae33ca4ab5a170320fc7b85631bbf8dfb2450d07ca9ce64be06d38d4050089460fa20cb6139add468724fd84bbd139413f876d4cda5cf9b2003e28bc04ca663eeafc25cc6f9180a46c8cc1f241b8e19796c992a18f775bd50517de970f6cdf53b3d0531605627ab2eae80a3831842403d902a58564d37d5dbbd685489f278cf54848920a4e4489661a4ecea263204ad250241d67d8dd117e5b2fe58d206235a9ed9682372fde1df543cb0851664b5d2cb956eeeaf917507d1ccd5a625c2dedc8cc7bb48905f54b64347cec450dabfbcd7a4390144d1e7e728ba7e490e756a2e6b6d9ab90f86ee2f2b2aa5f46d7950b21d2ceb47ec73cfdb98486516b9bad66c1ea21a4c8b07b53b3acebc6734bb0f91b9f9e10de460d43e5fba0052ebd4ec949bfac9abde312b84ea1eed039b933c9af43b9810da7ac618b1285fd6bf822697a8f413a5970a33953b05226a5fcd67c23d19ab08e935a75e2bd7d4e5fdea47fbb31c6bd407edc7e166846d2108e29da4730d51739e79d736944178ea06cae5a04af1b1437b51f6f748fd9c2c7ee66fd81f70fb537627060a789f347f040990c1805f9591c3d841c00103cbbc379892610de95295a8a0b558304acbe244b3f3c18e655a058525915dd516353175ce8444f17df607c96f393b3513112ea3130563501d17af2077f219596fe8fb1a49032dba30b4c753427faaba713d268dbcddaa64a47a44e68aef3d26b7356ab185485ceb01adcc07149060a2600864bb1152500fcd3cef2635fac055c112ecd747533d9c8fc27d0797927038239b7a7d4f5c4e9bff00daa3de55b980568d3596c6a593a3813f9123e6e66e52961dc2b19d0bc4a7bfc285a471f8308f3ef7acef1deea3f731a68fe887a6c0478020716befc978cde6beca42fef205f679706c474c61d9f109b61184d17b37ed91bda1606444fa825dcbb013b15af9b49af6d66a2bdfa151cf657e5034161daed38d85fbfe9e191c401a182b2788de51cf70d07503422c3025a1302989db563915e58a6922bab39558a61818a72ced9e315913c97132ce4af4b7fb530bb2827577d19c957046b88d4d12032df283d1d92f6563004b9607b40ac8424f82f5b7c12e66551823281a5f596a5276a44adedda56637adea04461545457d5ed41e511cc76245b1a744d3d6d0d95a6779469b6d224d06d25bbabdd5ab8e776d71de45bf69ce016411f7a25a64d35d8091816b8c54eeb9b5a9351f557d916af4be4c50c490f28c6b554bf010a82aceeb2dfd773e84fed53c5718df599444f995dba0adb41002c7d9907b711857ccdbde9a32382aeff8110c354c34e7d431090ff08ed1c9cda52cd44ae0a0799659d38d33bcdf68da3f4ca1ef111db6ceb496457e97443cfa16deb6ba49a639279d1efab84b743d2c115c0c7a43ea69d1c947b3b4241437e18bf5faf643aa3e09378051029c1f0cf86c40315b2440fe91c25610390c7689c5d2ad29da45a61361f3673e563a866c5e83489bd4cf9fb0c4f76b97cc19836ff3406ee356dfe42afbd46d7c217b23c7e09fccd8fc5fed17096c47a7dc2e42531c15528b856efa5605a16956613d81f6c4a7998c8c3d5ade820c162b8ecf3cf19e65d4041afff22805a5a51d4c39ddda4df00538f75e88973d67487bd52f21046dfa641b269d79f24c54697f0778af42d22bbf76315a317a3cf0f6f8edc7d6e6026f0be13c17fc98ae7a36bd563ff282c402e994e5cdb5f1e0e65cba3850617c0ff40af075caa4a67dc91611f5f4d670cc680958ac0aa4775770820382f9cdfcaf63bfc7f3ff6e8276f6011bf99dee79b51f43ebd8368620950540352006eb6d3b3a6b99fb669ea80e25544ff8463a438ec94ef36e660b552bfa908ab141bb9d174960746123674c2e38710e56ffd153569bb521fcdc320a2e4c7d23b2ccc1cea93e278738bd83b107371d7f1c3878e922e6cfc25c8dc42f57ca07e205e9d84ffd8a06373853793aaf17a33f275b94bbc14ecc949a8accc2a8c3170b30c6f7078f97abdaee302b3352c4a4e7e7be8419fb15723a16040e991e20eabe8e9e30f61dfc6b237d44c300a63e42abc9d0961c4a0a82450efbd8d370e9a801170998bf951b5597e7f5aef1f7417ec6b9225706e6ad7d68491132203cc35d821b27d44fca56aa28ef9679d403684612fe0e32b121cf64edf706af2873a486d0b2e7e1bbfccc4c5ce59a241710bb05bf961ce9179eea120f96f9ff29745ad683affa0e1a6e321df81b4c1e1c3460a7afef75a979b2ceceb520a83c753b310a8886bf5cfee020b930944865632619a44ca45d8415db843554923a0b82f81b31aba01e7d4dd33592f3d57ad9b8f7653e88a55bb1a9c6f4782de3bb346aeab5141d22bf286d13ed1eb1984f2370aef054512a5819ae9505e81f5ca5093aec43261bd01032455ebdfa5a672eb04b5bd076dddafdb509baa9916a34ce78331d5c037971e2e8c03734e48e9d52631fd1f8b76adf51a096434de54cbda88e6b98caf3b7acc716d4c6ef04d138aa3626829ad2c5a779b9087f6690275b045c0c8b81a67e76c6438a4231d71e42ebfb0fbb2c340bf9e6df32f3287244517892be388a7686bf23741983dc04702c414b0d2f0731d08cd70f84132df9a6ef62e2a67efcfbde3149cbb38162aef63edffc74730a23908b7d33419134300ec200bb0081ed06651276232a392984dc4adcc0bc61679e78d9d3f3028552989da9c6c6f8c3c3384c33342bf1c17c6a85f14b6e292a26fd4735a5635fb93e54d576ff23a741d7eb64ac46d60934a90ba2270f43ba2e6ad9116d6ae121c1ed6ded95808347a6de5e95326ad94fc80767158f6bbb26459fca01ddeba457860861bf84659c41bc1d5fad6d2d436f328b88e1446d79326dac87216d575da427c27b9ecc0ef9945c20e5863fce3abf71d1bff3f763676aecad8a1def701b18b626fb6ad6635487c0ae30a3f5d81bb98755ad1b7058141f6f1c2490d875becc0980b6043ef842b8e985f75fe4f665b2813cb885b287e0774bb8aa9ce05e6221c1235a469bc29de0de3c372595a1670a6412dcc386470ef4c49835c49ffdc934e678645a9fec7df2976c4078c5bbedd08c01ce6a0ea8109c358ccdaea213e17c18b68d6070d02d6f31d93c948f7424103accf0cd4c55b5f090827672c057578ca0cbf02ebee49af510214bf4a8224a371a5e95a5bc8e9fb1e71deda261f5f41aa33421eacffd9b9eb846f923d130a0f12d51deb148a2591e2693a2ea0095187b7d573bf62c63fe1c70fee3959264731ba9475ea06e38056f44fcdcc658bdd77dc71089c4af00d1b089b016d5d038d5f40bf9f505bca2c91a37f7711600c86837e1e8a287c82c80be9b226a1b0cceba0970011b5796d2a1f56090c096710a82c30158772bd2c5980ca2f47347a876fd3a3535f0cd672fbfc9abc08bbc7ad661dbab0e3dda0d0edcaa8af4dba9385cbe1a44a980e508d79fad8aba2a3a99d8215bf2d433ae69465af9bd03d13f356bcc0f3fe2a4ccd0bd13d96cdc86fb27e1c5385818eddf5d1ccba54773bf3f91e3a8c81012df9da12b8fc8dcc45dc4956b9c16a2d829e22b92a95914563f7c8776bb4f39cb7e2d4086eaf639005809012c525ed26cb0a909ab3a4c275845d0948ea779986177f1ff77ec7658a35cf12c26e15184f3d63b19a6ac246dc330da2926c128e918d6e3687731c33dccb268452997202c8af3eb0e178026c6141f505777685d2d894133aca286d3d407289eac320e53a9229e85ee2f3076e2f3620670bc53227940dfe2845ec84dca06930455f619897137d0de53d90caf5213f6742037831b9a2ffd4dba9b6d86e933250a7aab82eb9bf1da25012eb4b9264199e62ed7febf4dad4f06313f180ebe5b283d87d0b915ae3dec8853a104c9559ce9c03d219db6afa49fcf631f7576658cfa9537167f7580aba0cc468f54667ba05dddeca74956696bb08648fbdb27f41318fdf8c30bb098d24ec17ebb6ce4a4fd0823ffc30b926b34e1bedf4c4488070a980bddb1b73a5ecc0283db3fe50d0276e4d240229aec5f9d2a8e0cae07060f81c0ac799386e9c7f6cbfff7240abb7cc503717c40bae8019ada8ae77854f23868bd48d942d8eabcb5b911e926e9310ae7c32dcb369376658883f4c0d1beaa81228eda6ac20d5762fcd9827b780a1f185ba2c3e6c96c2a6bd77c5a4582893fffb5814b4b32362f22745d714347c51505fb002ab11f9cd507e6c3c47f1bacbf6380eded527844154a3256fb86e3d2e71f8b04a946b264da12ceb9ae8b5a2379e2abf74b2c522dede798b8f2f9652dc9b55b123d320adf3c818e0f1325fec3f40a955b0f3517e264c2d3ae7e788f1da05ee402a41a3da60b930b729ea71d97af4512798907c20d7f80d3c568a830c690182bac71c837aba747e8624a56f51afa725ab81c5ceb048a28a8bdc5b2e2c310ef4170d617836f1fa9be1c038c418735d2a8c6e4d06e8c7515517b9a0028e279b1ba720a676b375a4d678e9e336dd55c1cd0ea9a1367c80dc5eb39e3a0e999e96ec686372ef253c37cc0ed17b38ee7f7cd1eb190b28236777272b122ceee93141507491e2a9323910d0f9ca6998aa1eba65eb2913dfc6811673552161d3c37645aecf041bdb1b8945f191e7c2d880289f05276f389fe570d237894f2302c9e0b0995789f801e8cb08d52df78800f09d31163b9477fb6bdcf1e47f45ed7b15fd8b160eccbfed4ac1207ac0ed0d760ded9215225b9405fe6a392d34680556458bd35a2c678026d5b4e999eb6678a6332f12a2f7534ca2474def7adb1a9b40796d55e144eff78a9dcc9cce635a48062b12d1247a35000d06a50ed0170649e4fb09b5e475fc776425d126a94df1328cd3dfc3f58ddcd97a0bb0fe1810be2e25c218adc8986695f63eea54ad825b8c000\";\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(\"Mobaiko\", 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 [\"Mobai red panda\", \"Mobai red panda\", \"Mobai red panda\", \"Mobai red panda\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Red silk jacket\", \"Red silk jacket\", \"Red silk jacket\", \"Red silk jacket\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Lantern gold glow\", \"Lantern gold glow\", \"Lantern gold glow\", \"Lantern gold glow\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Night temple street\", \"Night temple street\", \"Night temple street\", \"Night temple 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\":\"Mobaiko #', id.toString(),\n            '\",\"description\":\"Mobaiko is 1991 Mobai red panda bowing in worship in a red silk jacket on a lantern lit temple 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\":\"Mobaiko\",\"description\":\"Mobaiko is 1991 Mobai red panda bowing in worship in a red silk jacket on a lantern lit temple 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":"58027561","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T01:54:37Z","match":"exact_match","chainId":"56","address":"0x387A03820eA1b6463DB070dbC9b62a8215D1420c"}