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