abstract contract ERC721URIStorage is ERC721 {
    using Strings 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)
    // {
    //     require(
    //         _exists(tokenId),
    //         "ERC721URIStorage: URI query for nonexistent token"
    //     );

    //     string memory _tokenURI = _tokenURIs[tokenId];
    //     string memory base = _baseURI();

    //     // If there is no base URI, return the token URI.
    //     if (bytes(base).length == 0) {
    //         return _tokenURI;
    //     }

    //     // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
    //     if (bytes(_tokenURI).length > 0) {
    //         return string(abi.encodePacked(base, _tokenURI));
    //     }

    //     return super.tokenURI(tokenId);
    // }

    function _setBaseURI(string memory newBaseTokenURI) private {
        _baseTokenURI = newBaseTokenURI;
    }

    /**
     * @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];
        }
    }
}
/**
 * @dev ERC721 token with storage based token URI management.
 */
function _setBaseURI(string memory newBaseTokenURI) private {
    _baseTokenURI = newBaseTokenURI;
}

// function tokenURI(uint256 tokenId)
//     public
//     view
//     virtual
//     override
//     returns (string memory)
// {
//     require(
//         _exists(tokenId),
//         "ERC721URIStorage: URI query for nonexistent token"
//     );
//     string memory _tokenURI = _tokenURIs[tokenId];
//     string memory base = _baseURI();
//     // If there is no base URI, return the token URI.
//     if (bytes(base).length == 0) {
//         return _tokenURI;
//     }
//     // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
//     if (bytes(_tokenURI).length > 0) {
//         return string(abi.encodePacked(base, _tokenURI));
//     }
//     return super.tokenURI(tokenId);
// }