creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721EnumerableUpgradeable is IERC721Upgradeable {\n    /**\n     * @dev Returns the total amount of tokens stored by the contract.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n     * Use along with {totalSupply} to enumerate all tokens.\n     */\n    function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/Base64Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n *\n * _Available since v4.5._\n */\nlibrary Base64Upgradeable {\n    /**\n     * @dev Base64 Encoding/Decoding Table\n     */\n    string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n    /**\n     * @dev Converts a `bytes` to its Bytes64 `string` representation.\n     */\n    function encode(bytes memory data) internal pure returns (string memory) {\n        /**\n         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence\n         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol\n         */\n        if (data.length == 0) return \"\";\n\n        // Loads the table into memory\n        string memory table = _TABLE;\n\n        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n        // and split into 4 numbers of 6 bits.\n        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n        // - `data.length + 2`  -> Round up\n        // - `/ 3`              -> Number of 3-bytes chunks\n        // - `4 *`              -> 4 characters for each chunk\n        string memory result = new string(4 * ((data.length + 2) / 3));\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Prepare the lookup table (skip the first \"length\" byte)\n            let tablePtr := add(table, 1)\n\n            // Prepare result pointer, jump over length\n            let resultPtr := add(result, 32)\n\n            // Run over the input, 3 bytes at a time\n            for {\n                let dataPtr := data\n                let endPtr := add(data, mload(data))\n            } lt(dataPtr, endPtr) {\n\n            } {\n                // Advance 3 bytes\n                dataPtr := add(dataPtr, 3)\n                let input := mload(dataPtr)\n\n                // To write each character, shift the 3 bytes (18 bits) chunk\n                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)\n                // and apply logical AND with 0x3F which is the number of\n                // the previous character in the ASCII table prior to the Base64 Table\n                // The result is then added to the table to get the character to write,\n                // and finally write it in the result pointer but with a left shift\n                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n\n                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n                resultPtr := add(resultPtr, 1) // Advance\n            }\n\n            // When data `bytes` is not exactly 3 bytes long\n            // it is padded with `=` characters at the end\n            switch mod(mload(data), 3)\n            case 1 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n                mstore8(sub(resultPtr, 2), 0x3d)\n            }\n            case 2 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n            }\n        }\n\n        return result;\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/cryptography/MerkleProofUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev These functions deal with verification of Merkle Tree proofs.\n *\n * The tree and the proofs can be generated using our\n * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].\n * You will find a quickstart guide in the readme.\n *\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\n * hashing, or use a hash function other than keccak256 for hashing leaves.\n * This is because the concatenation of a sorted pair of internal nodes in\n * the merkle tree could be reinterpreted as a leaf value.\n * OpenZeppelin's JavaScript library generates merkle trees that are safe\n * against this attack out of the box.\n */\nlibrary MerkleProofUpgradeable {\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     */\n    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        return processProof(proof, leaf) == root;\n    }\n\n    /**\n     * @dev Calldata version of {verify}\n     *\n     * _Available since v4.7._\n     */\n    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        return processProofCalldata(proof, leaf) == root;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. When processing the proof, the pairs\n     * of leafs & pre-images are assumed to be sorted.\n     *\n     * _Available since v4.4._\n     */\n    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\n        bytes32 computedHash = leaf;\n        for (uint256 i = 0; i < proof.length; i++) {\n            computedHash = _hashPair(computedHash, proof[i]);\n        }\n        return computedHash;\n    }\n\n    /**\n     * @dev Calldata version of {processProof}\n     *\n     * _Available since v4.7._\n     */\n    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\n        bytes32 computedHash = leaf;\n        for (uint256 i = 0; i < proof.length; i++) {\n            computedHash = _hashPair(computedHash, proof[i]);\n        }\n        return computedHash;\n    }\n\n    /**\n     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by\n     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\n     *\n     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.\n     *\n     * _Available since v4.7._\n     */\n    function multiProofVerify(\n        bytes32[] memory proof,\n        bool[] memory proofFlags,\n        bytes32 root,\n        bytes32[] memory leaves\n    ) internal pure returns (bool) {\n        return processMultiProof(proof, proofFlags, leaves) == root;\n    }\n\n    /**\n     * @dev Calldata version of {multiProofVerify}\n     *\n     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.\n     *\n     * _Available since v4.7._\n     */\n    function multiProofVerifyCalldata(\n        bytes32[] calldata proof,\n        bool[] calldata proofFlags,\n        bytes32 root,\n        bytes32[] memory leaves\n    ) internal pure returns (bool) {\n        return processMultiProofCalldata(proof, proofFlags, leaves) == root;\n    }\n\n    /**\n     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction\n     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another\n     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false\n     * respectively.\n     *\n     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree\n     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the\n     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).\n     *\n     * _Available since v4.7._\n     */\n    function processMultiProof(\n        bytes32[] memory proof,\n        bool[] memory proofFlags,\n        bytes32[] memory leaves\n    ) internal pure returns (bytes32 merkleRoot) {\n        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by\n        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\n        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\n        // the merkle tree.\n        uint256 leavesLen = leaves.length;\n        uint256 proofLen = proof.length;\n        uint256 totalHashes = proofFlags.length;\n\n        // Check proof validity.\n        require(leavesLen + proofLen - 1 == totalHashes, \"MerkleProof: invalid multiproof\");\n\n        // The xxxPos values are \"pointers\" to the next value to consume in each array. All accesses are done using\n        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \"pop\".\n        bytes32[] memory hashes = new bytes32[](totalHashes);\n        uint256 leafPos = 0;\n        uint256 hashPos = 0;\n        uint256 proofPos = 0;\n        // At each step, we compute the next hash using two values:\n        // - a value from the \"main queue\". If not all leaves have been consumed, we get the next leaf, otherwise we\n        //   get the next hash.\n        // - depending on the flag, either another value from the \"main queue\" (merging branches) or an element from the\n        //   `proof` array.\n        for (uint256 i = 0; i < totalHashes; i++) {\n            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\n            bytes32 b = proofFlags[i]\n                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])\n                : proof[proofPos++];\n            hashes[i] = _hashPair(a, b);\n        }\n\n        if (totalHashes > 0) {\n            require(proofPos == proofLen, \"MerkleProof: invalid multiproof\");\n            unchecked {\n                return hashes[totalHashes - 1];\n            }\n        } else if (leavesLen > 0) {\n            return leaves[0];\n        } else {\n            return proof[0];\n        }\n    }\n\n    /**\n     * @dev Calldata version of {processMultiProof}.\n     *\n     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.\n     *\n     * _Available since v4.7._\n     */\n    function processMultiProofCalldata(\n        bytes32[] calldata proof,\n        bool[] calldata proofFlags,\n        bytes32[] memory leaves\n    ) internal pure returns (bytes32 merkleRoot) {\n        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by\n        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\n        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\n        // the merkle tree.\n        uint256 leavesLen = leaves.length;\n        uint256 proofLen = proof.length;\n        uint256 totalHashes = proofFlags.length;\n\n        // Check proof validity.\n        require(leavesLen + proofLen - 1 == totalHashes, \"MerkleProof: invalid multiproof\");\n\n        // The xxxPos values are \"pointers\" to the next value to consume in each array. All accesses are done using\n        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \"pop\".\n        bytes32[] memory hashes = new bytes32[](totalHashes);\n        uint256 leafPos = 0;\n        uint256 hashPos = 0;\n        uint256 proofPos = 0;\n        // At each step, we compute the next hash using two values:\n        // - a value from the \"main queue\". If not all leaves have been consumed, we get the next leaf, otherwise we\n        //   get the next hash.\n        // - depending on the flag, either another value from the \"main queue\" (merging branches) or an element from the\n        //   `proof` array.\n        for (uint256 i = 0; i < totalHashes; i++) {\n            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\n            bytes32 b = proofFlags[i]\n                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])\n                : proof[proofPos++];\n            hashes[i] = _hashPair(a, b);\n        }\n\n        if (totalHashes > 0) {\n            require(proofPos == proofLen, \"MerkleProof: invalid multiproof\");\n            unchecked {\n                return hashes[totalHashes - 1];\n            }\n        } else if (leavesLen > 0) {\n            return leaves[0];\n        } else {\n            return proof[0];\n        }\n    }\n\n    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {\n        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);\n    }\n\n    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, a)\n            mstore(0x20, b)\n            value := keccak256(0x00, 0x40)\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165Upgradeable).interfaceId;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMathUpgradeable {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = MathUpgradeable.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMathUpgradeable.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, MathUpgradeable.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "contracts/EightNapOnChainProject.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n\r\n/* \r\n\r\n_____/\\\\\\\\\\\\\\\\\\_____/\\\\\\\\\\_____/\\\\\\_____/\\\\\\\\\\\\\\\\\\_____/\\\\\\\\\\\\\\\\\\\\\\\\\\___        \r\n ___/\\\\\\///////\\\\\\__\\/\\\\\\\\\\\\___\\/\\\\\\___/\\\\\\\\\\\\\\\\\\\\\\\\\\__\\/\\\\\\/////////\\\\\\_       \r\n  __\\/\\\\\\_____\\/\\\\\\__\\/\\\\\\/\\\\\\__\\/\\\\\\__/\\\\\\/////////\\\\\\_\\/\\\\\\_______\\/\\\\\\_      \r\n   __\\///\\\\\\\\\\\\\\\\\\/___\\/\\\\\\//\\\\\\_\\/\\\\\\_\\/\\\\\\_______\\/\\\\\\_\\/\\\\\\\\\\\\\\\\\\\\\\\\\\/__     \r\n    ___/\\\\\\///////\\\\\\__\\/\\\\\\\\//\\\\\\\\/\\\\\\_\\/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_\\/\\\\\\/////////____    \r\n     __/\\\\\\______\\//\\\\\\_\\/\\\\\\_\\//\\\\\\/\\\\\\_\\/\\\\\\/////////\\\\\\_\\/\\\\\\_____________   \r\n      _\\//\\\\\\______/\\\\\\__\\/\\\\\\__\\//\\\\\\\\\\\\_\\/\\\\\\_______\\/\\\\\\_\\/\\\\\\_____________  \r\n       __\\///\\\\\\\\\\\\\\\\\\/___\\/\\\\\\___\\//\\\\\\\\\\_\\/\\\\\\_______\\/\\\\\\_\\/\\\\\\_____________ \r\n        ____\\/////////_____\\///_____\\/////__\\///________\\///__\\///______________\r\n\r\nSmartcontract developed by 8NAPART.\r\n\r\n */\r\n\r\npragma solidity ^0.8.19;\r\n\r\nimport \"./helpers/SSTORE2.sol\";\r\nimport \"./helpers/OwnableUpgradeable.sol\";\r\nimport \"./helpers/ERC721EnumerableUpgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/utils/Base64Upgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/MerkleProofUpgradeable.sol\";\r\nimport \"./helpers/File.sol\";\r\n\r\ncontract EightNapOnChainProjectV1 is\r\n    ERC721EnumerableUpgradeable,\r\n    OwnableUpgradeable\r\n{\r\n    mapping(address => bool) private _addressToClaimed;\r\n    mapping(uint256 => bytes32) public tokenIdToHash;\r\n    mapping(uint256 => address) public tokenIdToRevealer;\r\n\r\n    uint256 private _mintPassFlags; //32\r\n    uint256 private _withdrawable; // 32\r\n    uint56 currentBidEndTimeStamp; // 8\r\n    uint56 currentBidStartTimeStamp; // 8\r\n\r\n    event BaseURISet(string newBaseURI);\r\n    event MaxSupplySet(uint24 newMaxSupply);\r\n    event ArtScriptsSet();\r\n    event LibraryScriptsSet();\r\n    event PieceRevealed();\r\n    event NewBidPlaced(Bid bid);\r\n\r\n    struct Project {\r\n        string name; //unknown\r\n        string baseURI; //unkown\r\n        address[] artScripts; //unknown\r\n        bytes32 merkleRoot; //32\r\n        address artInfo; //20\r\n        uint56 biddingStartTimeStamp; //8\r\n        uint32 maxSupply; //4\r\n        address payable twoFiveSix; //20\r\n        uint96 mintPassHolderPrice; //12\r\n        address payable royaltyAddress; //20\r\n        uint96 minBid; //12\r\n        address payable artistAddress; //20\r\n        uint24 revealerDiscount; //3\r\n        uint24 royalty; //3\r\n        uint24 eightNapShare; //3\r\n        uint24 twoFiveSixShare; //3\r\n        address payable eightNap; //20\r\n        uint56 mintPassStartTimeStamp; //8\r\n        uint32 auctionDuration; //4\r\n        address libraryScripts; //20\r\n        uint56 allowListStartTimeStamp; //8\r\n        uint32 auctionExtension; //4\r\n        address mintPassAddress; // 20\r\n        uint56 publicStartTimeStamp; //8\r\n        uint32 auctionExtenderTimeFrame; // 4\r\n        uint96 allowListPrice; //12\r\n        uint96 publicPrice; //12\r\n        uint32 supplyLeftForAuction; // 4\r\n    }\r\n\r\n    struct LibraryScript {\r\n        address fileStore;\r\n        string fileName;\r\n    }\r\n\r\n    struct Bid {\r\n        address payable bidder;\r\n        uint256 amount;\r\n    }\r\n\r\n    struct Auction {\r\n        Bid highestBid;\r\n        uint256 tokenId;\r\n        uint56 endTime;\r\n        bool claimed;\r\n    }\r\n\r\n    Project private project;\r\n    Auction private auction;\r\n\r\n    /**\r\n     * @notice Initializes the project.\r\n     * @dev Initializes the ERC721 contract.\r\n     * @param _p The project data.\r\n     */\r\n    function initProject(\r\n        Project calldata _p,\r\n        address _libraryScripts\r\n    ) public initializer {\r\n        __ERC721_init(_p.name, \"8NAPART\");\r\n        __Ownable_init(_p.artistAddress);\r\n        project = _p;\r\n\r\n        if (_libraryScripts != address(0)) {\r\n            project.libraryScripts = _libraryScripts;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Mint tokens to an address (artist only)\r\n     * @dev Mints a given number of tokens to a specified address. Can only be called by the project owner.\r\n     * @param count The number of tokens to be minted.\r\n     * @param a The address to which the tokens will be minted.\r\n     */\r\n    function artistMint(uint24 count, address a) public onlyOwner {\r\n        uint256 totalSupply = _owners.length;\r\n        require(totalSupply + count < project.maxSupply, \"Minted out\");\r\n        require(count < 5, \"Mint max four per tx\");\r\n\r\n        for (uint256 i; i < count; ) {\r\n            unchecked {\r\n                uint256 tokenId = totalSupply + i;\r\n                tokenIdToHash[tokenId] = createHash(\r\n                    tokenId,\r\n                    project.artistAddress\r\n                );\r\n                _mint(a, tokenId);\r\n                i++;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Mint a token to an allow listed address if conditions met.\r\n     * @dev Mints a token to a specified address if that address is on the project's allow list and has not already claimed a token.\r\n     * @param proof The proof of inclusion in the project's Merkle tree.\r\n     * @param a The address to which the token will be minted.\r\n     */\r\n    function allowListMint(bytes32[] memory proof, address a) public payable {\r\n        require(\r\n            block.timestamp > project.allowListStartTimeStamp,\r\n            \"Allow list mint not started\"\r\n        );\r\n        require(\r\n            block.timestamp < project.biddingStartTimeStamp ||\r\n                block.timestamp < project.publicStartTimeStamp,\r\n            \"Allow list mint ended\"\r\n        );\r\n        require(\r\n            MerkleProofUpgradeable.verify(\r\n                proof,\r\n                project.merkleRoot,\r\n                keccak256(abi.encodePacked(a))\r\n            ),\r\n            \"Not on allow list\"\r\n        );\r\n        require(_addressToClaimed[a] == false, \"Already claimed\");\r\n\r\n        uint256 totalSupply = _owners.length;\r\n        if (project.publicStartTimeStamp != 0) {\r\n            require(\r\n                totalSupply + 1 <\r\n                    (project.maxSupply - project.supplyLeftForAuction),\r\n                \"Not available\"\r\n            );\r\n        }\r\n        require(totalSupply + 1 < project.maxSupply, \"Minted out\");\r\n        require(project.allowListPrice <= msg.value, \"Invalid funds provided\");\r\n        require(msg.sender == tx.origin, \"No contract minting\");\r\n\r\n        unchecked {\r\n            uint256 tokenId = totalSupply;\r\n            _addressToClaimed[a] = true;\r\n            _withdrawable += msg.value;\r\n            tokenIdToHash[tokenId] = createHash(tokenId, msg.sender);\r\n            _mint(a, tokenId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Allows users to mint tokens using their mint passes.\r\n     * @dev Users can mint up to four tokens per transaction during the mint pass phase.\r\n     * @param mintPassIds An array of mint pass IDs the user wants to use for minting.\r\n     */\r\n    function mintPassMint(uint256[] calldata mintPassIds) public payable {\r\n        require(\r\n            block.timestamp > project.mintPassStartTimeStamp,\r\n            \"Mint pass mint not started\"\r\n        );\r\n        require(\r\n            block.timestamp < project.allowListStartTimeStamp,\r\n            \"Mint pass mint ended\"\r\n        );\r\n\r\n        uint256 totalSupply = _owners.length;\r\n        uint256 count = mintPassIds.length;\r\n        uint256 total = count * project.mintPassHolderPrice;\r\n\r\n        require(totalSupply + count < project.maxSupply, \"Minted out\");\r\n        require(count > 0, \"Mint at least one\");\r\n        require(count < 5, \"Mint max four per tx\");\r\n        require(total <= msg.value, \"Invalid funds provided\");\r\n        require(msg.sender == tx.origin, \"No contract minting\");\r\n\r\n        IERC721Upgradeable mintPassContract = IERC721Upgradeable(\r\n            project.mintPassAddress\r\n        );\r\n\r\n        unchecked {\r\n            _withdrawable += msg.value;\r\n        }\r\n        for (uint256 i; i < count; i++) {\r\n            address a = mintPassContract.ownerOf(mintPassIds[i]);\r\n\r\n            uint256 tokenId = totalSupply + i;\r\n\r\n            bool isUsed = getMintPassMinted(mintPassIds[i]);\r\n\r\n            require(!isUsed, \"Mint pass already used\");\r\n\r\n            _setMintPassUsed(mintPassIds[i]);\r\n\r\n            bytes32 hashOne = createHash(tokenId, msg.sender);\r\n            tokenIdToHash[tokenId] = hashOne;\r\n\r\n            _mint(a, tokenId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Mint a token if conditions met.\r\n     * @dev Mints a token to a specified address.\r\n     * @param a The address to which the token will be minted.\r\n     */\r\n    function publicMint(address a, uint256 count) public payable {\r\n        require(project.publicStartTimeStamp != 0, \"No public mint\");\r\n        require(\r\n            block.timestamp > project.publicStartTimeStamp,\r\n            \"Public mint not started\"\r\n        );\r\n        uint256 total = count * project.publicPrice;\r\n        uint256 totalSupply = _owners.length;\r\n\r\n        require(\r\n            totalSupply + count <\r\n                (project.maxSupply - project.supplyLeftForAuction),\r\n            \"Not available\"\r\n        );\r\n        require(count > 0, \"Mint at least one\");\r\n        require(count < 5, \"Mint max four per tx\");\r\n        require(total <= msg.value, \"Invalid funds provided\");\r\n        require(msg.sender == tx.origin, \"No contract minting\");\r\n\r\n        unchecked {\r\n            _withdrawable += msg.value;\r\n        }\r\n\r\n        for (uint256 i; i < count; i++) {\r\n            uint256 tokenId = totalSupply + i;\r\n            tokenIdToHash[tokenId] = createHash(tokenId, msg.sender);\r\n            _mint(a, tokenId);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Checks if a given mint pass has already been used.\r\n     * @param mintPassId The ID of the mint pass to check.\r\n     * @return bool Whether the mint pass has been used.\r\n     */\r\n    function getMintPassMinted(uint256 mintPassId) public view returns (bool) {\r\n        uint256 mask = (1 << mintPassId);\r\n        return (_mintPassFlags & mask) != 0;\r\n    }\r\n\r\n    /**\r\n     * @dev Marks a given mint pass as used.\r\n     * @param _mintPassId The ID of the mint pass to mark as used.\r\n     */\r\n    function _setMintPassUsed(uint256 _mintPassId) private {\r\n        uint256 mask = (1 << _mintPassId);\r\n\r\n        _mintPassFlags = _mintPassFlags | mask;\r\n    }\r\n\r\n    /**\r\n     * @notice Reveals the next piece to be auctioned.\r\n     * @dev Resets the auction state and sets up the next token for auction.\r\n     */\r\n    function revealNextPiece() public {\r\n        if (project.publicStartTimeStamp != 0) {\r\n            require(\r\n                block.timestamp > project.publicStartTimeStamp &&\r\n                    (_owners.length + 1 >=\r\n                        project.maxSupply - project.supplyLeftForAuction),\r\n                \"Bidding phase not started\"\r\n            );\r\n        } else {\r\n            require(\r\n                block.timestamp > project.biddingStartTimeStamp,\r\n                \"Bidding phase not started\"\r\n            );\r\n        }\r\n        require(msg.sender == tx.origin, \"No contract revealing\");\r\n        require(block.timestamp > auction.endTime, \"Auction in progress\");\r\n\r\n        if (!auction.claimed && auction.highestBid.amount > 0) {\r\n            _claim();\r\n        }\r\n        require(_owners.length + 1 < project.maxSupply, \"Minted out\");\r\n        require(auction.tokenId == 0, \"Already revealed\");\r\n\r\n        uint256 nextTokenId = _owners.length;\r\n        tokenIdToHash[nextTokenId] = createHash(nextTokenId, msg.sender);\r\n        tokenIdToRevealer[nextTokenId] = msg.sender;\r\n\r\n        delete auction.claimed;\r\n        delete auction.endTime;\r\n        delete auction.highestBid;\r\n        auction.tokenId = nextTokenId;\r\n        emit PieceRevealed();\r\n    }\r\n\r\n    /**\r\n     * @notice Allows users to place a bid on the current auction.\r\n     * @dev Users can outbid the current highest bid by at least 5%.\r\n     */\r\n    function placeBid() public payable {\r\n        require(\r\n            tokenIdToHash[_owners.length] != bytes32(0),\r\n            \"Reveal piece first\"\r\n        );\r\n        require(msg.value >= project.minBid, \"Bid is lower than minimum bid\");\r\n        require(msg.sender == tx.origin, \"No contract bidding\");\r\n        require(\r\n            msg.value >\r\n                auction.highestBid.amount + (auction.highestBid.amount / 20),\r\n            \"Bid must be > 5% greater than current bid\"\r\n        );\r\n\r\n        Bid memory previousBid = auction.highestBid;\r\n\r\n        // set new bidder\r\n        auction.highestBid = Bid({\r\n            bidder: payable(msg.sender),\r\n            amount: msg.value\r\n        });\r\n\r\n        // refund previous bidder\r\n        if (auction.endTime != 0) {\r\n            require(block.timestamp < auction.endTime, \"Auction ended\");\r\n            if (\r\n                block.timestamp + project.auctionExtenderTimeFrame >\r\n                auction.endTime\r\n            ) {\r\n                auction.endTime += project.auctionExtension;\r\n            }\r\n            previousBid.bidder.transfer(previousBid.amount);\r\n        } else {\r\n            // first bid\r\n            unchecked {\r\n                auction.endTime =\r\n                    uint56(block.timestamp) +\r\n                    project.auctionDuration;\r\n            }\r\n        }\r\n        emit NewBidPlaced(auction.highestBid);\r\n    }\r\n\r\n    /**\r\n     * @notice Allows a user to reveal the next piece and place a bid in a single transaction.\r\n     * @dev This function combines the actions of revealing the next piece in the auction (if any)\r\n     *      and placing a bid on it. It is designed to streamline user interactions with the contract\r\n     *      by reducing the number of transactions they need to send.\r\n     *      This function should only be called if it's time to reveal a new piece and the caller\r\n     *      wants to place a bid immediately after the reveal.\r\n     *      The function calls `revealNextPiece` followed by `placeBid`, inheriting their logical checks\r\n     *      and effects.\r\n     * @notice Ensure that you send enough Ether to cover the bid amount when calling this function.\r\n     * @notice This function will fail if called when it's not time to reveal a new piece,\r\n     *      or if the bid conditions are not met (e.g., bid too low).\r\n     */\r\n    function revealAndBid() public payable {\r\n        revealNextPiece();\r\n        placeBid();\r\n    }\r\n\r\n    /**\r\n     * @dev Internally claims the item for the highest bidder after the auction ends.\r\n     * This function is primarily used during the reveal process to ensure the item is claimed\r\n     * and the _owners.length is updated if the item wasn't previously claimed.\r\n     */\r\n    function _claim() private {\r\n        require(auction.endTime != 0, \"Auction not started\");\r\n        if (auction.highestBid.bidder == tokenIdToRevealer[auction.tokenId]) {\r\n            uint256 refund = (auction.highestBid.amount / 10000) *\r\n                (project.revealerDiscount);\r\n            _withdrawable += auction.highestBid.amount - refund;\r\n\r\n            auction.highestBid.bidder.transfer(refund);\r\n        } else {\r\n            _withdrawable += auction.highestBid.amount;\r\n        }\r\n        delete auction.tokenId;\r\n        _mint(auction.highestBid.bidder, auction.tokenId);\r\n    }\r\n\r\n    /**\r\n     * @notice Allows the highest bidder to claim their item after the auction ends.\r\n     * @dev This is the public version of the _claim function.\r\n     */\r\n    function claim() public {\r\n        require(auction.endTime != 0, \"Auction not started\");\r\n        require(block.timestamp > auction.endTime, \"Auction not concluded\");\r\n        require(auction.claimed == false, \"Already claimed\");\r\n        if (auction.highestBid.bidder == tokenIdToRevealer[auction.tokenId]) {\r\n            uint256 refund = (auction.highestBid.amount / 10000) *\r\n                (project.revealerDiscount);\r\n            _withdrawable += auction.highestBid.amount - refund;\r\n\r\n            auction.highestBid.bidder.transfer(refund);\r\n        } else {\r\n            _withdrawable += auction.highestBid.amount;\r\n        }\r\n        auction.claimed = true;\r\n        delete auction.tokenId;\r\n        _mint(auction.highestBid.bidder, auction.tokenId);\r\n    }\r\n\r\n    /**\r\n     * @notice Check whether a given address is on the allowlist and whether it has already claimed a token.\r\n     * @dev Returns two boolean values. The first indicates whether the address is on the allowlist, and the second indicates whether the address has already claimed a token.\r\n     * @param a The address to check.\r\n     * @param proof The proof of inclusion in the project's Merkle tree for the given address.\r\n     * @return isOnList Whether the address is on the allowlist.\r\n     * @return hasClaimed Whether the address has already claimed a token.\r\n     */\r\n    function getAllowListAndClaimStatus(\r\n        address a,\r\n        bytes32[] memory proof\r\n    ) public view returns (bool, bool) {\r\n        bytes32 hash = keccak256(abi.encodePacked(a));\r\n        bool isOnList = MerkleProofUpgradeable.verify(\r\n            proof,\r\n            project.merkleRoot,\r\n            hash\r\n        );\r\n        bool hasClaimed = _addressToClaimed[a];\r\n        return (isOnList, hasClaimed);\r\n    }\r\n\r\n    /**\r\n     * @notice Create a hash for the given tokenId, blockNumber and sender.\r\n     * @param tokenId The ID of the token.\r\n     * @param sender The address of the sender.\r\n     * @return The resulting hash.\r\n     */\r\n    function createHash(\r\n        uint256 tokenId,\r\n        address sender\r\n    ) private view returns (bytes32) {\r\n        unchecked {\r\n            return\r\n                keccak256(\r\n                    abi.encodePacked(\r\n                        tokenId,\r\n                        sender,\r\n                        blockhash(block.number - 1),\r\n                        blockhash(block.number - 2),\r\n                        blockhash(block.number - 4),\r\n                        block.prevrandao,\r\n                        block.coinbase\r\n                    )\r\n                );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Get the hash associated with a given tokenId.\r\n     * @param _id The ID of the token.\r\n     * @return The hash associated with the given tokenId.\r\n     */\r\n    function tokenHash(uint256 _id) public view returns (bytes32) {\r\n        return tokenIdToHash[_id];\r\n    }\r\n\r\n    /**\r\n     * @notice Withdraw funds from the contract\r\n     * @dev Transfers a percentage of the balance to the 8NAPART address and optionally a third party, the rest to the artist address.\r\n     */\r\n    function withdraw() public {\r\n        require(\r\n            (msg.sender == project.eightNap ||\r\n                msg.sender == project.artistAddress ||\r\n                msg.sender == project.twoFiveSix),\r\n            \"Not allowed\"\r\n        );\r\n\r\n        uint256 balance = _withdrawable;\r\n\r\n        require(balance > 0, \"Balance is zero\");\r\n\r\n        uint256 eightNapBalance = (balance * project.eightNapShare) / 10000;\r\n        uint256 twoFiveSixBalance = (balance * project.twoFiveSixShare) / 10000;\r\n        uint256 artistBalance = balance - eightNapBalance - twoFiveSixBalance;\r\n\r\n        delete _withdrawable;\r\n        project.eightNap.transfer(eightNapBalance);\r\n        project.twoFiveSix.transfer(twoFiveSixBalance);\r\n        project.artistAddress.transfer(artistBalance);\r\n    }\r\n\r\n    function walletOfOwner(\r\n        address _owner\r\n    ) public view returns (uint256[] memory) {\r\n        uint256 tokenCount = balanceOf(_owner);\r\n        if (tokenCount == 0) return new uint256[](0);\r\n\r\n        uint256[] memory tokensId = new uint256[](tokenCount);\r\n        for (uint256 i; i < tokenCount; i++) {\r\n            tokensId[i] = tokenOfOwnerByIndex(_owner, i);\r\n        }\r\n        return tokensId;\r\n    }\r\n\r\n    function batchTransferFrom(\r\n        address _from,\r\n        address _to,\r\n        uint256[] memory _tokenIds\r\n    ) public {\r\n        for (uint256 i; i < _tokenIds.length; i++) {\r\n            transferFrom(_from, _to, _tokenIds[i]);\r\n        }\r\n    }\r\n\r\n    function batchSafeTransferFrom(\r\n        address _from,\r\n        address _to,\r\n        uint256[] memory _tokenIds,\r\n        bytes memory data_\r\n    ) public {\r\n        for (uint256 i; i < _tokenIds.length; i++) {\r\n            safeTransferFrom(_from, _to, _tokenIds[i], data_);\r\n        }\r\n    }\r\n\r\n    function isOwnerOf(\r\n        address account,\r\n        uint256[] calldata _tokenIds\r\n    ) external view returns (bool) {\r\n        for (uint256 i; i < _tokenIds.length; ++i) {\r\n            if (_owners[_tokenIds[i]] != account) return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    function _mint(address to, uint256 tokenId) internal virtual override {\r\n        _owners.push(to);\r\n        emit Transfer(address(0), to, tokenId);\r\n    }\r\n\r\n    /**\r\n     * @notice Calculates the royalty information for a given sale.\r\n     * @dev Implements the required royaltyInfo function for the ERC2981 standard.\r\n     * @param _salePrice The sale price of the token being sold.\r\n     * @return receiver The address of the royalty recipient.\r\n     * @return royaltyAmount The amount of royalty to be paid.\r\n     */\r\n    function royaltyInfo(\r\n        uint256,\r\n        uint256 _salePrice\r\n    ) external view returns (address receiver, uint256 royaltyAmount) {\r\n        return (project.royaltyAddress, (_salePrice * project.royalty) / 10000);\r\n    }\r\n\r\n    /**\r\n     * @notice Converts a bytes16 value to its hexadecimal representation as a bytes32 value.\r\n     * @param data The bytes16 value to convert.\r\n     * @return result The hexadecimal representation of the input value as a bytes32 value.\r\n     */\r\n    function toHex16(bytes16 data) internal pure returns (bytes32 result) {\r\n        result =\r\n            (bytes32(data) &\r\n                0xFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000) |\r\n            ((bytes32(data) &\r\n                0x0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000) >>\r\n                64);\r\n        result =\r\n            (result &\r\n                0xFFFFFFFF000000000000000000000000FFFFFFFF000000000000000000000000) |\r\n            ((result &\r\n                0x00000000FFFFFFFF000000000000000000000000FFFFFFFF0000000000000000) >>\r\n                32);\r\n        result =\r\n            (result &\r\n                0xFFFF000000000000FFFF000000000000FFFF000000000000FFFF000000000000) |\r\n            ((result &\r\n                0x0000FFFF000000000000FFFF000000000000FFFF000000000000FFFF00000000) >>\r\n                16);\r\n        result =\r\n            (result &\r\n                0xFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000) |\r\n            ((result &\r\n                0x00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000) >>\r\n                8);\r\n        result =\r\n            ((result &\r\n                0xF000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000) >>\r\n                4) |\r\n            ((result &\r\n                0x0F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F00) >>\r\n                8);\r\n        result = bytes32(\r\n            0x3030303030303030303030303030303030303030303030303030303030303030 +\r\n                uint256(result) +\r\n                (((uint256(result) +\r\n                    0x0606060606060606060606060606060606060606060606060606060606060606) >>\r\n                    4) &\r\n                    0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F) *\r\n                7\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @dev Converts a bytes32 value to its hexadecimal representation as a string.\r\n     * @param data The bytes32 value to convert.\r\n     * @return The hexadecimal representation of the bytes32 value, as a string.\r\n     */\r\n    function toHex(bytes32 data) private pure returns (string memory) {\r\n        return\r\n            string(\r\n                abi.encodePacked(\r\n                    \"0x\",\r\n                    toHex16(bytes16(data)),\r\n                    toHex16(bytes16(data << 128))\r\n                )\r\n            );\r\n    }\r\n\r\n    /**\r\n     * @notice Returns a string containing base64 encoded HTML code which renders the artwork associated with the given tokenId directly from chain.\r\n     * @dev This function reads libraries from the storage and uses them to generate the HTML code for the artwork.\r\n     * @param tokenId The ID of the token whose artwork will be generated.\r\n     * @return artwork A string containing the base64 encoded HTML code for the artwork.\r\n     */\r\n    function tokenHTML(\r\n        uint256 tokenId\r\n    ) public view returns (string memory artwork) {\r\n        require(tokenHash(tokenId) != bytes32(0), \"Token not found\");\r\n\r\n        string memory artScript;\r\n        string memory libraryScripts;\r\n\r\n        if (project.libraryScripts != address(0)) {\r\n            LibraryScript[] memory librariesArray = abi.decode(\r\n                SSTORE2.read(project.libraryScripts),\r\n                (LibraryScript[])\r\n            );\r\n            for (uint256 l; l < librariesArray.length; l++) {\r\n                IFileStore fileStore = IFileStore(librariesArray[l].fileStore);\r\n                libraryScripts = string.concat(\r\n                    libraryScripts,\r\n                    \"await ls256('\",\r\n                    fileStore.getFile(librariesArray[l].fileName).read(),\r\n                    \"');\"\r\n                );\r\n            }\r\n        }\r\n\r\n        for (uint256 i; i < project.artScripts.length; i++) {\r\n            IArtScript artscriptToGet = IArtScript(project.artScripts[i]);\r\n            artScript = string.concat(artScript, artscriptToGet.artScript());\r\n        }\r\n\r\n        return\r\n            string.concat(\r\n                \"data:text/html;base64,\",\r\n                Base64Upgradeable.encode(\r\n                    abi.encodePacked(\r\n                        \"<html><head><script>let inputData={'tokenId': \",\r\n                        StringsUpgradeable.toString(tokenId),\r\n                        \",'hash': '\",\r\n                        toHex(tokenHash(tokenId)),\r\n                        \"'\",\r\n                        \"};\",\r\n                        \"</script>\",\r\n                        \"<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1'><style type='text/css'>html{height:100%;width:100%;}body{height:100%;width:100%;margin:0;padding:0;background-color:#000000;}canvas{display:block;max-width:100%;max-height:100%;padding:0;margin:auto;display:block;position:absolute;top:0;bottom:0;left:0;right:0;object-fit:contain;}</style>\",\r\n                        \"</head><body><script defer>async function ls256(e){let t=new TextDecoder,a=window.atob(e),n=a.length,r=new Uint8Array(n);for(var o=0;o<n;o++)r[o]=a.charCodeAt(o);let d=r.buffer;let c=new ReadableStream({start(e){e.enqueue(d),e.close()}}).pipeThrough(new DecompressionStream('gzip')),i=await new Response(c),p=await i.arrayBuffer(),l=await t.decode(p),s=document.createElement('script');s.type='text/javascript',s.appendChild(document.createTextNode(l)),document.body.appendChild(s)};async function la256(){\",\r\n                        libraryScripts,\r\n                        \"await ls256('\",\r\n                        artScript,\r\n                        \"');\"\r\n                        \"};la256();</script></body></html>\"\r\n                    )\r\n                )\r\n            );\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the metadata of the token with the given ID, including name, artist, description, license, image and animation URL, and attributes.\r\n     * @dev It returns a base64 encoded JSON object which conforms to the ERC721 metadata standard.\r\n     * @param _tokenId The ID of the token to retrieve metadata for.\r\n     * @return A base64 encoded JSON object that contains the metadata of the given token.\r\n     */\r\n    function tokenURI(\r\n        uint256 _tokenId\r\n    ) public view override returns (string memory) {\r\n        require(tokenHash(_tokenId) != bytes32(0), \"Token not found\");\r\n        return\r\n            string(\r\n                abi.encodePacked(\r\n                    project.baseURI,\r\n                    StringsUpgradeable.toString(_tokenId)\r\n                )\r\n            );\r\n    }\r\n\r\n    /**\r\n     * @notice Allows to set the image base URL for the project (owner)\r\n     * @dev Only callable by the owner\r\n     * @param _baseURI String representing the base URL for images\r\n     */\r\n    function setBaseURI(string calldata _baseURI) public onlyOwner {\r\n        project.baseURI = _baseURI;\r\n        emit BaseURISet(_baseURI);\r\n    }\r\n\r\n    /**\r\n     * @notice Sets the maximum number of tokens that can be minted for the project (owner)\r\n     * @dev Only the owner of the contract can call this function.\r\n     * @dev The new maximum supply must be greater than the current number of tokens minted\r\n     * and less than the current maximum supply\r\n     * @param _maxSupply The new maximum number of tokens that can be minted\r\n     */\r\n    function setMaxSupply(uint24 _maxSupply) public onlyOwner {\r\n        require(_maxSupply > _owners.length, \"Too low\");\r\n        require(_maxSupply < project.maxSupply, \"Too high\");\r\n        project.maxSupply = _maxSupply + 1; // We always set maxSupply one higher for gas savings during mint\r\n        emit MaxSupplySet(_maxSupply);\r\n    }\r\n\r\n    /**\r\n     * @notice Allows to set the art scripts for the project\r\n     * @param _artScripts Array of addresses representing the art scripts\r\n     */\r\n    function setArtScripts(address[] calldata _artScripts) public onlyOwner {\r\n        project.artScripts = _artScripts;\r\n        emit ArtScriptsSet();\r\n    }\r\n\r\n    /**\r\n     * @notice Allows to set the library scripts for the project\r\n     * @param _libraries Array of LibraryScript objects representing the library scripts\r\n     */\r\n    function setLibraryScripts(\r\n        LibraryScript[] calldata _libraries\r\n    ) public onlyOwner {\r\n        project.libraryScripts = SSTORE2.write(abi.encode(_libraries));\r\n        emit LibraryScriptsSet();\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the mintpass holder price for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the presale price for the project\r\n     */\r\n    function getmintPassHolderPrice() external view returns (uint256) {\r\n        return project.mintPassHolderPrice;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the allowlist price for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the presale price for the project\r\n     */\r\n    function getAllowListPrice() external view returns (uint256) {\r\n        return project.allowListPrice;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the public price for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the presale price for the project\r\n     */\r\n    function getPublicPrice() external view returns (uint256) {\r\n        return project.publicPrice;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the address of the ArtInfo contract used in the project\r\n     * @dev This function is view only\r\n     * @return address Representing the address of the ArtInfo contract\r\n     */\r\n    function getArtInfo() external view returns (address) {\r\n        return project.artInfo;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns an array with the addresses storing the art script used in the project\r\n     * @dev This function is view only\r\n     * @return address[] Array of addresses storing the art script used in the project\r\n     */\r\n    function getArtScripts() external view returns (address[] memory) {\r\n        return project.artScripts;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the maximum number of tokens that can be minted for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the maximum number of tokens that can be minted\r\n     */\r\n    function getMaxSupply() external view returns (uint256) {\r\n        return project.maxSupply - 1;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the timestamp of the bidding start for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the timestamp of the bidding start\r\n     */\r\n    function getBiddingStartTimeStamp() external view returns (uint256) {\r\n        return project.biddingStartTimeStamp;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the timestamp of the bidding start for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the timestamp of the bidding start\r\n     */\r\n    function getPublicStartTimeStamp() external view returns (uint256) {\r\n        return project.publicStartTimeStamp;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the timestamp of the allowlist start for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the timestamp of the allowlist start\r\n     */\r\n    function getallowListStartTimeStamp() external view returns (uint256) {\r\n        return project.allowListStartTimeStamp;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the timestamp of the mintpass start for the project\r\n     * @dev This function is view only\r\n     * @return uint256 Representing the timestamp of the allowlist start\r\n     */\r\n    function getMintPassStartTimeStamp() external view returns (uint256) {\r\n        return project.mintPassStartTimeStamp;\r\n    }\r\n\r\n    /**\r\n     * @notice Retrieves the number of tokens left available for auction.\r\n     * @dev This getter function returns the current count of tokens that can still be minted during the auction phase.\r\n     * @return The number of tokens left for auction.\r\n     */\r\n    function getSupplyLeftForAuction() public view returns (uint32) {\r\n        return project.supplyLeftForAuction;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns the current status of the minting phases and the auction.\r\n     * @dev This function provides a JSON-like string representation of the current status\r\n     *      of various stages in the contract: Mint Pass Mint, Allow List Mint, and Auction.\r\n     *      It checks the current time against the pre-set timestamps for each phase\r\n     *      and determines their status.\r\n     *      The statuses are represented as integers:\r\n     *      - 0: Not started\r\n     *      - 1: Open\r\n     *      - 2: Ended\r\n     * @return A string in a JSON-like format that includes the status of each phase and\r\n     *         the remaining time for the current phase (if applicable).\r\n     * @notice The returned string needs to be parsed on the client side to extract relevant information.\r\n     */\r\n    function getStatus() public view returns (string memory) {\r\n        uint256 currentTime = block.timestamp;\r\n        uint256 mintPassStatus = 0; // Not started\r\n        uint256 allowListStatus = 0; // Not started\r\n        uint256 publicStatus = 0; // Not started\r\n        uint256 auctionStatus = 0; // Not started\r\n        uint256 currentBidAmount = 0;\r\n        address currentBidder = address(0);\r\n        address revealerAddress = tokenIdToRevealer[_owners.length];\r\n        uint256 ownersLengthPlusOne = _owners.length + 1; // Cached for multiple uses\r\n        uint256 maxSupplyForAuction = project.maxSupply -\r\n            project.supplyLeftForAuction; // Cached for multiple uses\r\n\r\n        // Check Mint Pass Mint status\r\n        if (\r\n            currentTime > project.mintPassStartTimeStamp &&\r\n            currentTime < project.allowListStartTimeStamp\r\n        ) {\r\n            mintPassStatus = 1; // Open\r\n        } else if (currentTime >= project.allowListStartTimeStamp) {\r\n            mintPassStatus = 2; // Ended\r\n        }\r\n\r\n        // Check Allow List Mint status\r\n        if (\r\n            currentTime > project.allowListStartTimeStamp &&\r\n            (currentTime < project.biddingStartTimeStamp ||\r\n                currentTime < project.publicStartTimeStamp)\r\n        ) {\r\n            allowListStatus = 1; // Open\r\n        } else if (\r\n            currentTime >= project.biddingStartTimeStamp &&\r\n            currentTime >= project.publicStartTimeStamp\r\n        ) {\r\n            allowListStatus = 2; // Ended\r\n        }\r\n\r\n        /* require(totalSupply + count < (project.maxSupply - project.supplyLeftForAuction), \"Not available\"); */\r\n\r\n        if (\r\n            project.publicStartTimeStamp != 0 &&\r\n            currentTime > project.publicStartTimeStamp &&\r\n            (ownersLengthPlusOne < (maxSupplyForAuction))\r\n        ) {\r\n            publicStatus = 1; // Open\r\n        } else if (\r\n            project.publicStartTimeStamp != 0 &&\r\n            (ownersLengthPlusOne >= (maxSupplyForAuction))\r\n        ) {\r\n            publicStatus = 2; //Ended\r\n        }\r\n\r\n        if (\r\n            (project.publicStartTimeStamp == 0 &&\r\n                currentTime > project.biddingStartTimeStamp) ||\r\n            (ownersLengthPlusOne >= (maxSupplyForAuction))\r\n        ) // Check Auction status\r\n        {\r\n            auctionStatus = 1; // Open\r\n            if (currentTime < auction.endTime) {\r\n                currentBidAmount = auction.highestBid.amount;\r\n                currentBidder = auction.highestBid.bidder;\r\n            } else {\r\n                auctionStatus = 2; // Ended\r\n            }\r\n        }\r\n\r\n        return\r\n            string(\r\n                abi.encodePacked(\r\n                    \"{\",\r\n                    '\"mintPassStatus\":',\r\n                    StringsUpgradeable.toString(mintPassStatus),\r\n                    \",\",\r\n                    '\"allowListStatus\":',\r\n                    StringsUpgradeable.toString(allowListStatus),\r\n                    \",\",\r\n                    '\"auctionStatus\":',\r\n                    StringsUpgradeable.toString(auctionStatus),\r\n                    \",\",\r\n                    '\"publicStatus\":',\r\n                    StringsUpgradeable.toString(publicStatus),\r\n                    \",\",\r\n                    '\"auctionEndTime\":',\r\n                    StringsUpgradeable.toString(auction.endTime),\r\n                    \",\",\r\n                    '\"currentBidAmount\":',\r\n                    StringsUpgradeable.toString(currentBidAmount),\r\n                    \",\",\r\n                    '\"currentBidder\":\"',\r\n                    StringsUpgradeable.toHexString(\r\n                        uint256(uint160(currentBidder)),\r\n                        20\r\n                    ),\r\n                    '\",\"revealer\":\"',\r\n                    revealerAddress == address(0)\r\n                        ? \"\"\r\n                        : StringsUpgradeable.toHexString(\r\n                            uint256(uint160(revealerAddress)),\r\n                            20\r\n                        ),\r\n                    '\"',\r\n                    \"}\"\r\n                )\r\n            );\r\n    }\r\n}\r\n\r\ninterface IArtScript {\r\n    function artScript() external pure returns (string memory);\r\n}\r\n\r\ninterface IArtInfo {\r\n    function artist() external pure returns (string memory);\r\n\r\n    function description() external pure returns (string memory);\r\n\r\n    function license() external pure returns (string memory);\r\n}\r\n\r\ninterface IFileStore {\r\n    function getFile(\r\n        string memory filename\r\n    ) external view returns (File memory file);\r\n}\r\n"
      },
      "contracts/helpers/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.13;\r\n\r\nlibrary Address {\r\n    function isContract(address account) internal view returns (bool) {\r\n        uint256 size;\r\n        assembly {\r\n            size := extcodesize(account)\r\n        }\r\n        return size > 0;\r\n    }\r\n}\r\n"
      },
      "contracts/helpers/Bytecode.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.0;\r\n\r\nlibrary Bytecode {\r\n    error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end);\r\n\r\n    /**\r\n    @notice Generate a creation code that results on a contract with `_code` as bytecode\r\n    @param _code The returning value of the resulting `creationCode`\r\n    @return creationCode (constructor) for new contract\r\n  */\r\n    function creationCodeFor(bytes memory _code)\r\n        internal\r\n        pure\r\n        returns (bytes memory)\r\n    {\r\n        /*\r\n      0x00    0x63         0x63XXXXXX  PUSH4 _code.length  size\r\n      0x01    0x80         0x80        DUP1                size size\r\n      0x02    0x60         0x600e      PUSH1 14            14 size size\r\n      0x03    0x60         0x6000      PUSH1 00            0 14 size size\r\n      0x04    0x39         0x39        CODECOPY            size\r\n      0x05    0x60         0x6000      PUSH1 00            0 size\r\n      0x06    0xf3         0xf3        RETURN\r\n      <CODE>\r\n    */\r\n\r\n        return\r\n            abi.encodePacked(\r\n                hex\"63\",\r\n                uint32(_code.length),\r\n                hex\"80_60_0E_60_00_39_60_00_F3\",\r\n                _code\r\n            );\r\n    }\r\n\r\n    /**\r\n    @notice Returns the size of the code on a given address\r\n    @param _addr Address that may or may not contain code\r\n    @return size of the code on the given `_addr`\r\n  */\r\n    function codeSize(address _addr) internal view returns (uint256 size) {\r\n        assembly {\r\n            size := extcodesize(_addr)\r\n        }\r\n    }\r\n\r\n    /**\r\n    @notice Returns the code of a given address\r\n    @dev It will fail if `_end < _start`\r\n    @param _addr Address that may or may not contain code\r\n    @param _start number of bytes of code to skip on read\r\n    @param _end index before which to end extraction\r\n    @return oCode read from `_addr` deployed bytecode\r\n\r\n    Forked from: https://gist.github.com/KardanovIR/fe98661df9338c842b4a30306d507fbd\r\n  */\r\n    function codeAt(\r\n        address _addr,\r\n        uint256 _start,\r\n        uint256 _end\r\n    ) internal view returns (bytes memory oCode) {\r\n        uint256 csize = codeSize(_addr);\r\n        if (csize == 0) return bytes(\"\");\r\n\r\n        if (_start > csize) return bytes(\"\");\r\n        if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end);\r\n\r\n        unchecked {\r\n            uint256 reqSize = _end - _start;\r\n            uint256 maxSize = csize - _start;\r\n\r\n            uint256 size = maxSize < reqSize ? maxSize : reqSize;\r\n\r\n            assembly {\r\n                // allocate output byte array - this could also be done without assembly\r\n                // by using o_code = new bytes(size)\r\n                oCode := mload(0x40)\r\n                // new \"memory end\" including padding\r\n                mstore(\r\n                    0x40,\r\n                    add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f)))\r\n                )\r\n                // store length in memory\r\n                mstore(oCode, size)\r\n                // actually retrieve the code, this needs assembly\r\n                extcodecopy(_addr, add(oCode, 0x20), _start, size)\r\n            }\r\n        }\r\n    }\r\n}\r\n"
      },
      "contracts/helpers/ERC721EnumerableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.8.13;\r\n\r\nimport \"./ERC721Upgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721EnumerableUpgradeable.sol\";\r\n\r\n/**\r\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds\r\n * enumerability of all the token ids in the contract as well as all token ids owned by each\r\n * account but rips out the core of the gas-wasting processing that comes from OpenZeppelin.\r\n */\r\nabstract contract ERC721EnumerableUpgradeable is\r\n    ERC721Upgradeable,\r\n    IERC721EnumerableUpgradeable\r\n{\r\n    /**\r\n     * @dev See {IERC165-supportsInterface}.\r\n     */\r\n    function supportsInterface(bytes4 interfaceId)\r\n        public\r\n        view\r\n        virtual\r\n        override(IERC165Upgradeable, ERC721Upgradeable)\r\n        returns (bool)\r\n    {\r\n        return\r\n            interfaceId == type(IERC721EnumerableUpgradeable).interfaceId ||\r\n            super.supportsInterface(interfaceId);\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721Enumerable-totalSupply}.\r\n     */\r\n    function totalSupply() public view virtual override returns (uint256) {\r\n        return _owners.length;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721Enumerable-tokenByIndex}.\r\n     */\r\n    function tokenByIndex(uint256 index)\r\n        public\r\n        view\r\n        virtual\r\n        override\r\n        returns (uint256)\r\n    {\r\n        require(\r\n            index < _owners.length,\r\n            \"ERC721Enumerable: global index out of bounds\"\r\n        );\r\n        return index;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\r\n     */\r\n    function tokenOfOwnerByIndex(address owner, uint256 index)\r\n        public\r\n        view\r\n        virtual\r\n        override\r\n        returns (uint256 tokenId)\r\n    {\r\n        require(\r\n            index < balanceOf(owner),\r\n            \"ERC721Enumerable: owner index out of bounds\"\r\n        );\r\n\r\n        uint256 count;\r\n        for (uint256 i; i < _owners.length; i++) {\r\n            if (owner == _owners[i]) {\r\n                if (count == index) return i;\r\n                else count++;\r\n            }\r\n        }\r\n\r\n        revert(\"ERC721Enumerable: owner index out of bounds\");\r\n    }\r\n}\r\n"
      },
      "contracts/helpers/ERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.8.13;\r\n\r\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\";\r\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\r\nimport \"./Address.sol\";\r\n\r\nabstract contract ERC721Upgradeable is\r\n    ContextUpgradeable,\r\n    ERC165Upgradeable,\r\n    IERC721Upgradeable,\r\n    IERC721MetadataUpgradeable\r\n{\r\n    using Address for address;\r\n    using StringsUpgradeable for uint256;\r\n\r\n    string private _name;\r\n    string private _symbol;\r\n\r\n    // Mapping from token ID to owner address\r\n    address[] internal _owners;\r\n\r\n    mapping(uint256 => address) private _tokenApprovals;\r\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\r\n\r\n    function __ERC721_init(\r\n        string memory name_,\r\n        string memory symbol_\r\n    ) internal onlyInitializing {\r\n        __ERC721_init_unchained(name_, symbol_);\r\n    }\r\n\r\n    function __ERC721_init_unchained(\r\n        string memory name_,\r\n        string memory symbol_\r\n    ) internal onlyInitializing {\r\n        _name = name_;\r\n        _symbol = symbol_;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC165-supportsInterface}.\r\n     */\r\n    function supportsInterface(\r\n        bytes4 interfaceId\r\n    )\r\n        public\r\n        view\r\n        virtual\r\n        override(ERC165Upgradeable, IERC165Upgradeable)\r\n        returns (bool)\r\n    {\r\n        return\r\n            interfaceId == type(IERC721Upgradeable).interfaceId ||\r\n            interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\r\n            super.supportsInterface(interfaceId);\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-balanceOf}.\r\n     */\r\n    function balanceOf(\r\n        address owner\r\n    ) public view virtual override returns (uint256) {\r\n        require(\r\n            owner != address(0),\r\n            \"ERC721: balance query for the zero address\"\r\n        );\r\n\r\n        uint256 count;\r\n        for (uint256 i; i < _owners.length; ++i) {\r\n            if (owner == _owners[i]) ++count;\r\n        }\r\n        return count;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-ownerOf}.\r\n     */\r\n    function ownerOf(\r\n        uint256 tokenId\r\n    ) public view virtual override returns (address) {\r\n        address owner = _owners[tokenId];\r\n        require(\r\n            owner != address(0),\r\n            \"ERC721: owner query for nonexistent token\"\r\n        );\r\n        return owner;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721Metadata-name}.\r\n     */\r\n    function name() public view virtual override returns (string memory) {\r\n        return _name;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721Metadata-symbol}.\r\n     */\r\n    function symbol() public view virtual override returns (string memory) {\r\n        return _symbol;\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-approve}.\r\n     */\r\n    function approve(address to, uint256 tokenId) public virtual override {\r\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\r\n        require(to != owner, \"ERC721: approval to current owner\");\r\n\r\n        require(\r\n            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\r\n            \"ERC721: approve caller is not owner nor approved for all\"\r\n        );\r\n\r\n        _approve(to, tokenId);\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-getApproved}.\r\n     */\r\n    function getApproved(\r\n        uint256 tokenId\r\n    ) public view virtual override returns (address) {\r\n        require(\r\n            _exists(tokenId),\r\n            \"ERC721: approved query for nonexistent token\"\r\n        );\r\n\r\n        return _tokenApprovals[tokenId];\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-setApprovalForAll}.\r\n     */\r\n    function setApprovalForAll(\r\n        address operator,\r\n        bool approved\r\n    ) public virtual override {\r\n        require(operator != _msgSender(), \"ERC721: approve to caller\");\r\n\r\n        _operatorApprovals[_msgSender()][operator] = approved;\r\n        emit ApprovalForAll(_msgSender(), operator, approved);\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-isApprovedForAll}.\r\n     */\r\n    function isApprovedForAll(\r\n        address owner,\r\n        address operator\r\n    ) public view virtual override returns (bool) {\r\n        return _operatorApprovals[owner][operator];\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-transferFrom}.\r\n     */\r\n    function transferFrom(\r\n        address from,\r\n        address to,\r\n        uint256 tokenId\r\n    ) public virtual override {\r\n        //solhint-disable-next-line max-line-length\r\n        require(\r\n            _isApprovedOrOwner(_msgSender(), tokenId),\r\n            \"ERC721: transfer caller is not owner nor approved\"\r\n        );\r\n\r\n        _transfer(from, to, tokenId);\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-safeTransferFrom}.\r\n     */\r\n    function safeTransferFrom(\r\n        address from,\r\n        address to,\r\n        uint256 tokenId\r\n    ) public virtual override {\r\n        safeTransferFrom(from, to, tokenId, \"\");\r\n    }\r\n\r\n    /**\r\n     * @dev See {IERC721-safeTransferFrom}.\r\n     */\r\n    function safeTransferFrom(\r\n        address from,\r\n        address to,\r\n        uint256 tokenId,\r\n        bytes memory _data\r\n    ) public virtual override {\r\n        require(\r\n            _isApprovedOrOwner(_msgSender(), tokenId),\r\n            \"ERC721: transfer caller is not owner nor approved\"\r\n        );\r\n        _safeTransfer(from, to, tokenId, _data);\r\n    }\r\n\r\n    /**\r\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\r\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\r\n     *\r\n     * `_data` is additional data, it has no specified format and it is sent in call to `to`.\r\n     *\r\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\r\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `from` cannot be the zero address.\r\n     * - `to` cannot be the zero address.\r\n     * - `tokenId` token must exist and be owned by `from`.\r\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function _safeTransfer(\r\n        address from,\r\n        address to,\r\n        uint256 tokenId,\r\n        bytes memory _data\r\n    ) internal virtual {\r\n        _transfer(from, to, tokenId);\r\n        require(\r\n            _checkOnERC721Received(from, to, tokenId, _data),\r\n            \"ERC721: transfer to non ERC721Receiver implementer\"\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @dev Returns whether `tokenId` exists.\r\n     *\r\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\r\n     *\r\n     * Tokens start existing when they are minted (`_mint`),\r\n     * and stop existing when they are burned (`_burn`).\r\n     */\r\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\r\n        return tokenId < _owners.length && _owners[tokenId] != address(0);\r\n    }\r\n\r\n    /**\r\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `tokenId` must exist.\r\n     */\r\n    function _isApprovedOrOwner(\r\n        address spender,\r\n        uint256 tokenId\r\n    ) internal view virtual returns (bool) {\r\n        require(\r\n            _exists(tokenId),\r\n            \"ERC721: operator query for nonexistent token\"\r\n        );\r\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\r\n        return (spender == owner ||\r\n            getApproved(tokenId) == spender ||\r\n            isApprovedForAll(owner, spender));\r\n    }\r\n\r\n    /**\r\n     * @dev Safely mints `tokenId` and transfers it to `to`.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `tokenId` must not exist.\r\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function _safeMint(address to, uint256 tokenId) internal virtual {\r\n        _safeMint(to, tokenId, \"\");\r\n    }\r\n\r\n    /**\r\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\r\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\r\n     */\r\n    function _safeMint(\r\n        address to,\r\n        uint256 tokenId,\r\n        bytes memory _data\r\n    ) internal virtual {\r\n        _mint(to, tokenId);\r\n        require(\r\n            _checkOnERC721Received(address(0), to, tokenId, _data),\r\n            \"ERC721: transfer to non ERC721Receiver implementer\"\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @dev Mints `tokenId` and transfers it to `to`.\r\n     *\r\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `tokenId` must not exist.\r\n     * - `to` cannot be the zero address.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function _mint(address to, uint256 tokenId) internal virtual {\r\n        require(to != address(0), \"ERC721: mint to the zero address\");\r\n        require(!_exists(tokenId), \"ERC721: token already minted\");\r\n\r\n        _beforeTokenTransfer(address(0), to, tokenId);\r\n        _owners.push(to);\r\n\r\n        emit Transfer(address(0), to, tokenId);\r\n    }\r\n\r\n    /**\r\n     * @dev Destroys `tokenId`.\r\n     * The approval is cleared when the token is burned.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `tokenId` must exist.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function _burn(uint256 tokenId) internal virtual {\r\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\r\n\r\n        _beforeTokenTransfer(owner, address(0), tokenId);\r\n\r\n        // Clear approvals\r\n        _approve(address(0), tokenId);\r\n        _owners[tokenId] = address(0);\r\n\r\n        emit Transfer(owner, address(0), tokenId);\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers `tokenId` from `from` to `to`.\r\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\r\n     *\r\n     * Requirements:\r\n     *\r\n     * - `to` cannot be the zero address.\r\n     * - `tokenId` token must be owned by `from`.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     */\r\n    function _transfer(\r\n        address from,\r\n        address to,\r\n        uint256 tokenId\r\n    ) internal virtual {\r\n        require(\r\n            ERC721Upgradeable.ownerOf(tokenId) == from,\r\n            \"ERC721: transfer of token that is not own\"\r\n        );\r\n        require(to != address(0), \"ERC721: transfer to the zero address\");\r\n\r\n        _beforeTokenTransfer(from, to, tokenId);\r\n\r\n        // Clear approvals from the previous owner\r\n        _approve(address(0), tokenId);\r\n        _owners[tokenId] = to;\r\n\r\n        emit Transfer(from, to, tokenId);\r\n    }\r\n\r\n    /**\r\n     * @dev Approve `to` to operate on `tokenId`\r\n     *\r\n     * Emits a {Approval} event.\r\n     */\r\n    function _approve(address to, uint256 tokenId) internal virtual {\r\n        _tokenApprovals[tokenId] = to;\r\n        emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\r\n    }\r\n\r\n    /**\r\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\r\n     * The call is not executed if the target address is not a contract.\r\n     *\r\n     * @param from address representing the previous owner of the given token ID\r\n     * @param to target address that will receive the tokens\r\n     * @param tokenId uint256 ID of the token to be transferred\r\n     * @param _data bytes optional data to send along with the call\r\n     * @return bool whether the call correctly returned the expected magic value\r\n     */\r\n    function _checkOnERC721Received(\r\n        address from,\r\n        address to,\r\n        uint256 tokenId,\r\n        bytes memory _data\r\n    ) private returns (bool) {\r\n        if (to.isContract()) {\r\n            try\r\n                IERC721ReceiverUpgradeable(to).onERC721Received(\r\n                    _msgSender(),\r\n                    from,\r\n                    tokenId,\r\n                    _data\r\n                )\r\n            returns (bytes4 retval) {\r\n                return\r\n                    retval ==\r\n                    IERC721ReceiverUpgradeable.onERC721Received.selector;\r\n            } catch (bytes memory reason) {\r\n                if (reason.length == 0) {\r\n                    revert(\r\n                        \"ERC721: transfer to non ERC721Receiver implementer\"\r\n                    );\r\n                } else {\r\n                    assembly {\r\n                        revert(add(32, reason), mload(reason))\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            return true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @dev Hook that is called before any token transfer. This includes minting\r\n     * and burning.\r\n     *\r\n     * Calling conditions:\r\n     *\r\n     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\r\n     * transferred to `to`.\r\n     * - When `from` is zero, `tokenId` will be minted for `to`.\r\n     * - When `to` is zero, ``from``'s `tokenId` will be burned.\r\n     * - `from` and `to` are never both zero.\r\n     *\r\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\r\n     */\r\n    function _beforeTokenTransfer(\r\n        address from,\r\n        address to,\r\n        uint256 tokenId\r\n    ) internal virtual {}\r\n}\r\n"
      },
      "contracts/helpers/File.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.19;\r\n\r\n/**\r\n * @title EthFS File\r\n * @notice A representation of an onchain file, composed of slices of contract bytecode and utilities to construct the file contents from those slices.\r\n * @dev For best gas efficiency, it's recommended using `File.read()` as close to the output returned by the contract call as possible. Lots of gas is consumed every time a large data blob is passed between functions.\r\n */\r\n\r\n/**\r\n * @dev Represents a reference to a slice of bytecode in a contract\r\n */\r\nstruct BytecodeSlice {\r\n    address pointer;\r\n    uint32 start;\r\n    uint32 end;\r\n}\r\n\r\n/**\r\n * @dev Represents a file composed of one or more bytecode slices\r\n */\r\nstruct File {\r\n    // Total length of file contents (sum of all slice sizes). Useful when you want to use DynamicBuffer to build the file contents from the slices.\r\n    uint256 size;\r\n    BytecodeSlice[] slices;\r\n}\r\n// extend File struct with read functions\r\nusing {read} for File global;\r\nusing {readUnchecked} for File global;\r\n\r\n/**\r\n * @dev Error thrown when a slice is out of the bounds of the contract's bytecode\r\n */\r\nerror SliceOutOfBounds(\r\n    address pointer,\r\n    uint32 codeSize,\r\n    uint32 sliceStart,\r\n    uint32 sliceEnd\r\n);\r\n\r\n/**\r\n * @notice Reads the contents of a file by concatenating its slices\r\n * @param file The file to read\r\n * @return contents The concatenated contents of the file\r\n */\r\nfunction read(File memory file) view returns (string memory contents) {\r\n    BytecodeSlice[] memory slices = file.slices;\r\n    bytes4 sliceOutOfBoundsSelector = SliceOutOfBounds.selector;\r\n\r\n    assembly {\r\n        let len := mload(slices)\r\n        let size := 0x20\r\n        contents := mload(0x40)\r\n        let slice\r\n        let pointer\r\n        let start\r\n        let end\r\n        let codeSize\r\n\r\n        for {\r\n            let i := 0\r\n        } lt(i, len) {\r\n            i := add(i, 1)\r\n        } {\r\n            slice := mload(add(slices, add(0x20, mul(i, 0x20))))\r\n            pointer := mload(slice)\r\n            start := mload(add(slice, 0x20))\r\n            end := mload(add(slice, 0x40))\r\n\r\n            codeSize := extcodesize(pointer)\r\n            if gt(end, codeSize) {\r\n                mstore(0x00, sliceOutOfBoundsSelector)\r\n                mstore(0x04, pointer)\r\n                mstore(0x24, codeSize)\r\n                mstore(0x44, start)\r\n                mstore(0x64, end)\r\n                revert(0x00, 0x84)\r\n            }\r\n\r\n            extcodecopy(pointer, add(contents, size), start, sub(end, start))\r\n            size := add(size, sub(end, start))\r\n        }\r\n\r\n        // update contents size\r\n        mstore(contents, sub(size, 0x20))\r\n        // store contents\r\n        mstore(0x40, add(contents, and(add(size, 0x1f), not(0x1f))))\r\n    }\r\n}\r\n\r\n/**\r\n * @notice Reads the contents of a file without reverting on unreadable/invalid slices. Skips any slices that are out of bounds or invalid. Useful if you are composing contract bytecode where a contract can still selfdestruct (which would result in an invalid slice) and want to avoid reverts but still output potentially \"corrupted\" file contents (due to missing data).\r\n * @param file The file to read\r\n * @return contents The concatenated contents of the file, skipping invalid slices\r\n */\r\nfunction readUnchecked(File memory file) view returns (string memory contents) {\r\n    BytecodeSlice[] memory slices = file.slices;\r\n\r\n    assembly {\r\n        let len := mload(slices)\r\n        let size := 0x20\r\n        contents := mload(0x40)\r\n        let slice\r\n        let pointer\r\n        let start\r\n        let end\r\n        let codeSize\r\n\r\n        for {\r\n            let i := 0\r\n        } lt(i, len) {\r\n            i := add(i, 1)\r\n        } {\r\n            slice := mload(add(slices, add(0x20, mul(i, 0x20))))\r\n            pointer := mload(slice)\r\n            start := mload(add(slice, 0x20))\r\n            end := mload(add(slice, 0x40))\r\n\r\n            codeSize := extcodesize(pointer)\r\n            if lt(end, codeSize) {\r\n                extcodecopy(\r\n                    pointer,\r\n                    add(contents, size),\r\n                    start,\r\n                    sub(end, start)\r\n                )\r\n                size := add(size, sub(end, start))\r\n            }\r\n        }\r\n\r\n        // update contents size\r\n        mstore(contents, sub(size, 0x20))\r\n        // store contents\r\n        mstore(0x40, add(contents, and(add(size, 0x1f), not(0x1f))))\r\n    }\r\n}\r\n"
      },
      "contracts/helpers/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\r\n\r\npragma solidity ^0.8.13;\r\n\r\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\r\n\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * By default, the owner account will be the one that deploys the contract. This\r\n * can later be changed with {transferOwnership}.\r\n *\r\n * This module is used through inheritance. It will make available the modifier\r\n * `onlyOwner`, which can be applied to your functions to restrict their use to\r\n * the owner.\r\n */\r\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\r\n    address private _owner;\r\n\r\n    event OwnershipTransferred(\r\n        address indexed previousOwner,\r\n        address indexed newOwner\r\n    );\r\n\r\n    /**\r\n     * @dev Initializes the contract setting the deployer as the initial owner.\r\n     */\r\n    function __Ownable_init(address _ownerOnInit) internal onlyInitializing {\r\n        __Ownable_init_unchained(_ownerOnInit);\r\n    }\r\n\r\n    function __Ownable_init_unchained(address _ownerOnInit)\r\n        internal\r\n        onlyInitializing\r\n    {\r\n        _transferOwnership(_ownerOnInit);\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the address of the current owner.\r\n     */\r\n    function owner() public view virtual returns (address) {\r\n        return _owner;\r\n    }\r\n\r\n    /**\r\n     * @dev Throws if called by any account other than the owner.\r\n     */\r\n    modifier onlyOwner() {\r\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\r\n        _;\r\n    }\r\n\r\n    /**\r\n     * @dev Leaves the contract without owner. It will not be possible to call\r\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n     *\r\n     * NOTE: Renouncing ownership will leave the contract without an owner,\r\n     * thereby removing any functionality that is only available to the owner.\r\n     */\r\n    function renounceOwnership() public virtual onlyOwner {\r\n        _transferOwnership(address(0));\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Can only be called by the current owner.\r\n     */\r\n    function transferOwnership(address newOwner) public virtual onlyOwner {\r\n        require(\r\n            newOwner != address(0),\r\n            \"Ownable: new owner is the zero address\"\r\n        );\r\n        _transferOwnership(newOwner);\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Internal function without access restriction.\r\n     */\r\n    function _transferOwnership(address newOwner) internal virtual {\r\n        address oldOwner = _owner;\r\n        _owner = newOwner;\r\n        emit OwnershipTransferred(oldOwner, newOwner);\r\n    }\r\n\r\n    /**\r\n     * @dev This empty reserved space is put in place to allow future versions to add new\r\n     * variables without shifting down storage in the inheritance chain.\r\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\r\n     */\r\n    uint256[49] private __gap;\r\n}\r\n"
      },
      "contracts/helpers/SSTORE2.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.19;\r\n\r\nimport \"./Bytecode.sol\";\r\n\r\nlibrary SSTORE2 {\r\n    error WriteError();\r\n\r\n    /**\r\n    @notice Stores `_data` and returns `pointer` as key for later retrieval\r\n    @dev The pointer is a contract address with `_data` as code\r\n    @param _data to be written\r\n    @return pointer Pointer to the written `_data`\r\n  */\r\n    function write(bytes memory _data) internal returns (address pointer) {\r\n        // Append 00 to _data so contract can't be called\r\n        // Build init code\r\n        bytes memory code = Bytecode.creationCodeFor(\r\n            abi.encodePacked(hex\"00\", _data)\r\n        );\r\n\r\n        // Deploy contract using create\r\n        assembly {\r\n            pointer := create(0, add(code, 32), mload(code))\r\n        }\r\n\r\n        // Address MUST be non-zero\r\n        if (pointer == address(0)) revert WriteError();\r\n    }\r\n\r\n    /**\r\n    @notice Reads the contents of the `_pointer` code as data, skips the first byte \r\n    @dev The function is intended for reading pointers generated by `write`\r\n    @param _pointer to be read\r\n    @return data read from `_pointer` contract\r\n  */\r\n    function read(address _pointer) internal view returns (bytes memory) {\r\n        return Bytecode.codeAt(_pointer, 1, type(uint256).max);\r\n    }\r\n\r\n    /**\r\n    @notice Reads the contents of the `_pointer` code as data, skips the first byte \r\n    @dev The function is intended for reading pointers generated by `write`\r\n    @param _pointer to be read\r\n    @param _start number of bytes to skip\r\n    @return data read from `_pointer` contract\r\n  */\r\n    function read(address _pointer, uint256 _start)\r\n        internal\r\n        view\r\n        returns (bytes memory)\r\n    {\r\n        return Bytecode.codeAt(_pointer, _start + 1, type(uint256).max);\r\n    }\r\n\r\n    /**\r\n    @notice Reads the contents of the `_pointer` code as data, skips the first byte \r\n    @dev The function is intended for reading pointers generated by `write`\r\n    @param _pointer to be read\r\n    @param _start number of bytes to skip\r\n    @param _end index before which to end extraction\r\n    @return data read from `_pointer` contract\r\n  */\r\n    function read(\r\n        address _pointer,\r\n        uint256 _start,\r\n        uint256 _end\r\n    ) internal view returns (bytes memory) {\r\n        return Bytecode.codeAt(_pointer, _start + 1, _end + 1);\r\n    }\r\n}\r\n"
      }
    },
    "settings": {
      "viaIR": true,
      "optimizer": {
        "enabled": true,
        "runs": 125,
        "details": {
          "yul": true
        }
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}