mermaid
Version:
Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.
4 lines • 146 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/isoWeek.js", "../../../../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/customParseFormat.js", "../../../../../node_modules/.pnpm/dayjs@1.11.13/node_modules/dayjs/plugin/advancedFormat.js", "../../../src/diagrams/gantt/parser/gantt.jison", "../../../src/diagrams/gantt/ganttDb.js", "../../../src/diagrams/gantt/ganttRenderer.js", "../../../src/diagrams/gantt/styles.js", "../../../src/diagrams/gantt/ganttDiagram.ts"],
"sourcesContent": ["!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_isoWeek=t()}(this,(function(){\"use strict\";var e=\"day\";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf(\"year\"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,\"week\")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return\"isoweek\"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf(\"day\"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf(\"day\"):n.bind(this)(e,t)}}}));", "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_customParseFormat=t()}(this,(function(){\"use strict\";var e={LTS:\"h:mm:ss A\",LT:\"h:mm A\",L:\"MM/DD/YYYY\",LL:\"MMMM D, YYYY\",LLL:\"MMMM D, YYYY h:mm A\",LLLL:\"dddd, MMMM D, YYYY h:mm A\"},t=/(\\[[^[]*\\])|([-_:/.,()\\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\\d/,r=/\\d\\d/,i=/\\d\\d?/,o=/\\d*[^-_:/,()\\s\\d]+/,s={},a=function(e){return(e=+e)+(e>68?1900:2e3)};var f=function(e){return function(t){this[e]=+t}},h=[/[+-]\\d\\d:?(\\d\\d)?|Z/,function(e){(this.zone||(this.zone={})).offset=function(e){if(!e)return 0;if(\"Z\"===e)return 0;var t=e.match(/([+-]|\\d\\d)/g),n=60*t[1]+(+t[2]||0);return 0===n?0:\"+\"===t[0]?-n:n}(e)}],u=function(e){var t=s[e];return t&&(t.indexOf?t:t.s.concat(t.f))},d=function(e,t){var n,r=s.meridiem;if(r){for(var i=1;i<=24;i+=1)if(e.indexOf(r(i,0,t))>-1){n=i>12;break}}else n=e===(t?\"pm\":\"PM\");return n},c={A:[o,function(e){this.afternoon=d(e,!1)}],a:[o,function(e){this.afternoon=d(e,!0)}],Q:[n,function(e){this.month=3*(e-1)+1}],S:[n,function(e){this.milliseconds=100*+e}],SS:[r,function(e){this.milliseconds=10*+e}],SSS:[/\\d{3}/,function(e){this.milliseconds=+e}],s:[i,f(\"seconds\")],ss:[i,f(\"seconds\")],m:[i,f(\"minutes\")],mm:[i,f(\"minutes\")],H:[i,f(\"hours\")],h:[i,f(\"hours\")],HH:[i,f(\"hours\")],hh:[i,f(\"hours\")],D:[i,f(\"day\")],DD:[r,f(\"day\")],Do:[o,function(e){var t=s.ordinal,n=e.match(/\\d+/);if(this.day=n[0],t)for(var r=1;r<=31;r+=1)t(r).replace(/\\[|\\]/g,\"\")===e&&(this.day=r)}],w:[i,f(\"week\")],ww:[r,f(\"week\")],M:[i,f(\"month\")],MM:[r,f(\"month\")],MMM:[o,function(e){var t=u(\"months\"),n=(u(\"monthsShort\")||t.map((function(e){return e.slice(0,3)}))).indexOf(e)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[o,function(e){var t=u(\"months\").indexOf(e)+1;if(t<1)throw new Error;this.month=t%12||t}],Y:[/[+-]?\\d+/,f(\"year\")],YY:[r,function(e){this.year=a(e)}],YYYY:[/\\d{4}/,f(\"year\")],Z:h,ZZ:h};function l(n){var r,i;r=n,i=s&&s.formats;for(var o=(n=r.replace(/(\\[[^\\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var o=r&&r.toUpperCase();return n||i[r]||e[r]||i[o].replace(/(\\[[^\\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,n){return t||n.slice(1)}))}))).match(t),a=o.length,f=0;f<a;f+=1){var h=o[f],u=c[h],d=u&&u[0],l=u&&u[1];o[f]=l?{regex:d,parser:l}:h.replace(/^\\[|\\]$/g,\"\")}return function(e){for(var t={},n=0,r=0;n<a;n+=1){var i=o[n];if(\"string\"==typeof i)r+=i.length;else{var s=i.regex,f=i.parser,h=e.slice(r),u=s.exec(h)[0];f.call(t,u),e=e.replace(u,\"\")}}return function(e){var t=e.afternoon;if(void 0!==t){var n=e.hours;t?n<12&&(e.hours+=12):12===n&&(e.hours=0),delete e.afternoon}}(t),t}}return function(e,t,n){n.p.customParseFormat=!0,e&&e.parseTwoDigitYear&&(a=e.parseTwoDigitYear);var r=t.prototype,i=r.parse;r.parse=function(e){var t=e.date,r=e.utc,o=e.args;this.$u=r;var a=o[1];if(\"string\"==typeof a){var f=!0===o[2],h=!0===o[3],u=f||h,d=o[2];h&&(d=o[2]),s=this.$locale(),!f&&d&&(s=n.Ls[d]),this.$d=function(e,t,n,r){try{if([\"x\",\"X\"].indexOf(t)>-1)return new Date((\"X\"===t?1e3:1)*e);var i=l(t)(e),o=i.year,s=i.month,a=i.day,f=i.hours,h=i.minutes,u=i.seconds,d=i.milliseconds,c=i.zone,m=i.week,M=new Date,Y=a||(o||s?1:M.getDate()),p=o||M.getFullYear(),v=0;o&&!s||(v=s>0?s-1:M.getMonth());var D,w=f||0,g=h||0,y=u||0,L=d||0;return c?new Date(Date.UTC(p,v,Y,w,g,y,L+60*c.offset*1e3)):n?new Date(Date.UTC(p,v,Y,w,g,y,L)):(D=new Date(p,v,Y,w,g,y,L),m&&(D=r(D).week(m).toDate()),D)}catch(e){return new Date(\"\")}}(t,a,r,n),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&t!=this.format(a)&&(this.$d=new Date(\"\")),s={}}else if(a instanceof Array)for(var c=a.length,m=1;m<=c;m+=1){o[1]=a[m-1];var M=n.apply(this,o);if(M.isValid()){this.$d=M.$d,this.$L=M.$L,this.init();break}m===c&&(this.$d=new Date(\"\"))}else i.call(this,e)}}}));", "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_advancedFormat=t()}(this,(function(){\"use strict\";return function(e,t){var r=t.prototype,n=r.format;r.format=function(e){var t=this,r=this.$locale();if(!this.isValid())return n.bind(this)(e);var s=this.$utils(),a=(e||\"YYYY-MM-DDTHH:mm:ssZ\").replace(/\\[([^\\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(e){switch(e){case\"Q\":return Math.ceil((t.$M+1)/3);case\"Do\":return r.ordinal(t.$D);case\"gggg\":return t.weekYear();case\"GGGG\":return t.isoWeekYear();case\"wo\":return r.ordinal(t.week(),\"W\");case\"w\":case\"ww\":return s.s(t.week(),\"w\"===e?1:2,\"0\");case\"W\":case\"WW\":return s.s(t.isoWeek(),\"W\"===e?1:2,\"0\");case\"k\":case\"kk\":return s.s(String(0===t.$H?24:t.$H),\"k\"===e?1:2,\"0\");case\"X\":return Math.floor(t.$d.getTime()/1e3);case\"x\":return t.$d.getTime();case\"z\":return\"[\"+t.offsetName()+\"]\";case\"zzz\":return\"[\"+t.offsetName(\"long\")+\"]\";default:return e}}));return n.bind(this)(a)}}}));", "/* parser generated by jison 0.4.18 */\n/*\n Returns a Parser object of the following structure:\n\n Parser: {\n yy: {}\n }\n\n Parser.prototype: {\n yy: {},\n trace: function(),\n symbols_: {associative list: name ==> number},\n terminals_: {associative list: number ==> name},\n productions_: [...],\n performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),\n table: [...],\n defaultActions: {...},\n parseError: function(str, hash),\n parse: function(input),\n\n lexer: {\n EOF: 1,\n parseError: function(str, hash),\n setInput: function(input),\n input: function(),\n unput: function(str),\n more: function(),\n less: function(n),\n pastInput: function(),\n upcomingInput: function(),\n showPosition: function(),\n test_match: function(regex_match_array, rule_index),\n next: function(),\n lex: function(),\n begin: function(condition),\n popState: function(),\n _currentRules: function(),\n topState: function(),\n pushState: function(condition),\n\n options: {\n ranges: boolean (optional: true ==> token location info will include a .range[] member)\n flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)\n backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)\n },\n\n performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),\n rules: [...],\n conditions: {associative list: name ==> set},\n }\n }\n\n\n token location info (@$, _$, etc.): {\n first_line: n,\n last_line: n,\n first_column: n,\n last_column: n,\n range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)\n }\n\n\n the parseError function receives a 'hash' object with these members for lexer and parser errors: {\n text: (matched text)\n token: (the produced terminal token, if any)\n line: (yylineno)\n }\n while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {\n loc: (yylloc)\n expected: (string describing the set of expected tokens)\n recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)\n }\n*/\nvar parser = (function(){\nvar o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],$V1=[1,26],$V2=[1,27],$V3=[1,28],$V4=[1,29],$V5=[1,30],$V6=[1,31],$V7=[1,32],$V8=[1,33],$V9=[1,34],$Va=[1,9],$Vb=[1,10],$Vc=[1,11],$Vd=[1,12],$Ve=[1,13],$Vf=[1,14],$Vg=[1,15],$Vh=[1,16],$Vi=[1,19],$Vj=[1,20],$Vk=[1,21],$Vl=[1,22],$Vm=[1,23],$Vn=[1,25],$Vo=[1,35];\nvar parser = {trace: function trace () { },\nyy: {},\nsymbols_: {\"error\":2,\"start\":3,\"gantt\":4,\"document\":5,\"EOF\":6,\"line\":7,\"SPACE\":8,\"statement\":9,\"NL\":10,\"weekday\":11,\"weekday_monday\":12,\"weekday_tuesday\":13,\"weekday_wednesday\":14,\"weekday_thursday\":15,\"weekday_friday\":16,\"weekday_saturday\":17,\"weekday_sunday\":18,\"weekend\":19,\"weekend_friday\":20,\"weekend_saturday\":21,\"dateFormat\":22,\"inclusiveEndDates\":23,\"topAxis\":24,\"axisFormat\":25,\"tickInterval\":26,\"excludes\":27,\"includes\":28,\"todayMarker\":29,\"title\":30,\"acc_title\":31,\"acc_title_value\":32,\"acc_descr\":33,\"acc_descr_value\":34,\"acc_descr_multiline_value\":35,\"section\":36,\"clickStatement\":37,\"taskTxt\":38,\"taskData\":39,\"click\":40,\"callbackname\":41,\"callbackargs\":42,\"href\":43,\"clickStatementDebug\":44,\"$accept\":0,\"$end\":1},\nterminals_: {2:\"error\",4:\"gantt\",6:\"EOF\",8:\"SPACE\",10:\"NL\",12:\"weekday_monday\",13:\"weekday_tuesday\",14:\"weekday_wednesday\",15:\"weekday_thursday\",16:\"weekday_friday\",17:\"weekday_saturday\",18:\"weekday_sunday\",20:\"weekend_friday\",21:\"weekend_saturday\",22:\"dateFormat\",23:\"inclusiveEndDates\",24:\"topAxis\",25:\"axisFormat\",26:\"tickInterval\",27:\"excludes\",28:\"includes\",29:\"todayMarker\",30:\"title\",31:\"acc_title\",32:\"acc_title_value\",33:\"acc_descr\",34:\"acc_descr_value\",35:\"acc_descr_multiline_value\",36:\"section\",38:\"taskTxt\",39:\"taskData\",40:\"click\",41:\"callbackname\",42:\"callbackargs\",43:\"href\"},\nproductions_: [0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],\nperformAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {\n/* this == yyval */\n\nvar $0 = $$.length - 1;\nswitch (yystate) {\ncase 1:\n return $$[$0-1]; \nbreak;\ncase 2:\n this.$ = [] \nbreak;\ncase 3:\n$$[$0-1].push($$[$0]);this.$ = $$[$0-1]\nbreak;\ncase 4: case 5:\n this.$ = $$[$0] \nbreak;\ncase 6: case 7:\n this.$=[];\nbreak;\ncase 8:\n yy.setWeekday(\"monday\");\nbreak;\ncase 9:\n yy.setWeekday(\"tuesday\");\nbreak;\ncase 10:\n yy.setWeekday(\"wednesday\");\nbreak;\ncase 11:\n yy.setWeekday(\"thursday\");\nbreak;\ncase 12:\n yy.setWeekday(\"friday\");\nbreak;\ncase 13:\n yy.setWeekday(\"saturday\");\nbreak;\ncase 14:\n yy.setWeekday(\"sunday\");\nbreak;\ncase 15:\n yy.setWeekend(\"friday\");\nbreak;\ncase 16:\n yy.setWeekend(\"saturday\");\nbreak;\ncase 17:\nyy.setDateFormat($$[$0].substr(11));this.$=$$[$0].substr(11);\nbreak;\ncase 18:\nyy.enableInclusiveEndDates();this.$=$$[$0].substr(18);\nbreak;\ncase 19:\nyy.TopAxis();this.$=$$[$0].substr(8);\nbreak;\ncase 20:\nyy.setAxisFormat($$[$0].substr(11));this.$=$$[$0].substr(11);\nbreak;\ncase 21:\nyy.setTickInterval($$[$0].substr(13));this.$=$$[$0].substr(13);\nbreak;\ncase 22:\nyy.setExcludes($$[$0].substr(9));this.$=$$[$0].substr(9);\nbreak;\ncase 23:\nyy.setIncludes($$[$0].substr(9));this.$=$$[$0].substr(9);\nbreak;\ncase 24:\nyy.setTodayMarker($$[$0].substr(12));this.$=$$[$0].substr(12);\nbreak;\ncase 27:\nyy.setDiagramTitle($$[$0].substr(6));this.$=$$[$0].substr(6);\nbreak;\ncase 28:\n this.$=$$[$0].trim();yy.setAccTitle(this.$); \nbreak;\ncase 29: case 30:\n this.$=$$[$0].trim();yy.setAccDescription(this.$); \nbreak;\ncase 31:\n yy.addSection($$[$0].substr(8));this.$=$$[$0].substr(8); \nbreak;\ncase 33:\nyy.addTask($$[$0-1],$$[$0]);this.$='task';\nbreak;\ncase 34:\nthis.$ = $$[$0-1];yy.setClickEvent($$[$0-1], $$[$0], null);\nbreak;\ncase 35:\nthis.$ = $$[$0-2];yy.setClickEvent($$[$0-2], $$[$0-1], $$[$0]);\nbreak;\ncase 36:\nthis.$ = $$[$0-2];yy.setClickEvent($$[$0-2], $$[$0-1], null);yy.setLink($$[$0-2],$$[$0]);\nbreak;\ncase 37:\nthis.$ = $$[$0-3];yy.setClickEvent($$[$0-3], $$[$0-2], $$[$0-1]);yy.setLink($$[$0-3],$$[$0]);\nbreak;\ncase 38:\nthis.$ = $$[$0-2];yy.setClickEvent($$[$0-2], $$[$0], null);yy.setLink($$[$0-2],$$[$0-1]);\nbreak;\ncase 39:\nthis.$ = $$[$0-3];yy.setClickEvent($$[$0-3], $$[$0-1], $$[$0]);yy.setLink($$[$0-3],$$[$0-2]);\nbreak;\ncase 40:\nthis.$ = $$[$0-1];yy.setLink($$[$0-1], $$[$0]);\nbreak;\ncase 41: case 47:\nthis.$=$$[$0-1] + ' ' + $$[$0];\nbreak;\ncase 42: case 43: case 45:\nthis.$=$$[$0-2] + ' ' + $$[$0-1] + ' ' + $$[$0];\nbreak;\ncase 44: case 46:\nthis.$=$$[$0-3] + ' ' + $$[$0-2] + ' ' + $$[$0-1] + ' ' + $$[$0];\nbreak;\n}\n},\ntable: [{3:1,4:[1,2]},{1:[3]},o($V0,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:$V1,13:$V2,14:$V3,15:$V4,16:$V5,17:$V6,18:$V7,19:18,20:$V8,21:$V9,22:$Va,23:$Vb,24:$Vc,25:$Vd,26:$Ve,27:$Vf,28:$Vg,29:$Vh,30:$Vi,31:$Vj,33:$Vk,35:$Vl,36:$Vm,37:24,38:$Vn,40:$Vo},o($V0,[2,7],{1:[2,1]}),o($V0,[2,3]),{9:36,11:17,12:$V1,13:$V2,14:$V3,15:$V4,16:$V5,17:$V6,18:$V7,19:18,20:$V8,21:$V9,22:$Va,23:$Vb,24:$Vc,25:$Vd,26:$Ve,27:$Vf,28:$Vg,29:$Vh,30:$Vi,31:$Vj,33:$Vk,35:$Vl,36:$Vm,37:24,38:$Vn,40:$Vo},o($V0,[2,5]),o($V0,[2,6]),o($V0,[2,17]),o($V0,[2,18]),o($V0,[2,19]),o($V0,[2,20]),o($V0,[2,21]),o($V0,[2,22]),o($V0,[2,23]),o($V0,[2,24]),o($V0,[2,25]),o($V0,[2,26]),o($V0,[2,27]),{32:[1,37]},{34:[1,38]},o($V0,[2,30]),o($V0,[2,31]),o($V0,[2,32]),{39:[1,39]},o($V0,[2,8]),o($V0,[2,9]),o($V0,[2,10]),o($V0,[2,11]),o($V0,[2,12]),o($V0,[2,13]),o($V0,[2,14]),o($V0,[2,15]),o($V0,[2,16]),{41:[1,40],43:[1,41]},o($V0,[2,4]),o($V0,[2,28]),o($V0,[2,29]),o($V0,[2,33]),o($V0,[2,34],{42:[1,42],43:[1,43]}),o($V0,[2,40],{41:[1,44]}),o($V0,[2,35],{43:[1,45]}),o($V0,[2,36]),o($V0,[2,38],{42:[1,46]}),o($V0,[2,37]),o($V0,[2,39])],\ndefaultActions: {},\nparseError: function parseError (str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n},\nparse: function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer;\n sharedState.yy.parser = this;\n if (typeof lexer.yylloc == 'undefined') {\n lexer.yylloc = {};\n }\n var yyloc = lexer.yylloc;\n lstack.push(yyloc);\n var ranges = lexer.options && lexer.options.ranges;\n if (typeof sharedState.yy.parseError === 'function') {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n function lex() {\n var token;\n token = tstack.pop() || lexer.lex() || EOF;\n if (typeof token !== 'number') {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == 'undefined') {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === 'undefined' || !action.length || !action[0]) {\n var errStr = '';\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push('\\'' + this.terminals_[p] + '\\'');\n }\n }\n if (lexer.showPosition) {\n errStr = 'Parse error on line ' + (yylineno + 1) + ':\\n' + lexer.showPosition() + '\\nExpecting ' + expected.join(', ') + ', got \\'' + (this.terminals_[symbol] || symbol) + '\\'';\n } else {\n errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\\'' + (this.terminals_[symbol] || symbol) + '\\'');\n }\n this.parseError(errStr, {\n text: lexer.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer.yylineno,\n loc: yyloc,\n expected: expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer.yytext);\n lstack.push(lexer.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer.yyleng;\n yytext = lexer.yytext;\n yylineno = lexer.yylineno;\n yyloc = lexer.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== 'undefined') {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n}};\n\n/* generated by jison-lex 0.3.4 */\nvar lexer = (function(){\nvar lexer = ({\n\nEOF:1,\n\nparseError:function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n },\n\n// resets the lexer, sets new input\nsetInput:function (input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = '';\n this.conditionStack = ['INITIAL'];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0,0];\n }\n this.offset = 0;\n return this;\n },\n\n// consumes and returns one char from the input\ninput:function () {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n\n this._input = this._input.slice(1);\n return ch;\n },\n\n// unshifts one char (or a string) into the input\nunput:function (ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n //this.yyleng -= len;\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ?\n (lines.length === oldLines.length ? this.yylloc.first_column : 0)\n + oldLines[oldLines.length - lines.length].length - lines[0].length :\n this.yylloc.first_column - len\n };\n\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n },\n\n// When called from action, caches matched text and appends it on next action\nmore:function () {\n this._more = true;\n return this;\n },\n\n// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\nreject:function () {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n' + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n\n }\n return this;\n },\n\n// retain first n characters of the match\nless:function (n) {\n this.unput(this.match.slice(n));\n },\n\n// displays already matched input, i.e. for error messages\npastInput:function () {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\\n/g, \"\");\n },\n\n// displays upcoming input, i.e. for error messages\nupcomingInput:function () {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20-next.length);\n }\n return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\\n/g, \"\");\n },\n\n// displays the character position where the lexing error occurred, i.e. for error messages\nshowPosition:function () {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n },\n\n// test the lexed token: return FALSE when not a match, otherwise return token\ntest_match:function(match, indexed_rule) {\n var token,\n lines,\n backup;\n\n if (this.options.backtrack_lexer) {\n // save context\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ?\n lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length :\n this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n // recover context\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false; // rule action called reject() implying the next rule should be tested instead.\n }\n return false;\n },\n\n// return next match in input\nnext:function () {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n\n var token,\n match,\n tempMatch,\n index;\n if (!this._more) {\n this.yytext = '';\n this.match = '';\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue; // rule action called reject() implying a rule MISmatch.\n } else {\n // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\\n' + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n },\n\n// return next match that has a token\nlex:function lex () {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n },\n\n// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\nbegin:function begin (condition) {\n this.conditionStack.push(condition);\n },\n\n// pop the previously active lexer condition state off the condition stack\npopState:function popState () {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n },\n\n// produce the lexer rule set which is active for the currently active lexer condition state\n_currentRules:function _currentRules () {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n },\n\n// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\ntopState:function topState (n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n },\n\n// alias for begin(condition)\npushState:function pushState (condition) {\n this.begin(condition);\n },\n\n// return the number of states currently on the stack\nstateStackSize:function stateStackSize() {\n return this.conditionStack.length;\n },\noptions: {\"case-insensitive\":true},\nperformAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {\nvar YYSTATE=YY_START;\nswitch($avoiding_name_collisions) {\ncase 0: this.begin('open_directive'); return 'open_directive'; \nbreak;\ncase 1: this.begin(\"acc_title\");return 31; \nbreak;\ncase 2: this.popState(); return \"acc_title_value\"; \nbreak;\ncase 3: this.begin(\"acc_descr\");return 33; \nbreak;\ncase 4: this.popState(); return \"acc_descr_value\"; \nbreak;\ncase 5: this.begin(\"acc_descr_multiline\");\nbreak;\ncase 6: this.popState(); \nbreak;\ncase 7:return \"acc_descr_multiline_value\";\nbreak;\ncase 8:/* skip comments */\nbreak;\ncase 9:/* skip comments */\nbreak;\ncase 10:/* do nothing */\nbreak;\ncase 11:return 10;\nbreak;\ncase 12:/* skip whitespace */\nbreak;\ncase 13:/* skip comments */\nbreak;\ncase 14:this.begin(\"href\");\nbreak;\ncase 15:this.popState();\nbreak;\ncase 16:return 43;\nbreak;\ncase 17:this.begin(\"callbackname\");\nbreak;\ncase 18:this.popState();\nbreak;\ncase 19:this.popState(); this.begin(\"callbackargs\");\nbreak;\ncase 20:return 41;\nbreak;\ncase 21:this.popState();\nbreak;\ncase 22:return 42;\nbreak;\ncase 23:this.begin(\"click\");\nbreak;\ncase 24:this.popState();\nbreak;\ncase 25:return 40;\nbreak;\ncase 26:return 4;\nbreak;\ncase 27:return 22;\nbreak;\ncase 28:return 23;\nbreak;\ncase 29:return 24;\nbreak;\ncase 30:return 25;\nbreak;\ncase 31:return 26;\nbreak;\ncase 32:return 28;\nbreak;\ncase 33:return 27;\nbreak;\ncase 34:return 29;\nbreak;\ncase 35:return 12\nbreak;\ncase 36:return 13\nbreak;\ncase 37:return 14\nbreak;\ncase 38:return 15\nbreak;\ncase 39:return 16\nbreak;\ncase 40:return 17\nbreak;\ncase 41:return 18\nbreak;\ncase 42:return 20\nbreak;\ncase 43:return 21\nbreak;\ncase 44:return 'date';\nbreak;\ncase 45:return 30;\nbreak;\ncase 46:return 'accDescription'\nbreak;\ncase 47:return 36;\nbreak;\ncase 48:return 38;\nbreak;\ncase 49:return 39;\nbreak;\ncase 50:return ':';\nbreak;\ncase 51:return 6;\nbreak;\ncase 52:return 'INVALID';\nbreak;\n}\n},\nrules: [/^(?:%%\\{)/i,/^(?:accTitle\\s*:\\s*)/i,/^(?:(?!\\n||)*[^\\n]*)/i,/^(?:accDescr\\s*:\\s*)/i,/^(?:(?!\\n||)*[^\\n]*)/i,/^(?:accDescr\\s*\\{\\s*)/i,/^(?:[\\}])/i,/^(?:[^\\}]*)/i,/^(?:%%(?!\\{)*[^\\n]*)/i,/^(?:[^\\}]%%*[^\\n]*)/i,/^(?:%%*[^\\n]*[\\n]*)/i,/^(?:[\\n]+)/i,/^(?:\\s+)/i,/^(?:%[^\\n]*)/i,/^(?:href[\\s]+[\"])/i,/^(?:[\"])/i,/^(?:[^\"]*)/i,/^(?:call[\\s]+)/i,/^(?:\\([\\s]*\\))/i,/^(?:\\()/i,/^(?:[^(]*)/i,/^(?:\\))/i,/^(?:[^)]*)/i,/^(?:click[\\s]+)/i,/^(?:[\\s\\n])/i,/^(?:[^\\s\\n]*)/i,/^(?:gantt\\b)/i,/^(?:dateFormat\\s[^#\\n;]+)/i,/^(?:inclusiveEndDates\\b)/i,/^(?:topAxis\\b)/i,/^(?:axisFormat\\s[^#\\n;]+)/i,/^(?:tickInterval\\s[^#\\n;]+)/i,/^(?:includes\\s[^#\\n;]+)/i,/^(?:excludes\\s[^#\\n;]+)/i,/^(?:todayMarker\\s[^\\n;]+)/i,/^(?:weekday\\s+monday\\b)/i,/^(?:weekday\\s+tuesday\\b)/i,/^(?:weekday\\s+wednesday\\b)/i,/^(?:weekday\\s+thursday\\b)/i,/^(?:weekday\\s+friday\\b)/i,/^(?:weekday\\s+saturday\\b)/i,/^(?:weekday\\s+sunday\\b)/i,/^(?:weekend\\s+friday\\b)/i,/^(?:weekend\\s+saturday\\b)/i,/^(?:\\d\\d\\d\\d-\\d\\d-\\d\\d\\b)/i,/^(?:title\\s[^\\n]+)/i,/^(?:accDescription\\s[^#\\n;]+)/i,/^(?:section\\s[^\\n]+)/i,/^(?:[^:\\n]+)/i,/^(?::[^#\\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],\nconditions: {\"acc_descr_multiline\":{\"rules\":[6,7],\"inclusive\":false},\"acc_descr\":{\"rules\":[4],\"inclusive\":false},\"acc_title\":{\"rules\":[2],\"inclusive\":false},\"callbackargs\":{\"rules\":[21,22],\"inclusive\":false},\"callbackname\":{\"rules\":[18,19,20],\"inclusive\":false},\"href\":{\"rules\":[15,16],\"inclusive\":false},\"click\":{\"rules\":[24,25],\"inclusive\":false},\"INITIAL\":{\"rules\":[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52],\"inclusive\":true}}\n});\nreturn lexer;\n})();\nparser.lexer = lexer;\nfunction Parser () {\n this.yy = {};\n}\nParser.prototype = parser;parser.Parser = Parser;\nreturn new Parser;\n})(); \n\tparser.parser = parser;\n\texport { parser };\n\texport default parser;\n\t", "import { sanitizeUrl } from '@braintree/sanitize-url';\nimport dayjs from 'dayjs';\nimport dayjsIsoWeek from 'dayjs/plugin/isoWeek.js';\nimport dayjsCustomParseFormat from 'dayjs/plugin/customParseFormat.js';\nimport dayjsAdvancedFormat from 'dayjs/plugin/advancedFormat.js';\nimport { log } from '../../logger.js';\nimport { getConfig } from '../../diagram-api/diagramAPI.js';\nimport utils from '../../utils.js';\n\nimport {\n setAccTitle,\n getAccTitle,\n getAccDescription,\n setAccDescription,\n clear as commonClear,\n setDiagramTitle,\n getDiagramTitle,\n} from '../common/commonDb.js';\n\ndayjs.extend(dayjsIsoWeek);\ndayjs.extend(dayjsCustomParseFormat);\ndayjs.extend(dayjsAdvancedFormat);\n\nconst WEEKEND_START_DAY = { friday: 5, saturday: 6 };\nlet dateFormat = '';\nlet axisFormat = '';\nlet tickInterval = undefined;\nlet todayMarker = '';\nlet includes = [];\nlet excludes = [];\nlet links = new Map();\nlet sections = [];\nlet tasks = [];\nlet currentSection = '';\nlet displayMode = '';\nconst tags = ['active', 'done', 'crit', 'milestone', 'vert'];\nlet funs = [];\nlet inclusiveEndDates = false;\nlet topAxis = false;\nlet weekday = 'sunday';\nlet weekend = 'saturday';\n\n// The serial order of the task in the script\nlet lastOrder = 0;\n\nexport const clear = function () {\n sections = [];\n tasks = [];\n currentSection = '';\n funs = [];\n taskCnt = 0;\n lastTask = undefined;\n lastTaskID = undefined;\n rawTasks = [];\n dateFormat = '';\n axisFormat = '';\n displayMode = '';\n tickInterval = undefined;\n todayMarker = '';\n includes = [];\n excludes = [];\n inclusiveEndDates = false;\n topAxis = false;\n lastOrder = 0;\n links = new Map();\n commonClear();\n weekday = 'sunday';\n weekend = 'saturday';\n};\n\nexport const setAxisFormat = function (txt) {\n axisFormat = txt;\n};\n\nexport const getAxisFormat = function () {\n return axisFormat;\n};\n\nexport const setTickInterval = function (txt) {\n tickInterval = txt;\n};\n\nexport const getTickInterval = function () {\n return tickInterval;\n};\n\nexport const setTodayMarker = function (txt) {\n todayMarker = txt;\n};\n\nexport const getTodayMarker = function () {\n return todayMarker;\n};\n\nexport const setDateFormat = function (txt) {\n dateFormat = txt;\n};\n\nexport const enableInclusiveEndDates = function () {\n inclusiveEndDates = true;\n};\n\nexport const endDatesAreInclusive = function () {\n return inclusiveEndDates;\n};\n\nexport const enableTopAxis = function () {\n topAxis = true;\n};\n\nexport const topAxisEnabled = function () {\n return topAxis;\n};\n\nexport const setDisplayMode = function (txt) {\n displayMode = txt;\n};\n\nexport const getDisplayMode = function () {\n return displayMode;\n};\n\nexport const getDateFormat = function () {\n return dateFormat;\n};\n\nexport const setIncludes = function (txt) {\n includes = txt.toLowerCase().split(/[\\s,]+/);\n};\n\nexport const getIncludes = function () {\n return includes;\n};\nexport const setExcludes = function (txt) {\n excludes = txt.toLowerCase().split(/[\\s,]+/);\n};\n\nexport const getExcludes = function () {\n return excludes;\n};\n\nexport const getLinks = function () {\n return links;\n};\n\nexport const addSection = function (txt) {\n currentSection = txt;\n sections.push(txt);\n};\n\nexport const getSections = function () {\n return sections;\n};\n\nexport const getTasks = function () {\n let allItemsProcessed = compileTasks();\n const maxDepth = 10;\n let iterationCount = 0;\n while (!allItemsProcessed && iterationCount < maxDepth) {\n allItemsProcessed = compileTasks();\n iterationCount++;\n }\n\n tasks = rawTasks;\n\n return tasks;\n};\n\nexport const isInvalidDate = function (date, dateFormat, excludes, includes) {\n if (includes.includes(date.format(dateFormat.trim()))) {\n return false;\n }\n if (\n excludes.includes('weekends') &&\n (date.isoWeekday() === WEEKEND_START_DAY[weekend] ||\n date.isoWeekday() === WEEKEND_START_DAY[weekend] + 1)\n ) {\n return true;\n }\n if (excludes.includes(date.format('dddd').toLowerCase())) {\n return true;\n }\n return excludes.includes(date.format(dateFormat.trim()));\n};\n\nexport const setWeekday = function (txt) {\n weekday = txt;\n};\n\nexport const getWeekday = function () {\n return weekday;\n};\n\nexport const setWeekend = function (startDay) {\n weekend = startDay;\n};\n\n/**\n * TODO: fully document what this function does and what types it accepts\n *\n * @param {object} task - The task to check.\n * @param {string | Date} task.startTime - Might be a `Date` or a `string`.\n * TODO: is this always a Date?\n * @param {string | Date} task.endTime - Might be a `Date` or a `string`.\n * TODO: is this always a Date?\n * @param {string} dateFormat - Dayjs date format string.\n * @param {*} excludes\n * @param {*} includes\n */\nconst checkTaskDates = function (task, dateFormat, excludes, includes) {\n if (!excludes.length || task.manualEndTime) {\n return;\n }\n let startTime;\n if (task.startTime instanceof Date) {\n startTime = dayjs(task.startTime);\n } else {\n startTime = dayjs(task.startTime, dateFormat, true);\n }\n startTime = startTime.add(1, 'd');\n\n let originalEndTime;\n if (task.endTime instanceof Date) {\n originalEndTime = dayjs(task.endTime);\n } else {\n originalEndTime = dayjs(task.endTime, dateFormat, true);\n }\n const [fixedEndTime, renderEndTime] = fixTaskDates(\n startTime,\n originalEndTime,\n dateFormat,\n excludes,\n includes\n );\n task.endTime = fixedEndTime.toDate();\n task.renderEndTime = renderEndTime;\n};\n\n/**\n * TODO: what does this function do?\n *\n * @param {dayjs.Dayjs} startTime - The start time.\n * @param {dayjs.Dayjs} endTime - The original end time (will return a different end time if it's invalid).\n * @param {string} dateFormat - Dayjs date format string.\n * @param {*} excludes\n * @param {*} includes\n * @returns {[endTime: dayjs.Dayjs, renderEndTime: Date | null]} The new `endTime`, and the end time to render.\n * `renderEndTime` may be `null` if `startTime` is newer than `endTime`.\n */\nconst fixTaskDates = function (startTime, endTime, dateFormat, excludes, includes) {\n let invalid = false;\n let renderEndTime = null;\n while (startTime <= endTime) {\n if (!invalid) {\n renderEndTime = endTime.toDate();\n }\n invalid = isInvalidDate(startTime, dateFormat, excludes, includes);\n if (invalid) {\n endTime = endTime.add(1, 'd');\n }\n startTime = startTime.add(1, 'd');\n }\n return [endTime, renderEndTime];\n};\n\nconst getStartDate = function (prevTime, dateFormat, str) {\n str = str.trim();\n\n // Test for after\n const afterRePattern = /^after\\s+(?<ids>[\\d\\w- ]+)/;\n const afterStatement = afterRePattern.exec(str);\n\n if (afterStatement !== null) {\n // check all after ids and take the latest\n let latestTask = null;\n for (const id of afterStatement.groups.ids.split(' ')) {\n let task = findTaskById(id);\n if (task !== undefined && (!latestTask || task.endTime > latestTask.endTime)) {\n latestTask = task;\n }\n }\n\n if (latestTask) {\n return latestTask.endTime;\n }\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n return today;\n }\n\n // Check for actual date set\n let mDate = dayjs(str, dateFormat.trim(), true);\n if (mDate.isValid()) {\n return mDate.toDate();\n } else {\n log.debug('Invalid date:' + str);\n log.debug('With date format:' + dateFormat.trim());\n const d = new Date(str);\n if (\n d === undefined ||\n isNaN(d.getTime()) ||\n // WebKit browsers can mis-parse invalid dates to be ridiculously\n // huge numbers, e.g. new Date('202304') gets parsed as January 1, 202304.\n // This can cause virtually infinite loops while rendering, so for the\n // purposes of Gantt charts we'll just treat any date beyond 10,000 AD/BC as\n // invalid.\n d.getFullYear() < -10000 ||\n d.getFullYear() > 10000\n ) {\n throw new Error('Invalid date:' + str);\n }\n return d;\n }\n};\n\n/**\n * Parse a string into the args for `dayjs.add()`.\n *\n * The string have to be compound by a value and a shorthand duration unit. For example `5d`\n * represents 5 days.\n *\n * Please be aware that 1 day may be 23 or 25 hours, if the user lives in an area\n * that has daylight savings time (or even 23.5/24.5 hours in Lord Howe Island!)\n *\n * Shorthand unit supported are:\n *\n * - `y` for years\n * - `M` for months\n * - `w` for weeks\n * - `d` for days\n * - `h` for hours\n * - `s` for seconds\n * - `ms` for milliseconds\n *\n * @param {string} str - A string representing the duration.\n * @returns {[value: number, unit: dayjs.ManipulateType]} Arguments to pass to `dayjs.add()`\n */\nconst parseDuration = function (str) {\n // cspell:disable-next-line\n const statement = /^(\\d+(?:\\.\\d+)?)([Mdhmswy]|ms)$/.exec(str.trim());\n if (statement !== null) {\n return [Number.parseFloat(statement[1]), statement[2]];\n }\n // NaN means an invalid duration\n return [NaN, 'ms'];\n};\n\nconst getEndDate = function (prevTime, dateFormat, str, inclusive = false) {\n str = str.trim();\n\n // test for until\n const untilRePattern = /^until\\s+(?<ids>[\\d\\w- ]+)/;\n const untilStatement = untilRePattern.exec(str);\n\n if (untilStatement !== null) {\n // check all until ids and take the earliest\n let earliestTask = null;\n for (const id of untilStatement.groups.ids.split(' ')) {\n let task = findTaskById(id);\n if (task !== undefined && (!earliestTask || task.startTime < earliestTask.startTime)) {\n earliestTask = task;\n }\n }\n\n if (earliestTask) {\n return earliestTask.startTime;\n }\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n return today;\n }\n\n // check for actual date\n let parsedDate = dayjs(str, dateFormat.trim(), true);\n if (parsedDate.isValid()) {\n if (inclusive) {\n parsedDate = parsedDate.add(1, 'd');\n }\n return parsedDate.toDate();\n }\n\n let endTime = dayjs(prevTime);\n const [durationValue, durationUnit] = parseDuration(str);\n if (!Number.isNaN(durationValue)) {\n const newEndTime = endTime.add(durationValue, durationUnit);\n if (newEndTime.isValid()) {\n endTime = newEndTime;\n }\n }\n return endTime.toDate();\n};\n\nlet taskCnt = 0;\nconst parseId = function (idStr) {\n if (idStr === undefined) {\n taskCnt = taskCnt + 1;\n return 'task' + taskCnt;\n }\n return idStr;\n};\n// id, startDate, endDate\n// id, startDate, length\n// id, after x, endDate\n// id, after x, length\n// startDate, endDate\n// startDate, length\n// after x, endDate\n// after x, length\n// endDate\n// length\n\nconst compileData = function (prevTask, dataStr) {\n let ds;\n\n if (dataStr.substr(0, 1) === ':') {\n ds = dataStr.substr(1, dataStr.length);\n } else {\n ds = dataStr;\n }\n\n const data = ds.split(',');\n\n const task = {};\n\n // Get tags like active, done, crit, milestone, and vert\n getTaskTags(data, task, tags);\n\n for (let i = 0; i < data.length; i++) {\n data[i] = data[i].trim();\n }\n\n let endTimeData = '';\n switch (data.length) {\n case 1:\n task.id = parseId();\n task.startTime = prevTask.endTime;\n endTimeData = data[0];\n break;\n case 2:\n task.id = parseId();\n task.startTime = getStartDate(undefined, dateFormat, data[0]);\n endTimeData = data[1];\n break;\n case 3:\n task.id = parseId(data[0]);\n task.startTime = getStartDate(undefined, dateFormat, data[1]);\n endTimeData = data[2];\n break;\n default:\n }\n\n if (endTimeData) {\n task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates);\n task.manualEndTime = dayjs(endTimeData, 'YYYY-MM-DD', true).isValid();\n checkTaskDates(task, dateFormat, excludes, includes);\n }\n\n return task;\n};\n\nconst parseData = function (prevTaskId, dataStr) {\n let ds;\n if (dataStr.substr(0, 1) === ':') {\n ds = dataStr.substr(1, dataStr.length);\n } else {\n ds = dataStr;\n }\n\n const data = ds.split(',');\n\n const task = {};\n\n // Get tags like active, done, crit, milestone, and vert\n getTaskTags(data, task, tags);\n\n for (let i = 0; i < data.length; i++) {\n data[i] = data[i].trim();\n }\n\n switch (data.length) {\n case 1:\n task.id = parseId();\n task.startTime = {\n type: 'prevTaskEnd',\n id: prevTaskId,\n };\n task.endTime = {\n data: data[0],\n };\n break;\n case 2:\n task.id = parseId();\n task.startTime = {\n type: 'getStartDate',\n startData: data[0],\n };\n task.endTime = {\n data: data[1],\n };\n break;\n case 3:\n task.id = parseId(data[0]);\n task.startTime = {\n type: 'getStartDate',\n startData: data[1],\n };\n task.endTime = {\n data: data[2],\n };\n break;\n default:\n }\n\n return task;\n};\n\nlet lastTask;\nlet lastTaskID;\nlet rawTasks = [];\nconst taskDb = {};\nexport const addTask = function (descr, data) {\n const rawTask = {\n section: currentSection,\n type: currentSection,\n