{"sources":{"Hydralet.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: Hydralet.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Hydralet - 6622 Baby three headed hydra with jade scales and a gold collar by a glowing misty lagoon for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 344 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 6622 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 Hydralet is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 6622;\n    uint256 public constant FREE_SUPPLY = 344;\n    uint256 public constant FREE_PER_WALLET = 1;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00005 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Hydralet\", \"HYDRALET\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646903b00005745425056503820843b0000f04f019d012a900190013ec156a34e27a4ab3528b47bf2a018094713bdf1ceca21b578b0a50a8879026d6a22f19e96de3df2fbfcf2fe844f72f9aef523b8e39d4b4f5e99cfe11e527e33d83f6ae50d7cd784fe0178addf9c33b965fd0acb8702e4614d2a284224b642a6c8ad216193b445e10649bb0b80e8d8ca5f27182418366d1a6899804943358306098d9b0864faa69d4216fedc94fb1e8fb8bb7a58254cd4ada2d73775903e0afcadff6e0ddb65723cc388a698fd4ce513f35b9d7c14afbc9fc20ff9ccc60c07da1d0c440933403dcb7877e105ab4cab30137ce4b7fa9f27b009aabdb0974079b70bab324579bdc378d67bab5b021ec343c98c3acb6021e3a9e4e94b962463415a71dfabaf759c2a8cb1681bf4e1e00e2913ae78ccc68800631bb6fab9a5442fac66de97ffe71a7e6212c38ac4fc1ed6e0b438f8e96021cb7c02a6ca332fb4d7e9900acfab8eec974d0b086c72080938b53d8231b9a5bc3905df5e7697a405d4d9869571cacfcb02ad41a8e852b9f9733ac43e95e32f7f19f873deea91344b440dd354e80030f18b3f73d351adaac5376ee11f751add06d19e029cc151ef9c3505b620598876251fe7aaecf2f923d1b6b26ae8a061713bdefb92e8ea3868d00f3c3cb9aa0ba0c6a6f3f3e7716acc407b4147818c541e134d963fd4285ae3e2e0c228de34b6bc474d6276bedc2f0f26f82ff90375ad6969d62d8655bc5501ae62da606734096ee9435c613ca38993acef348a177a85f1bf17bb7a43f1a92cf186e5af0d701a32acc36817d01c32f5975945a0f175b62e70bf61802040709403ef19d12bda2edeeb5fc7a7b93e4e7457a147a50ff02e27a1af0134864828cadece4b9fc627c9f4e11611e32224a637125bfc268c5166333e8b48de150c32de68e9599ebc0bef817d55cc56bf26fac32b56ea0251ba0fbde6df57737a9ecc11b6a93b16e6ff9557ca890fe95b548cf5f6adcf772858611e93990886cf1921e1d90c340205b8aa342bcc313e4fcbadfdceec851da981cac5dd3af80cd86d1a614cd848db43ec938bbf7fa4db6b7ea1b6e0a3eb9b1ca5c8411b048da93597b9d67026188b7fcbb801d7db0e28646f97d6f2eaf1438e57de7816abe883ebe537ac1b7a5ade16039ea91b53a71af3cb7d85687556e4f4b812e6a8a35c1ea2c19d8099eef0f901da9fbafcacd674e005fb45a09ff72d8666e327ee02908cd5131ef00e9f97417d525e8100a4fe549e98510977861f00585e60278e582c09b03c65a573756ea4427b9624ca85200925ae31791debf23f1a14dd6e3911dcce5fbc2bbd7dbeeb510e7d54365a8806f2b82e162fef8fa61b9c4d6b554a371a1f63873704d86f654ebdee7cc70450bacf28fd93dca3116661132bdaef9fdd16e3a3da33796512d2f52b08cdfac0cee02221211e14639663aa0e7bbb5c56ffbdc86a5a9d3f9fed3841515ca9542338056e12449ae041f89eda7d704b0fcac7ae926de8c6d0c2bc6bfc6b1639bdd4a619f5f2c1e07149d613f3cef4593ed881d7b79d99ff9c26c3d72809904938157de940f06b32737eb4d72140714cf506f73ce6de365da74489ac05b8ce40252dfd63529720288f31bdfb0af4990c7ddd8763269d93aceb9932d5efcccf7c379f7f41d26d896374d5192dff0d002a699028961497115747e13d098db6bb97c2a962b1f7d6f0dbbdd75a77a8b4f6ba3dedebb39e5dd5fa307c22a649f04d55d127b43a3eece429f16f0fea81f9774e3cd4963c2c3266dda9eb16bbb116183a72df789adeb11c79fb897dac81157a657898c42a0c15c9e20c6925842694b5e706df33883d649efdf8978ee338572694f002fe4a99b65e5949eafef2c697bd57e865e56f398527d5d0fed9cd1a3656398a75973b5e2fd1ff78c0ca2ffd9b18654e42704682579ea3801e307a83007bde99345aa7879b0c7566625801fe7b4b940de731e206e4d347384f1a964e98bd029885c8a759da1f6601b296033e9f0bc369bc6b25c4579a798ff462c5e198022aac09b7e09137f65188f1f8f91af0559f23b61f4b58a58be9c620e26bd873d73348e7c21d3b1992ae3d46abb3c710f64b70057f24053ff5c1f8ff873a3e0b928dcbd6cb2055c30a560000a4c5ca3d9dfbccecaa3aa02dc236d42816bfa8a3afbfd293468b77f7a8a6c38d8da6f167bf282668996fa78988d8ec1f30d2c89bd0ae854ff6f8cc9291d00089b8725bfd2e4e8d1691097bbf3ebcd3aeafae36461b450fdcab43267505e064d2a79e6a29b03f849cb3906d77f6039a7ce63a29ac11eedc05fcf375b5ff78db4dc34980ca8cf4fe1ce0fc7b7f2b0ead036399facebc6c8d30e9341914473322bc7d0f51706f3133fa6d05cf470ccbdadd3845f53b22c1600b650c39e783802ee9dbd538c2fc0c2c1b1b313e2801bb209aad4ba8bf23ad6e76034294f9d0d2e150f7609fb97776f04c5ab96f59008eb4da9628b2763f51170237d62d6ef00779a2d2d02fa2ca24a39c33c03ba963250bd6f860ad8eb9c4f86d023c7a48b2f14331b1ca2e6e98ff38209e1fe6855bbf2c02e8b41b180f34c077572f777ed1422c72cf71b9355f9f4ba2e35e2e635e407c6ef17e2395011f97bd15290f27016525ee92b95fd94a1a58e61d94bf99b1493f059c4fd980c2f5cc00fd01d041fdb784a2837309eb54d0ef32c42c01dc86b28c31bcddc1e3eb7825a45ccce69e96503b8d8b8727e70a7f2d3ccd3d9f91632632e3a2248b5e9a74017212376a1a4e01cdd864f763658263a7d566e85ad13b9e9a71ab1c352db793481d5cfd4fef96dad4b5962527bf87597510a0a1d6e1ded9f0fd60712962c173cba04f4182842f2a8dbaef6826cd1562e52597b48504384267efe0914d00fa352a2a41a5e145ffd01d1b313eb5aa945b664c43a9b5a6c052b130cdeabfd9ab24e597faa6ddc8777cbe11f8bdc394fdc91936ee73e9f00f7ff3c831653ffe740d040c53eb37e04d9b632e179d9c334cf08a00edc50c138d5a8414ac494459047691ca02f42d9efd7721a3a019cd7ec96218826b3c8db11eba9f22a291b9039fd52c8ab00e361ce47f3947eb19c11b2b255cec1db8cd2a48ef1a331ea2c9ddab474ed2b4307e97f09bff76b07639025dba5800ba79fc41efa49474c9898de0e283043c76aeb83713045fc0af9431d16c352236aee3384e37dcb2a38dd20befb4c43bb8d853c609ef55071bd01f8433c7feeb154bdf8aabbe46e6dcc32da77cf2a228b25570077fc57287eecae9d562c4a31c3c7833d817a2b9c2cbfe1d3638b7b8647fdf5f9d072a67f68aa41e586eb3ffab04efae3acf7d45ef4a078b60619549b4344b816bc1d714fa4bd230d6bb5c51f2560f88db724eb75d709413ec9787fa4dced4b061c79cd3a1dd827d6c8923d538aee47360aefc0c534555fb3855b53a42da2159d35044703888b5e7af765193f7d7922dcaed9be4907bed2ddc247f184531d21c6076298e09628d61fe27c6d1ec837a7069acea2c519b49f8b3c56c2b8e7d780fcb5a63408abff2c29c018880048d5c1c3366fb57d8b9d4106ab389d53c9e96f1b44e6a4bc16d0ecf5225ef9e410e50d98feed5382136a69dc3e57fee8bffd66f8df59423843df9e12317b93a1698f654e69baf9f2646ecdaeffa90ef2b14401eb6a4a949efae8664a2959f752ca29f9c90211b156bd112cf7dcc99f87b7440aedbfbaba4017d4078ec6e8f5d34f6149142fc42aac259b9decff2f5036bf53eeb7fc2a5a3ff4aa576c3f9b309d8398728f2a7af1e0ec5ea25630dc2bfa38732e989fa4dfb0f0000fef49ae7a333261c6d66a558f674081237bdf934c65123860e477ce74c87af5574e2e63e4b062da49e70b663cb110f35578cf496244a14d701c834441bfc491ba02c9488665ef98d3d0f60153a0291d85ab931b378b643830cdea0dba6e49cceb5cb73cf6836376c090683ca0ee20da08212f90c26f56f1958e6dad8fb64a296d501786593c2b003bc061087fd29cd83e31ec18ff6f8ca5c514c7a26b13667b9dfc4720c7f8e8e91ddd9ea48da826e9e2bf900b6291e954f49f85d444859d757f4cedadc8bedc2197df34644c3665176853f2bec0eb73eb9ec81a7ada4778897fbdc2f4ec15422daa32a5bc10e600ee5c2d1b0cc2ed03357406caa0dd2cf02f81abfd115ca56dc602f5d22921c7185e71040bfe649d942c5a42efc36c359a5362606c7380b589150508a81739c48b2932b0531b36b7bd01e4824483be376169873870f24442a4f1bd38188ca6b8266a96bd8118ca148b81d8aad0c38a235fd968d58321675b724c545a32ff3016b9cfba9435c20385e87eef428e56fdb8e8cabbdf20535036e11fbb2d78e5ea91bd57eddf9e5d3f494c8db1878870cb38fe0fb03166da827476089d7cda9cbb3ebcdecf5d2a8c47496ec14bb97d3644056a0e642b988db86cd8c4719976207d148b84623be35466ddb78261ff0627f62ad92d3b5cfd1447b1f1bffdf15eee6809386e5fe3bafdea67f56c1f8724d5d82c0382259da28812808c70b022352b052a69d5f76015c7265101a15ffc03613f9c83be2591f251e56ede40c57c0cf56e094354174dca46169e9fa9a0793892b8555f82e8b7d40993f0342e72f4dd5b3fb8f3d0c902c61eea5efa6bee398b5836b077a95cc4e1f9e3e529f9a1bd65fd17936be3a1316574ab62099938489a6c0070c82ae3e3e419898f841f2418aa74660c170903e53f5691bf0be8e9832fab3067a22bb2774596956a0a771a91ab9a7bf146fa4e6b3098b595b1c1ab9e264ad7c0b514eee5117d5e1a0c54d6f7b3eb27e9978b87541b3a05347a3a38a7fda804f9bfb5ca1e4b4eb5b4d192bd1243db52d9c657f4c0594f9677c094997b69de66bebe6e868bf6e63980412dce288f996724d06733deee12f17b3061ad30c07c9d4d5ef7f9225f841b9966059ab8a3b236939ccc7abf86d16f077e0d057d9a4bda87dc80b94a5bc882d223d8dec607dd25b22b8a1cfad9806e6972d7bf16c90102ec1e86ce3ac4ee0005b01874019f7adcf28bd1c3c65e271cbd3172833c9c834e7fbf21c6ab2c7c6a60b76449deda28ad1103706233fb5996151d3b0286c9c245372c570f97f6912e21a744a5446056bad20cbae0848a1f29b102b3a3969c2ffa9077bac39062892df559184107d5d6b85ca27267912f0e1c6f1fe695dca5e18b3dad7f43fe48dac05d5a310186257c719282d542a23be7f5ff51be810eb663657fc0f9fde5f8eb739ab2bcdea63ba0dc1ac24f797d55b807d51e8d3a60b8255a89c3a70d9115811621fd427607160b12cc31e9e5c3d7c04c8e7284777eb68ba2b57ead34d3edad0cb8679f092501fddc4fa0fc11d287754065ded8649f90ff29e3c572fa14321cc5e55cde8daf0f2070fe524bdd2dfcf8bf3fb032632726c0df461de612af284509d5980152f223f6da57cc90f26c62334b696516aa3ad8154f4b7de239a436357226247735be6ab546e486630db373882a98972436d3139fb87b0c31d34d550fe3dd27c64b0d3b3c44cff4c57ead5033f927f4d33f42e93209296d65ffc9dba1fe5a5d47202b329d4a60c9258453289a1f998295d102083236420f8c75f4aefd125de4c1d332d464b90e10316ffadc6b20c4c183f69b38e07e50266e550146e1cfdcc97b16bd195049f80e82379eadcee9139bf49c8860539f8a749439a3a0f6a4203267a0d0a7e884c61c7b917fb936358459c561dfec76a7560fdb9151f67748b149f80e2424c9cce9b751e6d52e4839cb3e4c3da46dec14e9eb40137a025e410f2b3362f389ec73b1edf9d03160c1d7e2fe553fe102c2a003e99a03b75f6d2b8e699e1a88cbaabd6167cac5c02e0c9907d369a53a99e27c25c8ba28af3ad2c5b8a440d8012c092ff6cca4d5db64ba220ea6e81a2ae510cdace3f520fe6d8bedffe79ee83c5d0e46efd4ac87567c3fa7d004c9070da8f00104bca85294ef96d702c1213d636bd6d986df478443174f7783ee01b28ce33e39b27a6941e931c04203ebb8cf34cc9a57a3a52ed98ed887cad36c7d1cd1218c040082c33d472031a3d1f60cddbb62276028d1b5eb2be0e6a97cb0fdfb2b0d01d17c5a54661af77bb1ae973b3e87c513ab08b693ff7fd3654a9c4a746b0e7d418db802dd59b975788fadf3aa09f9bdbbd56ead61016f05b5fc0ccc8ac8623c4c52655bb445c42fb14ef47a2371251b286e8b61a224f1010f7b491439d8d73b3c909469e165a29c8d2a324dbc8013950f24941ac25cc769f223a701b3d065e9203ec929ff1b6a3fbf9c64a060f811665d9cb5f748b84384b89bd786e0b060e8467d4bc5646d849718322bc6e97074e9751ee0df2df35e579583ba76497bbf8bd2799efb4a69465f293a9715032626b3e0d763648a87ce6e93931b79a22288e5ec514f06e0efa09326dfb4954ee3831edcd228b461085d3c6feed7cf2b4eb688e705432ffd30148fe6a98e9d4953fa66f417d42a0d48cb97ce267426ce2cd06f62ea39ba97bd30f7033a545c8667110d9a8ce84daae95d59fb1635842e0451fc90ea04fc2b5fcd914d1bc7df59d97562732cc7d5042f8995380523eeb4ddcd39c12613d943dc7ed10c7679f25433d7adb112fb45617d945824a0f6eed780bd71aa4ff241edae613222f49bef63809425f9daffc59a6ef5e7937437cbab4b1816cabeac7a7af795f18f1f281745eb3b7c20dee1adc8bb5c5ba64458e9c788d77b6621963779ed685b678dd4d23f554189ad340af2d55559047b93f00aa144edc7ecf1187cc0476a0236b49d55b63308bf963fda157ed2ee3c8099dbf8d56e6f5166b4f4a85f56e573959d94138bf00e32f5cc311f32d141f33954c261af878f2231e587ef38cd3e40ff4f7e6a3070ea072878bd892cdeee025fad316f9978d18e1118c8ccfa0ddfaed68166b2f5f0d56ccc749f1fd681d051dbb47413583c6787374ac5c183a8a00009f2e06d489827b76253f6691d1603956355c21df1d86cfef53b8a595ae1a644f9c76f3ba419098b0923377b5af7e43e77f860f4b1cd9fbb8cb2066c223f9a6f1397207d0efc21879a6cc646ea3eef072c30b03fa1a58fb917a30665071472a9145d09081b03c4a98b21dbf25ad3bd48f2cec0c738448950b1368c3a9a67827829478f6665f3e3f3013968b2a471fc34571adb0c309d1bdd8f9bbb03d7f7aa139807d9332b4ebe509a70d64e1b9518f91b2aa1cf4a536b811e502bf8fd0c3edac534870a9e5b861d91cfee2f78f91f6de1efafaa3e32a0fcb07af814cc219929b98a0a35e84f831994ccd6d6dbc4b0df70eda1f1d51a166d5d1847810666aef107e39f372e0d11b185ad311bb0bcf6109f2324eb7049998d14ed0fb249d95254d27aec73b768627486876be7ff8b5067d36c4dbf6877624622163b594c4ad61f11feebc0a121cdac00902a67fc5a4c4f0719e22a101fd73436229e58f59b0cbac4531a0b1616a8646908c1c5ff40e54969ce038b7ef2b20f8b36537cd97896a876ca8198a0371273624867cb3218edf03cb3610e6fbc064afc0c4ec6e0b48c2d91c07cfd0ff51214e3a4bfcef4ae8b95b55f356b0669d5733cb2a2c45b771b3b644d1eb420aca6a557a2d4c0bed34d9bb06ebbf9047a3c5a19b4b782bb16e4bd6bf57c061ad7fe14e2e9ebcff3fa1337ba595978eaa697a8086764e55ad708671bf9f21d44d8c585b228a5a75a86bef61682428e94b89e118035afe6d50d056623aa9219fa97cd914e77bafbfb25144c22733f826e206297751e15ffa8412dfde2fd70d69a846fe2a8177aa723ecc0a58216065daa358a2d2a85a7edfaf8c2c1fa007b4f39b425d93456d1dad7310bb2a4e198d3f24c9d730ebd827a962b221ef407726dd47f58ea05b4e224f1c0194634918fc1b1ff7e6243665d00d3451e3a19a9cb2dcd9ec9107f3c789e9d2a44a52772ecbbfb0a700772abe08fefeef33cd5f054846b25195e293f04a09c428657ece63dd35bf919790f74de6331bb125cf5b9069e556ab58555de3dcfe81efdb4afbedd782e57485192fba976e51a70acf96236dbd38b48f98ee58a7a4956c3b62ffe6964a762c6fa903008bdd5f79269ee5b7395871d5f84fe63d57d17495bc2db0953428f706d107bbfcfb3479c82924b9616a3d9fb267a34c2da6867186a79287583f2231b610e907bde17487cd47fb74c1cea70ce6ac3c3f74c5a64d40aebab857c74e961ee8a1ee46a9079b7166f109df41a8e003530dc5a386c8d15d181b0466b6e27035d9a4664939d6a6844b1faabf3415090dc2bbb1c702d8944a20f29253eefd5ae7efcb62e017048d33f725d86cd45da784f4d6de0af2dda13a72c0d24a2eef0a0626089b5708c0320d8d25eeb0fe9c218f1f584e76424e9a7ad83ef8854ed1e147aefe4f795903f1cb9916706b3a93ce2e4412aa798a7e8cd7f538974d27ee007b14fef4c81abe7179314ee97e7f35b70ea96dbf50511079792a09fa3d793acf15a3ac886721ce97178aae0d623cf008e97f6e7b90a824d140af2c170860274d624a355423b61b3fb55e1b642258b96456f4f61cfa78ae9746b00abd2f0b5ef22004115eec19145907d68cf45c611bc51653a9e5d66fd716dea304750347b0d20b4dcb9647fd8a51acdc36d90b411b8af9b358f8123562dfaa4cb848c567b49038a2c0f07ecb26be145eee77a287dfed0733af568bc7cdbe161fdc44c178b4042a72c1eb14c9e7f219733e946812159620025d976cb1a835782938f7dd90302a255da65d0ded3d52027b01055d959227acf718af8fb0acd3330263f461e0ef88f2bd28f17563de2fe7c89b97d6441da98d098611510be98771a0eeabf41294fe338b67ef2dbf2009ec3d5491c38fab120c8b8741d6acf5d87f6960a4f2d224094a568efe16146c8d24cf4507b90b33a0dfd25749392881bc07b80f1965d9673dd6be37a076a90af1cf9672aa192b9d745a74840fb147498666953278e9dc9d8abc94d171837fe9a1a5b430224a5b7c1e91f553b53f0a2451dcf1c8e3d1e20ad4ec653db10ca82882a211c3c68f4c2a8f5323ae4b8ff3530484e40e9d9f95ce2ffb92a3e2d55d43655075c3aff915c86683b3d9940b5ed526d02e0a8e15cd5007599e33cd883a0419e36a33e7baa08ba22a80f924a5190d969f6622fe2550b061e39801690f6bfa16455337bcaf152c95d71174ff1ecf1b75bf9d7866c088b6d6ecdcb068af167fcb0fa1a1db7af103596ae53da1672ce2a65d190c4a4a70804564bd2c8af730e739c88663fc97ffedf1a270a0498ce9747a3bec60f4fa2f05edf2e41bef85485fb7688fd927f9e1e749b88bf89d6ff0f115a23e8bb489ffce3b33c6635fa1936ff1771149c167e9c10b886b26e97eb691c8d742a08fb88790ef9c9e1fc0892b2ba660eb62adac680cd9d53f7243bfdc75ebe2e0f56d53687e738dc565a6ad5139e94bf4854023b70e61bea399a6af4676e54112c23caa89b41517dffb55ad3bae2c97b9d7b44fc8a538ec018a90a7bde7a92633cc5b53c478616dff19fef7190357ea8e859dfb66fe0689b811ea506b4cf19eaa09799dd2825184b1456e7efca748bfc291847220de45c8c67d03db274dd46e32335873b607e46f027bca63c2561187296c0711decf74011956ac80f01ccc9bdb6cbdf34cd19923aec13c1e13360603a31f9e92515e15b878fae890147595f66dcaa67d328867400e87112a40c61db1ab0fdb54b0ae309daa10d7048312894e82a5fe7ef76eb40436ef040f954b9ffddce3366faecace0caebbe02e0bae2886098a4c0345d909665ef326d27dcfcbbea23eae9a23c2491eb033691bfc64f7fdc4e22e7d240fd75a61ee0316cf5ded3ac62222bac9aa9a3e3349030b67893196daaa23026451a699878e1d7c69d3e5c63195c587ecc4114e700f9f5745cafe568e2e5656348442f4d111920ee4a27fb7209c2c76803e81cc5cb3425e0770ced9f338b3bee2917e0b06f9a7813c52de642426fd3fa8903b35d96a14e4b3420adb665d28345a531b462a3a3d51dd1e2ddd2e073a9763cbe260961de6b8eeb3ba2920cbcc6669d6f213141b7493e47970e549b419593f7e8c8cb45e5b06427269fadeb38cf35a437f2e235b025b8d27ef564476109489e28cfcfe4a5be7a30373553df296b914ba8a89110e51d5a024c6f16ed8d0c7e0b186360eb3defaa6d847d21d7c42a7755ac0f481d7145d80325f824fa45ffbdfc1060f9fadf46075c0a88d02a0aa76d5ea4ccd7f55b4ca0628f9a118e2c7dd851d2284ad176521f7b6a435675eddc0c42df9224595f853d7d277c20dc7457795e6487eac380382e9c07b9016c94dbde3c3a9a63d551ecc05b0bdc8a8250882e90ed28c453972b3722f7ea6bb6d490ec5eeb67d86fc4aa7b04e933aa8c324135a95de2a0a1fca54ceaefa91b656b0c88f241d2cbc8e62f030f4eeced5347e34c862bf7c973eea99e17239d8cae861f0731f4eac13f56ce6733fe0a3c020c8549fef6d62812ab61fee7adb4e209aa3a73de3dc591a627865b47d220817594abd6a7ecdc8878ac076c3445690e6890a68b59335f8a897bc6ab7b010c3aaca9df55207fb9ff64e8b593bcbe574280fe6d174d504b7746de4568665de43f4278949d6cdf416247f2701f0fc9122114c7f692900483e4f6b66e8af4e62e1048e60693c3f8494c33b5c27c662fc0fe311c214bf990ef1bb63e44d2bf7807f2f2270dcba4e3300954eefc11bad91f86c7e77d9a9ceb0a5bfd7a357b432313b7ffaf5684645b3b055b8c0ab15ef7308ea527130fc6f9de8409a233a3f8cd659ee6fbedbe48ab8019d58d7065628e102d72efad5748d4229c0d53be559905fe5e3ea6fc563aa975de998045c33e1817588f92c12f6feaf83b7255faf39574f81eff84513679d24d0fba8919f9500dbdec0499a23f7ce0c8f0f03f45da3d8e0e58f04a56f4c958de2b3d7f2e02d9d7496db39074af18cfed5066727c13ddaf922a0bcd5b4069d42a834a47f5cd297b80660d1cc19c0f8f2ceea08b69538352266fa5061c23dc052bb29246cf7acc6e934ead7c2cda2d3afd1e91dbcf7383a60feb0849270ecd3e8a2e55f306c3d4b6c26bd450ff9580aa2cffb551b68017415124330c7f56cac523f2b21b056f46efd0d13bbf4cb57399b3a5b7b8b3b5b1e15b3de4b8dc6eb698c46046d1e96a14b38db3f740f9317406dcf7256e81e0c60c84b69445b3ec352c5411a306906614423deed419418e6675fd45c8e341d8eb4ed0a7aa645c3251f9a187d3101c07497d06409f8c5daa5cb8e84f6a4e5a5ab55213df7ec9e651eaa6841ce52171defe494878591025780da6e94de3ba5edd8f8e832ecd4e6c9374372e5a03fc65ba3a322f0deb92f2e1f3d57c99e57e34fe27b00c332070d0d0dbb23b3df1c923448c47de7e73e0e2a8cbecb93e4c1aaf683c69da5de54949b04f3d0b28867b828b9d99ce4e55993a4d8a6d208d321f930ff63df0ddf655606e59d89861cd538a82adb277806670adf0ee32ae590cf947c15928e63c798eb4c279e5078bd971b0cd7bd3666ab2f71fd610c4f37f3c68eec24213195f09873b08a6e8b4e06ba1c19329e0fa714c74d3b932829f195cf7bcd1c6de0e219e48568e7f6beaef5c81617b25cac5499502f10a36e09ce3145880bfb39f08e47b527cce327b6d2e0e523cb7c7f5c58da2b26b6e21d3e27c297dec346d7ce0df902c8c53f70b583630aad183f427bcb40ed2932abb1f0cab769a016e2c86ffd1d68af7f0e9c95718689ecd4a3a75965c0c7716391d69e7deb70949405bb538175c76f255c4928eee0216beefa8007abd7f5d92321d563937e308eea30ef0ede2f49cc0cdf615ee407bb06226b6e8e2106b9bd7f9b9216313a9c484632ee0946311ec43fdce82e33da788650ffa8af41236e3e9062a70ee019d4ceb4cb5b09a5588a1b25aa96d3f884260b142683c984b7957b096b6b7c401e54842027127e0dfa3626401086d7555018fc130cdffc9980be776a937ba975b8f0696af09965cac5f1de95bcef147d2aa3711fe1511c3f54c30f7d793273e69d021df799cac8a90a4f83e3db07e99e24699b43d636174437c3f0922e7ad3f9eb6df61b8d165a947bb6c21de7e02e406ac7dd94fc41b9fa6810321e91882bf5164f97df3dfa1be1cb1631f343d89e23275fc5c2d7f8be201e113690595702503373f07db0e51013c345740e4fedf1fb8bfe9cb1660067dd64a46d356f2eeef19b8df4eb7e781b8bab51c11810af506b5ef09c0f7f5b6bcdb71626740ad6c4652a819a728208f42760c26e95eb5ff9417ad4888591c57c9142bfd01307c48e401275d03f1d3a8bdc9c5f5d54919c303de16078ad75f2c20e1b1759f1cfc6698eb98ccae7177c696df066556929261a247bb342d2d7bf5c514940f6ac80577e6c848b69c4e997be42afbd9be6a17aa57e1009130b2b9cbff4e36e747e7ff5373ebd5969f830df483f8a28f577defca0f0802397cc264f8c7654a0202403d16eb4f2720077d34742f20343f83f5e69f100fa145b4c44157abe928e2e247637b2507501c3cdde935216dae7b6134701aa8c8870d81a61d265ab4effeeaf4442053ad8bb6780a53991980f6531e1d62845105e31b0c8eeb4ff10ce8d64d82a22b29287d79dacb76859d9cbbb906fc6f96e6494a171e90376b2e15dd34083687a3a51ef2b5c507c2d5f926336d442777f3aaadc10cc5992274636f9103ff356d9bc28471865898ccaec1bc526afab4d78ea7520a55f11f180b4d909b82834e1e22cd61b07d50b5ca706a39ddc12a7c2d14dcf02c95b4dff801489bc98829185ce28143fbfaac06d59b3c44a296fd389de1b2d70adae50c298c8b74ce0bb3f3ca6e861a564bfc468ff8ceea3f9d092ffd55eff6cd88151ab6b9c92b2e24736b2add9979420704bdfbe062bb6ab5761176181357fd0b54cc14932ab460dc49f20ba1fc35278ed610c922d20e9d71043af89cdef3b6c7bb909fc4518572a4ef7926ae4ec7db6da41b6a756b85cb3b0e0694bc74211590b89f227ca357c8a71b68113a5d81a14c87e9a99ba9f81367ded1748939cd2a1886eceeaaad79ef6e17c6d4ebdd7ca05222336b766803ca94389b39fd41aa3fd32134e0557c12ed55be7c8268fe42255699a69b17a7c11034f59d369e7d7d76c6ac0bf1fb2514d4680b3db3914ee9b47284e01888734c933573911404c34d722cba1e50db84c2d3a6481630bed1b47f6e3d8fa9b2db34d56cfc372828de50fb3b3975957cf56b78e7de16423624f2dd6ca3d0b813eab34fbf34220174bbaa43063302974435b9558996c83a2d425d9aaec2df763419a3d91298267df173f63e2037a6ac70f97d471cc4a7e1cdc295617c03e4d3c4c5bf9101bf2f9672495ea2d4ccde1b46e733ab59e65a3fdb21a439cd7aa3ab5cb94b32af03a02253f8149a800333d16672996727d4dca17725de7edce6d788511b38bca376341d17072922b1c71f3ce78be552e8290be4ee0d7a7b9accd4557912685240e246c0bf864208015efebcaf21db228ca8db3104be12f0a114d20caaba01ff8233e996ed5504ab3443b31846136a49c1e6e361ee375a0d2584f74550f6d8e5e42d6bc818f811870e245431c6daab80c333fa18dadfc8e03661fecc025e6f5edc443bfb8724174dc1a556b75a77845bd0c84a1628727360bd7b50f5a3d16f169041c5072f8d19a4f3a690c424e3c8215d8675818f0839bead400d7650000631be817a73e235471816acdb3c15ab01e75d417375427091616128b147618d97c19a33503feab8126187450de4d49f8a2897e3ecc0df76f1e4d69d252d04de53454092945b40be719f9bb614002f22bf4635c318ed3b184cc11055c7a884b78d5db494b8ebdcd50fc3db92090b2f01cec85a1d4ae90bb382fd71a70f88ce915d2e4a816cc2778380a9aaefbdf6f6fb2778b7ca75f8fe7e75a0166d6458928d7b4a4d64485fd1d592b53779dd97235813548c0bc6df11ad1a3d3625758bec44635509c514a63f6cba673cea8f992bef1942639df875f0f7de3c144c8883b583c4cbd5368bd7163a04000e47d90f574705ee8664dc9f4f95186dfb47b9d5f01a08e5055b5b6de0757160ccbf212bb2dad26df48f081f99689f75514f2838e670d327bb580caf900bcb093ccee208781d36e7a77e63dc99d643239110bcd31c55ed2662f9a8b0fd1f8c9ef8d8519fc628eed081e24425366cd457a90e28f03db673576e1a7aac4276b849487043bce1d11de97bc91a896663f4eb8e996f5064a5ce67c0216bb4e85ac08544f7f13c0f7310a667efb2153044996da4bbf08c30e48406e89423e8a4eebe6c1a794a03982bf879325680f46f626c3ff8f217d983cfab983f033f82d6b1dd12aa3ab1e67ec6f98f66cef424e20a69eea12f5fb2d76e3b647f3447fa8931c2afd49f2933d11fbc4f20911f96963636ae64f0c26993be2f2ee66e530782e5d26236a0af308b4372beeb4e8ac8a3fba0bdb3ed799ebf9b6b0f32ab887d22fe5190c496e815181b270e59788f1dcb790cbc6c92360764a40eb0920860b469273439ae24cb245bd9c51fd19fff82f8cb9049d217122e695a3948c2cce5dd29422cde73f874108077744749047b05cbed315246265b1e4ae23084dc4e1a54262604bee10f6a63768ad18c90f62a7e3208df4d609b3bcf77ec0858a20a1fddb0ba21ac643cfe70b9e3fedbb6ed7942f3ee51112aae993dd99e3b584d4ebadb902afa74e3f685e024dd8549ee0d0f3386a578aaebe2adfda3374612aa68c112b8b9437d0eef9ce212bcdf2485f7f4862f26bcda28cfd9dde612bef7097fada9171cc132678368e169e1324d4035042421c9a771aadd9c42e02eced60abe4c399a7630460cd25ee5e9435799ee9f65ddf38af22cf644e78bca9cbb0f6faa42a1f58f8361b5b35d199e1bdbfd37ad8ca330710febeb8cf025501149a20deebd2c4b83af43c857a5138a629529f088ae0cf260677525930127a62cedd206b3203c0d026c905fa288d23616f80d9631b54c619c940dfb5dd8cc81535cb9494faae0e7ab5b3e823db722b2256082f3592fbec2f5ceacca36c777964035ac5fdeec3f163673f4fca6668920a8f058856136f22fe3e4d50e37cfc7ae097d7e58c8a9a82eec289a9f7032cd9267ffc3fe60c1c317e7f29b2262ece1b026d4b1abe33af91d734e509db76b54c0387db1ca5aef29087efda30aff82a6d142d5b85be6ad9bd8a64ddc5e57d82332696ed78710a4d4593bcbfcbabcd058ed73c39c42e251a1377de10d06ce3ee02dc09bb21d7dddb924419d08f748ca64a3257f366fb7d0e4215bf78bf2eb60a9badd8f222f7bab9a0f97c58778583bf0814a26131dd995f71c767e19534e22850193dc838ec7c754dd69811ad7fd8b47544c73b41e330b62cb1e41d86cef1d0e9faf86453a4001dd26f5e143fe93512f6b012891ddd34b31c5770bd71f34ce2dc8a5097606b878721b96c80bc42478fe3c25ed3ae165dda339632739fa33d6ea66c5003cf078ef5b0d7698f576c91988c057cf2a2616137f0f2d4e06e067518bf6c03999a5efc11ae99ad2f660986af6cc39c79e0a8f9f34e4bf4302e8c0ac7b060fb0ca90f2bda209a39689ffff011f3b6149d8e0825dc46963b6dd825efbde355f5fb4e9cc9b2dfc4d79375334f3f70fca72544774606ad9fedd8baf4e22f39c6aac37b54a36857cc6f2cf0d47109e06747b6802cdf142ab12cb9d9413763eebc89dea676481ea4e390b69360ce6885fc3680fe86e5e16f4036cd203dada17d33f1b71411e27bf364428b68022de56e32fd434cae076687c60331ea3542ff764e4322a962920c70fb7f5f1d0f4c0feb3ad79a50272bed5c40688ad9c5146b3e147c5c49a788e4dfc15821e3e238a77617974c17fb3190617df6e218f02acf65e344fb312e2265b2f405f8b343391b1db2407fdff96edaf09ef3784ef4353ff52ee93b385b0f47d3a75d51a87104cac55b5d476893970908dd20a71fb3242f3b3169a7d8bd199a72b3d3deb8e4bfd58abc8ae4abdc664c2a74ad815ed2a6ec66ae9f2a0d1d3eecced174ab64d311b1d0b9df039d5fb95d3e42082c6b4946cd73c8d1941b04a90442883a51111ba950b7561be6248c8bac3b29da138c9f0d85dcc69e0ca21ded2ac613db1c22c6a94d4ca576e3e60a5eb99b889373b8586cc264c5f09de3c1365498e40a747b4de67a2e3475b2668f6fe91954581c48f91a77b6479a2fded56b7ece79fd92eb471d90b729d930df11ae4f10c471b8d2c2ba197af5f392d7aa56862d6606170a35bf045135ca7ed3642b458f3e1b9e412e655d0bdaef029f5f6623e0a07a218059206759bc9a716d9ed777cf9e4dfd5607e14a8e76bcf43e090f1fca4596b5977178437bad5c50e9a2516b4c8963b7b252d21210dacf9609018fff1477702bcc3b1f1c3d8319142dd4915f4b8fb09c3efa0206ba8b8c69971e526857f10dad0c2976b48d46f824b14ca7f32087c0a3f185b2383355efa9f3dcce614fb9f7ebf5d018e207460c27497cd00e16d21b4f87969606061330b5e7c7ad180b2e0511b8335f94c6f133dd8432ec7f7abd70ded50abf78be1393d950d03c3976c62107be0f3494ef1af52423aeb6c4cf2681fdb211d9e3a0c5ca210a79aad6a4adb14be51012704e9a72407249bdccdc6cc9927296c1969ea195a7ecc8a8e3cc323b42f6a80af94be8fcb903319d719ddaa222acac0547149d273cc30f169f86577013ae6462ca33391156a56b88ad7dfda4ff2780dbcb203ea80aa6d442b91048b9b811f48f874bec13e51d78d7cf4612c44f9f80514318a853ff5f363a33e21b9c51d166bc1967fe37914c3aea9f83580256d3c63e454efc076c6a045512f61102c968411c491b5e3e2b0f1f8e76fd5968654039eb6ab9edcbff199738f1bfc8d6edfb2ae2c1b117e73f9074e8e7b7235ab19ea948e152f3ef391da2ec6e8d637aaec3e788bf7976bac2b3f876065f180f31c1b9112c13ffc8b0f967a66236a04052f7daf97e4318fc80f0ac8acc0d15319f1b3768f7ed190ca70d68088f64c956bd2170c4fdf88b560276c3c3c57cf03911641acb6bf6fc16de34b7ff53188a1fe2b755d177c651280c423967d738b4a699b30fa072a20c3775cd050018730b1fbf9b1bc03494f663b506f82a4344dc4855f55220a3332fe13aaf7e1e16209ccf0b14a79c25542e85a081e13bd332f3b894346ee9bc71c7bb901dc1d8f71a75ffeb6c4e07ef2f15734ada5bc9286760a4312471d879d66f6605f6a8f97a56851af45dbd0b85a954689e92d18ace3c0a0f9dd34538749440108a7db00f80d6b6e922956a6f74ca55a06b8eab24700941617fdad0022f92a3776a63054b1dda8c16ca991bb7bd8498c7e6bd53906747999605f2bcb448d94cb5516f988b47b701f346257bc836e005d2688ebfed0472ff92b2993bc9e40dc194e98968110062a71f99607b86acfbc32206d5878786411e5abec350ae6c770e3f6ceddc749190eeef1357740380a6ac4776e306f632c38c3226729bc9980074dd0adefc84bfc8c27705dab0139ab58e811e8e139242feb3b8f91508e8399137aba80ca98488ba37a658e3423601ac0d8e4153fa0bbd2039aa10f99fef978e4deaf2f61361d36c8d95ede89bea969b4fba53e85aaa92f6e72a50bc65f281d6eef5ee9cbaf988a5543bbc822ed12383d58796c1e430a9e2d91f62fb1dd9f5c4e47ff2ebcf8c59db1a53559a289f394230bab21b36458a8fed2c808f2aaadf2f384c656f2701ce89ac163778961d9aa2fde9e6be2421e2442d9cc984d53a17c9188e340f8a33b1392b328ad4e2ee6d72095e40ccecc8f2390887782f88824b172d37d219fa9fd9c94f0dad105d17997fd6af03a316bd9f4ad752cb0c8cabf14a4246a9398e3900911229282bb4d6132eb67a7abb5f9f4e338db5dfeabfbe16a2454aca3b1601b5076d2594fdb145d2996da5a2bc2f5d07168fde29933f918ac85115aeabcd580f2ed8353a44824cd25471d7c73dae6b979cb9b773ee27afec993e91b9e218288eaa3db6fc3bbfebe9e3ad8d04cde52e979b02495222b18c690cbb4387dd590d20291bcb3e94d65ce3004b3ee8c1486f303ecd39684ab4513938f2b19162c4953f791ed83786364868380a37ed87f6f717c5b1b9fb2011b0f7ade085c770f87b008d8bfb6ee6b6764fa113a1b8a1bfd83e40c2bbc8362ecba6a0c46351e1b744105f530bbfa77952b8fe5a4963f5017bee143223ce61f50428d54ee37976d03a35c989fb0374ff964649ed92a4685bd141f9ca5b9c864317f5efceec1dcbc6a9258b462734c01093cc11c33938e730377a5bed019a1b91278df4f8ff9d3be160af064d099161a00285147c7a40d0de803e94c576ef580c9ded5596d14074ed9703cb96e1c3ca656eab2237e2dabf84604af0b3b9b86a05925277613fac86e5ae5d8ad0e8dca6c3f04ebc09fb142b6c974f1d1ac2c39df06c236b238ffe67565df2c33ecaec884a95f8edb7a3c295eb93b853ca0708feda2c2acaf6dd9e25582db004d981225c8dcea73ab4635e2deba3da8408e9c03d82dbfe57ef8488f08316a10ce3c39bb2c1f37164cb99f2abc84b17ec7c158bbb6b885c274739ba3a69c4a9759f234feeeee929ccba4a6122cba2aeac78064ddfa877b7564290e2f4fabca1a3068f6637978ea632434b283cea92e918084641feaef8a7dd36c8987f4d810f2e148be741705f174447918ecaf0a07594e37dfc16a802ac4dd26ee0e9ff8be0935988839b0a91387be07fa08fe5f6edda9ca1787a5f2ef7a9b71b2460859cda6f0371f4901b26ce9a1f726e6927433db589b392fdd56b197c7bf5e0e76ca243c1d6ebc94c4a776406fd9c90b17c9944260debd44ed1850c650471ecbe2b40864e5b0bb1c9b8e321b545902556e53e3f4d37ac2caecbaea05bf735b8f07f2001125607aff44f59399488664642d9986a95e3a62ce39e11ad6a9bbd103fbd5b4720f9de5290995f97a4c517edaea1d79521ae6ef97cab8ab286407dfa9923110f955a72db0f30438b7e7b3d566498596d501e0f2fedded139a3ee593075aaeb111446f5dac3841f127b70db125004825bbc9b29db94cf14457224acee856b062ef7610bb9a889b3a5a4008cd19d9efd11b1df8ad9950d94d9a11c2011de803756f5e52b6230497910e9581a8f763af347cc57c9d10f852a67529a62e8b55515c768915a926fba79245fa4bda6853f7c5b47f959ba115205159fea5d233b53488d2c94ffa31ccaa7a4744370c1c045e05cec25c2f3cb48e68b73b6c45682c6cae4b81cc2bbfbecc12f14da576cd450cbb3daa15088613e7e95360d05144bea3d57200209975d6defdb86e3dfa9f83e6d974ee77d2d44bf393d95634e5e1be72aced1f8177e323a6a92e7042e7ef6877feb8593a3c3a454ad0317eec46341a62c14f9adbda9cc52ab642aa0fb622e7738a893178182a727917daa962741798c32b630924c7222a473ef51ceb9173c4f56c16d99d17d4794c178dd9ef347b5b3a4926e9e268fbdcad86fa1f6706b822ac2e9f9b65a1fea7c4167b293eeeead3f97daca3d470adb04ad80751607078947e6df29367723696c0415b16cd50bf3fad56456b9cf52265ab97a0dde1195c9da1151f4168930748101ad0c035ed6779805aa1f53a96adca37dae835b0e41129215fb59368a1fe17b32d587376c315fb0c9c143f691528dd99112252c00cc91019f591852ba7ae6fcf8f3ca38d56a7b33bc314ddcc59c0bebbba102896407868a9e2b44613a32289065778cdbf461cba8d062607189129c4e6d339c8b9c3839975d391d9f364832c520d1240c5855bd472ec2ee3ba4a3ac1402bbab7966bbc51246ce74d601ad9d6bd1c90dfe00bc4fdebcaf5221058de113b510794a5dd22ce1667a79a11260eb3e1f52e10915fbdad85347e69d1f371d586d2e4465ed70811643091aac41b26611a018dce1eadc9f2c74c5215e5d53ff0108a9767b43d09a7427150564b56129841b7f89d88a182812175c9bef234d9bd263831c5a3b09d515a103207995549fa8cbda503511ce144b451052d2ec4139307dee6d8ab21e84064f7f1a973f077209e062e880e6ff3122888b2ef4cd2824acc4f08927e5ff316873f793387d684a3f62c9328a42bc79295b10b1eed00fd0e72e0293c641e336616d8597a41c359cf38b7f28b90ac1b4d8fd1927a090e09347c51e1bd4bcba4ece20629ab0d33a613b1d992e34ca0c9b9b947306e002c749d744149244d17f3cf290ef01dfbb83ff6d51f5b5a5ab75478de800ec91ff4202919d60e21d5a424094003ec8af717e2c34b7ab349d76fb2440e6a56874f55f73f93b3ec72e5faec5ae3a3a440b3a4957e8c7eb828a37aaa1951ed5b056c011fd25d4c27130750b7622caa23d898f78099a95390f5f01d6a2b81832f83304f7bf9a6c6e4be9d6f556c7594e42d26c8e74a8e7aa8e9e778ed91c24166cd76c4341e4a069bd9119ef0ed5888a79d24717664a0f80b594b3ee49aeb1366fdaf0834999f35cd35ed5661f1ce0500ac63b60e187877b75b4a0bdf24961e28e2163ba29f1d7727a5b4ffa0e5428f1551ddccd4cd591346597de9bf4e6fadebf43d15b22bdea0e556a12ecaf01a59d5154892d6e82b6887908a6246a959a5af24c35aa567820ed00ea84c62940fab0791cd9795e77a6b9ed9dc11bc84de7e0c187c67d4ccf087fb5385cdbe03212d4933845715b51ba507fff59f880c44f6bc68b04eef86a266a664b3f9c9a9404b63937e5363229d485df1bba65b2e59dec1aac8f6026cf90229cd438b68ac75ffa0142b6a6c21387caf04cfd5cebb6cdfbc363d5d01f3f984ae815659a86ae1c7059fc6922b1738a1b9973d71f1e50230f24c191c44997e2720f7e52445e25d089788d1cee02753e5c03854dd246edb2b82741687284ab83e9da6e280825b56fde8934c1ebca24ea52693cb1edc28a48d2a13cf037a51499a99687af951f19b6afe96ca1c9a1235d94f4cedcea4db3e44a3f94508b11219de669451b23f568d983c9f4e57fa5023c1b63d28aa4b70a8f8b3aa111958d997d3614f814cc68db2bcd84d47596f1fa56acff62caafb8510660aed1e39a3bd58aecde0ac10959ebed2012ca81a80a70e3012f272a8aa0d4b982fec3ca9e59b472d6916ba158a0785120a80584815cceaf021db4494ec69db45d5b2437514652b006f7bea5b27b5cc8c29942ef9834027db39033424b318cf7f31f33909fb4f8fdfe22a2164b628307f61b6bdedb1e2225e9b581f8af76471bdade4ce935d2c2fff892081f55fd9bdecae9ac188b99641c9060c8048a9473d30744c974bed8dc374f9717546b5cfef7180760aedfabd570bab4f12563db7244080ecee4b498fc1f7a5cd53f70b26faa844262e4f2d80382573605c67c53898b3488beef33cf8c31d2f6b0205313cedab8d29a299dbf310d1c233294025e138852fa20000000\";\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(\"Hydralet\", id)));\n    }\n\n    function _r(uint256 s, uint256 i) internal pure returns (uint256) {\n        return uint256(keccak256(abi.encodePacked(s, i)));\n    }\n\n    /// @dev HSL (h 0-359, s and l 0-100) to an rgb() string, which every SVG renderer reads.\n    function _hsl(uint256 h, uint256 s, uint256 l) internal pure returns (string memory) {\n        h %= 360;\n        int256 c = (100 - _abs(int256(2 * l) - 100)) * int256(s) * 255 / 10000;\n        int256 x = c * (60 - _abs(int256(h % 120) - 60)) / 60;\n        int256 m = int256(l) * 255 / 100 - c / 2;\n        int256 r; int256 g; int256 b;\n        if (h < 60) (r, g, b) = (c, x, 0);\n        else if (h < 120) (r, g, b) = (x, c, 0);\n        else if (h < 180) (r, g, b) = (0, c, x);\n        else if (h < 240) (r, g, b) = (0, x, c);\n        else if (h < 300) (r, g, b) = (x, 0, c);\n        else (r, g, b) = (c, 0, x);\n        return string.concat(\"rgb(\", _u(r + m), \",\", _u(g + m), \",\", _u(b + m), \")\");\n    }\n\n    function _abs(int256 v) internal pure returns (int256) {\n        return v < 0 ? -v : v;\n    }\n\n    function _u(int256 v) internal pure returns (string memory) {\n        if (v < 0) v = 0;\n        if (v > 255) v = 255;\n        return uint256(v).toString();\n    }\n\n    function _pick(string[4] memory names, uint256 r) internal pure returns (string memory) {\n        return names[r % 4];\n    }\n\n    function _T1() internal pure returns (string[4] memory) {\n        return [\"Baby hydra\", \"Baby hydra\", \"Baby hydra\", \"Baby hydra\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Gold collar\", \"Gold collar\", \"Gold collar\", \"Gold collar\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Teal rim light\", \"Teal rim light\", \"Teal rim light\", \"Teal rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Misty lagoon\", \"Misty lagoon\", \"Misty lagoon\", \"Misty lagoon\"];\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\":\"Hydralet #', id.toString(),\n            '\",\"description\":\"Hydralet is 6622 Baby three headed hydra with jade scales and a gold collar by a glowing misty lagoon. 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\":\"Hydralet\",\"description\":\"Hydralet is 6622 Baby three headed hydra with jade scales and a gold collar by a glowing misty lagoon. 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":"58051538","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T07:54:51Z","match":"exact_match","chainId":"56","address":"0x429f23778562bc4Be82c215ba12180E1FF297E8F"}