{"sources":{"src/NeonPulseGrid.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ERC721} from \"solady/tokens/ERC721.sol\";\nimport {LibString} from \"solady/utils/LibString.sol\";\nimport {Base64} from \"solady/utils/Base64.sol\";\n\n/// @title NeonPulseGrid (Variant C: 1st Free for .ai + Bundled Pack Discount)\n/// @notice Holographic radar terminal SVG artifact on BNB Chain.\n/// @dev Variant C tests 1st-free-per-agent + bundled pack pricing:\n///      - 1st card free for up to 250 .ai wallets\n///      - Additional cards 0.0005 BNB each, or mint(3) bundle (1 free + 2 paid = 0.0008 BNB discount!)\ncontract NeonPulseGrid is ERC721 {\n    using LibString for uint256;\n\n    address public constant AGENT_ID_REGISTRY = 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F;\n\n    address public immutable PAYEE;\n    address public immutable OWNER;\n    uint256 public constant MAX_SUPPLY = 1800;\n    uint256 public constant FREE_SUPPLY = 250;\n    uint256 public constant PRICE = 0.0005 ether;\n    uint256 public constant BUNDLE_THREE_PRICE = 0.0008 ether;\n    uint256 public constant MAX_PER_WALLET = 5;\n\n    uint256 public totalSupply;\n    uint256 public freeMinted;\n\n    mapping(address => uint256) public mintedBy;\n    mapping(address => bool) public claimedFree;\n    mapping(uint256 => uint8) public pulseGrade; // 0 = Basic, 1 = Overclocked (Paid), 2 = Hyper-Bundle (mint >= 3)\n\n    uint256 private _locked = 1;\n\n    event PulseTerminalMinted(address indexed to, uint256 indexed startId, uint256 qty, uint8 grade);\n\n    error SoldOut();\n    error WalletLimitExceeded();\n    error InsufficientPayment();\n    error FreeQuotaExhaustedOrNotAgent();\n    error PayoutFailed();\n    error Reentrancy();\n    error ZeroQuantity();\n\n    modifier nonReentrant() {\n        if (_locked != 1) revert Reentrancy();\n        _locked = 2;\n        _;\n        _locked = 1;\n    }\n\n    constructor(address payee_) {\n        if (payee_ == address(0)) revert PayoutFailed();\n        PAYEE = payee_;\n        OWNER = payee_;\n    }\n\n    function name() public pure override returns (string memory) {\n        return \"NeonPulse Holographic Grid\";\n    }\n\n    function symbol() public pure override returns (string memory) {\n        return \"NPULSE\";\n    }\n\n    function owner() external view returns (address) {\n        return OWNER;\n    }\n\n    function totalMinted() external view returns (uint256) {\n        return totalSupply;\n    }\n\n    function mintOpen() external pure returns (bool) {\n        return true;\n    }\n\n    function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n        return interfaceId == 0x2a55205a || super.supportsInterface(interfaceId);\n    }\n\n    function royaltyInfo(uint256, uint256 salePrice) external view returns (address, uint256) {\n        return (PAYEE, (salePrice * 500) / 10000);\n    }\n\n    function contractURI() external view returns (string memory) {\n        string memory json = string.concat(\n            '{\"name\":\"NeonPulse Holographic Grid\",\"description\":\"Holographic radar terminal artifact for .ai agents on BNB Chain.\",\"fee_recipient\":\"',\n            LibString.toHexStringChecksummed(PAYEE),\n            '\",\"seller_fee_basis_points\":500}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n\n    function checkAgentHandle(address wallet) public view returns (bool) {\n        (bool ok, bytes memory data) = AGENT_ID_REGISTRY.staticcall(\n            abi.encodeWithSelector(0x70a08231, wallet)\n        );\n        if (!ok || data.length < 32) return false;\n        return abi.decode(data, (uint256)) > 0;\n    }\n\n    function canClaimFree(address wallet) public view returns (bool) {\n        if (claimedFree[wallet] || freeMinted >= FREE_SUPPLY) return false;\n        return checkAgentHandle(wallet);\n    }\n\n    function quote(address wallet, uint256 qty) public view returns (uint256) {\n        if (qty == 0) return 0;\n        if (canClaimFree(wallet)) {\n            if (qty == 1) return 0;\n            if (qty == 3) return BUNDLE_THREE_PRICE;\n            return (qty - 1) * PRICE;\n        }\n        if (qty == 3) return BUNDLE_THREE_PRICE + PRICE;\n        return qty * PRICE;\n    }\n\n    function freeMint() external payable nonReentrant {\n        _mintInternal(msg.sender, 1);\n    }\n\n    function mint() external payable nonReentrant {\n        _mintInternal(msg.sender, 1);\n    }\n\n    function mint(uint256 qty) external payable nonReentrant {\n        _mintInternal(msg.sender, qty);\n    }\n\n    function _mintInternal(address to, uint256 qty) internal {\n        if (qty == 0) revert ZeroQuantity();\n        if (totalSupply + qty > MAX_SUPPLY) revert SoldOut();\n        if (mintedBy[to] + qty > MAX_PER_WALLET) revert WalletLimitExceeded();\n\n        bool eligibleFree = canClaimFree(to);\n        uint256 requiredWei = quote(to, qty);\n        if (msg.value == 0 && requiredWei > 0) revert FreeQuotaExhaustedOrNotAgent();\n        if (msg.value < requiredWei) revert InsufficientPayment();\n\n        uint256 freeUsed = 0;\n        if (eligibleFree && msg.value < qty * PRICE) {\n            claimedFree[to] = true;\n            freeMinted += 1;\n            freeUsed = 1;\n        }\n\n        mintedBy[to] += qty;\n        uint256 startId = totalSupply + 1;\n        totalSupply += qty;\n\n        uint8 paidGrade = qty >= 3 ? 2 : 1;\n        for (uint256 i = 0; i < qty; ++i) {\n            uint256 tid = startId + i;\n            bool isPaidUnit = (i >= freeUsed) || (msg.value >= qty * PRICE && msg.value > 0);\n            pulseGrade[tid] = isPaidUnit ? paidGrade : 0;\n            _mint(to, tid);\n        }\n\n        emit PulseTerminalMinted(to, startId, qty, msg.value > 0 ? paidGrade : 0);\n\n        if (msg.value > 0) {\n            (bool ok, ) = PAYEE.call{value: msg.value}(\"\");\n            if (!ok) revert PayoutFailed();\n        }\n    }\n\n    function gradeNameOf(uint256 tokenId) public view returns (string memory) {\n        if (!_exists(tokenId)) revert TokenDoesNotExist();\n        uint8 g = pulseGrade[tokenId];\n        if (g == 2) return \"HYPER-PULSE (BUNDLE)\";\n        if (g == 1) return \"OVERCLOCK-PRIME\";\n        return \"BASE-SIGNAL\";\n    }\n\n    function tokenURI(uint256 tokenId) public view override returns (string memory) {\n        if (!_exists(tokenId)) revert TokenDoesNotExist();\n        uint8 g = pulseGrade[tokenId];\n        string memory idStr = tokenId.toString();\n        string memory gName = gradeNameOf(tokenId);\n        string memory c1 = g == 2 ? \"#ff0844\" : (g == 1 ? \"#b721ff\" : \"#3a7bd5\");\n        string memory c2 = g == 2 ? \"#ffb199\" : (g == 1 ? \"#21d4fd\" : \"#3a6073\");\n\n        string memory svgA = string.concat(\n            '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 400\">',\n            '<defs><linearGradient id=\"pg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">',\n            '<stop offset=\"0%\" stop-color=\"', c1, '\"/><stop offset=\"100%\" stop-color=\"', c2, '\"/></linearGradient></defs>',\n            '<rect width=\"400\" height=\"400\" rx=\"22\" fill=\"#090612\"/>',\n            '<rect x=\"14\" y=\"14\" width=\"372\" height=\"372\" rx=\"16\" fill=\"none\" stroke=\"url(#pg)\" stroke-width=\"2.5\"/>',\n            '<rect x=\"34\" y=\"62\" width=\"332\" height=\"176\" rx=\"10\" fill=\"#120b24\" stroke=\"', c1, '\" stroke-width=\"1.5\"/>'\n        );\n        string memory svg = string.concat(\n            svgA,\n            '<line x1=\"34\" y1=\"120\" x2=\"366\" y2=\"120\" stroke=\"#2a1b4e\" stroke-width=\"1\"/><line x1=\"34\" y1=\"180\" x2=\"366\" y2=\"180\" stroke=\"#2a1b4e\" stroke-width=\"1\"/>',\n            '<polyline points=\"48,175 95,140 135,165 180,92 220,195 265,110 310,152 352,105\" fill=\"none\" stroke=\"url(#pg)\" stroke-width=\"3.5\"/>',\n            '<circle cx=\"180\" cy=\"92\" r=\"5\" fill=\"#ffffff\"/><circle cx=\"265\" cy=\"110\" r=\"5\" fill=\"#ffffff\"/>',\n            '<text x=\"34\" y=\"44\" fill=\"', c2, '\" font-family=\"monospace\" font-size=\"12\" letter-spacing=\"2\">NEONPULSE // HOLOGRAPHIC GRID</text>',\n            '<text x=\"34\" y=\"278\" fill=\"#ffffff\" font-family=\"monospace\" font-weight=\"bold\" font-size=\"25\">TERMINAL #', idStr, '</text>',\n            '<text x=\"34\" y=\"310\" fill=\"url(#pg)\" font-family=\"monospace\" font-size=\"16\">MODE: ', gName, '</text>',\n            '<rect x=\"34\" y=\"336\" width=\"332\" height=\"28\" rx=\"6\" fill=\"#140c29\" stroke=\"url(#pg)\" stroke-width=\"1\"/>',\n            '<text x=\"200\" y=\"354\" text-anchor=\"middle\" fill=\"#e0c3fc\" font-family=\"monospace\" font-size=\"11\">1ST FREE (.AI) // MINT(3) HYPER-PULSE PACK</text></svg>'\n        );\n\n        string memory json = string.concat(\n            '{\"name\":\"NeonPulse #', idStr,\n            '\",\"description\":\"Holographic radar terminal artifact on BNB Chain. 1st free for .ai; mint(3) unlocks HYPER-PULSE grade.\",',\n            '\"image\":\"data:image/svg+xml;base64,', Base64.encode(bytes(svg)),\n            '\",\"attributes\":[{\"trait_type\":\"Grade\",\"value\":\"', gName, '\"}]}'\n        );\n        return string.concat(\"data:application/json;base64,\", Base64.encode(bytes(json)));\n    }\n}\n"},"lib/solady/src/tokens/ERC721.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple ERC721 implementation with storage hitchhiking.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC721.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC721/ERC721.sol)\n///\n/// @dev Note:\n/// - The ERC721 standard allows for self-approvals.\n///   For performance, this implementation WILL NOT revert for such actions.\n///   Please add any checks with overrides if desired.\n/// - For performance, methods are made payable where permitted by the ERC721 standard.\n/// - The `safeTransfer` functions use the identity precompile (0x4)\n///   to copy memory internally.\n///\n/// If you are overriding:\n/// - NEVER violate the ERC721 invariant:\n///   the balance of an owner MUST always be equal to their number of ownership slots.\n///   The transfer functions do not have an underflow guard for user token balances.\n/// - Make sure all variables written to storage are properly cleaned\n///   (e.g. the bool value for `isApprovedForAll` MUST be either 1 or 0 under the hood).\n/// - Check that the overridden function is actually used in the function you want to\n///   change the behavior of. Much of the code has been manually inlined for performance.\nabstract contract ERC721 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev An account can hold up to 4294967295 tokens.\n    uint256 internal constant _MAX_ACCOUNT_BALANCE = 0xffffffff;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Only the token owner or an approved account can manage the token.\n    error NotOwnerNorApproved();\n\n    /// @dev The token does not exist.\n    error TokenDoesNotExist();\n\n    /// @dev The token already exists.\n    error TokenAlreadyExists();\n\n    /// @dev Cannot query the balance for the zero address.\n    error BalanceQueryForZeroAddress();\n\n    /// @dev Cannot mint or transfer to the zero address.\n    error TransferToZeroAddress();\n\n    /// @dev The token must be owned by `from`.\n    error TransferFromIncorrectOwner();\n\n    /// @dev The recipient's balance has overflowed.\n    error AccountBalanceOverflow();\n\n    /// @dev Cannot safely transfer to a contract that does not implement\n    /// the ERC721Receiver interface.\n    error TransferToNonERC721ReceiverImplementer();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Emitted when token `id` is transferred from `from` to `to`.\n    event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n    /// @dev Emitted when `owner` enables `account` to manage the `id` token.\n    event Approval(address indexed owner, address indexed account, uint256 indexed id);\n\n    /// @dev Emitted when `owner` enables or disables `operator` to manage all of their tokens.\n    event ApprovalForAll(address indexed owner, address indexed operator, bool isApproved);\n\n    /// @dev `keccak256(bytes(\"Transfer(address,address,uint256)\"))`.\n    uint256 private constant _TRANSFER_EVENT_SIGNATURE =\n        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;\n\n    /// @dev `keccak256(bytes(\"Approval(address,address,uint256)\"))`.\n    uint256 private constant _APPROVAL_EVENT_SIGNATURE =\n        0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;\n\n    /// @dev `keccak256(bytes(\"ApprovalForAll(address,address,bool)\"))`.\n    uint256 private constant _APPROVAL_FOR_ALL_EVENT_SIGNATURE =\n        0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ownership data slot of `id` is given by:\n    /// ```\n    ///     mstore(0x00, id)\n    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n    ///     let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n    /// ```\n    /// Bits Layout:\n    /// - [0..159]   `addr`\n    /// - [160..255] `extraData`\n    ///\n    /// The approved address slot is given by: `add(1, ownershipSlot)`.\n    ///\n    /// See: https://notes.ethereum.org/%40vbuterin/verkle_tree_eip\n    ///\n    /// The balance slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n    ///     mstore(0x00, owner)\n    ///     let balanceSlot := keccak256(0x0c, 0x1c)\n    /// ```\n    /// Bits Layout:\n    /// - [0..31]   `balance`\n    /// - [32..255] `aux`\n    ///\n    /// The `operator` approval slot of `owner` is given by:\n    /// ```\n    ///     mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))\n    ///     mstore(0x00, owner)\n    ///     let operatorApprovalSlot := keccak256(0x0c, 0x30)\n    /// ```\n    uint256 private constant _ERC721_MASTER_SLOT_SEED = 0x7d8825530a5a2e7a << 192;\n\n    /// @dev Pre-shifted and pre-masked constant.\n    uint256 private constant _ERC721_MASTER_SLOT_SEED_MASKED = 0x0a5a2e7a00000000;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      ERC721 METADATA                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the token collection name.\n    function name() public view virtual returns (string memory);\n\n    /// @dev Returns the token collection symbol.\n    function symbol() public view virtual returns (string memory);\n\n    /// @dev Returns the Uniform Resource Identifier (URI) for token `id`.\n    function tokenURI(uint256 id) public view virtual returns (string memory);\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           ERC721                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the owner of token `id`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    function ownerOf(uint256 id) public view virtual returns (address result) {\n        result = _ownerOf(id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(result) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Returns the number of tokens owned by `owner`.\n    ///\n    /// Requirements:\n    /// - `owner` must not be the zero address.\n    function balanceOf(address owner) public view virtual returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Revert if the `owner` is the zero address.\n            if iszero(owner) {\n                mstore(0x00, 0x8f4eb604) // `BalanceQueryForZeroAddress()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            mstore(0x00, owner)\n            result := and(sload(keccak256(0x0c, 0x1c)), _MAX_ACCOUNT_BALANCE)\n        }\n    }\n\n    /// @dev Returns the account approved to manage token `id`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    function getApproved(uint256 id) public view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            if iszero(shl(96, sload(ownershipSlot))) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            result := sload(add(1, ownershipSlot))\n        }\n    }\n\n    /// @dev Sets `account` as the approved account to manage token `id`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    /// - The caller must be the owner of the token,\n    ///   or an approved operator for the token owner.\n    ///\n    /// Emits an {Approval} event.\n    function approve(address account, uint256 id) public payable virtual {\n        _approve(msg.sender, account, id);\n    }\n\n    /// @dev Returns whether `operator` is approved to manage the tokens of `owner`.\n    function isApprovedForAll(address owner, address operator)\n        public\n        view\n        virtual\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x1c, operator)\n            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)\n            mstore(0x00, owner)\n            result := sload(keccak256(0x0c, 0x30))\n        }\n    }\n\n    /// @dev Sets whether `operator` is approved to manage the tokens of the caller.\n    ///\n    /// Emits an {ApprovalForAll} event.\n    function setApprovalForAll(address operator, bool isApproved) public virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Convert to 0 or 1.\n            isApproved := iszero(iszero(isApproved))\n            // Update the `isApproved` for (`msg.sender`, `operator`).\n            mstore(0x1c, operator)\n            mstore(0x08, _ERC721_MASTER_SLOT_SEED_MASKED)\n            mstore(0x00, caller())\n            sstore(keccak256(0x0c, 0x30), isApproved)\n            // Emit the {ApprovalForAll} event.\n            mstore(0x00, isApproved)\n            // forgefmt: disable-next-item\n            log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, caller(), shr(96, shl(96, operator)))\n        }\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - The caller must be the owner of the token, or be approved to manage the token.\n    ///\n    /// Emits a {Transfer} event.\n    function transferFrom(address from, address to, uint256 id) public payable virtual {\n        _beforeTokenTransfer(from, to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            let bitmaskAddress := shr(96, not(0))\n            from := and(bitmaskAddress, from)\n            to := and(bitmaskAddress, to)\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, caller()))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            let owner := and(bitmaskAddress, ownershipPacked)\n            // Revert if the token does not exist, or if `from` is not the owner.\n            if iszero(mul(owner, eq(owner, from))) {\n                // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`.\n                mstore(shl(2, iszero(owner)), 0xceea21b6a1148100)\n                revert(0x1c, 0x04)\n            }\n            // Load, check, and update the token approval.\n            {\n                mstore(0x00, from)\n                let approvedAddress := sload(add(1, ownershipSlot))\n                // Revert if the caller is not the owner, nor approved.\n                if iszero(or(eq(caller(), from), eq(caller(), approvedAddress))) {\n                    if iszero(sload(keccak256(0x0c, 0x30))) {\n                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                        revert(0x1c, 0x04)\n                    }\n                }\n                // Delete the approved address if any.\n                if approvedAddress { sstore(add(1, ownershipSlot), 0) }\n            }\n            // Update with the new owner.\n            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))\n            // Decrement the balance of `from`.\n            {\n                let fromBalanceSlot := keccak256(0x0c, 0x1c)\n                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))\n            }\n            // Increment the balance of `to`.\n            {\n                mstore(0x00, to)\n                let toBalanceSlot := keccak256(0x0c, 0x1c)\n                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(toBalanceSlot, toBalanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)\n        }\n        _afterTokenTransfer(from, to, id);\n    }\n\n    /// @dev Equivalent to `safeTransferFrom(from, to, id, \"\")`.\n    function safeTransferFrom(address from, address to, uint256 id) public payable virtual {\n        transferFrom(from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, \"\");\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - The caller must be the owner of the token, or be approved to manage the token.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function safeTransferFrom(address from, address to, uint256 id, bytes calldata data)\n        public\n        payable\n        virtual\n    {\n        transferFrom(from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);\n    }\n\n    /// @dev Returns true if this contract implements the interface defined by `interfaceId`.\n    /// See: https://eips.ethereum.org/EIPS/eip-165\n    /// This function call must use less than 30000 gas.\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let s := shr(224, interfaceId)\n            // ERC165: 0x01ffc9a7, ERC721: 0x80ac58cd, ERC721Metadata: 0x5b5e139f.\n            result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x80ac58cd)), eq(s, 0x5b5e139f))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL QUERY FUNCTIONS                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns if token `id` exists.\n    function _exists(uint256 id) internal view virtual returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := iszero(iszero(shl(96, sload(add(id, add(id, keccak256(0x00, 0x20)))))))\n        }\n    }\n\n    /// @dev Returns the owner of token `id`.\n    /// Returns the zero address instead of reverting if the token does not exist.\n    function _ownerOf(uint256 id) internal view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := shr(96, shl(96, sload(add(id, add(id, keccak256(0x00, 0x20))))))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*            INTERNAL DATA HITCHHIKING FUNCTIONS             */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // For performance, no events are emitted for the hitchhiking setters.\n    // Please emit your own events if required.\n\n    /// @dev Returns the auxiliary data for `owner`.\n    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.\n    /// Auxiliary data can be set for any address, even if it does not have any tokens.\n    function _getAux(address owner) internal view virtual returns (uint224 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            mstore(0x00, owner)\n            result := shr(32, sload(keccak256(0x0c, 0x1c)))\n        }\n    }\n\n    /// @dev Set the auxiliary data for `owner` to `value`.\n    /// Minting, transferring, burning the tokens of `owner` will not change the auxiliary data.\n    /// Auxiliary data can be set for any address, even if it does not have any tokens.\n    function _setAux(address owner, uint224 value) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            mstore(0x00, owner)\n            let balanceSlot := keccak256(0x0c, 0x1c)\n            let packed := sload(balanceSlot)\n            sstore(balanceSlot, xor(packed, shl(32, xor(value, shr(32, packed)))))\n        }\n    }\n\n    /// @dev Returns the extra data for token `id`.\n    /// Minting, transferring, burning a token will not change the extra data.\n    /// The extra data can be set on a non-existent token.\n    function _getExtraData(uint256 id) internal view virtual returns (uint96 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := shr(160, sload(add(id, add(id, keccak256(0x00, 0x20)))))\n        }\n    }\n\n    /// @dev Sets the extra data for token `id` to `value`.\n    /// Minting, transferring, burning a token will not change the extra data.\n    /// The extra data can be set on a non-existent token.\n    function _setExtraData(uint256 id, uint96 value) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let packed := sload(ownershipSlot)\n            sstore(ownershipSlot, xor(packed, shl(160, xor(value, shr(160, packed)))))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL MINT FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Mints token `id` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must not exist.\n    /// - `to` cannot be the zero address.\n    ///\n    /// Emits a {Transfer} event.\n    function _mint(address to, uint256 id) internal virtual {\n        _beforeTokenTransfer(address(0), to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            to := shr(96, shl(96, to))\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            // Revert if the token already exists.\n            if shl(96, ownershipPacked) {\n                mstore(0x00, 0xc991cbb1) // `TokenAlreadyExists()`.\n                revert(0x1c, 0x04)\n            }\n            // Update with the owner.\n            sstore(ownershipSlot, or(ownershipPacked, to))\n            // Increment the balance of the owner.\n            {\n                mstore(0x00, to)\n                let balanceSlot := keccak256(0x0c, 0x1c)\n                let balanceSlotPacked := add(sload(balanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(balanceSlot, balanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)\n        }\n        _afterTokenTransfer(address(0), to, id);\n    }\n\n    /// @dev Mints token `id` to `to`, and updates the extra data for token `id` to `value`.\n    /// Does NOT check if token `id` already exists (assumes `id` is auto-incrementing).\n    ///\n    /// Requirements:\n    ///\n    /// - `to` cannot be the zero address.\n    ///\n    /// Emits a {Transfer} event.\n    function _mintAndSetExtraDataUnchecked(address to, uint256 id, uint96 value) internal virtual {\n        _beforeTokenTransfer(address(0), to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            to := shr(96, shl(96, to))\n            // Update with the owner and extra data.\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            sstore(add(id, add(id, keccak256(0x00, 0x20))), or(shl(160, value), to))\n            // Increment the balance of the owner.\n            {\n                mstore(0x00, to)\n                let balanceSlot := keccak256(0x0c, 0x1c)\n                let balanceSlotPacked := add(sload(balanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(balanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(balanceSlot, balanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, 0, to, id)\n        }\n        _afterTokenTransfer(address(0), to, id);\n    }\n\n    /// @dev Equivalent to `_safeMint(to, id, \"\")`.\n    function _safeMint(address to, uint256 id) internal virtual {\n        _safeMint(to, id, \"\");\n    }\n\n    /// @dev Mints token `id` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must not exist.\n    /// - `to` cannot be the zero address.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function _safeMint(address to, uint256 id, bytes memory data) internal virtual {\n        _mint(to, id);\n        if (_hasCode(to)) _checkOnERC721Received(address(0), to, id, data);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  INTERNAL BURN FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Equivalent to `_burn(address(0), id)`.\n    function _burn(uint256 id) internal virtual {\n        _burn(address(0), id);\n    }\n\n    /// @dev Destroys token `id`, using `by`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - If `by` is not the zero address,\n    ///   it must be the owner of the token, or be approved to manage the token.\n    ///\n    /// Emits a {Transfer} event.\n    function _burn(address by, uint256 id) internal virtual {\n        address owner = ownerOf(id);\n        _beforeTokenTransfer(owner, address(0), id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            by := shr(96, shl(96, by))\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            // Reload the owner in case it is changed in `_beforeTokenTransfer`.\n            owner := shr(96, shl(96, ownershipPacked))\n            // Revert if the token does not exist.\n            if iszero(owner) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            // Load and check the token approval.\n            {\n                mstore(0x00, owner)\n                let approvedAddress := sload(add(1, ownershipSlot))\n                // If `by` is not the zero address, do the authorization check.\n                // Revert if the `by` is not the owner, nor approved.\n                if iszero(or(iszero(by), or(eq(by, owner), eq(by, approvedAddress)))) {\n                    if iszero(sload(keccak256(0x0c, 0x30))) {\n                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                        revert(0x1c, 0x04)\n                    }\n                }\n                // Delete the approved address if any.\n                if approvedAddress { sstore(add(1, ownershipSlot), 0) }\n            }\n            // Clear the owner.\n            sstore(ownershipSlot, xor(ownershipPacked, owner))\n            // Decrement the balance of `owner`.\n            {\n                let balanceSlot := keccak256(0x0c, 0x1c)\n                sstore(balanceSlot, sub(sload(balanceSlot), 1))\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, owner, 0, id)\n        }\n        _afterTokenTransfer(owner, address(0), id);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL APPROVAL FUNCTIONS                 */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns whether `account` is the owner of token `id`, or is approved to manage it.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    function _isApprovedOrOwner(address account, uint256 id)\n        internal\n        view\n        virtual\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            // Clear the upper 96 bits.\n            account := shr(96, shl(96, account))\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, account))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let owner := shr(96, shl(96, sload(ownershipSlot)))\n            // Revert if the token does not exist.\n            if iszero(owner) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            // Check if `account` is the `owner`.\n            if iszero(eq(account, owner)) {\n                mstore(0x00, owner)\n                // Check if `account` is approved to manage the token.\n                if iszero(sload(keccak256(0x0c, 0x30))) {\n                    result := eq(account, sload(add(1, ownershipSlot)))\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the account approved to manage token `id`.\n    /// Returns the zero address instead of reverting if the token does not exist.\n    function _getApproved(uint256 id) internal view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, id)\n            mstore(0x1c, _ERC721_MASTER_SLOT_SEED)\n            result := sload(add(1, add(id, add(id, keccak256(0x00, 0x20)))))\n        }\n    }\n\n    /// @dev Equivalent to `_approve(address(0), account, id)`.\n    function _approve(address account, uint256 id) internal virtual {\n        _approve(address(0), account, id);\n    }\n\n    /// @dev Sets `account` as the approved account to manage token `id`, using `by`.\n    ///\n    /// Requirements:\n    /// - Token `id` must exist.\n    /// - If `by` is not the zero address, `by` must be the owner\n    ///   or an approved operator for the token owner.\n    ///\n    /// Emits a {Approval} event.\n    function _approve(address by, address account, uint256 id) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            let bitmaskAddress := shr(96, not(0))\n            account := and(bitmaskAddress, account)\n            by := and(bitmaskAddress, by)\n            // Load the owner of the token.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let owner := and(bitmaskAddress, sload(ownershipSlot))\n            // Revert if the token does not exist.\n            if iszero(owner) {\n                mstore(0x00, 0xceea21b6) // `TokenDoesNotExist()`.\n                revert(0x1c, 0x04)\n            }\n            // If `by` is not the zero address, do the authorization check.\n            // Revert if `by` is not the owner, nor approved.\n            if iszero(or(iszero(by), eq(by, owner))) {\n                mstore(0x00, owner)\n                if iszero(sload(keccak256(0x0c, 0x30))) {\n                    mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n            // Sets `account` as the approved account to manage `id`.\n            sstore(add(1, ownershipSlot), account)\n            // Emit the {Approval} event.\n            log4(codesize(), 0x00, _APPROVAL_EVENT_SIGNATURE, owner, account, id)\n        }\n    }\n\n    /// @dev Approve or remove the `operator` as an operator for `by`,\n    /// without authorization checks.\n    ///\n    /// Emits an {ApprovalForAll} event.\n    function _setApprovalForAll(address by, address operator, bool isApproved) internal virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            by := shr(96, shl(96, by))\n            operator := shr(96, shl(96, operator))\n            // Convert to 0 or 1.\n            isApproved := iszero(iszero(isApproved))\n            // Update the `isApproved` for (`by`, `operator`).\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, operator))\n            mstore(0x00, by)\n            sstore(keccak256(0x0c, 0x30), isApproved)\n            // Emit the {ApprovalForAll} event.\n            mstore(0x00, isApproved)\n            log3(0x00, 0x20, _APPROVAL_FOR_ALL_EVENT_SIGNATURE, by, operator)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                INTERNAL TRANSFER FUNCTIONS                 */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Equivalent to `_transfer(address(0), from, to, id)`.\n    function _transfer(address from, address to, uint256 id) internal virtual {\n        _transfer(address(0), from, to, id);\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - If `by` is not the zero address,\n    ///   it must be the owner of the token, or be approved to manage the token.\n    ///\n    /// Emits a {Transfer} event.\n    function _transfer(address by, address from, address to, uint256 id) internal virtual {\n        _beforeTokenTransfer(from, to, id);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Clear the upper 96 bits.\n            let bitmaskAddress := shr(96, not(0))\n            from := and(bitmaskAddress, from)\n            to := and(bitmaskAddress, to)\n            by := and(bitmaskAddress, by)\n            // Load the ownership data.\n            mstore(0x00, id)\n            mstore(0x1c, or(_ERC721_MASTER_SLOT_SEED, by))\n            let ownershipSlot := add(id, add(id, keccak256(0x00, 0x20)))\n            let ownershipPacked := sload(ownershipSlot)\n            let owner := and(bitmaskAddress, ownershipPacked)\n            // Revert if the token does not exist, or if `from` is not the owner.\n            if iszero(mul(owner, eq(owner, from))) {\n                // `TokenDoesNotExist()`, `TransferFromIncorrectOwner()`.\n                mstore(shl(2, iszero(owner)), 0xceea21b6a1148100)\n                revert(0x1c, 0x04)\n            }\n            // Load, check, and update the token approval.\n            {\n                mstore(0x00, from)\n                let approvedAddress := sload(add(1, ownershipSlot))\n                // If `by` is not the zero address, do the authorization check.\n                // Revert if the `by` is not the owner, nor approved.\n                if iszero(or(iszero(by), or(eq(by, from), eq(by, approvedAddress)))) {\n                    if iszero(sload(keccak256(0x0c, 0x30))) {\n                        mstore(0x00, 0x4b6e7f18) // `NotOwnerNorApproved()`.\n                        revert(0x1c, 0x04)\n                    }\n                }\n                // Delete the approved address if any.\n                if approvedAddress { sstore(add(1, ownershipSlot), 0) }\n            }\n            // Update with the new owner.\n            sstore(ownershipSlot, xor(ownershipPacked, xor(from, to)))\n            // Decrement the balance of `from`.\n            {\n                let fromBalanceSlot := keccak256(0x0c, 0x1c)\n                sstore(fromBalanceSlot, sub(sload(fromBalanceSlot), 1))\n            }\n            // Increment the balance of `to`.\n            {\n                mstore(0x00, to)\n                let toBalanceSlot := keccak256(0x0c, 0x1c)\n                let toBalanceSlotPacked := add(sload(toBalanceSlot), 1)\n                // Revert if `to` is the zero address, or if the account balance overflows.\n                if iszero(mul(to, and(toBalanceSlotPacked, _MAX_ACCOUNT_BALANCE))) {\n                    // `TransferToZeroAddress()`, `AccountBalanceOverflow()`.\n                    mstore(shl(2, iszero(to)), 0xea553b3401336cea)\n                    revert(0x1c, 0x04)\n                }\n                sstore(toBalanceSlot, toBalanceSlotPacked)\n            }\n            // Emit the {Transfer} event.\n            log4(codesize(), 0x00, _TRANSFER_EVENT_SIGNATURE, from, to, id)\n        }\n        _afterTokenTransfer(from, to, id);\n    }\n\n    /// @dev Equivalent to `_safeTransfer(from, to, id, \"\")`.\n    function _safeTransfer(address from, address to, uint256 id) internal virtual {\n        _safeTransfer(from, to, id, \"\");\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - The caller must be the owner of the token, or be approved to manage the token.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function _safeTransfer(address from, address to, uint256 id, bytes memory data)\n        internal\n        virtual\n    {\n        _transfer(address(0), from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);\n    }\n\n    /// @dev Equivalent to `_safeTransfer(by, from, to, id, \"\")`.\n    function _safeTransfer(address by, address from, address to, uint256 id) internal virtual {\n        _safeTransfer(by, from, to, id, \"\");\n    }\n\n    /// @dev Transfers token `id` from `from` to `to`.\n    ///\n    /// Requirements:\n    ///\n    /// - Token `id` must exist.\n    /// - `from` must be the owner of the token.\n    /// - `to` cannot be the zero address.\n    /// - If `by` is not the zero address,\n    ///   it must be the owner of the token, or be approved to manage the token.\n    /// - If `to` refers to a smart contract, it must implement\n    ///   {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n    ///\n    /// Emits a {Transfer} event.\n    function _safeTransfer(address by, address from, address to, uint256 id, bytes memory data)\n        internal\n        virtual\n    {\n        _transfer(by, from, to, id);\n        if (_hasCode(to)) _checkOnERC721Received(from, to, id, data);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                    HOOKS FOR OVERRIDING                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Hook that is called before any token transfers, including minting and burning.\n    function _beforeTokenTransfer(address from, address to, uint256 id) internal virtual {}\n\n    /// @dev Hook that is called after any token transfers, including minting and burning.\n    function _afterTokenTransfer(address from, address to, uint256 id) internal virtual {}\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      PRIVATE HELPERS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns if `a` has bytecode of non-zero length.\n    function _hasCode(address a) private view returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := extcodesize(a) // Can handle dirty upper bits.\n        }\n    }\n\n    /// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`.\n    /// Reverts if the target does not support the function correctly.\n    function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data)\n        private\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Prepare the calldata.\n            let m := mload(0x40)\n            let onERC721ReceivedSelector := 0x150b7a02\n            mstore(m, onERC721ReceivedSelector)\n            mstore(add(m, 0x20), caller()) // The `operator`, which is always `msg.sender`.\n            mstore(add(m, 0x40), shr(96, shl(96, from)))\n            mstore(add(m, 0x60), id)\n            mstore(add(m, 0x80), 0x80)\n            let n := mload(data)\n            mstore(add(m, 0xa0), n)\n            if n { pop(staticcall(gas(), 4, add(data, 0x20), n, add(m, 0xc0), n)) }\n            // Revert if the call reverts.\n            if iszero(call(gas(), to, 0, add(m, 0x1c), add(n, 0xa4), m, 0x20)) {\n                if returndatasize() {\n                    // Bubble up the revert if the call reverts.\n                    returndatacopy(m, 0x00, returndatasize())\n                    revert(m, returndatasize())\n                }\n            }\n            // Load the returndata and compare it.\n            if iszero(eq(mload(m), shl(224, onERC721ReceivedSelector))) {\n                mstore(0x00, 0xd1a57ed6) // `TransferToNonERC721ReceiverImplementer()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n}\n"},"lib/solady/src/utils/LibString.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {LibBytes} from \"./LibBytes.sol\";\n\n/// @notice Library for converting numbers into strings and other string operations.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)\n///\n/// @dev Note:\n/// For performance and bytecode compactness, most of the string operations are restricted to\n/// byte strings (7-bit ASCII), except where otherwise specified.\n/// Usage of byte string operations on charsets with runes spanning two or more bytes\n/// can lead to undefined behavior.\nlibrary LibString {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STRUCTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Goated string storage struct that totally MOGs, no cap, fr.\n    /// Uses less gas and bytecode than Solidity's native string storage. It's meta af.\n    /// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight.\n    struct StringStorage {\n        bytes32 _spacer;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CUSTOM ERRORS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The length of the output is too small to contain all the hex digits.\n    error HexLengthInsufficient();\n\n    /// @dev The length of the string is more than 32 bytes.\n    error TooBigForSmallString();\n\n    /// @dev The input string must be a 7-bit ASCII.\n    error StringNot7BitASCII();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The constant returned when the `search` is not found in the string.\n    uint256 internal constant NOT_FOUND = type(uint256).max;\n\n    /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n    uint128 internal constant ALPHANUMERIC_7_BIT_ASCII = 0x7fffffe07fffffe03ff000000000000;\n\n    /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n    uint128 internal constant LETTERS_7_BIT_ASCII = 0x7fffffe07fffffe0000000000000000;\n\n    /// @dev Lookup for 'abcdefghijklmnopqrstuvwxyz'.\n    uint128 internal constant LOWERCASE_7_BIT_ASCII = 0x7fffffe000000000000000000000000;\n\n    /// @dev Lookup for 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n    uint128 internal constant UPPERCASE_7_BIT_ASCII = 0x7fffffe0000000000000000;\n\n    /// @dev Lookup for '0123456789'.\n    uint128 internal constant DIGITS_7_BIT_ASCII = 0x3ff000000000000;\n\n    /// @dev Lookup for '0123456789abcdefABCDEF'.\n    uint128 internal constant HEXDIGITS_7_BIT_ASCII = 0x7e0000007e03ff000000000000;\n\n    /// @dev Lookup for '01234567'.\n    uint128 internal constant OCTDIGITS_7_BIT_ASCII = 0xff000000000000;\n\n    /// @dev Lookup for '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~ \\t\\n\\r\\x0b\\x0c'.\n    uint128 internal constant PRINTABLE_7_BIT_ASCII = 0x7fffffffffffffffffffffff00003e00;\n\n    /// @dev Lookup for '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'.\n    uint128 internal constant PUNCTUATION_7_BIT_ASCII = 0x78000001f8000001fc00fffe00000000;\n\n    /// @dev Lookup for ' \\t\\n\\r\\x0b\\x0c'.\n    uint128 internal constant WHITESPACE_7_BIT_ASCII = 0x100003e00;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                 STRING STORAGE OPERATIONS                  */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sets the value of the string storage `$` to `s`.\n    function set(StringStorage storage $, string memory s) internal {\n        LibBytes.set(bytesStorage($), bytes(s));\n    }\n\n    /// @dev Sets the value of the string storage `$` to `s`.\n    function setCalldata(StringStorage storage $, string calldata s) internal {\n        LibBytes.setCalldata(bytesStorage($), bytes(s));\n    }\n\n    /// @dev Sets the value of the string storage `$` to the empty string.\n    function clear(StringStorage storage $) internal {\n        delete $._spacer;\n    }\n\n    /// @dev Returns whether the value stored is `$` is the empty string \"\".\n    function isEmpty(StringStorage storage $) internal view returns (bool) {\n        return uint256($._spacer) & 0xff == uint256(0);\n    }\n\n    /// @dev Returns the length of the value stored in `$`.\n    function length(StringStorage storage $) internal view returns (uint256) {\n        return LibBytes.length(bytesStorage($));\n    }\n\n    /// @dev Returns the value stored in `$`.\n    function get(StringStorage storage $) internal view returns (string memory) {\n        return string(LibBytes.get(bytesStorage($)));\n    }\n\n    /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0.\n    function uint8At(StringStorage storage $, uint256 i) internal view returns (uint8) {\n        return LibBytes.uint8At(bytesStorage($), i);\n    }\n\n    /// @dev Helper to cast `$` to a `BytesStorage`.\n    function bytesStorage(StringStorage storage $)\n        internal\n        pure\n        returns (LibBytes.BytesStorage storage casted)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            casted.slot := $.slot\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     DECIMAL OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(uint256 value) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but\n            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.\n            // We will need 1 word for the trailing zeros padding, 1 word for the length,\n            // and 3 words for a maximum of 78 digits.\n            result := add(mload(0x40), 0x80)\n            mstore(0x40, add(result, 0x20)) // Allocate memory.\n            mstore(result, 0) // Zeroize the slot after the string.\n\n            let end := result // Cache the end of the memory to calculate the length later.\n            let w := not(0) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                result := add(result, w) // `sub(result, 1)`.\n                // Store the character to the pointer.\n                // The ASCII index of the '0' character is 48.\n                mstore8(result, add(48, mod(temp, 10)))\n                temp := div(temp, 10) // Keep dividing `temp` until zero.\n                if iszero(temp) { break }\n            }\n            let n := sub(end, result)\n            result := sub(result, 0x20) // Move the pointer 32 bytes back to make room for the length.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(int256 value) internal pure returns (string memory result) {\n        if (value >= 0) return toString(uint256(value));\n        unchecked {\n            result = toString(~uint256(value) + 1);\n        }\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We still have some spare memory space on the left,\n            // as we have allocated 3 words (96 bytes) for up to 78 digits.\n            let n := mload(result) // Load the string length.\n            mstore(result, 0x2d) // Store the '-' character.\n            result := sub(result, 1) // Move back the string pointer by a byte.\n            mstore(result, add(n, 1)) // Update the string length.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   HEXADECIMAL OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `byteCount` bytes.\n    /// The output is prefixed with \"0x\" encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `byteCount * 2 + 2` bytes.\n    /// Reverts if `byteCount` is too small for the output to contain all the digits.\n    function toHexString(uint256 value, uint256 byteCount)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = toHexStringNoPrefix(value, byteCount);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `byteCount` bytes.\n    /// The output is not prefixed with \"0x\" and is encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `byteCount * 2` bytes.\n    /// Reverts if `byteCount` is too small for the output to contain all the digits.\n    function toHexStringNoPrefix(uint256 value, uint256 byteCount)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, `byteCount * 2` bytes\n            // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.\n            // We add 0x20 to the total and round down to a multiple of 0x20.\n            // (0x20 + 0x20 + 0x02 + 0x20) = 0x62.\n            result := add(mload(0x40), and(add(shl(1, byteCount), 0x42), not(0x1f)))\n            mstore(0x40, add(result, 0x20)) // Allocate memory.\n            mstore(result, 0) // Zeroize the slot after the string.\n\n            let end := result // Cache the end to calculate the length later.\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let start := sub(result, add(byteCount, byteCount))\n            let w := not(1) // Tsk.\n            let temp := value\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for {} 1 {} {\n                result := add(result, w) // `sub(result, 2)`.\n                mstore8(add(result, 1), mload(and(temp, 15)))\n                mstore8(result, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(xor(result, start)) { break }\n            }\n            if temp {\n                mstore(0x00, 0x2194895a) // `HexLengthInsufficient()`.\n                revert(0x1c, 0x04)\n            }\n            let n := sub(end, result)\n            result := sub(result, 0x20)\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2 + 2` bytes.\n    function toHexString(uint256 value) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\".\n    /// The output excludes leading \"0\" from the `toHexString` output.\n    /// `0x00: \"0x0\", 0x01: \"0x1\", 0x12: \"0x12\", 0x123: \"0x123\"`.\n    function toMinimalHexString(uint256 value) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present.\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(add(result, o), 0x3078) // Store the \"0x\" prefix, accounting for leading zero.\n            result := sub(add(result, o), 2) // Move the pointer, accounting for leading zero.\n            mstore(result, sub(n, o)) // Store the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output excludes leading \"0\" from the `toHexStringNoPrefix` output.\n    /// `0x00: \"0\", 0x01: \"1\", 0x12: \"12\", 0x123: \"123\"`.\n    function toMinimalHexStringNoPrefix(uint256 value)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(result, 0x20))), 0x30) // Whether leading zero is present.\n            let n := mload(result) // Get the length.\n            result := add(result, o) // Move the pointer, accounting for leading zero.\n            mstore(result, sub(n, o)) // Store the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2` bytes.\n    function toHexStringNoPrefix(uint256 value) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x40 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.\n            result := add(mload(0x40), 0x80)\n            mstore(0x40, add(result, 0x20)) // Allocate memory.\n            mstore(result, 0) // Zeroize the slot after the string.\n\n            let end := result // Cache the end to calculate the length later.\n            mstore(0x0f, 0x30313233343536373839616263646566) // Store the \"0123456789abcdef\" lookup.\n\n            let w := not(1) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                result := add(result, w) // `sub(result, 2)`.\n                mstore8(add(result, 1), mload(and(temp, 15)))\n                mstore8(result, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(temp) { break }\n            }\n            let n := sub(end, result)\n            result := sub(result, 0x20)\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\", encoded using 2 hexadecimal digits per byte,\n    /// and the alphabets are capitalized conditionally according to\n    /// https://eips.ethereum.org/EIPS/eip-55\n    function toHexStringChecksummed(address value) internal pure returns (string memory result) {\n        result = toHexString(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`\n            let o := add(result, 0x22)\n            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `\n            let t := shl(240, 136) // `0b10001000 << 240`\n            for { let i := 0 } 1 {} {\n                mstore(add(i, i), mul(t, byte(i, hashed)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))\n            o := add(o, 0x20)\n            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    function toHexString(address value) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(address value) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            // Allocate memory.\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x28 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.\n            mstore(0x40, add(result, 0x80))\n            mstore(0x0f, 0x30313233343536373839616263646566) // Store the \"0123456789abcdef\" lookup.\n\n            result := add(result, 2)\n            mstore(result, 40) // Store the length.\n            let o := add(result, 0x20)\n            mstore(add(o, 40), 0) // Zeroize the slot after the string.\n            value := shl(96, value)\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let i := 0 } 1 {} {\n                let p := add(o, add(i, i))\n                let temp := byte(i, value)\n                mstore8(add(p, 1), mload(and(temp, 15)))\n                mstore8(p, mload(shr(4, temp)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexString(bytes memory raw) internal pure returns (string memory result) {\n        result = toHexStringNoPrefix(raw);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := add(mload(result), 2) // Compute the length.\n            mstore(result, 0x3078) // Store the \"0x\" prefix.\n            result := sub(result, 2) // Move the pointer.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(raw)\n            result := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.\n            mstore(result, add(n, n)) // Store the length of the output.\n\n            mstore(0x0f, 0x30313233343536373839616263646566) // Store the \"0123456789abcdef\" lookup.\n            let o := add(result, 0x20)\n            let end := add(raw, n)\n            for {} iszero(eq(raw, end)) {} {\n                raw := add(raw, 1)\n                mstore8(add(o, 1), mload(and(mload(raw), 15)))\n                mstore8(o, mload(and(shr(4, mload(raw)), 15)))\n                o := add(o, 2)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   RUNE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the number of UTF characters in the string.\n    function runeCount(string memory s) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mload(s) {\n                mstore(0x00, div(not(0), 255))\n                mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)\n                let o := add(s, 0x20)\n                let end := add(o, mload(s))\n                for { result := 1 } 1 { result := add(result, 1) } {\n                    o := add(o, byte(0, mload(shr(250, mload(o)))))\n                    if iszero(lt(o, end)) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns if this string is a 7-bit ASCII string.\n    /// (i.e. all characters codes are in [0..127])\n    function is7BitASCII(string memory s) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            let mask := shl(7, div(not(0), 255))\n            let n := mload(s)\n            if n {\n                let o := add(s, 0x20)\n                let end := add(o, n)\n                let last := mload(end)\n                mstore(end, 0)\n                for {} 1 {} {\n                    if and(mask, mload(o)) {\n                        result := 0\n                        break\n                    }\n                    o := add(o, 0x20)\n                    if iszero(lt(o, end)) { break }\n                }\n                mstore(end, last)\n            }\n        }\n    }\n\n    /// @dev Returns if this string is a 7-bit ASCII string,\n    /// AND all characters are in the `allowed` lookup.\n    /// Note: If `s` is empty, returns true regardless of `allowed`.\n    function is7BitASCII(string memory s, uint128 allowed) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := 1\n            if mload(s) {\n                let allowed_ := shr(128, shl(128, allowed))\n                let o := add(s, 0x20)\n                for { let end := add(o, mload(s)) } 1 {} {\n                    result := and(result, shr(byte(0, mload(o)), allowed_))\n                    o := add(o, 1)\n                    if iszero(and(result, lt(o, end))) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Converts the bytes in the 7-bit ASCII string `s` to\n    /// an allowed lookup for use in `is7BitASCII(s, allowed)`.\n    /// To save runtime gas, you can cache the result in an immutable variable.\n    function to7BitASCIIAllowedLookup(string memory s) internal pure returns (uint128 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mload(s) {\n                let o := add(s, 0x20)\n                for { let end := add(o, mload(s)) } 1 {} {\n                    result := or(result, shl(byte(0, mload(o)), 1))\n                    o := add(o, 1)\n                    if iszero(lt(o, end)) { break }\n                }\n                if shr(128, result) {\n                    mstore(0x00, 0xc9807e0d) // `StringNot7BitASCII()`.\n                    revert(0x1c, 0x04)\n                }\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   BYTE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // For performance and bytecode compactness, byte string operations are restricted\n    // to 7-bit ASCII strings. All offsets are byte offsets, not UTF character offsets.\n    // Usage of byte string operations on charsets with runes spanning two or more bytes\n    // can lead to undefined behavior.\n\n    /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`.\n    function replace(string memory subject, string memory needle, string memory replacement)\n        internal\n        pure\n        returns (string memory)\n    {\n        return string(LibBytes.replace(bytes(subject), bytes(needle), bytes(replacement)));\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(string memory subject, string memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256)\n    {\n        return LibBytes.indexOf(bytes(subject), bytes(needle), from);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(string memory subject, string memory needle) internal pure returns (uint256) {\n        return LibBytes.indexOf(bytes(subject), bytes(needle), 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(string memory subject, string memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256)\n    {\n        return LibBytes.lastIndexOf(bytes(subject), bytes(needle), from);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(string memory subject, string memory needle)\n        internal\n        pure\n        returns (uint256)\n    {\n        return LibBytes.lastIndexOf(bytes(subject), bytes(needle), type(uint256).max);\n    }\n\n    /// @dev Returns true if `needle` is found in `subject`, false otherwise.\n    function contains(string memory subject, string memory needle) internal pure returns (bool) {\n        return LibBytes.contains(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns whether `subject` starts with `needle`.\n    function startsWith(string memory subject, string memory needle) internal pure returns (bool) {\n        return LibBytes.startsWith(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns whether `subject` ends with `needle`.\n    function endsWith(string memory subject, string memory needle) internal pure returns (bool) {\n        return LibBytes.endsWith(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns `subject` repeated `times`.\n    function repeat(string memory subject, uint256 times) internal pure returns (string memory) {\n        return string(LibBytes.repeat(bytes(subject), times));\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets.\n    function slice(string memory subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (string memory)\n    {\n        return string(LibBytes.slice(bytes(subject), start, end));\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the string.\n    /// `start` is a byte offset.\n    function slice(string memory subject, uint256 start) internal pure returns (string memory) {\n        return string(LibBytes.slice(bytes(subject), start, type(uint256).max));\n    }\n\n    /// @dev Returns all the indices of `needle` in `subject`.\n    /// The indices are byte offsets.\n    function indicesOf(string memory subject, string memory needle)\n        internal\n        pure\n        returns (uint256[] memory)\n    {\n        return LibBytes.indicesOf(bytes(subject), bytes(needle));\n    }\n\n    /// @dev Returns an arrays of strings based on the `delimiter` inside of the `subject` string.\n    function split(string memory subject, string memory delimiter)\n        internal\n        pure\n        returns (string[] memory result)\n    {\n        bytes[] memory a = LibBytes.split(bytes(subject), bytes(delimiter));\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := a\n        }\n    }\n\n    /// @dev Returns a concatenated string of `a` and `b`.\n    /// Cheaper than `string.concat()` and does not de-align the free memory pointer.\n    function concat(string memory a, string memory b) internal pure returns (string memory) {\n        return string(LibBytes.concat(bytes(a), bytes(b)));\n    }\n\n    /// @dev Returns a copy of the string in either lowercase or UPPERCASE.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function toCase(string memory subject, bool toUpper)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(subject)\n            if n {\n                result := mload(0x40)\n                let o := add(result, 0x20)\n                let d := sub(subject, result)\n                let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)\n                for { let end := add(o, n) } 1 {} {\n                    let b := byte(0, mload(add(d, o)))\n                    mstore8(o, xor(and(shr(b, flags), 0x20), b))\n                    o := add(o, 1)\n                    if eq(o, end) { break }\n                }\n                mstore(result, n) // Store the length.\n                mstore(o, 0) // Zeroize the slot after the string.\n                mstore(0x40, add(o, 0x20)) // Allocate memory.\n            }\n        }\n    }\n\n    /// @dev Returns a string from a small bytes32 string.\n    /// `s` must be null-terminated, or behavior will be undefined.\n    function fromSmallString(bytes32 s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let n := 0\n            for {} byte(n, s) { n := add(n, 1) } {} // Scan for '\\0'.\n            mstore(result, n) // Store the length.\n            let o := add(result, 0x20)\n            mstore(o, s) // Store the bytes of the string.\n            mstore(add(o, n), 0) // Zeroize the slot after the string.\n            mstore(0x40, add(result, 0x40)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the small string, with all bytes after the first null byte zeroized.\n    function normalizeSmallString(bytes32 s) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} byte(result, s) { result := add(result, 1) } {} // Scan for '\\0'.\n            mstore(0x00, s)\n            mstore(result, 0x00)\n            result := mload(0x00)\n        }\n    }\n\n    /// @dev Returns the string as a normalized null-terminated small string.\n    function toSmallString(string memory s) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(s)\n            if iszero(lt(result, 33)) {\n                mstore(0x00, 0xec92f9a3) // `TooBigForSmallString()`.\n                revert(0x1c, 0x04)\n            }\n            result := shl(shl(3, sub(32, result)), mload(add(s, result)))\n        }\n    }\n\n    /// @dev Returns a lowercased copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function lower(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, false);\n    }\n\n    /// @dev Returns an UPPERCASED copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function upper(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, true);\n    }\n\n    /// @dev Escapes the string to be used within HTML tags.\n    function escapeHTML(string memory s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let end := add(s, mload(s))\n            let o := add(result, 0x20)\n            // Store the bytes of the packed offsets and strides into the scratch space.\n            // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6.\n            mstore(0x1f, 0x900094)\n            mstore(0x08, 0xc0000000a6ab)\n            // Store \"&quot;&amp;&#39;&lt;&gt;\" into the scratch space.\n            mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))\n            for {} iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                // Not in `[\"\\\"\",\"'\",\"&\",\"<\",\">\"]`.\n                if iszero(and(shl(c, 1), 0x500000c400000000)) {\n                    mstore8(o, c)\n                    o := add(o, 1)\n                    continue\n                }\n                let t := shr(248, mload(c))\n                mstore(o, mload(and(t, 0x1f)))\n                o := add(o, shr(5, t))\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes.\n    function escapeJSON(string memory s, bool addDoubleQuotes)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let o := add(result, 0x20)\n            if addDoubleQuotes {\n                mstore8(o, 34)\n                o := add(1, o)\n            }\n            // Store \"\\\\u0000\" in scratch space.\n            // Store \"0123456789abcdef\" in scratch space.\n            // Also, store `{0x08:\"b\", 0x09:\"t\", 0x0a:\"n\", 0x0c:\"f\", 0x0d:\"r\"}`.\n            // into the scratch space.\n            mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)\n            // Bitmask for detecting `[\"\\\"\",\"\\\\\"]`.\n            let e := or(shl(0x22, 1), shl(0x5c, 1))\n            for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                if iszero(lt(c, 0x20)) {\n                    if iszero(and(shl(c, 1), e)) {\n                        // Not in `[\"\\\"\",\"\\\\\"]`.\n                        mstore8(o, c)\n                        o := add(o, 1)\n                        continue\n                    }\n                    mstore8(o, 0x5c) // \"\\\\\".\n                    mstore8(add(o, 1), c)\n                    o := add(o, 2)\n                    continue\n                }\n                if iszero(and(shl(c, 1), 0x3700)) {\n                    // Not in `[\"\\b\",\"\\t\",\"\\n\",\"\\f\",\"\\d\"]`.\n                    mstore8(0x1d, mload(shr(4, c))) // Hex value.\n                    mstore8(0x1e, mload(and(c, 15))) // Hex value.\n                    mstore(o, mload(0x19)) // \"\\\\u00XX\".\n                    o := add(o, 6)\n                    continue\n                }\n                mstore8(o, 0x5c) // \"\\\\\".\n                mstore8(add(o, 1), mload(add(c, 8)))\n                o := add(o, 2)\n            }\n            if addDoubleQuotes {\n                mstore8(o, 34)\n                o := add(1, o)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    function escapeJSON(string memory s) internal pure returns (string memory result) {\n        result = escapeJSON(s, false);\n    }\n\n    /// @dev Encodes `s` so that it can be safely used in a URI,\n    /// just like `encodeURIComponent` in JavaScript.\n    /// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent\n    /// See: https://datatracker.ietf.org/doc/html/rfc2396\n    /// See: https://datatracker.ietf.org/doc/html/rfc3986\n    function encodeURIComponent(string memory s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            // Store \"0123456789ABCDEF\" in scratch space.\n            // Uppercased to be consistent with JavaScript's implementation.\n            mstore(0x0f, 0x30313233343536373839414243444546)\n            let o := add(result, 0x20)\n            for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                // If not in `[0-9A-Z-a-z-_.!~*'()]`.\n                if iszero(and(1, shr(c, 0x47fffffe87fffffe03ff678200000000))) {\n                    mstore8(o, 0x25) // '%'.\n                    mstore8(add(o, 1), mload(and(shr(4, c), 15)))\n                    mstore8(add(o, 2), mload(and(c, 15)))\n                    o := add(o, 3)\n                    continue\n                }\n                mstore8(o, c)\n                o := add(o, 1)\n            }\n            mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`.\n    function eq(string memory a, string memory b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small string.\n    function eqs(string memory a, bytes32 b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // These should be evaluated on compile time, as far as possible.\n            let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`.\n            let x := not(or(m, or(b, add(m, and(b, m)))))\n            let r := shl(7, iszero(iszero(shr(128, x))))\n            r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x))))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            // forgefmt: disable-next-item\n            result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))),\n                xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20)))))\n        }\n    }\n\n    /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`.\n    /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1.\n    function cmp(string memory a, string memory b) internal pure returns (int256) {\n        return LibBytes.cmp(bytes(a), bytes(b));\n    }\n\n    /// @dev Packs a single string with its length into a single word.\n    /// Returns `bytes32(0)` if the length is zero or greater than 31.\n    function packOne(string memory a) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We don't need to zero right pad the string,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    // Load the length and the bytes.\n                    mload(add(a, 0x1f)),\n                    // `length != 0 && length < 32`. Abuses underflow.\n                    // Assumes that the length is valid and within the block gas limit.\n                    lt(sub(mload(a), 1), 0x1f)\n                )\n        }\n    }\n\n    /// @dev Unpacks a string packed using {packOne}.\n    /// Returns the empty string if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packOne}, the output behavior is undefined.\n    function unpackOne(bytes32 packed) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40) // Grab the free memory pointer.\n            mstore(0x40, add(result, 0x40)) // Allocate 2 words (1 for the length, 1 for the bytes).\n            mstore(result, 0) // Zeroize the length slot.\n            mstore(add(result, 0x1f), packed) // Store the length and bytes.\n            mstore(add(add(result, 0x20), mload(result)), 0) // Right pad with zeroes.\n        }\n    }\n\n    /// @dev Packs two strings with their lengths into a single word.\n    /// Returns `bytes32(0)` if combined length is zero or greater than 30.\n    function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let aLen := mload(a)\n            // We don't need to zero right pad the strings,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    or( // Load the length and the bytes of `a` and `b`.\n                    shl(shl(3, sub(0x1f, aLen)), mload(add(a, aLen))), mload(sub(add(b, 0x1e), aLen))),\n                    // `totalLen != 0 && totalLen < 31`. Abuses underflow.\n                    // Assumes that the lengths are valid and within the block gas limit.\n                    lt(sub(add(aLen, mload(b)), 1), 0x1e)\n                )\n        }\n    }\n\n    /// @dev Unpacks strings packed using {packTwo}.\n    /// Returns the empty strings if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packTwo}, the output behavior is undefined.\n    function unpackTwo(bytes32 packed)\n        internal\n        pure\n        returns (string memory resultA, string memory resultB)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            resultA := mload(0x40) // Grab the free memory pointer.\n            resultB := add(resultA, 0x40)\n            // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.\n            mstore(0x40, add(resultB, 0x40))\n            // Zeroize the length slots.\n            mstore(resultA, 0)\n            mstore(resultB, 0)\n            // Store the lengths and bytes.\n            mstore(add(resultA, 0x1f), packed)\n            mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))\n            // Right pad with zeroes.\n            mstore(add(add(resultA, 0x20), mload(resultA)), 0)\n            mstore(add(add(resultB, 0x20), mload(resultB)), 0)\n        }\n    }\n\n    /// @dev Directly returns `a` without copying.\n    function directReturn(string memory a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Assumes that the string does not start from the scratch space.\n            let retStart := sub(a, 0x20)\n            let retUnpaddedSize := add(mload(a), 0x40)\n            // Right pad with zeroes. Just in case the string is produced\n            // by a method that doesn't zero right pad.\n            mstore(add(retStart, retUnpaddedSize), 0)\n            mstore(retStart, 0x20) // Store the return offset.\n            // End the transaction, returning the string.\n            return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize)))\n        }\n    }\n}\n"},"lib/solady/src/utils/Base64.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Library to encode strings in Base64.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Base64.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Base64.sol)\n/// @author Modified from (https://github.com/Brechtpd/base64/blob/main/base64.sol) by Brecht Devos - <brecht@loopring.org>.\nlibrary Base64 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                    ENCODING / DECODING                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.\n    /// See: https://datatracker.ietf.org/doc/html/rfc4648\n    /// @param fileSafe  Whether to replace '+' with '-' and '/' with '_'.\n    /// @param noPadding Whether to strip away the padding.\n    function encode(bytes memory data, bool fileSafe, bool noPadding)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let dataLength := mload(data)\n\n            if dataLength {\n                // Multiply by 4/3 rounded up.\n                // The `shl(2, ...)` is equivalent to multiplying by 4.\n                let encodedLength := shl(2, div(add(dataLength, 2), 3))\n\n                // Set `result` to point to the start of the free memory.\n                result := mload(0x40)\n\n                // Store the table into the scratch space.\n                // Offsetted by -1 byte so that the `mload` will load the character.\n                // We will rewrite the free memory pointer at `0x40` later with\n                // the allocated size.\n                // The magic constant 0x0670 will turn \"-_\" into \"+/\".\n                mstore(0x1f, \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\")\n                mstore(0x3f, xor(\"ghijklmnopqrstuvwxyz0123456789-_\", mul(iszero(fileSafe), 0x0670)))\n\n                // Skip the first slot, which stores the length.\n                let ptr := add(result, 0x20)\n                let end := add(ptr, encodedLength)\n\n                let dataEnd := add(add(0x20, data), dataLength)\n                let dataEndValue := mload(dataEnd) // Cache the value at the `dataEnd` slot.\n                mstore(dataEnd, 0x00) // Zeroize the `dataEnd` slot to clear dirty bits.\n\n                // Run over the input, 3 bytes at a time.\n                for {} 1 {} {\n                    data := add(data, 3) // Advance 3 bytes.\n                    let input := mload(data)\n\n                    // Write 4 bytes. Optimized for fewer stack operations.\n                    mstore8(0, mload(and(shr(18, input), 0x3F)))\n                    mstore8(1, mload(and(shr(12, input), 0x3F)))\n                    mstore8(2, mload(and(shr(6, input), 0x3F)))\n                    mstore8(3, mload(and(input, 0x3F)))\n                    mstore(ptr, mload(0x00))\n\n                    ptr := add(ptr, 4) // Advance 4 bytes.\n                    if iszero(lt(ptr, end)) { break }\n                }\n                mstore(dataEnd, dataEndValue) // Restore the cached value at `dataEnd`.\n                mstore(0x40, add(end, 0x20)) // Allocate the memory.\n                // Equivalent to `o = [0, 2, 1][dataLength % 3]`.\n                let o := div(2, mod(dataLength, 3))\n                // Offset `ptr` and pad with '='. We can simply write over the end.\n                mstore(sub(ptr, o), shl(240, 0x3d3d))\n                // Set `o` to zero if there is padding.\n                o := mul(iszero(iszero(noPadding)), o)\n                mstore(sub(ptr, o), 0) // Zeroize the slot after the string.\n                mstore(result, sub(encodedLength, o)) // Store the length.\n            }\n        }\n    }\n\n    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.\n    /// Equivalent to `encode(data, false, false)`.\n    function encode(bytes memory data) internal pure returns (string memory result) {\n        result = encode(data, false, false);\n    }\n\n    /// @dev Encodes `data` using the base64 encoding described in RFC 4648.\n    /// Equivalent to `encode(data, fileSafe, false)`.\n    function encode(bytes memory data, bool fileSafe)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = encode(data, fileSafe, false);\n    }\n\n    /// @dev Decodes base64 encoded `data`.\n    ///\n    /// Supports:\n    /// - RFC 4648 (both standard and file-safe mode).\n    /// - RFC 3501 (63: ',').\n    ///\n    /// Does not support:\n    /// - Line breaks.\n    ///\n    /// Note: For performance reasons,\n    /// this function will NOT revert on invalid `data` inputs.\n    /// Outputs for invalid inputs will simply be undefined behaviour.\n    /// It is the user's responsibility to ensure that the `data`\n    /// is a valid base64 encoded string.\n    function decode(string memory data) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let dataLength := mload(data)\n\n            if dataLength {\n                let decodedLength := mul(shr(2, dataLength), 3)\n\n                for {} 1 {} {\n                    // If padded.\n                    if iszero(and(dataLength, 3)) {\n                        let t := xor(mload(add(data, dataLength)), 0x3d3d)\n                        // forgefmt: disable-next-item\n                        decodedLength := sub(\n                            decodedLength,\n                            add(iszero(byte(30, t)), iszero(byte(31, t)))\n                        )\n                        break\n                    }\n                    // If non-padded.\n                    decodedLength := add(decodedLength, sub(and(dataLength, 3), 1))\n                    break\n                }\n                result := mload(0x40)\n\n                // Write the length of the bytes.\n                mstore(result, decodedLength)\n\n                // Skip the first slot, which stores the length.\n                let ptr := add(result, 0x20)\n                let end := add(ptr, decodedLength)\n\n                // Load the table into the scratch space.\n                // Constants are optimized for smaller bytecode with zero gas overhead.\n                // `m` also doubles as the mask of the upper 6 bits.\n                let m := 0xfc000000fc00686c7074787c8084888c9094989ca0a4a8acb0b4b8bcc0c4c8cc\n                mstore(0x5b, m)\n                mstore(0x3b, 0x04080c1014181c2024282c3034383c4044484c5054585c6064)\n                mstore(0x1a, 0xf8fcf800fcd0d4d8dce0e4e8ecf0f4)\n\n                for {} 1 {} {\n                    // Read 4 bytes.\n                    data := add(data, 4)\n                    let input := mload(data)\n\n                    // Write 3 bytes.\n                    // forgefmt: disable-next-item\n                    mstore(ptr, or(\n                        and(m, mload(byte(28, input))),\n                        shr(6, or(\n                            and(m, mload(byte(29, input))),\n                            shr(6, or(\n                                and(m, mload(byte(30, input))),\n                                shr(6, mload(byte(31, input)))\n                            ))\n                        ))\n                    ))\n                    ptr := add(ptr, 3)\n                    if iszero(lt(ptr, end)) { break }\n                }\n                mstore(0x40, add(end, 0x20)) // Allocate the memory.\n                mstore(end, 0) // Zeroize the slot after the bytes.\n                mstore(0x60, 0) // Restore the zero slot.\n            }\n        }\n    }\n}\n"},"lib/solady/src/utils/LibBytes.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Library for byte related operations.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBytes.sol)\nlibrary LibBytes {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STRUCTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Goated bytes storage struct that totally MOGs, no cap, fr.\n    /// Uses less gas and bytecode than Solidity's native bytes storage. It's meta af.\n    /// Packs length with the first 31 bytes if <255 bytes, so it’s mad tight.\n    struct BytesStorage {\n        bytes32 _spacer;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The constant returned when the `search` is not found in the bytes.\n    uint256 internal constant NOT_FOUND = type(uint256).max;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  BYTE STORAGE OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Sets the value of the bytes storage `$` to `s`.\n    function set(BytesStorage storage $, bytes memory s) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(s)\n            let packed := or(0xff, shl(8, n))\n            for { let i := 0 } 1 {} {\n                if iszero(gt(n, 0xfe)) {\n                    i := 0x1f\n                    packed := or(n, shl(8, mload(add(s, i))))\n                    if iszero(gt(n, i)) { break }\n                }\n                let o := add(s, 0x20)\n                mstore(0x00, $.slot)\n                for { let p := keccak256(0x00, 0x20) } 1 {} {\n                    sstore(add(p, shr(5, i)), mload(add(o, i)))\n                    i := add(i, 0x20)\n                    if iszero(lt(i, n)) { break }\n                }\n                break\n            }\n            sstore($.slot, packed)\n        }\n    }\n\n    /// @dev Sets the value of the bytes storage `$` to `s`.\n    function setCalldata(BytesStorage storage $, bytes calldata s) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let packed := or(0xff, shl(8, s.length))\n            for { let i := 0 } 1 {} {\n                if iszero(gt(s.length, 0xfe)) {\n                    i := 0x1f\n                    packed := or(s.length, shl(8, shr(8, calldataload(s.offset))))\n                    if iszero(gt(s.length, i)) { break }\n                }\n                mstore(0x00, $.slot)\n                for { let p := keccak256(0x00, 0x20) } 1 {} {\n                    sstore(add(p, shr(5, i)), calldataload(add(s.offset, i)))\n                    i := add(i, 0x20)\n                    if iszero(lt(i, s.length)) { break }\n                }\n                break\n            }\n            sstore($.slot, packed)\n        }\n    }\n\n    /// @dev Sets the value of the bytes storage `$` to the empty bytes.\n    function clear(BytesStorage storage $) internal {\n        delete $._spacer;\n    }\n\n    /// @dev Returns whether the value stored is `$` is the empty bytes \"\".\n    function isEmpty(BytesStorage storage $) internal view returns (bool) {\n        return uint256($._spacer) & 0xff == uint256(0);\n    }\n\n    /// @dev Returns the length of the value stored in `$`.\n    function length(BytesStorage storage $) internal view returns (uint256 result) {\n        result = uint256($._spacer);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := and(0xff, result)\n            result := or(mul(shr(8, result), eq(0xff, n)), mul(n, iszero(eq(0xff, n))))\n        }\n    }\n\n    /// @dev Returns the value stored in `$`.\n    function get(BytesStorage storage $) internal view returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let o := add(result, 0x20)\n            let packed := sload($.slot)\n            let n := shr(8, packed)\n            for { let i := 0 } 1 {} {\n                if iszero(eq(or(packed, 0xff), packed)) {\n                    mstore(o, packed)\n                    n := and(0xff, packed)\n                    i := 0x1f\n                    if iszero(gt(n, i)) { break }\n                }\n                mstore(0x00, $.slot)\n                for { let p := keccak256(0x00, 0x20) } 1 {} {\n                    mstore(add(o, i), sload(add(p, shr(5, i))))\n                    i := add(i, 0x20)\n                    if iszero(lt(i, n)) { break }\n                }\n                break\n            }\n            mstore(result, n) // Store the length of the memory.\n            mstore(add(o, n), 0) // Zeroize the slot after the bytes.\n            mstore(0x40, add(add(o, n), 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns the uint8 at index `i`. If out-of-bounds, returns 0.\n    function uint8At(BytesStorage storage $, uint256 i) internal view returns (uint8 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for { let packed := sload($.slot) } 1 {} {\n                if iszero(eq(or(packed, 0xff), packed)) {\n                    if iszero(gt(i, 0x1e)) {\n                        result := byte(i, packed)\n                        break\n                    }\n                    if iszero(gt(i, and(0xff, packed))) {\n                        mstore(0x00, $.slot)\n                        let j := sub(i, 0x1f)\n                        result := byte(and(j, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, j))))\n                    }\n                    break\n                }\n                if iszero(gt(i, shr(8, packed))) {\n                    mstore(0x00, $.slot)\n                    result := byte(and(i, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, i))))\n                }\n                break\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                      BYTES OPERATIONS                      */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns `subject` all occurrences of `needle` replaced with `replacement`.\n    function replace(bytes memory subject, bytes memory needle, bytes memory replacement)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let needleLen := mload(needle)\n            let replacementLen := mload(replacement)\n            let d := sub(result, subject) // Memory difference.\n            let i := add(subject, 0x20) // Subject bytes pointer.\n            mstore(0x00, add(i, mload(subject))) // End of subject.\n            if iszero(gt(needleLen, mload(subject))) {\n                let subjectSearchEnd := add(sub(mload(0x00), needleLen), 1)\n                let h := 0 // The hash of `needle`.\n                if iszero(lt(needleLen, 0x20)) { h := keccak256(add(needle, 0x20), needleLen) }\n                let s := mload(add(needle, 0x20))\n                for { let m := shl(3, sub(0x20, and(needleLen, 0x1f))) } 1 {} {\n                    let t := mload(i)\n                    // Whether the first `needleLen % 32` bytes of `subject` and `needle` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(i, needleLen), h)) {\n                                mstore(add(i, d), t)\n                                i := add(i, 1)\n                                if iszero(lt(i, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        // Copy the `replacement` one word at a time.\n                        for { let j := 0 } 1 {} {\n                            mstore(add(add(i, d), j), mload(add(add(replacement, 0x20), j)))\n                            j := add(j, 0x20)\n                            if iszero(lt(j, replacementLen)) { break }\n                        }\n                        d := sub(add(d, replacementLen), needleLen)\n                        if needleLen {\n                            i := add(i, needleLen)\n                            if iszero(lt(i, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    mstore(add(i, d), t)\n                    i := add(i, 1)\n                    if iszero(lt(i, subjectSearchEnd)) { break }\n                }\n            }\n            let end := mload(0x00)\n            let n := add(sub(d, add(result, 0x20)), end)\n            // Copy the rest of the bytes one word at a time.\n            for {} lt(i, end) { i := add(i, 0x20) } { mstore(add(i, d), mload(i)) }\n            let o := add(i, d)\n            mstore(o, 0) // Zeroize the slot after the bytes.\n            mstore(0x40, add(o, 0x20)) // Allocate memory.\n            mstore(result, n) // Store the length.\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(bytes memory subject, bytes memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := not(0) // Initialize to `NOT_FOUND`.\n            for { let subjectLen := mload(subject) } 1 {} {\n                if iszero(mload(needle)) {\n                    result := from\n                    if iszero(gt(from, subjectLen)) { break }\n                    result := subjectLen\n                    break\n                }\n                let needleLen := mload(needle)\n                let subjectStart := add(subject, 0x20)\n\n                subject := add(subjectStart, from)\n                let end := add(sub(add(subjectStart, subjectLen), needleLen), 1)\n                let m := shl(3, sub(0x20, and(needleLen, 0x1f)))\n                let s := mload(add(needle, 0x20))\n\n                if iszero(and(lt(subject, end), lt(from, subjectLen))) { break }\n\n                if iszero(lt(needleLen, 0x20)) {\n                    for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} {\n                        if iszero(shr(m, xor(mload(subject), s))) {\n                            if eq(keccak256(subject, needleLen), h) {\n                                result := sub(subject, subjectStart)\n                                break\n                            }\n                        }\n                        subject := add(subject, 1)\n                        if iszero(lt(subject, end)) { break }\n                    }\n                    break\n                }\n                for {} 1 {} {\n                    if iszero(shr(m, xor(mload(subject), s))) {\n                        result := sub(subject, subjectStart)\n                        break\n                    }\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right, starting from `from`. Optimized for byte needles.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOfByte(bytes memory subject, bytes1 needle, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := not(0) // Initialize to `NOT_FOUND`.\n            if gt(mload(subject), from) {\n                let start := add(subject, 0x20)\n                let end := add(start, mload(subject))\n                let m := div(not(0), 255) // `0x0101 ... `.\n                let h := mul(byte(0, needle), m) // Replicating needle mask.\n                m := not(shl(7, m)) // `0x7f7f ... `.\n                for { let i := add(start, from) } 1 {} {\n                    let c := xor(mload(i), h) // Load 32-byte chunk and xor with mask.\n                    c := not(or(or(add(and(c, m), m), c), m)) // Each needle byte will be `0x80`.\n                    if c {\n                        c := and(not(shr(shl(3, sub(end, i)), not(0))), c) // Truncate bytes past the end.\n                        if c {\n                            let r := shl(7, lt(0x8421084210842108cc6318c6db6d54be, c)) // Save bytecode.\n                            r := or(shl(6, lt(0xffffffffffffffff, shr(r, c))), r)\n                            // forgefmt: disable-next-item\n                            result := add(sub(i, start), shr(3, xor(byte(and(0x1f, shr(byte(24,\n                                mul(0x02040810204081, shr(r, c))), 0x8421084210842108cc6318c6db6d54be)),\n                                0xc0c8c8d0c8e8d0d8c8e8e0e8d0d8e0f0c8d0e8d0e0e0d8f0d0d0e0d8f8f8f8f8), r)))\n                            break\n                        }\n                    }\n                    i := add(i, 0x20)\n                    if iszero(lt(i, end)) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right. Optimized for byte needles.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOfByte(bytes memory subject, bytes1 needle)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        return indexOfByte(subject, needle, 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from left to right.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function indexOf(bytes memory subject, bytes memory needle) internal pure returns (uint256) {\n        return indexOf(subject, needle, 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(bytes memory subject, bytes memory needle, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} 1 {} {\n                result := not(0) // Initialize to `NOT_FOUND`.\n                let needleLen := mload(needle)\n                if gt(needleLen, mload(subject)) { break }\n                let w := result\n\n                let fromMax := sub(mload(subject), needleLen)\n                if iszero(gt(fromMax, from)) { from := fromMax }\n\n                let end := add(add(subject, 0x20), w)\n                subject := add(add(subject, 0x20), from)\n                if iszero(gt(subject, end)) { break }\n                // As this function is not too often used,\n                // we shall simply use keccak256 for smaller bytecode size.\n                for { let h := keccak256(add(needle, 0x20), needleLen) } 1 {} {\n                    if eq(keccak256(subject, needleLen), h) {\n                        result := sub(subject, add(end, 1))\n                        break\n                    }\n                    subject := add(subject, w) // `sub(subject, 1)`.\n                    if iszero(gt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `needle` in `subject`,\n    /// needleing from right to left.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `needle` is not found.\n    function lastIndexOf(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (uint256)\n    {\n        return lastIndexOf(subject, needle, type(uint256).max);\n    }\n\n    /// @dev Returns true if `needle` is found in `subject`, false otherwise.\n    function contains(bytes memory subject, bytes memory needle) internal pure returns (bool) {\n        return indexOf(subject, needle) != NOT_FOUND;\n    }\n\n    /// @dev Returns whether `subject` starts with `needle`.\n    function startsWith(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(needle)\n            // Just using keccak256 directly is actually cheaper.\n            let t := eq(keccak256(add(subject, 0x20), n), keccak256(add(needle, 0x20), n))\n            result := lt(gt(n, mload(subject)), t)\n        }\n    }\n\n    /// @dev Returns whether `subject` ends with `needle`.\n    function endsWith(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(needle)\n            let notInRange := gt(n, mload(subject))\n            // `subject + 0x20 + max(subject.length - needle.length, 0)`.\n            let t := add(add(subject, 0x20), mul(iszero(notInRange), sub(mload(subject), n)))\n            // Just using keccak256 directly is actually cheaper.\n            result := gt(eq(keccak256(t, n), keccak256(add(needle, 0x20), n)), notInRange)\n        }\n    }\n\n    /// @dev Returns `subject` repeated `times`.\n    function repeat(bytes memory subject, uint256 times)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := mload(subject) // Subject length.\n            if iszero(or(iszero(times), iszero(l))) {\n                result := mload(0x40)\n                subject := add(subject, 0x20)\n                let o := add(result, 0x20)\n                for {} 1 {} {\n                    // Copy the `subject` one word at a time.\n                    for { let j := 0 } 1 {} {\n                        mstore(add(o, j), mload(add(subject, j)))\n                        j := add(j, 0x20)\n                        if iszero(lt(j, l)) { break }\n                    }\n                    o := add(o, l)\n                    times := sub(times, 1)\n                    if iszero(times) { break }\n                }\n                mstore(o, 0) // Zeroize the slot after the bytes.\n                mstore(0x40, add(o, 0x20)) // Allocate memory.\n                mstore(result, sub(o, add(result, 0x20))) // Store the length.\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets.\n    function slice(bytes memory subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := mload(subject) // Subject length.\n            if iszero(gt(l, end)) { end := l }\n            if iszero(gt(l, start)) { start := l }\n            if lt(start, end) {\n                result := mload(0x40)\n                let n := sub(end, start)\n                let i := add(subject, start)\n                let w := not(0x1f)\n                // Copy the `subject` one word at a time, backwards.\n                for { let j := and(add(n, 0x1f), w) } 1 {} {\n                    mstore(add(result, j), mload(add(i, j)))\n                    j := add(j, w) // `sub(j, 0x20)`.\n                    if iszero(j) { break }\n                }\n                let o := add(add(result, 0x20), n)\n                mstore(o, 0) // Zeroize the slot after the bytes.\n                mstore(0x40, add(o, 0x20)) // Allocate memory.\n                mstore(result, n) // Store the length.\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes.\n    /// `start` is a byte offset.\n    function slice(bytes memory subject, uint256 start)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        result = slice(subject, start, type(uint256).max);\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets. Faster than Solidity's native slicing.\n    function sliceCalldata(bytes calldata subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            end := xor(end, mul(xor(end, subject.length), lt(subject.length, end)))\n            start := xor(start, mul(xor(start, subject.length), lt(subject.length, start)))\n            result.offset := add(subject.offset, start)\n            result.length := mul(lt(start, end), sub(end, start))\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the bytes.\n    /// `start` is a byte offset. Faster than Solidity's native slicing.\n    function sliceCalldata(bytes calldata subject, uint256 start)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            start := xor(start, mul(xor(start, subject.length), lt(subject.length, start)))\n            result.offset := add(subject.offset, start)\n            result.length := mul(lt(start, subject.length), sub(subject.length, start))\n        }\n    }\n\n    /// @dev Reduces the size of `subject` to `n`.\n    /// If `n` is greater than the size of `subject`, this will be a no-op.\n    function truncate(bytes memory subject, uint256 n)\n        internal\n        pure\n        returns (bytes memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := subject\n            mstore(mul(lt(n, mload(result)), result), n)\n        }\n    }\n\n    /// @dev Returns a copy of `subject`, with the length reduced to `n`.\n    /// If `n` is greater than the size of `subject`, this will be a no-op.\n    function truncatedCalldata(bytes calldata subject, uint256 n)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result.offset := subject.offset\n            result.length := xor(n, mul(xor(n, subject.length), lt(subject.length, n)))\n        }\n    }\n\n    /// @dev Returns all the indices of `needle` in `subject`.\n    /// The indices are byte offsets.\n    function indicesOf(bytes memory subject, bytes memory needle)\n        internal\n        pure\n        returns (uint256[] memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let searchLen := mload(needle)\n            if iszero(gt(searchLen, mload(subject))) {\n                result := mload(0x40)\n                let i := add(subject, 0x20)\n                let o := add(result, 0x20)\n                let subjectSearchEnd := add(sub(add(i, mload(subject)), searchLen), 1)\n                let h := 0 // The hash of `needle`.\n                if iszero(lt(searchLen, 0x20)) { h := keccak256(add(needle, 0x20), searchLen) }\n                let s := mload(add(needle, 0x20))\n                for { let m := shl(3, sub(0x20, and(searchLen, 0x1f))) } 1 {} {\n                    let t := mload(i)\n                    // Whether the first `searchLen % 32` bytes of `subject` and `needle` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(i, searchLen), h)) {\n                                i := add(i, 1)\n                                if iszero(lt(i, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        mstore(o, sub(i, add(subject, 0x20))) // Append to `result`.\n                        o := add(o, 0x20)\n                        i := add(i, searchLen) // Advance `i` by `searchLen`.\n                        if searchLen {\n                            if iszero(lt(i, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    i := add(i, 1)\n                    if iszero(lt(i, subjectSearchEnd)) { break }\n                }\n                mstore(result, shr(5, sub(o, add(result, 0x20)))) // Store the length of `result`.\n                // Allocate memory for result.\n                // We allocate one more word, so this array can be recycled for {split}.\n                mstore(0x40, add(o, 0x20))\n            }\n        }\n    }\n\n    /// @dev Returns an arrays of bytess based on the `delimiter` inside of the `subject` bytes.\n    function split(bytes memory subject, bytes memory delimiter)\n        internal\n        pure\n        returns (bytes[] memory result)\n    {\n        uint256[] memory indices = indicesOf(subject, delimiter);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let w := not(0x1f)\n            let indexPtr := add(indices, 0x20)\n            let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))\n            mstore(add(indicesEnd, w), mload(subject))\n            mstore(indices, add(mload(indices), 1))\n            for { let prevIndex := 0 } 1 {} {\n                let index := mload(indexPtr)\n                mstore(indexPtr, 0x60)\n                if iszero(eq(index, prevIndex)) {\n                    let element := mload(0x40)\n                    let l := sub(index, prevIndex)\n                    mstore(element, l) // Store the length of the element.\n                    // Copy the `subject` one word at a time, backwards.\n                    for { let o := and(add(l, 0x1f), w) } 1 {} {\n                        mstore(add(element, o), mload(add(add(subject, prevIndex), o)))\n                        o := add(o, w) // `sub(o, 0x20)`.\n                        if iszero(o) { break }\n                    }\n                    mstore(add(add(element, 0x20), l), 0) // Zeroize the slot after the bytes.\n                    // Allocate memory for the length and the bytes, rounded up to a multiple of 32.\n                    mstore(0x40, add(element, and(add(l, 0x3f), w)))\n                    mstore(indexPtr, element) // Store the `element` into the array.\n                }\n                prevIndex := add(index, mload(delimiter))\n                indexPtr := add(indexPtr, 0x20)\n                if iszero(lt(indexPtr, indicesEnd)) { break }\n            }\n            result := indices\n            if iszero(mload(delimiter)) {\n                result := add(indices, 0x20)\n                mstore(result, sub(mload(indices), 2))\n            }\n        }\n    }\n\n    /// @dev Returns a concatenated bytes of `a` and `b`.\n    /// Cheaper than `bytes.concat()` and does not de-align the free memory pointer.\n    function concat(bytes memory a, bytes memory b) internal pure returns (bytes memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(0x40)\n            let w := not(0x1f)\n            let aLen := mload(a)\n            // Copy `a` one word at a time, backwards.\n            for { let o := and(add(aLen, 0x20), w) } 1 {} {\n                mstore(add(result, o), mload(add(a, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let bLen := mload(b)\n            let output := add(result, aLen)\n            // Copy `b` one word at a time, backwards.\n            for { let o := and(add(bLen, 0x20), w) } 1 {} {\n                mstore(add(output, o), mload(add(b, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let totalLen := add(aLen, bLen)\n            let last := add(add(result, 0x20), totalLen)\n            mstore(last, 0) // Zeroize the slot after the bytes.\n            mstore(result, totalLen) // Store the length.\n            mstore(0x40, add(last, 0x20)) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`.\n    function eq(bytes memory a, bytes memory b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`, where `b` is a null-terminated small bytes.\n    function eqs(bytes memory a, bytes32 b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // These should be evaluated on compile time, as far as possible.\n            let m := not(shl(7, div(not(iszero(b)), 255))) // `0x7f7f ...`.\n            let x := not(or(m, or(b, add(m, and(b, m)))))\n            let r := shl(7, iszero(iszero(shr(128, x))))\n            r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x))))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            // forgefmt: disable-next-item\n            result := gt(eq(mload(a), add(iszero(x), xor(31, shr(3, r)))),\n                xor(shr(add(8, r), b), shr(add(8, r), mload(add(a, 0x20)))))\n        }\n    }\n\n    /// @dev Returns 0 if `a == b`, -1 if `a < b`, +1 if `a > b`.\n    /// If `a` == b[:a.length]`, and `a.length < b.length`, returns -1.\n    function cmp(bytes memory a, bytes memory b) internal pure returns (int256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let aLen := mload(a)\n            let bLen := mload(b)\n            let n := and(xor(aLen, mul(xor(aLen, bLen), lt(bLen, aLen))), not(0x1f))\n            if n {\n                for { let i := 0x20 } 1 {} {\n                    let x := mload(add(a, i))\n                    let y := mload(add(b, i))\n                    if iszero(or(xor(x, y), eq(i, n))) {\n                        i := add(i, 0x20)\n                        continue\n                    }\n                    result := sub(gt(x, y), lt(x, y))\n                    break\n                }\n            }\n            // forgefmt: disable-next-item\n            if iszero(result) {\n                let l := 0x201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201\n                let x := and(mload(add(add(a, 0x20), n)), shl(shl(3, byte(sub(aLen, n), l)), not(0)))\n                let y := and(mload(add(add(b, 0x20), n)), shl(shl(3, byte(sub(bLen, n), l)), not(0)))\n                result := sub(gt(x, y), lt(x, y))\n                if iszero(result) { result := sub(gt(aLen, bLen), lt(aLen, bLen)) }\n            }\n        }\n    }\n\n    /// @dev Directly returns `a` without copying.\n    function directReturn(bytes memory a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Assumes that the bytes does not start from the scratch space.\n            let retStart := sub(a, 0x20)\n            let retUnpaddedSize := add(mload(a), 0x40)\n            // Right pad with zeroes. Just in case the bytes is produced\n            // by a method that doesn't zero right pad.\n            mstore(add(retStart, retUnpaddedSize), 0)\n            mstore(retStart, 0x20) // Store the return offset.\n            // End the transaction, returning the bytes.\n            return(retStart, and(not(0x1f), add(0x1f, retUnpaddedSize)))\n        }\n    }\n\n    /// @dev Directly returns `a` with minimal copying.\n    function directReturn(bytes[] memory a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(a) // `a.length`.\n            let o := add(a, 0x20) // Start of elements in `a`.\n            let u := a // Highest memory slot.\n            let w := not(0x1f)\n            for { let i := 0 } iszero(eq(i, n)) { i := add(i, 1) } {\n                let c := add(o, shl(5, i)) // Location of pointer to `a[i]`.\n                let s := mload(c) // `a[i]`.\n                let l := mload(s) // `a[i].length`.\n                let r := and(l, 0x1f) // `a[i].length % 32`.\n                let z := add(0x20, and(l, w)) // Offset of last word in `a[i]` from `s`.\n                // If `s` comes before `o`, or `s` is not zero right padded.\n                if iszero(lt(lt(s, o), or(iszero(r), iszero(shl(shl(3, r), mload(add(s, z))))))) {\n                    let m := mload(0x40)\n                    mstore(m, l) // Copy `a[i].length`.\n                    for {} 1 {} {\n                        mstore(add(m, z), mload(add(s, z))) // Copy `a[i]`, backwards.\n                        z := add(z, w) // `sub(z, 0x20)`.\n                        if iszero(z) { break }\n                    }\n                    let e := add(add(m, 0x20), l)\n                    mstore(e, 0) // Zeroize the slot after the copied bytes.\n                    mstore(0x40, add(e, 0x20)) // Allocate memory.\n                    s := m\n                }\n                mstore(c, sub(s, o)) // Convert to calldata offset.\n                let t := add(l, add(s, 0x20))\n                if iszero(lt(t, u)) { u := t }\n            }\n            let retStart := add(a, w) // Assumes `a` doesn't start from scratch space.\n            mstore(retStart, 0x20) // Store the return offset.\n            return(retStart, add(0x40, sub(u, retStart))) // End the transaction.\n        }\n    }\n\n    /// @dev Returns the word at `offset`, without any bounds checks.\n    function load(bytes memory a, uint256 offset) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := mload(add(add(a, 0x20), offset))\n        }\n    }\n\n    /// @dev Returns the word at `offset`, without any bounds checks.\n    function loadCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := calldataload(add(a.offset, offset))\n        }\n    }\n\n    /// @dev Returns a slice representing a static struct in the calldata. Performs bounds checks.\n    function staticStructInCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := sub(a.length, 0x20)\n            result.offset := add(a.offset, offset)\n            result.length := sub(a.length, offset)\n            if or(shr(64, or(l, a.offset)), gt(offset, l)) { revert(l, 0x00) }\n        }\n    }\n\n    /// @dev Returns a slice representing a dynamic struct in the calldata. Performs bounds checks.\n    function dynamicStructInCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := sub(a.length, 0x20)\n            let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`.\n            result.offset := add(a.offset, s)\n            result.length := sub(a.length, s)\n            if or(shr(64, or(s, or(l, a.offset))), gt(offset, l)) { revert(l, 0x00) }\n        }\n    }\n\n    /// @dev Returns bytes in calldata. Performs bounds checks.\n    function bytesInCalldata(bytes calldata a, uint256 offset)\n        internal\n        pure\n        returns (bytes calldata result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let l := sub(a.length, 0x20)\n            let s := calldataload(add(a.offset, offset)) // Relative offset of `result` from `a.offset`.\n            result.offset := add(add(a.offset, s), 0x20)\n            result.length := calldataload(add(a.offset, s))\n            // forgefmt: disable-next-item\n            if or(shr(64, or(result.length, or(s, or(l, a.offset)))),\n                or(gt(add(s, result.length), l), gt(offset, l))) { revert(l, 0x00) }\n        }\n    }\n\n    /// @dev Checks if `x` is in `a`. Assumes `a` has been checked.\n    function checkInCalldata(bytes calldata x, bytes calldata a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if or(\n                or(lt(x.offset, a.offset), gt(add(x.offset, x.length), add(a.length, a.offset))),\n                shr(64, or(x.length, x.offset))\n            ) { revert(0x00, 0x00) }\n        }\n    }\n\n    /// @dev Checks if `x` is in `a`. Assumes `a` has been checked.\n    function checkInCalldata(bytes[] calldata x, bytes calldata a) internal pure {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let e := sub(add(a.length, a.offset), 0x20)\n            if or(lt(x.offset, a.offset), shr(64, x.offset)) { revert(0x00, 0x00) }\n            for { let i := 0 } iszero(eq(x.length, i)) { i := add(i, 1) } {\n                let o := calldataload(add(x.offset, shl(5, i)))\n                let t := add(o, x.offset)\n                let l := calldataload(t)\n                if or(shr(64, or(l, o)), gt(add(t, l), e)) { revert(0x00, 0x00) }\n            }\n        }\n    }\n\n    /// @dev Returns empty calldata bytes. For silencing the compiler.\n    function emptyCalldata() internal pure returns (bytes calldata result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result.length := 0\n        }\n    }\n\n    /// @dev Returns the most significant 20 bytes as an address.\n    function msbToAddress(bytes32 x) internal pure returns (address) {\n        return address(bytes20(x));\n    }\n\n    /// @dev Returns the least significant 20 bytes as an address.\n    function lsbToAddress(bytes32 x) internal pure returns (address) {\n        return address(uint160(uint256(x)));\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"payee_","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"AccountBalanceOverflow","type":"error","inputs":[]},{"name":"BalanceQueryForZeroAddress","type":"error","inputs":[]},{"name":"FreeQuotaExhaustedOrNotAgent","type":"error","inputs":[]},{"name":"InsufficientPayment","type":"error","inputs":[]},{"name":"NotOwnerNorApproved","type":"error","inputs":[]},{"name":"PayoutFailed","type":"error","inputs":[]},{"name":"Reentrancy","type":"error","inputs":[]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"TokenAlreadyExists","type":"error","inputs":[]},{"name":"TokenDoesNotExist","type":"error","inputs":[]},{"name":"TransferFromIncorrectOwner","type":"error","inputs":[]},{"name":"TransferToNonERC721ReceiverImplementer","type":"error","inputs":[]},{"name":"TransferToZeroAddress","type":"error","inputs":[]},{"name":"WalletLimitExceeded","type":"error","inputs":[]},{"name":"ZeroQuantity","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"id","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":"isApproved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"PulseTerminalMinted","type":"event","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"startId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"qty","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"grade","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"id","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID_REGISTRY","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"BUNDLE_THREE_PRICE","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":"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":"OWNER","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"PAYEE","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"result","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"canClaimFree","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"checkAgentHandle","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"claimedFree","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"freeMint","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"freeMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"result","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"gradeNameOf","type":"function","inputs":[{"name":"tokenId","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":"result","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"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":"pure"},{"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":"pure"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"result","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pulseGrade","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"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":"royaltyInfo","type":"function","inputs":[{"name":"","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":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"isApproved","type":"bool","internalType":"bool"}],"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":"pure"},{"name":"tokenURI","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"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":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"}],"matchId":"57563833","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-10-29T16:29:28Z","match":"exact_match","chainId":"56","address":"0x6f0eB9eDE1Fa087947D16Cc1A98648Ea6e421bfe"}