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