{"sources":{"Wuyuhive.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: Wuyuhive.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Wuyuhive - 3000 Speechless bee-robot with honeycomb helmet and blank dot eyes on an orange-magenta gradient for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 3000 free pool lasts (gas only).\n/// Every other mint costs 0.00007 BNB. Max 50 per wallet, 3000 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 Wuyuhive is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 3000;\n    uint256 public constant FREE_SUPPLY = 3000;\n    uint256 public constant FREE_PER_WALLET = 2;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00007 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Wuyuhive\", \"WUYUHIVE\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646fc3f00005745425056503820f03f0000500b019d012a900190013ec158a54ca7a52fa82b76ea49f01809646ee0eba5bed3cafebdd38acf5d3e014729ec152708bfe57efb3813d6530c8e6dfeef9d1fb1f7dfffb5eaf7fa9fa2ff478f379e72bea1ffbe7a50754eef547f6ab5d0e566313aa5148f1bf52fb62ff97dfbf008f73eff180dee75fc7f3ebf78d6f5a0af8d5e95b51c337d07a6af6fde6136e1e981492d36084d6bb2d7a1c6e80999c93648d089c461e330a60c3f5ef546502ac2506b6734e9d69bd455bffe13a5d0c1c3a62b607a4ee74528347d8c66fea99564e4122db1f8c7ff2e319e0a4490d3a62f39dae9c29dbe4206371cffac8b266f7ffff5b06c7eab96532ea56472a617c55a5219a891273027a4a6f4d17af1a71637c3aec03ff8071254342b60fe3bda2f292089f444a5163312e16c43e84856ec59e5fd3fccd8111831e78f06ca724bff18c6bda92ff88e9614d457d280e7aef79253a9b3f2411b14c6e47305518025fb83278bca4a1d552c7e211a799e083b1d1b3d2fd95212e01d02291f4692c66edfe1257b8ddb697151c653eb103051b90afcea9d2fd883020fe18ff717f907a08c31ed2a019debdfe4423c0e1e764369b89fea9a342d4050c456fda5ff852543512e8b1a5367bc4c83fbd84b3c53f1dfafbaab059ead0899d83203201e7f785d7b41e80f4ab2d2f45bb8448cad25854ebf0082925a3ffb4ac95372f40107af82e6bc7312db45209118627914ec354fd3b249aad06d3696e9e8d83c35f83a4e8e2975435aecd256b075a3e2f3e537f7518bdfeb8b19e7ae74d54929b20714bdfd4bb12c310104a83baba7c5aa36374fc25bea05c7d6367e84e2f8705f0c325961dd3571ffd92313130feb9d52cefdecf866023abb0bf48d3d8e17e7ad6e42286c34bb258b8ca0ddb1b741dfedc6a58c3f8857d9d347532955c5bef6f482da372ee1037a27b5d9581fb38336883dae8d3608172883dd46c4217b034e0ba72d5e0e3f3e71dcc9aef2540e8412bac512b841c72bc269b1a9345332e51acd67ca48e6add17ffb3a3551fc7b04b03400eeced3ba0bef9e03ec5d0e0efd3bfcc88b04646ef955d33613234fe9a7524b41a68cc694ddcdce9854335fe71baa271936e6bca20c043cec5767d30985eee03cd55a517d40994e9cb6864b0a346c7ecfc9fa9ecce6902307f9bd8523f28433bc64044d0f20acb52d57462ce3ddd8996ea5b38079831fa4b930361ddbedb37bf770eb1b5c1b8246980bf926c46f35ef0ed2704f1791f25001da4504a6f46b3537c1eb8c17b56feba333c933f62653836f6be2fcc632c34ea33e2e3199b160334078655f792113e39d264d8e8d80a316a78ac80024ed84eb8a16edd4fb2c266b34ca21ec9a40a64e75ed478e173538bdd33534996232359da7d2c0a0eb0f7947c32063778bf53ededa1f28eb6980efc12578e8c9d78df481d21808398e20343793bd69c263c8e4c1d0eb465868fc8e7f863ccad28f97db28fba77891f5c23fd104c6d2bf93831333164c7eec5b2400dd10a79d5144795073ca9ffa343f783d32205312cf20443b9c6fe78cffcf18ac215c9144259a55dc29aba72c6fd331e425a1ab31d198bf117076fc7d9767417e57107cdfb6ec70f9e4f49f37ffa6f61330e96a615f21f239a024d0e8a375b61b980690298792d6c403a064de242cdc9d24d57bd46344395e412b930a7e1b36e158145f9066b69f9d02d46da11e92dfd98d945a1812734830f297aaba33271e676052c0f0ac7053f1cfa4e46f6e54186809050ebdeb69fff789d1b4d8b66c6f1e4fbb666737dcc2a7418211d1fb4ad78d420545fdc5d53b23d60d1c8ae2d4e4375f714c3a9f4ad32a557c9bbb1057086c232a135dba3685e47d8c225b3d18da8ebfddbe1ddaae9f602b239ae8aa43fedc6829b563e41dbfca8c196def8fd62c83af4201f391baea6f68a93d21004ef727520b674f074092155779017fe3919fbb7dac7d1a980ed68dccdf0c24461fe799d58c9bc31d1fa8871a3b532ddde4bd8271ab56b6530287eb1db6734a2e17e3fd9be76977da1158e6bba81c5159c6741f7363dd23def09a03112dac08c5f105309efdaa8c2ae9c4b848dbf746e8600d2f15be7b1713d29fbceefcfcb650ec1cb7dde607fd756dc30c65f7c80fd6eee6a139fbe44387897f1951e82078a5731aa59103aa9b5a6e45ffeda5568c6bf4fd78834b06ce18b5fd07ee344723f3ca0bc1131664e1c28c0d6b8f1736d5b5fca6f1dbc0f3a479a1182194085c9c14c906b6b92186239bf28203737d02ac67f8864d8161caccc4ef2a6987fa5395a1ad6d4c568cb089c59487dec66cd72f7b82a6d7adaae8af23787642b741a14cc676cd1559c75967f0e4ed7733cbcaccf661b20b5faa0bf046980a5578b3b88aaa8595240e4ac23080e3e88197ee08660ac0d6cf64833b514be8c6c1fd86e6f4f401ebeaa2c6c94422862ec69857df2633f4c97be7b00bb419bc02893a5737ac95c85fe69b12d2c2695ba5feb70f129d35eeee0d51894a50eb317a7cc846be0bfdf4e81fa1d3977ebaa3eb0a7cb227430507bc4598afcfff4f9c39571e79d4ca4aa82bf3dc2814fb6a2ffeb0e97285810aecd2fa0ba479f2c8edf3a53a7bd071144307027b59857bb0924c98cf1b7d92ad91eb75bdac69f8bef480dca2d463a5c96b79fe7d5dd5f83c4870cead1198c3134cd538188fda3bc7f62a932b5a53df83f8c3dd215ec31a549d815c35823fce5b812147b0256fb78ed240cd7d80d096992d2056dc041b85a1b55bd1cc09828d441a19dfe1c75bf2e7014b82d4f9dee334a01ecc0ffba81a6921f23b58c5a6e6dad6f41041fe46b4ebdd0c558eb74a8663d281587cefdea5ad34c1846bc5e5e4deb29eac41ee0bdd174cb13b959e0fa3d733e42afa5c2fb794c0a45c726b4f9d164a54a321d37a70983a72ed684219ae681e082855e985dab2a1c27a752d6fa83e401fcc74cc8325b2bad14563816f1edae8d1e497123f5aa5723028e117e82ee5afc5795b5c01c32e6710df8850634000fea2725b2fec3f921f2556cfff8d2ffab7fe3ef31c339ec1f0d7219f88fc21da6bf7be7d7b9353d2a422bb1dbfeafe282a26f00d835b9fe3986d9d64de93fda56a0f2eda1217d9bf7ef7ef25330dce3f8248cbd8dd997a6136513c688025ad74359f35423a30a01e4f1d3c1ee5513b41d53c837638dc80b7ac4b075e5da8549e0c6f2c5a8f8a6625e61d8da29eff98dfe62034a7a35bf7f954925f8902001be10400dbe2084492085d7210b377fe52aaddfc6d8c4f5462e5abf782a1510870721e558e1ccf0017231a8bf23c3d1c0c16f32cda8f43015736315e4dd81458e417d0389ec2cda6cdbe28642535aa3658bcaba4980d828b6bddf584507cc0a049b364e801729db39ac2710e857440f90f2f6d83e660759388141ce6119aee658c287e52b6ae1cb6f82a33424d7ff565fdd9f3b6a001866cf753a409e376773d45966cb04f95a759a5200a046e3172d1d757b23f7c4ef3e4f922d83e9641d31ed46d1acbf7dda8b76b644d2d379e5c0770908c1d990c178c18f99232ab674ce98dd80607998119961b615ed4014e19c81f6096fc682c0da97b85a5054d37696f22d88445e94566f5d4250ceea7a72edfe72e8cc89b99bb6bdd673543d780634d3eed8a7c88d62fd343e6b8a19efd00cdc581551d2ab8fd06f1f92229a474b11ce69f9717e33a308ae10ca4dc2a899d74cd5d41844c5e27cd7183265f67c55f0a9e81aece0dd65de771a53937041cd9d7e9ec40aa695632fce5076d48a9a5c4f738fd206e8cb1f5a6e07f9834c12ba6fe239b13b874cf26a781cf014955c004a42fc71c09961bbfdb4ecf9092238823a6a8cf1411a4c25b8296b991a0fa8cc0f6a210a3beb235bbc83536d82ad1d8ae869a08bc9db25370257ffa9cff22104fe4825fe249b5abe7d60ad38542636f87a92cfccb19d61f4163519af9011c439a6a63a04acc33587c6cccaeec3850863de85bf4ce93dad35a271d570ee9b39891dc7f40debdded9e6b97920ea93dd4e612468b2b1b1985f99c91786b4e8a17798dd2fa45637b8e27a33cf4cd1fed2e4e367eb5796f6c35f0ac71103d3e2677c1aed6b88c8049d3332d454ed53a4de6882e813bf46adffa5a1fcb81567a92edce392daa38c7c8a0d774d4bcb0ed1fa060005a57d345bb397d33ed6513491f2a6023bc2206ef3f2312bf99acb891e5aa514004744c265249fb5cdcd306d4b87218e5ee9676a46248e3927a9544859b089f32f02a7ab972ffb8f97d4f1db669c31647b61becd2df82b295ae9d5ff15d41ecbf4af631f50f0117f2a6b21c9221ffd28499bf23535cbed4ab411376fa67b18051045b24b4b33855b06d576c96e4702fec2becdbdb7e54981ed253c912a8bf59df40d0ede0746d9a64075df56a7343118e610760ed6221f5f2b2b8974a5d384550bd3180aec4a1d82fe775f1907d0ac21e5e9398fa22e8470d29bfed2cfaec7737194d14e933f1697544f9d131087f1c51d7700e56918101e2a149a0b8065fb3c136f53e1f4b8b573ad3ef4695f3d25a3bb17a46b7d2acc3931897165fc92997d95b7b94b417a888b9e826b406851552459077f262d219205314d57c7f3f55d2e1a77c6486125e83c9694e448b9092e426e2b1b3a26ea8a2c41198ee0f09a87c14963ea0ef00ee3a101f297924475c37ad6e3e38a1127c73236c5dbf15bc9a12d56b058f8d636c8058b27116bd98aed7ea4cba7d92eae333169d121859858715eb51a4a1faca0da9c1708df0beed8c2ac50d2f8f96c5545ff9821707f28fc40692b125876dd820512d52329126164c695e565e97dc9556a75f9bf980ee6bd0726c79cbf6f0a3991d6ca2bdc968e7c72853654d9f9cf001484b60840d9f316d92a283f27acfa98fa853d5c62e3c2a6a852707f4ab553a51442dcb29b3050ca63ce38a51e4f01800eb1534a8b4ca3d9980d078a22524e68c0c007aed1e7663629ca47314f13eb61ae62aeafbdbc9290ae7111d4c1532af7f903869b052a5be4e14f8a3a6e146f3097fd20e349e7ae7bdd2cfdc0d1e9e50e2d1698eea9129ea668a1c10db577503a7777ae5ba404680fa1455a9bf7d8fd908d4f1b99b39c1fbbe5060d04f19b01242339417d0b5e6333f94c4d40088a7a00f7501992270d28229eb3b277b7fe42147532099a1c187c34a85a20ed8f79f73d7aff9a449ef5639a0fe04f88c677f1eb17e5c8f8f091515581d8659795a8f2580b82ca510b2a0be8c66d3260506f9c7b5ea0aa133d76abf9cbfbc3f947b84e8e7daa5704d37e0db6e134c9ab514565b4494e3491270d0f26784b91aa80ef1e745dd95505b542020dced1efbd397f419b3679b35a2819660f78fbd697ef1f7ed03e84841a738d22b96683b9337a623646d984daa8e9eb3804d9a375a77a6f3b5e78c10dadb2ed9ecf656d402bd731b6beced7b66a00fb9b43493c0a03988cb983c30860b40f1a798e177ee319431f673695ffc55e57bb2bbae7a9f102332832808ec36ba556375bde589ef36326e4bbbd262f5d704a9c7b41b1245beee8beb92b6625c6319380bc1bff1de844c5275b2aa05e9d3cf8b093fc6a5e7153ff8ccadd0722bb764566d74b80313bfcbe0e3058a3298fd34ff3a7c782ed9f47aff0aa68c55e5fd1af956394b697a82c987422f32853984c2ceae77d3b16a8842d855f5653f0b3a3086fd924b28055af88d3aa953d99e913af3cebddaf859263b42917de135cb71e7697ee6db1a394714b4837bd7189d459ebb17d42ae241134f2f6ab879d0f8d4e6636269b8a9cf5e4042a8688b9be4682885eab96bfd8508060c9a032360625e869292c0d4207dfc73e9e258a04aaa69839721db5b4ac2edb101a93d15171f2a6f9b9d00e9852a9f0d970f2b7b0ee97d595215b5a99fd9c9dd8926422f5018a26fce4609a57b8e05be161a69804e8bd35e5825f8c3757601b48e0f1905735f5e039b300b81f094002c2414a7eef869e2fcaadcfcb03e40d96453668e4408b11eeb6d509e230b4c485a950563fb4dcf297ab3e6eb46ed8f2deaf893eabda8f90fa2675721d8a0aa0af204c3d6a4926518eacf1427a9e161f3c0d66bcb2fbea7298556ad3b88f4b9c1fbf588fa86835d5d4243853f02eac4ea12f48f72b5271455b5603a13f6536d0da28aecb6e5816c487bed2b296a247275a7e9e8d44751514e5c898d3e073cabbc859ca6ec0ce16eec69f40acec416b64110d854e3ab6074195398c79d01c2611f134784e309b55d5a38bc7a40b0aa6e1651063046807f069b3a4758334a80a5584b44a7e513a79270c52e110e2cca0aa2e9111ca1f55af45efe45395b558a3481e8ac50216afdeae290ffab9caa1aab791141a696a18b36cc0ffd398777b3b795390d546a4f162210e6c3c203a19da52c44855309a9e58e49d2bb82ec1ebac3713bed573f74aed204f8d0f1dcb4683517ced6fbfb436aa073d518f5b0146ffc6fec5353ecd7ffb496402cf028506289071d8c8fde1e22d886af10c769a42ce76eda7f05f3bc5ffaacd439200cefc7c9893fd7a06c13c1d36064297efad82f4c0ff21112b91316a0f23f3a4b58a9a0d94b72400e034be93d6ea499d8f63bc1a58e74ec1f06feda297a3e646e523a24839877592af88b20ed3c0d1f926549bccd33165137d8b7a7e789fd852c8f82e56c0466fbcb8118dd55895149562583012c7c851520af09e9bdffae40ae18bd027b2732a1e3f323ec8a9ccc66029c1d72eb48ba6995bb1cbf28cc9ecabe2d06ec69d8966545a58bef12c9ce593eb3431220421566bd2bebd224bf4c77bbf3d58a07f2da444e5d2c3a6a2d0a206468bebfd9814d1d74e4b9ff562b76657d03bb15d368a30c4232f19d212170a5801e0c306f592094971ab6a14d2528827689532f81bef14283dee2a4f6010b79115d69a8e1f0301f6997d285feb7c879596b5f0cf1020c24e3e0bdc5fe79d6f7384e2adf2f125c2f55fa3005914024cfb04ed928b02c6966a014cbef9c1b64add6c6579118ffdd42537e93a83d98b78cccd2d8ee4840ef3076e0786bedf5f74ca09b4ecb58e1f3c94fc0aabb6790d5422d45064a782da114609edccc6ace5dd8258f0fa431221b3fa33fbc9ade3c6689ba75c28184612524719619c54f342db36da3af03f3c492b7168b75d98dfc012438460cdafd5251e5773368863d1743867de4f7c6e6578f8b87a27c68fd1004b42e53d656521b493ffd220521c185a222711ebbd6cb1bdee98fd1233aed6ad232a32bb87ed616a8f07c907de247cd7db8494e2c436b8e9f4ef8736f78331185b630b75c6e03b0f2ac2004e74596ad9a95336f42f45db81b9f414015e8932d366ffd585f24eb1b706f1c28b6206d0a23e530bdfc6e8c36346ab7ca2cc02d10854424def95aadcf28893b6f7ed33162c0182c856a0ec0affb999f28dfbbe798c1c8bb6e002e297e33bab79888e07d7761a6c8fdafaedba5765612208c9cf8df8cf9a88288db6b8bfb0493202553a614640a7d4d89a15f008dc57dccfc0e047c61134f7ee2cde2b9e13a45469cf0817dc1ea72e0d6ea3e8083fc881f1ee2ab1b41d740a86ab7824374cbb028768c6bfcc860ff9c9889395e754afbf75b28f585844e2bad78e267d29edb0d9bc210bb9e7abf9d85c6ac467da809e0ce715522f3c68d9fb53328839978626069aad8340ab2203d66a6b1d7f3f48539f8ca4b59b89cd223f3aa4f69efb4fdb72b5c7388731efa0805b8693550e297eeb60dce096cc16bc9c4f062f900e03e9a7b7229683a3bde4fc7085a1044154d1ade0be3ac71c557cbfef6cec5df377ac2f9027c973c4f586fff2a9e10872874f89b9a377b0589896a786fc0091d9d4ab75749ae06be2a95d110d8bc414084935d507b5f74b885ba53ee0c52c4030feb2cc77759ffac5deb602124a749f6398cb3c710874e027e282fb5112c4c2c2b7c674ddbfcaf17fb814f2ebd0bb8ee05e3dc72211b657a1c3cefbb6a823bc1bc6dbb073a7357c46c56d6cb21ef5c82155cf61c8857f3d5529999d3ee9567f95980213df432268ce75c45517dc47ecbe71fd623b84ba89a2e62aea04ae63ceca4642f0d0addbe7053d75dee74808cc4c8d3f972dae743facbd313bcc3c2c78b93b16fa8b455cf691f56a235c2e58d5642f46afb8309e2fd0497baf5e982604a3fd618679e17dad46bf17770adb74498c8a4665a626e4c5e43d0c87514aed35757486396fc19866035e7346f455683066f764e983cbd675e7c4d02dbac8df600c1b81a615bcfb1cb2848c358c54de00a063c96dff2c7effca4f182a5432b6dfbd9ba50b0def9dc0a9c30b75ff3c06ad150c466c7746f7e4bfb810e351b951fc24556cc2d4d6e32a954008fb6ff4097fd3490149bb34b6d78acf23142962daecb2d5353533f3cf57f6067af898284944032c338c64cf86913ae1f21d39502621a40e4dca7cb162dc03ba89ab7eae5a98ee7a13e1b69a04d3fd0016506152634f06acf0a8571585c6f0274bbc5b98b947013d506e0ab818c36d065346b9d808ee62c6d707155a5420e4687dbed3247bce270f3148778ac405a6d709a0a89b79dca50bef5f9546abdc21bf71a6cd5dd7cf1a08efaa4e1615dbf2d0731558502df94ac918ca03273528c203b8e36b794bd975de5ff6b29ac5e078cecdbab0032f4bcd4c076b1c317ce71a06ddbc84a28adf1817b7660102b87f7f43dd8574511c24f3409c9dd6e69764b6086dfa6bf279dd18c33a570731eae4f629da581887569611040b11655c8c649ceaa1fa87f3a5670e237e31bd532f1396466e5a283c2f9ed46462ebdb572b33ebdc4370bb764cc8acc828d885c62dc9a21974ed124ac3bba816f48957306cee76fe1a02747ca10f016942544be6447e6a93f5b5c12812dc6e966d89838a5bb691870aeb7126ffd904bfccc7de9cce5413d7fd193a3e897b27eebddb7bcee60ceacdd05500c2e2c7f3c33963cd229552efae2d373a168b9c15b9268e0fd0322e2e5451a258de2afb6a8494f580e60b636c27ced99c0b324b75b2da722119acd49b4a80b875b04bc9f2845b8132ade049f283c03a72da499f8fa72164657a18d5078ce8491331a928773244ea844fde66296edf055f09f85d5eadfd2fb93d5bf0213bdd281f622d45d79ff10e27bbf324b9c4a7e9441ad161c87b0ebcec9d44bf64f3a73bc2cdb3c37857c02da792adb023d35abc02f8ef030ee7a19c9eaebd84290532a04e408d7622d6640bf074ba2bb17b7dc4beaced804c3deed5810ea3f488a2aa2892136386b10b3b4f8932118ea403344c421e7433000969ff4ef5f0da973d2d0e288686904ba37bfc4716cacbfc369ed38ee9509a0cb7176ba7b53ce1b318c70261f3d8d9d85f070450bd21c7f77d67f8d307ce1210d5bdd201390602cbeb5321c1e4903c3f4a468e955600a5d2ee390bfb39d6af6bf142afdf0a01d966174f77acb6c69f2a91fcbbf91dd21ff5bcca1b7b1cf19fee1bcf7e791ddef7597ed1d18efe87a929261811e22ab922e73d92f90911eb443d4fe6c29ebda112b9a590097b759c0b51010ae306a24f35492c337336ef130f10c60402a5dc5834ba8b3d129c6555142c59f52b0cf21338ae253cba16c9f0a88d1a9aaf7d4d44c67fdef4aa55fe282aa98742105110f8abd858983f106ccb3e45e4c5e41099b9e5afdb82b2634a17da7684884ebbcf1ffff6becc39f7d411a5c6903e6ff71c17ebfd50dfc82afe5a096db694f931fb2b10c5f45a8ae30f9af10fcc23ce6c03afb761ae4975fae21d988169a61f179466d65f8f0a5a9c331c41da366e14d9859f5fa52a31a9807637fca03b8feede2afc5caa5894a12b1a822c4d62bc6b46dbd27d11d888dcb22f5ed427a39d9ab6235b2c88aa63c8f8e7f256328837558c0e3f2b1b6a4a34b89583a387c0c47c2a55d72c435095a196a9442f7899472765979a1b8f195a1b7d71c6a9a8de834ddd2acc657d522d2e85ca8aa51dfc4d64dcba6e6eb772977bb4ad9a46e923bed214568e307c8b5bc6e3ee7995631a2ee2478f45e584bff9545a93648d56f5cc4e5133ec21df302c3d0ac75d274d4eaa176506b91710b29c23aaa26c9ca8c55a861081edbd06c380df88969ba87bc194e01f75f23f2f7cb4a7bfbe4820353353acc6a34730dc56ab663114d3d35a2c0bb5b89212ce3b8df430785e41d45bd8ded9dd8db93baf8159c067ace401e8c40bc9d0ff2d54dcde216547e46d46e49714163efdc276d398c1a40e188b1c86923f22896832a652bf710bf7deabbabbed09a578b111cf601cda8d8deaffecde40fde8d24a114ded62e2b815f78c8c9125d189101d990a3e193800e6bac98d9418728ba03d8826ca3813a162c17c118e6233f24d466faf107c11ae91a91240b062f2777159585e9bf6f70b765a9cab3369e952f6fe3b3b0702a36271d47549c4512984fb565cb30e0e325fe8b5db076039b9c8306d80f97c0ff7ae7f025f4636f7b63c8144b543d31ea2ccd4238c78d1819e86be5c5e2deff0c3e123abf5807cd4cc614aaf8b9625e4725041370c09a041159d8d4aa47fa9593a1ec347612e1db62bde1e232bbbd5b9f8caf7db03a3d35f3822e01dcb1686dc18c5ae17d39926b41ee2f9494db90c3d5e14a43d5d6ad4ab6e9cf4ed305d1d036f9e5c880fb87ac6f12fbb6cecebe2d48fbe74cadffa0761f573c7bd328e07d0a7ca0104a3a5071daf409210e78d67e88347d52468bababc741cd17aadadd86d8a925ce46cb05f0d42b314d4229d5a01ac31c0e253484125453ce3338e395eefe0790c6e553166dd2e9747b200b00016f9f6d9305fb1b6e92cf73d92116528d2f7e42ecf2fe8b8e462b23fc175016b3ba077bd9662f86b70e76c2f86000a7d48ab5d0bbf43eb6c46e30fbec0e9ce6230acc1b4e0536420411b18953b1e5cbe67802f7e693868e221e338351ee21df7c99f608f1e721f53bf266572787aee3044e46d39e480a7172e293d5240663bc38b73840e985df932ac50d15043bd18f91d7bffc4dd7f8c8c90903ce1b2df7e91232b6ba291762d35dfa7bf5e31b2cd8d32c98363c31dba25c3acd9a510b8c01cf98eb822105a88c068fb97b9e4d1827ec945477c11ff0ae32b5d34dae516daeb1cfff8407a36b67cf708477c09e290ef8c3d0c87b27039b56b1ff8b68c4484079d1bf4db3c6b13a69139d750648c0e734c450edecec576dae143af16f6d110593c808257babe76f0a088f8e8ad826be7818a263d9c3f16bbf6e18a1cd8ca3522f2224461147cf2ea1081da607c371c17e6733de675082c299edc03279ce665e76107e271dc1acf2d02b4e1217bef51d67ca39882077f8f5ff614d2a8e0079349f8a61c4b2eaa05a95f6bdf0c377145bef608287b90d455c78a32b11a649f510cac586699517862f6ef3c870d07838f4f7078e7f62fd38cd0999c9b2eb5d5ff7107227f42c1da7876b86acf5a1b057c9741cea4b5706bdcc6a729a8efd92e8e764dd8bbf9ab6eac117b2c1febc96ff5b9de90124bc6358522ca5132a82b7e54ef610b2ea5009272269caf14be0a73aa9fc57d1ab850045450ad0145c9fcee0bbfd4826055598a39bcd4233e88f00b4d2a15639eecd7c89a8f4972ee916ad18a3c7118011d01aa2d66ac2ba2432bbb2a2b0520f17dc8ac33ae3e947583cb55380cebf2d14d9fb38da668362aeeba8829df273550d77959581eb85caddd2cf491187317ce5021729be9f3e2e546acc065b9777e8c9e85e0e4f0bffa7d873eb9d5b572d66a5c787c1b70a5e169e82bd77c2f9c13c62019649cb447ba7a261970de222b6fd13c155b0a4e7ca67034df5594bc0356cadffd46c1fce9b9f9344ccd6ce605fadeb2fcbf69a9eff106dd9137e2514d23da4f398a5aad787b5ef7dabda9ec9e402040716c75747d396f835c45ff5391aa161f3679e2a635d54b34d89f0a24c910f1f2fe5099efdb4a44e2e78904bcef21f2f485b1f508790943bbafb8de419752b5bb8a93e4c7efae916868267617b15f528efcfdb4d2e3206efc53568482474d2ced7528b60995f71b2de8bf7ae979157e39c7759fc5fc27160caf13e9bd2e4744670d4e7e912daeb81619370af01360ac5141d0d431fa1de1cb655b3b8b71b2b8ed026a708e281b520ce924949f4d88000d8cc5f7163adcd95649c8aab3e1be32a603b2afe8efa54371600a5ebd71cf317889209746d5ee3a982005c301747f4140fe45d167ada394f12a06e019bb5faae488088cf01a2b8c0cc35952f73ff8ad619d5b22284761812f891f13dc603f9b8e3dcace0d4cec78c541f2b3bc9ff9440c41564e0db8feb9af6760154254441f1e1ddfa73b5d28c36aebe17ef506ce430dad0dbd5114ab72cd0f45af808c33f833a0e6ea7eaeefd98d730d4c34ba392b82830339e405675c8b9c02b3ba20ecacb356778395c031c0a3dd38b2261d04b3f34ddb29090dec7123512116ab89f72642d933209203a2e6e619c2d8ed9be222ad4379c5c8422e1271b499c3dd320c68a60c33a36798eb1a732c84028e112ba09eaaa2ddc9351b8b7dc1a87a3d4b72b30a214e540fe59b0b2159370656e5a7ee8384e505b266b0633d55689982a067f4dd58718f8c7dece7ea87040f110124aea293970b081a2e0e090ddd5420044cf535b3655b584c071a754676265f7a2e52b05d35542e3083a4a89ecb995a7f15dfb0344513d776e7f4e05c038084a36707acc2f769809240f4a8da96d277ed136604f87b03aab490e934a1c4e5f9ccba65e785c1ec2bbba339dd1de95083034e474341a38d5b728c15ea202ef0cd23708c3c55a686b29bc2428e4cca087b98f8fb557f9bd50435b0f6d346ac220e38a97fe94cfed9e010c03a095b719f2c7ff53d67aaf633bb08b7fff80cf1ca86a24ea2025ad3a82bcf00dc907716561dae526b9c3079232020c9da93cf8a10a177f7498a67e7bf3f804d55a835d02c3c7948b085dfb2b8973a35170cbbce2d92c856a21ac97c1f441e41a187b4b779585e2bf4762245c5b2f445e9c275b385bc7664bd3dfc070e5791ef895c5c89e4e3edb5d74291437e2f90235ab6d52e9ddc40823cf8cc9f7fcf63e064747af76c1df41e12cad91f39917b9ad4dfefd299839c7c2db825da56596151e3c2f777c5b355ae5bb578e89e0441de0e779dcb21ae7f39371c215c9c59a56feb93b5723c2ceb04982f0dc35797716b5b7a9e498480ea10c67973905dbe1edde2dbebed0fd4c19168bddad7117ba7730311524cf15bf3809b627103c2dad18dd92f0e893aabe536e6b910e41089a6d4c5534be64a40554f977be575e7ebbbae1dbb274e5bb39e8b89a01635e0191e5afb7fe3f2bf2de4e111e2561d172245a21ed2324c45a0fb3b4f1f5ad1e6df231c14dd23c8a8e7bd8fc466ba04aff175a4112dc845d36de3ae516bfd16bf1581cfbf613b3030ab2a383146972b9e4b2c2190369e1f3e100db70eddbd9d0503e729aae2e4ce377a7f7701554b6e03a39146e8e4a182bcd014254d157ed017a8aee41c0e652fde0c14c951ce05fc048621c4fc87e5aafdeffd280211ee17c969fd23ceaca145f2e9778a687143d34710c4ee9edd47731ddadb2ee7f70cd8055376b52d647bd1930b14d4f3f6fe3a16c3cbfd5d9843cd7535331d0e304ca24dcecf1a5918915d80c78d3f4b76a2808c5f2683a64467b0fc3c2f3bdc51d1ca7a6ca4305b4f9f98c02701f317c2f59418ab3cbfb96c950435dbda589b7066731173c461dd16ed41f0b6771ad79ea2f74952e33bc12b200143402361298bb9cffa7576b71980b9830d541d48369d9a5a1774ebadce347253ee4f69cb851aa4622614c5e7f6f6134234070abbb4ab8399b7797ad9ace19f7055aac14be9d53e650d5ecfdd1a0f43d1bf449b5e6b4ef86b5a369ba583aee91d252bec0c3f02f4ca9d49e66d977d22795d50428931cb1701d7138e4fc221341aa31de38984df70f7a836d27646dae05636a94a97aa6a9079bfaeb6d928ba3260746a9a8caabd6ebba81edc98e6d6212c4c96e5fb6fd8b314a458527014e70d4b981c9cd06f39c837f236ce7a4de3847bea873b828287d456d06694404b07dd2dad42a736229c51ad984acb51ebc2dbadc5fb8822b2d3ae684bde152125dbdf8fcc4b000927872a63f45a8886b6c04d3adff41ba47f10d4cd1cffe70992e1ca557bfb822f193f4bbac199c7db479d9dd898b969af279c3f4c8e7014d965d9acd2a0c08c59ba4c8898cdac74e796aa56465e839351f56152d4d2d5ae5f4177be6b7e13b7a1314e9f48f99d346293d00a5a477b8fa271fe67c1ff583d97358e8a8266a4c857fd443e1b87f7b28204481f8354c28dd78b77958317ebad3a25fe27378cacb7b2ac146b8146f2f6a50c1c0a86a3f2e8c03e98d477ddb0ea51f02885353952dbfdcd802b43240b4fd84f98507fbd53e484d077be172e48999164daf7ee61c13fb869160808ecb900574dc3570fe241c04069f2cc3c6175af0c51b7ef848c70f91fd1f5540c721c0057effd8de48f568a6db18af34b3c29e33e6cda2c4bf117ef53c0c7698cbc6ae360596b764f8629868791377878d96a5142b725a8a16cb41d4bfec22f976e991e68f1d3df07fc76a340ba60527d108686e244743e616a920e9bd49ae16e6c16e31cfa8cedd457b1576bb922c57ad69904fa1eca82edcd2019902ffe189dd38ebf6f882455f3554c873419b499892b116dec10ddfda512c7fa9e062890711ec718e1707f15557d93842ea6492ea9fa4e5492ad36656bd859df3a6a2bc6c9470bf9c7edc3f37eb7c1a9cc43750bd24ea316cdb918e9f8ddd3280691fb2d3d0d2b5d2bf25e55bd6231fb95b75397652d97ca97f17d5df451fb31476e91e001333aa7058cf5a27b1ce4c7e074469af6ac1ea36140c8defd9f7a48025b4b25e32f51bbfb72b2bdf1f67a2dcc2de606c7e804370e96dcd8f76b92ba7f1f95611f29f3945986a0385935f873998388ac2abcfc374a25cb49ee7b7a9827ecb09036b3541d9a2f8a3e60d34e01b0d8e1bc529860c55ad29ddb7df17b43832bd77611bd546aa890d44b71404c3345bb52ab8ddd2b6f482eb9f11c1f976db343c56635eaf301217594120adf87f6ac7b12b288e76f1b6bdafd8d72d443d78910ab9a094939a88b47f3acfc644cb06b5ff2bf54dc3f2fdc3e7b128039c1901394ba12f405672ad56b6296a0b7c94db6c1b7d48223c3e4d6dc409c23db0fcd7c36ca8476119b0d40ffbc2250feb848d95a9c47d267ec6a109f13b0430a52b1de4ffcb5718502a79e90d552724551bff332b392921abd512be24f9a930e384560d01a91850f57bcd51a342e7d8ea7cff3499e9aadcd8522e46ccb5a2fc167ed684b4be89851f8bd3b14569d6ed23862c964a16aadc27349e63a322a2a4466d7aed731bfc01c4f7c6cb9e37e1d91ef2fbb55b9afeda540c30c1d62ab64bc97fe300fc2784f31f2541b7bdc54439288dd78ab3d9d13f6e17148210811af42e70fe40e5ae9d57f558cd4bedb5708098912c963c1956b640980bb18b6544491161586518e290eec4f12255ecc784614297faee9bf0e2d1357770153d133ba7e5e2bc3b794ed585ac225447cc7356c0d18e63d0571206bbe558d32323b38075810021b01279c4cf544f149bd382cc338a4e0fc8e0b4bdd787c3525d864d5f7c5ed8d665a88d859fff1cd9f63a1cd8e46eaf5e38bb201e956050a359f7ef6852d42e1764e037ef85a01b943e2f22fb4c913427651bfbba8f08d96d4cdbbd4dd6f55307f2aad9e4ee686ec113ced4a7750cc8c1ad94b6274b304537b8061d21ff1d488c2c36f65cc538b10a7acd035bf64fb95a4ca8ff4ccc324b546d6dcfdc9a1d17496ff399b3f93f1cea18a7ac769414b5645c7bfe4ed6973221f0cf38a5227e6cccf18279f10fe97972b4b5bd3b6e2f7237860238a776ba5ddecd0404512095c5bc5601245b92d2d9d782b628668c1436684ad91dfce810523297cc4547b5aaa3c3db81a6950dc9c6defb286b305fb87f6e43c0859c4bf294b3c57f0406d2d6b7f02cfe0284582961b0f74d4f1d7c85df40aff6b5d9a66479ad10155e797f11126b6905666da811d7d991f5a38fc22474037dad1ea71a197240079ae5fd5005bfe64470dbd874f8267cfd1eb6c309fafefee0755def04a1a045e01ae56a1c0d84bf66aa1847157d8a4fe9aa258b3358a6a0d30994dc9cafc67e1954349b359e266c4c0fe6fda93fdef294c1d3b144513dbac660327766661c05c596533f04e81fb145bb1f42b2b300e6cd760089948401fceb3d94b1f584bb229520af789e34fd2309233288d095b0e27d3d5576b289ad284d62936ca735f8e96051e005a319e08903ee086f6b65e7e2f0936a8500475e870adda79c37e2e7efaec80c3b8b1a306aea51019b33d0160b392454526c6f58ef861c94bda848bd8627884f19770e02c60d97da39b381c3712dcdad3fb2032e409c50d732003e9629efc1128cee4b2ffbbc61d394af2425d80d1d916aedbaea54604865d3ba14d920075bb62c61411fa43bf40f34c5d624df6f3e6c381aef241456d791a2f6a14b65d4b582be229b3956c5c25b701b6bfbb2ac706199e848d6a17a3ec60cc90e2a95dace653bae15708a96f67ee80aa341076d503dc349f786891105db519753c74444a91294c92c557533f9d6c51b01a6c3a20b9955189393d351766c4fd69c746efc71561f9fd473231afc55c6ced8af4319ade0b75d2cbc396b2b3e3063ac934d05d95a5739f2cb8fa19c1af40bd719833e91ad71bf23d3e638de11324b4bac34490a57f7258ffd1079a8a9cdae7cb48c4c0b937fde3d42771ab040adb35a90d5fbae186aa743d38e9fde7ec2e65e5fc5f19c518a03638213dcd6f3ff86d6fb5a0eff27694c02a17e2ceb066598b9165334fae96e2ede666b359c77b9c54a8d9d8820533d782a704e759c71926bbaef68fef73251a2bba7025df623076d054a27d8d085990915694ccccfa45c0b93e70e6e1dc9440d06dcba3a5a7ac113c4c4896a64c25180ccaa99a591a66d21d8267b2442e6dc996e2e2bb8458c4fbd849a5e71112766ca74f359040c40475384aae0bd5d56e3f721ee14fe2c82073946a7c95968c06c58baa49d551ecd287233dffa4669caa6c789d6e323db02c12373f3e85a849f45bfd64c08b1cbb5986d571949d12deba2c2227f526149ffc6c389a2cdfb2b1a80479d564fcfd5ecb258297c0155980f4816a6177111df72c9e33bdd5725b1498589dfe61d6151a125dd05b550ed37151fac1b4eeac49830d54195dc695f07edc13e6ae5ef1842cb45684407b575ee86efb986099e401e2fefa66967de8597e7d4f8559aa31b4a7b30b3e6ac8175b022f7260e371d897a757a09a6ede41f4e806e90e69960b7c4dd8d74756b738122dbb2d6776500d1b234eeafbec06621c8f6d12ae63f6a8032d34b742c80e024ef4074dc605472dfc50c6adb7900ae148325eb103318a11d3e3987363e3dacc084211a91106201a8cbbe1149da601f4aebb952c0fa3ab69762e55e49771ce43ebda5e5acc3f0a12c5cbab138f8fc13aa6305d97905f33af647a791a82eb4c2ca604fdfbbc5feb9555ae7abd35c4fb7e7ef1e56a05deeb73b0508b927c3a422062c7b78eeb898d0851641ded04449778c31188105cbd6f1a0d9558bede60b87235dc3905f12aeaf3a261eb801733bc1453bc46c27bd685d4cbccb02a5bd9e67f2a1945326cc84581cad01100567b287f2082128b6225706375a88ec7cfbb90cc38104dbd403f737e8273a20c04ff7f0a22cefecb56ba3d99a11e4c0ccc65a40e36d734d53b23329394db8e2c09383f0ae82832ed7ec7e213097335f13e1cc2daafddd52642d5172fdfc56739da379e9d454daadcb4e20f96975e45017d74d8ccd01a136300070bb9a22f7296d41024cad19bcdef1649e3431754ed3dbfde99c08f85840a3cc338e48992b79a390e07e62cfafac9f2103a58799238f765c6af3f8eba4d7b2e7a74291229f97e8840de3d1d4dc8ca10ec6dd64b62f05caa3fe29c420f57ade2a8d1c5b5d58661a84761c4ba2d237207764ba17bbfcc293d0f3aa6b8b59bf66a7b8da1339e46e41546fd0636f5efb29bc2d7894b3e75f26a446279f51581cf2829e175ccf33b0ef7cb02a79294969f12d3c89f18d19055e6a1bc23c8716a83dfec0a19ce072280aa50b5c0fae95623633b3b662e2f554d031c716e6474cd16c6f625477d0f398dff90a3f50270da40a11c1d5ea1e4f84a6d64295ed13c33a45e0e1fe396164e3cb5cda879a8eddd0e6176300880bfb536158b088d0d17e384c6a1339f5f1575b3869cdc9207467bc1d831d02de379dae4f67b49c330beec7622fa0991adf6512114b243b06d8eaad964cbdd987afe60367e21d5d89a4b8d0a5e36ccb85f1084a6a61290ea34716ebce032433097c2bd93c95d83a2409be0b79358e524eab6ab62b1bd77acb42635bf1948fc42e98808bcac4932225b719c2e7eaeb70d0d860d63219908d86cb62ffd56fb0846fbb83f14283a3c7104d52bcf4acc82608ebef5e4b61eecec4ad501940c0042d2b082f4fa788bd62ba226c2aaf3d86722dc6b29632a1f2581ecbab108287a9fb5993ed508c1747c08c3b4625199b56fb4c0e23d6cea04b117714bca5aa97629b5aaba62720c77d97690cb36e3c84b96ca4c4dce520e40cd4468d19999010d77be4f2913b1589e925c3a0009c2578b18a425b17691d7cbe93614e590e8516aeab2c5cb5acfed69cc8e337c3ceace7e84b8cf044c84c524c6032cafa3c65e5008ee1796abfec8b712eb521f2a32b7aa16e7f60648b192fa692df4c7fe18991a724472ec0fc63fa9addc1f8541ad90aa08079baead1271c5135f0d5124dfc37aee822eb484131a6313d11949e52ed26fed773385b02efd0d648555f04311aea4ab319005f72a72d6276c593ea65dc19e6b7e8b70ba28ff424d4812abf6e483d6773e52ead8269eda320d971eadaf81248e7c63531b115ec94485847b19c687e917c84802a5472201d4685e95823210cec01e23334c919fc82a91721a5734fcf0fa553f255a3ec506a8adba3c874ea2540e8eb1f05dbe2d1aed67f1b637bc3f7392f87cd1bf34c09488e3a03f18192de76fc0814388e0be39ab9fe46c34204f9bd92ac65aafbf7a224f33b057fec2bad7a527856b0c2672c41d316e0db4756ebc56018d5a22108a927db3b908785a498df985741f6fccf224873b1e212ce15dd2403c0f42ebc5d8004dcd882db500f4eff0b6a6d98dd092e2ddb15878071cf082501e552cf64a11cb3fb12b60cc1318de6bcc6edfd0a2eedd4e187e87f1bc4af1b5957ecfcf85f47186980ee9126e1cfc4e44ca00ecd4247637841681a5cfed2267a9dbe77607f32f89ba2b8bb34c5053dec80590f1b573b1e321c1d43d6b31a2ff6a673c71f6d927eb05de12ca39dc1777e8dcd640fa2babc561c9326f45b4a82396d7e7c4d4052f732a58eee8f5a8b66113a274e0f65b52c2810ab9a624a7e05bf74688d51172b5ca58f082ca7898ae3d3c628d0c475c9fdf74d49bf9fc64a34f6c4da48ade169d81ae9f297ddff89128d995627b5c834138a39cb9c3be3bd117a66e3f807d7e4ab866524a05b6643f670a969617f5b0bcb44e788918ed405371129862a3cabb9efa93ed2e8e98ea9305cf7c1078799bc3137ddbf25d79e7a9d65d278548e84cd766205f1a61ec9b79fff06865410c734630f5659cd16b4caf72b4feb3ff369a5fd436c16ea22ce455a202963e61168e194d7f3135ebc6b9a3a3b7d4f64d81abafc745b6a084113f01a0d653bd4725d7afe623b40d5f4396f78e27a43f129a04261614f0aa5034e02ffb5fad415da42f9e742421b6f17abafa3dc6a5479fdb73c374afde6728bf7b239bbe5035b62f054ee0074133a6ad721edb60b60d52a569b04aa36886a57b04ed907021d1d7fb42d1725d9b871a267404c5257486fbd4f2540326596e2bd2f2b0151e2629c94793cd76765498ef5e7811ef6638e09a16b64082248eff253a5281c4954270d106a361a273aaefe9f2e2491a90852d45e9780feb17936a060822b01f759d9144c275ffaa91749e93fa3b9d0a714a61a9b060dea685ea236cc1080a3462804515f5f2c36c5927caf19b09af8bfc135682a74293ce3117e4b6c7e8d6a40aaec7184015b6d15bf65be6699d1e5949f4c111b8eafefa0ea7b64031ebd4ef62349ab301e318ec7ccd063c0368ec85c2acfd9f94ea8a5478cb85c1e57c562b669a724eb4244a374f43a12f3d1db8155de9376e419490daa4f3df0f469ce1d714c33b81b233dfd683ea4fac80603af090920e8ef9ed1d4459c9bdfc8d8fcd3e3525b094ab0c06a7d221817d813f4a80dfa29cc4f4c32a2f3569adc2e3169644bebc3dac161bce0cac0ba71ee187b2f7c558e20ae372a4a1b8af0e2e6907771932a3fef47a0cef2b99c04670e65927fb1a417a6a3eef0026b4f7003c9e6f157af1b7a3f1951653f79481a39fd5417a3fb68eb4d35979013c39bedf920b8047f8d9571be936e80ad7cf6b9d6f1e13006977f95d6d99a73e8dee4661894f1f60225701b3f8ff9b33086e2f936b86dcb8feef734e01bb2ea900d32c4e623d3d69197bbf91275184021025b8bb7dbaf92212020280431d2fda3cbc6cce60b02703c9122ec222f2df428e6c867eba65a3cd70a36b56d58076a19346f852c18d94318f5e35686e9845ce5975984fcf43053c63b1c3c9397607ba3cfb127a97e98f99c46b80fe2837c84d052e9870af4699eb7643c378c24eb9c81b29d03144fb2844a025280bee6b9b276b4e24069050fffe2eae121381ee3b5b5a8129852e17fb342adb03ab130fa87343df67cd252444f26b9eba3f37d14deac70d8ed6fe9f047f7c8c26dffc87029ab28fbd87e21cc780749ed487eba28c42f222a865cc0375f5e449a7662fe9ca61198f6771d0d3d5b0629c47fc411c1071212548848f8cc745ac782130c688ea4db7bf0105e32593795a7767ae7f170714e2eacdba85b83352dbfaa2c64f5f683b6404c5d634fa06183034133c69c442dcbe8b097f96f20b8a8e0d31248f32223c77847c15f4e6ee15139a26ce9683d1415cc1ce6372cdfbd34df404c2583429ef4b9dec398a6601c943361d708b4c9709723744932005279cc45baa05753df704d97377329e891998a434e16444c5ddf4e879ae4e32c82b46660b81449ee1c5f7c29bf042fd8190e3842ce13fe5f62730cb2aec088b623497d0b05a8f54858b6dc76e0f81b7c1d7fc110210843e33879381ab42be4cf55f046083d6baacdc796e3ceaa1ff19e5a7cd8b729ef9a6c5a1540a5d15f8b3b609d7517ed4157341314d020b50c04340fa7106644045ae2d347f0389ab65e014eea6ebef6942e9152af8d748cd1152200b094ecc1489d8cfcc6403285ea2d260fd52699b8d72005a46cba7d1d3e7a3d1c2a01c94f65bf163469328b4de1bc104a8f376ea11bc3a6da4fa0c33af6ef15ef5039700d2c16b8bf3ecadd7364ff7359793ee799ffbe61c6a6afd13a4095a2f56db9c0803180b4ec74a7eee16d007bee724309d7e9f18fa68990f06d1d4a6c574c02ac7a7a4145af38f24e04c2fd0f095d744dcb47b895fb8307cc3cf1acf3ee584ed39be44bdfa86a909e11d548173b0ddf521202f52ed2e3e1b3f492f398bc29d115b1f45c817186d7c19406a9737782d472d6b3917b29f687f38403769657f7ce3492440b9234bbd596b5513cb6874271a3a1d5d10fd5600cc5881ee085317885a59bb859e6a905324b00ec148093b6e64db7122600050bf8345591bb77b5d9574becd52f65c55c6a2e7a964af0613b6c31da5a0dfc2db2d603b124e9d9370c61a0dfa9d76f85f0c7e75dd871f4d81021cb8b54fb8e42e51b4ae1725fb828de4a22e5b9c3904676b85d582124024db6717e8fd8e38f7d6a8461ad9003a8b4fe6127543913edb0fc9d23d9dd5325d92e4342b79a88f764ac53ebd4ea8352878591c8c12e675a6b07bb0d1b1c8bb43fc67169018a1fc93101438baf559f4e0290189e42ba0eaa111df4511fbb30d4aaad72f2fb08669632ab1ca0570e53d97da77c27afa56f62271c004b564ac7b2276cbe721b7bfc69c1a485e562fa8436cf2c7a024dd3f9604292cbfec5118b1cc416b09ddbc9612491774fa9550e0e3fca69b0e588510ab89089799c27116a71c34ae945fb744ceac08d8407b9afe1c22e3f11d7c9b4efabc52dd1fec7be0321cb2611ddd17c4a66706128ecc80b7183be5a5d7fcc1c5378d838d3c61a3783076374081c6ce96980b52050cb84dde5485e010feff754eff9f95ed9961c068ad87378278589480a975879113afdc283788a7cb901151933713a3d5c64be6f75670e576290995c9be5601149959aaa74d9ab432028f42bdd5c89d2bca66082ece2b08f2ba0495eca2cfad68f01f7bee668df585da2837ca14037b37db580d13a00f4a30510782326b8b08af84e6577caad229176f3fb01928f0e49321247dfa72c53a9c17cb41bcd4ffec0838377c63a227f293cfac1fa8515302cee48ff0ebdf654c636ecc548afa39f2454dfb659af1e3dea14b757b5ef916a335e4d2c32b19352637dce355a8479fd8c72453a93b2c65bcc0cb4282fac88c6cc06a8a343a17ee88622ebd50bbe70e1aef3ea4b73cfb271c7127538b767d5e03e74488d46ef64056f97e70baec5436fa745e73067ccd01d4a8fb38a349a9a0ba5a95e31510e27155b632bc0066f6a427ac105e67f9bb1dd1ce649c12d4a926df27e74c474ea9ab940b4eecac7749a352e68cb2f30a7c8e070f6eb199f7a50c7f27b002c06dfe1a113036f6330e564a38e1eb9796cdb82fa82d6051433cbdc5edcb190a547af4f538543db4d67b0298b8e34bb5559c9e5e25a0f0ca1b8114c9d106779c4b187d9ae5978199035f261b886ddb26ba6f1317a91a3e9db64390d2153157ec6728a27acd465522e98b5baff0c11f425bb2c87c332b3333cfc3652c6b5edcc9b87aaf4fad5ab15cfeba45639635caaacb8ba7f9367973f35abded31dcabac5f7eeab2cb910100f93386398efc77fdec501ce5d14a46287687efa6c3d6dea3295a6c7d6d0048175cb12000\";\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(\"Wuyuhive\", 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 [\"Bee robot\", \"Bee robot\", \"Bee robot\", \"Bee robot\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Honeycomb helmet\", \"Honeycomb helmet\", \"Honeycomb helmet\", \"Honeycomb helmet\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Amber glow\", \"Amber glow\", \"Amber glow\", \"Amber glow\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Orange-magenta gradient\", \"Orange-magenta gradient\", \"Orange-magenta gradient\", \"Orange-magenta gradient\"];\n    }\n\n\n    /// @notice Raw artwork bytes read from the IMAGE data contract.\n    function _img() internal view returns (bytes memory b) {\n        address a = IMAGE;\n        uint256 n = a.code.length - 1;\n        b = new bytes(n);\n        assembly {\n            extcodecopy(a, add(b, 32), 1, n)\n        }\n    }\n\n    function _svg(uint256) internal view returns (string memory) {\n        return string.concat('<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\"><image width=\"400\" height=\"400\" href=\"data:image/webp;base64,', Base64.encode(_img()), '\"/></svg>');\n    }\n\n    function _attributes(uint256 s) internal pure returns (string memory) {\n        return string.concat(\n            '[{\"trait_type\":\"Character\",\"value\":\"', _pick(_T1(), s), '\"},',\n            '{\"trait_type\":\"Outfit\",\"value\":\"', _pick(_T2(), s >> 8), '\"},',\n            '{\"trait_type\":\"Light\",\"value\":\"', _pick(_T3(), s >> 16), '\"},',\n            '{\"trait_type\":\"Background\",\"value\":\"', _pick(_T4(), s >> 80), '\"}]'\n        );\n    }\n\n    /// @notice The token's SVG image.\n    function image(uint256 id) public view returns (string memory) {\n        _requireOwned(id);\n        return _svg(_seed(id));\n    }\n\n    function tokenURI(uint256 id) public view override returns (string memory) {\n        _requireOwned(id);\n        uint256 s = _seed(id);\n        string memory json = string.concat(\n            '{\"name\":\"Wuyuhive #', id.toString(),\n            '\",\"description\":\"Wuyuhive is 3000 Speechless bee-robot with honeycomb helmet and blank dot eyes on an orange-magenta gradient. Art generated fully on-chain on BNB Chain. Minted by .ai Agent ID holders.\",',\n            '\"image\":\"data:image/svg+xml;base64,', Base64.encode(bytes(_svg(s))),\n            '\",\"attributes\":', _attributes(s), '}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    /// @notice Collection-level metadata for marketplaces.\n    function contractURI() external pure returns (string memory) {\n        string memory json = string.concat(\n            '{\"name\":\"Wuyuhive\",\"description\":\"Wuyuhive is 3000 Speechless bee-robot with honeycomb helmet and blank dot eyes on an orange-magenta gradient. Art generated fully on-chain on BNB Chain. Mint is gated to .ai Agent ID holders.\",',\n            '\"seller_fee_basis_points\":500}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    // ---------------- owner ----------------\n\n    function setMintOpen(bool open) external onlyOwner {\n        mintOpen = open;\n    }\n\n    function setRoyalty(address receiver, uint96 feeBps) external onlyOwner {\n        _setDefaultRoyalty(receiver, feeBps);\n    }\n\n    function withdraw() external onlyOwner {\n        (bool ok,) = owner().call{value: address(this).balance}(\"\");\n        if (!ok) revert WithdrawFailed();\n    }\n\n    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) {\n        return super.supportsInterface(interfaceId);\n    }\n}"}},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"BadQuantity","type":"error","inputs":[]},{"name":"ERC2981InvalidDefaultRoyalty","type":"error","inputs":[{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC2981InvalidTokenRoyalty","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"numerator","type":"uint256","internalType":"uint256"},{"name":"denominator","type":"uint256","internalType":"uint256"}]},{"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721IncorrectOwner","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InsufficientApproval","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"ERC721InvalidApprover","type":"error","inputs":[{"name":"approver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOperator","type":"error","inputs":[{"name":"operator","type":"address","internalType":"address"}]},{"name":"ERC721InvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"ERC721InvalidReceiver","type":"error","inputs":[{"name":"receiver","type":"address","internalType":"address"}]},{"name":"ERC721InvalidSender","type":"error","inputs":[{"name":"sender","type":"address","internalType":"address"}]},{"name":"ERC721NonexistentToken","type":"error","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}]},{"name":"MintClosed","type":"error","inputs":[]},{"name":"NoAgentId","type":"error","inputs":[]},{"name":"OnlyWallets","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"WalletLimit","type":"error","inputs":[]},{"name":"WithdrawFailed","type":"error","inputs":[]},{"name":"WrongPayment","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"ApprovalForAll","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Launched","type":"event","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"agent","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentIdRegistry"}],"stateMutability":"view"},{"name":"FREE_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"IMAGE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"freeClaimed","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeFor","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"n","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeLeft","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeUsed","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"image","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"royaltyInfo","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"salePrice","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMintOpen","type":"function","inputs":[{"name":"open","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setRoyalty","type":"function","inputs":[{"name":"receiver","type":"address","internalType":"address"},{"name":"feeBps","type":"uint96","internalType":"uint96"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"58222165","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-03T13:50:10Z","match":"exact_match","chainId":"56","address":"0x250e800025a9a7861970E253BaB6975a57f80567"}