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