contract Ways is ERC721, ERC721Enumerable, ERC721URIStorage, ERC721Burnable, Ownable {

    uint256 public nextTokenId = 1;
    uint256 public CAP = 1000;

    constructor() ERC721("1000Ways", "WAYS") {}

    function _baseURI() internal pure override returns (string memory) {
        return "https://ipfs.io/ipfs/";
    }

    function safeMint(address to, string memory ipfsHash) public onlyOwner {
        require(nextTokenId <= CAP, "Ways: cap exceeded");
        uint256 tokenId = nextTokenId++;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, ipfsHash);
    }

    function safeMintArray(address to, string[] memory _ipfsHashArr) public onlyOwner {
        for (uint256 i = 0; i < _ipfsHashArr.length; i++) {
            safeMint(to, _ipfsHashArr[i]);
        }
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        override(ERC721, ERC721Enumerable){
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
    internal
    override(ERC721, ERC721Enumerable){
    super._beforeTokenTransfer(from, to, tokenId);
}

// The following functions are overrides required by Solidity.