{"sources":{"Circuitfox.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: Circuitfox.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Circuitfox - 5995 Cyber fox girl with glowing circuit face lines and chrome visor in neon bokeh city for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 315 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 5995 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 Circuitfox is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 5995;\n    uint256 public constant FREE_SUPPLY = 315;\n    uint256 public constant FREE_PER_WALLET = 1;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00005 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Circuitfox\", \"CIRCUITFOX\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646ce4700005745425056503820c24700009073019d012a900190013ec154a14c27a4aab02ab5dd8a0018096a38820c337b66031cba156cfd53f01be4fe6e7b40db5fd77f7ce25ab93cd63abbcdd7fdaf5d1e647fd37a4979c2f346ffc7fbb1efc3facfa8bff63ff71d741fe4ffeffb1afeda7a7a7b407f68ffc791bb311f1cec66d2b8a9bcad18c756adbff96d960005b71b499e798bee23af37180320fb41a6ef245e9592aa3a923d7abee83867a09a0eb64cc2deed867ed229ddd13e83cc9bb92750e8915a20888f5323b5c6acdb4efb4d178b5b9b95b36c599c3d8a81ce9260724023b466f9e552cddbfa766fb81256caab91ee128ebec1d6c6fd1f7500c5a463a2a69910d974cd4a3ab9d52c85efd455d8efb19bc98974d966d577794527931fd98332c56edb4eaff532923e565f3205a7c05acd75d963b38280cbce87e96fefd83c1865fa59396311554c259500fe70b97264d3c8983527cc2046e8ad8429e5a7f287c9b554ede5890d697b3f44921c03bc7e07ce6991da95e17cc3d59e4692c7c539714302c9dfd4811b39c0ff828215434d00c91804e32adb65d60e53795208bba3e9c4bf32cd4583fadfbf18d27d855ad08fb3d75565168fabae31114be0797d3d29496f499abf02da95616debfc66b3c330ff23f33d050a521c653fabfdf3d8233cbd6e673cb709704691e9d2508ffc480be0b2026b1dc18ee3af2033363cf19acf110b66bb64732b0268b0be4863869199bf76c33ca608fe0e79cb0464fce9027e5ab7d5e94d5c54b0e561894f42b7bf9f8b1adf928ea4964015440ae3745f3d7cb4b064e080e51231ae1652ed161960b8698f3b032e7dae2eaccff9ac6f39baa3967a3593b7aa7940cec672360c14da34b5ffaa8c30d5fee8479bd74d5398fd6b2f9f9edef4fe3d628ddf7050f2c734f30277319501aa14e259f88d692a6ef90b95edbb74b912006e6c424aad3796e4f5efbe93e47c36a4029f2f50e2ab4d4c0f30bddc592b2b1530d161fa061467fbe0ed139101f821c0573ee07dfbed0e83da89805a1748dff1335321c431148a8a9a0029e4d8c448ec9c3854856f1cff0aa6429697adc7f5a3f8874a6e3f644a4bbec3db8d1143ae8b23aae37ac5736fb29e289b9eb717427cf75272f75ce0b874fe360d9a82186453beec9bd95cb0e4cb8ed849fc9838dc13e2eaf95c55fcb8e752bf790b7b4cdbccb40f983fcd6553057bef9552f5bf92de18dce4b7477e4aed51de3b8820b26c6c8dc8f48626cfeeeb52d2b7453d823df243fec3fc38b5602579931ebb962277736887984a7e039222304ffcdbd48d27a116cb7c0cff53d605801ab321654a6e004ab9a20154b7426585bd6e4e9012112e558b7869444a369b5813ed1b6deaf113de4933a6c6c21fb21228c6c939db33d95a4d4ae144dd087b31f1b2822cef7c7ddd4699e176b0f238740e57d026a2fe09096e67b74fa916a7b4c950598b77d9552d0ee65df553218772fa76ca8cb3270f7e012587f9d8db51c096c3000691a2afdff83d17fbcd9cf0ff3dcbc87c7aeb9b2f966a69da0e22afac3eb2f2844764eaa1f3aa4bff7ff5f73cfb8afd36dc1a26aa5b42aa1e2ec3bc12f5dae8a732e7babebb461de9318e7ebfaf551cae6ec6cd5772256f88125465860713010b16ba969c00ac699999d5b8038ba6e5210d322c8d0fc3ab52757444e2d11f6e2a2c7fafed0aa4e8af595c3c84b84612071101c8e00610802525c2731b9fa285854428dea2f33c9b00df668ee962279bd7ccc96afa024fb6833418fb0536f3b1849ec637d79af8f572b3ab64d0baca2db2d8569a47544e7b15952730191702bc045ab1c444bfff80ac3b1f322821f1bf5c464873ed02e142f2c00ba038a0f255381b2c66b80ee131d63dc0bc7ad8b9c77e0898591e097031275ef314f1cccdcbb7e24592a869975e0f8942ec4eafa0e8dfe0a34cc886cf96463e57daf38d00358b10788da307bcbbf76da54394eaaedd9871fa39fbcb2cdc657faa7db02ed37fc8bbd08197c3eedffbf960b73052fedbe73ae7cee2562af4b6c076d661f1a478ddec27dae8ff0f04e523e24b7915ea1b8180f0db5e2dc4401224dffbc10e5a5b18c083f325856caab3f339e59b048d2cf782083d1ad726f9e48d221b438a1d9d4dff435545c906f337b7cc4df8a3306110d7c855680cb771379fc6eba817355d98e63118803d43e8d902661cd965edce91962132ef35043d303d50743ee85cfbb9746fc7ef9504028bafd429bd4c3240b041045fe41a91f5ae8cfee71d7d1658b7af8238208034cf7ab44b9534d283b4a2e7d8823d0b18cef311ffbc20829d4842b04895b014228786267ccc88c34f266f72f96d6ec8d5b7df6951edbcc84b3abd14d9e6917ebe527cae33b04baa920da061bb8e3261f784b96ce2e20b5105dc576630d26c4f5a3366a1e67a8168d1d5ea9133284bc754e4c0078bfe676f9949a34ca56bc32ea9b68f0f5c64dc36ffb37424eb191da30f9a20273a36c2ceecbce28ee443c0842c87fad736961c6ff6e0105f43fec2e916593d46e73c48071cd33a57a9f64e093c0d7cdf5b50d8c860d80846ca405a3fd358686b7c938e0d03524c1103604279c2d6bfbdd1b05820d163fbcd5b11ff056cdb667aac9c83e895e531c62a7df9beab08637e48ff0b1d77e8f76c2d6fd68f3830a8fc2e64ebffc65c17e71f8ad53603621a47ea8b7f2c8ed7c20218646251f534b39b997bacaa9707f9e87d65348c78cde47f58abc02db790edd94352547ebba3dfdd2a5b1e447e4254a3ece3f46f7a1adc6c613c8f300220a77855e0495e050e89b0f715d0ddb6a8a66a7d89e2791c95c4705afe1703fbdc958d387cfc79b3b996435107b23d3063046db6e79784bb956812c00d9f2aa3dbdff8e1c90e46ea9c5eba8a08061b61f73e114e43dec92d7351d15cbbad61b7f4d6d31bdc53ab962ac5de1b6c40e4541d64a42e453a7d6aec7cba7a6db3c44fbfbdc920580d5e9bcb34419d7cf22c471312085787d26eaa5919c748eb7257ebee801fd8c22667ddb6b763a0e79d0330e819d775ce1825aad464562c2afc458cf97c33f5a2106402067f406d2165499672455494f816b145f603b87a37905da001c61043058ffb2d3dfcf370c1834f1a1d99662ca85a174eb3a9cf89d214c5129ea9f946c8b8a37504ded1b56a79b85a5cc29bda21ceb77665951d6c324b9450dbf87ff82003ff2a98524709d73d695f6d994d93ed8696f2dad7fab755f066d1edbfbefb47f343d30cd1d11fa01899f97ffe9c8730090fb0a9b252b2c43f92edd8e04f19daff0429c372a39c27b109ce1275419bc8ee2748b9470751ffb21aa7c49c1812aaacf0ff5b9c6a7fccce8f36277990e6219682f2239542d1bc04217a80a929f8d89f6cdb6177ae1c6dd73199b519b32ad35155c3069d09e9594abf772095c9a08a4ec9521cd90600709e9444305fcf93ad9249d5644551dc314153b84ce878a40ddb9a55ca77385c84f16bba543bbf2c1ce4a04592962d710b032ecb0f4031b6e856efc99152408cd7fb5ba2a5df42d971ac0d9efe33645f473ee7d53d92e2f158879d7c32c94da80b606d2201004f467f9ed2f08d66d0d734a93e7058fe2ddd9292893badf46723b30b60c3ccc95795725ad29176a09a5c835fbd068ea05de9f6d5871401f4f6919ce8be46856de7b8a7a6a1824db39baab550e81f501394a3e1c056e59320332a29b9326fd39906a3b2de6b399a4055dd4108931e8934eb931cfdf0e3c05373d1fb12785b44a4167dfaab76f0c530722bd965f0b6e0c249002b8e106c2e2ec9fa069b9d5e976d205a304e332e96df7b2c0624e87fb9a0b4f8c6cf8fe047f7ab09f091314438102fe736f493cf45d1f2e3b569420fb25b3e2028c5435b9e34588c5d1f3282caa4b089849f075ed633b568267a6af3b1684a2198075b4b4ede0ca2df58b9f9dc1250dacd0019cfcbb5069520ddfe5644cea51eb914ba04185d7da0a07a56d40c89c0326194bfdf0611f37e4bbab43afb0a6de68309098234d8e63356d9984c7700b10c72d794b2173bba0284dd3d9b97554491fb4195e55db047aa6464020527c0ae2109226155ed39ef317c7ce37e710dc8cf98278764673071b74ee88c7ba9d94dac94bc031e13dfc7741be1d23115f038551270a42ba5e7b1291e6c20043c29a0d502f2aca8b6a9f5554da80eec8790a8982a9138266108d15809a800fef07b1bc1059163c4ca8113c6d52ae2252a61c07226968864bbee52d79f57042b40b650aa7bd52195d393bd04102c4bd7fb3b9db176f4bc6dbd656ecbd70d2b2dcf71f0cafa787ec208cc1ce80d0da2a983cb28a781e0b71c4dd7a6be0ef750814bc79997861e473ee615abb2611cbbd028ab9ff0164a7fcb8e00370cfb6550dea560a2d1b8fab60680e3268de6cb6bfe268e6c7003ca636731f44d869c08815dceda7dc75fe4fe8ba27e3bf1f807e6d06ec2693600fcb6dbeeab91a25791e1e98e1f93f0d89bdcbefb313ba35c6cf93c64297cc352ae33223d688fcefc87ac8a746a1e50750f425cd3e5d129f2bc429ef6fa364b8fa2b2abc9520aba00ef45f6e40eef83402a915a61e58b17a5f3e192f0339c389ee31a1dadc31bea7d4f9c0370e70a0f572f796e00015130244ff32e22694ac9fed39318e48274c5e9562d777bc8c47d179bcb72e72c0a348ade635b4e1d5ed26dc0e3d3a4164b409ed8e9ee8480a1257a9aaa3ad08bb371a471d066dd5e79ba667d1f420fd95005faa235c42241dbaf4959e87cbd2d08a17c731c65cfab9dc1aacb8a0b995daa488a1b108dc7f1b36e3a68aedfea401761c4c44628ca3ed9940ece8ea7958a8a524fea32b3b3900adb71f4fad09d7e55884f112019d0f10dc7d9fead1bb71d72bb5446c1ca3ed6b06677a719341b83032b402b443411fe0e1f4908319a1c84e4d9e405d5a2c56aa5e33dc869a50dc3da832aa3a3be18bb8989ac4ab1d3a855b8b86dac6eb2830f8b1c8e13c67c87ab57af4719bcfed740ea49cbbb018f5b2fd0a51b51ba129ed93e30a252bae47de64636c133f1817ce7860fe55dd0dcfe24653e9bae164238785c12fceeb99707be21e3ffe5c01f3d54d3b92765da49e23e61870ce3788acd393fa0381bf6c7a07f92419904874f67621f39181db0d4c4e4e1532309e75c81228c2dbf8210ab272d879736b5b4734900781f8e8a8b0a455dcac31f9d805a819028575bd3a94e3e272dda325179357bd225c21ab9454e49e74f11995a4d0851415e300b477d4057394c0ddd4b746cc27205a6407fd8bbed5b783ea5dc37973d44829be806f31784b422b54a0f15cb58d9412f98ac0b3ea217295ea21bbb9eef630f733366c8f0a2c4da00f59a8fb12b4a248fa714d4407c28996c97c00da8650aba9fc11b059d46dc8f8b55def8ae89218a9d014c7443a1e0ea69d4606e188c3c8fdd437ef4179da5e8d7c24fda184ce4e4e8d7180738104357023ff5f6d8926c41c3a6e99de90f3ad9fab39d0ec30127c6dbeba644c3188bacb4112e5a5edb95717f1044f1e5d55b7ff121500942431d9fe8bd6fca4528c4c947c405eb74b13d4dee85aab0bf59e7e0a7bc5a64c751137c164efea49ce2a16d0208fdcbac1ff1b83827f18435107292dbfdf31547e8ccf9f2cff4729e9d00fd863c3219db3779ce756f09eaf6f0fbe4c6eb68220584c9643e0582a64e3f3429300e2a1870ecc43405e94c00b2ee5fcd2dd75ec496600d01904460cbc3ee99a2ba7dac4f08bf84508aab8ddc4cee66bb834bd64835cf7b502ec462a838af306b9cdd52e2a5591099d497d0d19a2ab2047d94266ea818e9410717e72d1c865cce2151a2f42fd9f55f7d4bb559cafcaa1474dfb8f3ba7f6864ba6553593e101555071435b3941751a0347807f1e62c16b28a830ce87135e6e5eed67fae06dbe07a452ccc1523fc31ce220b142c7073c54d82bf19fcb99c05e9b3689fa9464ee6fbba36cdee700f7143efd70f4ad76191f783de553f30bceaeafebf4b053dedb13789f3c59a04c63f65fd3868489c8be9f856cf4ad3f181df19120bebabaa53055d33b8a22d6e2f884b7fa8441986383a30b7a0b3cfb958d508f40a3358ca0f789f4d8bd8e640ebbc78104854f54aaf917ce501eb2019ec655c790057fb429762846d3133a6d7bee9386f1e640d3e777e9a1a35b1e0c9fbb91d89c3a1a4db3822918138d1cce10cf4b617d236a59c98afdf5b0df2912458956688bce097853a34895395af9b8e7085f9b1f9d08b8d717d4d66839fe2f0c1d7298d80b4e1c0639fd2506d8434425928cea7c81f87eadb4eca67fe2d9543659dd41b14d61f930a087562d89961e65d69bb6730874a95b171c5b0eddd991b81ae9db382e18a6156b98bedead84eea6fdfc6e3a5b3020721593e68de2324e23c66def0743cdc4ecc482be672c84446dc61fb799282cc535d4df3e903a9fbbdb3214ef51a2b88fc105fbe72586ffd1dbc06cd90d48a1113144a7b0ca90e27cdf4cac9198dc526dbcbf85774a6956520185569f0979b3d86a3424844a0d8fc94ab9a4008bdcf2e61ac01f4cf9148342065ba83649d0fb1da6a61548cdd85b239f51191d1b0126a24ece364097423e6ad743e6b2a61c96dc4430733b20b4ae6aa52ed8169120128b3569343ea6156d0c30fc1e9f6f46b912348f6a38e40438f80445fbe062e8d1313d2b96e9eec6a084d836728084e7f8e54aa01e7765715778686e23538419ac69ff077988940798289f73fc3ee431796c3359ab0b2a87b5f4d7eaf7235132a6e33176e56cacbac1c11b47036d136df7f7650eda54b93c6ffdf7aa2610b23552bb5b400c05d7797739ad59fe39d207382f7ee6b9224fa4f8cae89d2cb3b76c04f4eedb09f76b752411537bd2551e693ad4e5721254c40ce0e7d8072cc60fdf99bbc0efa8f52e961c2701044fbeb4022c821cb68d9760a966ece0580b8d80d4d120f3211db060bc1075841bf34349c4a926cb400a8e134f28ee7f1da30d009f812d80f8d8bb44568f9b7e5f8614dde34d27e77fb1cd8b31731036c9c3335202403d0b8a9b4efa4d12cda07bd745f8dc59a011cd07720909e242f6ca6aaf93764ae5eafd1e0811a9526b2acfebcfc783c4429baa61a6790b31f5b759c5012c22036a3a9822c7d4f19ff895e2a1c3735e92f2fc3985efdda6a6d9a59686f4958d7f67893ecf979a475ee5d485c0353d0571e2d32bf2315b70df539b275a1e7e68660014cbf761675aa9fa36c12306494034bad88ea09eec26160fd74c0ec5a85e4ed7ed7b59d7da5777f6a2584ac634afc5cd69f404699ec41714e33642c8351c664a79cb24874bce9538d6ba2cd6acd65e9d16a280785997d6d46bc158f73134cec5dabe27857e4c28011719de5027b8689d575a850a95181ace88791a13f4f656c5a9faa31512977799488c1209a44efe7ffe272e2bdee703c210010890e092fca7c84b352ae486292c5209a30ae0db79df6f985bc486dad1cd4b985126960cbeb2328e3ddecad6c5598b2d6166d10d4dfbcd6987e1d323ac5c21d0770357f74582a4d2feae5acc4eceaffc394a5145be782e7b47038fbbe7e908b818ea848afa5c317e5e765fc62384d439e484506fe9f8a8c453df87e582c59443e4de08a1a0beca52f93068ae6917c9843d788b3741430d9deb6fed0784b95db143ab5836afb9c0982d99dc50d07813db57eb87611fde7b86718668a8f22919ac82ecd3bcd87253b435cae11c62df263d60a3e9ca1a2a872e0b8b664056f36ed18bb06f2a614f5560f7852d00438473a664215bf43041542bfb4ddd16eeb5c014023c834083fadb00dad569088be416ee886e97be8f0e53f96528e57307db2b5ee75a7c1a154e9178eca5843a1ac92e073129a507eaeba4a44b43d82f5dc21c1a564ef7dd8b74f2041e4af0323f36ad8b4cd13b0cad631f7fe2be6087dcd3ad2c6c22c3c2042f540ab9f26d7700eee05c615fcd0f12abd5db2561857bf18ea3762260d2e9101e878e79ff8e930cb62e1e975340e29307d84e200067477357c3073ec76f5d1549f2a484af02423e5b5629f82ad64bd35e4339520e4f507927a789c77c323b743a1a7f59d4c5430823b0de3730b8fa99c79662bd3b80a12b0fbe9c79c1408da8e265ffa225487eabb9b586803d309e89faa228f7c8db4cb7edb482ce2874b08b9e13ce3c6463ac909cd0c9fe7557b58179d77a1deb8b6fb7ea97d6a8b31768ab161a4523efb32ef0b721d001d95cb4499927abe6d3a6194fc0ff0f800e07598056a390f65669ded8e48239856d1dc0e9f8851c4c5631af83cc6648f90dcd927cd45f957ac450c79dc7bdd7f15ffd95b73178932e1ebf2845cc64bdec1359b3e9c3e40e6065cddb0b6922e22b7ac3ecda75a90ef014653eb89a184adc9e3bd80a00ded66a31d6096c0752692ffdca2349000108f4b6626883c51cba0fd95a8dc119e94e9ae0ca3457cbffed468ba5909b64774b3fcb3a4751429b727f24298252c3731a2c25427fa797338577c273beab68cb15dd534dd6de961fca6dbe2dd0fc69cf22bcc18e16956929cf2baff4657c2c1b19b136af39f1e7d6c06bd95d96f8aa57eb5955518f950b4993da5bac68c2abffd7f94b1c2f23470ab422f400f832933fa0c863abf236642ad7ae562719c188bd23faac9c6cb994953f8c7dcfa49a71ed938868d97dc957b22241dc4033f0c1ad8e4a34696634225f5df49e50a607bd085f14293462a326ba5f2b9dafd925a9f827435b98929690f19fcd884fc84ac95e12a11dda3bb6806f11ef21edb58ef192e053b5c0a3667614476d4b5d5e8f31877894654dc529ba72cc14979f8e7cde3a09c59fb9a1c1403e043ab0fc4e9fd0eeae0a8702c6726e3ea58f60828ec80c4a263586d58ec861fc02d612a9fdd861b4f4be4ea7dbfdd6357aafb5267a47f261438089271d684faf6ecb9106cb6e6753c02b1de354f92d44ea2fe195aa9dd679f75770d47327b5183d31fbc1f9b7e9a40e2721ce1459679f458a9be81241926e76899a39ce2a4e1a52f364f9e87feba02424e0d8eac36f12c16eab349bcd82c667968cbd23129b067aba090ad7eb8bb5db6ed5e2d3dcd74249e0bca0ab2094ddc7a004c5a9cab0b9fee168d47a99118c7830c580ae61f2070e3e7c06b945219e1cf812b5cef8c0fe35c9945b0882da3ac03257420533b65670144ae665890477b31113835cd0fc6c0e435567810f8a88484fadc12d5a25fb1a6e001439021296b675d6a693f6e3923ce0b113b4c6ae57d199a965dddb0e2295923447c2d99db1d383aaffa04db6072e86b3ada7f909d120e2f39794219a74c8a4fe18b3329a37db164b595a404142e7b7b0994ca53774d9819100915a9f396b40a13b604ab8eb487528ade10e7749bd5974d64891084da76d79c36dfae9c7fd9d74ecf1ea3a4ebd7ced35f8f6e8bbb902d544f696a26807ea5aaed6e120362fa1b8b4a8f96c8272f3da49694f213c289cda44e914380b9c4df63da7c19c9f3ce70af70bd0d66de26cac3c71135c8dd685275dd7b7472949befa841876e7af428eed77303bc6cd4125e9466a2e9bbdea388fd1ebd250c7c9ff8910e3121e7fb0a355235b8a5177ac6d5f2556e5887114964d6a3d33801e3a1ce353dee366f51cb84039ab29b1ca3910136344f61331d4d4f56d3a054ff674f84542934cd4f8fc74400731d9be4d541b729985a5f6690de7f1f2d320dc58ee19e729d2cdfdf5ecdf61bd5c9ed3a1a3c81b9a76f995d6ac72c5b87a45afedc7f9cbde6b2adbf687b6ec117ff0aa5c170fd74a34640450b4ea9398f46bce8ed533a813d539e29efe1bd3246e9e1fd312dc84f9538f11a4eba475620a35bec42edc1034b4fe2df513568e2ab2ea328232e05159ab4055cb7734c47723ea30f5f0b4ba7ff51d756bde09ed56efcebc3aa85ce36f73ecd746db2f309383140b4d5f5c2f0deed8dbeee7f42ea51fbbb15108edf3e6ea33181dceab540c91e063a1f42a37120abe606a910a059b308246c10e97a80e96d328476efd861d77239f64204f80d887d5aa84d90181f908ddc0c54bb8f3c7df2106cdab7750312b3375b40d7c7adcb55eb8e8b4dee1f5589acea8ce6a78c46a193ec48630dcf84d8739ec4250b6552c3b26ddff7ef02ebc064ba8ecd6ed69eec62f9b1de828f137e3ecd1ed4a7b2767b9661ed247e31b36c9e43643c164e9889b132a0ccb559a7ce76d77175de06d0df2f11e9f7ab69473febaf55e7185da3eec47c7070706357efbacd49392eac72529f36fa9674b6e41ed38559302fd9b2d1a1cb419e8616be9b09755918a5e1b8271fd88e34ab2a15a75f76b3bc468c04e87eaaf5b2de9ad3868bbfd9e8f662b333d07d6e499aa5179978cd92b5a0ec93fb3585f60ee14f992a7eeacc81097bcf661691a3056bf4cd0a0ef7b754273913d05e0e1191d6e9b13cef2e7f23328ebea7494269d3f96d56399287976da08062fd2ebafe83deebf735c676a731a5cee19126d3ddccfe618bacb4fdb6b367edc0b5f3547cddf27a7397d2c047bbd093a018b617b4c88146e56c2400ee30171c2c55d4921ebc8eb5d9a8693a816a88864fc87eb30ba00eb4a038c0da43486eeaae06cc16ff31dc97e0e8a9dcb2ba9acd368ec7d14a888cab919186a1312d6c6c27779eb3afd1b7004ab5087035e291254cfb0be016eb154b0ce35b3ae5497b92082be69f224c215272c2d728984e3d19d35dc51787ccdb052e7ab1bfda92a0eb344e0bc10b33e2804d38a5da0e4108f108f2ac22f6e13100f8393f9ac39f63a052a3ffa991dd1a388fdc0d324bcdbf74f8b0f359d07bb3e8578e8729a11ec9901a186c2531accf8e350b2648632df79d0d4bc5ef37b393a955c41a3ddf088b8529b2f798aaf96e13d0edaa3ea835d823ab776c4c7b866c50d34a16c489b80388661108795735faf135b5dfaa860e66befb8d8b1e75504d295f1bf0f906076fac50e71a012e044de1ab66d7f4277f8168ed337590f34f2bb24ab2cf1a200216dc374cfda3d58897422abe7be26b8d934d670c62ba5999922275d434c1bbb6504e1423e5d44f1667e89def732d0ab17f8b767f36540a06649b4449c535a410daeda8f8819ddf7295bff10f6592d489af37311ada07164a25253e7bd8a0e91f0e29bca8b2b5b19c2faa9448a519ed9539333caa8bab7349a77d0fc5dd8b9ade191c99de2e1c86a3205cd7f5b69c220ff74983c2fdbc8d5c08d6747f6d8f9bdf9580da6c547b81288336ee4ce990561d7cc94ab2c0d6fb6a8f2a2ffc91c1f3ba35eba07ec15affe189d1831143c181a83c880366bd24db8c5f529037329d6acb26b3c620ddfee61045666e3540ecaaee15fbc1be12cb9792c8f37c8d6e3be5e3d559e40f25549af9ef67cf75c377e2e228df451fa636c41e9eb2aca43dbea88bcfa245efc0e1ebeb8528d970e0df6f001aabc63f951b81a4eeed7f029945fb3c10d67473375f9602e8016b29338fe80b6b7eb68d40fc215d0c5abae06d5cab5bbbe23f119851f81e65a7541beceb32a0933ccf6be412eaba32f18646c7533c19b2731b2d55f0ad2b5eccaee91287c145fd090a2a9195ec714118d422fe5321409018fd8abaf2abd42edce2461ce902321c3639596c13ab7de1b82c74288b3fa1a2fa39f43eca380129640fa42f8653ffadd3d72fa7fce00f745aa88e58ed4691bd372d92b0e80fb826f3ca2c7c240d9bf859536a490361c0fd3bff0eaea9e8e28d9239e6b00d3a058ab53e605e8da70979fc3c67a2cc12289986e692e7725c3e15d6068adbc4c5d837617ca1e2b564c0ea5cd8cfdde77b03fc464c603df97e0b7542253f0e87dedf83abbd72fc2e0c48dd0a6f23cb2555694829db2bbf903e49322a3c5fd6258619a9cc734871df0dae91e86b931be4dcbb13e6854966cb03496d2e0325459231fe32581ebd2a841bcacd9f26c444a0864745981f2c5f38536d22e35755b777e2f0140b0ef6c451e0a621a157665502d444ace20b4a97eca0aff630f6a41e22b063691415af5d451d0e1ec50d3b5ffc3139bfb93e67bcf00e99ef58c53f2514b85e28dcb54c721fdbb0fc1e43722e3287ebaa3dcafa904718fec9d818825348f404e7ab649f8276197e12571461704c68109d18d7567a5b3abc11c971875dbea60dc8863c319c790732a7552d2117387fdfb79f19ebff4341ea8d60cb2d31769f42ef6e7ca6d775dab5c56f31a88ee6d94286c4155f395a96f337c019a739b916985ca742e6f5f63528e7e5a0ad41be5c599d941df7954127ffcf86fa1299fc51e45e187756c14e30341bcc728e8278ecd992edc7e81cd379ccf9a630db2e995f2be37316613dfa2c655305c91d2a21719985b5ae394db5fcf3e0e994dcef462f88b8e9295c810f2b445130c3415e728a22855c8e5f1eb73c43fee5c71fe87b5f081deaa74a987471adf6bb110602af44bae96a5f878079032c724f266c0ebb28aef0e21235cf4a0530697d993d2d73273a59a8f0a66015caff9893d8a34bb96f7c530fb75c39133be3b9b3c5e6fa1ee622025aacf6bae18faabb7eef2fd22111f674f546775659e5c8ec431db24f110ebe7f0fca79aab2229233a3704375f21632544681e0134b39580b88e5e0a65f21516d03c81ef55ee808265f7a7f2955759b5c47bdfd2c9ce49e1fc2233a69cf1e062a19469d016faebb2942ac0292b49fbfa7a5a0f1e443f2b4f5d83949ac23a717f957a71c425857356e0336eec50322b7f35e731f9aba6f5d03b5cf3d78fb3f2d37f72ab88cea4a60bb96830a8c619debd0ab2cb7550126c3e63e9ddae9f58010e3a0b672ab9a581e8a219292ad8a2b9b6db4a0c1b0eaf7c2b89d49ca775d758d7568cab44c912e9d1cd9b8a833799a6b1b3226fef25b7bd73210890bc32ce884882722a1470f84c4b2f182e78b666efb70f8d5fddc11a1493dce3e7c2d716aecd5d58771014535182f26a9283fd6010d6c675284b7df89b1e5b2ec6a33229b26be667e61aac1041736c3b37adc2a5eea0048c204b203c63c0119af18ac2535c86d4a6dcb3c311a4cc3e36e9cb188c4491f89c6f611f5889849829efc99cdf96a73305998c8f2f3e33b9ff095ebd732a864468b4e54d4541a684fceb88fa88adee4727d6ecebac24607bedd5e39afd637f0a52138bf3fecbd44cf1a9ec1c97228dc52e85af9e8bf8d2589d496a05c2749f5d982d25821472f806fe983954a53f878e202714a1738e71c832904b3d6e48f701d347dda0ab45290a3491aac643693230d2503747b5d6ebcc639728cf6f4fb709f7a425d3f0bcb76095aca858a439228e4c637350f92f7a2093a67ce085ff335c96c88a12f01d965d0e4224619e644bfedee7cc0f59d4911cacf280a4de398a114c1a3951dd18e18397aae5b50e8f764bcbcd76875d01b47bcc84a14748a49f8b49bb22c6c8815537bb724d6ff993cc5a5fcad9a91f4a63caaf7a2b26a4567d16ed406be6c9b1c141d71cecba3f71310821cf00e34bd368e4279de679b26088a922eee268423944540f91ce7b24a0393597036ed70bcd6e750ab6200246532db6170e872a892279cc43d00a2fad93fd871cf922eac7977b597ee5fb1efd06f6705ec102674ce5bed44d323c9e0e684a551a5255700bfeb94585ff3afaa5325df269bd16048ea0200108d360e89eedbffc5fb56288ef8c370f2b36aa18f9fd7e93b0ee7da4e02e118b706b29a4433be37043072f6bceda95affe7c50e46b8d2bd80efbcc56d7dd237ee427308d00102668209cc703bb30097c8d0e6fcfc8ae3545198766db77d7ac9722987846dde864b75c760e6f97bb7f688bb3d2d82dbf4df55a844d26fe1a24c799dcf7511e0a556bebecd6bb9509b369dd12c71b9b71344300c5f6995500a1dbf1d342a4b5fa34380e56d44662f5cefdbc1807e9f732becc64cb83b13da4b107bbe940bf99cb33fbf510a99c4322385a4fdcaf428841140e3f34374b2681d6478ea92249e12d28f41187511507fcb033d3fc341fee69d2f9e1a84fd2538534b9c200bd375ca2c2baa7c9d5b306468ff9995f3a0bdde8e03a5a7179cf800db8d3586f6804021cceec3c03776f75275e637f323701d043d536cf2f120a6a673df33654d151639c79c96cb6d4cea7b500712e63779405f33b44c79019ad9243f7990d76ec4c134da981f951568ec6462df51eb03ff6155fdf21fee52ab6e1c5ada8e943b772420df9509c369a9787f5e99ad58f07d484aa7e9a7b25e83f1cc2d828c90111a68108bd39e747e35396dde333ce71f4740f0bd7615aa780d45534d683b8e33aa382a1bd8d2c9aeaa2d797c911c85516a0907e62062379f6e7dc82683feda1b0bddbf2bf06dc0ad2efbde3c40a0f570a8180e9816fa18f675f789ff73ff350be855c8fc84b796de4716e03409b0971e8feb5a2f4a940f908c5bcdbc03c24b13e4b36c7a87c7cdcdade69a900a1ce4cb7580ab175d6c70f5e8551bca41733e3b865f8ad6173e28e7c7083abf52ceb21e279830588788bfbfa684f01da9c3b05c3bc7a76456f5cfec1d1d0180ec57266ad1e94a8eceba6d43f1c74e1b8ff53ef491734d77ca4273e57c5ef4e93eab619d57533839abb1a004f2bdc76bb8bb20e458493a6ad7d4fd8fa3dabda586cbf8fbef9d7b62ee2ac9e3136f0a497377dafdcd069260a0474bcb8b0967a653e38aaa24d9bc0ea64a97cd5cfc162f5dc2f0a6ef91638c3905c8e646b7ef65106acf6c28ed3f8481c4327076b6717f51e0f13ce3fd3a8140a6deb97b5b6f3aae2ae0c84b5f835c5f2f14d3c65559d0a6e620648ab624e2bfd12d74ff12c97fb6477ea785957ca3962fd60a22a0b54216575cff038d1020245796ea689619229d9bf9c5e823c187bfc4b1258da7b9a0357c961cb5ead2eb79a4f49ee499b968c22233909e7e63bbc7c61669ea6d2200c464cc78e00bd29d97e953047f186a47bb346be01f00ffe8ec0db811267718cf0808385f8c468419e9021b11801eda34549f3b3de73ad299cffea9bbb74a0b4ed34bc91d31bf74ba9e298c29283f7c5f3ec04ccd3dec8d33a843e7c4a8b213ddd64415dc8eaa71e354f5e8a8f9f1e970563c314a31b7211ab36b19f1861f42151907e25cf7fd98a45e4aad0f061baac7ac89aa8b4cac14cd835592bdfb2f40151f4522e13d2544fd54ce6224d8d4dee586941fac452acc7c7ae0a6eefffa1cd45a0bc00b95376d00cc19192af26aeb45ca71da0d1944db66fa3ff51216b8fc2309a8a748155fe808acf63eae70f3b7cd5a0acd8ea18c74bd1ae75414373d81f996884f2b8d092ee1313f67f92eff0464babe37669ca74431fe26b93e18a994160de0efe789acd82556fa3440cfbac2ac7fa28a0de5849c2921dce93bf8f493368af91cae6e48b71bf07cf3801f11769a3ecbe328f36c409aebd570db388d54cac7ad70e9ebd3f799d863715517522f00d77b946cd30071921a3c11931021624eb92b6d66b34da5a780b1990332fd920ad243b15948795e0aacbbea808bf6d1965235b23860cb035638c2e9b1c71ef484c6e07361d6b374f28d1f8bde9381baabf93ea87366843497736a293e86059099de1cea8322c642099c5a6fd6ef33837589ad5686284d740a5568fbeaf10e0abbe89b46912518dfc9fb85edc222929f83daf627ea6a13b4aa2eddd10615e068c203be92c3581cdf8ba2be4af52aeeb2c57a97e9500eb3e49d23f44898159adf53d6507d1cd87fd4e7b81760f21e29e28f96bad35af3fe3d9e85b1e8ec6ed08b66aeb590b05df7aed3c5f3fcdb7d034b0802f4adbde39d92f3310e7c4f65349e50096fd7dfa747ce4f13798bb1cc17a67f68aa9ac0f26467013abc388fd091fe253ab0dc90938a05e2c2f8373b6dbb1d927556dbd0cae2b73532188e2598dcd8e1ffa926ea7688996670e9c4a8574dd6ae49475abe8ad8366fcdcda24ad8357a6b1876c6e1d0a01416a46d25f29ab68ff715ae4af7e1919adb40ca537fae5fa242f078430a6df49f106d930e4f8bbcffd66d8d8e344c43483fda13ea472d1410cf3efe17dfafba4065c23243c2b8e6711c2f409b2f0a8d729e460a569aa36cf10a19a1863944a104d55cdbd6645f2c6ab2a8ec147e54b391812555a249023d07a7a5fbc55efb25a05e34220c1f15cd39186d15f171a76fc156e3dc70c6e2db25ee5cf48230f80a6b5a398195674736ab3e87e049cc584983782a19a18c2e702e466a839032e5feb8ba1664bc54bee2487d36b9804d28e2997e93879f5ccd243e3613581478efabf62f66876c9306be8c37d6d793a9c0cc5bdbf306bc3f16355d72097b1cf4b4d5f1e78357d22d6c4c0bf485d795758364dffc736d4fbc47b30601c3364c269071f25b1eed8b1830887e5f69f2117dfc2705746b375a76a8f2f49591d70b6ac7b06ec187c0f99caf79f1da73f341fd5946daf9d4ed9ea77a2c696286bb5439a5689a2e9cde482da018717cf1b5311284e837ab4159829e390d43126e5932318bea94aac6dc4e6eff2eb16001325e692b6ede2c424cdb3f5b59a4e40f58bbe731f214407ba65fcb427abcc9e1c210151c4adb4ec41ed526c020966c383f97ee4447979f797fba9cd9a29284e86114f540e0cb19c5b907028591dd6897c285edb6bd8dc4b185738d6f3d58803893ab6fb303c442cb82f242d2bdabc995dd94547b087290b5da197c519fa9a3a7a31996491336936d4b6d78ee82ee9c415f928c37c2f699c8f7ce2e4d68bab2ad835c9a456158d37ef65fb3334372a156c6b9fea628afdf3d932724531d831263f1dee8b717e884788f7a12261e9c52bbe4fb64ff02cd109681d2a555534840cc5569ef70836357c4785fb5e33c162f5a6400f17542c8a3defeee9fdd94faa4fd437c6252df3ffe52fe011775cb6a47aaab9f7da10970370abfa14afa5c6d232bea5a2af38874bd90db7a82beb5c6c27fac42f8b5ab661ee243e29bc31383916863c23d4095a676bb517559b23395b75a3fbcc841c6450e2401f89bb3ebb3b74606f3a138c791bff37b9b2b08d93d3a52a8cae0b5dca3cd29e895a802bb98933b7c38b8bde66bc3f7832b220adcad186068eb6022424a7aac8388f68dab18a415b964fca2648e9bf921c1e687821b384d4bc1a74e0c3d17eb82fcee298bcc3ca43cbbdb76321eb5a69744d08fede5f89eaec8e156fb8770dce82d5263a637bcc7f687b688fc646e909ef3aae401bf71ada8ef2999bedc165859f7bafe133d5d76711041d6d7a9013f703f7711668c8c8b2cee425e0a90f948ccd3a9ded91ccb792fa7ae7b3004e981cbb8b8c39a1bd503b4b298ae51b0b66e85f1b0d4b3506ebcd943111679d7741a33eaf2444cda3683c39d244cb7dc71b9f64dad6f791dbb376753bc370f795684633f630c497d633cb500b056f8e930dbf035b010b54ed648c2222d2141bf317faa1ed08d379e26bed58aab81f0457bd1f2daa4da0f4ec4d0333fb0aa73dff89197c1df9d14dfff4cb6a921a79d2452d6652dc07a711aa26a8b789b9361c5b27a70543b3cbd9a9d3fcff99642f22f29296504169de834dc60f0fae6988c04d67bc795f66c193dad061496e26c0f95a9870cc23b880650ed9f350c328c1f894408518f1c7c527437e2109c34f4759f4c11220f39b395b4f230fed1408c7c789de2e706a9b3a94ddeb31d47271a6a5b386670584c7346e09463fffce7bee8955c55a895285042413cf1572988f328811f6091e37da7f7f001bc86e3f9f445f19266365561080f002409887225a15ccecbf1f3b67a4015831b0256e8df507837d9c4d9422ae7acdfa82eae8020fd846b209a3a0d9b4d6be179ca85650fe041b21e9020ea459a865f413a1fadae95a6983c57bc7c325e893b98fdb0d49eacb6ab8928208b42dd22aec4e898628f6c90f921388109034c6619a8a92dab653c4a2f686a0b30217f46b5cd19b92d97fa5b95007a311c449c7943f0f074b5287436d41ade9f54327a7065345697c15a64ce8243d4485663170ea7165e856b2b1f530dd38852faa1dcce05e07f5c97ffad18e24b2b2eabd5dd0413d76fc97400fe0f5df04aa84d6fd7f356ecbf762aa4ea673a8ba853d41a7517103efec7a20e376d1be4cb069a4e7a37f87cff9df78ac5f0aa48a88606ea3112659b055d796ec6c16abe91fbb726379da9c238c525717fc353059cde2ebe9af137fa7fbd453c3a4773d202191c3ba9a4a72712e70402ac355002b1ece3a955349c3b17c4e52255c6dcff51a9ed37fcea13a9df6e95bc59f55723ec9339c83c682ba0200df60416b308604325d4f077b91aac9ead560cb252daf4525dea8a32daf9829665671b24ea157c1788eade1cef8c18c7ca4862e99a685397f1e4a4b72e015aac4c3fd1c77a443b5aa8a56d8de2bafad5e27d42afb03a3f8b39fc5a10391ba192abbb46dad72c2a4b7ca2fe6eed0d566ff5977874b03d36881ad29cbc362685ea4c8e6971263865075b4d69820e7910439c10ed0048d0b918a69da47a8eb5c282c16bf649eaf0547bb97087d091ca1f269764e6493741ef9be8059ee6587a8afbdcfbde64bf241a6d2b55133624963645695c687aa2d5b59886f1b453833eaa78246f08ba217b0c57e4bc67e7e5d7ff72d2004af1cde5a435b5bba6f63eacd818a595194ed2294543d56a215ac7cdb92faa7425f0aaf312d3e9aa87cb080dabcf75ed0ee8267c738ca342a191e80ecf76cad70ee05a853cb0097e92921950228db22b67c423e7ed9400bf2badc42a1d9391c79623fb7002d2443300cd1804c3d21872b284fd44830704a169bf9ab10bdbe8dce266e9998b7795e548f0a800eee1e20b0599ae668d88ca482d4e30aa2ae5bf62ed1003f700aed65b40f1214ecaf2c90f6e1ef9c34ff481250914efacf85bd2dbc4b26acc347b8b006845209bcf336c865592e20c708e5ec33f9c3f85468f0a28bb89126c38c1648cb708da7cb8dfb843819eb4d8798eaff08c0c438a60ef2678f70c096336389376bde45d2fc226939182549c326ac32ffd70fcb94c350924668ac9f9c277e05886062fab89ae754a8dd5ba97987fa07628b2d1a24028bd1ac5b3d01dc90b04c2565aea45402df09514684fe95f69a9ed60c08836fef57398fa0ecdcc1cd881fb96a5d56a74b3ff7846b4855eb879e59ef985aad681d96ce1628fa38cc90263bb850722dc5836c20eed02d88804c4637ce951ae00b53ce745f3067aaeb4839f6971b9dc80e1e73fa5c800ef24778090eeaa0f2d4955a0f2c135aeb844e84d894e6e163d7c0decff753ab68b9b6ddcc8079db8c9cd966f5ff7bc844786d975fb9782e1740ea9caf0c00433eba773165b0a18ec7ba23d8036bacc7e1c35e6fed934412ac22b31e6e4687bb6adffe7e7af54c8a781e93f7263a85fbd30290217ae8d0678750ee8a9cc2dfabb76dc7a90fda0c507b038e06a2c6b915d7550a21eebd6d38fe17439e3d9234a36162bb08f3e080fb161519ec8f045a33a3c5c62268391e8553c59ef66b64059414701b3a4ed5d0483467cd0d4ba050648176c637a5b062a53f5eb196489b0948a440da05cce7d2613ebadbaf8e0ec02b6ca897f93504363ecbcbf29c0283400cdf3cb05d9ad21e6e77e92f8de0367c3b7430cd2206264a783f87637e73f229328eb313b97b4fabf19e8dbf37e642e3cc13d14b1af63e516b38b3be198bc98fed922c4ecb96f5fa30342ff2614a4f45f0b98bd1ff3b4dabf7be27a7161d51234d82f8e9b9631fa44a6f18a6b3c1ac0256cfba471c71dd892de19f29680bfabb97fac035ab727ac6b3c7dfa9fce6371ac3401336eb6580067f8504d8f07643871ac242c42149b6f38d9b91f18d52e81f17637adac14ec5efb7a2c551862735cf6b8c98b60cc6faf464123f9db55f1cfbdea0e74cde2273b8499741608478a6e53dfbbb836df9778527f1774b41d07e28900b0d16726a9649eb5f7f678586cd343655074e8b4472b85b070b088ef1a1122ba25d46bb20c01b62c94b3d6d82e360df0a82793106098d1ee1db9bc690bc81ed36ea796380dec2a9c98868ecf7e5589797cad1a702b1450918de35afa7cd0b523920f0d13305dc5b5583142226203363ff805e9029ff3c3f148c1ccc4df0655b2ba018098a84822637216f6364f09951c3c700b1d342ba4c20d023252ca700002f760e47146b84b3a32b567b810548e1dfa553266634072b420b7b9a18f56dc0fad92bf509af7d3f16bd71b5a4e92825cee092212331f5bafa328afc854af9c7c911be5c2fde39976140f8d0f02e40c0b11f1d80eb438c955b32a2e94cbe937b2f83f838d138ebe3f19b81224a70936a3b9c62b7bf436dd61ecfb9108ef95ce6574f1c5a96d7c77645c6b92809277966c5849a100069f441f85d56144d6c3c7b60610dbae65cca4a34fad33ae29a5bb1ceac3cfab84b2b693852ab50816e1e37977177255d08a3c17585928af85af40350280f20a02babafdee4dc5e4a50537680bcf7154b49b2d729b6d982a95e0af0dab0c6ee5603770b4308f0fa46d8fcf9853b8bf29e15d8484138bd00153465e36601f6ad682fb52d05b6dfbd5ab80378b247f69df309fac61e13d6890f31c1e7f75e00a777a16e5d8492d270b772755eea8ac1f553b5e8811337f1358cfa318f2f79b76b97784ef6b374d7d5169d4007f8414f7e1d4482e4da2e86007eed68b70079693f2611a4f224958b18cfe6e7f9c4c1ced9695943cb807821dde21c89f1f2c7234c44ae679743d8531184b5a9583cc79e5bd6e51ca9dfbe2302a41db0010380582f7139c5b1c036a3618d871e41607e2e817a8ca3ca3372882c63efdc0ea6c979584cfe5a06b66f4c40857848a1d8b812cbe9d0361b42c2c64962e306f672bd86fc73acb463b08f983711044a97fdd159c7f6bd54b12becb4c1372a97d80ae7888dbd5a70764360767e523b719df56aecab725d54331cd6669b52bfb0d8a9422a1432e91352cb1c15612c8ca71ba4230ab3cc44aa86743f108159460be32bae8b147fbe750fe8490ae875afa9ea03a0186bffb053e0c593cad4f99d8744664846056f56cbfee6719e6ffa83194e0ead9d525b11706296d995d539f5979e498993a81da6744f9de87bbcc03e9d456381c081d0c932deb0c82fb62e4db5117d504a4ad031fcf43d39f76be6d24fc9c655241f9ae42adcc0d5b949f921abe2a3886b68d9b2962714009c93c7b2351c460f54dce241ffa2cd1072bce0ebc2738abe19f78d0a82e59d9fbe180e8668236d70dfcc7080154096e85198c6330e9473ac74d21415da99455c8819de67404fa92e51fc301840ebe6a9a1c7fe0988f594bb3de1f58e99db4a3954c3802a62a371862cdde8a89282cff49b2419aa066c7d017ced845d8ba66442990914d4d03f254d0e3763e1ef155d0631b645bc3d79388ab440dd231db0534632968de06e537e6381d1a6d6fccd4e3a5e970e00e2973929f6e430eb17e868c30147ece9d9bca80ceeb8851bbfc3ff32a9c93ea546c0ea324a24336cb1e7d4b07b197bf44866b020c5a8e5264246837d53320166d05ac01098aabfe118a723e9b295ac97cbf520a74486ce08f33cebe3673f04dac9ec8e06e1146dbff081b86c6b12431be82e456e2b8a9f7f0cb029cc3790fcb2bab555f3cfd3ec4e66738666dd8dc37f16a07a217bb743578a0e20f97ffbe1f9c096a8b7ef94fb087c5dfe562d57bdae755999aa51381018a017fc4419b38a64682a39d312cf0a1cecb12d382bd64b6bded44bd41f34ebb1e69347fb64de74cd05856867cd5d3c41e51748e368f14cf37a6d73d2f852da67b0b1f48d0e0a58a5df5f3ac2e68cee9b53b44c9ce9bcd554773a3f5e149e3f6c4b5d5834aa1d2ce8e766bc1fdf1879d87aa0e8bf30beec1d767d6bc71258bda7c23e6bc3c4b362a80ce47ee09e7dc2c74d45eca58cb4d2feb1663c26591bca65d019e0d0817c1d922335ce901c9314976cac9be94663f26f9d87a3a32d8a0f1327c3ba0df55a4d540464b8bbc5ae0361b53a2ec792e62bef15f900dd23b3cb92742b7f6079c2f1258589f5b94d1b4aae8019dbb551b208eaad3715b1d9f240544b4f3cbd5d75968a38d15280c70eeb299a604060842acab915e440b8cdf3f4a3b1e0671d223c8d857ed68e334846915d4224e4046a94f6cdfdf35f26e72e52d0689dccae61dbf810b67a1e9fa2a94df55b7c6af524bb428a998c27152d9d5fc269294368a3275f8c3427b3e32d2121567b78f6cc739c9c24e13718dce3afac8ea38660d37f60e373e49fbccc47bfa097866d3d0767ef147977a0608d710b346e8254a37b99a4f6d37e165ca32ebc261bcbfe757614b5bfc24c2dc8c334959e07fd43472481ffa892ed2ef7612f5cd43a06c93faca4c86cf1e77063e2fdb188b110da018940ac08044f88c82b2667bc62108a1907721dded62d8b3c20679719375eb07e72e7f17f3613f6b448299ce3c880f8104e823462764df907a214526e2e11edf7d92d89ab40cf0d0c4a635fbd864d897e1a76ca78305c791613282fed0e0972af0cc3fde4bbf26aa11a0adfa1836bb581b1de7fc5360944c6652cb7329736114ee44f86c167bbcda7a54e44e11e5ed460f6ae7d3c9d3d0f9e7d5cd1f273536fec097b41302d2e822b8a8fa514bb2478737878ea9e23f3fc252ab8d6257545e965b65d399ec0866a228770b76c17dc64dcceac7b53367f4d1d436c84b5bebfd78895015e81e4fc7cd1b856980bce1871d19103bc184a1e71a473a71dd2c74e5be21e3ceca0121a82a43b18c7dd5ea1cce23f492d063ef3727a771bd51df069a9f86cf43333c1e1ec903decab8976b7083bc33c00ebdb19119568729debc1f1aa7d32a9e98e04cfaf01f78c6f2f574bda353d03f022c19b1f9e657eebfaeb10376d5b088100695feb790319966d48837383974d34ba81e8f399b9048b1cb48eb41729945c2d6dcbfe563ff60ce4e5edfe61a54f95f1180813817ec59a48ac7ee40b4c036e7ba14d67ddd5bbcde6f27bcac313912a1528c1c0af9662031362675a5dedb9d2ac4ac4bbda8f13550970385478a7d08703fed64b52a041de87d6d1637efbec86a3b292049fb86108f22bae3dea1756405b047b20fa8efb72c229375bb84be1db7f393729a4436390a1921b082df3d5904473b6f1b1186cf264736a76528f46bef5c4fbe49c96af54febc4214156d30bf5e5dc7e8d92b94023c3529643e7352df99017d0a0cc55532ab24dc60eb619ef7a65c960a86aca45fad9db2ac487cd09b7195bbf688bc68bc7865998d81caee7d9ea8172a7e1e0cb4b93813f176de134d019fb063119679f8acb241832165ee6e16dfd4689ceb25a2caa3e0d05c64659e4f88c09be871f053a3c513453ff24480e9e5bc49adfbd0b70acaa57c33b1ecf06a073b35d72bfb6c22c5ab8bfd9279fb86a74bc394719215bba972d42c0c0e10dbb712b8ffb0d96723d53c6bf63fd80d8b1022c5520f7c94a4c6acbeda5ae64a780baabc6f6750d2013b76fcca5ea8c0ff9b87d6b2426b322fbaff8bc4242eb8e21cf3d16402b8f2591b8891e2da8060b0525ec4e0eba4dd0f0c0138189e6284710cbd6b87a0e206dba62a01598489c4e9024deb25efec5886f529b1d4e7a7ded47370a3f17bda4a30e95a4da12c4ef668d39345ed138f20a11de25ced38e4be3a0546fd67326217de735787762b1229ec1d6661495b9f19727cd23a6010e885783ac0ca8c0a2749a32a1731cf2244e4824fc2f60cfa7ca881e842088a3213dff5a1d73357468b39efc7f69b26d5eae616dd72617b5c8c38d062164f01960d5d1fdf7cd0e544c9799ba61388773670bb07b384c49630992705e170b435c3aa1ed85092c47d9adde1aa5317385b95678c2d8d96dd65a30a4104e6090909cdffc0716a96e828d73da7a02ac1772212577804a3e130ef11ba1547a658312fb85bf9071450d63a0b2d9e33b4f009193011060653dd8e2acdf0e425ad981a84c03964b4ead119c7c6e8bf08b4fe47957060bfcafd8e70110c946c4342f9b1ebfec5cfc87d3fddabbf3e0cd3e535befdc338be3b19fbe4989a0087348672bcfc977e8d5dad2997677c54a1a420edad4bed6c5cfc710b5121cf6e03b6e763e3e7c722ed381c83ad0daa3fa4e2f72a37498a947b6fad71b982c92a3b30bd27d15abb7ac0533bbb62051fb3e2db46088b13f9c795d725465470e333421e78fa3a1349a32833242e9f1a1777b9354ec4ce0e5b73d3d71150719cfd1148fc3417e9ccd15073f42ef4214041e5af4911a9ac5ceb4745f0c93a0e90b7de9a2c8935b88744ad42c8c522e5581ed20344e537a91c1e648cabdee12d3292d58e7e6954de6193a5f3a19179723dba7aeff4f60a5810d18d7181e1689f5c16fc4596d2c875535174c37691f1fecd1c616b9f93b7dac6902cf1cec9f3a44d597ad9fcf8ac2ce58546dff9dd4714ecca19630c2e999858ef951eac5ca3920364fe3d0e24489e0ca52d494ddcdd58bd907bb85592b61267e53f3506983298172c6200f983fc1a7f3f27a97c469f454553b1d7038336f4b2f6967357c1ff469055bff32e508be6ac189d07dab7956054fd2905b12cfb45f26338bf0fe9b82880f3f4ed99a457f29f5c1aee288cbfa02aa23c973848668b9295fe737f6fa00f4e76f04fd380596b84641c89cb22403b32ac3bc662e820f149eedb0b6de1fa9a8e8d8bca37b2364976753249eb3526ecedf9e4bab16a3ec5e1babee96fa9874ccf95613f66abe8981007d899a40b5e8ce12edc94347216171a6508b4f0444274caddf1647e6dd0c449c354ba851ff20ed014d84df8ef5606723bca56e01966553d36535fc106b7044f2b4673e8d6c7a1e2fd9361d057c10945b48dfb08616d163a4d4862396af97e2010a2f1e123513a3fc6e3310ad7bdab3ab22da93fe1fc96bc14da815fe1caf64a79a9e006a92883fec2f811fffb2b2f27eb9fd3bd487a3b7f99bdc814aab73b80fcf943d56b5d77c3f837548c4adc34b355eaa8381fa348403a98678d5afd26856072cf28ccde5554f0091ce159c06aea195ea2e9a02c5a2c91850a1f363b0e964e748f64c289ddfaae87381591d13a3938f72cb1d11a8ad64fd8b06191d78f2b5e67e08f2ad74c85b8e107b0e327c6d513ec6f0e32ce149e2030a318f004ce0295fcc142705836e3d8470132f1d74df7209fec0f3bf0eed8ec9259337ed4dcd4c075937b53754ea77e470482f68154820cb8a348fece9c5b2d50d881f7b6d418a0b947343a1a54299ce29b398a3e6b70c6513c108d8e26c7d48979e4c5c9701145889815c889f6209f0850433aebbd176cabefbc8a268fe604d163cc328ac6cdf3dab7954a2ca73e50ce57507faec9facfd6c339fb46e17271b1048b63168fc76a0990133920240f40bd5a2cc78911a99a7ee2442a4ad4cc2de5c9901ce074073b2995aedfeebe571020068f6cc6f6aa11c33d11c9593854c1599f4591c403339afa3ce365f69d0c03ee82b3be24123fc7eb7dd59d7d083f394c870188aa16bab0264ea5903ec415090141bafb1c2f4aa71e2271abd17ef0a10180a18b089e883a2a126046a2b9c65e9c58206b36ca7ed6d8d27675ccd14858d478197b9ab6c3fbd01a3900b19bf7f8a0cc270722c076c88c916dbf0b75da351e885a07bca56ce98dbc2805da97d5f30263a5cda871251dba836df60dfa4bd7cb9971491a732036f20437b299f15404c1cd9eae82f9c3375ed361fd76885eed12750bcacd659cacea1d970e0bf60016e7ac9d248576098f848bfab9ded15012fcfc629f786b6dd0f3cc716011180ad4767f3c9811febe31ff4fdc3d920e7721d4581afbdb5c2a7fea8c897131f90cd5f8812b6e0369fd44ee3afd454544f54b9285dd798892bffb8618f91910709b266b9cfa77e437233cbf601e46c8bf2c8193ccb01d700ff81e856eda73a9fd4c1c094d9ba4c20a0c09b51ce03cdf2b44cb41d9bd306863968b1000000\";\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(\"Circuitfox\", 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 [\"Cyber fox girl\", \"Cyber fox girl\", \"Cyber fox girl\", \"Cyber fox girl\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Techwear jacket\", \"Techwear jacket\", \"Techwear jacket\", \"Techwear jacket\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Magenta cyan rim light\", \"Magenta cyan rim light\", \"Magenta cyan rim light\", \"Magenta cyan rim light\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Neon bokeh city\", \"Neon bokeh city\", \"Neon bokeh city\", \"Neon bokeh 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\":\"Circuitfox #', id.toString(),\n            '\",\"description\":\"Circuitfox is 5995 Cyber fox girl with glowing circuit face lines and chrome visor in neon bokeh 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\":\"Circuitfox\",\"description\":\"Circuitfox is 5995 Cyber fox girl with glowing circuit face lines and chrome visor in neon bokeh 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":"58057031","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T08:57:16Z","match":"exact_match","chainId":"56","address":"0xD12B23694A910dBC74EF50aDBaC6aB4F6b34F55C"}