{"sources":{"Botkirin.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: Botkirin.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Botkirin - 5000 Robot qilin with jade metallic scales and golden antlers on a teal-violet gradient for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 5000 free pool lasts (gas only).\n/// Every other mint costs 0.00007 BNB. Max 50 per wallet, 5000 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 Botkirin is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 5000;\n    uint256 public constant FREE_SUPPLY = 5000;\n    uint256 public constant FREE_PER_WALLET = 2;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00007 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(\"Botkirin\", \"BOTKIRIN\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646983a000057454250565038208c3a00009009019d012a900190013ec158a54d27a527b72a565a42e018094ddb264422164e91d0a0bc4a069fc66bb0131e738799be5ee01ee167af9857a8f9ffa2291d5b4bd37f9317486ff97e8f3cd9fce0b7f1bfa7efd76083f943b2b756f10ccfbf6c1a91d87f950c051f17efdcc6aff7fcdf3cbf7ed75ba0af8d5e96f5152f7837b6b7a145a1869217d282be70369d872f51d5c222348708be9c2fb815698f6a0d5af52fcc1376258b30063fec78ba124e9b81927e8f947fbf26c35e68dc3c6de89bff1c53a1d37069996fc2c371bf8ff10888118d48a56761ae2740351e6ab40644286eb010b2027831d1e9e7df4107c6361591dc1cca40f0a0c80462694f2d57b9924120aae758cbb3b0910b76927fc211e7d135c5cc086e6a18fbe26c41e9318e927f08b9478d95bb0666249a26134523f2b20fdab751743a256f025b95f11914874aed83bf5c4fe161acfd773c5cb2c07ebaa5d15081543943435e14fa79d04d742399c4588dd13d7fcb61b1a986e7f4faf5a383dadf38f4819ad4d77a733021a7f7ead0753173f6bd3efd89b13e593e9e83d9d55ff385ec03b72b848cc09fce17c90f26afcc5e116525aa7260654f836d9f1bf33f493d2baa08c5d6bf71bf57ea1cb296c0a9319ec42bd3aba8aef99bdfe925b86415c29328e691c9f8aa1d069f5bbe98bdaa76102ee5fa39194da82316f433ce3ca41e2e29f6b847b29b5aedaf3ea31cb833325b327bc56c0284664e144ea17fe1044ace82d50ccd49dd9d303ca2ad3e3dbe4ad4117f7faf7ff3c12eae8264f0d16eecf5cf0980aa6e63213dfd1b4aae5dd547f0a506f41c30c9aafa6b15ec63a675fb6d0ca8f35b4678244fc4ce5c4a1de3ef81362bf3847521d312123060bbf512fe76db8d4de3a61a5e45523c59fc2b530386a55385a6eba6273e8fc3557918238a1f019150fe5bf6060b6c9aa00fecf216fe675b17b1ac15bf4e8f6e27f251f8f6ff479f2a82bffffe12b7a8f1e6db2502f3dd18c19dc37cc5241d68e67ec5068f6e7433ce5a680bfc6c71c3b51174ad24c6fdc82f3fe153ef29e63e3fdf36d29f07f7df025b631cb61ca5721f0a3d073add9e42931c1ba6e2f21045da835d4aa918a453fe6c380fb255bacf6e56a120c26d42632236baca9ae503ec65819f95fe655a6dd517e58ae63824d153ef3100fd9f9aa67150ed049f6b137c59993a9cfd4d06cf26898e43c995a9d35dd1371ec7f78b1bc6c14de78c62f1d6c1d8c37175ce8e93ab1e9573ed5c52dca40028424ff2d9fb810297dfb516b2ab83d2d7336b05f7c81f82cee55a6bf67c5cff96dda18feaa972e4e2f080d690719e462ed9b8de9ee9d31e61f06c87e2a9a6b961f05dcc1b06f449510dc19cbce2f4b83ce1300243c6558db55b7eb7dc53d256b599ad83da1afc8a602b8b7d531900a825f05c13fe3983ee6b164df6c484f20f14c135ca538d59b9c743c72b861a39600977d229ee2739f85407a037cd9938d8da8376f32e22425fb36f2b9737b1b5eb9e8bce072f6c74d1b44d10b26f386cb64c5cbfa14637d97f3eb303c90084e7f07785034417cb0f628c7e89d9c36923f75db1a0d7a8eb59e96f6a9fe6637028cacca158e987f83302eba1ff8696ffe82b7431138c58d2da9de257e979c7b606a955eaf8de3544a9113e3f7838b1c5e91f00c40e803b811540287ed078e524e8a6259dc96bfdb75b57d3e526b51562eb9690f3483bebfcaa3b0dd803e9fd877ab4f38d58277a1e6f989938bcc17ebde7b436e3566095e15557b9e5db71d296e85f8a90729c6bf1597430a8ce5ad86a541f4927c4781c6dfff3f380c93026ad7ee0362902ac225af696832ccf7055f141ca9ad45bccf3f54078beb4177649af5b435eb0395167908cfd7735e51428052c5ec6e805a6bf800e2d9c41ca5b78d6b16eacd47e657c375fed034876ceabb3b98100636b09d8a7432e054ae8a36983622dc2c92442fa7cb08e8ccd7dcabaca2b8ea757a8c5335461a84b3270adbc90dde11a131f45e2d2d151d363e864fb05eea388dbc757ce94bace4201777456c45f0faa5fb67849cf25fa1398b9aec122f3dbbe3a0a721f1f55f04fc1f4f6b7b1c7140610fb1393cff81b42bb1aae3b208a6ffbe1f44cbb527f59effed2c007bf3908e1f202b5bf225c6dfbb07366ebb2d845ade5ae423b75a120126d96fa0cdd486a85aac6804ab50002b319b96e27b7ae3a4efe7c9e533fd16c96f31823cb76c78c25d6a4e3e2fff0cc047763a716eb052922a5769ef1a285cb4df93b63c1380842e55ee154e0118d456c874bddc5d607910bf3305b59006966cebc40dba6ccf687532832e5e75f113105115283992dd6b75830d07f2e8e93370b59f0fade8476dd09473f61e57082c34c8a4c8e3d6a31a84a6bfb513b692025370281f104536971fb6cb727f91e0d225371a6a21fc8dde324a5bf3fad07e845ee0e0405d13b816a259639b053613903bbd844019959be9915f1082ab27dffd1db715da31326990cba037880beaef00958ad5c2dd11d7e1e8596c916633477ef280c85eba9e8714ab249471b53ea4aee0e7a8ead971465db41931e83ccf09aee316764da5f956648ecfb6d5decd1cd0ad1a9340b77b9c14c90025a7d0269f82cef95e7e862fcac6715d7df069d12c71ae2a24f64704963f595ae7e08f5b547b130aa183e79a53eb1e6367888bb31266bc5cfef4bbe112e32dcd53dc4782df8be16deb209b3993d745c96af84e181dd26166c6a60c261e42c8174ba0d27aca56002f8219e0a6c9bfd4ebb6f641f0d985c5e02c6e5f90372bc7f6f1658b418f50234186f57a9aef7d0ac5a4cc28058939271973bf699cffb9098ee531be2b3b028650e3938e1331cc72c47ffeb7b8b6ae2a47167a6534269a67bfde710131e11df61e8fe30ba18590ac3756b4d5c5be01fb5304281adf8b3eb5dc90ab73edc9225a78b058f4dd5572086fa58183e725b23203c9c7befc34e1dcabc5363f75213f9edf08eb49c52bbd44000feef793e9b249ad84bbe4fbf36865c4d8c5b666155ac21fc6377dc07c6bd786072937899029287f83260beacd86a9088e5f43255b988b3fe5d7dd6d7ab228ddb72f925f462a223fb181a988d74093711f684edebe9bc3611757fdc5d70b9a3aeb34e06f76811a53ba196b431fc854952a4fd8e3b5c943af1925efae310fdaad43b337d554bfce9d7e1c826d0e4605368d736c85ccf11190cb99c3d5a2c8dd39b10cd3afcd12dc4cdc696e9ad9ce49a6de24a96ea41751fe503ecac25904b6b0ea21c782082653d5d1897fe7edad37ce01a1750b19e7d8a6a046e06e6ab4d4a74c27af476d330414a6f1c7c59c51946bc51841c5796bb48b5f08c4a5687c14aafeffcd9f3c1029225f8b40280c7de65d4927f4f9881e0442c047f3c04a80dd2e2dac069d2f4dd9150072e8ad8bbde379f2e0e82a92b9e965f9be22c3213b5d9d7cecaaf12539abb11efb5ce6a46260291aacbec9d285a1d3b5481d49e71822951d0f31a395561230dd651cca9f30559335d24247fd518b1db5545db675c656753c9c4656c4772fb607fd12c9a565a9d9b52ed48e793c124fb0e9a6f53a9dfd8b70d348d5ca18c56156349bc64e9c27e851a7b1b9c4979864486ab873655d507625c78ca6e246754f3f3526f7fb288166afb759396eacc4a090ae5e51a99507fccb80c7eddb44cd0742a4675aad6cbe919865e8bffc9bba43287e0d94f12d0f233908182948eca7d7da15cfffc7dff524ba770a2ab8be3291ac8d7dec6b288456f5775e53333d00f0d3856cc3a177d5b23c30f2afae3386418a10cc7b1f77f430cdb32b125b76cdfb875b8749fc49296116e6394885aeff7ddf7696b57ff19d0801623e99c4bfa339352f0ca42b29fa7a052994b3e721c2a42532d10342027a3d1a177750ac36d8c40e9df66941af37e735c3c1dfcc11cb3cbab7179d27f65a764c82b99368469511494a4ae8709010cec8f24cf439e5bd24a8adfbfa90bffa8bec95625aeb971e05f98d8ed756049d59c99e298c536e6d1853d002bb4a0b2a0f368c7438ca96ac04e2b3fb9065ebd0f4d158b13990ab16b412b6493837f366e40c17c1d15e0f805db51ff1826ef8fed6de1e4a606eb026970cf8e5c66677fc688d9760138fec9ce24466a3ebd9790103b98266c9f834ff87e6c91cf183a7b45a53bdf4cd5145636660de8157d0135dee14010be04bf5ede1e8cde274d849ede0e6a1fa0b5d968e873b83b330fe794d127afaf4a8c329778a035b5cd283a23c43ce8437baaf1c1eddb9967443a09e8c80d1b7445c5862fce5a97f4884ce516c6a8d269e7c3b083ebcafabdc4ce03f3fb2a2b7f63e794cf55c2a7d62a5474074112f9f403c07e1269f8b857a64fe3908247a021d004f34312e9f654746f85db6f240b0ee7bafe0f8746c188279a4e64f732789d3038cb5537e7cb115a2b970d4e2e9cf51fdcfcb19971d05c297cb02b221ebdd5dda9729ff954aaf18ef444d3bdbc473764624e45d82fdb2990131f7a13de27fa404edd5bbd73bd7cd19e83baea0dad85dc0c355a7f8ca6b4442d2697ff7d3b28561e43a4c6a2ef17d09818c8485f44ff1c5da2193364be919ce06aee75304944bd42799ca36ab59968084ba182413b81d28f73061fdd1c94d0ee4cb0f14edf0f8f0bad150ee61e8c8213c9c5bfc5cd317689c977bd6aaf6ae2680023ed9dc8422275e97ff1c1e882d2dda238e1a5beaddaf16d4dae646c1cfb1f5b6e5ff737464a1a527f3651348011a4b005c726dfaed6ae2bcf163e23bee5ba571d21290a39eb158bd7aacf4e0d07d97252529d9085f6e952417a5a386af743909da499d963e31e3d81bf8b75f4d6a7d18425f43ec7eb69f4c300b9ab1b6907b78dd62298dd9c0d6be58209511a3ee9d9a18c853836d43fe9525d6e5be6b7df7966dae56145384c2576befed0de7978f1bdf451a8da75eea3abb621be432560debc1d8a9480e902f5e0dc177a7e7c975fc66f62f4d5be8ccbd9b5760490b1a9c7410386f0b425b3bd2f1d4c7f58096ea7b7313804a1f19cace7d08e83811bf7cbfd6384a2946ef6c15eaa13724798d6ac9b0117c673819b929bda9a3c463ce82894a41b5b37e36605ae82d8157ac5b4bfa2229fcdeacd2d931808be22a1da56ef167526921551aa09b02e5280d79beed697cb6d5c100a306cfe26e99fe505ec1c5860322cc7e378789fb3e4d1e5f4884fc35924f3d4407616884c2bdc8f855e8bcd1626a9f97ddb202420056690790ad49f4027ad7f2a1b36a0f5f8251f2825fd4dcad53c1632ca65337fdce0a49d08f426a04ff27e3507ada0526c6d16246b7a06e8462b72757472911aea822b513c900f2e8b52128d0a28b24a619101f7e3033303a4493d119393fa56de9753c3c7fc4e5b793e036b191e8a15ad9dbe6bc5c28f72f17be4f6fde63844812d9efe62110ec80fd1ec53752ec2ba0c529910dd8187e9412eb68308c6c5bac9de73651cf1e20da5c0c1a7d1c6be117fe67376e8ad114b10b95bc65ca085c46784bd5c1d5988e3b9c19d9731a277e817fdf775d2d8396e90d90e25a7430fdee17a3cd9e35c13e6a5d5f1db3dba8b1d7dffa7a8e2d4f64c23675ecca5362a1babf449d7cbc3c92c286e5e8371cad26357d4defed01e9d735ea7f9f78a13e2e34b16ff0e229469bbc3b81ad980b4ec609aa452426afa4edd689cd23dfe668aafe54fe3c7c42cc52a41fc80071c9d9554f4d303780556cb4eb4849230de5cfdee64aeb7dacddb42c1e642eec6f774cdb6e8bb34a906ba30e182c1a02a5012fc46d1465968cc6910bfa42172d463ee55d71d7fdc9db9a8f6783d9d21bbfc39ba86238a24000ddc39a29847b8bfd97ef660eb689b77f048a83acb126b25cbfb72de12040df77d72ab4d63425d6c71b40db76555ab6c8f06dd481d9180fbbc1dc0f8adf94045c0de15e858a382d792fbb97ea1b45c580a4a384f46d49354d7d484ebd61282cc83190d5c0be56684eb41a4cccc2cf1cbbe9e85d29cc74e6289dc8fe6455c4b3370804cdaea9ac50d1847bca332853fc4638fcd810937ceff8d677b3032f837c8962207e394fcf1f42116591a5cbbe43f1e4ad71ebc14db1bc379fc0890ac5c34879c6fe1fd0e4413bfe67ffaac775a066977aa4472114543eb848da84f9a9a33d2f7d1710f312e973399f91b4d7445759e4f7893df8e0b1e7fbae1cf46ae9dda25b3d7e46eb73ec8c5103516087a31f2654051e210558e40335cf63ff6ebf5423515131970ad798ec2e472c1237b72e282f9d4df8542742529f4e9e6d277372bb8beaa567223e1a00c60e6a047f51f30df2fcacf2cf4988ce9752bb07bbef899cf9db1fea2262526cb0bc5f8f2251c5c58a13c8defce225597b3dd9e8f274376180fd3e345d828d0ccb2f11b1649325d0e95ce4f3e192c0943de5f37d9e1becc3d3f9774d3fe8f1df0ce3129c8b12ccc0eb1e2813d8b33facb4b1b594551295bc0ea581a88f0ce23e6d15321032ffa1b56d1dcc2acb5aa55b77ef378b9df10f732e6fcba6aa1ec524978b71b61c70e9d6cadec9a500b97fecad8f4b146671bb9761a8301bfcc032680fd3d7f77028f0f41023b05a6f2e2aae2b47a610f7801c8c24ffa552e9477227012dbcc9b2b39afa25749b7cd7521cc646f8353bed5760d2b627113ff36b4ae1602f71f47dab7ac372d6b2091790619b3bcf9823359bab93c789329c1fa978c2984066c9084dceaa474f5dfa78f6d31b636c902b110393e22fbda81a0ddc595f2944a0aac24b0f072f96cee560f633dde5c3499acc64efb07ca50c7a9c9a61f020b6eb32c26e73038debbf975ab1240a018863a65dcae1bb4745d06e5d4250b157b7acaa0caf0bc2c61cc31b12a7b20c0f1fe2ee406aaa7fb63a9d87e50cadb4c5b97b7979cd1dd4a8f442f2cebf0fdc60616eb7fdab825ca896be13924966ce2ddcb403f7930bb47c7dcbdedebe4242f21639231b66dce8e272d0793139638ced902d52f66c11577badaeb7bf849de595c1f7a06b2b6357fb9cfe31a4593b3dee527fd42c6f13840e8f2881db542e767348b643724902eb103378d1709f6c2349b1fb1e4ef87ac667f3a865048565962655c4f86169664274283cbc73e610432c9144a04f4205675a8f3b96ae4347d4a76604754adef46b5d6ff07b1b84ebb145d158c44efee9a0751636d1e19893d194d82fc199703668999a1f1a5ab7dd448d364f7ad63c8c6cfe4a10c8d458a3ba6c69b6b5cb306907d01195bbce443bfd091814ed5c95295ffe58934066edcf9b6d90aaccdeb5ddd1be97c584a82a3afcda3e1b4ea282909b3df0bd4e1ab3d8df05940c203feec30fa981685eb0771a5b725a06a98a220de250226e18f940d697247c69e92b14713e26d617e69af970b399081d0db6641b2394b288ac140dce2f4340e2c74dcb5d55881cf3df977760b6cdc305b4e6095653b37ae826cc6746762e5f84e8ec002d328b039e3f76ff81c918e6a90e316a9710a468faeab22697a7c8053425f2b29c7b59870684e81ec01c59aa6e2eacc5d0859ac3cd46c208d548e64054d59d5a60b61634938160c10740b399b96ad5a8d9fd2ca11c138f5af47b5586acdb4e9460394add81f7741162fda5536eb1750d8f9ac4e1bff21e7258a930245bc5d25dc3380ac3426659727bc21fed3caf9278716a6791c851f1f909e535a4b1c4f68f173b06420f71f5ad7c02f23c4855da37fe532f08be5d0b46714e4d0d1570b52c2dd66e9bd42016428af53a3bdc90968c1299651c372fc3fe18ec01adbc5a1fe399c68de16d18b119ed728452d2e2a210408dcb3cfc1b6512d759e5363132cd512b98bd4dade85049b2b7bc786c9ad281f9ecc4ac306042d39d4a68fa7e98becf1ffa0351d545eac15f3fcddc6e90d7b33e64a62a7b003850b9e967e7ac47592cf8602066ec62e2c331b90e6d7a8471187e14a74ec1c2de4a7a0069b20c66245b79ecf7b61e9431fb44ecc299d66537f8948e40dbadf53312e9bf460d12d1e100646a73bf94384ba3904a7695c595a2895a8a78ab683f1a46278de5c85b915f12037a5ae96fc9d2aa2e248f00f8db9692f19ea323964b39178f60588c1770d5842e09af4032750686ee335c29fe320c7756973b7de5c7b14663b375e1bad6bf01706b460ea16f8f68034acfa277318d321cfa6898dcad526e3b9a676380ee5df5ecc35fa012c958169beefeaa866d1356b488735f3ecc7edaf4f1aefd7d0a39d691a7a642ca2abb76cd4ffccc77fe9e971ab6bce7c12de746907ae447956bcdad2b97a92f1754489aae363271950d2c4fa6677f846d7f617d859fff7896de2148d3cbc5658e2d3d4b423721b0d1e9d3531f00bfd69b82fab7b08a0de45f955092f0db676ce24526f73fbc4de4a829ef0a8e9a01e069fbb871ebd365334fb18c2e2766aec599eaf41700e1061a0e9459d3ccbf9957ed3dc3a3e755d752bf49ac44b77939545f67a23ba452c0d2f0e0d17cb7e7b5e00a30e6cdd395614afceef335e0d32744367865986827bfe86b054945bae9d5e98142e9395bc4923a09c292e27aa2c66015c250a2648b150711b49c816df5b3de0db773f5802891d739bcdb71003907876739a5f98d9b994aaa8a9e04e0f36f6ca88ab07ae9baaa627dca49d44118090b606330f1fd7bca603e039e05bdde99bf29750fd4c3bcc07cafd9ec0de4f548d54ff9e69837dcf875a1081f7b1739a767f3d6a64437ba7bef4b8946f2eb2168aa80664ea242fcf58d80d4c0561df37a19c84ada812778b0163489bf811b0daba7f1c6e4e53ff12ea5825042418fc9da7a785602c29a174265be020f2ce39dbff654a4800adddf7cec901f8d9d56c8143381e187aebd31b0e8b944e7f92b6492a35e2beea9017d1b225f56ee04af83cc5f28b80b2c10d2d5ab13beffa2da4867da766a268a708b7903ece9873358b312035fd7ad4128ff1e3bb20893503aed25b9b6a50bc15a2c32efa6d55605637d90b50c208fa5d2d5caabc86770951fa047603a68ec160a8dfc3d9cf42f69056f3d9aaa54e28268d887b993f38c0376e0636b29c4a21ba5d04823e803468c73f89c9dabb0fa4129534411302de97939069cfb513d12f9e664693b6aaee21972ac22f040c2d9ea6d522c5e7b5c0f883a2e151a33b641b7a7eb47c4f1c3ef93e7086a2e20cae108bbccbc620b196101794d4c936eb097f9fc55e9eafc481a2687069a5c8aba54a18da9cc24958b8342d580f3f22b6cf2b23a5b9dcc05616859e5a8bd373a96f4bfe0e45c050651a1722a8b3b17d1103ac33934dcf38ddd07c84b63cb64ee58d4069ea8a4e21e2c0e5572a980c890ce14b39849ddd711636ad2d9fa712a54f784163897fa19c7fe81ac0ed7fe5939d9b78b925098f84f63054fc600d390cb4e3ccf5af935e1fcc4f875ba7ea6eb91ec31fe0f9a732463cfed044ed7acda9c03cd7f8ee8bf05714db8a1f9416607b94e4955c9d8e0c319399279e031918fb5f65a9f357a7820d2af8137d1b685a6363c963d3b67c970d5dc5e5cddaa1e87e3403775235ea3b0d67bb3f8d8ab84599de10115572db65145d23fbc59c75147192ddbdcd081a9b7317c5c754a40a23706635aa24fe7b43365426a32d62ae67b42e72589f9d81e616439144cf0bcd1976016c84ed4a5c6b5c643061a5da53f41173e40765f2db2b6e95349b9579106fe6a51fa0fc69a6cf958c93cbedd061b96633d72bff9a1b95ad18a22857ff50699aa95dcf897340987d9e992b2bf23b173d1d6e522936c17f7ecaa6bf7aa63130865755ae87ea9126575f54a82371bde745fe9101a1a81e29a8596e668475be1574fd61328db8a4444bce49bfbf7ed226d4c55febe44640219f886eb2f841acd241b5029f0a5002e6033500871d71bb078fef6d0f002e56274ee63bc5e3f7166d77d05c1021d943a43b781b61565612e722dec9ba31c8207418d7c3c3a4419c197c0fca86d89fc38a5746a45620257fd20e60895227eaf96491b102a9fea22f95b18d9c438f46a474395a265f194501e0dece354f0f75958ed84c002d810a45e563b6f01c949b01b5fb0d02273cdebadcc1424c357b9fea6772b728a8ce481926e2761a4006f56087e1e92115a02c99389650725ee4c065b394477701813e318724a362fee8e0869bc39cc76dc019a4759e3400788867979f0fdfb7f09187b19663030564864cf7f3df69e1ee3dc03752843ee9befb2c2515b03b38b71d6cd27db8f9d86a95046734f57797906dec7ba824a803cda9c503a21c0ab659444b6c75dd52a0f7df4186089678aa92f1e99bb01ef16220b28b6af70c76323185435f6543108b728725b0aa893a62e31760817783ad547ac0aa7c2291222533afa536a17fae920c6e7f1e24ebba60d0e539fb751c55109df064dde53037d2d019d247b3f07e08c9214912c3408ebddafe5e8f8b8cf5da492e49000bb03f2ee5d5c9d9b6f380c92e74da6f64073d453585204bdbc6d38dd09846cf0017c1870e943b83f4f6ddf4b8482458f1d2fbf9e7c2851dd1a440b0ae56cf11171c6f2da11aa642e9812ea4bcbd5bfdb2e5106ce169a53ab25d8bb288d58a2213a9c49b0a59c586672f63debe74178444a508c6d7cb302df488b668eb313fdfbbf7e59d2f7d1bc95e7793aff3c1cb19bf83ce63ffc27f126f12f013886992fe3ee7c0a6686e4f6bd578352f9a57aa237497c5302b9df6453b018b4633a55ce87625b6c046f01a0ef9f5cd699b41163867f76e1ade88e2a4aefc6aa170e259477a13f25f35e93905cd303c177be8d899a8394c122cca2740599f8d459bcda5eadecf4e1ed7492cec6097389a985445a1e52c274113c0b1171af9ea016aebc823a51a0c08f763896684485918066c08c98582dff80b84ce5b5886a1273a41a75d2e3bcaa513a724949294e498e55f9d24e6e248a2b57cfc4fd50ccb006558d1838c04840799a0ff7e20afa2fc98f42bf455d539b278e4fcbe54d51b99bf9585e500e76023ae73917869ff5362e2192da59e99001af90ae5c6c255aa5cdd6b9628ac7ded5323eb524c179e2e0b3d651290e1205952c180fca84c8746d6e234b134477ebfd12ddf201b5bbdc3b6886fca8ea9d833a74c2bb031b6054d3b2215ae63441d89aa905b551d85dcd87fc689f7bcaece08392b7202eb47888d339c562e38708fd407152971f24d2dfc80b19b29d562897b694c3178f8e85a81bfafac9269bae9cc36a8ff0519cec3b75fe5085e8fbf9f794ccd09f5b2b505e88bc8dc55a3941d6371fed273ffb37ca3d62d37aa767e0a8ae06b4e26cfaa697e5257c156a7f5263c587a9bec807a4e15d794676b59d138920975b4b8b4df3099b04199b03a45533964311ec621a9f80ea36b6cd568311f3b69156742f380fed4f1031643f5eaa103156c5882edc8020b92f493d0c9204c42bcb125e50ef4658c26c1fa6c65336a7e28047372f2a2501b903c08dfef46d67653a762d427d3be2f79b7f22490e1b6cde98c6b40246e4f36d7048cdde3c7408543ff0d6fc0cd3f659ba992fa0f981a0b572ce7b69a4d5eeb7c9c26e9ecd79f07dc77d500523c67e55a3b206eb3cfeae8189635ac74a2e529ffa13c7899c07da2c2d6b300b52558c068adbe3d3bef9bd11496309fe16f9f40f6b93f075fe1917a53bd7afcd3f65cf6bf3e7c1eee17c499099d591cf0700a4a6c8c4a5b17417c9f6aac31c0d721008cc31c830245f632df460d66193a1797a8eba6d941bfbf48c1f1a21f5dc07ac5aefbae20bebd5150ed8aac82aaec7d87a58068b971a7187ed827061872adbfe518e8617a7d2bb7db20dc6f5a2298926628818db7f0123455d8ff616e67ddb4af6d3108c5b5b5ee936f3ef3be53e2f4709d7136312ee274052b59b57171e0cf90256c97329ef82a1fab446bbe61948c8344fb3e2ee0c9c959142b389bd5d71e79b03fb861b56504f1aef6b1219013b57bc5144826e964339861249efed517709ebb0657c3b6a279ee58b29305361802e4d24dfd960a42d686194ae29e6a1a5efe03e58f3f9703fcbcf2ed9e99d32f68c86b92adb57092ba4905767e5d00b4c00de761bd0632407bfd3455c26c4812667597c3427b740999ad61eef42068c51c1b60862abaa78c335ff23f7a72c1fa5f28b6fc1f73dd4354264c9c5c99e02bfc0373ad42e1307ef80b3fc49c76fc64a0be67b9a79579993ac0d3a49628cfc03deb390bb263e7e361442cedbec19009ad36506dc77b1254d78709a136e44060c8869bf2d484a47192dd4445de92dc0a606e3ae1b128196618cee82521052e7a1d3277ad33756e3d5f1e609c4f3c217cc7a06514d7798b758bdebe51598a9fb2d78fd9d5c1fa8d670e7543d5259e3178ab1bc7084a8b5ba31e2728e287e6354d6c8f428f5080724379c6e42fbd02a22d107085ea5c9358efd1e3713cd91cb6ce74e566c68e37ff4fe1bed541764790b20354f6efde04b0588459d05ee20970cb5849c6e63f46a77b9501ee0db292c644eca70c3380ac5fb73ab55cf153be4b35710ca64094ba621e1d4be1e68bdf4bf9df09c0212a31fd3aa1f650e5a39ebd7f00b8447f807522f338073422f652f7bf83af0a83bf1fa50934b18bb4d706b358135d52e28492ceab2a2d4e836f8bb14c4ba2263151326ca918f3ded86774dfd0d87095a336f2edc20197b03ebc4d0824dac3f0a41dab7707fc82ca4f3cc2a3d8bb2d35da8a116d32081a185ac0d514a7ad13de06726c731ed4bc0e65fbfd45fb5ecf24465721585b2f0e93013785e4a6b5af51199a2705c3b4cf7e2511b401fc8348325817ae4c9f723c737ec45433d92aa2147a971e16843006da47c929ea23be0f910982359679c7323f19478812e69b5f50a5b15781562f903310f1a35499dcd9c261cada8e29054b5a77f1e099085171fff87aaa29ee7da83f3377da35d950c9f5e948b553cc8548a37a02908c484028aee4f9143a4799aab0fac6fb0a47015d46f5574c62b0d2d91f32f764d751914ab30789965895b377ce325b18b96957782fed014fe696ada0aa234e49a4bb9ec9a0e7cb0f6a0a3e9080d70699d4022e1d4d8d5cea68a47e2e3ab7514632df6c51b97a1600e20f8b293636bf090668b472da8d41a33b30ea20bbd42cfb0e6796f1b326d56b419e5621bddf4969211e121203e7e29b1312b40618d26bb779a38415d5c9dce1011671d9b0ca6ccf713e184c4111820212aafbc905d158341582aaee2db986751f1935be3d0835c5af157cb0218231821ffb0ba851a09b53a40c7574a5caefe31e6fe5a44a5142c5b564804c9f7ab8785484eba38a1409e5df1f17d24c87ca152ce2dee3b50fc6db6d78a7566439665bd49838924743a63edfdf3d6271522a11a8e3dbeb9c485cd86fa0bc0a0d397c5413a36268c68b886d115ca50abf727297b8c8c32898add3db93454ff3c6f0f6a0a7ee8aa1b44f4360e3ee887b9034400bbe2911faf35084e6e10f7585ab66742f0777aac8a134529d7cea7e9f2855c979b08480fe735946eeac8de775edef8c6bf61fefc993b0aaabe17549bee3d05dadcb51d15c2a70cfdbca2c48a2fe3daa8821295480725cb132f2791174028ef75ae18fd48c7543f91789d3cd5c5fa41d7aaabaac8f0da3c1dc32c5e531bc911b6e0f07d08b9fe19966bff5e553a61a9195b43c4e1f64b571c3bc7330c9a5a969baf5d585274de1f07cae86f29fbb9210224bdd3a0511b5931af8b516f9aa29282420a134ff22ff23c0b31d04b72913efac397462d7a36c27ffde30c6c974e84cfd7bc16db72252f57339304a460c5620f8b978475e6ea9f6343603a23ccff3927cce122c1f562db762e59b44eacd020c161482db6aeff85a338e91feee1d6e4d1a993ae82457417fde434650e9c3de6e95707ddd3483b4be68703dc58bf98f2315acc38ec5d90a9ddb91d9a63de0dfb2d4ca7730cb71d5ee7624281f89a3215220fca6eb3b9e1198cad70002d4f24659af19d9e41e5e58b4e54cd837886c26df87282064b78e6d3a5deff45be87792ac5fca6b8596741b8227ef5085e8cc04fa710fdaccef9f461120f5b262914dd2c6a0a3a852f5a90a29e08fed7a6ab59948e384e07d53bb04ed0a816ee69c6c89f69c108134803dce7f399938f606ec756b6385e066ccbe6d5c473b90b57685080ee3d5a33ed8cf6d4cc0b3a275aac7b795c5b6ba3ec7c6093474adfaf0bf161f02d9d9f17d2b8737ef23f52d623856807e25e8dc60577af28b544a78f3ff99802b473afbe65e426ae299108cd5e4f242cceec3e231d3abc69f4f520d20e9aba75c9e734cd47b2de8a1e08575eef367fe356c2136f48c471c2db6f37417174b7d7deff8cd5d60f1f91d5263e3de3af444ce476c95225595435d8ab722e3d76503e9e95588b0585327caba151495e00dcfca708a90ecff20c3c4846860e7d990a7cd81b414dda8c0f2ebded4ca939d5bf5919a95c3517a60c55de3434eb3188afbe8ee2fecc97e6ee766b6b951ddd95e1f154e47197fb64893422bc39662b2403dcfff040ce6c113f3f000c025d15078f7ad84ed10e2f79d64adbeeca644b491dfc6f1cd8b27d1fa4b59806c1d76496851f9e9d1ea4ce683de674c4987a496fadeb64c10dee69757e7d4d6b0869bef36256762d58dded941468953a3173851e2d0a4618dda8bfed83ff5c9472e966ed846aa642d54cafee0f6196d5474667dc89e113d150998f7dfd30f5e3f165b3a293099517164fb0cf435e1c243f7e6a99586fbedeafebd7d4fda4f783b8e3c2313f9d48ad011c7cb792db8cf758d8c3c1b207062501a8a58f2ca3e0f729d9fa104797c1f3816d3456304903717f30d83db8351cfacc5cb2446d0948f4744c084e71949d5c5d1667ea765810abec6414508d69967435292921cdbd2b974a3a2d94f7843abcbbbbe56b5968833aa5c381810e7dfa3c4f060131aaa62c19ad8455f88253b29b4e8e187877cef164bbcb678f71a44b71bcdcf914b8196c9c105138d5037d5ffa5e7f5fc45e8f0885c58b06b63cbe26d89201ad1730ff05a61db6c9a2f9eb2c06f5d7186f44329711cbc83b89e9e453076cd9cb0089943dc6f65251488bc4c8665ed8858a5a3785561851a363dff7e6400615206d73cc6a8679bf36555711ccea1860337b2b9297c4c7ea93479f93c5fd803e7e240d4af04c1344510796c0e130aa98234fc94f7edf865b3abb19819d37d087045392fac5192098a020e166dd1214dc0f60848ad481f19b019992f4ee60c73180aa99f498012487124ec92f1479aa23d8c45df1b047e49932492f55d4f684386b6c814525b6d2ab1a56830bd15401fdad2adf595b43f05c94f555265242e77de3d9baa8383302b8530fc9e28ca2ff894cb3b94c966b7d93daca0844ecc219f36e7d473780fcdea5667188e6f02952db071ac0043e04f8115bcdb65593d6b75e82c0b006c9fdb43fcb83250c1eb41e9afb4a3bd3e706230998f5e54467883c41130aaf90735cbd4698aa873159955a561c62cee61ddac99bd3203ec26235e081f4e08a8bc534cb4c1e3628f77928f2026fe4a72c3e08dc4548f00c78112150cf213bd90fd9b9a9a1020a777aa885648a599ecf83c2b38f0107a345717d4f93014d9fe22109ae2591e4740f3eeedc8653c42cc6e2be417ce0ff12404538f053dba957c04399eb289b7cd9c7f65523d99a6ae74fd943a5df5e6a1f3ed90ca151dc221c83469b4db5d65713f450f719e78f226cfbdd7d898c213ecfa9953c2f048db92f05f4c9c696f3df7d072e473727231c3a52376f67056851f0254e988f4f3f9ce346a444803c57f558316c8c486e70ea8b600a79c83b7c3a2ffc391346405c7d3015b84999e8503cd2748bec10feda917232d33470ba40721b687517662532482583f716b226966696c5bcd8d27bef7632c2e3fb3a68592f7e1b952464152bf9a6d98f67e7f44c14c31851e857ba9c3251d80c4b37d4cabde66edd07fab14fde1a55c82e15beeb97024c64627fd693f2190beb521a5dbca5e5f497a832fc8d158f5d19dc03ededaa3615284d6f0f87c881e2f7c575ff32f6a942a60d725c9330610e4bcead1294fce75b98c2f2faac849ef236c814e591b6a1caf666736a541126347b91e1104ec281a21ede0c85ee29e9ed22aef7f606ff6467c05e91bdef2b8905a5127b902f7332b567f9595f5f68abc9be640e143e894ecec72c44f82e3f4baaa8d159573046117a0ff61f53f5b18a8f8f11ee532771a0ad2458f9f233bf9822824259cb8483425ee35746c714939214de002a93b8b18568b05d0ca49bb332f60ac234bfeb1e97786ccac3bb7e66d4e6bbff26a4e1b5ad5029792f31cb1619f9cbf90f25408309fd2af0610e1313335f50ff1368d52034fc554d44c0e8a70dcd9fbe63bdd80855d5eb911cb9cffe0ce11060397becb52240c88abc0d42f261bc62fa686ca458868a5d196be1ba2fcf6bd6bcfe0b669dc5bd935d5c11f16d931f97b5f9ef8349a573c6137265efcc27f029da56a7b0eb1984509d57b317b5e19b6c690533bd8890a67e89dee9b280f4638e4b1bbe4692024f9cb9f592bc143c1d2a1ca2128be6de50e7e0aa9a275b2faaac0a2619c74aefa58667107d6efb544a299491b0fa2831582858296b29bc40d1a4bf24a4246cf73cd75786ccabdf00329cb2efed339ff8bbddd1ad632c645d12bce9274a8993804266e9046aab685191d06b96f13fa539656a4b7058c3471d5572d81b0ece9f33054d0ca847887e1c4569e5ae65a9c43c5058882ff80366825e4384431083c800067235962e06e9403c52a39f5e578c62f5af0c468452b9f933571d6954acc92daee2a434284900f53d99fa218e6c45608cfb37b7d79777940c0478b6c2b350ff288d87e510d7383df1ac4bcf3fa05b47988002594801480e6a238db21486f79a5d9d141903dbe02c2be2687c7373dad3bf538550e6a2c52a4dd345650ed10e051a9f6cc3813a771b0e55e3697cf4ca7c615032183acc056ca0d6c821f5a0b638b2767fd40af0bbdc88d3b3c42adc270522f25ec9c74f9e40b3996452a400b1cfa0fb57bbeea819509f6c17fc8d55b1187486beb46cca65f8b1f85d4f749fa51fd8ec016f93ed7ccae054eadb87090f79734a41032c7ef2e7ff10f9a2d3c9b7156c4725327857a832fef8767072c419798e2e75bdf373d35dc7bef7690f5a1c03363cf45bcb320bcbbaf5f283a23274bb79fad19ae27fe877358aec240cacc92ffa89b6a477b2668e2991f6cf44791a3510e78798448bda49b8dc60e0bc7b93948a88218b8001e54a24626ae975657f6028657a26dc2021b140aa120830196fe87c067c015fe2c0357e1e6f6d8651f53a099afde4c5c8c55959b1d453fc8fac4bc570f94d4760029017ca9b2489e1aabb196cb62b48d3daeb1953e20716233777638bad0caa312efeabf8ea7f334cada8aa07583529cfd824dac1e585cfb7b02aa8f411911785a4025f26c5f3300aecce2a47398e22b03410084bc62107309d4f413dc3712dd12e2669b53159ec5b169a9019dfc430c8d209958f2a69c4ca1ab8031d987f50382aa0b22912c0f4f6d0c947aa04eff12102148fcfa7e5e06394f18c91e92e73dbb02494efcdb10dbb6289a9b641fa679326c83ecdb50b8cd8c26b30a055ad6bf234b3d95f55393728fee699e2065beacf36d01d78b17143bba336e96af8632415d145741bda972bbab961496a7eb8a537de378b4508984c882faad31239e5798da31cfc87dfef2b49c2e7746e0f804e89b0c20d58b1952317e3e81b80ecc9bea4fc7d994e5b097e18c60a959c996e3daca57558a75f491694dbd61d4de08f0564f72aea5211ed7ae3423e4582d490965bbe8dc63efa0fe1035c68a9e68e5438e96e27912010aafebfbce2e2d454699a1788560733e0ed964cec273387ad43a8cdca66e8fdfcffad4088ea1fde30d817aaa202a273993a810ba4295fe438de04bb1f508d4611d030301180b875893a795d61c9cba8baaad2b1f9ea200e8213d47aeef64dfb26f88e69eb43ff2e8efb495c1955308951eecab419ad963dc181439508e29026e9eef5af14050ffd4ed365b81cc004f4f85eeb8fae60de21f9a84b04607ff2082e5a307df81d71dd237a706c143f152cabd1a9998e4634f8f5c4a75ef10f6044fb9ebfddeb97f9483741ddb8b0e0731392b27174e68727ff4a6d7170fa2cb4d26abf45e11d2af00b496e786df7052d54436af336c5e2f87454c6c3b838d853d21820b1a29d48ac23f2d31876865a4da31ac65e243239e97de9d8ddeeceb8fc4ee62ce3dad5ee572b86ccd432977cd718a77245843f43cbdd72bd31e6b66cdc8c1ad054dc7453697ba15d267f64b250708c5ab6bba32aa51659b1de59678f1b54ea8ea0ee945252ecacaabec5ccf3c0641f21a9d1cc855ec3f37afb9fde387ed917e8a8e4bd9c03e166fecbab5614b3ad0975eed43efd03125f51eaba2791dff81c568d06de4a0315718259b673fa865b91894ef85a120aac3646e79ef026c1d1d80e1dc6ab49ee6b41471b65b11b070af8fb11fab7a0f484e25a4cc4deb3c51c6b499bb3bb8c8a2930ec908ca0b9e653f70cd29a2f7983ab87996370e6a5a47759612ac8ae7809bd1f6248d20004ee73e76b8a63fbb7fa1edde910f5d38155a3def1b8323c10938a8e75db71f4deb03c4cf2b264929e48601f874e18c90a5d552605df1fff446a367cf4f883c1c14db10f77b9dbcebfff067507f708108d314340c16ae9662365f2b53ce08282b1f23d72facce6d4b27921ce549a852c98e8aa059dfeefdedd01be2cc960c1d4ec4dad004760f46b4d6675b5746a3d077411cc7dade7738072d8eb417e4bedac42f33b4307566cf87d954e643d96f697abfcd27865c37359bc6d35af337b9756605894562d758a8fab059a50f0567f7f490dcb4fdc56341f8733d615359af131639b157ffb17cbea0c93e5743206525c7c0e3b6b9c1d6610a8e999020f604a7a97f5b62865a2e023f58b29e6cd945c4a35f920e412416f148bd4545a43d6a37edafbc6416f59cd2a16810639e01c23e79dce4b3de7e313ca0cda3f8e6cfe21be83534a12af8b490b79d4c0ef238a5ae5d14ae825c95a04c2a2b044a7808b8a0242cb68a506d8b53c2cf9252a3a33523edff0abf48ac144e5cbc0cc90c735b7e8c45f6de225779e5d00f3da43e6aca83cd1c9798c705d9431e3540d74161ac84ba76e3b8331f66f9cdb80a1d44cd473f3f35a3533ed856917b60b64c569859d0d191a03f15936f9f8b9a2115ebcbc6ef03c0620910c1c88eb4e362409eaa5f0fc16504a6037da7cf67a4b16439a60a9c828b3123f0179eec48c8c6dc987d4eefbdb8304a754a487da5ee9e0862ed739c36a74721646d1e99f6c8e72118433fb8cae79eaafeb2d772dcb9eab718efc47a8e11ed3f9eacc3b67cb4b5583ae66b854c919649dfa51d8d5aa0c601abd8c2a09cc9421857576ba58768598a3fea053b2dfa5bb2d449e04ce9897300d6092e09174e2619677933277b925f3a37bf3ca445845441f80cf8a23199c2760a89fc166892e825f14d9e2f83bfd766b3f65b6058c075cedbbfb6d0c2954a197aeb2a5935935b005315115f0697e9b183307f2421b4feed684cacf0ed501e1370dfa6862a552811461e924465271b393a7b10af761fd8a1065ecb9ef9f79e93bc49859e1fe5731981b35e67a3433f95ad1b71b3a6eb174ea4036a922bc6766b4055848e83293a34468292acf100b79ad1fc7732b3fe436514a51b8f0a6b6ca9ed88aefccc70f2fc98647b0083139b107cd502b7367575c4b99581e6545b40162a4f3912a99a016597f23c33fc323941db2dfa399460fa6784c5589e5637d09850b478d7b63122bef278c1266f865d100a98f080c624630f8aba7daf7aae1ea3148ec0a4254b466866aa82a2abf5996da1e9876161f52ace4d1bb2f2b9965f9122b6757803f442b3da3d5880af07b8e4a4fea3e4ae82159d962d0416bd3cfc92524e558fc2dcf1e9462a7f7b560fd93f1acaa680920029ece5d1d1ab345d68ad09aab37550c698104208dcd6b3cf6ed3474f1d31083a4ac1a2210effbcaad74dbbe8efad1ef71da5b1e5720a0816ef3eeaae72436c9ce755564a0c69a859d17670f651305f4c1bb5855798701e2008356ad43aa24661cf08bbfb1726a22369f0bbbcc525623a0a1e7eb8362d54ee22df3f442961c32757656b49d9c9b45586d67df4a04b571d8ab4a758a1532a45562c72aa2d1f1c9daafad7470547153516606ec8899addbd5ffa84636d9d7d3c1bf103979301da3ed24d54dc74684acf64acc368c8f73c8d20304987e12175e85ae59a0851af5e429bd8bb1251556e46b78a568678cd8a69774bd431892e544646561b5c409221ed65b9fb37b4d4a685d40098afe0a48675c4126f8a73c3d32aedd716a00923c50563cec5f0d082d544900ac3ad96c482ec9f742d5c07c082a5acdfba0745ad3b616cb5f4ed0a26c85325aee0a74c9672f858357455b31285d7dbc2113ce32bb5249701f14a35af8c76bc56e9667f5789fc2a6ed507ecb7a55b36c65e3ca07fd485ffbf018968005f29ea18470aec1e06f83e72e18c8a32cd9087c09200ef635ee1aecb90615acb26fcda5c58c7679f7bf23624091c49fe00f9c5de6d3f21eb69b83212e93f45c7cb47c31fcae3ddb2bcef2f9e51ab65e5401effa5fa6bd8472ed955b3ccf3e4129cc19c37e90d2383ea2489eec8e12c8e72a66c90d4f1cb53ce6473e97709b4817845831ec762a4585c3aea33c7522ad8748f7cc75088d23f4436288b8966de8af2f751e23cda1d51ff74cba0d56ac9ef811791b827574464d064e1eaf8fa5c92431a9d64add503c696b01ecfc5a5f1a2bf36c53bec1c7a8c0e4a90ebd681087881c0e9f19e9947344ba0be7226672abe8444e41f67f0a8dc8a97d19422e7b553735a7dfb8cb88f46002b10628b988217c9780ace60e7785ea1d5edca327811ccdc3f266523c2506ce4fa59b6cf9a4aa4fea7ae0c412a991755b00813303bcc1e554a65bc8eaf96629e8cb2b2be4b12b7fb71e42c54628ccf5b102edccd164a7b0401b231d0fb3ff4cf269690f8364804ab3f9bb2f8e91e60634b7e03051726cc6c5c3d8094c4b01dbbed6e04975a46a7a1d2f13c9474c0931fefd0dadf6605344814040137c8000000\";\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(\"Botkirin\", 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 [\"Robot qilin\", \"Robot qilin\", \"Robot qilin\", \"Robot qilin\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Jade scales\", \"Jade scales\", \"Jade scales\", \"Jade scales\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Cinematic rim light\", \"Cinematic rim light\", \"Cinematic rim light\", \"Cinematic rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Teal-violet gradient\", \"Teal-violet gradient\", \"Teal-violet gradient\", \"Teal-violet gradient\"];\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\":\"Botkirin #', id.toString(),\n            '\",\"description\":\"Botkirin is 5000 Robot qilin with jade metallic scales and golden antlers on a teal-violet gradient. 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\":\"Botkirin\",\"description\":\"Botkirin is 5000 Robot qilin with jade metallic scales and golden antlers on a teal-violet gradient. 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":"58212418","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-03T12:09:28Z","match":"exact_match","chainId":"56","address":"0xe43818C2C6080E9d2bef53DB14092806B51711D2"}