UNPKG

@darkeyedevelopers/natural-cron.js

Version:

Pure JavaScript library for converting natural English phrases into Cron expressions

1,044 lines (972 loc) 92.4 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.getCronString = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 'use strict'; const regexString = require('./maps').regexString; var defaultFlags = require('./maps').defaultFlags; var defaultResultCron = require('./maps').defaultResultCron; var flags = require('./maps').flags; var resultCron = require('./maps').resultCron; const tokenizeInput = require('./tokens').tokenizeInput; const getClockTime = require('./states/clocktime').getClockTime; const getDay = require('./states/day').getDay; const getFrequencyOnly = require('./states/frequency').getFrequencyOnly; const getFrequencyWith = require('./states/frequency').getFrequencyWith; const getHour = require('./states/hour').getHour; const getMonth = require('./states/month').getMonth; const getMinute = require('./states/minute').getMinute; const rangeStartState = require('./states/range').rangeStartState; const rangeEndState = require('./states/range').rangeEndState; const getYear = require('./states/year').getYear; /*callState function to match and call curresponding state function*/ function callState(token,stack,error) { let stateName = decideState(token); switch(stateName) { case "frequencyWith" : { return getFrequencyWith(token,stack,error); } break; case "frequencyOnly" : { return getFrequencyOnly(token,stack,error); } break; case "clockTime" : { return getClockTime(token,stack,error); } break; case "day" : { return getDay(token,stack,error); } break; case "minute" : { return getMinute(token,stack,error); } break; case "hour" : { return getHour(token,stack,error); } break; case "month" : { return getMonth(token,stack,error); } break; case "year" : { return getYear(token,stack,error); } break; case "rangeStart" : { return rangeStartState(token,stack,error); } break; case "rangeEnd" : { return rangeEndState(token,stack,error); } break; } return true; } /*decideState function to decide next state*/ function decideState(token) { let isFound = "decideState"; for(let key in regexString) { // TO DO: check for group let regBuilder = new RegExp(regexString[key].regextest,'ig'); if(regBuilder.test(token)) { isFound = key; break; } } return isFound; } /*getCronString fucntion to convert human readable input string to cron string*/ module.exports = function getCronString(inputString, syntaxString) { //Set default syntax string syntaxString = typeof(syntaxString) !== 'undefined' ? syntaxString : "MIN HOR DOM MON WEK YER"; //resetting map values to default flags.isRangeForDay = defaultFlags.isRangeForDay; flags.isRangeForMonth = defaultFlags.isRangeForMonth; flags.isRangeForYear = defaultFlags.isRangeForYear; flags.isRangeForHour = defaultFlags.isRangeForHour; flags.isRangeForMin = defaultFlags.isRangeForMin; resultCron.min = defaultResultCron.min; resultCron.hour = defaultResultCron.hour; resultCron.day_of_month = defaultResultCron.day_of_month; resultCron.month = defaultResultCron.month; resultCron.day_of_week = defaultResultCron.day_of_week; resultCron.year = defaultResultCron.year; //Stack to store temperory states' data let stack = []; let error = ""; let tokens = tokenizeInput(inputString); if(tokens == null) { error+="Please enter human readable rules !\n"; } let notEndState = true; for(let i=0; notEndState && i<tokens.length;i++) { notEndState = callState(tokens[i],stack,error); } if(notEndState == false) { return "ERROR:"+error + "\t\t" + syntaxString.replace("MIN",resultCron.min).replace("HOR",resultCron.hour).replace("DOM",resultCron.day_of_month).replace("MON",resultCron.month).replace("WEK",resultCron.day_of_week).replace("YER",resultCron.year); } else { return syntaxString.replace("MIN",resultCron.min).replace("HOR",resultCron.hour).replace("DOM",resultCron.day_of_month).replace("MON",resultCron.month).replace("WEK",resultCron.day_of_week).replace("YER",resultCron.year); } } },{"./maps":2,"./states/clocktime":3,"./states/day":4,"./states/frequency":5,"./states/hour":6,"./states/minute":7,"./states/month":8,"./states/range":9,"./states/year":10,"./tokens":11}],2:[function(require,module,exports){ 'use strict'; //regexString json var regexString = { every : { "regextest" : "^(every|each|all|entire)$" }, clockTime : { //https://regexr.com/3qqbn "regextest" : "^([0-9]+:)?[0-9]+ *(AM|PM)$|^([0-9]+:[0-9]+)$|(noon|midnight)", //https://regexr.com/3qqbt "regexexec" : [ "^[0-9]+", ":[0-9]+", "pm", "am", "(noon|midnight)" ] }, year : { "regextest" : "((years|year)|([0-9]{4}[0-9]*(( ?and)?,? ?))+)", "regexexec" : [ "^(years|year)$", "[0-9]*", "^[0-9]{4}$" ] }, frequencyWith : { "regextest" : "^[0-9]+(th|nd|rd|st)$" }, frequencyOnly : { "regextest" : "^[0-9]+$", "regexexec" : "^[0-9]+" }, minute : { "regextest" : "(minutes|minute|mins|min)", "regexexec" : [ "^(minutes|minute|mins|min)$" ] }, hour : { "regextest" : "(hour|hrs|hours)", "regexexec" : [ "^(hour|hrs|hours)$" ] }, day : { //https://regexr.com/3qqc3 "regextest" : "^((days|day)|(((monday|tuesday|wednesday|thursday|friday|saturday|sunday|WEEKEND|MON|TUE|WED|THU|FRI|SAT|SUN)( ?and)?,? ?)+))$", "regexexec" : [ "^(day|days)$", "(MON|TUE|WED|THU|FRI|SAT|SUN|WEEKEND)" ] }, month : { //https://regexr.com/3r1na "regextest" : "^((months|month)|(((january|february|march|april|may|june|july|august|september|october|november|december|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEPT|OCT|NOV|DEC)( ?and)?,? ?)+))$", "regexexec" : [ "^(month|months)$", "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEPT|OCT|NOV|DEC)" ] }, rangeStart : { "regextest" : "(between|starting|start)" , }, rangeEnd : { "regextest" : "(to|through|ending|end|and)" , }, tokenising : { "regexexec" : "(hour|hrs|hours)|(minutes|minute|mins|min)|((months|month)|(((january|february|march|april|may|june|july|august|september|october|november|december|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEPT|OCT|NOV|DEC)( ?and)?,? ?)+))|[0-9]+(th|nd|rd|st)|(([0-9]+:)?[0-9]+( +)?(AM|PM))|([0-9]+:[0-9]+)|(noon|midnight)|((days|day)|(((monday|tuesday|wednesday|thursday|friday|saturday|sunday|WEEKEND|MON|TUE|WED|THU|FRI|SAT|SUN)( ?and)?,? ?)+))|(([0-9]{4}[0-9]*(( ?and)?,? ?))+)|([0-9]+)|(to|through|ending|end|and)|(between|starting|start)" } } var defaultFlags = { "isRangeForDay" : false, "isRangeForMonth" : false, "isRangeForYear" : false, "isRangeForHour" : false, "isRangeForMin" : false }; var defaultResultCron = { "min" : "*", "hour" : "*", "day_of_month" : "*", "month" : "*", "day_of_week" : "?", "year" : "*" }; var flags = { "isRangeForDay" : defaultFlags.isRangeForDay, "isRangeForMonth" : defaultFlags.isRangeForMonth, "isRangeForYear" : defaultFlags.isRangeForYear, "isRangeForHour" : defaultFlags.isRangeForHour, "isRangeForMin" : defaultFlags.isRangeForMin }; var resultCron = { "min" : defaultResultCron.min, "hour" : defaultResultCron.hour, "day_of_month" : defaultResultCron.day_of_month, "month" : defaultResultCron.month, "day_of_week" : defaultResultCron.day_of_week, "year" : defaultResultCron.year }; module.exports = { regexString, defaultFlags, defaultResultCron, flags, resultCron } },{}],3:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*clockTime function to parse and store frequency value without nth*/ function getClockTime(token,stack,error) { //retrive hours from clocktime let regBuilder = new RegExp(regexString.clockTime.regexexec[0]); let str = token.match(regBuilder); let hour,min; if(str != null && str.length > 0) { hour = parseInt(str[0]); } else { hour = 0; } //retrive minutes from clockTime regBuilder = new RegExp(regexString.clockTime.regexexec[1]); str = regBuilder.exec(token); if(str != null && str.length > 0) { if(str[0].indexOf(':')!=-1) { min = parseInt(str[0].slice(str[0].indexOf(':')+1)); if(min >= 60) { error +=" please enter correct minutes !"; return false; } } else { min = 0; } } else { min = 0; } //check for increment of hour by 12 for PM let regBuilderPM = new RegExp(regexString.clockTime.regexexec[2],'ig'); let regBuilderAM = new RegExp(regexString.clockTime.regexexec[3],'ig'); if(regBuilderPM.test(token)) { if(hour < 12) { hour+=12; } else if(hour > 12 ){ error +=" please correct the time before PM !"; return false; } } else if(regBuilderAM.test(token)){ if(hour == 12) { hour = 0; } else if(hour > 12 ){ error +=" please correct the time before AM !"; return false; } } regBuilder = new RegExp(regexString.clockTime.regexexec[4],'ig'); if(regBuilder.test(token)) { str = token.match(regBuilder); if(str == "noon") { hour = 12; min = 0; } else { hour = 0; min = 0; } } // TO DO: checked=>Test==? let topElement = stack[stack.length-1]; if(topElement != null) { //Check if already a range is defined if(flags.isRangeForHour == true || flags.isRangeForMin == true) { error +=" already set for range expressions, seperate into two crons!"; return false; } if(topElement.ownerState == "rangeStart") { topElement.hour.start = hour; topElement.min.start = min; stack.pop(); stack.push(topElement); return true; } else if(topElement.ownerState == "rangeEnd") { if(topElement.hour == hour) { topElement.min.end = min; resultCron.min = topElement.min.start + "-"+topElement.min.end; //flags.isRangeForHour = true; return true; } else { topElement.hour.end = hour; resultCron.hour = topElement.hour.start + "-"+topElement.hour.end; //flags.isRangeForMin = true; return true; } stack.pop(); return true; } } let stackElement = { "ownerState" : "clockTime", "hour" : hour, "min" : min }; resultCron.min = min; if(resultCron.hour != "*" && resultCron.hour != "") resultCron.hour += ","+hour; else resultCron.hour = hour; stack.push(stackElement); return true; } module.exports = { getClockTime }; },{"../maps":2}],4:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*getDay function to parse days*/ function getDay(token,stack,error) { // TO DO: check for group let regBuilder = new RegExp(regexString.day.regexexec[0],"ig"); let value = ""; // check for word day,days if(regBuilder.test(token)) { let topElement = stack[stack.length-1]; resultCron.day_of_week = "?"; if(topElement == null) { topElement = { 'frequency' : "*" }; } else if(topElement.ownerState == "frequencyOnly") { resultCron.day_of_month = "0/"+topElement.frequency; stack.pop(); } else if(topElement.ownerState == "frequencyWith") { resultCron.day_of_month = ""+topElement.frequency; stack.pop(); } else { resultCron.day_of_month = "*"; } } // check for values of days between [MON-SUN] else { regBuilder = new RegExp(regexString.day.regexexec[1],"ig"); let matches = token.match(regBuilder); if(matches!=null && matches.length != 0) { resultCron.day_of_week = ""; for(let i=0; i<matches.length; i++) { matches[i] = matches[i].toUpperCase(); } // TO DO: check let topElement = stack[stack.length-1]; if(matches.length == 1 && topElement != null) { //Check if already a range is defined if(flags.isRangeForDay == true) { error +=" already set for range expressions, seperate into two crons!"; return false; } stack.pop(); if(topElement.ownerState == "rangeStart") { topElement.day.start = matches[0]; stack.push(topElement); return true; } else if(topElement.ownerState == "rangeEnd") { topElement.day.end = matches[0]; resultCron.day_of_week = topElement.day.start + "-"+topElement.day.end; resultCron.day_of_month = "?"; //flags.isRangeForDay = true; return true; } } if(matches.includes('MON') && !resultCron.day_of_week.includes('MON')) resultCron.day_of_week += "MON,"; if(matches.includes('TUE') && !resultCron.day_of_week.includes('TUE')) resultCron.day_of_week += "TUE,"; if(matches.includes('WED') && !resultCron.day_of_week.includes('WED')) resultCron.day_of_week += "WED,"; if(matches.includes('THU') && !resultCron.day_of_week.includes('THU')) resultCron.day_of_week += "THU,"; if(matches.includes('FRI') && !resultCron.day_of_week.includes('FRI')) resultCron.day_of_week += "FRI,"; if(matches.includes('SAT') && !resultCron.day_of_week.includes('SAT')) resultCron.day_of_week += "SAT,"; if(matches.includes('SUN') && !resultCron.day_of_week.includes('SUN')) resultCron.day_of_week += "SUN,"; if(matches.includes('WEEKEND') && !resultCron.day_of_week.includes('SAT')) resultCron.day_of_week += "SAT,"; if(matches.includes('WEEKEND') && !resultCron.day_of_week.includes('SUN')) resultCron.day_of_week += "SUN,"; // removed extra comma resultCron.day_of_week = resultCron.day_of_week.slice(0,-1); resultCron.day_of_month = "?"; value = ""+resultCron.day_of_week; } else { // TO DO: provide in future. but for NOW error error +=" In unresolved state at 2;Day !"; return false; } } let stackElement = { "ownerState" : "day", "day_of_week" : resultCron.day_of_week, "day_of_month" : resultCron.day_of_month }; stack.push(stackElement); return true; } module.exports = { getDay }; },{"../maps":2}],5:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*frequencyOnly function to parse and store frequency value without nth*/ function getFrequencyOnly(token,stack,error) { let freq = parseInt(token); if(isNaN(token)) { error +=" token is not number in frequency only !"; return false; } if(stack.length > 0 && stack[stack.length - 1].ownerState=="rangeEnd") { let topElement = stack[stack.length - 1]; stack.pop(); topElement.frequency.end = freq; stack.push(topElement); return true; } else if(stack.length > 0 && stack[stack.length - 1].ownerState=="rangeStart") { let topElement = stack[stack.length - 1]; stack.pop(); topElement.frequency.start = freq; stack.push(topElement); return true; } let stackElement = { "ownerState" : "frequencyOnly", "frequency" : freq }; stack.push(stackElement); return true; } /*frequencyWith function to parse and store frequency value with nth*/ function getFrequencyWith(token,stack,error) { // TO DO: check for group let regBuilder = new RegExp(regexString.frequencyOnly.regexexec,"ig"); let freq = regBuilder.exec(token); let value = parseInt(freq); if(isNaN(value)) { error +=" token is not number in frequency with !"; return false; } if(stack.length!=0 && stack[stack.length - 1].ownerState=="rangeEnd") { let topElement = stack[stack.length - 1]; stack.pop(); topElement.frequency.end = ""+value; stack.push(topElement); return true; } else if(stack.length > 0 && stack[stack.length - 1].ownerState=="rangeStart") { let topElement = stack[stack.length - 1]; stack.pop(); topElement.frequency.start = ""+value; stack.push(topElement); return true; } let stackElement = { "ownerState" : "frequencyWith", "frequency" : value }; stack.push(stackElement); return true; } module.exports = { getFrequencyOnly, getFrequencyWith }; },{"../maps":2}],6:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*getHour function to parse Hours*/ function getHour(token,stack,error) { // TO DO: check for group let regBuilder = new RegExp(regexString.hour.regexexec[0],"ig"); let value; // check for word hours if(regBuilder.test(token)) { let topElement = stack[stack.length-1]; if(topElement == null) { topElement = { 'frequency' : "*" }; } else if(topElement.ownerState == "frequencyOnly") { value = topElement.frequency; resultCron.hour = "0/"+topElement.frequency; stack.pop(); } else if(topElement.ownerState == "frequencyWith") { //hour already set if(resultCron.hour != "*" && resultCron.hour != "") resultCron.hour += ","+topElement.frequency; else resultCron.hour = ""+topElement.frequency; value = resultCron.hour; stack.pop(); } else { if(flags.isRangeForHour == true) { error +=" already set for range expressions, seperate into two crons!"; return false; } else if(topElement.ownerState == "rangeStart") { topElement.hour.start = topElement.frequency.start; topElement.frequency.start = ""; stack.pop(); stack.push(topElement); return true; } else if(topElement.ownerState == "rangeEnd") { stack.pop(); topElement.hour.start = topElement.frequency.start; topElement.hour.end = topElement.frequency.end; topElement.frequency.end = ""; resultCron.hour = topElement.hour.start + "-"+topElement.hour.end; //flags.isRangeForHour = true; return true; } } } let stackElement = { "ownerState" : "hour", "hour" : value }; stack.push(stackElement); return true; } module.exports = { getHour }; },{"../maps":2}],7:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*getMinute function to parse minutes*/ function getMinute(token,stack,error) { // TO DO: check for group let regBuilder = new RegExp(regexString.minute.regexexec[0],"ig"); let value; // check for word minute,minutes if(regBuilder.test(token)) { let topElement = stack[stack.length-1]; if(topElement == null) { topElement = { 'frequency' : "*" }; } else if(topElement.ownerState == "frequencyOnly") { value = topElement.frequency; resultCron.min = "0/"+topElement.frequency; stack.pop(); } else if(topElement.ownerState == "frequencyWith") { value = topElement.frequency; resultCron.min = ""+topElement.frequency; stack.pop(); } else { if(flags.isRangeForMinute == true) { error +=" already set for range expressions, seperate into two crons!"; return false; } else if(topElement.ownerState == "rangeStart") { topElement.min.start = topElement.frequency.start; topElement.frequency.start = ""; stack.pop(); stack.push(topElement); return true; } else if(topElement.ownerState == "rangeEnd") { stack.pop(); topElement.min.start = topElement.frequency.start; topElement.min.end = topElement.frequency.end; topElement.frequency.end = ""; resultCron.min = topElement.min.start + "-"+topElement.min.end; //flags.isRangeForMin = true; return true; } } } let stackElement = { "ownerState" : "minute", "min" : value }; stack.push(stackElement); return true; } module.exports = { getMinute }; },{"../maps":2}],8:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*getMonth function to parse months*/ function getMonth(token,stack,error) { // TO DO: check for group let regBuilder = new RegExp(regexString.month.regexexec[0],"ig"); let value = ""; // check for word month,months if(regBuilder.test(token)) { let topElement = stack[stack.length-1]; if(topElement == null) { topElement = { 'frequency' : "*" }; } if(topElement.ownerState == "frequencyOnly") { resultCron.month = "0/"+topElement.frequency; stack.pop(); } else if(topElement.ownerState == "frequencyWith") { resultCron.month = ""+topElement.frequency; stack.pop(); } else { resultCron.month = "*"; } } // check for values of months between [JAN-DEC] else { // TO DO: check for group regBuilder = new RegExp(regexString.month.regexexec[1],"ig"); let matches = token.match(regBuilder); if(matches!=null && matches.length != 0) { resultCron.month = ""; for(let i=0; i<matches.length; i++) { matches[i] = matches[i].toUpperCase(); } // TO DO: check let topElement = stack[stack.length-1]; if(matches.length == 1 && topElement != null) { //Check if already a range is defined if(flags.isRangeForMonth == true) { error +=" already set for range expressions, seperate into two crons!"; return false; } stack.pop(); if(topElement.ownerState == "frequencyOnly") { resultCron.day_of_month = topElement.frequency; } else if(topElement.ownerState == "frequencyWith") { resultCron.day_of_month = topElement.frequency; } else if(topElement.ownerState == "rangeStart") { topElement.month.start = matches[0]; stack.push(topElement); return true; } else if(topElement.ownerState == "rangeEnd") { if(topElement.frequency.end != "") { resultCron.day_of_week = "?"; resultCron.day_of_month = topElement.frequency.start + "-" + topElement.frequency.end; } topElement.month.end = matches[0]; resultCron.month = topElement.month.start + "-"+topElement.month.end; //flags.isRangeForMonth = true; return true; } } if(matches.includes('JAN') && !resultCron.month.includes('JAN')) resultCron.month += "JAN,"; if(matches.includes('FEB') && !resultCron.month.includes('FEB')) resultCron.month += "FEB,"; if(matches.includes('MAR') && !resultCron.month.includes('MAR')) resultCron.month += "MAR,"; if(matches.includes('APR') && !resultCron.month.includes('APR')) resultCron.month += "APR,"; if(matches.includes('MAY') && !resultCron.month.includes('MAY')) resultCron.month += "MAY,"; if(matches.includes('JUN') && !resultCron.month.includes('JUN')) resultCron.month += "JUN,"; if(matches.includes('JUL') && !resultCron.month.includes('JUL')) resultCron.month += "JUL,"; if(matches.includes('AUG') && !resultCron.month.includes('AUG')) resultCron.month += "AUG,"; if(matches.includes('SEPT') && !resultCron.month.includes('SEPT')) resultCron.month += "SEPT,"; if(matches.includes('OCT') && !resultCron.month.includes('OCT')) resultCron.month += "OCT,"; if(matches.includes('NOV') && !resultCron.month.includes('NOV')) resultCron.month += "NOV,"; if(matches.includes('DEC') && !resultCron.month.includes('DEC')) resultCron.month += "DEC,"; // removed extra comma resultCron.month = resultCron.month.slice(0,-1); value = ""+resultCron.month; } else { // TO DO: provide in future. but for NOW error error +=" In unresolved state at 2;Month !"; return false; } } let stackElement = { "ownerState" : "month", "month" : resultCron.month, }; stack.push(stackElement); return true; } module.exports = { getMonth }; },{"../maps":2}],9:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*rangeStartState function for range input*/ function rangeStartState(token,stack,error) { if(flags.isRangeForDay || flags.isRangeForMin || flags.isRangeForMonth || flags.isRangeForYear || flags.isRangeForHour) { error +=" already range expressions !"; return false; } let stackElement = { "ownerState" : "rangeStart", "min": { "start" : "", "end" : "" }, "hour" : { "start" : "", "end" : "" }, "day" : { "start" : "", "end" : "" }, "month" : { "start" : "", "end" : "" }, "year" : { "start" : "", "end" : "" }, "frequency" : { "start" : "", "end" : "" } }; stack.push(stackElement); return true; } /*rangeEndState function for range input*/ function rangeEndState(token,stack,error) { let stackElement = { "ownerState" : "rangeEnd", "min": { "start" : "", "end" : "" }, "hour" : { "start" : "", "end" : "" }, "day" : { "start" : "", "end" : "" }, "month" : { "start" : "", "end" : "" }, "year" : { "start" : "", "end" : "" }, "frequency" : { "start" : "", "end" : "" } }; let topElement = stack[stack.length-1]; if(topElement!=null) { switch(topElement.ownerState) { case "frequencyWith" : case "frequencyOnly" : { stack.pop(); stackElement.frequency.start = topElement.frequency; stackElement.ownerState = "rangeEnd"; stack.push(stackElement) } break; case "clockTime" : { stack.pop(); stackElement.hour.start = topElement.hour; stackElement.min.start = topElement.min; stackElement.ownerState = "rangeEnd"; stack.push(stackElement) } break; case "rangeStart" : { stack.pop(); topElement.ownerState = "rangeEnd"; stack.push(topElement); } break; case "month" : { stack.pop(); stackElement.ownerState = "rangeEnd"; stackElement.month.start = topElement.month; stack.push(stackElement); } break; case "minute" : { stack.pop(); stackElement.ownerState = "rangeEnd"; stackElement.frequency.start = stackElement.min.start = topElement.min; stack.push(stackElement); } break; case "hour" : { stack.pop(); stackElement.ownerState = "rangeEnd"; stackElement.frequency.start = stackElement.hour.start = topElement.hour; stack.push(stackElement); } break; case "day" : { stack.pop(); stackElement.ownerState = "rangeEnd"; stackElement.day.start = topElement.day_of_week; stack.push(stackElement); } break; case "year" : { stack.pop(); stackElement.ownerState = "rangeEnd"; stackElement.year.start = topElement.year; stack.push(stackElement); } break; } } return true; } module.exports = { rangeStartState, rangeEndState }; },{"../maps":2}],10:[function(require,module,exports){ 'use strict'; const regexString = require('../maps').regexString; var flags = require('../maps').flags; var resultCron = require('../maps').resultCron; /*getYear function to parse year*/ function getYear(token,stack,error) { // TO DO: check for group let regBuilder = new RegExp(regexString.year.regexexec[0],"ig"); let value = ""; // check for word year,years if(regBuilder.test(token)) { let topElement = stack[stack.length-1]; resultCron.year = "?"; if(topElement == null) { topElement = { 'frequency' : "*" }; } else if(topElement.ownerState == "frequencyOnly") { resultCron.year = "0/"+topElement.frequency; stack.pop(); } else if(topElement.ownerState == "frequencyWith") { resultCron.year = ""+topElement.frequency; stack.pop(); } else { resultCron.year = "*"; } } // check for values of years else { regBuilder = new RegExp(regexString.year.regexexec[1],"ig"); let regBuilder2 = new RegExp(regexString.year.regexexec[2],"ig") let matches = token.match(regBuilder); let exactMatches = new Set(); for(let i=0; i<matches.length; i++) { if(regBuilder2.test(matches[i])) { exactMatches.add(matches[i].match(regBuilder2)[0]); } } // TO DO: check let topElement = stack[stack.length-1]; if(exactMatches.size == 1 && topElement != null) { //Check if already a range is defined if(flags.isRangeForYear == true) { error +=" Cannot handle multiple range expressions, seperate into two crons!"; return false; } if(topElement.ownerState == "rangeStart") { topElement.year.start = Array.from(exactMatches)[0]; stack.pop(); stack.push(topElement); return true; } else if(topElement.ownerState == "rangeEnd") { topElement.year.end = Array.from(exactMatches)[0]; stack.pop(); resultCron.year = topElement.year.start + "-"+topElement.year.end; //flags.isRangeForYear = true; return true; } } if(exactMatches.size != 0) { resultCron.year = ""; exactMatches.forEach(function(yr){ resultCron.year += yr+","; }); // removed extra comma resultCron.year = resultCron.year.slice(0,-1); value = ""+resultCron.year; } else { // TO DO: provide in future. but for NOW error error +=" In unresolved state at 2;year !"; return false; } } let stackElement = { "ownerState" : "year", "year" : resultCron.year }; stack.push(stackElement); return true; } module.exports = { getYear }; },{"../maps":2}],11:[function(require,module,exports){ 'use strict'; const regexString = require('./maps').regexString; var flags = require('./maps').flags; var resultCron = require('./maps').resultCron; //tokenizeInput function to seperate out all tokens module.exports = { tokenizeInput : function(inputString){ let regBuilder = new RegExp(regexString.tokenising.regexexec,"ig"); let matches = inputString.match(regBuilder); if(matches == null || matches.length == 0 ) { return []; } for(let i=0;i<matches.length;i++) { matches[i] = (matches[i]+"").trim(); } return matches; } }; },{"./maps":2}]},{},[1])(1) }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy5udm0vdmVyc2lvbnMvbm9kZS92MTIuMTkuMC9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImluZGV4LmpzIiwibWFwcy5qcyIsInN0YXRlcy9jbG9ja3RpbWUuanMiLCJzdGF0ZXMvZGF5LmpzIiwic3RhdGVzL2ZyZXF1ZW5jeS5qcyIsInN0YXRlcy9ob3VyLmpzIiwic3RhdGVzL21pbnV0ZS5qcyIsInN0YXRlcy9tb250aC5qcyIsInN0YXRlcy9yYW5nZS5qcyIsInN0YXRlcy95ZWFyLmpzIiwidG9rZW5zLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIndXNlIHN0cmljdCc7XG5jb25zdCByZWdleFN0cmluZyA9IHJlcXVpcmUoJy4vbWFwcycpLnJlZ2V4U3RyaW5nO1xudmFyIGRlZmF1bHRGbGFncyA9IHJlcXVpcmUoJy4vbWFwcycpLmRlZmF1bHRGbGFncztcbnZhciBkZWZhdWx0UmVzdWx0Q3JvbiA9IHJlcXVpcmUoJy4vbWFwcycpLmRlZmF1bHRSZXN1bHRDcm9uO1xudmFyIGZsYWdzID0gcmVxdWlyZSgnLi9tYXBzJykuZmxhZ3M7XG52YXIgcmVzdWx0Q3JvbiA9IHJlcXVpcmUoJy4vbWFwcycpLnJlc3VsdENyb247XG5cbmNvbnN0IHRva2VuaXplSW5wdXQgID0gcmVxdWlyZSgnLi90b2tlbnMnKS50b2tlbml6ZUlucHV0O1xuY29uc3QgZ2V0Q2xvY2tUaW1lICA9IHJlcXVpcmUoJy4vc3RhdGVzL2Nsb2NrdGltZScpLmdldENsb2NrVGltZTtcbmNvbnN0IGdldERheSAgPSByZXF1aXJlKCcuL3N0YXRlcy9kYXknKS5nZXREYXk7XG5jb25zdCBnZXRGcmVxdWVuY3lPbmx5ICA9IHJlcXVpcmUoJy4vc3RhdGVzL2ZyZXF1ZW5jeScpLmdldEZyZXF1ZW5jeU9ubHk7XG5jb25zdCBnZXRGcmVxdWVuY3lXaXRoICA9IHJlcXVpcmUoJy4vc3RhdGVzL2ZyZXF1ZW5jeScpLmdldEZyZXF1ZW5jeVdpdGg7XG5jb25zdCBnZXRIb3VyICA9IHJlcXVpcmUoJy4vc3RhdGVzL2hvdXInKS5nZXRIb3VyO1xuY29uc3QgZ2V0TW9udGggID0gcmVxdWlyZSgnLi9zdGF0ZXMvbW9udGgnKS5nZXRNb250aDtcbmNvbnN0IGdldE1pbnV0ZSAgPSByZXF1aXJlKCcuL3N0YXRlcy9taW51dGUnKS5nZXRNaW51dGU7XG5jb25zdCByYW5nZVN0YXJ0U3RhdGUgID0gcmVxdWlyZSgnLi9zdGF0ZXMvcmFuZ2UnKS5yYW5nZVN0YXJ0U3RhdGU7XG5jb25zdCByYW5nZUVuZFN0YXRlICA9IHJlcXVpcmUoJy4vc3RhdGVzL3JhbmdlJykucmFuZ2VFbmRTdGF0ZTtcbmNvbnN0IGdldFllYXIgID0gcmVxdWlyZSgnLi9zdGF0ZXMveWVhcicpLmdldFllYXI7XG5cbi8qY2FsbFN0YXRlIGZ1bmN0aW9uIHRvIG1hdGNoIGFuZCBjYWxsIGN1cnJlc3BvbmRpbmcgc3RhdGUgZnVuY3Rpb24qL1xuZnVuY3Rpb24gY2FsbFN0YXRlKHRva2VuLHN0YWNrLGVycm9yKSB7XG4gICAgbGV0IHN0YXRlTmFtZSA9IGRlY2lkZVN0YXRlKHRva2VuKTtcblxuICAgIHN3aXRjaChzdGF0ZU5hbWUpIHtcbiAgICAgICAgY2FzZSBcImZyZXF1ZW5jeVdpdGhcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXRGcmVxdWVuY3lXaXRoKHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImZyZXF1ZW5jeU9ubHlcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXRGcmVxdWVuY3lPbmx5KHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImNsb2NrVGltZVwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIGdldENsb2NrVGltZSh0b2tlbixzdGFjayxlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJkYXlcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXREYXkodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwibWludXRlXCIgOiB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0TWludXRlKHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImhvdXJcIiA6IHtcbiAgICAgICAgICAgIHJldHVybiBnZXRIb3VyKHRva2VuLHN0YWNrLGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIm1vbnRoXCIgOiB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0TW9udGgodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwieWVhclwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIGdldFllYXIodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwicmFuZ2VTdGFydFwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIHJhbmdlU3RhcnRTdGF0ZSh0b2tlbixzdGFjayxlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJyYW5nZUVuZFwiIDoge1xuICAgICAgICAgICAgcmV0dXJuIHJhbmdlRW5kU3RhdGUodG9rZW4sc3RhY2ssZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLypkZWNpZGVTdGF0ZSBmdW5jdGlvbiB0byBkZWNpZGUgbmV4dCBzdGF0ZSovXG5mdW5jdGlvbiBkZWNpZGVTdGF0ZSh0b2tlbikge1xuICAgIGxldCBpc0ZvdW5kID0gXCJkZWNpZGVTdGF0ZVwiO1xuICAgIGZvcihsZXQga2V5IGluIHJlZ2V4U3RyaW5nKSB7XG4gICAgICAgIC8vIFRPIERPOiBjaGVjayBmb3IgZ3JvdXBcbiAgICAgICAgbGV0IHJlZ0J1aWxkZXIgPSBuZXcgUmVnRXhwKHJlZ2V4U3RyaW5nW2tleV0ucmVnZXh0ZXN0LCdpZycpO1xuICAgICAgICBpZihyZWdCdWlsZGVyLnRlc3QodG9rZW4pKSB7XG4gICAgICAgICAgICBpc0ZvdW5kID0ga2V5O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlzRm91bmQ7XG59XG5cbi8qZ2V0Q3JvblN0cmluZyBmdWNudGlvbiB0byBjb252ZXJ0IGh1bWFuIHJlYWRhYmxlIGlucHV0IHN0cmluZyB0byBjcm9uIHN0cmluZyovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldENyb25TdHJpbmcoaW5wdXRTdHJpbmcsIHN5bnRheFN0cmluZykge1xuICAgIC8vU2V0IGRlZmF1bHQgc3ludGF4IHN0cmluZ1xuICAgIHN5bnRheFN0cmluZyA9IHR5cGVvZihzeW50YXhTdHJpbmcpICE9PSAndW5kZWZpbmVkJyA/IHN5bnRheFN0cmluZyA6IFwiTUlOIEhPUiBET00gTU9OIFdFSyBZRVJcIjtcblxuICAgIC8vcmVzZXR0aW5nIG1hcCB2YWx1ZXMgdG8gZGVmYXVsdFxuICAgIGZsYWdzLmlzUmFuZ2VGb3JEYXkgPSBkZWZhdWx0RmxhZ3MuaXNSYW5nZUZvckRheTtcbiAgICBmbGFncy5pc1JhbmdlRm9yTW9udGggPSBkZWZhdWx0RmxhZ3MuaXNSYW5nZUZvck1vbnRoO1xuICAgIGZsYWdzLmlzUmFuZ2VGb3JZZWFyID0gZGVmYXVsdEZsYWdzLmlzUmFuZ2VGb3JZZWFyO1xuICAgIGZsYWdzLmlzUmFuZ2VGb3JIb3VyID0gZGVmYXVsdEZsYWdzLmlzUmFuZ2VGb3JIb3VyO1xuICAgIGZsYWdzLmlzUmFuZ2VGb3JNaW4gPSBkZWZhdWx0RmxhZ3MuaXNSYW5nZUZvck1pbjtcblxuICAgIHJlc3VsdENyb24ubWluID0gZGVmYXVsdFJlc3VsdENyb24ubWluO1xuICAgIHJlc3VsdENyb24uaG91ciA9IGRlZmF1bHRSZXN1bHRDcm9uLmhvdXI7XG4gICAgcmVzdWx0Q3Jvbi5kYXlfb2ZfbW9udGggPSBkZWZhdWx0UmVzdWx0Q3Jvbi5kYXlfb2ZfbW9udGg7XG4gICAgcmVzdWx0Q3Jvbi5tb250aCA9IGRlZmF1bHRSZXN1bHRDcm9uLm1vbnRoO1xuICAgIHJlc3VsdENyb24uZGF5X29mX3dlZWsgPSBkZWZhdWx0UmVzdWx0Q3Jvbi5kYXlfb2Zfd2VlaztcbiAgICByZXN1bHRDcm9uLnllYXIgPSBkZWZhdWx0UmVzdWx0Q3Jvbi55ZWFyO1xuXG4gICAgLy9TdGFjayB0byBzdG9yZSB0ZW1wZXJvcnkgc3RhdGVzJyBkYXRhXG4gICAgbGV0IHN0YWNrID0gW107XG4gICAgbGV0IGVycm9yID0gXCJcIjtcbiAgICBsZXQgdG9rZW5zID0gdG9rZW5pemVJbnB1dChpbnB1dFN0cmluZyk7XG5cbiAgICBpZih0b2tlbnMgPT0gbnVsbCkge1xuICAgICAgICBlcnJvcis9XCJQbGVhc2UgZW50ZXIgaHVtYW4gcmVhZGFibGUgcnVsZXMgIVxcblwiO1xuICAgIH1cbiAgICBsZXQgbm90RW5kU3RhdGUgPSB0cnVlO1xuICAgIGZvcihsZXQgaT0wOyBub3RFbmRTdGF0ZSAmJiBpPHRva2Vucy5sZW5ndGg7aSsrKSB7XG4gICAgICAgIG5vdEVuZFN0YXRlID0gY2FsbFN0YXRlKHRva2Vuc1tpXSxzdGFjayxlcnJvcik7XG4gICAgfVxuICAgIGlmKG5vdEVuZFN0YXRlID09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBcIkVSUk9SOlwiK2Vycm9yICsgXCJcXHRcXHRcIiArIHN5bnRheFN0cmluZy5yZXBsYWNlKFwiTUlOXCIscmVzdWx0Q3Jvbi5taW4pLnJlcGxhY2UoXCJIT1JcIixyZXN1bHRDcm9uLmhvdXIpLnJlcGxhY2UoXCJET01cIixyZXN1bHRDcm9uLmRheV9vZl9tb250aCkucmVwbGFjZShcIk1PTlwiLHJlc3VsdENyb24ubW9udGgpLnJlcGxhY2UoXCJXRUtcIixyZXN1bHRDcm9uLmRheV9vZl93ZWVrKS5yZXBsYWNlKFwiWUVSXCIscmVzdWx0Q3Jvbi55ZWFyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBzeW50YXhTdHJpbmcucmVwbGFjZShcIk1JTlwiLHJlc3VsdENyb24ubWluKS5yZXBsYWNlKFwiSE9SXCIscmVzdWx0Q3Jvbi5ob3VyKS5yZXBsYWNlKFwiRE9NXCIscmVzdWx0Q3Jvbi