import {UrlSegment} from '@angular/router'; import {ValidatorFn, Validators} from "@angular/forms"; export class Dates { public static yearMin = 1800; public static yearMax = (new Date().getFullYear()) + 10; public static currentYear = (new Date().getFullYear()); public static isValidYear(yearString, yearMin=this.yearMin, yearMax=this.yearMax) { // First check for the pattern if (!/^\d{4}$/.test(yearString)) return false; var year = parseInt(yearString, 10); // Check the ranges of month and year if (year < yearMin || year > yearMax) return false; return true; } //format YYYY-MM-DD public static isValidDate(dateString: string) { // First check for the pattern if (!/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(dateString)) return false; // Parse the date parts to integers var parts = dateString.split("-"); var day = parseInt(parts[2], 10); var month = parseInt(parts[1], 10); var year = parseInt(parts[0], 10); if (!this.isValidYear(parts[0])) { return false; } // Check the ranges of month and year if (month == 0 || month > 12) return false; var monthLength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // Adjust for leap years if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) monthLength[1] = 29; // Check the range of the day return day > 0 && day <= monthLength[month - 1]; } public static getDateToday(): Date { var myDate = new Date(); return myDate; } public static getDateToString(myDate: Date): string { var date: string = myDate.getFullYear() + "-"; date += ((myDate.getMonth() + 1) < 10) ? "0" + (myDate.getMonth() + 1) : (myDate.getMonth() + 1); date += "-"; date += (myDate.getDate() < 10) ? "0" + myDate.getDate() : myDate.getDate(); return date; } public static getDateXMonthsAgo(x: number): Date { var myDate = new Date(); myDate.setMonth(myDate.getMonth() - x); return myDate; } public static getDateXYearsAgo(x: number): Date { var myDate = new Date(); myDate.setFullYear(myDate.getFullYear() - x); return myDate; } public static getDateFromString(date: string): Date { var myDate = new Date(); myDate.setFullYear(+date.substring(0, 4)); myDate.setMonth(((date.length > 5) ? (+date.substring(5, 7) - 1) : (0))); myDate.setDate(((date.length > 8) ? (+date.substring(8, 11)) : (1))); return myDate; } public static getDate(dateString: string): Date { let date = new Date(dateString); if (Object.prototype.toString.call(date) === "[object Date]") { if (isNaN(date.getTime())) { return null; } else { return date; } } else { return null; } } } export class DOI { public static getDOIsFromString(str: string): string[] { return Identifier.getDOIsFromString(str); } public static isValidDOI(str: string): boolean { return Identifier.isValidDOI(str); } } export class Identifier { class: "doi" | "pmc" | "pmid" | "handle" | "ORCID" = null; id: string; public static getDOIsFromString(str: string): string[] { var DOIs: string[] = []; var words: string[] = str.split(" "); for (var i = 0; i < words.length; i++) { if (DOI.isValidDOI(words[i]) && DOIs.indexOf(words[i]) == -1) { DOIs.push(words[i]); } } return DOIs; } public static getIdentifiersFromString(str: string): Identifier[] { let identifiers: Identifier[] = []; let words: string[] = str.split(" "); for (let id of words) { if (id.length > 0) { let identifier: Identifier = this.getIdentifierFromString(id); if(identifier) { identifiers.push(identifier); } } } return identifiers; } public static getIdentifierFromString(pid: string): Identifier { if (Identifier.isValidDOI(pid)) { return {"class": "doi", "id": pid}; } else if (Identifier.isValidORCID(pid)) { return {"class": "ORCID", "id": pid}; } else if (Identifier.isValidPMCID(pid)) { return {"class": "pmc", "id": pid}; } else if (Identifier.isValidPMID(pid)) { return {"class": "pmid", "id": pid}; } else if (Identifier.isValidHANDLE(pid)) { return {"class": "handle", "id": pid}; } return null; } public static isValidDOI(str: string): boolean { var exp1 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])\S)+)\b/g var exp2 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])[[:graph:]])+)\b/g return (str.match(exp1) != null || str.match(exp2) != null); } public static isValidORCID(str: string): boolean { let exp = /\b\d{4}-\d{4}-\d{4}-(\d{3}X|\d{4})\b/g; return str.match(exp) != null; } public static isValidPMID(str: string): boolean { let exp = /^\d*$/g; return str.match(exp) != null; } public static isValidPMCID(str: string): boolean { let exp = /^(PMC\d{7})$/g; return str.match(exp) != null; } public static isValidHANDLE(str: string): boolean { let exp = /^[0-9a-zA-Z-]*\/[0-9a-zA-Z-]*$/g; return str.match(exp) != null; } } export class StringUtils { public static urlPrefix(url: string): string { if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//")) { return ""; } else { return "//"; } } public static quote(params: string): string { return '"' + params + '"'; } public static unquote(params: string): string { if (params.length > 2 && (params[0] == '"' && params[params.length - 1] == '"') || (params[0] == "'" && params[params.length - 1] == "'")) { params = params.substring(1, params.length - 1); } return params; } public static URIEncode(params: string): string { return encodeURIComponent(params); } public static URIDecode(params: string): string { return decodeURIComponent(params); } public static b64DecodeUnicode(str) { return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); } private emailValidator(email: any): boolean { return !!email.match("^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$"); } public static urlValidator(): ValidatorFn { return Validators.pattern('https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.' + '[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.' + '[a-zA-Z0-9]+\.[^\s]{2,}'); } public static sliceString(mystr, size: number): string { const sliced = String(mystr).substr(0, size); return sliced + (String(mystr).length > size ? '...' : ''); } /** * Splits a text to words base on a list of separators. Returns the words of the text including the separators. * DO NOT TOUCH, IT WORKS * * @param text * @param separators */ public static split(text: string, separators: string[]): string[] { let words: (string | string[])[] = [text]; separators.forEach(separator => { words.forEach((word, index) => { if (typeof word === "string" && separators.indexOf(word) === -1) { let tokens: string[] = word.split(separator).filter(value => value !== ''); if (tokens.length > 1) { words[index] = []; tokens.forEach((token, i) => { ((words[index])).push(token); if (i !== (tokens.length - 1)) { ((words[index])).push(separator); } }); } } }); words = [].concat.apply([], words); }); return words; } public static capitalize(value: string): string { return value.charAt(0).toUpperCase() + value.slice(1); } /** * Checks if a text contains a word */ public static containsWord(text: string, word: string):boolean { return (text && text.toLowerCase().includes(word)); } public static URLSegmentsToPath(segments: UrlSegment[]): string { let path = ''; segments.forEach(route => { path += '/' + route.path; }) return path; } public static isEuropeanCountry(country: string) { let countries = ["Albania", "Andorra", "Armenia", "Austria", "Azerbaijan", "Belarus", "Belgium", "Bosnia and Herzegovina", "Bulgaria", "Croatia", "Cyprus", "Czech Republic", "Denmark", "Estonia", "Finland", "France", "Georgia", "Germany", "Greece", "Hungary", "Iceland", "Ireland", "Italy", "Kosovo", "Latvia", "Liechtenstein", "Lithuania", "Luxembourg", "Macedonia", "Malta", "Moldova", "Monaco", "Montenegro", "The Netherlands", "Norway", "Poland", "Portugal", "Romania", "Russia", "San Marino", "Serbia", "Slovakia", "Slovenia", "Spain", "Sweden", "Switzerland", "Turkey", "Ukraine", "United Kingdom", "Vatican City", ]; return (country && countries.indexOf(country) != -1); } public static isOpenAIREID(id:string){ if(id && id.length == 46){ let exp1 = /^.{12}::([0-9a-z]{32})$/g; return (id.match(exp1)!=null); } return false; } }