abstract contract ERC721URIStorageUpgradeable is
    Initializable,
    ERC721Upgradeable
{
    struct Metadata {
        string name;
        string ipfsimage;
        string ipfsmetadata;
    }
    mapping(uint256 => Metadata) token_id;

    function __ERC721URIStorage_init() internal initializer {
        __Context_init_unchained();
        __ERC165_init_unchained();
        __ERC721URIStorage_init_unchained();
    }

    function __ERC721URIStorage_init_unchained() internal initializer {}

    using StringsUpgradeable for uint256;
    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory ipfsmetadata)
    {
        require(
            _exists(tokenId),
            "ERC721URIStorage: URI query for nonexistent token"
        );
        Metadata memory date = token_id[tokenId];
        ipfsmetadata = date.ipfsmetadata;
        return ipfsmetadata;
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI)
        internal
        virtual
    {
        require(
            _exists(tokenId),
            "ERC721URIStorage: URI set of nonexistent token"
        );
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }

    uint256[49] private __gap;
}
/**
 * @dev ERC721 token with storage based token URI management.
 */
function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override
    returns (string memory ipfsmetadata)
{
    require(
        _exists(tokenId),
        "ERC721URIStorage: URI query for nonexistent token"
    );
    Metadata memory date = token_id[tokenId];
    ipfsmetadata = date.ipfsmetadata;
    return ipfsmetadata;
}

/**
 * @dev See {IERC721Metadata-tokenURI}.
 */