contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
	// Token name
	string private _name;

	// Token symbol
	string private _symbol;

	// Base URI
	string private _baseURI;

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

	/*
 	* 	bytes4(keccak256('name()')) == 0x06fdde03
 	* 	bytes4(keccak256('symbol()')) == 0x95d89b41
 	* 	bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
 	*
 	* 	=> 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
 	*/
	bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

	/**
 	* @dev Constructor function
 	*/
	constructor (string memory name, string memory symbol) public {
    	_name = name;
    	_symbol = symbol;

    	// register the supported interfaces to conform to ERC721 via ERC165
    	_registerInterface(_INTERFACE_ID_ERC721_METADATA);
	}

	/**
 	* @dev Gets the token name.
 	* @return string representing the token name
 	*/
	function name() external view returns (string memory) {
    	return _name;
	}

	/**
 	* @dev Gets the token symbol.
 	* @return string representing the token symbol
 	*/
	function symbol() external view returns (string memory) {
    	return _symbol;
	}

	/**
 	* @dev Returns the URI for a given token ID. May return an empty string.
 	*
 	* If the token's URI is non-empty and a base URI was set (via
 	* {_setBaseURI}), it will be added to the token ID's URI as a prefix.
 	*
 	* Reverts if the token ID does not exist.
 	*/
	function tokenURI(uint256 tokenId) external view returns (string memory) {
    	require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

    	string memory _tokenURI = _tokenURIs[tokenId];

    	// Even if there is a base URI, it is only appended to non-empty token-specific URIs
    	if (bytes(_tokenURI).length == 0) {
        	return "";
    	} else {
        	// abi.encodePacked is being used to concatenate strings
        	return string(abi.encodePacked(_baseURI, _tokenURI));
    	}
	}

	/**
 	* @dev Internal function to set the token URI for a given token.
 	*
 	* Reverts if the token ID does not exist.
 	*
 	* TIP: if all token IDs share a prefix (e.g. if your URIs look like
 	* `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
 	* it and save gas.
 	*/
	function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
    	require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
    	_tokenURIs[tokenId] = _tokenURI;
	}

	/**
 	* @dev Internal function to set the base URI for all token IDs. It is
 	* automatically added as a prefix to the value returned in {tokenURI}.
 	*
 	* _Available since v2.5.0._
 	*/
	function _setBaseURI(string memory baseURI) internal {
    	_baseURI = baseURI;
	}

	/**
	* @dev Returns the base URI set via {_setBaseURI}. This will be
	* automatically added as a preffix in {tokenURI} to each token's URI, when
	* they are non-empty.
	*
	* _Available since v2.5.0._
	*/
	function baseURI() external view returns (string memory) {
    	return _baseURI;
	}

	/**
 	* @dev Internal function to burn a specific token.
 	* Reverts if the token does not exist.
 	* Deprecated, use _burn(uint256) instead.
 	* @param owner owner of the token to burn
 	* @param tokenId uint256 ID of the token being burned by the msg.sender
 	*/
	function _burn(address owner, uint256 tokenId) internal {
    	super._burn(owner, tokenId);

    	// Clear metadata (if any)
    	if (bytes(_tokenURIs[tokenId]).length != 0) {
        	delete _tokenURIs[tokenId];
    	}
	}
}
function _burn(address owner, uint256 tokenId) internal {
   	super._burn(owner, tokenId);

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

/**
 	* @dev Internal function to burn a specific token.
 	* Reverts if the token does not exist.
 	* Deprecated, use _burn(uint256) instead.
 	* @param owner owner of the token to burn
 	* @param tokenId uint256 ID of the token being burned by the msg.sender
 	*/