{"sources":{"src/Alchemister.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\nimport {ERC721} from \"solady/tokens/ERC721.sol\";\nimport {Ownable} from \"solady/auth/Ownable.sol\";\nimport {SSTORE2} from \"solady/utils/SSTORE2.sol\";\nimport {Base64} from \"solady/utils/Base64.sol\";\nimport {LibString} from \"solady/utils/LibString.sol\";\nimport {Glyphs} from \"./Glyphs.sol\";\n\ninterface IBalance {\n    function balanceOf(address) external view returns (uint256);\n}\n\n/// @title Alchemister — member card of Alchemist Agent\n/// @notice 15,000 cards. Mint is open only to wallets holding a .ai Agent ID.\n///         Mint 1 is free, mints 2-15 cost 0.0003 BNB, mints 16-30 cost 0.0006 BNB, max 30 per wallet.\n///         Cards cannot be sent wallet to wallet; they move only through approved marketplaces.\n///         Metadata and artwork are stored and rendered fully on-chain.\ncontract Alchemister is ERC721, Ownable {\n    using LibString for uint256;\n\n    uint256 public constant MAX_SUPPLY = 15_000;\n    uint256 public constant MAX_PER_WALLET = 30;\n    uint256 public constant PRICE_LOW = 0.0003 ether;\n    uint256 public constant PRICE_HIGH = 0.0006 ether;\n\n    address public constant AGENT_ID = 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F;\n    address payable public constant TREASURY = payable(0x4c0e8bf6488b8Bd612D53173D26582490e97F64e);\n\n    string public constant WEBSITE = \"https://usealchemist.org\";\n    string public constant X_URL = \"https://x.com/usealchemist\";\n    string public constant DESCRIPTION =\n        \"Alchemister is the member card of Alchemist Agent, the multi-model AI agent that turns intent into on-chain work. \"\n        \"15,000 cards, minted only by .ai Agent ID holders. Every card carries its own number, drawn on-chain. \"\n        \"Website: https://usealchemist.org | X: https://x.com/usealchemist\";\n\n    uint256 public totalSupply;\n    bool public mintOpen;\n    bool public artFrozen;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => bool) public isMarket;\n    /// @notice Wallets that mint up to MAX_PER_WALLET for free, without the Agent ID check, even before the public mint opens.\n    mapping(address => bool) public freeMinter;\n\n    address[] internal _art;\n\n    event MintOpen(bool open);\n    event MarketSet(address indexed market, bool allowed);\n    event FreeMinterSet(address indexed wallet, bool allowed);\n    event MetadataUpdate(uint256 _tokenId);\n    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n\n    error MintClosed();\n    error BadQuantity();\n    error WalletLimit();\n    error SoldOut();\n    error NoAgentId();\n    error WrongPayment();\n    error PayoutFailed();\n    error TransferLocked();\n    error OperatorNotAllowed();\n    error ArtFrozen();\n\n    constructor(address owner_, address[] memory markets, address[] memory freeMinters) {\n        _initializeOwner(owner_);\n        for (uint256 i; i < freeMinters.length; ++i) {\n            freeMinter[freeMinters[i]] = true;\n            emit FreeMinterSet(freeMinters[i], true);\n        }\n        for (uint256 i; i < markets.length; ++i) {\n            isMarket[markets[i]] = true;\n            emit MarketSet(markets[i], true);\n        }\n    }\n\n    function name() public pure override returns (string memory) { return \"Alchemister\"; }\n    function symbol() public pure override returns (string memory) { return \"ALCHEMISTER\"; }\n\n    /* ------------------------------ mint ------------------------------ */\n\n    function priceOf(uint256 n) public pure returns (uint256) {\n        return n <= 1 ? 0 : (n <= 15 ? PRICE_LOW : PRICE_HIGH);\n    }\n\n    /// @notice Total cost for `wallet` to mint `qty` more cards.\n    function costFor(address wallet, uint256 qty) public view returns (uint256 c) {\n        if (freeMinter[wallet]) return 0;\n        uint256 had = mintedBy[wallet];\n        for (uint256 i = had + 1; i <= had + qty; ++i) c += priceOf(i);\n    }\n\n    function mint(uint256 qty) external payable {\n        bool free = freeMinter[msg.sender];\n        if (!mintOpen && !free) revert MintClosed();\n        if (qty == 0 || qty > MAX_PER_WALLET) revert BadQuantity();\n        uint256 had = mintedBy[msg.sender];\n        if (had + qty > MAX_PER_WALLET) revert WalletLimit();\n        uint256 start = totalSupply;\n        if (start + qty > MAX_SUPPLY) revert SoldOut();\n        if (!free && IBalance(AGENT_ID).balanceOf(msg.sender) == 0) revert NoAgentId();\n        if (msg.value != costFor(msg.sender, qty)) revert WrongPayment();\n\n        mintedBy[msg.sender] = had + qty;\n        totalSupply = start + qty;\n        for (uint256 i = 1; i <= qty; ++i) _mint(msg.sender, start + i);\n\n        if (msg.value != 0) {\n            (bool ok,) = TREASURY.call{value: msg.value}(\"\");\n            if (!ok) revert PayoutFailed();\n        }\n    }\n\n    /* ------------------------- transfer lock ------------------------- */\n\n    function _beforeTokenTransfer(address from, address to, uint256) internal view override {\n        if (from != address(0) && to != address(0) && !isMarket[msg.sender]) revert TransferLocked();\n        if (to == address(0) && from != address(0)) revert TransferLocked();\n    }\n\n    function approve(address account, uint256 id) public payable override {\n        if (account != address(0) && !isMarket[account]) revert OperatorNotAllowed();\n        super.approve(account, id);\n    }\n\n    function setApprovalForAll(address operator, bool approved) public override {\n        if (approved && !isMarket[operator]) revert OperatorNotAllowed();\n        super.setApprovalForAll(operator, approved);\n    }\n\n    /* ---------------------------- metadata --------------------------- */\n\n    function image(uint256 id) public view returns (string memory svg) {\n        uint256 n = _art.length;\n        bytes memory head;\n        for (uint256 i; i < n; ++i) head = bytes.concat(head, SSTORE2.read(_art[i]));\n        bytes memory num;\n        uint256 x = Glyphs.X0;\n        bytes memory digits = bytes(_pad4(id));\n        for (uint256 i; i < digits.length; ++i) {\n            uint256 d = uint8(digits[i]) - 48;\n            num = bytes.concat(\n                num,\n                \"<path transform='translate(\", bytes((x / 10).toString()), \".\", bytes((x % 10).toString()),\n                \" 676)' d='\", bytes(Glyphs.path(d)), \"'/>\"\n            );\n            x += Glyphs.width(d);\n        }\n        svg = string(bytes.concat(\n            head, num,\n            \"</g></g><rect x='.5' y='.5' width='499' height='699' rx='26' fill='none' stroke='rgb(255,255,255)' stroke-opacity='.28'/></svg>\"\n        ));\n    }\n\n    function tokenURI(uint256 id) public view override returns (string memory) {\n        if (!_exists(id)) revert TokenDoesNotExist();\n        string memory n = id.toString();\n        bytes memory json = bytes.concat(\n            '{\"name\":\"Alchemister #', bytes(n),\n            '\",\"description\":\"', bytes(DESCRIPTION),\n            '\",\"external_url\":\"', bytes(WEBSITE),\n            '\",\"website\":\"', bytes(WEBSITE),\n            '\",\"twitter\":\"', bytes(X_URL),\n            '\",\"image\":\"data:image/svg+xml;base64,', bytes(Base64.encode(bytes(image(id)))),\n            '\",\"attributes\":[{\"trait_type\":\"Number\",\"display_type\":\"number\",\"value\":', bytes(n),\n            '},{\"trait_type\":\"Card\",\"value\":\"Member card\"},{\"trait_type\":\"Website\",\"value\":\"', bytes(WEBSITE),\n            '\"},{\"trait_type\":\"X\",\"value\":\"', bytes(X_URL), '\"}]}'\n        );\n        return string(bytes.concat(\"data:application/json;base64,\", bytes(Base64.encode(json))));\n    }\n\n    function logo() public pure returns (string memory) {\n        return \"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' width='512' height='512'><defs><linearGradient id='g' x1='10' y1='6' x2='56' y2='60' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='rgb(255,255,255)'/><stop offset='.38' stop-color='rgb(243,217,164)'/><stop offset='.7' stop-color='rgb(201,167,255)'/><stop offset='1' stop-color='rgb(127,231,255)'/></linearGradient></defs><rect width='512' height='512' fill='rgb(9,9,10)'/><g transform='translate(96 96) scale(5)'><path d='M32 5 L57.5 57 H47.2 L32 24.6 L16.8 57 H6.5 Z' fill='url(#g)'/><path d='M3 41.2 H61' stroke='url(#g)' stroke-width='3.2' stroke-linecap='round'/><circle cx='32' cy='47.5' r='3.6' fill='url(#g)'/></g></svg>\";\n    }\n\n    /// @notice Collection-level metadata (name, description, logo, links), read by marketplaces.\n    function contractURI() external pure returns (string memory) {\n        bytes memory json = bytes.concat(\n            '{\"name\":\"Alchemister\",\"description\":\"', bytes(DESCRIPTION),\n            '\",\"image\":\"data:image/svg+xml;base64,', bytes(Base64.encode(bytes(logo()))),\n            '\",\"external_link\":\"', bytes(WEBSITE),\n            '\",\"website\":\"', bytes(WEBSITE),\n            '\",\"twitter\":\"', bytes(X_URL), '\"}'\n        );\n        return string(bytes.concat(\"data:application/json;base64,\", bytes(Base64.encode(json))));\n    }\n\n    function supportsInterface(bytes4 id) public view override returns (bool) {\n        return id == 0x49064906 || super.supportsInterface(id);\n    }\n\n    function _pad4(uint256 id) internal pure returns (string memory) {\n        string memory s = id.toString();\n        uint256 l = bytes(s).length;\n        if (l >= 4) return s;\n        return string(bytes.concat(bytes(l == 1 ? \"000\" : (l == 2 ? \"00\" : \"0\")), bytes(s)));\n    }\n\n    /* ------------------------------ admin ----------------------------- */\n\n    function setMintOpen(bool open) external onlyOwner {\n        mintOpen = open;\n        emit MintOpen(open);\n    }\n\n    function setMarket(address market, bool allowed) external onlyOwner {\n        isMarket[market] = allowed;\n        emit MarketSet(market, allowed);\n    }\n\n    function setFreeMinter(address wallet, bool allowed) external onlyOwner {\n        freeMinter[wallet] = allowed;\n        emit FreeMinterSet(wallet, allowed);\n    }\n\n    function appendArt(bytes calldata chunk) external onlyOwner {\n        if (artFrozen) revert ArtFrozen();\n        _art.push(SSTORE2.write(chunk));\n    }\n\n    function resetArt() external onlyOwner {\n        if (artFrozen) revert ArtFrozen();\n        delete _art;\n    }\n\n    function freezeArt() external onlyOwner {\n        artFrozen = true;\n        if (totalSupply != 0) emit BatchMetadataUpdate(1, totalSupply);\n    }\n\n    function artChunks() external view returns (uint256) { return _art.length; }\n\n    /// @notice Sends any BNB that ends up in the contract to the treasury.\n    function sweep() external {\n        (bool ok,) = TREASURY.call{value: address(this).balance}(\"\");\n        if (!ok) revert PayoutFailed();\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/auth/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)\n///\n/// @dev Note:\n/// This implementation does NOT auto-initialize the owner to `msg.sender`.\n/// You MUST call the `_initializeOwner` in the constructor / initializer.\n///\n/// While the ownable portion follows\n/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,\n/// the nomenclature for the 2-step ownership handover may be unique to this codebase.\nabstract contract Ownable {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                       CUSTOM ERRORS                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The caller is not authorized to call the function.\n    error Unauthorized();\n\n    /// @dev The `newOwner` cannot be the zero address.\n    error NewOwnerIsZeroAddress();\n\n    /// @dev The `pendingOwner` does not have a valid handover request.\n    error NoHandoverRequest();\n\n    /// @dev Cannot double-initialize.\n    error AlreadyInitialized();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.\n    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be\n    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),\n    /// despite it not being as lightweight as a single argument event.\n    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);\n\n    /// @dev An ownership handover to `pendingOwner` has been requested.\n    event OwnershipHandoverRequested(address indexed pendingOwner);\n\n    /// @dev The ownership handover to `pendingOwner` has been canceled.\n    event OwnershipHandoverCanceled(address indexed pendingOwner);\n\n    /// @dev `keccak256(bytes(\"OwnershipTransferred(address,address)\"))`.\n    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =\n        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;\n\n    /// @dev `keccak256(bytes(\"OwnershipHandoverRequested(address)\"))`.\n    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =\n        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;\n\n    /// @dev `keccak256(bytes(\"OwnershipHandoverCanceled(address)\"))`.\n    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =\n        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                          STORAGE                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The owner slot is given by:\n    /// `bytes32(~uint256(uint32(bytes4(keccak256(\"_OWNER_SLOT_NOT\")))))`.\n    /// It is intentionally chosen to be a high value\n    /// to avoid collision with lower slots.\n    /// The choice of manual storage layout is to enable compatibility\n    /// with both regular and upgradeable contracts.\n    bytes32 internal constant _OWNER_SLOT =\n        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;\n\n    /// The ownership handover slot of `newOwner` is given by:\n    /// ```\n    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))\n    ///     let handoverSlot := keccak256(0x00, 0x20)\n    /// ```\n    /// It stores the expiry timestamp of the two-step ownership handover.\n    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     INTERNAL FUNCTIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.\n    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}\n\n    /// @dev Initializes the owner directly without authorization guard.\n    /// This function must be called upon initialization,\n    /// regardless of whether the contract is upgradeable or not.\n    /// This is to enable generalization to both regular and upgradeable contracts,\n    /// and to save gas in case the initial owner is not the caller.\n    /// For performance reasons, this function will not check if there\n    /// is an existing owner.\n    function _initializeOwner(address newOwner) internal virtual {\n        if (_guardInitializeOwner()) {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                if sload(ownerSlot) {\n                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.\n                    revert(0x1c, 0x04)\n                }\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Store the new value.\n                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n            }\n        } else {\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Store the new value.\n                sstore(_OWNER_SLOT, newOwner)\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\n            }\n        }\n    }\n\n    /// @dev Sets the owner directly without authorization guard.\n    function _setOwner(address newOwner) internal virtual {\n        if (_guardInitializeOwner()) {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n                // Store the new value.\n                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\n            }\n        } else {\n            /// @solidity memory-safe-assembly\n            assembly {\n                let ownerSlot := _OWNER_SLOT\n                // Clean the upper 96 bits.\n                newOwner := shr(96, shl(96, newOwner))\n                // Emit the {OwnershipTransferred} event.\n                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\n                // Store the new value.\n                sstore(ownerSlot, newOwner)\n            }\n        }\n    }\n\n    /// @dev Throws if the sender is not the owner.\n    function _checkOwner() internal view virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // If the caller is not the stored owner, revert.\n            if iszero(eq(caller(), sload(_OWNER_SLOT))) {\n                mstore(0x00, 0x82b42900) // `Unauthorized()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n\n    /// @dev Returns how long a two-step ownership handover is valid for in seconds.\n    /// Override to return a different value if needed.\n    /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {\n        return 48 * 3600;\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                  PUBLIC UPDATE FUNCTIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Allows the owner to transfer the ownership to `newOwner`.\n    function transferOwnership(address newOwner) public payable virtual onlyOwner {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(shl(96, newOwner)) {\n                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.\n                revert(0x1c, 0x04)\n            }\n        }\n        _setOwner(newOwner);\n    }\n\n    /// @dev Allows the owner to renounce their ownership.\n    function renounceOwnership() public payable virtual onlyOwner {\n        _setOwner(address(0));\n    }\n\n    /// @dev Request a two-step ownership handover to the caller.\n    /// The request will automatically expire in 48 hours (172800 seconds) by default.\n    function requestOwnershipHandover() public payable virtual {\n        unchecked {\n            uint256 expires = block.timestamp + _ownershipHandoverValidFor();\n            /// @solidity memory-safe-assembly\n            assembly {\n                // Compute and set the handover slot to `expires`.\n                mstore(0x0c, _HANDOVER_SLOT_SEED)\n                mstore(0x00, caller())\n                sstore(keccak256(0x0c, 0x20), expires)\n                // Emit the {OwnershipHandoverRequested} event.\n                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())\n            }\n        }\n    }\n\n    /// @dev Cancels the two-step ownership handover to the caller, if any.\n    function cancelOwnershipHandover() public payable virtual {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and set the handover slot to 0.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, caller())\n            sstore(keccak256(0x0c, 0x20), 0)\n            // Emit the {OwnershipHandoverCanceled} event.\n            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())\n        }\n    }\n\n    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.\n    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.\n    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and set the handover slot to 0.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, pendingOwner)\n            let handoverSlot := keccak256(0x0c, 0x20)\n            // If the handover does not exist, or has expired.\n            if gt(timestamp(), sload(handoverSlot)) {\n                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.\n                revert(0x1c, 0x04)\n            }\n            // Set the handover slot to 0.\n            sstore(handoverSlot, 0)\n        }\n        _setOwner(pendingOwner);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   PUBLIC READ FUNCTIONS                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the owner of the contract.\n    function owner() public view virtual returns (address result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := sload(_OWNER_SLOT)\n        }\n    }\n\n    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.\n    function ownershipHandoverExpiresAt(address pendingOwner)\n        public\n        view\n        virtual\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute the handover slot.\n            mstore(0x0c, _HANDOVER_SLOT_SEED)\n            mstore(0x00, pendingOwner)\n            // Load the handover slot.\n            result := sload(keccak256(0x0c, 0x20))\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         MODIFIERS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Marks a function as only callable by the owner.\n    modifier onlyOwner() virtual {\n        _checkOwner();\n        _;\n    }\n}\n"},"lib/solady/src/utils/SSTORE2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Read and write to persistent storage at a fraction of the cost.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SSTORE2.sol)\n/// @author Saw-mon-and-Natalie (https://github.com/Saw-mon-and-Natalie)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)\n/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)\n/// @author Modified from SSTORE3 (https://github.com/Philogy/sstore3)\nlibrary SSTORE2 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The proxy initialization code.\n    uint256 private constant _CREATE3_PROXY_INITCODE = 0x67363d3d37363d34f03d5260086018f3;\n\n    /// @dev Hash of the `_CREATE3_PROXY_INITCODE`.\n    /// Equivalent to `keccak256(abi.encodePacked(hex\"67363d3d37363d34f03d5260086018f3\"))`.\n    bytes32 internal constant CREATE3_PROXY_INITCODE_HASH =\n        0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CUSTOM ERRORS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Unable to deploy the storage contract.\n    error DeploymentFailed();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         WRITE LOGIC                        */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Writes `data` into the bytecode of a storage contract and returns its address.\n    function write(bytes memory data) internal returns (address pointer) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(data) // Let `l` be `n + 1`. +1 as we prefix a STOP opcode.\n            /**\n             * ---------------------------------------------------+\n             * Opcode | Mnemonic       | Stack     | Memory       |\n             * ---------------------------------------------------|\n             * 61 l   | PUSH2 l        | l         |              |\n             * 80     | DUP1           | l l       |              |\n             * 60 0xa | PUSH1 0xa      | 0xa l l   |              |\n             * 3D     | RETURNDATASIZE | 0 0xa l l |              |\n             * 39     | CODECOPY       | l         | [0..l): code |\n             * 3D     | RETURNDATASIZE | 0 l       | [0..l): code |\n             * F3     | RETURN         |           | [0..l): code |\n             * 00     | STOP           |           |              |\n             * ---------------------------------------------------+\n             * @dev Prefix the bytecode with a STOP opcode to ensure it cannot be called.\n             * Also PUSH2 is used since max contract size cap is 24,576 bytes which is less than 2 ** 16.\n             */\n            // Do a out-of-gas revert if `n + 1` is more than 2 bytes.\n            mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n)))\n            // Deploy a new contract with the generated creation code.\n            pointer := create(0, add(data, 0x15), add(n, 0xb))\n            if iszero(pointer) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(data, n) // Restore the length of `data`.\n        }\n    }\n\n    /// @dev Writes `data` into the bytecode of a storage contract with `salt`\n    /// and returns its normal CREATE2 deterministic address.\n    function writeCounterfactual(bytes memory data, bytes32 salt)\n        internal\n        returns (address pointer)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(data)\n            // Do a out-of-gas revert if `n + 1` is more than 2 bytes.\n            mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n)))\n            // Deploy a new contract with the generated creation code.\n            pointer := create2(0, add(data, 0x15), add(n, 0xb), salt)\n            if iszero(pointer) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(data, n) // Restore the length of `data`.\n        }\n    }\n\n    /// @dev Writes `data` into the bytecode of a storage contract and returns its address.\n    /// This uses the so-called \"CREATE3\" workflow,\n    /// which means that `pointer` is agnostic to `data, and only depends on `salt`.\n    function writeDeterministic(bytes memory data, bytes32 salt)\n        internal\n        returns (address pointer)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(data)\n            mstore(0x00, _CREATE3_PROXY_INITCODE) // Store the `_PROXY_INITCODE`.\n            let proxy := create2(0, 0x10, 0x10, salt)\n            if iszero(proxy) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(0x14, proxy) // Store the proxy's address.\n            // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01).\n            // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex).\n            mstore(0x00, 0xd694)\n            mstore8(0x34, 0x01) // Nonce of the proxy contract (1).\n            pointer := keccak256(0x1e, 0x17)\n\n            // Do a out-of-gas revert if `n + 1` is more than 2 bytes.\n            mstore(add(data, gt(n, 0xfffe)), add(0xfe61000180600a3d393df300, shl(0x40, n)))\n            if iszero(\n                mul( // The arguments of `mul` are evaluated last to first.\n                    extcodesize(pointer),\n                    call(gas(), proxy, 0, add(data, 0x15), add(n, 0xb), codesize(), 0x00)\n                )\n            ) {\n                mstore(0x00, 0x30116425) // `DeploymentFailed()`.\n                revert(0x1c, 0x04)\n            }\n            mstore(data, n) // Restore the length of `data`.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                    ADDRESS CALCULATIONS                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the initialization code hash of the storage contract for `data`.\n    /// Used for mining vanity addresses with create2crunch.\n    function initCodeHash(bytes memory data) internal pure returns (bytes32 hash) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let n := mload(data)\n            // Do a out-of-gas revert if `n + 1` is more than 2 bytes.\n            returndatacopy(returndatasize(), returndatasize(), gt(n, 0xfffe))\n            mstore(data, add(0x61000180600a3d393df300, shl(0x40, n)))\n            hash := keccak256(add(data, 0x15), add(n, 0xb))\n            mstore(data, n) // Restore the length of `data`.\n        }\n    }\n\n    /// @dev Equivalent to `predictCounterfactualAddress(data, salt, address(this))`\n    function predictCounterfactualAddress(bytes memory data, bytes32 salt)\n        internal\n        view\n        returns (address pointer)\n    {\n        pointer = predictCounterfactualAddress(data, salt, address(this));\n    }\n\n    /// @dev Returns the CREATE2 address of the storage contract for `data`\n    /// deployed with `salt` by `deployer`.\n    /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly.\n    function predictCounterfactualAddress(bytes memory data, bytes32 salt, address deployer)\n        internal\n        pure\n        returns (address predicted)\n    {\n        bytes32 hash = initCodeHash(data);\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Compute and store the bytecode hash.\n            mstore8(0x00, 0xff) // Write the prefix.\n            mstore(0x35, hash)\n            mstore(0x01, shl(96, deployer))\n            mstore(0x15, salt)\n            predicted := keccak256(0x00, 0x55)\n            // Restore the part of the free memory pointer that has been overwritten.\n            mstore(0x35, 0)\n        }\n    }\n\n    /// @dev Equivalent to `predictDeterministicAddress(salt, address(this))`.\n    function predictDeterministicAddress(bytes32 salt) internal view returns (address pointer) {\n        pointer = predictDeterministicAddress(salt, address(this));\n    }\n\n    /// @dev Returns the \"CREATE3\" deterministic address for `salt` with `deployer`.\n    function predictDeterministicAddress(bytes32 salt, address deployer)\n        internal\n        pure\n        returns (address pointer)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let m := mload(0x40) // Cache the free memory pointer.\n            mstore(0x00, deployer) // Store `deployer`.\n            mstore8(0x0b, 0xff) // Store the prefix.\n            mstore(0x20, salt) // Store the salt.\n            mstore(0x40, CREATE3_PROXY_INITCODE_HASH) // Store the bytecode hash.\n\n            mstore(0x14, keccak256(0x0b, 0x55)) // Store the proxy's address.\n            mstore(0x40, m) // Restore the free memory pointer.\n            // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01).\n            // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex).\n            mstore(0x00, 0xd694)\n            mstore8(0x34, 0x01) // Nonce of the proxy contract (1).\n            pointer := keccak256(0x1e, 0x17)\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         READ LOGIC                         */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Equivalent to `read(pointer, 0, 2 ** 256 - 1)`.\n    function read(address pointer) internal view returns (bytes memory data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            data := mload(0x40)\n            let n := and(0xffffffffff, sub(extcodesize(pointer), 0x01))\n            extcodecopy(pointer, add(data, 0x1f), 0x00, add(n, 0x21))\n            mstore(data, n) // Store the length.\n            mstore(0x40, add(n, add(data, 0x40))) // Allocate memory.\n        }\n    }\n\n    /// @dev Equivalent to `read(pointer, start, 2 ** 256 - 1)`.\n    function read(address pointer, uint256 start) internal view returns (bytes memory data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            data := mload(0x40)\n            let n := and(0xffffffffff, sub(extcodesize(pointer), 0x01))\n            let l := sub(n, and(0xffffff, mul(lt(start, n), start)))\n            extcodecopy(pointer, add(data, 0x1f), start, add(l, 0x21))\n            mstore(data, mul(sub(n, start), lt(start, n))) // Store the length.\n            mstore(0x40, add(data, add(0x40, mload(data)))) // Allocate memory.\n        }\n    }\n\n    /// @dev Returns a slice of the data on `pointer` from `start` to `end`.\n    /// `start` and `end` will be clamped to the range `[0, args.length]`.\n    /// The `pointer` MUST be deployed via the SSTORE2 write functions.\n    /// Otherwise, the behavior is undefined.\n    /// Out-of-gas reverts if `pointer` does not have any code.\n    function read(address pointer, uint256 start, uint256 end)\n        internal\n        view\n        returns (bytes memory data)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            data := mload(0x40)\n            if iszero(lt(end, 0xffff)) { end := 0xffff }\n            let d := mul(sub(end, start), lt(start, end))\n            extcodecopy(pointer, add(data, 0x1f), start, add(d, 0x01))\n            if iszero(and(0xff, mload(add(data, d)))) {\n                let n := sub(extcodesize(pointer), 0x01)\n                returndatacopy(returndatasize(), returndatasize(), shr(40, n))\n                d := mul(gt(n, start), sub(d, mul(gt(end, n), sub(end, n))))\n            }\n            mstore(data, d) // Store the length.\n            mstore(add(add(data, 0x20), d), 0) // Zeroize the slot after the bytes.\n            mstore(0x40, add(add(data, 0x40), d)) // Allocate memory.\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) internal pure returns (string memory result) {\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/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 {} // Scan for '\\0'.\n             byte(n, s) { n := add(n, 1) } {}\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 {} // Scan for '\\0'.\n             byte(result, s) { result := add(result, 1) } {}\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 := 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 := mul(\n                or( // Load the length and the bytes of `a` and `b`.\n                    shl(shl(3, sub(0x1f, aLen)), mload(add(a, aLen))),\n                    shr(shl(3, add(aLen, 1)), mload(add(b, 0x1f)))\n                ),\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"},"src/Glyphs.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\n/// @dev Unbounded SemiBold digit outlines (34px), generated.\nlibrary Glyphs {\n    uint256 internal constant X0 = 1002; // tenths of a px\n    function width(uint256 d) internal pure returns (uint256) {\n        return [uint256(305), 165, 273, 275, 281, 265, 282, 245, 293, 282][d];\n    }\n    function path(uint256 d) internal pure returns (string memory) {\n        if (d == 0) return \"M15.6 0.5Q11.3 0.5 8.1 -1.1Q4.9 -2.8 3.2 -5.8Q1.5 -8.8 1.5 -12.7Q1.5 -16.7 3.2 -19.7Q4.9 -22.7 8.1 -24.4Q11.3 -26 15.6 -26Q19.9 -26 23.1 -24.4Q26.2 -22.7 28 -19.7Q29.7 -16.7 29.7 -12.8Q29.7 -8.8 28 -5.8Q26.2 -2.8 23.1 -1.1Q19.9 0.5 15.6 0.5ZM15.6 -4.7Q19.2 -4.7 21.3 -6.8Q23.3 -8.9 23.3 -12.8Q23.3 -16.6 21.3 -18.7Q19.2 -20.8 15.6 -20.8Q12 -20.8 9.9 -18.7Q7.9 -16.6 7.9 -12.8Q7.9 -8.9 9.9 -6.8Q12 -4.7 15.6 -4.7Z\";\n        if (d == 1) return \"M14.6 -25.5V0H8.3V-23.3L11.3 -20.5L0.4 -18.6V-23.6L9.9 -25.5Z\";\n        if (d == 2) return \"M1.2 -16.4Q1.4 -19.4 3.2 -21.5Q4.9 -23.7 7.8 -24.9Q10.6 -26 14.3 -26Q17.7 -26 20.3 -25Q22.9 -23.9 24.4 -22Q25.8 -20.1 25.8 -17.7Q25.8 -15.7 24.8 -14.1Q23.8 -12.4 21.6 -10.8Q19.4 -9.1 15.8 -7.3L8.4 -3.4L8.1 -5.1H26.5V0H1.7V-4.5L12.6 -10.8Q15.2 -12.3 16.7 -13.4Q18.2 -14.4 18.8 -15.3Q19.4 -16.3 19.4 -17.3Q19.4 -18.4 18.8 -19.2Q18.2 -20.1 17 -20.6Q15.8 -21 14.1 -21Q11.9 -21 10.5 -20.4Q9.1 -19.8 8.4 -18.7Q7.8 -17.7 7.6 -16.4Z\";\n        if (d == 3) return \"M1.7 -17.4Q1.9 -19.8 3.4 -21.7Q4.9 -23.7 7.8 -24.9Q10.6 -26 14.6 -26Q18.1 -26 20.7 -25.1Q23.3 -24.3 24.7 -22.7Q26.1 -21.1 26.1 -18.9Q26.1 -17.2 25.1 -15.8Q24 -14.4 21.8 -13.5Q19.6 -12.7 16.2 -12.7V-13.4Q19.5 -13.6 21.8 -12.9Q24.1 -12.3 25.4 -10.9Q26.7 -9.5 26.7 -7.4Q26.7 -5.1 25.2 -3.3Q23.7 -1.5 20.9 -0.5Q18.1 0.5 14.1 0.5Q10.2 0.5 7.3 -0.6Q4.4 -1.7 2.8 -3.6Q1.1 -5.6 1 -8.3H7.4Q7.7 -6.5 9.3 -5.5Q11 -4.5 14.1 -4.5Q17.1 -4.5 18.6 -5.4Q20.2 -6.3 20.2 -7.9Q20.2 -8.8 19.6 -9.5Q19.1 -10.1 17.9 -10.4Q16.7 -10.8 14.5 -10.8H10.1V-15.2H14.5Q17.3 -15.2 18.5 -16Q19.7 -16.8 19.7 -18Q19.7 -19.5 18.3 -20.3Q17 -21 14.3 -21Q11.5 -21 9.9 -20.1Q8.4 -19.1 8.1 -17.4Z\";\n        if (d == 4) return \"M23.5 -25.5V0H17.1V-22.7H19.2L5.6 -7.7L5.5 -9.7H27.7V-4.9H0.8V-9.4L15.4 -25.5Z\";\n        if (d == 5) return \"M4.2 -25.5H23.9V-20.7H6.2L8.7 -21.9L7.3 -12.3L5.7 -12.3Q6.4 -13.6 7.7 -14.6Q9 -15.7 11 -16.3Q12.9 -17 15.4 -17Q18.6 -17 21 -15.9Q23.3 -14.8 24.6 -12.9Q25.9 -11 25.9 -8.5Q25.9 -5.9 24.4 -3.8Q22.9 -1.8 20.2 -0.6Q17.5 0.5 13.7 0.5Q9.9 0.5 7.2 -0.6Q4.4 -1.6 2.9 -3.5Q1.3 -5.4 1 -7.7H7.4Q7.8 -6.2 9.4 -5.3Q11 -4.5 13.7 -4.5Q15.5 -4.5 16.8 -4.9Q18.1 -5.4 18.8 -6.4Q19.5 -7.3 19.5 -8.5Q19.5 -9.7 18.8 -10.7Q18.2 -11.6 17 -12.1Q15.8 -12.6 13.9 -12.6Q12.4 -12.6 11.2 -12.2Q9.9 -11.9 9.1 -11.4Q8.2 -10.8 7.6 -10.2H2.1Z\";\n        if (d == 6) return \"M15.1 -26Q18.4 -26 20.9 -25.1Q23.4 -24.1 25 -22.4Q26.5 -20.7 26.9 -18.6H20.9Q20.4 -19.7 19.1 -20.5Q17.8 -21.2 15.3 -21.2Q12.7 -21.2 10.9 -20.3Q9.2 -19.3 8.4 -17.5Q7.6 -15.6 7.6 -13Q7.6 -10.2 8.5 -8.2Q9.4 -6.3 11.2 -5.3Q12.9 -4.3 15.5 -4.3Q17.3 -4.3 18.5 -4.8Q19.7 -5.3 20.4 -6.2Q21 -7 21 -8.1Q21 -9.2 20.4 -10Q19.8 -10.9 18.7 -11.3Q17.5 -11.8 15.7 -11.8Q13.3 -11.8 11.2 -10.7Q9.1 -9.6 7.5 -7.7L5.2 -9.2Q6.3 -11.3 8 -13Q9.7 -14.6 12 -15.6Q14.3 -16.6 17.2 -16.6Q20.4 -16.6 22.7 -15.5Q24.9 -14.5 26.2 -12.7Q27.4 -10.8 27.4 -8.3Q27.4 -5.7 26 -3.7Q24.6 -1.7 21.9 -0.6Q19.2 0.5 15.4 0.5Q10.8 0.5 7.7 -1.2Q4.6 -2.9 3.1 -5.9Q1.5 -8.9 1.5 -12.7Q1.5 -16.6 3.1 -19.6Q4.6 -22.6 7.6 -24.3Q10.7 -26 15.1 -26Z\";\n        if (d == 7) return \"M4.4 0 18.4 -22.2 18.4 -20.4H0.4V-25.5H24.2V-20.4L11.6 0Z\";\n        if (d == 8) return \"M15 -26Q21.1 -26 24.4 -24.1Q27.7 -22.2 27.7 -18.8Q27.7 -15.8 24.8 -14.2Q21.9 -12.6 16.8 -12.8V-13.5Q22.4 -13.9 25.4 -12.2Q28.5 -10.6 28.5 -7.1Q28.5 -3.4 25 -1.4Q21.6 0.5 15 0.5Q8.5 0.5 5 -1.4Q1.5 -3.4 1.5 -7.1Q1.5 -10.6 4.6 -12.2Q7.7 -13.9 13.2 -13.5V-12.8Q8.1 -12.6 5.2 -14.2Q2.3 -15.8 2.3 -18.8Q2.3 -22.2 5.6 -24.1Q8.9 -26 15 -26ZM15 -4.4Q18.4 -4.4 20.2 -5.2Q22 -6 22 -7.6Q22 -9.2 20.2 -10Q18.4 -10.7 15 -10.7Q11.6 -10.7 9.8 -10Q8 -9.2 8 -7.6Q8 -6 9.8 -5.2Q11.6 -4.4 15 -4.4ZM15 -15.3Q17 -15.3 18.4 -15.6Q19.8 -15.9 20.6 -16.6Q21.3 -17.2 21.3 -18.2Q21.3 -19.6 19.7 -20.3Q18.1 -21.1 15 -21.1Q12 -21.1 10.3 -20.3Q8.7 -19.6 8.7 -18.2Q8.7 -17.2 9.4 -16.6Q10.2 -15.9 11.6 -15.6Q13 -15.3 15 -15.3Z\";\n        if (d == 9) return \"M13.7 0.5Q10.5 0.5 8 -0.4Q5.5 -1.4 3.9 -3.1Q2.4 -4.8 2 -6.9H8Q8.5 -5.8 9.8 -5Q11.1 -4.3 13.6 -4.3Q16.2 -4.3 17.9 -5.2Q19.6 -6.2 20.5 -8.1Q21.3 -9.9 21.3 -12.5Q21.3 -15.4 20.4 -17.3Q19.5 -19.2 17.7 -20.2Q15.9 -21.2 13.4 -21.2Q11.6 -21.2 10.3 -20.7Q9.1 -20.2 8.5 -19.4Q7.9 -18.5 7.9 -17.4Q7.9 -16.3 8.4 -15.5Q9 -14.7 10.2 -14.2Q11.4 -13.7 13.1 -13.7Q15.5 -13.7 17.6 -14.8Q19.8 -15.9 21.4 -17.8L23.6 -16.3Q22.6 -14.2 20.9 -12.5Q19.2 -10.9 16.9 -9.9Q14.6 -8.9 11.6 -8.9Q8.5 -8.9 6.2 -10Q3.9 -11 2.7 -12.9Q1.4 -14.7 1.4 -17.2Q1.4 -19.8 2.9 -21.8Q4.3 -23.8 7 -24.9Q9.7 -26 13.5 -26Q18.1 -26 21.2 -24.3Q24.3 -22.6 25.8 -19.7Q27.4 -16.7 27.3 -12.8Q27.4 -8.9 25.8 -5.9Q24.3 -2.9 21.2 -1.2Q18.2 0.5 13.7 0.5Z\";\n        revert();\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(lt(i, and(packed, 0xff))) { break }\n                    if iszero(gt(i, 0x1e)) {\n                        result := byte(i, packed)\n                        break\n                    }\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                    break\n                }\n                if iszero(gt(shr(8, packed), i)) { break }\n                mstore(0x00, $.slot)\n                result := byte(and(i, 0x1f), sload(add(keccak256(0x00, 0x20), shr(5, i))))\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)) {\n                    h := keccak256(add(needle, 0x20), needleLen)\n                }\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) internal pure returns (bytes memory result) {\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            result := mload(0x40)\n            let o := add(result, 0x20)\n            let searchLen := mload(needle)\n            if iszero(gt(searchLen, mload(subject))) {\n                let i := add(subject, 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)) {\n                    h := keccak256(add(needle, 0x20), searchLen)\n                }\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            }\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    /// @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) internal pure returns (bytes32 result) {\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            // Relative offset of `result` from `a.offset`. Reuses `result.length` to save a stack slot.\n            result.length := calldataload(add(a.offset, offset))\n            result.offset := add(a.offset, result.length)\n            // Wraps if the relative offset exceeds `a.length`, caught below.\n            result.length := sub(a.length, result.length)\n            // `sub(result.offset, a.offset)` recovers the relative offset, even if the add wrapped.\n            // forgefmt: disable-next-item\n            if or(shr(64, or(result.length, or(sub(result.offset, a.offset), or(l, a.offset)))),\n                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":"owner_","type":"address","internalType":"address"},{"name":"markets","type":"address[]","internalType":"address[]"},{"name":"freeMinters","type":"address[]","internalType":"address[]"}],"stateMutability":"nonpayable"},{"name":"AccountBalanceOverflow","type":"error","inputs":[]},{"name":"AlreadyInitialized","type":"error","inputs":[]},{"name":"ArtFrozen","type":"error","inputs":[]},{"name":"BadQuantity","type":"error","inputs":[]},{"name":"BalanceQueryForZeroAddress","type":"error","inputs":[]},{"name":"MintClosed","type":"error","inputs":[]},{"name":"NewOwnerIsZeroAddress","type":"error","inputs":[]},{"name":"NoAgentId","type":"error","inputs":[]},{"name":"NoHandoverRequest","type":"error","inputs":[]},{"name":"NotOwnerNorApproved","type":"error","inputs":[]},{"name":"OperatorNotAllowed","type":"error","inputs":[]},{"name":"PayoutFailed","type":"error","inputs":[]},{"name":"SoldOut","type":"error","inputs":[]},{"name":"TokenAlreadyExists","type":"error","inputs":[]},{"name":"TokenDoesNotExist","type":"error","inputs":[]},{"name":"TransferFromIncorrectOwner","type":"error","inputs":[]},{"name":"TransferLocked","type":"error","inputs":[]},{"name":"TransferToNonERC721ReceiverImplementer","type":"error","inputs":[]},{"name":"TransferToZeroAddress","type":"error","inputs":[]},{"name":"Unauthorized","type":"error","inputs":[]},{"name":"WalletLimit","type":"error","inputs":[]},{"name":"WrongPayment","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":"BatchMetadataUpdate","type":"event","inputs":[{"name":"_fromTokenId","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"_toTokenId","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"FreeMinterSet","type":"event","inputs":[{"name":"wallet","type":"address","indexed":true,"internalType":"address"},{"name":"allowed","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"MarketSet","type":"event","inputs":[{"name":"market","type":"address","indexed":true,"internalType":"address"},{"name":"allowed","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"MetadataUpdate","type":"event","inputs":[{"name":"_tokenId","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"MintOpen","type":"event","inputs":[{"name":"open","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"OwnershipHandoverCanceled","type":"event","inputs":[{"name":"pendingOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"OwnershipHandoverRequested","type":"event","inputs":[{"name":"pendingOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"oldOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"id","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"DESCRIPTION","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE_HIGH","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE_LOW","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TREASURY","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address payable"}],"stateMutability":"view"},{"name":"WEBSITE","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"X_URL","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"appendArt","type":"function","inputs":[{"name":"chunk","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"approve","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"artChunks","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"artFrozen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"result","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"cancelOwnershipHandover","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"completeOwnershipHandover","type":"function","inputs":[{"name":"pendingOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"name":"contractURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"costFor","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"c","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeMinter","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"freezeArt","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"getApproved","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"result","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"image","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"svg","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":"isMarket","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"logo","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintOpen","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"result","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":"ownershipHandoverExpiresAt","type":"function","inputs":[{"name":"pendingOwner","type":"address","internalType":"address"}],"outputs":[{"name":"result","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"priceOf","type":"function","inputs":[{"name":"n","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"pure"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"requestOwnershipHandover","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"resetArt","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"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":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setFreeMinter","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"},{"name":"allowed","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMarket","type":"function","inputs":[{"name":"market","type":"address","internalType":"address"},{"name":"allowed","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setMintOpen","type":"function","inputs":[{"name":"open","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"id","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"sweep","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"}],"matchId":"58694608","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-07T00:56:23Z","match":"exact_match","chainId":"56","address":"0x69037Db8C6f237eCd9aB4B364D65C6dD05825dCb"}