{"sources":{"Cybergentle.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: Cybergentle.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Cybergentle - 500 Friendly cyberpunk gentleman android with a top hat and glowing magenta cyan monocle visor in a rainy neon city for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 500 free pool lasts (gas only).\n/// Every other mint costs 0.00007 BNB. Max 50 per wallet, 500 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 Cybergentle is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 500;\n    uint256 public constant FREE_SUPPLY = 500;\n    uint256 public constant FREE_PER_WALLET = 2;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00007 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Cybergentle\", \"CYBERGENTLE\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646764a000057454250565038206a4a0000107c019d012a900190013ed158a54da824a3262914edf1001a096869eb6f2e239f97f1a3b9f84b006c88103d776ef473c97ee8ce7fae3d488e4ef563f16d7f4f7fd93d143d2a7a86fde3f54fe69bea03fb7fa227fb7f5c4f5a7f44bf396f58bfeebe769a6172ad6e3e32f20e8aff98f9ccef77f5be32d95b3c057c0fb17a89ff4cf48af04bf701afbd828d4f03383c164f80babfae5198966db2e3d3009ad787c9278eff2356ef99a7372a7c4c98319aa4efaf4021dc5487c15727a787b64ff6fc287cc43e08bdd51e81d48558d3cb1ef9ac416963ded551c660a601fc3e4e2cd2a8b7c86109fe8fccc56e501cce2659fc477e1c09e1b26aee00f1450c25f819f131b88448358292978b99309441a502d07ae981e96135b8ebec554fd51ad41ec390df5e26aba1b239b4540e8463cc389cfabfb36faed252d0381dc4623297614b4cfa15ff53f680724fba6e4632dc88c9a49ac41c12de8c87e3e0a429542e66abfd61c9b5f76eabfd6aaf972725c125acb86fb13c45fb28fe513bc9e9a54649688d5badf32b5f1d6c1bc1839048b4cd9683ca46e9f1b86e5aa8d764627ed0f14f448ec9fa6107a15b527457a7346426a95b7c08b277c85aa7bbf0fbbac6b1404609f89232379a1f016f576786e58face8f7b08f90a29b7b30fae1ac60a6cf3a15820e6b28f8b6dbf86cbb08d99392e157d04b99ea5d3727000c5f4b672de87bb19d9276b6c1ab20220e4c05d7c13579f72f60a3b2862440deb224cd271775e22755983dd6dc6e400199b42b640e4f8db597f7ad74746f1734b058a80b89f7d55482c5db0b1613f84a3aefe90684aeb5631120af940241269ab509df3680cad0d1a799f5df9977832040e8c556d86533ec10463b969d4664ba2b7e68d4c2b8ab906b1c3919a0bf9f255d23cebb7d73b0dd302dd4ce92c3f23c00fd97b2e76db167d669ce29b742572b1ffa5fd95347dcc6a50373ed97a857e93826c158a283cdf70835b1c469736efbdf70f4e67dbc32b43f10ece5a5b57af520bdfa637466c9d70f72fe5900162b225823731e01cf88711baf3051a14b19d983c3cd4c967232e979ee541fc0aac65754742cbe34f051862127ab78df66058d4536b85b31f533d0c08715785640fdd1c9e2887ad082a51d331aa300cbed054579184df0557868189947b54b2178f61c0e2101ceb36243c229d0519e959d45f232d08d7e1eab2e49cbe980261848eaf0f64005d529753d09dd94dee386e3fd5148ffbb124e431e0b7c92c241ce14425c78d6538950be487c6ea2fbcd1f8ac8f842ef54aa1284ed3a32c015842d1883eac3f6a8ea27dcad824ed5f39f864e00a1bf63ea43657cd846ba09c52002498d467e75aa816f445b704bbf06d69c8a1c31ef1e373a384cbb98691b8158fe71eb8c5491f45e77ff3358f1203114874f26f0f399d455574cb3ab9d009cd28381c39337f45ca0f849f63449969b2b24fc136b0aada8daf825a19f520e84c016b847a6014feff9d08a800c714d2d65f8a08a4ba1a5815d10807e8391a822205a8af746aec6a5ac3404d35c3e05dd952e4e4790057b0c23bcd4bd9e0493f0624c3a5f8efef8b99476aacbecb1c9a9df9e13f43f2dba578acac8ed79d1045439ba2f8db8ca29ae3235b144b555e09b9f8f8a0fcd7824cf056fcabd5afd8f73dfe7cde4f9991d3b8c4b1ce150e9bc3615f6c0997f6c7003b8a38619c932f9b6c4cb0cb282b0232fd20e763bd21f577d3df28fdd4c4d4f00a7d63636adc13b214ee74b07f1cf1ed9acb60d893d37b0f492c1aa9b37be17f6082d975f788d744575d1a83809fd543cd783ef4488edeac6167f5d490a2b488a58c409280737501571f0ada9599428d1dfba89349fca00a632cfa3f30cac3da391157d327dcc14d662b5dc76901fc2ac619138486753127207cfeb1dbe4b3d1594aef777d09db5fa5a3dc16838157186209600d442ad13e4011ad9204c936d0c48e4ec69eb69375a74e22e7fe13f99b1376efd5c9a8221239def26367b16ca168b3b269b15f4d1ad1f9575153bfc67caa2837cb35943c99e26a993e25d947c663961e6345c5c5a6c31bc917836189ca87689d9238bca083040601464c38983c4553c7204e0ae56cdf0d9edfa8d71dab512d3eb2c2f5e5f2ac01a745fc3e08b096835b0c7fa8d847f245e4475d7e2581291e19bad22769d9abe4c8a213aa5ef2d2ccb300965d6b66b819b074389d31de3a388ba2cee4f221ea6f192672eac3a07e8c371d6e163e251d6fefaa87b48ba86230690b591975b74dbea3725b1ac4b663b5c42dda57257afe84788d9b08dc5190bf6ae5a4b8169613545ed91da6c7675d0f29868bd1ca66798e8239e756e415b8809fc5a254b38d00463807055261537d619bdfbff3022b21a9094f72e6f200f39db3a49a2e1ba11be56fd541bbebb8a9ad30b6d87a04ba917c6f36581530b7b17fb2dee2fea60cd6d4bca5182647d93d2a3a6357cb335beb7fe25273203cca0eb8f1436a570f46f66e975c5378b551fab425753858007c34b283a0ff4b4c7bbb3a4d070722e5f9b7a926889bb9f34f737f36d7d880ba8c82e8c2ef8180fb8c2c85cf4b2ca378658993a28132d7847cc1df0f6cd90ba134a3da06ea3ade96effdf500e5d29b8ae36832e8e8141abe9c74bb76623e2ab9e1fc6ad0e56ef58c140d5aa40fc58bc2d4b4616a5e1c42913839c64d4186b83f690590a1902dea64f333315bed10db6fbfe0e21e53559b04a3a35b3551b2ed4c6f2bc5ffae6a28b35b89181eaed670b17d3819507f362d4eca61cf5afb7f51033b1b8056e43c42eba8262ef2804a58e377aed1f82bf03e5408bcfe628141b883df0db37d18928dd81ec7fd407d0eb822e0621dba25a95ae4f4a4bb20b95dd07fca86cff0b6cf1e6c0170ab51fe3cc6156416b112620bb9bcf79b5ef3fa39a77f2890792cc18553eb0c9a99b3f306829b8f5ec3db1d024f3f0983eff2bdc86b562f2afe1750301173c4cbb196fae29fc288e390e4f10662d608cdb4aded3f2142ff869415e0984f6fa221826301e248c73a79b2e078423d200072e41dd791fd5620cd75142cfa81c90ceb6e01fcc566bc89ec26c9d16837c9b321bb43e016bb2b37609467a434490b4c75fef6adb1b2206db2001e1169b4a7c3417b0d09024171f02332ca6481ee2d93ff3d973bf209f46ff448d96ced33bfe81cdf3fd70323a59448bbc6faf53bd75d54e4005715302f4b0f9cfe89f400d9651ea14cbcc456215f524c0510086b3b07c1ea74130f2bec88f5b2b9d84cc2a04af62c67362043b2e299526d4e8963af45cb6c8c288256bdd3dc91dc8f425dce0e19fe247d73e80218770fff3657896f966787e89141c30becab143db991a04127e2cd86b9f5c10db44c4dcb30694b29fc02b35f4120cb7360f69f10011fd4b274a12d9e81dafc4e059f31cb82cf36b8de9aaf4677e77cac167b4b6a1072bbd1719e7d639b3be76013c6d53f4647973484cc913d0063e31b00d3ac68ea1ca0308fe94e669ed301a18dde5266df818676854a4afad9ad578df17d40a81fe35f2f567d679441df57d0d1e17afad2bfb2a3e9d49746eaebf77c17b6bcb2df614652c4582622556ef9d0274e6697b3544820992670897c538a6a1d50b53a8dd5e49f8f0ba7347a6cb5e0e7b50445e2ac1761617ec8a8b6bda5039de445ce28ed02cc7a1ccab83139d643abea7919d9343bd90f78ecd35fe9ec4fc8476db2ab3cff46f1f08bf3943db4cf1bc0e6ef026c4879285c3b5d7e5357635a84a4b1c83419e6bb8553a0b93917c834b5758e239d953da57aae92e6301c5729b18b7587e96bb21df125516f8c2631eeb4bc0faffaecfb6eabdcecc33d206f737d019581d1e3e29367ddbe6b7b3721db7ffe9aa74c5b84c70c722044f505babe644652a6ee9f942891dc4ad309968ab8cf88db9bef0828478cc4d4e18c23b675e42c2fbbf04b75a558fa92967de13ac266e1e541f5e876f199b31f27aad7266ab537099aeaf616a3800d6cd1b162ccb0dd9516ccfb2f8cf7e1be1783ff61abcb27c478ff9535df2257fd06752bf2ad2e05a6cdffb23dc42ed9e86724dd8748107d43c3729b644049ef56a0376d750678c0acf957b1565b5927402087e3660e900d8cb281f1efb59d8f609f03909ea53bf799324a6130446c2c0cb6bbd2cc6928b36fbb102afdc67e3415e2271fc04b9d939fa74999346d982348490859391550d904ed0c40caa81676e45a13ddd7297bdfa7d0fcda12337fa23de01f26b72daac03f6ef0d5f671130200bf87009dd500cd073c9190000feeb9d0714a73fa1e940422ec4ee87a1b0ced0f05f90d5441292f73d5f76a7b96da8d59e965659055e6021593e07386c342001215a0887860567dfde0c670f1613f08f07e51de8539110097110db0511e2ae52bfadac41e1df12ab83b7d651c9065d5fcf5299bdaf374328c02839a9ceef445e7751c2b5ca44ee334fbfb4f5e5639c5cc5f8836816947d4372edf66cc9b17b87542ae3ce969a9885121d8db9ce4709230ffabfbbd37f6fd9140683ac171149dd6f660daad870553967cdc448b2ebbd14f57ed473a9836b59d607fb9f93236f82b10ad394aab479d5677871f318c27620d298009264661dfab04010f875c20241735dc2cfca9db94d44ae1a4f6282da9da1e8786ea3d5184213e0f4a8745bfe2bb9d2eb912c02b171108e8b080e4ea2c313d2116844ed0a135957458df6851f7071daf68afbdbdfa90b0c4121f9b6889ba1dd19fcd600051d2e8dde1e6a33ff63d53b0aad2e8dcca440815aeafb67c4835efcb827f088826d9f578a6241af3ebf4fc5821ae8b1524cdbae26b5b2fe6ea9628fb0a3dca0104510af4ccd2be280819f065bf622d23963ce3a6f70d319596ac08d1770f764bffb3f60f93518ffb4cf6ec4fe09f71d274bb6f034a1797fc67ef096b66717e75d8f7361f1f06be178f754b22ac7c5bf29ebe53c8fc5daa164ec2df444c7862936dd2ac7cb64773d4a8a79dc0c6b3c9611754d862586464ec3b10b1dff60374278d11e7ce17524045c27b9d42611976f17351fef9f7501b446050661ffe2ac742ca078c20f238baa5ebb1d11821553cc34c0190eb1c9ad05b9abf1490e81b58d64de8ea7ccbe491c05df72011b7b29ab783a22a836622b0d7e34cdb3000f6e557e691e03a2f36ea4c6cc769af2b90e2dc0bc5241461f8476b8d84f0bfeaa5d6f0f16630a7626a3f858e7d4e83bcf4fa4843942d2cece4471c9cd5f0b283f4a65535ead0e813c6b02c83d2260f3eebb8a98be8c460322cf8ea1481c9186564592a2ae9391a5c2c1f4eac38b0cba54849a453e40de792d99235b74a4655cd1cf2f27054111eb6746fd565e147e438848524ae3aec4bf9095fbb1fd05c28a39ea3fd9f2cead7660b02f709a0f115b1f15e53f62940492225c01df79b2da76698cc4d46cff1a75d29199c9e91e71a6fc3cd6a83e1cf124604ee90a856963488016dd377762361fbc515a59af2c45576c65a683e315981cb6947760352439fbb5b3a61f67ab8d8f9e50207bd108a99dbcbb39c406cdbfc92d2299616e412ad5b27bf52ad8d9b19f0249609c3357e710e0ef78b068c578545a46f3252702d91577e04deb4dc630f9e955d595d85a84e0dd09408592aaaf39a0504736690c15fd9befd92f7567987a04ba8a6c48cd78882b2c58e132485750611436e178460bc6dffcfffed5448f439c30f2f3dc84a3102b680ce64a69e266c917caecaa5770c4cf6832689ba8b7d0abfea3cbfbe122971282f960b5ff1ca201b27b01d1c46693b99867abdcba35d230eb9f36ca664ffd2d7b318d9f5ae79683c094c7269a9f6ec02ef713d706eccfb00072e6766e4e15f6b7f30c32fb120e8125299f991cad0d131e3405a1ee723df77d806a240ca2cbc93722380b5145b31f8221e33765130c8ee69d6de762d239f601b95fcc8c809beee73a3cc238013c26c1d82ad6fdcad995500b608d5f334085100436012feb12fb50ef36890ae420fb1409decc9c776d4000d31c8667eaf003e638076e46309d8d366aa2d27631b760c4fe40aa2e4564c4530ca07b72b8d590acac198a0cf44128f112c8e6727437865350c85d4af92eeda7ec87e315fa06a3f04d2f6aa148ed391c585368f2abd9dbecf3f261c4990e0788aa7e404d830bffb58d85dd034995db75319cd808fb386f30e7a829fdb7a7daa22c03d2682d7eb7e24e2ee05a7caa73406b97d27c54bdb0347ac916b465032c3d1901b9cab953980234900d526706aad7c1fd7b3bc4ff80945ffaba99477d813dde11d7c4ea84a5902bdb2e079809f114a871be3a320151f83fa28c9d370fbeccd0b06d75e8157605124f7787d611970910b3d8146a97aaa9b1d928e6ceb498688d3cf1fcdbbd9742b8b97c9792ae6fa0f01078b240079bdd731901bedcb74ee15dbf39ef81d3b6d0dd71a758df82196c7da3cc162280bb6e855c7393e1248044fdefe3f90a6cf60f04130a15ad9de394d2ad61f7cb400385bf3bf190fefd53bfd50142ee118a780957e9e177d9ef8328ef47acbe5207c621b4c2b20ab5fba85c348b4dbfd8ab096f4caeed6cecc00ac2f1dd8d12e263017616727514ae031d1cc38159b65a1cd0b0012b408563626b29f62192e834eed508f703aec8ddae2613ee16bee9b63307074586f7a8f74e51bb94c9ff37e790375681f849744fb2cd47fd3d656d1e01658d24c3edc38532539c13a775137fa0d75a5e364d48591a084ea20b85c577e8c60187b102a857411287ef16909b06387996812e68e66b20330c075c243701b6ba8b334d6a1a520f14f422df5abea6fb33f3952834eb9d3a86165eb2a1da307e1b37f2af6413fb1a9ebcf65ace565379c2840eff4c7ba911d9538db59ab9cbe6b6fb8deb529ed2089928eed352f01eeedab5a6ad95bff05fc01ee9ae94493040b2ce1e49f4d831c0fd45a203091ee06db64b31e727cd799760b55e1f1895ffb5a5cfd52ccc333e8e162e8f97fc71aa594ec19d4fc7cb9cb348edfc8d353a8f54c54462aab2b3bd7a0f9beb4b4a6f28246c11c600b26eb392a6928b176f50019c7e314516a27427a73a780c682b521d2ee8dcaf5316f9fe06675c178b9e7a1d98499be276b05c0b714b71a34c7f84c3718eea97baf03923869ebcfadaba26e0e892a473210bcd5ae142dc2261b3d07f6390ba5021fa771064946feb69422e148a3b942140a33a7d5c921195924a9de5d501d31559c3edb1867e2a25336276181e985a05cc326bba3b241af6df86f80ba8ae2806a07b97403d4a2f674b40c46282b7f5e223ffa38cc72594699fd76bc48385f03dcb85e879f9288391105e5e05b72e48d6c44a6ad8e17cd4d45da4a862f770e185c10bfd3286de977c9bee77fada29ddd05485c83d493df41909b98fee7dc628e8eacc4b460a285c97af8afda70160de4ece7cf3f60af08d8b109d5b193e3ff33de50f1ab1b033a88009bda545febd22cb9324872dc3ff4c3517ec718982f38a71a2dafdac16571058b07a72fc477013ea9238eeaea31b835abbdc9e694880b9581f18e390f36e65b648e80e583c29f73322025b81a0bbac487dae2e8b0903c587f1f0043d9a75bca7ef287911d481b0777ff4ead44b91e7d66e9f93bdee479aae84dfe48695bb89bb7b967899708894c7070123b68ac61e5c50d8b903a8700ca675ad7e95bc5ca25cb57ba1820307968e6b43813f27b732d97a9732e4de4baec564d9f2b740d35a43838eb9c64b4c696df3dd20535386eeaa5a4d6eea9cb009d541e731b3d63a84c4478bce0a5ef540b8787641406e4fd2a9a663f9d7b99fccc1b867a71eee54d3f49df6d993d3f72d252f294516b288c3214d359e3158adde9090477e40c82383f796ea8a1b4e149883d9776d41bb15b91104c40c21948c6f8b80c3f900225f762f99fd8115ad531d14448592fd38aa092f030cc464e5d322e51aa3840f83a07ac80e9da808bdadf0f0f0f1762fcb34338847e6e30b95c6fa41d0ce4429a3e2508aedd665be94f0377bba9f50375d5698b44932335b8568c93276e2aa76451ec3315cfe931fb79c6e779f61264d263446e939049648ea555fa2609f6c80df8b161565128fdf06fe32fda2c6fe807acb92d358417f662cb73f817e6c9edc6580fb8138bf49cee7a4787f40ab4efe5f6bb76cc53d5d5e58bdfeb7852c2093eee93b72adaa2df0055e240350fa927015278410045e837bd90a4d6cd80ea914f0f8f7bb54bd97e808bcc469873c3109fec916cdb0fddb4ec079183fc895026bca43ef7c43aeb8a29d741d1b13ac8dd7bd166ac12111b82fc4163028c907844a8644411f6b8e21da46cebc07f8ee505f7ac1dfd6d57e4ab0ab2eb7a1efbc8ad22dc4496fbf472a73c4614ce36a9fe0f169f3050de40f4fe4309921056f828cfd642a75d795821293dcc1a7354df220e6d4f1451be5d25db126ccfe466a652382e11371c2e9ad81e8ef2c5a23329c1c5273f56c2f4a561765d8c02ffb2ead436b8216da450d438c400b92c5e026cb44933acbe18b0e463fcf9694dbe1cfb027d6ef5e4295c02fdbb0d5f2cdc176ebae0f3f9bdbfb10699c3bade3d16396652af05cd89083e3b9be50d2f78c9ad482b9eddd7189883006bd166f1251c2207c90bac070d8498d403fcde3328d1b47a9614b8d8478e20b09473d72c258064b3143e6ccb59bb462ca3a926d71ed8b47e238fcb6f5fd0e17ca71fb7d480fdee4ce00483e1c1ae171d3515267cec0a021fa98b0ffd8646acc3316539550d3ce2c504e088ccb239c434a5d36f27eba8dba03c09bb90a450f2cf0d506a7901986f108a69f5e66218ca1ebf47138aa6f3dcd2007d168beca31d83a14797d08434f3be322e675300a40f3c8abba85f97785007120ecdd53b309ae5d5b0a003aab3051099df094901f73d3de76e141ab8cfa8a525b8dcfaafe0deaff2778e6f5fd27316171545d69cf5f042b9937cf4c225a4ff4f99700e986cea3184691b6490063a7ae9eecb7430c14e92540db17e1f3511a4f04723c37991663ab9b7400d31c9dd5283ac607227eb32c53fe004126fa9b3cdd52a78bc1de1d1900be7b28ef9f4ce1c879e8fda6a9d4398cf137be0b122dec2cc4c6170c8a84f00e5407635690b555c657adf1e73153d30b8cdb19108c50e85dbc1b04ccfa811077e2ac7debefbfab5b28c47dce74aeec9dffb171972e864468446a9509782608ffcee96bd2baab2d147bea397ef11382b479db14106c171fead83f49a6097af30d7a76922e74c0687f72ba498bf8e4326089eb85f51f57a6f956b7b97fb410d24357a10ffc18b9b85746a091a361ae9a22b943d169f20158e5e3d6b4153ef2ad99164010931f6113f12be0bcf2557286ec5472c95e5bebbf26d872a20458a4dcaabd5b72e26fc94dfe515690236a9d321fb7caa852bb91d8c5337ae98e5d8dd187a4011d7253f9fd4bc5d481ddb66ea37e43707b54a761327cf336b4ec6cc18f256b561dfeb9da2155479b15ed0083ff82f607be1cbf8d5da8e8cba051a43900a62d37377df1e3976b7c82d81c3eae8538515b038c7b1cdc142553b8de51ded252bb8ef588f53ce5b4003e29f8b726ee90992246a7141eb31cfd1c67c205ccffbe0f10f3c5c3e5e68de2e2ab4d16191e0be7f3d41127cbc115b2ab6267761a1b514d5b56d30face5bedbd43c8ad9e719f46e672e4d8ddeb446a51d328a59d0ccdf05ec248db6562eb427ac2f480aef403eed619ed5aaf7ac502b7b5981615c4523a80d6c781e731ef4787c777d4273962256a7de829e4e16797a64b37cbc2bd7fbb80ac640e70e743d7f21b9b0b1bdd3e7c97d3b72cf52b3255f00284a5fb6386cb385e3012a043e908c5286176f36d00641be8b6136256eb4e0490ae9c27cfd939c5b243aaf5faa0d83045aacec51d5fa4d1704cc535f29ea9d8823eaeebbda2ee172922fca5d3e612460059bfb3f512e1326f39a613f8c41eca2fc2653e656c612b7a3fe307246c0b932c02758d7bfb29255f340a99958035cab6d2d472bef59cd6224e6eb4c7bbaeb11bf2c7db8695884d33d28beb0ade454a6ea6ba0e8ae266ab86f6a4599625cefef018a64debc03fb15a550303a36d81978b2c8d2c30a750b3eb23488153ed022a689562900c8108c430045b40da3852271400915f7b18c6a33737e52139a5a194e6f107986b358dbf5fa531fa7cf2f0ddfd43ceff9fbc894a99ab25c8d6b25972e5faea3acf5eccc37f4b5d6a2f89cd48ccf9d9a3a1665be09ebbc5c7fbbfed0aa283f29840304d954e69d4fd66610676b032c9f74c261b7dbb61a74c7e70aee667156524cabe7f71dc00738c53614a125c8df8a28a28a8bb8d63ec2a5811380ed9f6574d6fec8f9bc7ac4bbe8f084c62d0b54c55e051744fb8f63bfeff31a518ec11dd7f39a10a80796ff2a23c7e088ad5b58be38660747ef8c402c9d11a0386938a2533c1b2a90946b8c7085ea1eb1d852273b3a25848523ee4be87f460c87e166e1d5aafe0278d459327d3dfa190fd78549462abbca07e3e55d86c48eed1cb3dbce607226cf2eed1ebeaf0b9cd7f3d72db6adc07e0c1a330fc0a3414e3255436d7e84759d225eaa3055c9992d3ee00b0f83f335b8cb2fa3e4b26981a3ecde7c78812d02f8cd71e78416dfae985faddec3231bce1ffb7278dc5358dcf90dd14de8cd13f467d3fee83073b9121ee30fbe0b8cba39d410375ef543c14c77114e97f659b7d8a229e711f21b1bda2ee18194c74dcb4635bd4956613a0f47b95065243a3433dbd56f2143ce1225de8e25274ec5682255bea3daf8090bfa8c38037e8662b76bda27fa28274ca40aee61d6a8f0e8f81534be03cb525fcbf46c6412ea0f4b0c04702e264efb53a3f1f6dd5eb12448f87193d34a9766d197a2ffe661cb5e678cd2985b1f78f0ade2b7e6437131021d4e000817acd85c8dd17c0d7b230934dcae2bd24d1aba8a440a4a65b70441e25988a8aea5c15be4532d11354625d9c1573b31b85ad7f99f13b03161f7547b48497ac3f5a3ce9eddcc0d2fdc9748261e03cfc6c10092c94e5f3a26d621532e5a78b93cbc50d9fa710a2c6a0a5afedcc5da4895616e1200ff39d0c22b21fb34e0f6a2994def606ef425f50f4aab77ab99a2769f67b77456b591ae91c3a73149dbe664c147c64724d1e08a8205fb41b2d283d6950f436e4b1546844bafa8221aca7502a56a7f26be41630bd9be865ebeffb1b82a3c35c005ed5aa9fc8e52acdeb11e36374a69250f9b9ad73b912e79af42dfeeb9ef29e36dc55da0eb705f69d19052730712ed43aa7916c09ccc1e476ed2c8cefaea0fec4461f8c6dcee5c9d7b5b187f3d9dac139bba0999c023a49b1c314a20f47044e74d3c71553c5c28c9aa5eecccb9a05837fefae11ec31d265cc762e3702b4e728d6adf7e6fae1acb0d78fb7d6b3b63b5ae9e22284c984eb04e148a7a51ee1c7d4a0e4e0636f6c258eff7dce23cce91d0fcaeb1702d3561ad64c088c64d6d83e0aee4b352990ed0546be4b1b2139a1f2592970a4c53fc434ad70efe4e2ceb117b9627cdce00297172064a96b6037dee8f6bd86de085897fe0a7f4b3181f3f0ecf53fcf30ebf0b761cabe47382a290ca1d10c58600f1a34bc403f423f83d999fec6d506539bc8bca7e545629e8c1ffb640e5578e2793d03b1bbdc2e469226b463b2d1312f464d691a063c1ceeaff3b06db7ffa89e4dae826deaef05c09e3f64ac350c02c464bef0d076c3a2a5a2bfc1acc255e0f4bd551d7cf6ae1261f4c778644fb09e89aea59526844550ed8d30bbaa4dc34c9304aeedeab8ecb4ee977d35e31bd450835d5d975c4d9252ad043a2443d016df50c27d0c231688b1e8fb055c77320e625316d68a9eaaabd09fc32d2be40bec20636191cca7fb10f63bed79c466b8808725e13b985dec3fc9618f3bca033fabcbfc25ad9b7febf2563ab10f887fb9949eaafd613cf9b864b94cf3ea8b332d5e1ec6acf641c5f2640d08ba42b6a1e7989f2d347471d3331ce4bfc034779f200e1b0608cbf2d20a8eff17b472b479c42707cb1b1a1d42a1a4257f354e751e7dade2d780f041644c41d596899d20276addf0cb7d09c89cf18d6cbbef48cad86135c81ea062705dab7b31098d083eaa7d2196b2c0ac8a2454d2ab759fe75c8585f18678923118d979dd5cb4767828bd531f13f34cea2a70475187470aa0dc071b14e822f8ff2696b17f19bf862aeae72cd15b184d970b3e1bd4c8deb73bc331edf5b71bc210ec80141ffad828ed49334ab799e9a40b6c75e55c61f909907d85aa1ab9b686acae8db5b005b72bfbff3263cb92db037c551d1c20857c7e7b403c67799e87f67308bb19ed2ede13049e2d8685b0d371026707ec84327998589bc923062b41f80be5f2babad84ab99323d251d02d294fd2c97a3945b25bc27e3eae93a092f6605ba43d9f8c8f9315796f5357a027ce876b4c0335fe3fb3a469b2f13568e2090118402f9d775e3e6e84c5c555e70eabc46b8b1da1582cb82d5d82643993ee49d925239125ca3ef25386d07bebb55aa5075b53df21db7b8449ed5709e18bff265dbb4cad796f9f80fb3eeb70ed236832a8b015efa25e2147563e4b44de4838432ccda53126582a45caefb74c3ca29a88184a4d01661c65820469e4c594116d993927d42a8ef229e31509362c01330a68a8fa8aa8f7872d9d1aec82679175dc64d94341979d9797744fe35a344d59d5ea69c5d9618f30960c93df9d586560b5783f30f99ff3ae9ab85e6787622cba3bc0bf07ac4e40e974a3c1f7ad3c9d8ce5e2f8b61dd349116ee20776ea6b6861ab0b0f09d3ff4e44d8aff590ee2eb7cfd041acd7063c31bca762d3438ffaf0151235e8605afc2cd186311d1e22cb45e21ebdf842a8f9f0d2203e54f1992bcb546e06438a76aa804cc61b0e9762921e6d1c39dd787e2b2da708d1ad817e8510f49ab95fa85562ddfb47494aeac39e07c339b22d18f147e792022354703f4c76c7007b0f680509ee95aa10f7ed1cb2879392f5a26976817a9b397105fffd2eabd5a75c105aa39703d19d9b33b0dbfc40828bf99188463b0009ecd26e71d3704e1558246385fdb91255fa3040bfe948ef566259bb756201a67fed99ab50a3a1b741d69e2ca5f30ac3395cb5daeea4b08f7807306f706b3c211812d466ef2185533ac38f91ea72066007b16cbed1c911fa59808d4d8580f8aff32e9af78e03527b4e964c84fe693c81ae8cd1fdb9ff3ee65af9b5f9150e5bb608fb789fd4b675fb7dd2e71d471dc5a881f826187d7c89bf83343b0e6fa594d7e0a709c9a0143e51658ab334890ba3ac21b8b6609501dc2d07654ca4f2fa8740a6f482791951e29b90c47d119823ab83e648f4edee9da9d9550e474d030bd5a19c201546ecbc5bd066e5a27e29639f1b49c5bb39668264f3944bda80e3646d98768c377eb8aa01048dbc727e0911b1082eddc34c22169aba0cba5cc70c4a858017fba9b5fd427e69bc51977f385231e4665c11e05e6ba55c4bbacbbe90db4bc42a11d5ffd3ef4f811d703b3f9b4ef0e68ac552320a9e8544c3341c029c61c4a1da9ed27c77c6607ad8031e6f58a180bbc31a13e3478df4d452aad5e067cb4d8094cd3da2f36dd0d8159f4a72f55cfb514a408d0b5f89411080f6eb9d720b6556d54fd95b1f3fe1bc45c74485fc7453128ec0552eeb20495f59e5e5507c71c57abcae369eb23eadd7279f6d4f452c4cda6029a84d71e9c5e47ff66e9575c0576a231bf515336b3e80d30edb6e2685ca133438a68ba04ff67d9df47ea57b64d4fd27b0bd95c02e204ca5a2c977ee637df02dd4973077fb69150073f3825ce01f2c9f8b3b1d3c2f1a38efed0ead92743c72fb77947294be14136b28c989a0f370350607bff2a8a1dfde54a6b64da1f4bcc2528a957f92e0903e980d02959f427df6e9e8f24cadf8379c8ae7ac8228ad5489fb470a030f91d997afadc1e985df71eaa05af64a48cc5f256cce0ea86171be2436a9f1a402c648c759edd3d8264d012c5c9e496ee771f5ce5ddc181d3637ae91267ce9d05204d6e388c8213c798d6a3ad653c99e06425ab05430aede41b32548120a0306395839b7a80c73179234f8f0a11294c1600513089df9ad99ec58dcba0e242e7bca288664fe557ef8ee0ab9f56cfb097e0a785128a4811685adfbd783344b2a33fdae5b3168d99321974502bcf46f0f29fe386213d94b0d485d64449b8c0f4376ac269d75a04c0886ef615c447d16de546b9b3bf8f7e1c09a6480612d0c062224db95dcd45b3710ee239d0625650939217de77077db0c59915b475d4d854986dbc0b3563d26a4723676934cf8f1477b3d59e0322eecb8ac3585e0716ed2015c4a944262350080522679ebd9e3c4426a9c99b9e971b2655494a54ceef84be8420e4f49df36e0c000651a0d4dfd523b80ff66bfdbf66f0111e928a069f96e8143386fa701ed0b2a3e51f6a679fa86ab5d36c09aeae6bc8c9da176c13f349db1a9fbe7324ed194b500391451757059ffe5f798dae25f10ff9660326d3c8d6b01f9d509b1a6f4259cb711269ea0c9b1c06be757b5727100c1d2c45b5c32b4138d2108acd1342c8fe6b14412980488cbb743635327b4780490ac1affc4afed70aa52ad9b97f0ecbf6acdf3c848a053b8981573c15a74db8e342a410b9b22716c787fdfc0aaf6c736ad3b97c6a96d717f7a8f05fc57e0fea0fe6dfe809aa1182a13e82f2e29b8ab85846b2fe1efd6d67869433070375d60546fa983144be9b8b5f7d433606d0e63841a4cc1d2283f7d8ac915360acd45b5912c7c2a6c757089418df971a4dc32ff11116a0d20baec8e0b43a4118159e19a23c1ca95fc92bce8506b52f9d831fc5d1fd952365a08cf3023c7d1ed70ef83929656bd06b75d5d480c73280ff22d19266c9bfc067704ec12d4f9ddb9fb86694204c5d065b42ab2ebe54c3bd0b471aee81cd873b7abebd1ffcf8df69659dad32ecc46d80ff31d66b02a2013bea3cbdda7209bb2c5eae1c610b71d3392e1fbc8e59e10cb196cc7272ee68ec966654789edc4a42ea16b269dda0575bdfa25cb0ec7bd8cfbc0ffc140cf7b1a207d41f3ee271b45ec94ea3f8d9da98497b3fc75f1960c833025e07568e1ff60adf76c8b4f476674fbe79e3d87770895a969e4dbbccfdf127d763b3eec30203dcda7ca14882c53ad74f4799a3d39c9a795f34d3a4c0e36045c1fef58013bbf90f503539be3ac9c6f7d9f0663ac2408fd419337444bd3fffab967c12a7a9e135b98fb0378ce72c4f3f9d1164bbad790023c5ac621ec873b108ab7cdbb856137b4b59d1ac8d8023a1a07f2340d5baf619bd0b96283fc01511fc7e65ed1334295c3494fcb338e2552085737fe14927b5455dc6cbf58e49bcd5d72dd8d0b3e27ecb084cb0ff0788e77c678d69b06278f85c864b31a30c9bd3e6d0fc1ccb66a86a2ec5000f60bc88bbfea046f00df79045aa802f11ca5e2cd9deb9eaf3e0d499179637d1a2aaed45bbb042ab8c2b9f92c484cd6c10c834f9309d05eab5b06639ecb1aecc867412fcc40fdafb1c451a9a46866ad36c186ddbb0dd4b35500b6926ebbbd4cc8f7550aba2d42b036cd5e2451edb0a6e3e068d736f5d3675ad9e7f19697a63fc6628a08a7b28e010a6f73e7ae10bb356dc3ecf15195c7744f613fca68eb27ae8dc71c3711e9cc6bd67b9ef6eb5414d73a157a792fef8105e3eb85a16f6c8d97ea0e3b48f8e51794d1cd473e6c279b607ed273cad134a96aae8a74be62d19975891ba68c41f07f03c999e290c9625997da24860506ad2f9854ed6867da2da3a50c016229804df653b71286f0ab6164587d995451d83cc3856c690bd447a8996ebf37c4bb1709c872b7c8e842e2a044443ac3006fdc35a9478dc4d6773c9406d16c6043f1b1ca3a006ed054e06c33339955d59dd8b2dafd411481bbbfd85d78b64b520be063901dcd91b09fbd2c0b2a26ee286e83733ec4e5afc9325d173db33ff351b3858deb0a825db2842f7d672f01d1d31f5a52d15691395b9b78d3c6575ceacc9a5deca2cba5087a1ec605fc92e02270ba1fa3afd64441fe2cfd25846fb10db8fcd3b63f980234a55196ed8b882f41a84bba5fca15afbd0b2c36d5df56e02a5f6127f4ae893c7cd0c0b3845abca39a75c9acdb726d420f6f48d444a6e24c754f058b9b33e4a977b78f0b97b974d1485b7b3cd05d34f133650aa3d4d07a906b45d09f2bca416d9c894e3d4b7fd9dffe6486aedcb84e6fee0f1f7756603c920381a59379973f67c6a2a7eb4018da7fcfc2df3895a63cf87095674f14290c678312e695b47d8c58fb62d0f4b54d22218959a458f534e9465cb8ab763a0a7f1bf463f0e479a3f5619141f6f6984409347516c25774b3ba645223bce9fc0261f1f166289fe3b3b99a079dad4a382569a4207a320a6c0d563ba57320e1feea5fac02ab5a8b2995665f971d007e22fd619bc4b6058a84ada007b1c6ab47cd556341ca8675b0f487e733f832cc0e1fc597e81f2596075d2a6ee0d0c72022893377011e506c45fd636add45bd162a02e6ca195447276236b6264865591ed6d35386df75ba05ca7b6bd46a7924ad55ee9382289f3ec46065ba0ba96ea57dc296992e00cbbfca5f5bb0dcd1032dac31ef2091c1611a7d5e5133ede8c4b0554ae0b246c47434059c8f5914f967601e6dee4b19b61e00ef8cf41e5f7c76b4de348af8092414ce891b58bbc57f8fcd2fd465c184061eee4012c44f7e39c7fcd9034a9f738247ca4a666155bd1cf853114fb19232a88719d70759ffbe36d64f487aeb7632b1dab3217883af82bd8f17de77e0a1e3149c55f9362cdf6bdee65f8516abd09f0c4b874dce02241abcd997ddf352b8ce5fb0ae66c601acf27a482f70e3155d329946c3b49567ebd942eefb0dc2d0722b18bbc7d7b7b4c595bc5e0fe602eb7d29d5c4c6613e2dbbbb12611f9de986d421882e4139f5e94b584c9dcd8da7a7a305d0ef9f8d1a69719655cb3df3252b6d66c91c15a4ffe925c39ab4a31a648a04e1d52e897e9a93fa7a09720838d95b836157c1a5e63f717acd2562274ada4bcaf0a02f9c214fc90c3bce1b93681a861464294b2cd314d8de087410bdbe4932d2c721e038bc4a26705449236faa2e556974bfa18fb962a4dbe7239b119e51f5675b5bcff0c55ad8078dea6b8c9c181ebe017292af999961757e754920e442df416ad1b54c908b4ac0f3c09e00d788a5ef6923baddc1307f544bf7cf08e7cfe78379112ad1b1b637ac41307c80c2b7d250ef2a6fe809705a78fe63873bf82ffbe893974d99c582c4fff492766dff865b3636c89b70e1d1a7b5d413599687226c5af8a2793439ad4e289968a522df94bbd88ccea83f4e8d83b742ff5c785fb1e6fd1760d24e2b9b8c5aee5ef0afcc0edc1ec96d9d0005e11f17b8163bb29f3004a153fded3a95a7613772be61a6d77504dcb6f8401c6d02400d8c0a9c39e6db88997f457766f83d6cfee7292e04024ec1e5cb3e0c26138de4ee95ebc55998c455f83450f91f7b6fadedd344bc8319b9564d7d9a839ecae38aee0b7c216e5331ff034c152d7e0abd1953fca1346ce5c92f1980090a196bf3ace4f79ee4eb711160dab6dfd6fb93e4a502e7d75e93b44f57d884a1ed82098caf617aa4fc230d751bc8d34a4e8d9a0f5bfbf1810c727862507ab57067cb82a9e57dd975d322d0858f993b302047002ce83354b95c224b4d7dbae02bb8bf62d38d030b9f54766e4c10450b10a9ef311577fc2caf0a4424698e85a8e438227f8cb3f96fda698dce533af04ed8196e0486f591096915a777137b530828af075ef2baa31c0b40b0188b18bec7aa8c84bf416889f106ac56072304e64c59fc14130ea63658397d4c44ce93e52ef0b3edec754a5d4d6fff8c69dece9ca7c09d71416812c7999b1bf38dea9560e665e96bd8fc671cb545b9c4ae9b58023e08aa33d652b0a1ca220743f5219fa56dbc31435499ff4ff875769c65377801314c35d9fbf5a637b59946805958a638ec94a7f12c158e38ce7ad965c8d404edf2378aea278f71e4a23dcf205a63141f516cc4385e5529c6d931aba7593c1081dc107d7b1be2d2e7ddd365161aa7b2693e52440d2ed36a88d20d206aaadc29e95c7684c59c006140133e7443b7c3aa07426f7b119fc461499f2df634122a3e6a55f8ee99e17f2aa4fe0c2dae116cbd88e66f5cd672f5da1d2c50e0f84d03f46784393fadd19937246e7847ee07843d137fc2c535cc701224fd39598f94c728e90b689fa8c08c6b2e2cbd3328501f72aa5ff70c79b6b4a0c9b0c6e23dc6342d1339773e9be4b6e3133f492006db994ffba5aef110b8aac8f833d7d9108098f58e69799534d2d65e975c5084a4e35c30d82010a7913d5ecb0c6c0348ca077a85642e17425b39b0ccea0e8e008ef8ee4b00d93f246836a51938c1dbec668d128d84f886c1765fe30cd705f767a4a97724ecbcdba076019e88b92bace6b6e7914714d0aa6f6b9233f63df3106f0bcc95bbc3451f58acf73125db0cf8dc93a15bc8304b63e6ad4f3693bc30a19efd65d7f2ccd0d96a00c0235726756ecc7d215c49faeedb6395365765f7ca816ba17abce66265e3d2bad0effbfcbe8363a580522ae036f654a2c36600860c54cda10128e42d8f152978f682f8f65ff9bb6c0338bd271557dcf294b1e42cc3c95d213cb7fa3837facb4d57af72a42de058e5b37fc9e7f2ee1db9277a6b09e6f3f8986785a392b524b19ccfe90e04c4991af2f3d63bf6372d84dd62a9d8adabfa356c4f076160267d40670081a5955fb87a1dae20c301e09a17ea102eeefaa1e6415527ee8d2647c72d26bee3029d681506dcded7515939c16ab6164ef067f4494ce61b0d268fdaa3af3845a5cde9dd6951c27960db8444b720acfd2e3c2bf9b0ca4b10fe01bbf512d4ab64c20412f909bbc8fea2ec610c22d669debdaa063e339d3c8d73cc960974adfe32ab994469225dd2a84f9aafe820e9a2a912f9564e01a326c3dda801c8296959e1cac8b0a7a8c3308aeff82b21b0f9e55c2c8fc18a69eea2ba727f78c2b67628e2009d7bd43174084ec91aa80843314f03a321c5c111307b1a0be19dad80db7538fe336448f771d2939ac3adbca70885442888b52ec20c89c39b83f612080d936fffc586d81461fa13bd5ffec7c8ff7e99aad2f3a5894e68d785012898ce995f577e07e3569719692ff60b5d09467c202fc90ce2e2d333be6de8a80e175f853024e5b31f22fd5cf2c4aadb9847ce15826e3a9875c3c606b961a928c9a4a23d233c68019d75caf6c119a697c3d8c730c2f5963aa6c248fcca8fcf417b9e32d73ad789b5aabb565e32786d1d49c4722e7ad99131f5cb28f382a17feda4c0124a4f70a61f72ab7d1442aac53b11d2d578925fa41c731e0dcb2fbb74e30964cabc739f03092fb839106ab78f5d96be30b33e7ea71255c4e3186e9d1e6ac19a6913400c57f23b89f2ec74575dce1c41c11da3677d314a5665eca928010c7226e040ff3117ab69fbf0ac3cd8d6a27d47038c542b0893a6added874fdc2a545cd30cf37a240bac2f84fbe3f5c06255d6ee8232db6f2f0106bd26529807c2fe8fbd13d87442c0d914b4848cbee223b1ac1c838f4be79c3a461dba09aef74d87eec65b8d19ea9c6db9990ff344fb2723f068f54bda8fc8f7dfe950f25eff692b4a5e4407a8c3866389b073e3145c8ddebe47172de1b7cb034979dda12a5d56d994ec6755e90f6485c876da061c715321872e3237439a180e5aee372e9ae78c69cf74906214f2711d4643ac845f49d3a17762a405a61dc536bdd44cef958034139aef6e4af7be537a7c94261108519bb81aeee3611428e4e8e4ab59f6985fac8e409cc3bc04a6dc6ceb47803d848c80e7571ba272ff5e4d06bde4f9f10acbebc74a83f2511c6325e78ee943edbc043c8177e916963829fa7fdda43d05cfce8a3e7a8c0d092483b3780937ae83e8b342c393d76b7e756d9bcb705823b70af8f75d94baadd484788286fe6c391a92843f654fa42e82343fbe04839113ea988ae057a458f35c15b5b3a93803b51f75e8647e3e0aa72f19b099e107c76e6b615a7a8ffca93a058b3c52a78bcc3d75eb091c758a1ff6831fe6d25a7a6bc21f381623aaa7d9e3650f64df659016783b4ef2572c232f4b062c67e9b79ec7226443fc07429696abb1ed88899676ad6285ec8b5629c157cd47b3c7ece86389d037bf5318b59bc4b041552fdac6ea14140b35eaf261c063a3bad5ded95d98e62e84d02a0aa08403d0bc08c71add968eece5dc3211681ebef1d18c66af9efa1f316a69532cb14bf0bfea27becfd0a22de964b409a7f50f9f5e93c729f0e6bbc8b85f985a54c3e67c2ef9c54abbf5f53bb909f7941b18b070e6bc0623ce64863f94c3e61eedc8e1696d11a3878dd6bc90bc3d009dd7b4e6bfb3784b4deaa8ddbc0d93a4b09627fa25fd1b27f79e38dee9e4220e1129c9d5104fda80dbd9514ca22ecfa22d3f547e76f85fa901676e9b6dfb96dbfff1bb9b414c0f4a39d776dfcab029515a6e55397a1e8e108bc67a1de4e543f57d05abca438d0ae2b5a5c8c53d5e4b79e355dafe9c268b85b8c09ad830f16891a0d7e53731309ca66cae967350ab3a505235cc5585bcd512d088f71037f06eb8b9b01454f18b6b2f206aa9c936e36faac7a5210779df68095eddbc9fa62185f7d61698a6cd9d79b8943e005f390ae0e11104344fca1b47ccff7afa262e4a9e91ce984e9a51e7f768dfbdead267ec4637668986b789d7a1a7778a966a06484de2d66dda05f739cfefb5aa61fdf30235745b2bc6ab0ba94b73b87a2e566506dcd7cb6902c13c4be9c7047ca2f5ef8d296b770cf5b495f2dff01bc09c04eeb947d2f49cece952e5ddce34800b75bf29628819efdc55c71410491d8af6e30a146bfcd9d9ece7004d88e227ac8adab75a2551dc34ab7b8371a6836ff8ae89d3719dace9f2e2a8f69c5f892fdb194c3a922463af57be2473f5a250cf6e860c6291ca5838c39dc18cb0a7129705ae024011112045c446167e7e217282e3b88899eca166e58fa14a67e6159396b5870ea6c1cefb84ec96fe2c27d12593428d60a45f5a5897ec397e47a70e6a841a4907f5769ae1bd6c1dc21327ce9ba39261dcaa5e47739883ec7f2d97eab8957ba4b84d19f29cad15214a6b15f42c4f3802e45c3aad720d5fe05c4003451d5ae9f551834d32d4e3acc040ed6121bfef253826666461d84b17dda59f30147907866a12695b3ff3e6759d022e2cc3d94c0c6f2e6272dd41cad170e77c5af9c1ee0bf6ee0aac4fefde086ba91900127ed5fd2f90fca87c777b8b8dcca6026c6e5628c1e42a2ab71a07d82c78be59a1671ab77b7d443f6c996ad095f112e1440433cbe8389112e0be078a86d6d313086dc070985fd65d19a6d719f76d92ebfbf190fe9b7f0508ec83ed99a828bb10a0083a989699b2006e3e11470ef535d11591d9835caa1fb0a796b10b6972ab87d3f09ac3620c64f1362d7b89ccd23aecf5c9ad8c8fb652459aada63f71b3e0ccd951517f4ffa9bbdc2ff557906cffbd7994d7ca09a9c94d25cc9bec0411969de9ff7258d4e4f16e40a94b0c6c9ebbb7a51848b0d1311b511aafc2ec4c547249dca65eb4676ec62b5ebad33d2d3fc5a5dc346b025c1a56098a7c550f8783aa946a27cce79561839becf63813ca06be8a62df15b18499542fd8ed2ae8bb81b9b35f6f29c9805566fcc04a324450c0e6f403f4ba0dfbba024adc1e6c7c22a1c3ad6f25290660493bd2a37823cf984bd55f9722d4b85e3056e10ce289d4b0e536a52df32149d5858ccb73a468e2d9c1934b87c19e6b47a5d35e66fe58405bd9a4a7bb39ae30a40eb1f276bf83bf09f7264d3ea8ef87d2128e90793a70a13ed270449ea3901c627b254a4596409574c4b5156822c7db0c0926d96de1e505eecb9bf547a4eed17ab599253bd10430144ebbc1f53b23b1a079d1281d273cd1cb319db1eaf2aef53835f85fc603a849fc5dc13c3c4228570f9c1b68762faaf9052e04fac20a65ba5b872ad5646199861a45260c107befd0bf8f2627916a6a8abc231cce839d68b42950e21027d500c7509dcc2a17026a350c2b73aa1124287b805fc9bc63a29a3c5ace72c2756b1e71fec0439ebb2488760eeaae6356f4e52ebd8008e1fe38081ad125e3a992b8561003c6eb864f241628a72ab27878d0119841ba8ddaaf91dd46bac927a44cafac65f4821b5bbd11c8fed71e4d47785827d06556404fc84ef3eeed6da5aa33bdf3f48acfe285e06087ce6ac62597fb898878f255348f3da3930d618987b19a686881ce2d983137b0b96f6468c2b69d8547afd2a8cd80358cf75c26df5941fac5a89a8b55c803511760bdc667654d6f459a62f747b5d089687e95204f8e29c21e723a796ce1251f3e4cc1ec5969cc5323eb0b8eb41722ddc4308310004960232e97f0caf37de2ea60e767b11b4eb5f9a2aa963fb2d6254123c2b180215d3d391423d056bc9991394be0bba7a5aae14793c2982900a5d3a4f5279592d748a1323dade5f217412d0174c2939f2bdd6fda9f78ec89d82c1405b63d8be6e29a318e1f5f2b7f72edf66fe6d339a4b0cef0edfeab016116a5a132c0ecfe4c9d3900bec899276ac36d7d0823a52fcd4a0f43bd01a5e7ce50bb11ed7ea4813b8e1a9b7379000791bf476cc9b1a2e754efd4b9869eea6f4c8cbf22871e68c2be0abb9475452ac381cf361af4d98bee825619a4a4ea765134fd546be74bbcc47e9c57a5db760e578d1070adbc56d4f3a7cb59d94ef045f141f045ef512be12377b579419d9111f758dab90acaa024a734eae0b102f31f73f5131423c010a981fac4496169385f118ecd80cc4df06adef309d181b2e55519d823dd8e21711ed584d20946ed1de556c102f3ac74b7ae2945ece58eebef9c4b4763619d733b1d94108e2377633d6955984c263bc877f82ccb4a67fc378f4e7548f7de58cd26bd3b0eae0e8c48bf626dd017449bb24fd8ac196a4378954affdb649d66c870f32091bc8cffba5342bfaad5550e7ec98239be4cde22bfa55df1d59d7e68ff1b1c9cc089fe52a11cee90577783c337a87992b790ef045f4b71043668da21a0d07518fdbd934943abe5a636dfd86cab3d7791e1eab437bed41250c45d91da7d2b1c1ad66c26acd9f44e47d81beb745c740d7d8f821fe1fead22b21978a09eed62dc49562f633b6074930cc0f803b44b49da94f88095ef0e1f819f3304d634d96b113a9636297dae69a1db9d745028073c157fb31a11e101e63c25b3bc51d3800f76eecd35dc656322541a5bcf22412074068fd5e7f0d7b217754fafd78464e9a04b62a9c6fd93e3fc25363257b09cea64839f2cbb0cc0e86db6bb1bc3a08df11ad3f96ba94be9043fadc6950e436c99d2b961f38437a076c69b5d4c4985ac9e7bd8e75f62767b2ade4812f2eba8313c7ae43bf2d380b631bad5ac154a42f7ef405aea4ddebefc994fccc927e6af7f44c8a2f999aac8b4bba195e03411da052a7187a09bf8ad62c316f27859d87520cd54dcf4ef5cee42661fe9eae19520b3810c3bf0566d98275c45abc5db49cf3d4b3ff31ef25847beac4a1e2b147e6b5a49c88ad8c5c960f4bcf86327dc02562e2e3359043930a9a08dedbecffe2b4a285507e3a4db5990c92c9effbb367bb468f90d16c40dd7b6d73b2155acfa9e25eb60c172611c6bd794c4a5b51286eabaf147c67614e392f20d3779cc1f5d3397d4e8c8a8ab650c55f41600d1910b072a43bc0d4b2148c74044412f34f117f9bb8f6b1df343be223c2ea530c7ffae28e1023ca46a22258b657c01553ed63e9090bc6ff197916e541295a6e356f924b79ed9e91442c872fa67a48290ba4803a6e59e3c0bff404cf38032e288a0bb7586b4c95075e2b2b24d1940705d32f6ecae8e80582e4a1c3ed93f3d91251bd43aee80fab6c680447e68348e6ba298db5a28638d49070038358c94e06e5822dcd6e5f75e4bd4525a3c7e6c018766ef2cf6dd0e26ab941dfbd876a107ee1e347d01a443f9515640008ac7e13bd21248e7db05af66f37f80c9eb465708dc4fa9170290ae4f6f1e5d889895b2ee8fd1bc307927fe6666271fad8c9a6119eb8cff2cd7214f6eb8e72a35580f7d173853456fc90c2e6733c0d072309324f4198d3e3f1ac468ccb7c57acc4f2e806a98b863b22c0cc81072030f7ea9e48cab7b5e7a324ea2486f9bcfa9c8023d88e4c3de1ce67bc5327bc9667ea201a5fca6fbb8386b9ff422c5c0506bda703b3df1fb694d89cc91ce0e9ca7cf15a36dc4e2c3a25fa7a32351106325db00201f324cee253e2020cce91677e13bd2f3dbeb1329e4fef9ab0d26431329cdbed7c1a38d25b9af1abbffda6c60d01c98c99f7e2a4fc34e471da0259c598259521fd8e2350582ad6846c957d6593560de6557793252c9a1e278aff330247d6bf5f6318b05f2722604728dcd3f361ed28459b99783d29c059edd7c22a934fcfd885dce2f666cb5ae01fc08fd8185047e3abaacef39a90fdd9a3f71ecedc1c41b2efea2a80c3fa53d697726171abf793488ce97c75d793d015a8315966f05fd25e508cf924062bad12fdd59e00b462f1e386fc4e767741f1ad7d208e02c3d1eb03e4a18367908460fac6020a166a9d94042b892b4e6e376ea1f18cbf53193ef6e9f24aa474bcda651da88cf5c661f2ee99fc35653a67fbee3fa595f65ae6b0e141931cc6e3e0387b745987a63cd477969722c6e5ff73330e59efa40488e0f1c4b435d24f56f6cc5b7c919ad88905f6b78460395cb27f6fe4517501c1a05525b016c981a16f1504df49a24315ec3291a3f4fc5a5420e18bbae3edc32a56f0495a7be7aeb74911a77bec6357d0effae0261dee8219cd2f5c8cfba3942b2d50d99f8d3978b8b5d73c9ab9d4106d6e264e47ed1ae29d22234770a0918c2b83317ef267b9b54cc8132716ae7fe93d0385e269521a9bd275609a7e4c3223a8e0b9153bb648b01af172e33d31219cf7f6b8f4798b17be1ac5bcce3292e40158f27f04d171b62bb5b11352806cf6e953cf774ba3ed4c7a6cfff423cfde9cc413a191627aaaa86edcd40bd8cf7894128f8b79363f751dcd5f3f34de71a97ce02368b5777097baa968217f4da496afedbf020ebd0fd0d1c93f67c564816857b4e52630671540c0bd01bd9e99947967562def37d2c0a163308c9b16a202890a9d284b75e7f7b3c2e05530d28158b6c05ceabb63c34013068e5c3be63591be9b0c4d81ccc46aab6b8cc7b83ddf897c8ba8932194e824661738fad64b365c0b82781c39d6cd390eead96181319a3df22ce291250e6860091fa9dec268b9b4f7b2eca8e894621f7dd0519f25c1b6cc5c692f357ada3a1ccf7f02de0d716c808389aebcfdd81a16917fb172ff8556338bc8116e2216d3f539510d4bdb51e0b2b167ea2ffbe0adc1716b1bbb968d72c14d14095b950e0bdf6faeceb510b05d91cb0f2ee7973fb6000a863410ad7245a30e08eb74f5dc3962ff616532a63214c58e1407836eef8539c124bb2ae1db5f217f6e9292f297dc7a881facccd3289af236f66926310d043913ab67f1b10333d911bc3ecb7421a60d7575cd78f85f029a2bc56ce1c4783773a2d4ac8cd9ac3dbcf89c1b90e93d6b733d2eb93d28f75d227cccea3ef1fafa0c9935f60af7ef8e227b52ee17dde00997f29a0bbfb4bd14fedeab464b63880c5a3ca69c1abb13df0de64e24636ec9804def92cf4fdf4b9ee50604a2659bcb36650e3a527257a579254f5b8e9a40a49b82115d05758e7f26ffb4e60299beb2f65fd94e303d366c312f1bda82b3327243b5f39670d715bd1e987ccd535adff34ca11e4326bed6e483a0be1c057affc4df20f875864c86a43eaf828f6094d9c314df5b02385f638acc4dbaa933b2000858bab4107f78460b8ae8db28ec1cf2c610a7dedc8940860f6f673023a5773098ac02311dbf5d27b1b2f9743166494e1b7670ff86b21ee9f25b067692db2fc9dfe16384fd7c2095cefcf30da32ebde1cc34c5ec02ec3d556fbeba0f77589b0a1e39371bf041261037e3878dacf205bece8c5f0484ae40ffb546ce6c94828fc226ab9e2716077a08808ea8f3899b5021d962e19d48b93a04ae8921faf17d700c2327e1603a2a0875080f5f9cc1b050cd74f757373e7bbedb6a0f036fcaf3eb76f380c9af8bfe5a8cb9adf61835a9e0ad5856d3038887694699135773839510450434076a9936da7ef82a023e3c3bf336cef29c2269237b8370dcb4a2dc6c217cd8dba16616a5c5407100b10b41d74f0a7d28a4936f1106821b2a6dd31c6ee3a4853388bacf4b0051d1b7048d3ce2f0f57d3ecd0950639413a9f2f4671866a7d4659a8d81cc1eead5973214021549807f976de76ade8254701f1e2dcc67cd0d0efdda3a647f28fa80ffbd51966a9cae4da191c2cddfeef29039eeed92dca44c634865472c5435d585ae2345795d624a207a199584abee057fed9530c5fd8c8519f0bc4f076d18ddcf5ce56a04283c3f3494423494de73a3f11b97df9762450851dada7ffdc20aa8ee8748411dec2db50076a137639315c2fb23c71e8b7419486cd4dbcfaa063e9104a9672664031d1b00d1e352f51c460542ca7445cd0e99e1466472b6625924e67230663543fa431a67166722db58bf322748efb3cab0791ee47ea9615b13ebeecdbbf26de381fa7666b3e24e6758f1b6e98d7f000006dc4b5e4f2343f271a27609779f722f51d6de3c89c34f74c5c87e10308b3629e1e72bda3c836e69f8d5f7bc476b865ae173a69535523e7cc3a7198c45a29010945b280efc7a15b553ead65370e402063adb88ca1edf7efc615be242f7f061d3edcace597765fb15d20986c3b04d4000\";\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(\"Cybergentle\", 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 [\"Gentleman android\", \"Gentleman android\", \"Gentleman android\", \"Gentleman android\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Top hat\", \"Top hat\", \"Top hat\", \"Top hat\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Cyan rim light\", \"Cyan rim light\", \"Cyan rim light\", \"Cyan rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Rainy neon city\", \"Rainy neon city\", \"Rainy neon city\", \"Rainy neon city\"];\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\":\"Cybergentle #', id.toString(),\n            '\",\"description\":\"Cybergentle is 500 Friendly cyberpunk gentleman android with a top hat and glowing magenta cyan monocle visor in a rainy neon city. 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\":\"Cybergentle\",\"description\":\"Cybergentle is 500 Friendly cyberpunk gentleman android with a top hat and glowing magenta cyan monocle visor in a rainy neon city. 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":"58376970","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-04T14:54:59Z","match":"exact_match","chainId":"56","address":"0x3571f07D8e0Ea505fef98a5e554219e57829fEB6"}