{"sources":{"Yetibun.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: Yetibun.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Yetibun - 3993 Baby yeti guardian with icy blue horns and a red woven scarf on snowy peaks at dawn for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 331 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 3993 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 Yetibun is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 3993;\n    uint256 public constant FREE_SUPPLY = 331;\n    uint256 public constant FREE_PER_WALLET = 1;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00005 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Yetibun\", \"YETIBUN\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646a24000005745425056503820964000007063019d012a900190013ec154a24da7a4233228568cd24018094dbad884623803647093088902839b8c81d5c5f77e62fc7fe77c647299e7fd01fda7bd3fa7fdc89cecfe6ddbf9de841611f2e9f1dec6fb5728a7e6dc1bcf438b5a88a76af039a881ce6291c9eb04683b44490a73ab63e24378692b99f5c30e70dd541cff71865639e989f182178335939439ea1ed8b30bd618458432bce5244173a714a82db4857040a9bf3e850e39d1dcb74d05340258f34baa2a01ad261074059a6326bdbb8ea87d9bae6e6673278cfb1de7e5c75d98697ad77586441ae09836ee19fdd64e8f4c0c3862a2d744d0a292508932325bf9142b8b1f44e231ce9485b020f101197864a02f4f9a136121feb9ae065b7d1fa9a635fe07ed393d68de53f25b02593c7ce623c62f12f8420f24e92b4f87e039eea0b34c5fb5ea8992ee1926e3b4ff4ba1e203601136a380b47c4f194cbedb362116f7c1d37451ecf9acad01c8c30dc735667a808fb7f3b43fcfe5a31d34bdf5df594b6f2ac85b83c7782e5465d60a0db23b7e8c10dfd0eb8ee06030a89f42efa3499622da3452f6174c35b51db0f9f5b45b9dde4f53418c8334fb76dcecddf2b1f7f4fa3cd75f385db57cbe566f0bbdeebc4db31ae614af87cbfc51bae2f3a0c69add31859e1864c677c0cea6ca2c329e33b81a0065ea99a339fdbb60c8a5b2e2d8cd1a29e07c808a7a283a93b1009104cef02f85eca8403ac99ade4df01a44723c9bd49de4aaf4e97c7a5e0f056578ec43b322f7aa3de051f02a567035a6468dea02aae24596eb875b82569dd4628c923259e222ffabb53dab15e55141931ef69ec9fbc6c89345dd3edf4b61b3d399470d24e4cb70654410eb6a4be4bd37de9c5998f8ecf301c18653c287527c978147a9c4f81029646929ebd9e8c58f0198f7ea756693e1d8b7a183ab836eb7dfad7353d61ed2361bb5f3902bd5139c858fad65842cd1a1582b6c2afde43cea445bf2e09416b6bc7216f02ce3b64c305bc5e3af81e040d9b7f68ec734ebf0673278bce2c47e9384a13f67dc65beb5e7d57851bc5311066fc87dd5c94d7ab0fea47cf054097747f2955796df9c0684e74dea2d083beafad93d8f67a1e8d0822390f587842d39e200ceec14321e7d1bb0b80530b76597f01e7d8c861af00c95b6fac2aa1bbea29bf5ea9484fb523e2a490993fc5e5d5068d93074ddcf675b7b5ebb6b407368b01cda21fdd5f9b254b2d56ade805e2fdfe5d5971e54a12b8d080e68668a5614c6c8641900ee6c762dc527dcca64daff4c3dcf73a2346ecfecf21df1d6931cc9950acbfe5721cf2fe3880b75f4daeb2ec0d6d403dce09b306beaa9bb49bba334b666274655f6cbe7f46ddbcf1636ebd3c71f3ecacdbefb1423d9d6444925d6fec76a208eff68800a595747451b22b6c7d93b13e0aa5257cc3d80916ee0f9523b62cfdf3ffda525c2a90fd6453d05babeaaba6cd3329f3806d4c5eed4a1b5b4ae77b49f478ac8a29a63cb5e2c5340b079294d6debb2a8a5e83538a64a5ae4e76bee846e1d1de9bf9e19f5555a4fe8480dae42816ce8444b180dd85b72cf4c33a4fcdad2601039921c26f41fafeec2ac74407eeedac6bda9a0642823927ace680f16bab7fa3ad7de6471aa152c252eae02688208b05a5e0405a2fa82b02e6845d72f316fbb72e1a3700aea59d51bac2c4ebf72505577b06072d07ab8f5d067634aa6040dc51ff3522628176af45acce83c3e9ac245e5a481aa1396fd6865ff8256dee37f0f62850b4492118c2a72ba2c15e8d264ab77c54585c93608580aac2f14d4997a95983bea007e43a1a8b921010daf07133f4a993deaf3d19f3db42115dabdccde72c96cb7393f5731a1d6037d86fb4846cd8fc015fb550e521485f5dc53c55e1e14ea0f3a2f22fac9b4f0a73990d644f63acb7dd62a7a155ff716f7cfad1a0cac6bf2fbf287af9f09ac23405bcde89731204ad18126d8403fafc7a270f5b882e8b1d9f10b51d81a182434eb48fd34a034c88c01f119810fef6ef8bc5f588602d74d44368404212c3b2959c749ef9bf59fdcf3ad9949461d2319fc318bf812d39dc94c9cce3e32b4dbca7b6e1c125b742d682d8b16a974d01c2c32b11da779b24a3f72732d929f1c4534a1819bc54e784b355b32f3d1ebf0141207b50ec9189f87fc79710f66cca940337e1d5ee86e3cbada6bdace4da010ff3a4c05ce28d0d8343aa5bf7b96c2461bbbc1a1502dcc1f813d472c0332a5761403607db25acce2452f01f0e312e0642b360bee70df20c9374fc0063583e8b14cc4240d51d52807d087967d68777f569da612408f8d8b14232cd0e5d61fc7246c182fa3dd506de4fe42852d0707818f7c439515f46fb7416f399178cbbc2f41a829ec558e959cd555b514cc5a30c5d9eea250338c79d59fe0524f2f09673e7e09d951460b42843f23bf97da1880a104ba86ebcb768c8710a568d9b157cb7794b5b3bf1010393227ce0830d8e6f8a11dfe83019c0ad63a1ae60eac7c3032b73169c4c91193378bb9706877f10ddb32782be800be761582ed7069d0fbb4e7e03efaf1abb18b8203dd96368ce546c44948d8fde76402d4b92b917b061cc9981afcf7451dc6cf6f9bf3e97d9c548f19913c8e92b87b32e9fdfc1327977273302c39b2f685f30e1d33af49773c9aef02158bb2c1f6fe4af0d562cecfcd79a5e3e2ed9d6caa08ee6be08249de9d709ba5dd5115f132b86d2493d4f15d01b7332847b43f7c907e95c6a012c1dceda338e4592bd479736a2b52c02d1eba2ba3aa277e7bdbaeb08a539e4c2cdbf2a13985f1132683338a40a8aea486e3f9bc3fa6f0e9be1dd596a93024e5d9cc4dd7d8213d7b19045f1ee6727f2024bc8629fdece918a0b59cd090ad6c7ab31511bd800d4da84c37bb7ddde6c31e8ebadda88ee38a7341f6e3a1a9ea8f9b3efd21ab4a295e9a95263c6248a4f44ff40fcbcfd17a4f77ac0a0845d425053557d6766114a7184189bb625993ec0e5b531836d8673d4a7931274766f6181afe7d4bc48b7e97f71f2d08f07956656b0fd56579293048fbde7640249f46ebad5683ff7c58c1d6cdbfdf044a77e1c00e4da414d01b191127ca5e3a659d0732e33b784fedd93ba72152951d27deac8b13ac2da46963d7b8ab12e301749859d79beb6be28341212d6d0e66c99d4d6fc2947d7d9f30bc2e86a01c1fc755bfaa447f184ab7f81393ee549528aa62902c42bed066f794a6e1335e049ee186b2a91a87b20b929b0532a320979a1ae4c942b3da2f200bc11d2f29ffa1c391a54ad7280f4efeac5b946285d0d0ee65c38e1e80f02ef894b4f7072889cff4175f772851daafac15347c998fb22fb3d6f49c4755394e068dccdd59581f66268c48a017d4585ae33dd0871dc6e091b1dc740a3cf748621951507ed80a36ca2a64ce9f9f2813a0014f6700c78465b5be0e2579c4337fce61f6cb6e8e926e54c6d91cfd973fbc6b41b88cb5091795f91cab8fb85b4f8465c5136456af5eda745a16c29d97858f838dd02963925858c4fa063c33316561d22642775944f7f20426cca1233d099ab6cf2a15e8d2d6a3e5f90f59927abb69e5c667a898a08954774e8ac3b8b6b3cf195e95b06862b34b95c28b6cb40b50b76a9a716af25fde7d4c41ba15c4806e9aed79930518498cb3355c829fb677a514b9bde7e86c6f81a899a5d09054b59a9960c05af359df82b86f4724b9d098f6c2399b9034af83a438d0b4b9084a51a9afc7966c65b564650607a1be84e1b962e9e10bcee91b60b0dbb97129ea0035303774697faf759a0b49ce594c8bb4703e60158559870e769cf5ca91f59bf64cc71d17b1731894ad0957dae8bf2fe9845955ed4ddcc5c62b2c63ab5b4b344adbff6ba6dc4fe7ac9e3ca99a1c6f58533d5285ec4e06a02f992d7140d5d2df65ed6a28d0ce765abb5ff7a902020fbe86a3227b00de597507bff92672f1252f8002501dd071ca96a16151c501d123f8ff343ec62e641e9e0c511d0d15f37144f2fdfd430c00fa2c88dc874d27f4486ff97a3697dd80d6684bccde138c0fbd4671b499c5e69e6d68e900e224a3a0750924b40761f404589603f90813710605a7f14744299dd4c802e46e4f0f5a298bf7b0871ad024c44163ee6966bedc9195bee31d82b7c4b5f5140185d47579a933ca7795a5a9cddd8a92cc7aa9e5d1eae7ed1455598bec22c1e9c81508ab9dc242f0d55e971c10e9748ae1472e5315def17cb194242a2e893cd806a8e0d800e5a7e86a871b4af7c699e0e442630cd9bd034da72ec79d00b841ac1216ba94030680809ea40de40d492af134fc1a6f381ffa90360408cbdcfb02e9e772dd1a1e20925fedb184a251f34f011125c95654caebf3d1f3785fcd5b9d4caccdd33f37fe79a00a49e2a7222b973d8d30c675786711a548a6357a3292a1220ef53dc22f47216cbba8d0f81887e16e1d26d9e57fd4e90d592f6c088d04571abd4a44ac9aa357b88f2b8b9a79598099f41651207fc61e041325dfc723088e0b64e280826b5499b362344a26059c549638a362e81054ecfc4e16ef312fbc87fab7f8dd718e7ff99dd536aafd13b0ef267fbd7a487ac4f13f2179746005786db6fd065926ad28218d56f0cfbd567c4022c8e40bdfe4226dd810797094606d1bfa0ce4f59f9e058d88e6a9be447e9d01b9589b1780b3b56a6c21546f530a43b6de3f0b89f1a2ca7cd9321f398b1f6794f562d4b89541f18a4aaa83a3d6550c352691195086b3e0af84b9f7c27c6699dceb6bdd3fc9fac7169b7865c59107678b3febc1664e36ce5d03001ac9a96e2df826c77e18ec248f2e1eab93360de3226e08e71b5a8230f26212aa084ed2b12045ad16909a6bdb4c2e43b88caacfdcc24559fa421d0056b0f43d5511d1b0e510e4f65e5e32cf9d3e418e53ac2f01731ff1970ab6bc428a4012af45185b008b359bf2fb5c84d8f7bea5505848980e9f6001ddfac3b0a9c1435b09b951e3bc2ee43f0a54b52b3279c26c570655254b326cfb1978ea13b0f8740c99400a72d034590af90e1ac53fcc3d3a157381e3bcb84dbc480c32e695aa0f8eafc8671a0db58401e7975d2b4bdeae58d43910ce5935ed3664f9ecaeeef27160b5dd0c3902fe78fcc3716cddcaea46d4337ffc4064d4ada59600a80045267bf3b1b14adb5d194aa6e4f9f97e7e893a69af35a9672bfbe34f8576ce34a6ed19bebb0d527305a12165cb570833084cd4d92b350d79cd3635469239e8d26c106655583d09802c3be2b00af622139fb9bf49610408320996aba4a3a7db3530906e273c47255546fd6a08a7caa1f444f98ba7b2b2fa91917f7d9675c9c3fe4c89e49e5d4d9c36043398168ceefce7494feca3fc004f3c34c77980230b6990882edab4839df2fbfe50ccf16e004272a2549b220526bb4c38fe4a99980b96a909da4b9c245f0ae898000a7e95f70855e15fa032c476ec32c642f4eceac634e8173a03120caee0fce20fb997762a1eee56541b93e233c6776139003eb857e9a764961cb1d86b38093ee8b0261fd081ab52d8f93cdb8e0a151f65cb9705b6150dc2c9b8fd1afc7bc5fadd497caa518b7ec629976ce5d18c0fb3f7ffcc7e8d7db826b9217af76e82dbef9cfa5226750bd779ffb6e8dc8dfda5d03c1ea2d489bbab6e298d6f22789ea6109e70625f03ec0bcf11da413d269a181279ec987e22f20d247d3f46e93dee50ef3df2c7444d3e23b2e5a15805843df9e26af7301a7f0b6f072161e393e0c4d1e4cd7df5a680dd6ca750043a666a22982645defc7e9ba3ecb01bb167cedaf6d78a0ef7e573ea6a9b9912eb4b40fe9fccbccd8e25b96b082cca37d77819e0df4cce8d6d1be21a263bac0ed6dd5393613ef47d382b46b73b00b9c6d2659414ac620ee7595efab45ed3820ba5e2528362fe4552260921c4eb027665f98b7c5a0b48f7523c46b1ff1a6e9df091fb08a705620b738da8fbf634565fdd547f13bfef358d2c1a65d4090f2d3e013906e509d299ede88189419ac38764c6f283deea0ff5c5b0f5f338799b5d299a70cd94b5fbe90d762d4d62a6a268326a8bfcae3d8643170ebfd76c59fc4ba3ea570ba78df5401ab85e1fc255399470465bb780dea8360d1f6d0db1985ace411a86bfbfa77dd29c3100ddd524fcef9593e7559efb5913d0ece3e61308eb67131068bf47a4baec84181f572be9370f43924e4bc6c1d86154399c122ccd91a96d4ddcbfd64abb2d61934427524c084fceb90f135ced29361a0affa2489de56628b9d795bc14807f7f8339e63c19a350ede16af57c6e8b110f4f5fd52f1e9913651dc053baddf20dd79b31f1c05738f1f9af014f2643caf365471be3603a60d05630b00d9acb4da0c3ec3b09604599559fd8ba466e81c0c253efd548f9190afb749fbce4dbe33da585ac8b453e05d8793a394634bf3a80d6492058a6cd223525c938e9898888496ca1527de2ee2f13d6ad044063a7925bcf69a1d41ef8421a0f6534b21f608c2490f33f6a1c8a47c0988d67a7b5b4501a107a9df8e88655baa7b3576570ee462df472cad875c3932349f43407c17368764cf24dc86f55624cf08b8afa8a7fdff986d5059db289a1cfdce0be06a1735436c8c99f2d7e16169faf86700d4cf9a42622b08a567215fbedbc0799d6cbb1eb9d4a3eb0df318a1777251814e27c58c6f46643905cf015910c31f957061ca1442fa220f24995eef63a3ce508ecac5c12ce08ffe00e8dd58a4d406ea82882b27f5e58f43a519af816de82d1953b0baac910f8e34f62c7630860443214f72369033ee33492671ef4481b4c738fe5206cc51afc51aa0b53edbe1242d17b7d24a465436a8a257a99154be48071033cf0a2fadc2a0ae94d0a21f323f0104a13d2af692898e3fbd27c50ec9d66eb435b11af800c89e7032dd5e5d7a776ff1423fc0a5cd2f37951381fbad4befb76f602351437b8f9d7489f8e838c6b0c54d2e21a24f11e7605daca1b8cdeabc05a9e05a32118f971a3f79f1daba15d05e195ce9e2669a5f6149c380161e32198c8b825a555109cfe45e25d7bbd4cdf046963f6dfa39663ff64b7401c313c06441e08a473f97da11e53e23cf01f0dd1e2b4572f4a2431b1578372872b2f6a9c09384b7caa8a9dbeca0267d497591dd6180fad8fd862ff66b4b98f79c082fa125fc14cc18e54bcd9c7b6cdf2fd3ff02f41f1d22838c65c3a2bcc05576a1fb8fe28d035b02fa270ad20985e72f28dd31e77771c4b4cdb59683594a6b42abd695ba2b0794b43f2efffe60896f1b8753cdb0e2eb7f266119dc75545c2e321950a701b6adf8548fcba4a9fefc1811c17bd95e23b141ba827a85b9b6dcef6b549d040edad5f588bbcb90dc62b9a107a9d875fc706abe22d5ceb9e28048e701d9509c83e1e6ac6310f7562d68aaf39a6ae57e09cd9986ec79f7fd919b74f4e253f76e619aa10156f54064856710f12bee747bb3f4eb3a48f5b11978b00fcb70c73dbb84eafa05c5cf2cbe67fc3eebc4961caa4a2b79e12285dde75dfe83af191067527caa484da96ac0a94ec64b9e2d055149004cc9b12490d1eb43a39ad9a937b9cf03f450ce506b9cfbe1863125728c4dbab3d8423869b6a833c45ab1ec23e4282556dca29d4e4c8b12d9e93e91a77f20a2098c05de38aeac725d153a74182d7fae86ed6696bd6286569e8e3c73357c62c2a23d3adde6fcdec29b2aa5257cb4ef78a66f77d1bd613581f64dc8024a474d74c7711ea7f9bd8ddd1ce203877e69926e2f0d9a13b523c9761844d3b059177978330bd3a8335e5152311a00ef30dda24d2264e30f705d83b026082bcbeace05888c592791b7a72012c1ae6abc7f81eaad1f4b5a80223e5066456e6f65d3250a3e83d780c410935ee212699da3398b99081f64d7bad96642fd4c11ee2d785bf1d68110ec45d30a9837a45dedb61c3cccdb7672ee21a802089781a6699e0215eefccd34ab9d981299a7639d25874772fb50caf6065467e6c0f4900b01fea2559245a35ae750fb58025f53be413c26ebd26fc4cebb83bbc32ac3488e7e05aeccf003c659da5928ed3e44c0993823b7257b2b135f9cabc0c472930f75c6ec862c0f6e69280ca93c2aacc0f489fe55d96d1ed65944ea29eb461064caa83656ac6af7176a8df103b6c76e17f0734c609e2af516927c7e4c43c329bf2b4d3d6b8843f0aa575cd40a73d0d408634c6efc44f9344b34f70a10010761ac23dd6956fca40012b11524e64ade1c2bf842f69834b80674cd597cb071039197d5a12ed3a0e40b6a50c1d8721200f8e266d1793457066a5d4443cc8d18c76fe8a682d8c741d27cd8d7d69210ccd8d136ab3d23848be956cf7558e72d882a190880130df3c5d20bdba2744517bf094b1599a8623cbf4a20f3df36f3167661f813c200dc973c504c4ba0450d395c683ae323a26eebb6f1afe85b845c66ac0fd326534505813011a5515d266df9625ff1ec63ed0f4e0a78c9973449de29e863241375ac1931fc0e13bcd03dddfa133cf2e4be6b5b000bf1cc9622858b589b2c68c5233606b8cd5b9145daae3e7c6c568c9a7de028b2ed027441350170e7f598b19dd3b4c2b7df8e387a8675e50d0a20e1d7feb9d37746c41496cb73bbd487da917d3a36682cecd7a5f838a333da4e1f62f6d7b063b3965cc90be9a957e3466044b8c961b34e48574f0b89e5dd2739eb4cae318cbb5483fb9b2a27bf1e25a5d77595f34f0da929fd8b92acdf0d32fa3c2156a89045b8785b4cda6d8f0a47eeb74d1fe62708fd17e03dee0be16ee45dd46f38b1a385648c8c98d475a2a6aa5a4807d4f4f663c4ae72c13d164f8088dee928245fbf33aa006209020b5d2aaf764c6f6cc574f8075a08307ceba0e731a2b76d7a8194657024a7a9ec8c80b17c17fa9d91feccbec724c8d01cd5b42537149c7774d50a9623a6f0137aa0d3450a82b83da55959099fa6f782db8a70988796d024e2f464483f8d3e9caa9cacdfb61de9de227e1db76dc0d488e2fe890ffea139240773a80685405c93a6971c09bf2d2bd73a846af379c4fa7082737caa41c6e2d4ac91ffbb545d3d6bff6cfaee2eebf7817ac996d35bee15232cc53f8a05ab5a73f0ad454063bc612577392722672bf9853d5f5272f0f791a21737228f3118fd4d8862503f3938d0a0e632ad2ab62c4610ed76eec2085e18fac4ff0936e5113d0e6808bda7e67a3f123d205b13fe4190463a1a1130f4632056e12a2054f3c3a7eab7716f22b57878402923152a9462e4e913faf33585ccd298bbc867ffdf24e27d84008da1e7a61370ed2e8fa389365f62f7f568bb619ee8b0dad259a52b3102c7ba6861662dce0e4425ac13fe362035ee08077014cee9dcb783d318f21a25c7ed02fdf71b03cc4c664e0aa371453ba0a2400319de35fcc565df8f98dd8511983dbf502fa70b5514628517ad3ed19f8ba1244ed70dba2ede192d29dd8819ac3931215f4148b372404e42e9d79d21d67f798b90df477dc73ca9628d567f466f9022f8d6cd8f6a4a890b1c17a0b3e7c84fdf8a52dfdeb5bdfcd8573f8b673ea2951711bd72553a1586e294b10c888a26c32ca1b5031dbb5bb016643d0281afb32a14f00bf2defcd4bbbbd0bff2f3176bc87323cee9d58ae7ac1c72cf16259cc8eee6f0cf044335edf7987efa0427e080ae8415637c638a01ad72a2f3ece6ef792a342f011b8eef1c49b131c8065e265c50e898bc097903a6441036cf6ea8b632a17a7379c598225973e35311bc88bb0dca0ff8def32d916071d6a41cdef240c3b5f84831cde7deeb5e36781224777fa06f0566c110b247f073a3104c67ec2036780675f8789bb7667f5b3848d63ca59c08999724cf260ad0346c2697fd54c1f66962f0bfe5dbf1a2d779f6b63d174238c306ed55739b69d05b2417da8f82db61d08acce7d658073d8cc69ec9e8b0b45d3bdbd346d1e01b8c631812fdb9b1d8475408a6efa8ab2135d3d3dec2a4e68226c7c73cc615e9cbf2cf8a16416a1c074a529714c4be7b3115ffb17edc7092c41ad806fcdd3e6a5d61dd1ebad6a11545e039a24d2992e2e897aa27007d622df10bc9658c04a14f8d5e2f8fa5ae36bc13bf31a7e092d4f34e040d71fea665bfe584906bf44b462d5f57584a55589fee08aeddce6557d04bb207aff748f0b212c03553d115d487dfd91c10ae349a74b384a1d0826be04ec3ac5e20b6a77d86fc10320470c10303032c8de16297a37dc22d68aed88fefa8141111402cc92691ae4a26fd10ddb468ec0e7fba7ac4b59a4c4167332107ad1bef997530bc0a4bc92278ce14286baa98de0b4a901183d841d3fd66878f55c7993f81e4f555242bd3d054ff0fb840d692ea38111db2b83cb53bdc8588ac0e266429fd47564a065ddf202943c000af98f518c7ffce0b7c0431e78597332292b602a9671c6bfe892104655a80882fac9215fc63b454403189422c22f35d9acbfc56a7835395ad23d73db583b26893b5b802ae67b4bccfca30f727af5e0d036bbdf2a33290fabc506f2231ad888c8c089ca14c381ac6158e39df547fc78407328692495cdee8a37c923ab0b851d704cf029bd9153001211989b8e7b6c849136bccf5c8ae620f4ab41db0f79b5941882ac55e78e19aa2fd874e82c5f79c90119c9e19024b912757a73d494b9d3bfa0b7b8d891178c0cfc48abb0695df619915bb2a65379337d8287ceeda7da7feddd33a099c22cadc86a317ffa3cc32971647d3c4c6d713d9fde04e6330ce267d4a4ae7012ceb6e718b089d19189037c0af9bf54f35eb870774b961227b622664491aa356626cc8f0e59ea905f43c4e0dc346fc47dc6e74392031a04349aae4e0a493f5857b7045fd34b5c99787ccbfe8539509cd512e5876882aa96f4819d3d7a0e6aed3bfaf82f178b6152b936ac89e6d208e8ca7fcf629cd3468b67113a43abf3e0a66636bba6d3426105bdb0ee10ce8afca2a499c8544381c896d40ad40a7bf093a96b8b109d57a3c9775ad43786a211542a1a10889012d30e7bfc5400179dc5514f0b45e3a714b92c053678300137576a7e6fa0642b9c70e6748bce40ecacc32bea090d6cecbced9b0970b6a70ec2a9f28f46cfb4f33a01c56f863ff253180d8149be59cd8b63063431eb079646733092abcae2e35e58669f45b425cd712f1ff89c5177c6f4700ac3045ae6fb846e754d23ce9559e0f26ae03cdaacf026e6246ff24b4652821c83e80fa6f5a4ac07fdac68fe80c61698684f56d73fe0dada02e35bace7ebc45bf72c9de062f6677ef1bdee211b0f464f878e1be56807e9fd53d630975fe66ee11fc64b9d1e4a4ec6684aa46e399756b30588fa56fa33a67190d17828b2e6ef124fa850f959bad4ef4a5e986af3d0c61ef19b4290b211d56e614a0ee208f1afc0829e8804975696bb79c3baa3ed592285348214b9e83b1026644ef7736ed7587780e5bbded2a5c0dd7c12ac21506e0b4881201257adf3055931ab0aef7d61f95d438e34f82ec84029d5a9115a77beb10fe247bb6594def80025eb4b1aa63817842e5e92b2eb95a4a83993ffb84687e0b930849e233e168c9b20363d35cba1826d0745b705057e7bbc84f90225b65e6d96135bb1c4a9efd232eb4f0e68fad0ddf9030549b3fc6f11d42fceb846ad3a2d4a98c1c155d5ada1542c0bd43981210206f24b725ece4339321b874cf8b8593b79e9e71f4cd7cee88252f8e2cc60745885d9e3ef02c957b9a35a284ae7764b575854f1a32974b2c00078b819badbeced179217d5c2c0664e931220524ed3285eafde2e2a24c339da89fc9acb2cbbd9cd7fe42ee1cb47183bf1958fecc63559825233e868a7b7d28d0bccf23153fec9fbceb3919e0cef220c03902c9225210595aaba489dca2ad201d01ac94bab397b72009a33e933166b8599afff8f18f86cb98f4bdf48a9505ca609713618e96d5aeafcf1302b14b932760d5a435f9a85b62961802337cefabb454bd2228674326b98b2a72fc91707abecd64f7b28fe1b23c3f417ef7946aef00ec1c6569ca054bb4be54ff7fca0a3fcfb681ac2b457dbaeda5e97265a72b749afde4f46266349c0d00269ca510caa39a5946d902022da7b0102efa61b8653be5b1ae163a0e6e65daa215addd8cb43f59a61b928d3d2800f4d55dafab8902cb14f598ccb9fc8c170b2b407766fa800486c3826c32ec04d9088bc84d4c6c9d49018bd61fc112028bed1cc33f32585ecfa6108f05bbc2bef21b4f73da27700ce49ec1b62dd271bca43969d7e1224b913adbb2b306c7d4417aea98e046cc60b426206c852b4d3ef34fe866efa968da568444c7ba88aa64e3b5e65401046394c0ebe536215b928eaaa4342cec77940dd4463d18f4daf710ea0412d63220d72b97756830d8d88582b354417fbcd44896352c998641fea62ed25949c6d41c1d956bb6053ee31ba2740a46488c22448d0a5014aaa473cdb7647d4684409a7a28a20e587a4a63674256fbb2ed464de10f02a4cf32359210b84f29e04d4aad8d1f8c4ecabe0ea8bb279fb7ad81fb205445e420fc3494949369af044f12c0af778a86de83751ac5fc159108a555246493d91d4b28eab8f54af901de4ef81c2db41919976b07822f6ef839a0c91062c9a47aa5bfddaff23fe7b24eaad890c134665a226766acabf5a1e34510cc681f2ee5fab97d43f370d755d80d7390a377f79df765af1f4f9a4b01be0a8eac4c85a89c7947ffc19339d9672b0bd8662c951b561be8c036cd468c4b5c849279b885f4c44bc49fb93cf5523ad64cc8cd5a3f1642d25a464921b17c08364e832e92f07fb88b0fe020e9abb6af0c14e211f29e8cdff93e279dcdbd4199dcc559e6e79b6053537352be8eff5d99b6b20d1f0c7f269d8758c5208278cf04f36c161913551960d03e4f8ca30b370346e201b6638cb9c3ab479b2ade6f18333b700cd4ea46e34b244ff407e72665ddc848e182d5b79a161e2042d216dc0f2553736bdbc3c434d074e325720a23cb476662733579e37438427f0d93dd237fa9c7df3d240d5bbdaa517e35d508d6f89903784e1168538229a60589ecb0f278dcc99fbb1a4a971c7a22f1038c249826f6c3e4641a9b235c03e2e3d9ba70afd6158bef89ae4b019699a60219efc850846ee6561ab44ce55bf0c07dbc9acbc18a7075087a3aeded640541c66bccd2682ab6609b9f633cddb4dbf73c3113f58ea94a350190c37c4d3d0436cfbb6fd22e7aa4cc364a6ce300708e9c5e527b1c5dfa2befdf4b932dc5834252673867d535dda28ff168195f9a655b7ada26f7f11af05f565aa6c19de7507204672729402d68a9f612583f09692901e3dee0e00fbaab0a118c96c6cb9350c02d158a6595b385a8a99ce314d12e31d69852c49c0b0831a6f5db6b173b3b5c2049861db873ab59dfda7c079fe47c3ef20c6e9f1fd00c57587a9c8ba0222e813c3e0ad771c98c2cc5bd6d585fe2b9d09d5430651f5d0c09e5d602087485de4a7389865532628e5990c95404d4544cbf05c4010e3e42ddef76cd9cec587909351ac0616f1ebd97c27c59290a1408e02eb73546c0c7ec9452327e6f663c2721df76ac3ea8223a20e9cde90bf78553ce4e9954c4cefbde35b2c2cacdc2fe0c59312ed784f3cb4c0c1c56ffd8fd5f53a0c74c24e391246bf29ac6f011253dee128f2aeb065b0bdaa8d682c93edc28e67c0899023043200bcfb2aa346600bf60aca22bbb3b26f0c52ada2d9aa2a62347d428c564a0d42c85db45d4c1948837b8ca0d6795109aefbbb46e4a6299e7ba8d2ae0b98af9bee2f6c40ea14ad17041f7aa59158cd0ff800909f7115dafa474db1ec8c3edf0b331291af718807b2ff2434c8ba234fff582486037012e940ac7ec11b7526a7a343026db2defb3e3c41235ac7c3c871b53003bb3302f7a70f760813307ff9bb2132dc668ffe22bd627362caaddeb5606eb1bee5457279951c3fc8bd25060f946bdb76e0007f34d932a6110a7e900a3cc8a617d3c9f880c588ca1b7ab3c592d06bf3075586f083394d803881a48ea3441fec51786a863750e1211b4dd1d8185e16090b5b335b0ee1ec7e9dc82905f6d856d68031284bfa42ac9d81a2eab91daacfdca68cf3e99a1705d8cfe7b174701ab7c50a7eb2d822792dba3b881ccb99ed0c1ac922eb8dc52607a1f211235a6c66a5291680600fb5e1461b15dd47ee767e6c5be0f5f07e006d8c7381a8b75855db0baf553f6d06b83596d50ff8030ac61084d9d20a39bbd10e84c083903232e1a9798c73ddecdf0e6f964a95e3f63ac1a057d691f82173fea9219df09aab89131b67f6ad6ec76629ac46e022c3cec66e238e99a7803a739e26d23ff650ef48e5a6f2a1c298f2d27f3699d8f2b6616f712c1ee6754b1b7d974fd121675584f425ceabda97166afe0a926a76240cdbd4e2bb9d50e6fe442c4753a442e8a8320e45cef686c76b670fa4ab0bb22ecc24da818ac468df608ff6c2325b3a0213f6b0b5d9104e3030d7627906ece6fd931d2da850f86f86b8dfd7135681f4be0c6a4df4b1d579a4f98090c731fb3be1330ca9dcf9157ec32b25dacc4fca90b5f26a7bfa4d3a09c5fb3091968c3262124d8eb169f74ff8bb4ea64f6c8c365d9511967e6c4d1d7b2e70c3ee073e61d7527300716503ded61d939b8abd3bb06dcff84a2742d2bc44e34329644f457f342460de437ea41dc9554c02c14e00ae52316854544fdc7164d7663bf6daa49bb0017a42a6254f6db860b33b19dd2f32cbc9eb2f148a63b934592726a2297beaee0533ebe3ef29430571bdf149c218a5c4151bb9ebb4f32ede9603ce73d2868c8abf58ee6f42f2febfebba87971b88758a4d4cfa07ccd77055a8feed4b867f98790efcbc9513bf85b3407be4c628ab7898ac0c0b0b0099c20114f2a0835e462d2943846fcc08b74de7cb2df3faec7ae9f2eb9225f5955ae16142972d904d5a95c219c71de58cb156e9f377d565b5f26c778951cf180b9508378a9bd3168f126652546493dca278f90a9a299909c58baf04ba9ed9009fc8a47267687ebd19ff05de85ca3d5697782739b63eac61ef43860da3ce45ec61ea32023361dbdaa4da9da1407759f50dae8d7d07230e75797ffe8b3b2f9af4b80c6c216a21bf6e8785820e1d9091f0c09fd407a8c20ef96245dfbe93c410ec81c7bac275a8f4b128f7e3d36d854cb3a9f054ecff9bf3e2770d5fb8a17bf5bb041a1120ca1e670521b87445933fda3b5c9f51a07ccd75f12052912734260f61f3d0ab7d04d0cf52c625d58fbec42c05a7a339f74e14bb4623ccb9f60fc1345863682d231efe62e5a695d52c7176d18ede3067919153d6beaae70519c3493a279de2fc07882e5f69795ddb875165de5f15a9d88614f7c58b7864417613df327f3e11d99cf89c237950f55c5cc2a3c1344b4984a964cd27fb37608a42ebf9a9a8d39de9c1d6b9e636247d695956987f305696d51b75b63088d92ddd33af451e22ac0ea41f7b0027b1741a9aa780e037ab7e7f5add22dd458147dd7c924f986f54d18f422490a62e114cdee2342a52352f2cc93f6cd4e685d84de35f862438fbf8e3db3ddafc59af5781f7faecbe2dc4d9ad8188a3f01e5e12ae64cdbc32a8e7f491a824f715a3b6744632f3c370b93db913be831ff190c5dc361251e1e1951c1c0bd6132404eba6cceff27ac073b27d5d3ed270290307f5b688ebb86c79ddd07682691fecff9a88a90715ac7d726aa31a9d2c71dbd12c8f441b156478903b615af34652fd0bb7c23fc6be8a9765b835ed58ab63cbd30bc5ec41672b5e264006523a6375ae9d8a01496b75a99a18eb874240d6f66faedfa7bc64a6915ce41495101fe59094f403280321434211a64a9123d953718a46d7cc20aa17b00205d7858d96d226a4456264012ec2415f8a254d7e7af2c62ad8ee92d45d139c9e2f78185a42af3459481fabeeaea60c29268a96d687974f9ec0a9f51bd0cb35ffe08d5a8e8e1a6659b4ef154a261a09cf5f810b4c73e7216cdbbe89406e0526fff4246b2e17644021370d4e4d9e789ef8cd6ee4c7eb52c1cd61492a8d6d370e3dabf26220d8f3becd41862de6e1a958e8427e4bd4aed9126cf60f547a4922475a9106bc0fb73b53a51264eb3c55e8b680170df966f1e376c3418974f7e5f99d60b7ad0968d24dd784416e376a6d4aa9ae52fee841a759abe571ee379ca00d9ae78ad67de54b43808bd35d3926aa607ab3f7bc6be5370767b487857122343f6445cbf8f81eab947293b1165b709a0ad96c52045d4893c54942177788536e8e5d57a0cb08c71c6a827dd0b82d727b3864bad4218dc2765495b8d90a550ae5467faed87229128f1d698e68fe40294a5e1a0408afa65ffbad84808cbe4553b3d546d835c1aae904cdd5a773352c6f08f457315d79b89525e68a9b1343e67016f4c2c512f41f4f67cd666609636de24d4518b497fe8942b6a1dd168b37d0bb29eef8b99d9965d692894a473dac11dc7f462a98a456bf979ddbf5815b6d1bd1a3657d59bcc6027601ea967e987953ec3bc827b5fd406f3b6263ad39993b236cf9e4033faedfb216078b36e6db657803458325e9c4709422b246a6bb91bc3b3f889395be74ded303e990f40a6118408e1e60762a819695c9960d4a3cfbb6357c5785ffa708599b63a8bc511cda56046028818ec5eeee2743a51b77ecef1ea0c8158bd07ac58d45df2e5e5483bbff5a0845d15853d2e197f4cb4d33b9ea6178d9ba6f7a76473da835b65f538daac4c04b3868704008854f1a52b88cfc9e00e3a0d2ad8470fa349fe5d5559a653ad3ce8e52382bf83dd5360c1eae44bbd7ffc9a3cc035c8310c8c522e0980fb0358e0ebccdcf1b74780a6111adeaaec6bb1d9980369468c18007000b573706de66e31ea211ed2b10fb89645156daf35f6b04a2858a3bcc51f7dccdb7d20d166dbf1b511847c3221b30154d28b3773fdee814d0e5060841eb321421b05af81391d8dc6b2d4909fad555520749a56692cd9cc0338363482db204880ce14800a67f1e2ce8395133ecf1d20d2d0c017c799bda213bcc67b5d5a3a4476b8f335cb064c355a826c4764d326707787d254f639f20c18913745d08242fe70440c47a78b97f344de968c027aac27fc38a6e07b4e3d9ddbfd326a3990bc8188e333868678f2a5722cdb1e0f4143ed040afdc44bc4d186d784eea91eddcc61858c4915e06676f5791aae100cb021b7f861aaeacdd68b97e1dd90f5c086504962a548aa8fe8c584cfa247afb1a17cf29ff1ba021b34182f4d93af571d9fa4728f4affe25df83f20b843e8d746c02933a5b8e7893fae587499f4b183e724ed462e2af6d9bbc5a86e0b4f2dfb7a567eeb1cbff70142ab26b5839d1bb790c361d0dd251727f4fb71b412bd0baeeb1e4b5af3dfd104437fa5a79473fb36dc9413d42a5a9fc4e2c28e5dffefb4c024118845fd6f03c0337745516c84f1ab07864b1179da662a7815557ef6d368ae3926b965348579be0472d9565787d6da84c8dd63630ba56f10613779d7de90b05c893a9e51152adf92f1c9ce5137fd8ce871b177fd92655f3338c840e2a441a9145df2666d10da8b95cd1f305fc3e48a199533313635a3606a4b7f686b4722ae1dafb7f4d0c0e9cbc55e6e39d1bf5cdc5d70d18e7ee3bc081e90d9bc421a8e38f3b5178e7c8af97e96e5bf1b4f0cfa91d99997c992f92039a81d22e45095072d99ea2b133228e513dcc1c7eb972d8b6c983aaa4f65b122a36d773e19f5698af942f73bd37b214631c3d0008ecc4a58ad68f0f04d2d00860c73ee3e7da2e64397183542a34067ccefd146b9b48c897d774fab5abd9cc34c533229cfc6af00d508d699d59552b4b856a51751f4fe79fad8ca5e6d3d936e36cdacaffd8f88891420463ad570190daf7bdc06592cfccf13a61aedd21472a71867784fe2cb8e61c34f21335bfe012c106ac1970984f2b457df97be1cd156e74fe5d47663fca38804cd57a85bebc9deeb56f5fbab1a4f5faa2151d3ffadf5703e14f01f9ccb1eb19d2ed25e8721bfe4c5090b3a3d22d8e7be9e59c77c993c59e36b80216200cfc9b47e1984947eaabcdbf0b9adb07d85153658f8adbd09089d4a4aec74ac666731cec982758518b44c97414671a5bd92861e9c02863e9db5fad58e716c8f33919475e1b34a6c1ca4f1cd029cabe4e4449f2c2c237bf8d74901457905b24bb76d5984271f71687b06242ef8b86f6ccfbf1cac9b386be34790187b1b932e8d3c6081db87742e714f8eae8e91403ffecc5657155b126f5cef0f21ef01f9031632eda67c69c756207eb1e3bb9df6de572b3f501fbe02214aaaa0d825050fa2ed1cd21467e345f10e32ca3d09ca9c3c0c30616cac4bcc080bb7cce10d729cf7e73b475aa302dfe7a05aa01ef2b3e05757098f29e726d99f5eed097fea3fd5fb1ffe4d5c192828933b3c1cdea0f124a6637ae6ac4124509211db5ecef706b0f14876ed98bf710b9179b751105fb774eebdcbefd2c8eff51a3dae06948bde76fd90ca08c96b5260294d2b827d762a54d984f976b9cb1b52bd4db090b8087ed5d7f4c4272015c82f829d77305db7a35c8ee0471278bb3f9e5c42c4ec9faf203742d7b8680b5eae46baee28791581a8217bd7689a68d748c38563f3ff38bde9eec8ee4979df614523d6332b2e451e7d7291877455a444cfd38942c7111149842383dfbca2396b2b7bbb9a70d4385721b053cccb11e2eefdabd41c6c1d8f0ea77a343f3d8054bd58763f5fb5c8fa12d971e7a6f227153656136b979f36787424fd9c9a40c992b167aae18af75a3c7eccc67dc9b4218ad53beb098ea46d4cf1061f0a2a4bdcd001a0c518576106ae527b33be98312a7bac4a13f7016c4e0f101f01883aec8c72744a412db861fa1a5bfc21a69610d1d6d79f33a7d3634296fedd31a7d66079fb78716466607a59e854d216bb589fcc3cf7b8f681d975e555ba64c4bea7e2d67d32a08c8bca108d4318e66c1572d10423059e60d261a30a3dc621f83fb1f1f13a733262e336341b6a423cda4d6a14a49a67f0cf6d60a270256ec58d58009a10ab7576c67a1efa4f1d315ace5c4374d3e7e8a9492baf0bcc99b904ddf0dc594e46bc466edcfe88b97affc0cfe54cb0624010d4b01de919808c84971c023d54e7348ed5ded40c6cacbf2f0646e22b098a71eedc77a45bdd07c76ccc2754e3662c7008b6261c57080cbd7918f68cf2a4e66f45a247e721416fef2f24500609682c72bf454e74fd7cf89b1c878bb0f783b53a2f55224bc8c968985a30d543bfe9aeb4714c185c9e3489331bd38c05d92ef2c089a0a2c807c3b2bb0899471ebfd6b7bd9d87d3b33a911b5eb7081de0d39a71283f4260294e1b0dc96c396b295889cf5434766547c6f2db4436f32c966995ccd7fe3857a775ffb38fa29d9c65e3599e8d3cbcd8d47dd3028d57ae47154e2ee0819fab440557ecaa0d30b35ef194189922fd2a1d62ffb16177f9b7f2d5f90e94989199f3d5efe1ae3b64511ea40a8f967d2f305673f69bae4323d170bfb3c376a0c08b7c85760f80d705b500d80a8ce11c14afbea6e860be0ec4ad062ea1cf16fbd27281bb0f67d961e132defb1a564273fe615feadf137674e234ed6b32000a4a8eaf64d6ec2ca572b5a7a6a998ec2c2401ab5af65b7348843e1fd4beb22d6af899fca76c80603a457ec5d6bf262b01212eb7014cb9fefb232116792e70176f8ed8a386bf618074d4b584e295c38ffe807de27655df083fe1c4fed96d049de5d9c505d1e15157319924c4da6d667d265ff5b6ead9d7d3876772428916ffbc414c057b1d41ab6f14e5b4017c97c21a6e579c78660e89dafe83b427494de06d779aff49ea577981e1901db1257ea58c2961815cadf5ced7e5a5a63608c5010daae7f9c72d85ef8b64e04e550b919b624043bc3019c5fa69e2cf1682028aa3dcbc39a358145affcdb4aa82a7be684ce8c69f55c3c707387e056bb918b3092f400c8b5507e65e2fff470e26989d9a7091c59b48edc46b0d38109695734c85e774935be9a21511ed9776365c146f4730cbd873fbb7ba2d71a649c4b5ad0fabcd24d62c48baa392f1ba5c63298c9b97281bd81e8be043d7564af23feb659e7398b88c7cc06bc46d48c3a437cdfb7bec8cc2dfdac86d2b70ba7b20f07a897136f341df9ee74283ab85fdbaeb1ce5770c4ae24f488c6c11a68ca13883e43d956cb29be39613931a3ad06c50e834f2a48738e2107e580c476ae5795f737726562319641f6bae40fde5aaa29573551183e0828edc8492374ae664e9fff5e8084109299c1c35fc0ecd56ccb170651c29e9f95164091ed75b7d25bb46ab7c8eb974e6521be42b7485c15599452c38510438427176a9d97ad583326c3175a742b8587b119d6e829bb9df17ee8196f0e3d07ad52bbec89024dec7f38bce0ad510a4335e9d178a71211b942a86e8afb8aeb2bb7800ec96b9ab1c3ac4927e9fbda7727d33eaf947b791da7efe687a6adb853153a033c0f5983f6d2c8c9447cf9ff7ad1ad1c12244e79780146a4b4d7a657a3e23a075dfc3842c04fb75a06469065c37e9ac13ad101dd3222acfb65cc797141a668136fb875e04269f7825f3507ed3b4ccedf6faa179ce79ca09f311f928addf2adfddbcbaa5d1e2ac0a3ff20f971132a1dc017ff6fac3de397e3a218b5201799e267173f57d52f3bad7049c7982f85f1e5b38ac6bcb8dd19814e8605bb0f30d858b61471564cf010aea77ba2b44469cce9f6a1510a508e6b54f44e9b3bdf176209f6600e1e3d3bc3eb87990b1bb25a2e67ab6e23eb4fff83364357a25d4312b2e459ec5ac2c1b6b8b6ebd96bdcac47ca434032ff31358303dece28ce19b77ce7ed74007802105e3a0b5bcd2e4618bc091e9c9b99ba493737cf6d39a005d3f8118b5d8439192bb4b41f68d170618bad318106877607d2d148729ead8b9abba4712d7b4b11bf12d0651a9c4c68012e9dc39d4d78acd646ca229d906c65239fbe6705fe1c10d0fb5c148df5e39ce50d0e6ea3d5bf887d7e4a1916975705e7a6f7c5a025bf48584e165db467a0a2b790cc00544f2ba7eed47e07da0c77c17241b66c42baa01b275b7be67bd1feae4a261cf725e923ca6912872b06223d2484b618e9b37324ef82d75337fbe8a58e3298e6e966cd356cfc7efadd6ee19f30277fda7a16ea4b670cfabd4453126398f17899513e609e60892a2959774e9f22670073b6683ca0f6f7c3be95f926461d8c6f105e196293447856e8199e357c02893c29894af9cb03fee7bc6f14422c332666e5e90b1785cb3e740954a60de5f03ad7e7ddbfdfc3374eb97f7e91f755c7f29755525f68fc4c349dea25cf93ff4b83e2bff754121356fe819cca07d72443aaa51224e0e2bf63880aad2f95013c7d01da46fa8977de4ce9ddbeb00bc9365db6de197124d6b1dd6d859e8bd4f0f42b04c7abcc81204473fa6b5a02c294725a2e27989af2aa7383086a86d0f77bf676c25a4052895ec3dc76b4cf6f44edfac5a814fd57eb91611a5489e7ff62f0e0b4cdce62b83fb1b196b4906aaa07d28b369e233a2880347c58a70d8aebaaf76d8738a6bae0036d33786ef7b0f9d55e8d5210980eddb97dc04087cb58f6bb1be0179f25c2998a68d868e73143354eae26f50610b7c96ab825c91c4ed2707c2a9320baafb6cd1c371d79296af3b96fbeecb79902a328bc6ca0974ed34d3504169179c97f7ce84964e0348d94e1dd94e4095fcdb82f688d484c13a3212362336e4be784d29e66c3e31708db60c3e9ff9e5a537b292d03ada3eb0e050a7dd29512fa8e23e036c6f1bf6b7d27f75eb99cc2f5dd7ed0c814ea4dc840eba5f6fe9d253cf3539049c855f8347302c8b1b2166df3258688adea536e1b33b93303731f5c4fb75bdf81d3d32197d8e4161a684a1f79655901dd1bdd3393b5299e7e505a2155ac92498876fcb9e46e19cdef5e5d0bcd09f8fb5a1a5a19b6c528dbc7cbc32a384a27adeb0ca0b0e485298cefea14c8b3be40664e89318c6cd8057525b2115f2eb2a7d121e69d738b59fe6dcac4ae28cf6444c9a8bbaefc0b77d42a4e4545761b1ff90bab682327e9a3dabf1fcd544dd6bb43d90bf35b71489f083c74f31c116e143b03ee5b84e13b318ea69541873795cf22806d3e9824cfeeb51f70b6df6448d798d280058b39a8719250aa124c62efb54ab5b6e8641d323e834635d2abc41afe9f7adaf626c29f3c47a05addcc78790c0acead7120de913bd03a4dbf252dbbc6c9ecd876f9613d4500a8c1268c9f4e808e41b453c006218fd496d9ccdb2613147ec2a0873fc526622e547965ce28aa990fb932ecf681ab8b5def120e629c0811f17fd58871cd83ef182fbcc106fef822a20b232a634febae7cd1b64adbac0875c43486fbb40235eddd6b685a3365e0d9bb42dbbae690b7d08484509beac22d5e67cf0d999dc1cb22b6723ddf7eb1122764bbe5a7a65c23dff832c46ee3cb4a5e81c045f736ca61023c14918f0ff394d09e5a1674337306292df99169a28a9bc7fb55be8b5808d83012a8fddf4836569592fafecc0720d5bb37265ad6e15285fb4f07f61d256d7ab6d25cb917f08485920cd89048bd992c830accc76137a92ad244b8e508e0bdb8138107038d71c570edb905316078c22c53029665afef962b1ee46ae52101a57a13e4c54d695a43029b8b98458372a862886cdec654c9b281875353e6fcf9fe676bb58c92bd1f8db8d6e9ad70626d774976f0a0c86b85a97388842cc4b2a6737efaf9b514b596b7f1028ce462782ba639dffe6b262c308f9329b58ff24bfedb3dde9e749fa025897ff049096e2f04253312be742bc6d3e514e973a9dc8e77df33c2a38db5bfe7e683dd563a83d5a9c2297685030ca26f8855d64495b02337b4648591ec5e0386b29e0896379850a1ca25107c3ed7fa2d5c6568f9b2999f1b51ae4f73b79c1c4781518c535cd9b1fcc535bb3a9dce13bf6a9fce465297a690a8d581668267fba311af1541c98e3a5081310880be1892fdd48b353c104851df258e5d2c4ad6f2bcd4b5f65839912c466acc993b4867bc1e72bc1f9ba171ca28692acd3fe506961e439bc8269a13dcb76b3ca2bd477dcfdc4af9d0d4ea00182e5bf5f66b124fe2f3e08e7c402e7c8608981effd916119ab255d703950445cefcad21c648304cade4b7cc46e31e31710ef73c7598b29e4aaeb453974e2c3b3304f6b0e182712539de096cce94cfefd70b3cfd61a4e66533330ed693216f00b0f05247794d7ac6f00e0474d31ea13458ed4734001b687133b5ad83ba0cc1009ede5b01bc70717b4050e57f4170bcfa7bdc4228add67335978942292875fed2981950e3f327d091200dc9200000\";\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(\"Yetibun\", 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 [\"Baby yeti\", \"Baby yeti\", \"Baby yeti\", \"Baby yeti\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Red woven scarf\", \"Red woven scarf\", \"Red woven scarf\", \"Red woven scarf\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Sunrise rim light\", \"Sunrise rim light\", \"Sunrise rim light\", \"Sunrise rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Snowy peaks\", \"Snowy peaks\", \"Snowy peaks\", \"Snowy peaks\"];\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\":\"Yetibun #', id.toString(),\n            '\",\"description\":\"Yetibun is 3993 Baby yeti guardian with icy blue horns and a red woven scarf on snowy peaks at dawn. 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\":\"Yetibun\",\"description\":\"Yetibun is 3993 Baby yeti guardian with icy blue horns and a red woven scarf on snowy peaks at dawn. 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":"58031447","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T02:54:44Z","match":"exact_match","chainId":"56","address":"0x01Af9B670B7e2B18D5a9a11f1519E600bb838D25"}