{"sources":{"Banshiko.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: Banshiko.sol\ninterface IAgentIdRegistry {\n    function handleOf(address wallet) external view returns (string memory);\n}\n\n/// @title Banshiko - 1111 Little glowing banshee ghost girl with silver hair and a candle lantern in a moonlit pumpkin graveyard for .ai Agent ID holders on BNB Chain\n/// @notice Each wallet gets its first mint free while the 343 free pool lasts (gas only).\n/// Every other mint costs 0.00005 BNB. Max 50 per wallet, 1111 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 Banshiko is ERC721, ERC2981, Ownable {\n    using Strings for uint256;\n\n    IAgentIdRegistry public constant AGENT_ID = IAgentIdRegistry(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    uint256 public constant MAX_SUPPLY = 1111;\n    uint256 public constant FREE_SUPPLY = 343;\n    uint256 public constant FREE_PER_WALLET = 1;\n    uint256 public constant MAX_PER_WALLET = 50;\n    uint256 public constant PRICE = 0.00005 ether;\n\n    uint256 public totalSupply;\n    uint256 public freeClaimed;\n    bool public mintOpen = true;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public freeUsed;\n\n    error NoAgentId();\n    error OnlyWallets();\n    error MintClosed();\n    error BadQuantity();\n    error SoldOut();\n    error WalletLimit();\n    error WrongPayment();\n    error WithdrawFailed();\n\n    event Launched(address indexed to, uint256 indexed tokenId, string agent);\n\n    /// @notice Contract whose runtime code holds the artwork bytes (WebP), after a leading 0x00 STOP byte.\n    address public immutable IMAGE;\n\n    /// @dev The WebP artwork is embedded in this source and written, in this same deploy transaction,\n    /// into a small storage contract (runtime = 0x00 STOP byte + image bytes) owned by nobody.\n    constructor(address initialOwner) ERC721(\"Banshiko\", \"BANSHIKO\") Ownable(initialOwner) {\n        bytes memory image_ = hex\"52494646f22b00005745425056503820e62b0000703e019d012a900190013ec158a44e27a5333228526c12601809656e1f89c4f57fd6ed709108e03564c51d137acb610d337c37ca67c7bfc9fff5dc8bf4dff8ffb0cb3b76fffa9cce6e0f8b0f1935537ee7d101e1a23254f08e9f1c6484edbf259a3765868a73280a9d411b602299df760592e642d6f727c1f1747d0016aa985056cd8a8dcd75e4ae6adb78b936331098b0845c6dc9bb1d3478f317919e87638788ff4da8b6883eaf3b738d3fe1ca719954a24784a81be434eb81e4e007dfe1d2bcfb010bd69a090bdd2ff696496bfd7c2b46a65eda43fabbfa0c9746fffaa22ab30d02a90f528c74dbb8d3358fe4bdf30476095db9ccadba1910735d71c8cfda55c9b67dae3119fcdc1b4b43fa59b22b32f7931b775b444bfbcf0532594053d5f5092b70eb892de8a7c8f6405d3a858f252ee67ebfe7aefc3acd9c3fea462b7e6b5fb9fab703d4218732924f9df3c882393d85edc7e9740f1cedd6978ff814700b02655060487f940903fc4d95ede66cd1e87a1a267b5fb2e73505b77050c359e0578f3518ded52a1e700621e0ce4cb010e65fbf21b4831f2200144e149ba2d1904a92fdad991930ceefa44fca144b36a59cb646b80f265a53504e2beb54f8fd1bf2f00877c540c779afe61494cc97151ea0fa862b642675c2013acd442956b4026bf3bbe43a5d48b9dc5c4a2d5cefd1a70f186fe2a0bf519ed94be63d4bcec7660dba6556617223e6f411a0d26106e8286a5b2398ea72d39f1cc8c72f403a6a92a7b3d7f099814653d4e5524cbe02a2def290d0d631e94781d0ac7626d7caa9ae30d7a3a4233c5f1a5c408339ededeef3221973d20b3db4bf874c746dcdb1229b36e94c92cb0a6dd91e34920115516c73c1605193d3d08653dfe54231da1956e78deb5ece9d09ac96b2d547f6bba5c6bfa54aba821f48654fc056d5ac2e224fa25f6e170b641f89eef0a416ad006e4b3d766ed3463b3bf0c95d7d3cf7ffcf352ca61386d9a288504ab9818902acd81d3429a984120b373f25ca4cc614f304527b101d252a8127e9b710b395ae3dc4ae365136972337e425ce0d6d45efd6bc16059b41315eeb17f4823225fc1ddfc77d6207010023f68a046e3f73bde423b33d02595f44554170b8a56d8de3a53868e79809290db5ca39bd0b990bec48e0bf4bb6145a4f4f6e63c51d2059654ea4f9dfb6f419526c4812bd050041f5417d17a1e49eb6884b7a07e28f7dd646df1400194e3f0f96354c7b0ccef66e22474a5d48f8568e7b0e1b76f07fb5c314f55597d0a2dc8797d48b84205cd2a2e56eec38221ef2ae35330ab8c3a5bb28bb4f1e18b8b25db471c017d77d5f2d298ea274da437f18d7269b520d32523a15094ab02ee179bc665f2c1828cfd9ce41e8c740f228ef4bfb891445c8c12c78ca4dacf3122f73f43cd928a0a93dacf9f0ceb458dae99a9de2a4e22c342cff47ae8e8eeddfdfd9979e2fe4ccee2f6bfba557a85bbf78406adb75efda8a7137171a82322d7a1993bf138f01fd509e0ac177b3ee21c1382479da94e57bbda3ae8538bee113d64b14ac87b045458df19838fcb860c60890ec1fa7b53879b3965622138a0871d35067f9bfe9ea74ee1d93fe02fbb50bb0f4707ef5da4f9cd02aac3592c40b3fba67184d7fbeb67aad58b6ef3e6df443566359b55d46f7bbc730e262731a1199d83b21796b36f0f10c3a0c6e2754dafa0dd9792f507ffcfee1f6b4810ba2ea9dffc417e3c219023d407d39f6d5123b753b7bc60a2fef469d5d96cf92e3f5abcc99bed40397a69e0b6c46d44ec26bbb0ecfffd616fb3af4705a29d62bd0175e2acb896d0a034c2fb749caea61a32fe7000c0ed329e8c0318d8f7fc53f97250960d7ed4de0d61dcd2033cda51bdae50fb9fe956023ae95ef51684088f345e4daa1d4565236ec16e737549a721c874ca6c683f826e8eba4bd3a752921fcb1a2805498fdd0f14abce13c8010eaa6f403b5a8773d29dbffe303ebac0b5fe3708589e95d4b1a9441f9fd6c6a04dd631a9a946ed6e383a090dd96583b0270a1cc5d16e8fe8dedc6098cb0907a3d1be82476812705c68f2e78cf5a76f7a1e029a36b41719439db349726c12c73f81a7f1614b4169cfaca9ec9a2f0b3129c4925b3d2f5e44b6ef240901f043f1e33fc53ac66d6d4270e170306d158bf4ab1da36fb5a71b04e4568e0715058fb26a7930ac335777c035f6bc4904ef6a26e9b8d265068a7bd3ed0b8252c58ec504dca090b86846be0ecdc570af874d6d55dfa53faf75c78e6c4c2fdd78237b02ef13eef469ee178ae949c1582133f027bc13964476bbdad0a034d3afab417742b2ac9804c96c07add1ab52d1123fb68d27402e9c29ad6fe2ff988863d74a4249f4a1ef183c194ea4434da43bbdc6cacabfc2316ecad29c95d6deee1afbe8c8de2f4f299a20f8d36cf46ff2cd9e0fbe3a9d6f8b79cb9fb0ed74d40a021a0c0a8ad2ac009a0ba7cf2eb14040e485a308a2c3fef9309285722882992cdf35918b52acf900469f0798563662a40c5a5a011742fa4a956b907b086c628872d9ccd862c42a1096395e2fea110699af7929cf5e735eaf0d4994f7c58df27bd91b3ca70f8daaa9b01f04caf53d1aef146e7935ef89cf85ed8b0a3cd005b056404bc2f5603848f9733c39704c465a232760202e0443230e8fb767a24490d5f558f0699f7666af908dfb2d106a9799140a97520993fd8706b8fdac74261ded58a3fed3ba28c1bf7d33bad36be5cb0b720f8dd5d9c9b230f99c4051821f568a575c9a64443ea9dda1031934499e10b3280bdb26d8645dbe5121d978aa08f7635e3149a920fc2cf5530986e39f5cada091820b59e5203986d3cf8771fadc8a01627a99b2970c805b91c9cf94ec80702a3bf34762ab0c154a3a3fa5d31ae3bcadd8e0eb84a6bb5be29856fcf0084d534e204de20caa4604f7b86076921d91561c49179f3ac2af3d7f77551d3f2e543d86d48207d807f66352cf0409bcb22d769f4876daf8db51e1689c827e6c9e96218e29d020ed1fdc3fbb343a72726c6fc9b4b6f61fe36125975f237dcd9eb0bcb19b50504ffe72b8dddfdc7ff8a214a3fd199705dbb68bb5edcf08a73e8efeb84366368b343c924c822d7d5856d5134e01367c9d3f4c6cdb9f1fc2bac21d7516d235de4a457e56d971f1e72e5c57f9d3f70620ce3a6bbd1d75f98e9f3cd1e2eb3da8c58b532cd44c13e74f4dc9143422cc2246743e68a07b6df103c3ad152ba65915addf5c74107da5b96b03de9663e891044aeac97cee81d608abd760def69e4306db18e76d7b1c0ece4f66afecaeb00c0f927a93c1181784ad179ebabdaf4b006001a3c0048b1e85c309a28e5277cca83b5ebc9fcfd51f5d0fb038063725eac0241250b0302dadfd7c01d8e1fbeeb079bd0605f486c6c776a5e6376a7083cdc225d4a51ab73d22c62f3f944a6a604d2001d600e2ec28e0f285b9ccd62e6d0ff5d4a6243db358da903ea2254d39b4b5fd6e4e04553fc6c56e7eb4a7b93b621975c653162a49c16aaa7dddd3cd0e0a39ea7f64a761202185fbcbf95c79feb6a7aec16214c6231988315832a311656cb09c318ebb169ffa9b62af179895df000fef7ef308fd753b2df1f91fad9895d95e9c273707c4ac78ef9af71b3c4ee0fedaf3557f37f6ca80103e7c97166e0560cc6280290360dad453e2c85445f141cb3ad29f9cef3080d3e7ac8805d9c97697671baa4997b5828f292864def3ee01b027d50adbf8dfe28deb77730ffbf3e93ab0dd69ded959976261ba5a5e7233c0521fcb2ecf1433c5da0c76b99f03380e81c650cebef683bf0ff8c13b3ba090479904e1955d01ad6a7931c16f82ab840085ffd52e2ea6af6734f96342c09e34922b9b02416916c2bc046b5e1491bd775fb705b74d4ef8e9574cdd5a427d24fd7d100c3dbf61053e9db30961903fb725cc412ee43ea2d6676e7177f5c8d7eacb43630696a36d14b319906b74a2e6254e33dd97929684de4cdc89f1bc406e7d1a52cc5629eb83814e0cb3cd91cfe8cb9a0f91dc20082326e3ad569ff401b5eaae81d7dcf2f985e926edfb7867fede3da46e05bd010ec1f72257c0622a2907d16ac6e401d6465868768b572d8b9dd1ca870af21d6218cf6459d04328768bf10e97672bebc2aea4279f727bd15b16a46bbe06899a5c624d393960e2c84e18a4274df2739832c5e8dc0e55648b0d191181fa63e4ff92e9fc0ebc55fe1e76f0b16464e1b5ed1087e8f40db73b1909273603ce369abbafb02fb9e21579d73b1425d3b16fd7524130837db1a1b5f6d95644f86909800ad36d9e0bb5cf576b2f80ba6f84963c1250cd2a41a35869a9950fbde2f07729fd32d9143d49c0f47296f531c47da9192a55eb6547ef6627cc4ba008922c7ddb92251843951d32551b2144d9985df2b3cbf7c17e85d31ae01f6c9129d7b16c0c52e2d31d658ad55e32271d22602854b0d27ceb25edf4781b4ddb7028a00656ac5399d35465b1eabbd4d1388094b78adef7f22175527d2eb472b056ad485dd693347086a6d9854d67f673012d21e1b540e23b64d9fb6c4a400dd0171037c7235a87a20a98bc7414dd5cdff2db653b91d2c4d009c8efa1182863328389d1fcc2e342bc399da69960c1c18cd3df8a5dfb6a4be0ca272bdec4611f8be2c742c4a0d1b338f0dd19b185f8fb927132daee8236dd10a42cc8a554f736b636a3d13e9325fcee25c3cca5dbbb6d54d9d3b10c77e899a84ebb29beab46489d15cc2449c06e5a221992b2fb3a2242ff23b97f16ddc7e81e8c868ffb06cd201f61a618146f453182a94167869670d81a1c729e23995c209849d88c6977ad6567e42d510bd632657d243d10c6cbb6414dd23089c54e0ad6625993b18e6eaa56a06bb9fb89d4e047800722707cd838010223e6f07476a04e07515a8295cbb90b30e59f1f53653cf3e163036aa48193d8d9e7255ecdb9a5d2f709e897d3366d358e24e821b26ff0604c84cd9d7d5668b072aae70c7e071b7f43e5a7762a55f4a31e86f875016f050dad1ed9681047c837b3d4392f427ef6abf01cc6f2b5e804d63451c4fa9d9f042b8354a9430e69cd7d7ff7f9b99a3c577e666be85c2f3bc54f13c9724dfec4500d6853cb99286b4e777b5127668f0ad1e2c2961a3b965af2147566c276a8070ccdc047b7a82f7d1c5b6fa39d2906e3b697547b9826b71b4bfef42d1133de5a654540285d9df78d7ba281d7bf0accac884c5f45e88b7452dcefe0d9f12b4bfe0b5374a02f862542fdbf4c5ee624acea55992f24875dc0528b2d3454483964a9bfb8b999b0147a6306bfc0daa151a07a3414067e44dc9863bf12a0984dcd89c9631e9ac4b40f30e4acafe470fcd321e60aeb976cefa9bfc382df8e3e34a9470bdb944ae7fa7402bf7dd398aef926994679cbe4e44d87516ac43a5131c6c09eecb22f4f1621bf7070d244bd2c43095f30d500d2daa4e0dd3acf28af9a5b1cf09e1888dcef4520756fadc25ad6e3dfeaceab2778a04e6d1523a794be286661df12ab847f7cc0213ca4ce40807b0635b42ca783d5a4d2f44ae0b2602dd8e7d3d9a17f1784d1817771a690fc30d08cb838be0d2480e9d32c8de271f97d17fe4466de30ca7fa29d635573d4059e10ce578a07c25b98dbdbc617f65e2b8c6b9291f12ceb0e8696da482c968d900f7618553beff02dbae9d16283a6d8466b5fe9b61435ad0a27860fbc7d1b8ffb07a707b1cb9d9c8cadeda6dd37d6d2d9fb4eac840b94306e099b0fce0abb2790a3f13657b056a6bd6dcaa069d45d63875577e18875a475150e70c31cc15fcc9612eb7ca2f7d929b2b819555418d1f9767252b193ab0860e22436b8b8b55fb4c7c8ea307037a34603c779820984e125e02db3d0821646c2bbb525bd65d7912d789a3a239353d915cbb807e12a0733129b64163c089dd5ff932f24a319e8c5d65d789b94a07ae29810bd0333ef99c4096f41774e8c7727fb4535b7056cfa1f9f78ef83041ebde37d6d837a2704b753614814e5126ba0771e08ca034e2ad65e33ed11919011ed6618e908fabba398395290e9b51361ca9806dcf41c125c06d10d9bbf7cf25c5d54d8f1628be07056bdd69e58bc4f2cf4869b03f5c6b2232acc050480e9e625dcc368be9fb7b3583ab4ce676e476b8196e3d050a98f0581390aa0ddb81d6c9c69165df4766d51526a0420e1122e1902279b15210c9797a768ade098cc4c21e2ab96c6fb8df82bace9748f5f9dafc8a285ecaf4f8e82adc5c11bf5173bef642adc3f6c6f0e3e75bd80971b9ba3a5adb1cf9fb4ea2acf3bd65b5d2510d39ee3b285ac01c123b192595057c35f71620b0424b3cfa8a22dc58bc824e432230b59ba8c4a98d69571a47d4e22d5fdca057d0828be196fb45c18b83b4af3a5c248164811bc6ac9060849b7de9552cb4d67f5f637dbafd0f82215818a21ebff6c3eee08c44c2c5fe288aaec512d2feb227caf06ce97e8a01c88bf70e63ea52b0283fe8ed688558640fc09c150d4f77e7aaccf0fc12d6d1a605a8b57d9bc74dca85120195f826d93cdbf21e4a9054f914d2aa25c3f226070c18c5792a13e6451426065ec2189b46887623d1db2042a9a2680a87efe4e72730c4e6da677c90c5ec6b0d4773788ddd2310fcc6d91fc31fe0c6e8ad58772b48d77e75c6f726b2a57561457b2290433617662d7939f0707759695eafba7437f859755807c0a9d18ef6c5dfdc6b16b77dc95955fcab6d164d7988babc0fea9cfef8424c370daee3313e47e15afc427c981de1e1bffe23580a8218e69cb0be6e51c1b9f3633f7cf77db1bdfa8973ca5f66908b3353aea0d2e3d81df6b91f19defee990309769ad273fea31bcd7a893fbca1ba011bf1d30bc423875b81bb77bc2f73de643d8530cc604b67f2c1b598a5a75e4eb2294e2868ab3bd22e8b06fb423c621eb50df543b5023ffae85989ee3734c3995efda25bd73b1a8ae67b4d0eba5b07a0e005ca7bcde232345e45d9545c7818c5e55adc8886829f7261e75428340e55257a6f7be4bf01d9ff2002cf5a81a86ae040a43d4475d01537cc8682f8ec597feb080ec0f8eabaffefd06cb42c2add8150c51c1f2dd15360d78c2fb5e37b566821c2b85e6621df44aa561b63e2cd21a6b92f1df0c605732ce6387aa58b6445bdf145b1229ac08912c16c70f78d1b864620de576fa5bba582c4e0fdecf82a9ddb5e8d3f3843892853a68c4bccb13a9994587a24280e497ba3aa1cf73c762e4eaea497d3ef09aac8c74328088e9b2563f5d57fdf72c55b973acc26e07d865af1ffa8436ac6ec839c36a1a4871a1bd58244b104071e6da4b4f94fa4e6b95d2ca55056e9f3ddf98760500780f520c9e8ee4cc517fdebe0e83ec4a1b8a5174338649c934bd41ce1190d1735673b5c03b67e8fc515571f30361b1f5c054ee0bc75433eb92f89ac1284c73944cfee6f27f2a137add78bd39050203f9405a4158711fa6bf65a4d4ef13ec5121766d54a4a0b2ec122465e3f6108cc6b94a0c76f510405c337080cf06e8de135cdb9052029ab597d240ea391181de784b0ac013dc6ff045cb4f90fa1b5fdff9367b03ec8dab715193a0ce2d94bc3bace11262cb643d2f05c06240ec80c11a928a62de939b3f9c7fdb4a48913f9ff5b9c5827842e02d840f1c4825a439f574c067a047af61d746f4dd0714de538d1a1bc327fd09aea170d953db3ebe2cc1be1e260ba70dce09404088bf5ca33472ee395fb354f1c443bc7a823ea556b1fa4dcde5a9e77ed63bed338c07929c6422dccfeaa12e70a8c3d6e07637c7210eebf543010d53d05ec66b6221b1affc310a028ff154f35c2e184c550e8bb2b594e1974835c5a5d9e804db26c81a18075d0de78c870a56eec083a5c15bf72d15864021019085118601d25dd8cbc57ad6e950fc709a0577cd3c46e5ad5ce7e358d3f7e0a4643397dddedf48350989c1822a3ab81a70ac4e65acb18b7fbf440e5994409acd699f41de57708959cecfae1d7c51606d847d21654fa488f502c01cd30e7c4dbb70fb45c60eba081b276325499d4af0fd9b1c42293c40e0fbd13de495c379a247e853f1f620ce7266cdd0f053885af63d5b27be45b6bb6c7395cbd3be77bd02f408cfd28f222bc4c9b5485ec7ad6272cf75e9c77ab3ac1e83d67ac6634db8efb5d013e97f94e3d9d1e585304dd6bb3f29670d1a4f718a031656b838c4194485ffe9b5446cb912816d5b3e136a1302c1b1784926fd6ac71ebcb7f050b621743129ec7ab509ab2980fa8dd4abc520d7686daca8c274861ddef8318bb9338a55d71b528049fdbb3cf07988093dd19de65b4ea3fc647d2a5acd5ef1402fb1d9154c2bd02c8ecaa5d07cb27ac1b9ee0b465f60d6a2420fb471bad7242721b0eb1c8c081d24ccf2db711fbaad056be6d3827226d51a962bed15aeee0171dad40b3de7d11b6ab830d777cee6513723528b8c9984de20831af28135242dd2efaf0621f7d1112b6e77a208afd21c4ea7b5ea6d0c153f398ed69616e25ff0d4da6fbadac69495ef7f5e8f96166e0c1051f9cbf8fc7843da30478eb1b4d96439af21bba984167ab4308b9bccb92430db3f20e2641753c51dbcdb1299edc5a3a715bf504720020be8e811b394c2425f302e645bab8a3ab44e4eb68905e46f467897382a4ba0bf6e1121a2062ebea381314639542106cf5a634f50f80990e9b6e2b8ef47f110a7d10bae8b77e84257025d7bedbd38c00ed570cd457cd8e2d4717e79a02aa5a81d4d0e652cdc3b3accaacccbc8ff4fc3b2569af0cc798aa756635f2e43803c8f6dbd819f7c455052d72107f49b3b8048b38ffaca55eee570c5244403fec812e6bda3b7cae2df415950c3981b782b08750da6a936194aeb9b626356a38165b1e0579d5a3d2125dfdf8cabf56e5958e8838d63ad2d3e2d8b3b3587f8ad299182e911abe46ed0098b9e212dd82bcfcea652e3aed2c63f6bb9bf48ede0eb7b9d6eab07c481eb89110b2bcaa0ee60a592effbb1454438a7637d956ecc7bd65c58662468c2221efa829af83e6fa96646c1f87ed1b339a4dc5fd35341142112a261d8af9ed1586590db50b83894ebafe111ad5ed43168d46410f7674505cb982aeb9fa316d3db5882bbec3382b62494ed1e9dd212d9b69dfb407d1ed9a08db51dc8d39db61d15b06e965fa45fce19af39b06f4eca79afbce30d5678579e1a1961b90e7bc0ea94bf0941c343cf2464ae64b909edff57b3c64ac031e438a2dbbc947543799551f3678e75960ba28f4a38de745f4ccc073cf8ab877aa813a3b6c5f4a0e1973fca899fad8d7a3cd5bcdb979fc5cd6015e73578c1aaf9e628ea02ca1110700aca75ee43ecd12aa0d3cc0fc8025035a15a22a667e6da611a2530de42ca98cc07771c15f8ecf2b169d0be728737fc70426815e1b261719bccc79f4b54856c0971de1d87f191e7d9ee01345b779e1876f563bc097a473da0c30add9981a5fae97bdd7b29e4b88cd66d943477293efda5265b06bb2d1f09bad7081507f540ff213e64e50476819ee683a160ffd67fb54caee2dc4f08e1daddb12884019aa5eca46d357ef5a2fcb86a8bdff0c84c31a424a0e5edd25835431fa92b25552d61f067187ea7a58b11305ba735301cd30b3767d28822997234a2bfd0852bf7e6bad1b112057df957b92bb6918c9a21391e94d5c5bce18ecd1260bd2d0337e5e23b6be64a21fc74a7f48b494216637288226fcff01b8cf4d8104628e10bbe2bf57170b07b8a20b8afc94dce0f38eda807975469d03e1e2a79ebff98956f0517f609eef238a81a856c7397a54b391506fa95d0710afaa312a0dad5c90b441f7b558f035631476c07163ccbddb71666be205f5c018ccf6729be811df93bae22a276a8235c4ca1b721a8ffa7158e355628261e9c25f184f58d88fe9c77cc8e7825b97aba3489051149ead38a7a703d61e7e00dbc13281dcb4dce67cfbebcff3afcdcc6de5424fe7c132517ea336e7c18210f71f6458f89f0a845285b572b04d45d50a3afaeb8a0ac16c5e0274cf2330932102b3a6ee600add8648b4ca357d855e18f198eb710e13518faa7a95d43b48d376eccc32bb7fbc5324ec8f0e5977af0a5956abc414f16652cf1120420d33d9d8ab408df0b3d8241502a432f5b82ee06262f358aa53ee3a6b66bffd8b01f76eedda311959f14d1adc14ad35b778d875bbb061cd21b594ab63cdcdb3d8c7d0506dee243f0f3f1cb7cada90bc964fc0d8ab4fc3028e4ae0ea5ff8a9dc64c4a53cfd79c6644b5bb6cd4ec76551b7b02c482bc2c1d21ae6900ed1a7357fe6a335d8f6cc6de776441149e85e96e907006164cc0da31c06c8541e5761fe6f5c298acf5141355339a0ec2315a958bb919c9a9ff9e31f83511afe71bdff613f3b13c0ae3346d2cb8ff146d7f8410c191b2c2fce888867355dc51f22d4b5d07af791e0f60189dbda87c1d571c3642b143330e75c4c3268282c14997b35082bf091cf14957bad27cc440de4b1f2a19f745c41da328e9d6600e9508c61db3798f72dd246dd4763fbcb06d93b41dd87820e87a9c6ff9633687d0c5eedc7fd06f7f101c989d44d1682d37418283a565b101fe55b4839905a7448dd2848f2eab297a9dc1542fe8af6faff8a68d40ece96d65350d617d9a8ab1133584bcb93510dfac72d5270aceebf5649e86ced4a181228d2ebaf9285436b5a9283795cb05efd34726d3eb22b29284ecc87f31299744e5ead2df8c1769dc6792a128fd4b2f3a5beada0e5ea0a58209c6b1a07d796e6fb59e887e73892cac69cc1b937e1b6f319d03dd16ae1214e175fd94dc6229224b27e69a122d3677145d919cc2387485325ce264d1d55997c2e5c36e74d27547cb4ac385d5b06faa372c99bec91913e0d06d8306019af9fddfb3cefaa82425b05c3ce22baa19cc6e69f6bb9cc4f68b918dce01e059fed08a844bb9bb5fc96c36c947c0eab5694134bf20f4a80eb3a7e4dbcd7f57ec11273487ca7c20b740345ff41473b5b5e31548c9f451010549aad907bae25d93d62094ca7479563339110534a3a0273419468e8228fdc62a4eb09b42cd5851bbfe8e10d32c30db32fc00a8db49a3435179fa7ec3f014856079a86c4c7475d8f67c960774657037feda7fda5e63e9891d54645941ad23665008350ac2b72f1758385cb20ce3cf31da203f8c866795a4a807f701a461e4b9aad2c610ce873576c069092be77dab590bf9870cdb668a021eec4034295b8d056fc82a3ac7fb56c877f467c126b24868538d4e7e366644919984615366a2ae305a78d0541ba4488c83151e800c1e0d69d1fbf000b838e4d8bfb9f4b22e02927b997f8e8012d352b8219b1cf0fc0fb8fca188e3cb5e0ee046a6b7b29d3ae8ec5d6c5a75a9179ddee2b37fd8d70b79a2e5740c014538b03e9122078a0ded5b2e64685625256ea00fe47d1a2ad01a70bd4601470e70e0c2763c071b8d9bcd690068b4e8b39344286ce5e3a2cf4d200c9f269c60aca227805ad7bf0179cdc66c11ebc63c9a2b2744dcbe7260d40927fa48c1c1d2935151456ee9cc155dcef427ed5a739a4a556175b63e1a83b3f143f770df6d154d366858c2ee723cbefc790c5157c9190e44a68d54fa6604496af9a7d69a266201a701d88b2f6cef3751afd32304d108f36a555df0bd8dc009304ab9c42e5e10dbebd21afab74f4b7326fdfae26f9fee322174ac0ed425a93dbc3bc565650efc5cde958a46fabc3303de4ee246e23e062ab77763420a43c9ee066b751d0cae0e8b1ad5602b0b490b72e55a3d8dda9f46dcc20769ad5aabe5658dc2c2abbf963637a5c742e377f29b91f76f823b2111ccb2ed3dc45492aa007e931d53652d7a14624a5f94032ac524f23b91ebf9f5aeed513f7597df1538ffd92448fc0035290dd1f3453cb458f28bbfbf11a65837b3c109ac897e26cd963317bf3a81bf4a33796aad33d4e83a3855cee21cff282f75d8b01ba1f48d70dffc6e0c5c3749edbedba2678a142215d7356f6d0421371bd3a1c45efeeb7e1b8ff2e956c8e2dbaa411280cf67d2c8743208f8abee4c89e38f8ec1c48d6f871bf5cc26caac833c99dc2219b300a5bff0f6c29dcd6c343527ee01668c8e7b5cfa32f1883d6f4446e2df815cbe64e2df720ccc2853f58262e4bfc4cb364e7b7ceaeb2335450c48aaad189ab384b96008aa0296704c577754ec703499556bd1135a4cbd2a80c1aaedb88c01f08f60ab9bfd485ba84d0b1e611bc9a06864bb7b289b89e96a339f4f3089ba20af766d399219d59bc82792aa77b49d150d0f2a0f9f570a0b4eede8617f401c21186156b826d6b983ab10998ae9393448db72c93be48096b40e0b85b616c8ba0788219926df796607e22b6bd81789f3c1c0a97ef9ecc03eafb5f2e0a6e505d747b4f807b83149898b885f0a56ca87c85fa07a19433aefdfbf1222bd8edc599467cd7de3fc53c3008e1e33099dcbf5273d62fe3fc4f85311d37a071f248d4d911a9ab3c40ba5c845aadafa5b1c56a9b72773307e93d41d6c0aabaebd6021fa54560a66d9fccd1e5d4e1f3df8258fcc1693ceb03f71783ade25cecf4bdb427e3990b80279b6abbf695995791e89666056d011b6f7b310b1a7405a0541eb910067182a862dbabf07c1f3a024025cd62eb7da34b28e8a7826d446540783e4941ed014648748b93260e5dc43c62018102251f5a57b4a76e9f670ecece45cb338bf79b5f54f9ccdd2e848ba27ec3413e3dc93a23b27392ff3f64198350520dca6ae4578e9c2e5f7d7655d900aa7bbc7e20efde2091eafb69e878f90e2256399370e69e8e40724860e62358203273334dc8c4fbe7e85a7f37c93f230061f1523679d811716404a2e2a9c16fc92b15df7589f0def44fe0a852a178be0e320c3bd4de3961f21715ce95ddc583e6610165eb1d726520d04415a542538fb6ce6f28ac87dcd57b04d98e0aeb00a91ba4a6b5c2428cac4406a8209d581697a8c3b7fd5100b1fb421c7fce51c28d1ba55b6eb0b9febaf74eb5bae51cbde3adff6d17b524a112ee7b0742d37e5dd046db43d6590b2a4f47144ad72c613f6a7543771f77e5fe1db484a0d309a221a278b8eb78cf523a470ac645253a57786665da1ed5bcc8d435fedae2317e9a48b587cbdb020333655d279bd7827ea1b3ed10f21ec15397f1a1a6c0e18ac4a3a8d2e5a5e362c82a619ffc83b02c0971256029d8136e88d895c20fc20cbe8e118ea1108aa90509234cc43ff31ed4238aef95e98426523b69c581b3c18ef597f5a12a732d137b3b66d704ec8dc51721fe1d774473b8562f87e5efe3cd6669baec3d57c65f3e2e8496aec24bcf353271af3a85b7ba57fd3461f26dd5135751ba2d0921d9b4e10e9322e008ae902a84d1b1af35f6b8570df91f0282649df66289ea0a9a0ee9e9e2b52d627d3faa113a5b5d90e62abbb785f9636a6dfd6cdf0995574f8e5214716b8d196ed453a47ba5fcc30fc35e1db3986c0691a2c3ca7607d52a802cfe93ea2409123c9ac464b7d1a70ca6e4b76e2d061d3f2855899414e5a90bf0147b9b719daf81a2233896a1dd302ff03d58cbe1824084743c2e820a228b54eeb1e848f1065dd4125051c57eb14f39a7cf8be249fa09eb1918cbf7038a0e0dfb1f8d3e49c8e6d544634c5caa24db27cac1dc7fb22c606fe264faa3d0a89eac7ec001476c13c51e2a04278dd6cd56691938f9d3d8e48ae4a9a982d946684a43bc6421417e410b27530e02fdce8da0753c233f1ead4cb056f30f75ab094d849ce7df287548a42feed5f35bff74574bd2588d2b5686f6e2177e36d67d1e346e6bca67b3dc8c178c51f09d23f94ad2dee918528be122c184488653e8d39a86a5f66d6f56db0b69c18a871fa07da6dc95cfd713b4e5d60f340407e890bd2bb5aef22548bd35ca77fce824308d12af44b4c5b347ff5df13438041d64515ea12e72b469e669ea01378f05eed8caa7413804d8ec695734c501e13253a185c9fb67696d760862eabd0039d31a9d53132e7055986bca8c9ebb6151ecdd5dbe83f785051d7f7108d498420628552341d83670c233fdb5fb7728e665a474be85d9070c80465608538ebd26c9cb864b5a455bc5bab439b9ed3194b86f22783cd0176c7953abb03e56bace1bb4f37f48e0d748e846e48679358d0e9ba82064fa12be39a259ba6db85113ae1322d24fcea1d5ab11cf7daa77ac550425ed3eb57d091292ff018ed2bccbe5ec91ac1c1cd3fc1cf83e1dea5f21399af7feee6b5c2d18be56b41f47b1e42eb87343938404a563a583313f867715bbb25afbb1a979b58e23c272fcdc5027f37a1cd50ef89975d00bfa326b3802c4215af526a3b100554671c28609bd63eaf118371a574013908efaf9859d7c7a7af678ae5891f6c08bdb9c9b07306aa717ba605c6f7c5b1a3b79ba8110b4f75ff9b22615e47b276090d0c4613470a0eb52979e7c0fb1153f1ef4f27732f47e4434f6233fae00fb71aaf995bfca365975cc0df2866fe8a5bf70f8849c06d38e8ec475f0b1b97ef0210b424b9464a600bd0f99fc6c0e0b61cbe3739e6936634a5fcceca3ff081af7ab554819fb7b9b4bdb8b8ee34fc2d09223fef285d439b4507f733d7e5065131f112c53c466153b95838d3d0ed0e0e99dd20e3bfc528e079fe94a9df60964503cceb1b5429093362aa81c09cfe6ebef61704e4af7afa4d029b4414e76f31085da7b3d2fc8035b419db85d00f20ecc24fba64e38c91016f993c3345f2cf850fb9c60e64d833de274f582a7108bf7bcd946e839fae212772aca9a2839a4f1dd687cd3ca1600a85e68c1466c08d70dbee4221026aca4c327cc1d39417d5bb53d065f5f1576b085de27d9862c8429537db3249546ed18076533426c3a95778afc812316ac958d7404b5df5c8710bb01b0b7af0dc1f065b6500bc0496c0ef8543a501f5ecdcaecb950ac30325c30c6ec038d896fe7f76956cae838f6065d9e33877dde66271a771e9427bb9204e34424562785809041d641f17c12ed4d903bf529e0cabbcc2c9859afed94f3c71908db320bdd6b98baaf815310929dce2134a0edf77fd196fabc2376271506d336bdb045c1f76f8bf0d9a8bbbf7a2d775b70ff32d074165f3e9c90143f2ac45e1ab0735cf8657bff4105779a276d427bd53fcba5839f6ee4d8c4c7e37a7e34cf690a7b1c280701567ae83b9ee42a6e6c04078bfb12e23d58ff9b97184373b2ac3dc2d52f4ad7a637c7129670530e1610c909e3eb0247e0cc6adf7be6c6980fa65cb7127089a25a9919de77226f7e59223c80c06d0e972f39b2729d5e7de34035b701221f6de37e9dcdd9d8560d2115d43cbb6227b6ee1a5b31fe78d31a225239067ca8218a1838c8a0984e1fb2f9b1508806061874b5c56bb5c3174e7f86266ba4f175d67a4deb55ace08ba33ab5a3a7b10e56c3a195be503745b170fc91fb72a7aa24ea315f7dab9410411e41e1e203c7fbc34965aba97df25ba1ba5265c9da8c99255c693da003fe9c5fd4127a9e7c7c18786472dc508af85418b764d1b7879b15c2187328580ebb43b9a721d9446211166a3a92de254223b10bf09fe22d029e1a8a02c4eb16152aaebb54296a2f78fcf46a7364fc7d55fabb31c4d41a7f9835ad33a830219f899136c5738d4328008871012d15fabd0a93df05938d91ed7ee387e311b46a233ea69fff0108560a27f6cb0a56ccf170de94d0274ffe44d30e69466b4dcf6b6d05dfdc1b7437b86fe6c9cf6a598bcf77984d2a9d5c5a3e1430147b5b4a3777e856c1a2100f09ca12370419ae345150c5f7a707f073dc7be8886c9c423563c415be7d000d55bab7dec1c0c5344295a5656f64077c2181873c298f0953dfbe2f8daff76b5fbbc0e93d8a0a62c9047ed69b7e0000000\";\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(\"Banshiko\", 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 [\"Banshee ghost girl\", \"Banshee ghost girl\", \"Banshee ghost girl\", \"Banshee ghost girl\"];\n    }\n    function _T2() internal pure returns (string[4] memory) {\n        return [\"Tattered violet shawl\", \"Tattered violet shawl\", \"Tattered violet shawl\", \"Tattered violet shawl\"];\n    }\n    function _T3() internal pure returns (string[4] memory) {\n        return [\"Moonlight and candle glow\", \"Moonlight and candle glow\", \"Moonlight and candle glow\", \"Moonlight and candle glow\"];\n    }\n    function _T4() internal pure returns (string[4] memory) {\n        return [\"Pumpkin graveyard\", \"Pumpkin graveyard\", \"Pumpkin graveyard\", \"Pumpkin graveyard\"];\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\":\"Banshiko #', id.toString(),\n            '\",\"description\":\"Banshiko is 1111 Little glowing banshee ghost girl with silver hair and a candle lantern in a moonlit pumpkin graveyard. 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\":\"Banshiko\",\"description\":\"Banshiko is 1111 Little glowing banshee ghost girl with silver hair and a candle lantern in a moonlit pumpkin graveyard. 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":"58027570","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-02T01:54:43Z","match":"exact_match","chainId":"56","address":"0x7e395317a0B57F63c729C248a1558Eb93d86dcA7"}