contract HailDraconis is  ERC721 , PointList {

    using SafeMath for uint256;

    // Maximum supply of tokens
    uint256 public constant MAX_SUPPLY = 10000;
    uint256 public SALE_START_TIMESTAMP = 1611846000;

    mapping(address => uint256) public claimed;

    constructor() ERC721("Hail Draconis", "HAIL") public {
    }

    /**
     * @dev Mint a token
     */
    function mintToken(uint256 numTokens) public {
        require(numTokens > 0 && numTokens <= 20, "You can only mint between 1 and 20 tokens at a time");
        require(block.timestamp >= SALE_START_TIMESTAMP, "Claim has not started");

        uint256 newBalance = claimed[msg.sender].add(numTokens);
        require(hasPoints(msg.sender, newBalance));
        for (uint i = 0; i < numTokens; i++) {
            uint tokenId = totalSupply() ;
            require(tokenId < MAX_SUPPLY, "Cannot mint more tokens than the maximum limit");
            _safeMint(msg.sender, tokenId);
        }
        claimed[msg.sender] = newBalance;
    }

    /**
     * @dev Set the Base URI of tokens
     */
    function setBaseURI(string memory baseURI_) public  {
        require(
            hasAdminRole(msg.sender),
            "setBaseURI: Sender must be admin"
        );
        _setBaseURI(baseURI_);
    }


    /**
     * @dev See {IERC721Metadata-tokenURI}.
     * overides concatenated baseURI + tokenID in standard erc721 contract so that all tokens have the same token URI
     */
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        return baseURI();
    }

    /**
     * @dev Withdraw ether from the contract
     */
    function withdraw() public  {
        require(
            hasAdminRole(msg.sender),
            "withdraw: Sender must be admin"
        );
        payable(msg.sender).transfer(address(this).balance);
    }
}
function withdraw() public  {
        require(
            hasAdminRole(msg.sender),
            "withdraw: Sender must be admin"
        );
        payable(msg.sender).transfer(address(this).balance);
    }
/**
 * @dev Withdraw ether from the contract
 */