@fatcore/gantt-lite 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +16 -0
- package/.vscode/extensions.json +4 -0
- package/.vscode/launch.json +20 -0
- package/.vscode/tasks.json +42 -0
- package/README.md +27 -0
- package/angular.json +165 -0
- package/dist17/gantt-lite/README.md +24 -0
- package/dist17/gantt-lite/esm2022/gantt-lite.mjs +5 -0
- package/dist17/gantt-lite/esm2022/gantt-lite.module.mjs +18 -0
- package/dist17/gantt-lite/esm2022/lib/gantt-lite-base.mjs +290 -0
- package/dist17/gantt-lite/esm2022/lib/gantt-lite.component.mjs +359 -0
- package/dist17/gantt-lite/esm2022/lib/gantt-lite.helper.mjs +107 -0
- package/dist17/gantt-lite/esm2022/lib/gantt-lite.model.mjs +2 -0
- package/dist17/gantt-lite/esm2022/public-api.mjs +3 -0
- package/dist17/gantt-lite/fesm2022/gantt-lite.mjs +774 -0
- package/dist17/gantt-lite/fesm2022/gantt-lite.mjs.map +1 -0
- package/dist17/gantt-lite/gantt-lite.module.d.ts +8 -0
- package/dist17/gantt-lite/index.d.ts +5 -0
- package/dist17/gantt-lite/lib/gantt-lite-base.d.ts +50 -0
- package/dist17/gantt-lite/lib/gantt-lite.component.d.ts +55 -0
- package/dist17/gantt-lite/lib/gantt-lite.helper.d.ts +20 -0
- package/dist17/gantt-lite/lib/gantt-lite.model.d.ts +47 -0
- package/dist17/gantt-lite/public-api.d.ts +2 -0
- package/dist18/gantt-lite/README.md +24 -0
- package/dist18/gantt-lite/esm2022/gantt-lite.mjs +5 -0
- package/dist18/gantt-lite/esm2022/gantt-lite.module.mjs +18 -0
- package/dist18/gantt-lite/esm2022/lib/gantt-lite-base.mjs +290 -0
- package/dist18/gantt-lite/esm2022/lib/gantt-lite.component.mjs +359 -0
- package/dist18/gantt-lite/esm2022/lib/gantt-lite.helper.mjs +107 -0
- package/dist18/gantt-lite/esm2022/lib/gantt-lite.model.mjs +2 -0
- package/dist18/gantt-lite/esm2022/public-api.mjs +3 -0
- package/dist18/gantt-lite/fesm2022/gantt-lite.mjs +774 -0
- package/dist18/gantt-lite/fesm2022/gantt-lite.mjs.map +1 -0
- package/dist18/gantt-lite/gantt-lite.module.d.ts +8 -0
- package/dist18/gantt-lite/index.d.ts +5 -0
- package/dist18/gantt-lite/lib/gantt-lite-base.d.ts +50 -0
- package/dist18/gantt-lite/lib/gantt-lite.component.d.ts +55 -0
- package/dist18/gantt-lite/lib/gantt-lite.helper.d.ts +20 -0
- package/dist18/gantt-lite/lib/gantt-lite.model.d.ts +47 -0
- package/dist18/gantt-lite/public-api.d.ts +2 -0
- package/dist19/gantt-lite/README.md +24 -0
- package/dist19/gantt-lite/fesm2022/gantt-lite.mjs +774 -0
- package/dist19/gantt-lite/fesm2022/gantt-lite.mjs.map +1 -0
- package/dist19/gantt-lite/gantt-lite.module.d.ts +8 -0
- package/dist19/gantt-lite/index.d.ts +5 -0
- package/dist19/gantt-lite/lib/gantt-lite-base.d.ts +50 -0
- package/dist19/gantt-lite/lib/gantt-lite.component.d.ts +55 -0
- package/dist19/gantt-lite/lib/gantt-lite.helper.d.ts +20 -0
- package/dist19/gantt-lite/lib/gantt-lite.model.d.ts +47 -0
- package/dist19/gantt-lite/public-api.d.ts +2 -0
- package/dist20/gantt-lite/README.md +24 -0
- package/dist20/gantt-lite/fesm2022/gantt-lite.mjs +774 -0
- package/dist20/gantt-lite/fesm2022/gantt-lite.mjs.map +1 -0
- package/dist20/gantt-lite/index.d.ts +159 -0
- package/my-workspace-0.0.0.tgz +0 -0
- package/package.json +45 -0
- package/projects/gantt-lite/README.md +24 -0
- package/projects/gantt-lite/ng-package.json +7 -0
- package/projects/gantt-lite/package.json +10 -0
- package/projects/gantt-lite/src/gantt-lite.module.ts +10 -0
- package/projects/gantt-lite/src/lib/gantt-lite-base.ts +300 -0
- package/projects/gantt-lite/src/lib/gantt-lite.component.html +128 -0
- package/projects/gantt-lite/src/lib/gantt-lite.component.scss +323 -0
- package/projects/gantt-lite/src/lib/gantt-lite.component.ts +391 -0
- package/projects/gantt-lite/src/lib/gantt-lite.helper.ts +124 -0
- package/projects/gantt-lite/src/lib/gantt-lite.model.ts +56 -0
- package/projects/gantt-lite/src/public-api.ts +5 -0
- package/projects/gantt-lite/tsconfig.lib.json +14 -0
- package/projects/gantt-lite/tsconfig.lib.prod.json +10 -0
- package/projects/gantt-lite/tsconfig.spec.json +14 -0
- package/projects/my-app/server.ts +56 -0
- package/projects/my-app/src/app/app.component.html +336 -0
- package/projects/my-app/src/app/app.component.scss +0 -0
- package/projects/my-app/src/app/app.component.spec.ts +29 -0
- package/projects/my-app/src/app/app.component.ts +13 -0
- package/projects/my-app/src/app/app.config.server.ts +11 -0
- package/projects/my-app/src/app/app.config.ts +9 -0
- package/projects/my-app/src/app/app.routes.ts +3 -0
- package/projects/my-app/src/assets/.gitkeep +0 -0
- package/projects/my-app/src/favicon.ico +0 -0
- package/projects/my-app/src/index.html +13 -0
- package/projects/my-app/src/main.server.ts +7 -0
- package/projects/my-app/src/main.ts +6 -0
- package/projects/my-app/src/styles.scss +1 -0
- package/projects/my-app/tsconfig.app.json +18 -0
- package/projects/my-app/tsconfig.spec.json +14 -0
- package/tsconfig.json +37 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { Component, ViewChild, Input, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
+
import { SlotIndexToDateLabelConverter } from './gantt-lite.helper';
|
|
3
|
+
import { GanttLiteBase } from './gantt-lite-base';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/common";
|
|
6
|
+
export class GanttLiteComponent extends GanttLiteBase {
|
|
7
|
+
set rawTasks(value) {
|
|
8
|
+
this._rawTasks = value ?? [];
|
|
9
|
+
this.recalculteAll();
|
|
10
|
+
}
|
|
11
|
+
get rawTasks() {
|
|
12
|
+
return this._rawTasks;
|
|
13
|
+
}
|
|
14
|
+
constructor(cdr) {
|
|
15
|
+
super();
|
|
16
|
+
this.cdr = cdr;
|
|
17
|
+
this.toolbarHeight = 27;
|
|
18
|
+
this.hoveredDependencyIds = new Set();
|
|
19
|
+
this.selectedTaskId = null;
|
|
20
|
+
this.tooltipTask = null;
|
|
21
|
+
this.tooltipX = 0;
|
|
22
|
+
this.tooltipY = 0;
|
|
23
|
+
this.maxSlotsAlert = false;
|
|
24
|
+
this.loading = false;
|
|
25
|
+
this.showLeftBtn = false;
|
|
26
|
+
this.showRightBtn = true;
|
|
27
|
+
this.buttonsHeight = 20;
|
|
28
|
+
this.viewTasks = [];
|
|
29
|
+
this._rawTasks = [];
|
|
30
|
+
this.originDate = 0;
|
|
31
|
+
this.resizing = false;
|
|
32
|
+
this.labelConverter = null;
|
|
33
|
+
}
|
|
34
|
+
// recalculate all Gantt
|
|
35
|
+
recalculteAll() {
|
|
36
|
+
this.loading = true;
|
|
37
|
+
this.cdr.markForCheck();
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
const start = performance.now();
|
|
40
|
+
this.refreshVisibleColumns();
|
|
41
|
+
this.scaleSelected = this.getScaleConfig(this.defaultScale);
|
|
42
|
+
if (this.dataType !== 'duration') {
|
|
43
|
+
const base = new Date(Math.min(...this.rawTasks.map((t) => t.start.getTime())));
|
|
44
|
+
this.originDate = this.alignOriginByScale(base, this.defaultScale).getTime();
|
|
45
|
+
this.labelConverter = new SlotIndexToDateLabelConverter(this.dateMode, this.originDate, this.scaleSelected.secondes, this.hasNegativeDependencySpace);
|
|
46
|
+
this.buildTaskSlotsFromDates();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.labelConverter = new SlotIndexToDateLabelConverter(this.dateMode, this.originDate, this.scaleSelected.secondes, this.hasNegativeDependencySpace);
|
|
50
|
+
this.buildTaskSlotsFromDuration();
|
|
51
|
+
}
|
|
52
|
+
this.detectNegativeDependencySpace();
|
|
53
|
+
this.calculateTimelineSlots();
|
|
54
|
+
this.getAllDependencyPaths();
|
|
55
|
+
this.ganttHeightCalcul();
|
|
56
|
+
this.ganttWidthCalcul();
|
|
57
|
+
this.recomputeLayout();
|
|
58
|
+
this.ganttScroll.nativeElement.style.height = this.layout.scrollHeight + 'px';
|
|
59
|
+
this.ganttBodyScroll.nativeElement.style.height = this.layout.bodyHeight + 'px';
|
|
60
|
+
this.timelineHeader.nativeElement.style.height = this.headerHeight + 'px';
|
|
61
|
+
this.ganttContent.nativeElement.style.height = this.ganttHeight - this.rowHeight + 'px';
|
|
62
|
+
this.ganttContent.nativeElement.style.width = this.ganttWidth + 'px';
|
|
63
|
+
this.leftPanel.nativeElement.style.width = this.leftPanelWidth + 'px';
|
|
64
|
+
this.buildViewTasks();
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
this.recenterSelectedTask();
|
|
67
|
+
}, 0);
|
|
68
|
+
this.loading = false;
|
|
69
|
+
this.cdr.markForCheck();
|
|
70
|
+
requestAnimationFrame(() => {
|
|
71
|
+
const end = performance.now();
|
|
72
|
+
console.log('frame time including render:', end - start, 'ms');
|
|
73
|
+
});
|
|
74
|
+
}, 0);
|
|
75
|
+
}
|
|
76
|
+
buildViewTasks() {
|
|
77
|
+
const h = this.rowHeight / 1.25;
|
|
78
|
+
this.viewTasks = this.tasks.map((t) => {
|
|
79
|
+
return {
|
|
80
|
+
...t,
|
|
81
|
+
x: this.getTaskX(t),
|
|
82
|
+
y: this.getTaskY(t),
|
|
83
|
+
width: this.getTaskWidth(t),
|
|
84
|
+
height: h,
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// click on button 10m, hour, months
|
|
89
|
+
setScale(scale) {
|
|
90
|
+
this.defaultScale = scale;
|
|
91
|
+
this.recalculteAll();
|
|
92
|
+
}
|
|
93
|
+
// if task was selected scroll back to it
|
|
94
|
+
recenterSelectedTask() {
|
|
95
|
+
if (!this.selectedTaskId) {
|
|
96
|
+
if (!this.ganttScroll)
|
|
97
|
+
return;
|
|
98
|
+
this.ganttScroll.nativeElement.scrollLeft = 0;
|
|
99
|
+
// force header sync
|
|
100
|
+
if (this.timelineHeader?.nativeElement) {
|
|
101
|
+
this.timelineHeader.nativeElement.scrollLeft = 0;
|
|
102
|
+
}
|
|
103
|
+
this.onScrolled();
|
|
104
|
+
}
|
|
105
|
+
const task = this.tasks.find((t) => t.id === this.selectedTaskId);
|
|
106
|
+
if (!task || !this.ganttScroll)
|
|
107
|
+
return;
|
|
108
|
+
// scroll X
|
|
109
|
+
const viewportWidth = this.ganttScroll.nativeElement.clientWidth;
|
|
110
|
+
const targetScrollLeft = this.getTaskX(task) - viewportWidth / 2;
|
|
111
|
+
this.ganttScroll.nativeElement.scrollTo({ left: Math.max(targetScrollLeft, 0), behavior: 'auto' });
|
|
112
|
+
// scroll Y
|
|
113
|
+
const viewportHeight = this.ganttBodyScroll.nativeElement.clientHeight;
|
|
114
|
+
const targetTop = task.row * this.rowHeight;
|
|
115
|
+
const scrollTop = targetTop - viewportHeight / 2 + this.rowHeight / 2;
|
|
116
|
+
this.ganttBodyScroll.nativeElement.scrollTo({ top: Math.max(scrollTop, 0), behavior: 'auto' });
|
|
117
|
+
this.onScrolled();
|
|
118
|
+
}
|
|
119
|
+
// detect if there is a need to add the N/A slot in order to be able to show dependency arrow before 0.
|
|
120
|
+
detectNegativeDependencySpace() {
|
|
121
|
+
const originTasks = this.tasks.filter((t) => (t.startSlot ?? 0) === 0);
|
|
122
|
+
this.hasNegativeDependencySpace = originTasks.some((task) => {
|
|
123
|
+
const fromRight = this.getRawTaskX(task) + this.getTaskWidth(task);
|
|
124
|
+
return (task.dependencies ?? []).some((depId) => {
|
|
125
|
+
const target = this.tasks.find((t) => t.id === depId);
|
|
126
|
+
if (!target)
|
|
127
|
+
return false;
|
|
128
|
+
const toLeft = this.getRawTaskX(target);
|
|
129
|
+
// true if dependency goes "backwards"
|
|
130
|
+
return toLeft < fromRight;
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// scroll buttons left/right => click small go, stay clicked scroll a lot
|
|
135
|
+
startScroll(direction) {
|
|
136
|
+
// instant first move
|
|
137
|
+
this.scrollInterval = setInterval(() => {
|
|
138
|
+
this.ganttScroll.nativeElement.scrollLeft += direction === 'left' ? -100 : 100;
|
|
139
|
+
this.onScrolled();
|
|
140
|
+
}, 50);
|
|
141
|
+
}
|
|
142
|
+
// update buttons left/right after a scroll.
|
|
143
|
+
onScrolled() {
|
|
144
|
+
const el = this.ganttScroll.nativeElement;
|
|
145
|
+
const maxScrollLeft = el.scrollWidth - el.clientWidth;
|
|
146
|
+
// left button
|
|
147
|
+
this.showLeftBtn = el.scrollLeft > 0;
|
|
148
|
+
if (this.leftBtn?.nativeElement) {
|
|
149
|
+
if (this.showLeftBtn) {
|
|
150
|
+
this.leftBtn.nativeElement.style.display = 'block';
|
|
151
|
+
this.leftBtn.nativeElement.style.left = this.leftPanel.nativeElement.style.width;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
this.leftBtn.nativeElement.style.display = 'none';
|
|
155
|
+
this.leftBtn.nativeElement.style.left = this.leftPanel.nativeElement.style.width;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// right button
|
|
159
|
+
this.showRightBtn = el.scrollLeft < maxScrollLeft - 1 || el.scrollLeft === 0; // small tolerance
|
|
160
|
+
if (this.rightBtn?.nativeElement) {
|
|
161
|
+
if (this.showRightBtn) {
|
|
162
|
+
this.rightBtn.nativeElement.style.display = 'block';
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
this.rightBtn.nativeElement.style.display = 'none';
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (!this.showLeftBtn || !this.showRightBtn) {
|
|
169
|
+
this.stopScroll();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
stopScroll() {
|
|
173
|
+
clearInterval(this.scrollInterval);
|
|
174
|
+
}
|
|
175
|
+
// to sync header and grid
|
|
176
|
+
onHorizontalScroll(event) {
|
|
177
|
+
this.timelineHeader.nativeElement.scrollLeft = event.target.scrollLeft;
|
|
178
|
+
}
|
|
179
|
+
// highlight dependencies (arrows)
|
|
180
|
+
updateHoveredDependencies(task) {
|
|
181
|
+
this.hoveredDependencyIds.clear();
|
|
182
|
+
if (!task) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// outgoing dependencies
|
|
186
|
+
for (const dep of task.dependencies ?? []) {
|
|
187
|
+
this.hoveredDependencyIds.add(`${dep}->${task.id}`);
|
|
188
|
+
}
|
|
189
|
+
// incoming dependencies
|
|
190
|
+
for (const t of this.tasks) {
|
|
191
|
+
if ((t.dependencies ?? []).includes(task.id)) {
|
|
192
|
+
this.hoveredDependencyIds.add(`${task.id}->${t.id}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// select task left and right panel
|
|
197
|
+
selectTask(task, scroll) {
|
|
198
|
+
if (this.selectedTaskId === task.id) {
|
|
199
|
+
this.selectedTaskId = null;
|
|
200
|
+
this.hoveredDependencyIds.clear();
|
|
201
|
+
this.hideTooltip();
|
|
202
|
+
this.onScrolled();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
this.selectedTaskId = task.id;
|
|
206
|
+
this.updateHoveredDependencies(task);
|
|
207
|
+
this.onScrolled();
|
|
208
|
+
if (!scroll || !this.ganttScroll)
|
|
209
|
+
return;
|
|
210
|
+
const container = this.ganttScroll.nativeElement;
|
|
211
|
+
const viewportWidth = container.clientWidth;
|
|
212
|
+
const targetScrollLeft = this.getTaskX(task) - viewportWidth / 2;
|
|
213
|
+
container.scrollTo({
|
|
214
|
+
left: Math.max(targetScrollLeft, 0),
|
|
215
|
+
behavior: 'smooth',
|
|
216
|
+
});
|
|
217
|
+
this.onScrolled();
|
|
218
|
+
}
|
|
219
|
+
// resize between panel left and right
|
|
220
|
+
startResize(event) {
|
|
221
|
+
event.preventDefault();
|
|
222
|
+
this.resizing = true;
|
|
223
|
+
const containerRect = this.ganttBodyScroll.nativeElement.getBoundingClientRect();
|
|
224
|
+
const left = containerRect.left;
|
|
225
|
+
const min = 50;
|
|
226
|
+
const max = containerRect.width - 75;
|
|
227
|
+
const moveHandler = (e) => {
|
|
228
|
+
if (!this.resizing)
|
|
229
|
+
return;
|
|
230
|
+
const x = e.clientX - left;
|
|
231
|
+
const width = x < min ? min : x > max ? max : x;
|
|
232
|
+
// direct DOM update (no Angular)
|
|
233
|
+
this.leftPanel.nativeElement.style.width = width + 'px';
|
|
234
|
+
if (this.leftBtn?.nativeElement) {
|
|
235
|
+
this.leftBtn.nativeElement.style.left = `${width}px`;
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const upHandler = () => {
|
|
239
|
+
this.resizing = false;
|
|
240
|
+
window.removeEventListener('mousemove', moveHandler);
|
|
241
|
+
window.removeEventListener('mouseup', upHandler);
|
|
242
|
+
};
|
|
243
|
+
window.addEventListener('mousemove', moveHandler);
|
|
244
|
+
window.addEventListener('mouseup', upHandler);
|
|
245
|
+
}
|
|
246
|
+
showTooltip(event, task) {
|
|
247
|
+
this.tooltipTask = task;
|
|
248
|
+
const tooltip = document.querySelector('.global-tooltip');
|
|
249
|
+
if (!tooltip)
|
|
250
|
+
return;
|
|
251
|
+
tooltip.style.left = `${event.clientX + 10}px`;
|
|
252
|
+
tooltip.style.top = `${event.clientY - 50}px`;
|
|
253
|
+
tooltip.style.display = 'block';
|
|
254
|
+
}
|
|
255
|
+
hideTooltip() {
|
|
256
|
+
this.tooltipTask = null;
|
|
257
|
+
const tooltip = document.querySelector('.global-tooltip');
|
|
258
|
+
if (!tooltip)
|
|
259
|
+
return;
|
|
260
|
+
tooltip.style.display = 'none';
|
|
261
|
+
}
|
|
262
|
+
buildTaskSlotsFromDates() {
|
|
263
|
+
const slotMs = this.scaleSelected.secondes * 1000;
|
|
264
|
+
this.tasks = this.rawTasks.map((t) => {
|
|
265
|
+
if (!(t.start instanceof Date) || !(t.end instanceof Date)) {
|
|
266
|
+
throw new Error(`Task "${t.id}" must have Date start/end values.`);
|
|
267
|
+
}
|
|
268
|
+
const startSlot = (t.start.getTime() - this.originDate) / slotMs;
|
|
269
|
+
const endSlot = (t.end.getTime() - this.originDate) / slotMs;
|
|
270
|
+
return { ...t, startSlot, endSlot };
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
buildTaskSlotsFromDuration() {
|
|
274
|
+
this.tasks = this.rawTasks.map((t) => {
|
|
275
|
+
if (typeof t.start !== 'number' || typeof t.end !== 'number') {
|
|
276
|
+
throw new Error(`Task "${t.id}" must have numeric start/end values expressed in minutes.`);
|
|
277
|
+
}
|
|
278
|
+
const startSlot = t.start / this.scaleSelected.secondes;
|
|
279
|
+
const endSlot = t.end / this.scaleSelected.secondes;
|
|
280
|
+
return { ...t, startSlot, endSlot };
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
// get all slots (timeline)
|
|
284
|
+
calculateTimelineSlots() {
|
|
285
|
+
const maxSlot = Math.max(...this.tasks.map(t => t.endSlot ?? 0));
|
|
286
|
+
if (maxSlot > 53000) {
|
|
287
|
+
this.maxSlotsAlert = true;
|
|
288
|
+
this.slots = [];
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
this.maxSlotsAlert = false;
|
|
292
|
+
const buffer = [];
|
|
293
|
+
let offsetX = 0;
|
|
294
|
+
if (this.hasNegativeDependencySpace) {
|
|
295
|
+
buffer.push({
|
|
296
|
+
index: -1,
|
|
297
|
+
x: 0,
|
|
298
|
+
width: this.negativeSlotWidth,
|
|
299
|
+
label: 'N/A'
|
|
300
|
+
});
|
|
301
|
+
offsetX = this.negativeSlotWidth;
|
|
302
|
+
}
|
|
303
|
+
for (let i = 0; i <= maxSlot + 2; i++) {
|
|
304
|
+
buffer.push({
|
|
305
|
+
index: i,
|
|
306
|
+
x: offsetX + i * this.scaleSelected.px,
|
|
307
|
+
width: this.scaleSelected.px,
|
|
308
|
+
label: this.getSlotLabel(i) ?? 'Error',
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
this.slots = buffer;
|
|
312
|
+
}
|
|
313
|
+
// get all paths of arrows
|
|
314
|
+
getAllDependencyPaths() {
|
|
315
|
+
this.dependencyPaths = this.tasks.flatMap((task) => (task.dependencies ?? []).map((dep) => ({
|
|
316
|
+
from: dep,
|
|
317
|
+
to: task.id,
|
|
318
|
+
id: `${dep}->${task.id}`,
|
|
319
|
+
path: this.getDependencyPath(dep, task.id),
|
|
320
|
+
})));
|
|
321
|
+
}
|
|
322
|
+
// get label for date header
|
|
323
|
+
getSlotLabel(index) {
|
|
324
|
+
if (this.dataType === 'calendar') {
|
|
325
|
+
return this.labelConverter?.getLabelCalendar(index, this.defaultScale) ?? 'Error';
|
|
326
|
+
}
|
|
327
|
+
return this.labelConverter?.getLabelDuration(index, this.defaultScale) ?? 'Error';
|
|
328
|
+
}
|
|
329
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GanttLiteComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
330
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: GanttLiteComponent, selector: "gantt-lite", inputs: { rawTasks: "rawTasks" }, viewQueries: [{ propertyName: "ganttBodyScroll", first: true, predicate: ["ganttBodyScroll"], descendants: true }, { propertyName: "ganttContent", first: true, predicate: ["ganttContent"], descendants: true }, { propertyName: "ganttScroll", first: true, predicate: ["ganttScroll"], descendants: true }, { propertyName: "leftPanel", first: true, predicate: ["leftPanel"], descendants: true }, { propertyName: "timelineHeader", first: true, predicate: ["timelineHeader"], descendants: true }, { propertyName: "leftBtn", first: true, predicate: ["leftBtn"], descendants: true }, { propertyName: "rightBtn", first: true, predicate: ["rightBtn"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"gantt-root\" [style.max-height.px]=\"layout.rootMaxHeight\" [style.min-height.px]=\"100\">\n <!-- TOOLBAR -->\n <div class=\"toolbar\" [style.height.px]=\"buttonsHeight\">\n <div *ngIf=\"dateMode === 'utc' || dataType === 'duration'\">\n <button class=\"gantt-button\" *ngFor=\"let s of scales\" (click)=\"setScale(s)\" [class.active]=\"defaultScale === s\">\n {{ s }}\n </button>\n </div>\n <div *ngIf=\"dateMode !== 'utc' && dataType === 'calendar'\">\n <button class=\"gantt-button\" *ngFor=\"let s of scalesDate\" (click)=\"setScale(s)\"\n [class.active]=\"defaultScale === s\">\n {{ s }}\n </button>\n </div>\n <label *ngIf=\"maxSlotsAlert\" style=\"color: red;\">\n Data is too massive to show Gantt smoothly, try changing the scale\n </label>\n </div>\n <!-- TOOLTIP -->\n <div class=\"global-tooltip\" [style.display]=\"tooltipTask ? 'block' : 'none'\">\n <ng-container *ngIf=\"tooltipTask as task\">\n <div *ngFor=\"let column of visibleTooltipColumns\">\n <strong>{{ column?.title }}:</strong>\n {{ column?.valueGetter(task) }}\n </div>\n </ng-container>\n </div>\n <!-- BUTTONS FOR SCROLL GANTT -->\n <div *ngIf=\"!maxSlotsAlert && loading === false\" class=\"floating-nav\">\n <button class=\"nav-btn left\" (mousedown)=\"startScroll('left')\"\n (mouseup)=\"stopScroll()\" (mouseleave)=\"stopScroll()\" #leftBtn >\n \u2039\n </button>\n <button class=\"nav-btn right\" (mousedown)=\"startScroll('right')\"\n (mouseup)=\"stopScroll()\" (mouseleave)=\"stopScroll()\" #rightBtn>\n \u203A\n </button>\n </div>\n <!-- LOADING -->\n <div class=\"loading-overlay\" *ngIf=\"loading\" [style.top]=\"'50%'\">\n <div class=\"spinner\"></div>\n </div>\n <!-- SINGLE VERTICAL SCROLL -->\n <div class=\"gantt-body\" #ganttBodyScroll>\n <!-- LEFT PANEL -->\n <div class=\"left-panel\" #leftPanel>\n <div class=\"task-row header\" [style.height.px]=\"headerHeight\">\n <div class=\"cell\" *ngFor=\"let column of visibleGridColumns\" [style.width.px]=\"column.width || 120\">\n {{ column?.title }}\n </div>\n </div>\n <div class=\"task-row\" *ngFor=\"let task of tasks\" [style.height.px]=\"rowHeight\"\n (click)=\"selectTask(task, true); $event.stopPropagation()\"\n [class.highlighted-row]=\"selectedTaskId === task.id\">\n <div class=\"cell\" *ngFor=\"let column of visibleGridColumns\" [style.width.px]=\"column.width || 120\">\n {{ column?.valueGetter(task) }}\n </div>\n </div>\n </div>\n <!-- RESIZER -->\n <div class=\"resizer\" [style.height.px]=\"layout.resizerHeight\" (mousedown)=\"startResize($event)\">\n </div>\n <!-- RIGHT PANEL -->\n <div class=\"right-panel\" *ngIf=\"!maxSlotsAlert\">\n <!-- TIMELINE -->\n <div class=\"timeline-header\" #timelineHeader>\n <div class=\"timeline-slot\" *ngFor=\"let slot of slots\" [style.width.px]=\"slot.width\">\n {{ slot.label }}\n </div>\n </div>\n <!-- HORIZONTAL SCROLL ONLY -->\n <div class=\"horizontal-scroll\" (scroll)=\"onHorizontalScroll($event)\" #ganttScroll>\n <div class=\"gantt-content\" #ganttContent>\n <!-- GRID -->\n <div class=\"grid-layer\">\n <div *ngFor=\"let slot of slots; let i = index; trackBy: trackByIndex\" class=\"grid-line\"\n [style.left.px]=\"slot.x - 1\">\n </div>\n <!-- final vertical line -->\n <div class=\"grid-line\" [style.left.px]=\"ganttWidth - 1\">\n </div>\n <!-- horizontal lines -->\n <div class=\"horizontal-grid-layer\">\n <div *ngFor=\"let task of tasks; let i = index; trackBy: trackByIndex\"\n class=\"horizontal-line\" [style.top.px]=\"getGridTop(i)\">\n </div>\n <!-- final horizontal line -->\n <div class=\"horizontal-line\" [style.top.px]=\"ganttHeight\">\n </div>\n </div>\n </div>\n <!-- TASKS -->\n <div class=\"tasks-layer\">\n <div *ngFor=\"let task of viewTasks; let i = index; trackBy: trackByIndex\" class=\"task\"\n (mouseenter)=\"showTooltip($event, task)\" (mouseleave)=\"hideTooltip()\"\n (click)=\"selectTask(task, false); $event.stopPropagation()\"\n [class.highlighted-task]=\"selectedTaskId === task.id\" [style.left.px]=\"task.x\"\n [style.top.px]=\"task.y\" [style.width.px]=\"task.width\" [style.height.px]=\"task.height\">\n <div class=\"task-label\">\n {{ task.label }}\n </div>\n </div>\n </div>\n <!-- DEPENDENCIES -->\n <svg class=\"dependencies-svg\">\n <defs>\n <marker id=\"arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"6\" markerHeight=\"6\"\n orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#868d97\" />\n </marker>\n </defs>\n <g class=\"dependencies-normal\">\n <path *ngFor=\"let dep of dependencyPaths\" [attr.d]=\"dep.path\" class=\"dependency\"\n [class.hidden]=\"hoveredDependencyIds.has(dep.id)\" marker-end=\"url(#arrow)\">\n </path>\n </g>\n <g class=\"dependencies-highlighted\">\n <path *ngFor=\"let dep of dependencyPaths\" [attr.d]=\"dep.path\" class=\"highlighted-dependency\"\n [class.hidden]=\"!hoveredDependencyIds.has(dep.id)\" marker-end=\"url(#arrow)\">\n </path>\n </g>\n </svg>\n </div>\n </div>\n </div>\n <div class=\"right-panel-dead\" *ngIf=\"maxSlotsAlert\"></div>\n </div>\n</div>", styles: [":host{display:block;width:100%;height:100%}.gantt-root{height:100%;width:100%;display:flex;flex-direction:column;overflow:hidden}.gantt-body{flex:1;display:flex;overflow-y:auto;overflow-x:hidden;border-width:1px;border-style:solid;border-color:#aaac}.toolbar{flex-shrink:0;display:flex;gap:8px;background:#fff;position:sticky;top:0;z-index:50}.toolbar button.active{font-weight:700}.loading-overlay{position:sticky;inset:0;display:flex;align-items:center;justify-content:center;z-index:1000}.global-tooltip{position:fixed;background:#585858e6;color:#fff;padding:8px;border-radius:6px;font-size:12px;z-index:1000;pointer-events:none}.left-panel{flex-shrink:0;background:#fff;border-right:1px solid #dcdcdc}.task-row{display:grid;grid-auto-flow:column;grid-auto-columns:120px;gap:0 10px;font-size:small;align-items:center;border-bottom:1px solid #eee;white-space:nowrap;overflow:hidden}.cell{padding:0 8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.task-row.header{font-size:small;font-weight:600;position:sticky;top:0;background:#fff!important;z-index:1}.task-row:hover{background:#ff00001a}.highlighted-row{background:#ff00004d!important}.resizer{min-width:7px;cursor:col-resize;background:#b4b4b4}.resizer:hover{background:#696969}.right-panel{flex:1;min-width:100px!important;position:relative}.right-panel-dead{flex:1;height:10000px;min-width:100px!important;position:relative;background-color:#696969}.horizontal-scroll{overflow-x:hidden;overflow-y:hidden;position:relative}.gantt-content{position:relative}.timeline-header{display:flex;position:sticky;top:0;overflow:hidden;white-space:nowrap;z-index:20;background:#fff;border-bottom:1px solid #ccc}.timeline-slot{flex:0 0 auto;border-right:1px solid #e0e0e0;padding:8px;box-sizing:border-box;text-align:center;font-size:12px}.highlighted-task{background:#f006!important;border-color:#b71c1c!important;z-index:10}.grid-layer{position:absolute;inset:0;pointer-events:none}.grid-line{position:absolute;top:0;bottom:0;width:1px;background:#c8c8c859}.horizontal-grid-layer{position:absolute;inset:0;pointer-events:none}.horizontal-line{position:absolute;left:0;right:0;height:1px;background:#c8c8c840}.dependencies-svg{overflow:visible}.dependencies-normal,.dependencies-highlighted{pointer-events:none}.dependency{stroke:#9ba2ad;stroke-width:1.6;fill:none;opacity:.35}.highlighted-dependency{stroke:#52555a;stroke-width:2.7;fill:none;opacity:1}.dependencies-svg.hovering .dependency{opacity:.035}.tasks-layer{position:relative;z-index:2}.task{position:absolute;background:#9b94f7bf;opacity:.85;color:#505050;padding-top:4px;border-radius:4px;font-size:11px;white-space:nowrap;min-width:2px}.task:hover{background:#ff000026}.spinner{width:40px;height:40px;border:4px solid #ddd;border-top-color:#3f51b5;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}*{box-sizing:border-box}.floating-nav{position:sticky;top:50%;transform:translateY(-50%);z-index:100;pointer-events:none}.nav-btn{position:absolute;width:45px;height:45px;display:flex;align-items:center;justify-content:center;pointer-events:auto;background:#5c9af866;border:none;color:#535353;font-size:26px;cursor:pointer;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px);border-radius:2px;line-height:1;text-align:center}.nav-btn:hover{background:#5c9af8b3}.nav-btn.left{margin-left:13px}.nav-btn.right{right:23px}.task-label{padding-left:6px}.hidden{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
331
|
+
}
|
|
332
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GanttLiteComponent, decorators: [{
|
|
333
|
+
type: Component,
|
|
334
|
+
args: [{ selector: 'gantt-lite', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"gantt-root\" [style.max-height.px]=\"layout.rootMaxHeight\" [style.min-height.px]=\"100\">\n <!-- TOOLBAR -->\n <div class=\"toolbar\" [style.height.px]=\"buttonsHeight\">\n <div *ngIf=\"dateMode === 'utc' || dataType === 'duration'\">\n <button class=\"gantt-button\" *ngFor=\"let s of scales\" (click)=\"setScale(s)\" [class.active]=\"defaultScale === s\">\n {{ s }}\n </button>\n </div>\n <div *ngIf=\"dateMode !== 'utc' && dataType === 'calendar'\">\n <button class=\"gantt-button\" *ngFor=\"let s of scalesDate\" (click)=\"setScale(s)\"\n [class.active]=\"defaultScale === s\">\n {{ s }}\n </button>\n </div>\n <label *ngIf=\"maxSlotsAlert\" style=\"color: red;\">\n Data is too massive to show Gantt smoothly, try changing the scale\n </label>\n </div>\n <!-- TOOLTIP -->\n <div class=\"global-tooltip\" [style.display]=\"tooltipTask ? 'block' : 'none'\">\n <ng-container *ngIf=\"tooltipTask as task\">\n <div *ngFor=\"let column of visibleTooltipColumns\">\n <strong>{{ column?.title }}:</strong>\n {{ column?.valueGetter(task) }}\n </div>\n </ng-container>\n </div>\n <!-- BUTTONS FOR SCROLL GANTT -->\n <div *ngIf=\"!maxSlotsAlert && loading === false\" class=\"floating-nav\">\n <button class=\"nav-btn left\" (mousedown)=\"startScroll('left')\"\n (mouseup)=\"stopScroll()\" (mouseleave)=\"stopScroll()\" #leftBtn >\n \u2039\n </button>\n <button class=\"nav-btn right\" (mousedown)=\"startScroll('right')\"\n (mouseup)=\"stopScroll()\" (mouseleave)=\"stopScroll()\" #rightBtn>\n \u203A\n </button>\n </div>\n <!-- LOADING -->\n <div class=\"loading-overlay\" *ngIf=\"loading\" [style.top]=\"'50%'\">\n <div class=\"spinner\"></div>\n </div>\n <!-- SINGLE VERTICAL SCROLL -->\n <div class=\"gantt-body\" #ganttBodyScroll>\n <!-- LEFT PANEL -->\n <div class=\"left-panel\" #leftPanel>\n <div class=\"task-row header\" [style.height.px]=\"headerHeight\">\n <div class=\"cell\" *ngFor=\"let column of visibleGridColumns\" [style.width.px]=\"column.width || 120\">\n {{ column?.title }}\n </div>\n </div>\n <div class=\"task-row\" *ngFor=\"let task of tasks\" [style.height.px]=\"rowHeight\"\n (click)=\"selectTask(task, true); $event.stopPropagation()\"\n [class.highlighted-row]=\"selectedTaskId === task.id\">\n <div class=\"cell\" *ngFor=\"let column of visibleGridColumns\" [style.width.px]=\"column.width || 120\">\n {{ column?.valueGetter(task) }}\n </div>\n </div>\n </div>\n <!-- RESIZER -->\n <div class=\"resizer\" [style.height.px]=\"layout.resizerHeight\" (mousedown)=\"startResize($event)\">\n </div>\n <!-- RIGHT PANEL -->\n <div class=\"right-panel\" *ngIf=\"!maxSlotsAlert\">\n <!-- TIMELINE -->\n <div class=\"timeline-header\" #timelineHeader>\n <div class=\"timeline-slot\" *ngFor=\"let slot of slots\" [style.width.px]=\"slot.width\">\n {{ slot.label }}\n </div>\n </div>\n <!-- HORIZONTAL SCROLL ONLY -->\n <div class=\"horizontal-scroll\" (scroll)=\"onHorizontalScroll($event)\" #ganttScroll>\n <div class=\"gantt-content\" #ganttContent>\n <!-- GRID -->\n <div class=\"grid-layer\">\n <div *ngFor=\"let slot of slots; let i = index; trackBy: trackByIndex\" class=\"grid-line\"\n [style.left.px]=\"slot.x - 1\">\n </div>\n <!-- final vertical line -->\n <div class=\"grid-line\" [style.left.px]=\"ganttWidth - 1\">\n </div>\n <!-- horizontal lines -->\n <div class=\"horizontal-grid-layer\">\n <div *ngFor=\"let task of tasks; let i = index; trackBy: trackByIndex\"\n class=\"horizontal-line\" [style.top.px]=\"getGridTop(i)\">\n </div>\n <!-- final horizontal line -->\n <div class=\"horizontal-line\" [style.top.px]=\"ganttHeight\">\n </div>\n </div>\n </div>\n <!-- TASKS -->\n <div class=\"tasks-layer\">\n <div *ngFor=\"let task of viewTasks; let i = index; trackBy: trackByIndex\" class=\"task\"\n (mouseenter)=\"showTooltip($event, task)\" (mouseleave)=\"hideTooltip()\"\n (click)=\"selectTask(task, false); $event.stopPropagation()\"\n [class.highlighted-task]=\"selectedTaskId === task.id\" [style.left.px]=\"task.x\"\n [style.top.px]=\"task.y\" [style.width.px]=\"task.width\" [style.height.px]=\"task.height\">\n <div class=\"task-label\">\n {{ task.label }}\n </div>\n </div>\n </div>\n <!-- DEPENDENCIES -->\n <svg class=\"dependencies-svg\">\n <defs>\n <marker id=\"arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"6\" markerHeight=\"6\"\n orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#868d97\" />\n </marker>\n </defs>\n <g class=\"dependencies-normal\">\n <path *ngFor=\"let dep of dependencyPaths\" [attr.d]=\"dep.path\" class=\"dependency\"\n [class.hidden]=\"hoveredDependencyIds.has(dep.id)\" marker-end=\"url(#arrow)\">\n </path>\n </g>\n <g class=\"dependencies-highlighted\">\n <path *ngFor=\"let dep of dependencyPaths\" [attr.d]=\"dep.path\" class=\"highlighted-dependency\"\n [class.hidden]=\"!hoveredDependencyIds.has(dep.id)\" marker-end=\"url(#arrow)\">\n </path>\n </g>\n </svg>\n </div>\n </div>\n </div>\n <div class=\"right-panel-dead\" *ngIf=\"maxSlotsAlert\"></div>\n </div>\n</div>", styles: [":host{display:block;width:100%;height:100%}.gantt-root{height:100%;width:100%;display:flex;flex-direction:column;overflow:hidden}.gantt-body{flex:1;display:flex;overflow-y:auto;overflow-x:hidden;border-width:1px;border-style:solid;border-color:#aaac}.toolbar{flex-shrink:0;display:flex;gap:8px;background:#fff;position:sticky;top:0;z-index:50}.toolbar button.active{font-weight:700}.loading-overlay{position:sticky;inset:0;display:flex;align-items:center;justify-content:center;z-index:1000}.global-tooltip{position:fixed;background:#585858e6;color:#fff;padding:8px;border-radius:6px;font-size:12px;z-index:1000;pointer-events:none}.left-panel{flex-shrink:0;background:#fff;border-right:1px solid #dcdcdc}.task-row{display:grid;grid-auto-flow:column;grid-auto-columns:120px;gap:0 10px;font-size:small;align-items:center;border-bottom:1px solid #eee;white-space:nowrap;overflow:hidden}.cell{padding:0 8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.task-row.header{font-size:small;font-weight:600;position:sticky;top:0;background:#fff!important;z-index:1}.task-row:hover{background:#ff00001a}.highlighted-row{background:#ff00004d!important}.resizer{min-width:7px;cursor:col-resize;background:#b4b4b4}.resizer:hover{background:#696969}.right-panel{flex:1;min-width:100px!important;position:relative}.right-panel-dead{flex:1;height:10000px;min-width:100px!important;position:relative;background-color:#696969}.horizontal-scroll{overflow-x:hidden;overflow-y:hidden;position:relative}.gantt-content{position:relative}.timeline-header{display:flex;position:sticky;top:0;overflow:hidden;white-space:nowrap;z-index:20;background:#fff;border-bottom:1px solid #ccc}.timeline-slot{flex:0 0 auto;border-right:1px solid #e0e0e0;padding:8px;box-sizing:border-box;text-align:center;font-size:12px}.highlighted-task{background:#f006!important;border-color:#b71c1c!important;z-index:10}.grid-layer{position:absolute;inset:0;pointer-events:none}.grid-line{position:absolute;top:0;bottom:0;width:1px;background:#c8c8c859}.horizontal-grid-layer{position:absolute;inset:0;pointer-events:none}.horizontal-line{position:absolute;left:0;right:0;height:1px;background:#c8c8c840}.dependencies-svg{overflow:visible}.dependencies-normal,.dependencies-highlighted{pointer-events:none}.dependency{stroke:#9ba2ad;stroke-width:1.6;fill:none;opacity:.35}.highlighted-dependency{stroke:#52555a;stroke-width:2.7;fill:none;opacity:1}.dependencies-svg.hovering .dependency{opacity:.035}.tasks-layer{position:relative;z-index:2}.task{position:absolute;background:#9b94f7bf;opacity:.85;color:#505050;padding-top:4px;border-radius:4px;font-size:11px;white-space:nowrap;min-width:2px}.task:hover{background:#ff000026}.spinner{width:40px;height:40px;border:4px solid #ddd;border-top-color:#3f51b5;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}*{box-sizing:border-box}.floating-nav{position:sticky;top:50%;transform:translateY(-50%);z-index:100;pointer-events:none}.nav-btn{position:absolute;width:45px;height:45px;display:flex;align-items:center;justify-content:center;pointer-events:auto;background:#5c9af866;border:none;color:#535353;font-size:26px;cursor:pointer;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px);border-radius:2px;line-height:1;text-align:center}.nav-btn:hover{background:#5c9af8b3}.nav-btn.left{margin-left:13px}.nav-btn.right{right:23px}.task-label{padding-left:6px}.hidden{display:none}\n"] }]
|
|
335
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { rawTasks: [{
|
|
336
|
+
type: Input
|
|
337
|
+
}], ganttBodyScroll: [{
|
|
338
|
+
type: ViewChild,
|
|
339
|
+
args: ['ganttBodyScroll']
|
|
340
|
+
}], ganttContent: [{
|
|
341
|
+
type: ViewChild,
|
|
342
|
+
args: ['ganttContent']
|
|
343
|
+
}], ganttScroll: [{
|
|
344
|
+
type: ViewChild,
|
|
345
|
+
args: ['ganttScroll']
|
|
346
|
+
}], leftPanel: [{
|
|
347
|
+
type: ViewChild,
|
|
348
|
+
args: ['leftPanel']
|
|
349
|
+
}], timelineHeader: [{
|
|
350
|
+
type: ViewChild,
|
|
351
|
+
args: ['timelineHeader']
|
|
352
|
+
}], leftBtn: [{
|
|
353
|
+
type: ViewChild,
|
|
354
|
+
args: ['leftBtn']
|
|
355
|
+
}], rightBtn: [{
|
|
356
|
+
type: ViewChild,
|
|
357
|
+
args: ['rightBtn']
|
|
358
|
+
}] } });
|
|
359
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQtbGl0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW50dC1saXRlL3NyYy9saWIvZ2FudHQtbGl0ZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW50dC1saXRlL3NyYy9saWIvZ2FudHQtbGl0ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFNBQVMsRUFBRSxLQUFLLEVBQXFCLHVCQUF1QixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXBILE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7O0FBU2xELE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxhQUFhO0lBQ2pELElBQ1csUUFBUSxDQUFDLEtBQWtCO1FBQ2xDLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUNELElBQVcsUUFBUTtRQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUMxQixDQUFDO0lBMEJELFlBQW9CLEdBQXNCO1FBQUksS0FBSyxFQUFFLENBQUM7UUFBbEMsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFsQm5DLGtCQUFhLEdBQVcsRUFBRSxDQUFDO1FBQzNCLHlCQUFvQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDekMsbUJBQWMsR0FBa0IsSUFBSSxDQUFDO1FBQ3JDLGdCQUFXLEdBQXFCLElBQUksQ0FBQztRQUNyQyxhQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsYUFBUSxHQUFHLENBQUMsQ0FBQztRQUNiLGtCQUFhLEdBQVksS0FBSyxDQUFDO1FBQy9CLFlBQU8sR0FBWSxLQUFLLENBQUM7UUFDekIsZ0JBQVcs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LElBQUksRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7U0FDN0MsQ0FBQyxDQUNMLENBQ0osQ0FBQztJQUNOLENBQUM7SUFFRCw0QkFBNEI7SUFDcEIsWUFBWSxDQUFDLEtBQWE7UUFDOUIsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQy9CLE9BQU8sSUFBSSxDQUFDLGNBQWMsRUFBRSxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLE9BQU8sQ0FBQztRQUN0RixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsY0FBYyxFQUFFLGdCQUFnQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksT0FBTyxDQUFDO0lBQ3RGLENBQUM7K0dBelhRLGtCQUFrQjttR0FBbEIsa0JBQWtCLG13QkNaL0IsMndOQStITTs7NEZEbkhPLGtCQUFrQjtrQkFQOUIsU0FBUzsrQkFDSSxZQUFZLGNBR1YsS0FBSyxtQkFDQSx1QkFBdUIsQ0FBQyxNQUFNO3NGQUlwQyxRQUFRO3NCQURsQixLQUFLO2dCQVFnQyxlQUFlO3NCQUFwRCxTQUFTO3VCQUFDLGlCQUFpQjtnQkFDTyxZQUFZO3NCQUE5QyxTQUFTO3VCQUFDLGNBQWM7Z0JBQ1MsV0FBVztzQkFBNUMsU0FBUzt1QkFBQyxhQUFhO2dCQUNRLFNBQVM7c0JBQXhDLFNBQVM7dUJBQUMsV0FBVztnQkFDZSxjQUFjO3NCQUFsRCxTQUFTO3VCQUFDLGdCQUFnQjtnQkFDRyxPQUFPO3NCQUFwQyxTQUFTO3VCQUFDLFNBQVM7Z0JBQ1csUUFBUTtzQkFBdEMsU0FBUzt1QkFBQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIElucHV0LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRGVwZW5kZW5jeVBhdGgsIEdhbnR0U2NhbGUsIEdhbnR0VGFzaywgR2FudHRUYXNrVmlldyB9IGZyb20gJy4vZ2FudHQtbGl0ZS5tb2RlbCc7XHJcbmltcG9ydCB7IFNsb3RJbmRleFRvRGF0ZUxhYmVsQ29udmVydGVyIH0gZnJvbSAnLi9nYW50dC1saXRlLmhlbHBlcic7XHJcbmltcG9ydCB7IEdhbnR0TGl0ZUJhc2UgfSBmcm9tICcuL2dhbnR0LWxpdGUtYmFzZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnZ2FudHQtbGl0ZScsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZ2FudHQtbGl0ZS5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9nYW50dC1saXRlLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgICBzdGFuZGFsb25lOiBmYWxzZSxcclxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgR2FudHRMaXRlQ29tcG9uZW50IGV4dGVuZHMgR2FudHRMaXRlQmFzZSB7XHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIHNldCByYXdUYXNrcyh2YWx1ZTogR2FudHRUYXNrW10pIHtcclxuICAgICAgICB0aGlzLl9yYXdUYXNrcyA9IHZhbHVlID8/IFtdO1xyXG4gICAgICAgIHRoaXMucmVjYWxjdWx0ZUFsbCgpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIGdldCByYXdUYXNrcygpOiBHYW50dFRhc2tbXSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jhd1Rhc2tzO1xyXG4gICAgfVxyXG4gICAgQFZpZXdDaGlsZCgnZ2FudHRCb2R5U2Nyb2xsJykgcHJpdmF0ZSBnYW50dEJvZHlTY3JvbGwhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcclxuICAgIEBWaWV3Q2hpbGQoJ2dhbnR0Q29udGVudCcpIHByaXZhdGUgZ2FudHRDb250ZW50ITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcbiAgICBAVmlld0NoaWxkKCdnYW50dFNjcm9sbCcpIHByaXZhdGUgZ2FudHRTY3JvbGwhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcclxuICAgIEBWaWV3Q2hpbGQoJ2xlZnRQYW5lbCcpIHByaXZhdGUgbGVmdFBhbmVsITogRWxlbWVudFJlZjxIVE1MQnV0dG9uRWxlbWVudD47XHJcbiAgICBAVmlld0NoaWxkKCd0aW1lbGluZUhlYWRlcicpIHByaXZhdGUgdGltZWxpbmVIZWFkZXIhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcclxuICAgIEBWaWV3Q2hpbGQoJ2xlZnRCdG4nKSBwcml2YXRlIGxlZnRCdG4hOiBFbGVtZW50UmVmPEhUTUxCdXR0b25FbGVtZW50PjtcclxuICAgIEBWaWV3Q2hpbGQoJ3JpZ2h0QnRuJykgcHJpdmF0ZSByaWdodEJ0biE6IEVsZW1lbnRSZWY8SFRNTEJ1dHRvbkVsZW1lbnQ+O1xyXG4gICAgcHVibGljIHRvb2xiYXJIZWlnaHQ6IG51bWJlciA9IDI3O1xyXG4gICAgcHVibGljIGhvdmVyZWREZXBlbmRlbmN5SWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcbiAgICBwdWJsaWMgc2VsZWN0ZWRUYXNrSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG4gICAgcHVibGljIHRvb2x0aXBUYXNrOiBHYW50dFRhc2sgfCBudWxsID0gbnVsbDtcclxuICAgIHB1YmxpYyB0b29sdGlwWCA9IDA7XHJcbiAgICBwdWJsaWMgdG9vbHRpcFkgPSAwO1xyXG4gICAgcHVibGljIG1heFNsb3RzQWxlcnQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIHB1YmxpYyBsb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgc2hvd0xlZnRCdG4gPSBmYWxzZTtcclxuICAgIHB1YmxpYyBzaG93UmlnaHRCdG4gPSB0cnVlO1xyXG4gICAgcHVibGljIGJ1dHRvbnNIZWlnaHQ6IG51bWJlciA9IDIwO1xyXG4gICAgcHVibGljIHZpZXdUYXNrczogR2FudHRUYXNrVmlld1tdID0gW107XHJcbiAgICBwcml2YXRlIF9yYXdUYXNrczogR2FudHRUYXNrW10gPSBbXTtcclxuICAgIHByaXZhdGUgb3JpZ2luRGF0ZTogbnVtYmVyID0gMDtcclxuICAgIHByaXZhdGUgcmVzaXppbmcgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgc2Nyb2xsSW50ZXJ2YWw6IGFueTtcclxuICAgIHByaXZhdGUgbGFiZWxDb252ZXJ0ZXI6IFNsb3RJbmRleFRvRGF0ZUxhYmVsQ29udmVydGVyIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7IHN1cGVyKCk7IH1cclxuXHJcbiAgICAvLyByZWNhbGN1bGF0ZSBhbGwgR2FudHRcclxuICAgIHByaXZhdGUgcmVjYWxjdWx0ZUFsbCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpO1xyXG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hWaXNpYmxlQ29sdW1ucygpO1xyXG4gICAgICAgICAgICB0aGlzLnNjYWxlU2VsZWN0ZWQgPSB0aGlzLmdldFNjYWxlQ29uZmlnKHRoaXMuZGVmYXVsdFNjYWxlKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFUeXBlICE9PSAnZHVyYXRpb24nKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBiYXNlID0gbmV3IERhdGUoTWF0aC5taW4oLi4udGhpcy5yYXdUYXNrcy5tYXAoKHQpID0+ICh0LnN0YXJ0IGFzIERhdGUpLmdldFRpbWUoKSkpKTtcclxuICAgICAgICAgICAgICAgIHRoaXMub3JpZ2luRGF0ZSA9IHRoaXMuYWxpZ25PcmlnaW5CeVNjYWxlKGJhc2UsIHRoaXMuZGVmYXVsdFNjYWxlKS5nZXRUaW1lKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxhYmVsQ29udmVydGVyID0gbmV3IFNsb3RJbmRleFRvRGF0ZUxhYmVsQ29udmVydGVyKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0ZU1vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcmlnaW5EYXRlLFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2NhbGVTZWxlY3RlZC5zZWNvbmRlcyxcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc05lZ2F0aXZlRGVwZW5kZW5jeVNwYWNlXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZFRhc2tTbG90c0Zyb21EYXRlcygpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sYWJlbENvbnZlcnRlciA9IG5ldyBTbG90SW5kZXhUb0RhdGVMYWJlbENvbnZlcnRlcihcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGVNb2RlLFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3JpZ2luRGF0ZSxcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNjYWxlU2VsZWN0ZWQuc2Vjb25kZXMsXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNOZWdhdGl2ZURlcGVuZGVuY3lTcGFjZVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuYnVpbGRUYXNrU2xvdHNGcm9tRHVyYXRpb24oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmRldGVjdE5lZ2F0aXZlRGVwZW5kZW5jeVNwYWNlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlVGltZWxpbmVTbG90cygpO1xyXG4gICAgICAgICAgICB0aGlzLmdldEFsbERlcGVuZGVuY3lQYXRocygpO1xyXG4gICAgICAgICAgICB0aGlzLmdhbnR0SGVpZ2h0Q2FsY3VsKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZ2FudHRXaWR0aENhbGN1bCgpO1xyXG4gICAgICAgICAgICB0aGlzLnJlY29tcHV0ZUxheW91dCgpO1xyXG4gICAgICAgICAgICB0aGlzLmdhbnR0U2Nyb2xsLm5hdGl2ZUVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5sYXlvdXQuc2Nyb2xsSGVpZ2h0ICsgJ3B4JztcclxuICAgICAgICAgICAgdGhpcy5nYW50dEJvZHlTY3JvbGwubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmxheW91dC5ib2R5SGVpZ2h0ICsgJ3B4JztcclxuICAgICAgICAgICAgdGhpcy50aW1lbGluZUhlYWRlci5uYXRpdmVFbGVtZW50LnN0eWxlLmhlaWdodCA9IHRoaXMuaGVhZGVySGVpZ2h0ICsgJ3B4JztcclxuICAgICAgICAgICAgdGhpcy5nYW50dENvbnRlbnQubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmdhbnR0SGVpZ2h0IC0gdGhpcy5yb3dIZWlnaHQgKyAncHgnO1xyXG4gICAgICAgICAgICB0aGlzLmdhbnR0Q29udGVudC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gdGhpcy5nYW50dFdpZHRoICsgJ3B4JztcclxuICAgICAgICAgICAgdGhpcy5sZWZ0UGFuZWwubmF0aXZlRWxlbWVudC5zdHlsZS53aWR0aCA9IHRoaXMubGVmdFBhbmVsV2lkdGggKyAncHgnO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5idWlsZFZpZXdUYXNrcygpO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVjZW50ZXJTZWxlY3RlZFRhc2soKTtcclxuICAgICAgICAgICAgfSwgMCk7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVuZCA9IHBlcmZvcm1hbmNlLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2ZyYW1lIHRpbWUgaW5jbHVkaW5nIHJlbmRlcjonLCBlbmQgLSBzdGFydCwgJ21zJyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sIDApO1xyXG4gICAgfVxyXG4gICAgXHJcblxyXG4gICAgcHJpdmF0ZSBidWlsZFZpZXdUYXNrcygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBoID0gdGhpcy5yb3dIZWlnaHQgLyAxLjI1O1xyXG5cclxuICAgICAgICB0aGlzLnZpZXdUYXNrcyA9IHRoaXMudGFza3MubWFwKCh0KTogR2FudHRUYXNrVmlldyA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAuLi50LFxyXG4gICAgICAgICAgICAgICAgeDogdGhpcy5nZXRUYXNrWCh0KSxcclxuICAgICAgICAgICAgICAgIHk6IHRoaXMuZ2V0VGFza1kodCksXHJcbiAgICAgICAgICAgICAgICB3aWR0aDogdGhpcy5nZXRUYXNrV2lkdGgodCksXHJcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGgsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY2xpY2sgb24gYnV0dG9uIDEwbSwgaG91ciwgbW9udGhzXHJcbiAgICBwdWJsaWMgc2V0U2NhbGUoc2NhbGU6IEdhbnR0U2NhbGUpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmRlZmF1bHRTY2FsZSA9IHNjYWxlO1xyXG4gICAgICAgIHRoaXMucmVjYWxjdWx0ZUFsbCgpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvLyBpZiB0YXNrIHdhcyBzZWxlY3RlZCBzY3JvbGwgYmFjayB0byBpdFxyXG4gICAgcHJpdmF0ZSByZWNlbnRlclNlbGVjdGVkVGFzaygpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRUYXNrSWQpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmdhbnR0U2Nyb2xsKSByZXR1cm47XHJcbiAgICAgICAgICAgIHRoaXMuZ2FudHRTY3JvbGwubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0ID0gMDtcclxuXHJcbiAgICAgICAgICAgIC8vIGZvcmNlIGhlYWRlciBzeW5jXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnRpbWVsaW5lSGVhZGVyPy5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVsaW5lSGVhZGVyLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5vblNjcm9sbGVkKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCB0YXNrID0gdGhpcy50YXNrcy5maW5kKCh0KSA9PiB0LmlkID09PSB0aGlzLnNlbGVjdGVkVGFza0lkKTtcclxuICAgICAgICBpZiAoIXRhc2sgfHwgIXRoaXMuZ2FudHRTY3JvbGwpIHJldHVybjtcclxuXHJcbiAgICAgICAgLy8gc2Nyb2xsIFhcclxuICAgICAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gdGhpcy5nYW50dFNjcm9sbC5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xyXG4gICAgICAgIGNvbnN0IHRhcmdldFNjcm9sbExlZnQgPSB0aGlzLmdldFRhc2tYKHRhc2spIC0gdmlld3BvcnRXaWR0aCAvIDI7XHJcbiAgICAgICAgdGhpcy5nYW50dFNjcm9sbC5uYXRpdmVFbGVtZW50LnNjcm9sbFRvKHsgbGVmdDogTWF0aC5tYXgodGFyZ2V0U2Nyb2xsTGVmdCwgMCksIGJlaGF2aW9yOiAnYXV0bycgfSk7XHJcblxyXG4gICAgICAgIC8vIHNjcm9sbCBZXHJcbiAgICAgICAgY29uc3Qgdmlld3BvcnRIZWlnaHQgPSB0aGlzLmdhbnR0Qm9keVNjcm9sbC5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodDtcclxuICAgICAgICBjb25zdCB0YXJnZXRUb3AgPSB0YXNrLnJvdyAqIHRoaXMucm93SGVpZ2h0O1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcCA9IHRhcmdldFRvcCAtIHZpZXdwb3J0SGVpZ2h0IC8gMiArIHRoaXMucm93SGVpZ2h0IC8gMjtcclxuICAgICAgICB0aGlzLmdhbnR0Qm9keVNjcm9sbC5uYXRpdmVFbGVtZW50LnNjcm9sbFRvKHsgdG9wOiBNYXRoLm1heChzY3JvbGxUb3AsIDApLCBiZWhhdmlvcjogJ2F1dG8nIH0pO1xyXG5cclxuICAgICAgICB0aGlzLm9uU2Nyb2xsZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBkZXRlY3QgaWYgdGhlcmUgaXMgYSBuZWVkIHRvIGFkZCB0aGUgTi9BIHNsb3QgaW4gb3JkZXIgdG8gYmUgYWJsZSB0byBzaG93IGRlcGVuZGVuY3kgYXJyb3cgYmVmb3JlIDAuXHJcbiAgICBwcml2YXRlIGRldGVjdE5lZ2F0aXZlRGVwZW5kZW5jeVNwYWNlKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IG9yaWdpblRhc2tzID0gdGhpcy50YXNrcy5maWx0ZXIoKHQpID0+ICh0LnN0YXJ0U2xvdCA/PyAwKSA9PT0gMCk7XHJcblxyXG4gICAgICAgIHRoaXMuaGFzTmVnYXRpdmVEZXBlbmRlbmN5U3BhY2UgPSBvcmlnaW5UYXNrcy5zb21lKCh0YXNrKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZyb21SaWdodCA9IHRoaXMuZ2V0UmF3VGFza1godGFzaykgKyB0aGlzLmdldFRhc2tXaWR0aCh0YXNrKTtcclxuICAgICAgICAgICAgcmV0dXJuICh0YXNrLmRlcGVuZGVuY2llcyA/PyBbXSkuc29tZSgoZGVwSWQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy50YXNrcy5maW5kKCh0KSA9PiB0LmlkID09PSBkZXBJZCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldCkgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IHRvTGVmdCA9IHRoaXMuZ2V0UmF3VGFza1godGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgIC8vIHRydWUgaWYgZGVwZW5kZW5jeSBnb2VzIFwiYmFja3dhcmRzXCJcclxuICAgICAgICAgICAgICAgIHJldHVybiB0b0xlZnQgPCBmcm9tUmlnaHQ7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHNjcm9sbCBidXR0b25zIGxlZnQvcmlnaHQgPT4gY2xpY2sgc21hbGwgZ28sIHN0YXkgY2xpY2tlZCBzY3JvbGwgYSBsb3RcclxuICAgIHB1YmxpYyBzdGFydFNjcm9sbChkaXJlY3Rpb246ICdsZWZ0JyB8ICdyaWdodCcpOiB2b2lkIHtcclxuICAgICAgICAvLyBpbnN0YW50IGZpcnN0IG1vdmUgICAgICAgICAgIFxyXG4gICAgICAgIHRoaXMuc2Nyb2xsSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2FudHRTY3JvbGwubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0ICs9IGRpcmVjdGlvbiA9PT0gJ2xlZnQnID8gLTEwMCA6IDEwMDtcclxuICAgICAgICAgICAgdGhpcy5vblNjcm9sbGVkKCk7XHJcbiAgICAgICAgfSwgNTApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHVwZGF0ZSBidXR0b25zIGxlZnQvcmlnaHQgYWZ0ZXIgYSBzY3JvbGwuXHJcbiAgICBwcml2YXRlIG9uU2Nyb2xsZWQoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgZWwgPSB0aGlzLmdhbnR0U2Nyb2xsLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgY29uc3QgbWF4U2Nyb2xsTGVmdCA9IGVsLnNjcm9sbFdpZHRoIC0gZWwuY2xpZW50V2lkdGg7XHJcbiAgICAgICAgLy8gbGVmdCBidXR0b25cclxuICAgICAgICB0aGlzLnNob3dMZWZ0QnRuID0gZWwuc2Nyb2xsTGVmdCA+IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGVmdEJ0bj8ubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5zaG93TGVmdEJ0bikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0QnRuLm5hdGl2ZUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnRCdG4ubmF0aXZlRWxlbWVudC5zdHlsZS5sZWZ0ID0gdGhpcy5sZWZ0UGFuZWwubmF0aXZlRWxlbWVudC5zdHlsZS53aWR0aDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGVmdEJ0bi5uYXRpdmVFbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnRCdG4ubmF0aXZlRWxlbWVudC5zdHlsZS5sZWZ0ID0gdGhpcy5sZWZ0UGFuZWwubmF0aXZlRWxlbWVudC5zdHlsZS53aWR0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyByaWdodCBidXR0b25cclxuICAgICAgICB0aGlzLnNob3dSaWdodEJ0biA9IGVsLnNjcm9sbExlZnQgPCBtYXhTY3JvbGxMZWZ0IC0gMSB8fCBlbC5zY3JvbGxMZWZ0ID09PSAwOyAvLyBzbWFsbCB0b2xlcmFuY2VcclxuICAgICAgICBpZiAodGhpcy5yaWdodEJ0bj8ubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5zaG93UmlnaHRCdG4pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmlnaHRCdG4ubmF0aXZlRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmlnaHRCdG4ubmF0aXZlRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghdGhpcy5zaG93TGVmdEJ0biB8fCAhdGhpcy5zaG93UmlnaHRCdG4pIHtcclxuICAgICAgICAgICAgdGhpcy5zdG9wU2Nyb2xsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdG9wU2Nyb2xsKCk6IHZvaWR7XHJcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnNjcm9sbEludGVydmFsKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyB0byBzeW5jIGhlYWRlciBhbmQgZ3JpZFxyXG4gICAgcHVibGljIG9uSG9yaXpvbnRhbFNjcm9sbChldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnRpbWVsaW5lSGVhZGVyLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLnNjcm9sbExlZnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGlnaGxpZ2h0IGRlcGVuZGVuY2llcyAoYXJyb3dzKVxyXG4gICAgcHJpdmF0ZSB1cGRhdGVIb3ZlcmVkRGVwZW5kZW5jaWVzKHRhc2s6IEdhbnR0VGFzayB8IG51bGwpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmhvdmVyZWREZXBlbmRlbmN5SWRzLmNsZWFyKCk7XHJcbiAgICAgICAgaWYgKCF0YXNrKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG91dGdvaW5nIGRlcGVuZGVuY2llc1xyXG4gICAgICAgIGZvciAoY29uc3QgZGVwIG9mIHRhc2suZGVwZW5kZW5jaWVzID8/IFtdKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaG92ZXJlZERlcGVuZGVuY3lJZHMuYWRkKGAke2RlcH0tPiR7dGFzay5pZH1gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGluY29taW5nIGRlcGVuZGVuY2llc1xyXG4gICAgICAgIGZvciAoY29uc3QgdCBvZiB0aGlzLnRhc2tzKSB7XHJcbiAgICAgICAgICAgIGlmICgodC5kZXBlbmRlbmNpZXMgPz8gW10pLmluY2x1ZGVzKHRhc2suaWQpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmhvdmVyZWREZXBlbmRlbmN5SWRzLmFkZChgJHt0YXNrLmlkfS0+JHt0LmlkfWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHNlbGVjdCB0YXNrIGxlZnQgYW5kIHJpZ2h0IHBhbmVsXHJcbiAgICBwdWJsaWMgc2VsZWN0VGFzayh0YXNrOiBHYW50dFRhc2ssIHNjcm9sbDogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkVGFza0lkID09PSB0YXNrLmlkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUYXNrSWQgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLmhvdmVyZWREZXBlbmRlbmN5SWRzLmNsZWFyKCk7XHJcbiAgICAgICAgICAgIHRoaXMuaGlkZVRvb2x0aXAoKTtcclxuICAgICAgICAgICAgdGhpcy5vblNjcm9sbGVkKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYXNrSWQgPSB0YXNrLmlkO1xyXG4gICAgICAgIHRoaXMudXBkYXRlSG92ZXJlZERlcGVuZGVuY2llcyh0YXNrKTtcclxuICAgICAgICB0aGlzLm9uU2Nyb2xsZWQoKTtcclxuICAgICAgICBpZiAoIXNjcm9sbCB8fCAhdGhpcy5nYW50dFNjcm9sbCkgcmV0dXJuO1xyXG5cclxuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmdhbnR0U2Nyb2xsLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IGNvbnRhaW5lci5jbGllbnRXaWR0aDtcclxuICAgICAgICBjb25zdCB0YXJnZXRTY3JvbGxMZWZ0ID0gdGhpcy5nZXRUYXNrWCh0YXNrKSAtIHZpZXdwb3J0V2lkdGggLyAyO1xyXG5cclxuICAgICAgICBjb250YWluZXIuc2Nyb2xsVG8oe1xyXG4gICAgICAgICAgICBsZWZ0OiBNYXRoLm1heCh0YXJnZXRTY3JvbGxMZWZ0LCAwKSxcclxuICAgICAgICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMub25TY3JvbGxlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJlc2l6ZSBiZXR3ZWVuIHBhbmVsIGxlZnQgYW5kIHJpZ2h0XHJcbiAgICBwdWJsaWMgc3RhcnRSZXNpemUoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcclxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIHRoaXMucmVzaXppbmcgPSB0cnVlO1xyXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lclJlY3QgPSB0aGlzLmdhbnR0Qm9keVNjcm9sbC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIGNvbnN0IGxlZnQgPSBjb250YWluZXJSZWN0LmxlZnQ7XHJcbiAgICAgICAgY29uc3QgbWluID0gNTA7XHJcbiAgICAgICAgY29uc3QgbWF4ID0gY29udGFpbmVyUmVjdC53aWR0aCAtIDc1O1xyXG4gICAgICAgIGNvbnN0IG1vdmVIYW5kbGVyID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlc2l6aW5nKSByZXR1cm47XHJcbiAgICAgICAgICAgIGNvbnN0IHggPSBlLmNsaWVudFggLSBsZWZ0O1xyXG4gICAgICAgICAgICBjb25zdCB3aWR0aCA9IHggPCBtaW4gPyBtaW4gOiB4ID4gbWF4ID8gbWF4IDogeDtcclxuXHJcbiAgICAgICAgICAgIC8vIGRpcmVjdCBET00gdXBkYXRlIChubyBBbmd1bGFyKVxyXG4gICAgICAgICAgICB0aGlzLmxlZnRQYW5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gd2lkdGggKyAncHgnO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5sZWZ0QnRuPy5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnRCdG4ubmF0aXZlRWxlbWVudC5zdHlsZS5sZWZ0ID0gYCR7d2lkdGh9cHhgO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3QgdXBIYW5kbGVyID0gKCk6IHZvaWQgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnJlc2l6aW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBtb3ZlSGFuZGxlcik7XHJcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdXBIYW5kbGVyKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgbW92ZUhhbmRsZXIpO1xyXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdXBIYW5kbGVyKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2hvd1Rvb2x0aXAoZXZlbnQ6IE1vdXNlRXZlbnQsIHRhc2s6IEdhbnR0VGFzayk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudG9vbHRpcFRhc2sgPSB0YXNrO1xyXG4gICAgICAgIGNvbnN0IHRvb2x0aXAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZ2xvYmFsLXRvb2x0aXAnKSBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgICBpZiAoIXRvb2x0aXApIHJldHVybjtcclxuICAgICAgICB0b29sdGlwLnN0eWxlLmxlZnQgPSBgJHtldmVudC5jbGllbnRYICsgMTB9cHhgO1xyXG4gICAgICAgIHRvb2x0aXAuc3R5bGUudG9wID0gYCR7ZXZlbnQuY2xpZW50WSAtIDUwfXB4YDtcclxuICAgICAgICB0b29sdGlwLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBoaWRlVG9vbHRpcCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnRvb2x0aXBUYXNrID0gbnVsbDtcclxuICAgICAgICBjb25zdCB0b29sdGlwID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmdsb2JhbC10b29sdGlwJykgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgaWYgKCF0b29sdGlwKSByZXR1cm47XHJcbiAgICAgICAgdG9vbHRpcC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYnVpbGRUYXNrU2xvdHNGcm9tRGF0ZXMoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3Qgc2xvdE1zID0gdGhpcy5zY2FsZVNlbGVjdGVkLnNlY29uZGVzICogMTAwMDtcclxuICAgICAgICB0aGlzLnRhc2tzID0gdGhpcy5yYXdUYXNrcy5tYXAoKHQpID0+IHtcclxuICAgICAgICAgICAgaWYgKCEodC5zdGFydCBpbnN0YW5jZW9mIERhdGUpIHx8ICEodC5lbmQgaW5zdGFuY2VvZiBEYXRlKSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUYXNrIFwiJHt0LmlkfVwiIG11c3QgaGF2ZSBEYXRlIHN0YXJ0L2VuZCB2YWx1ZXMuYCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0U2xvdCA9ICgodC5zdGFydCBhcyBEYXRlKS5nZXRUaW1lKCkgLSB0aGlzLm9yaWdpbkRhdGUpIC8gc2xvdE1zO1xyXG4gICAgICAgICAgICBjb25zdCBlbmRTbG90ID0gKCh0LmVuZCBhcyBEYXRlKS5nZXRUaW1lKCkgLSB0aGlzLm9yaWdpbkRhdGUpIC8gc2xvdE1zO1xyXG4gICAgICAgICAgICByZXR1cm4geyAuLi50LCBzdGFydFNsb3QsIGVuZFNsb3QgfTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGJ1aWxkVGFza1Nsb3RzRnJvbUR1cmF0aW9uKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudGFza3MgPSB0aGlzLnJhd1Rhc2tzLm1hcCgodCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHQuc3RhcnQgIT09ICdudW1iZXInIHx8IHR5cGVvZiB0LmVuZCAhPT0gJ251bWJlcicpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGFzayBcIiR7dC5pZH1cIiBtdXN0IGhhdmUgbnVtZXJpYyBzdGFydC9lbmQgdmFsdWVzIGV4cHJlc3NlZCBpbiBtaW51dGVzLmApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBzdGFydFNsb3QgPSB0LnN0YXJ0IC8gdGhpcy5zY2FsZVNlbGVjdGVkLnNlY29uZGVzO1xyXG4gICAgICAgICAgICBjb25zdCBlbmRTbG90ID0gdC5lbmQgLyB0aGlzLnNjYWxlU2VsZWN0ZWQuc2Vjb25kZXM7XHJcbiAgICAgICAgICAgIHJldHVybiB7IC4uLnQsIHN0YXJ0U2xvdCwgZW5kU2xvdCB9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGdldCBhbGwgc2xvdHMgKHRpbWVsaW5lKVxyXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVUaW1lbGluZVNsb3RzKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IG1heFNsb3QgPSBNYXRoLm1heCguLi50aGlzLnRhc2tzLm1hcCh0ID0+IHQuZW5kU2xvdCA/PyAwKSk7XHJcbiAgICAgICAgaWYgKG1heFNsb3QgPiA1MzAwMCkge1xyXG4gICAgICAgICAgICB0aGlzLm1heFNsb3RzQWxlcnQgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLnNsb3RzID0gW107XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5tYXhTbG90c0FsZXJ0ID0gZmFsc2U7XHJcbiAgICAgICAgY29uc3QgYnVmZmVyID0gW107XHJcbiAgICAgICAgbGV0IG9mZnNldFggPSAwO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5oYXNOZWdhdGl2ZURlcGVuZGVuY3lTcGFjZSkge1xyXG4gICAgICAgICAgICBidWZmZXIucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBpbmRleDogLTEsXHJcbiAgICAgICAgICAgICAgICB4OiAwLFxyXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMubmVnYXRpdmVTbG90V2lkdGgsXHJcbiAgICAgICAgICAgICAgICBsYWJlbDogJ04vQSdcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG9mZnNldFggPSB0aGlzLm5lZ2F0aXZlU2xvdFdpZHRoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gbWF4U2xvdCArIDI7IGkrKykge1xyXG4gICAgICAgICAgICBidWZmZXIucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBpbmRleDogaSxcclxuICAgICAgICAgICAgICAgIHg6IG9mZnNldFggKyBpICogdGhpcy5zY2FsZVNlbGVjdGVkLnB4LFxyXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMuc2NhbGVTZWxlY3RlZC5weCxcclxuICAgICAgICAgICAgICAgIGxhYmVsOiB0aGlzLmdldFNsb3RMYWJlbChpKSA/PyAnRXJyb3InLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc2xvdHMgPSBidWZmZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZ2V0IGFsbCBwYXRocyBvZiBhcnJvd3NcclxuICAgIHByb3RlY3RlZCBnZXRBbGxEZXBlbmRlbmN5UGF0aHMoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5kZXBlbmRlbmN5UGF0aHMgPSB0aGlzLnRhc2tzLmZsYXRNYXAoKHRhc2spOiBEZXBlbmRlbmN5UGF0aFtdID0+XHJcbiAgICAgICAgICAgICh0YXNrLmRlcGVuZGVuY2llcyA/PyBbXSkubWFwKFxyXG4gICAgICAgICAgICAgICAgKGRlcDogYW55KTogRGVwZW5kZW5jeVBhdGggPT4gKHtcclxuICAgICAgICAgICAgICAgICAgICBmcm9tOiBkZXAsXHJcbiAgICAgICAgICAgICAgICAgICAgdG86IHRhc2suaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGAke2RlcH0tPiR7dGFzay5pZH1gLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IHRoaXMuZ2V0RGVwZW5kZW5jeVBhdGgoZGVwLCB0YXNrLmlkKSxcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGdldCBsYWJlbCBmb3IgZGF0ZSBoZWFkZXJcclxuICAgIHByaXZhdGUgZ2V0U2xvdExhYmVsKGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICh0aGlzLmRhdGFUeXBlID09PSAnY2FsZW5kYXInKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxhYmVsQ29udmVydGVyPy5nZXRMYWJlbENhbGVuZGFyKGluZGV4LCB0aGlzLmRlZmF1bHRTY2FsZSkgPz8gJ0Vycm9yJztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGFiZWxDb252ZXJ0ZXI/LmdldExhYmVsRHVyYXRpb24oaW5kZXgsIHRoaXMuZGVmYXVsdFNjYWxlKSA/PyAnRXJyb3InO1xyXG4gICAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJnYW50dC1yb290XCIgW3N0eWxlLm1heC1oZWlnaHQucHhdPVwibGF5b3V0LnJvb3RNYXhIZWlnaHRcIiBbc3R5bGUubWluLWhlaWdodC5weF09XCIxMDBcIj5cbiAgICA8IS0tIFRPT0xCQVIgLS0+XG4gICAgPGRpdiBjbGFzcz1cInRvb2xiYXJcIiBbc3R5bGUuaGVpZ2h0LnB4XT1cImJ1dHRvbnNIZWlnaHRcIj5cbiAgICAgICAgPGRpdiAqbmdJZj1cImRhdGVNb2RlID09PSAndXRjJyB8fCBkYXRhVHlwZSA9PT0gJ2R1cmF0aW9uJ1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImdhbnR0LWJ1dHRvblwiICpuZ0Zvcj1cImxldCBzIG9mIHNjYWxlc1wiIChjbGljayk9XCJzZXRTY2FsZShzKVwiIFtjbGFzcy5hY3RpdmVdPVwiZGVmYXVsdFNjYWxlID09PSBzXCI+XG4gICAgICAgICAgICAgICAge3sgcyB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiZGF0ZU1vZGUgIT09ICd1dGMnICYmIGRhdGFUeXBlID09PSAnY2FsZW5kYXInXCI+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZ2FudHQtYnV0dG9uXCIgKm5nRm9yPVwibGV0IHMgb2Ygc2NhbGVzRGF0ZVwiIChjbGljayk9XCJzZXRTY2FsZShzKVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJkZWZhdWx0U2NhbGUgPT09IHNcIj5cbiAgICAgICAgICAgICAgICB7eyBzIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxsYWJlbCAqbmdJZj1cIm1heFNsb3RzQWxlcnRcIiBzdHlsZT1cImNvbG9yOiByZWQ7XCI+XG4gICAgICAgICAgICBEYXRhIGlzIHRvbyBtYXNzaXZlIHRvIHNob3cgR2FudHQgc21vb3RobHksIHRyeSBjaGFuZ2luZyB0aGUgc2NhbGVcbiAgICAgICAgPC9sYWJlbD5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIFRPT0xUSVAgLS0+XG4gICAgPGRpdiBjbGFzcz1cImdsb2JhbC10b29sdGlwXCIgW3N0eWxlLmRpc3BsYXldPVwidG9vbHRpcFRhc2sgPyAnYmxvY2snIDogJ25vbmUnXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0b29sdGlwVGFzayBhcyB0YXNrXCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgdmlzaWJsZVRvb2x0aXBDb2x1bW5zXCI+XG4gICAgICAgICAgICAgICAgPHN0cm9uZz57eyBjb2x1bW4/LnRpdGxlIH19Ojwvc3Ryb25nPlxuICAgICAgICAgICAgICAgIHt7IGNvbHVtbj8udmFsdWVHZXR0ZXIodGFzaykgfX1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIEJVVFRPTlMgRk9SIFNDUk9MTCBHQU5UVCAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwiIW1heFNsb3RzQWxlcnQgJiYgbG9hZGluZyA9PT0gZmFsc2VcIiBjbGFzcz1cImZsb2F0aW5nLW5hdlwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwibmF2LWJ0biBsZWZ0XCIgKG1vdXNlZG93bik9XCJzdGFydFNjcm9sbCgnbGVmdCcpXCJcbiAgICAgICAgICAgIChtb3VzZXVwKT1cInN0b3BTY3JvbGwoKVwiIChtb3VzZWxlYXZlKT1cInN0b3BTY3JvbGwoKVwiICNsZWZ0QnRuID5cbiAgICAgICAgICAgIOKAuVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cIm5hdi1idG4gcmlnaHRcIiAobW91c2Vkb3duKT1cInN0YXJ0U2Nyb2xsKCdyaWdodCcpXCJcbiAgICAgICAgICAgIChtb3VzZXVwKT1cInN0b3BTY3JvbGwoKVwiIChtb3VzZWxlYXZlKT1cInN0b3BTY3JvbGwoKVwiICNyaWdodEJ0bj5cbiAgICAgICAgICAgIOKAulxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIExPQURJTkcgLS0+XG4gICAgPGRpdiBjbGFzcz1cImxvYWRpbmctb3ZlcmxheVwiICpuZ0lmPVwibG9hZGluZ1wiIFtzdHlsZS50b3BdPVwiJzUwJSdcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXJcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIFNJTkdMRSBWRVJUSUNBTCBTQ1JPTEwgLS0+XG4gICAgPGRpdiBjbGFzcz1cImdhbnR0LWJvZHlcIiAjZ2FudHRCb2R5U2Nyb2xsPlxuICAgICAgICA8IS0tIExFRlQgUEFORUwgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJsZWZ0LXBhbmVsXCIgI2xlZnRQYW5lbD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YXNrLXJvdyBoZWFkZXJcIiBbc3R5bGUuaGVpZ2h0LnB4XT1cImhlYWRlckhlaWdodFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZWxsXCIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiB2aXNpYmxlR3JpZENvbHVtbnNcIiBbc3R5bGUud2lkdGgucHhdPVwiY29sdW1uLndpZHRoIHx8IDEyMFwiPlxuICAgICAgICAgICAgICAgICAgICB7eyBjb2x1bW4/LnRpdGxlIH19XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YXNrLXJvd1wiICpuZ0Zvcj1cImxldCB0YXNrIG9mIHRhc2tzXCIgW3N0eWxlLmhlaWdodC5weF09XCJyb3dIZWlnaHRcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RUYXNrKHRhc2ssIHRydWUpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5oaWdobGlnaHRlZC1yb3ddPVwic2VsZWN0ZWRUYXNrSWQgPT09IHRhc2suaWRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2VsbFwiICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgdmlzaWJsZUdyaWRDb2x1bW5zXCIgW3N0eWxlLndpZHRoLnB4XT1cImNvbHVtbi53aWR0aCB8fCAxMjBcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgY29sdW1uPy52YWx1ZUdldHRlcih0YXNrKSB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8IS0tIFJFU0laRVIgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemVyXCIgW3N0eWxlLmhlaWdodC5weF09XCJsYXlvdXQucmVzaXplckhlaWdodFwiIChtb3VzZWRvd24pPVwic3RhcnRSZXNpemUoJGV2ZW50KVwiPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPCEtLSBSSUdIVCBQQU5FTCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0LXBhbmVsXCIgKm5nSWY9XCIhbWF4U2xvdHNBbGVydFwiPlxuICAgICAgICAgICAgPCEtLSBUSU1FTElORSAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lbGluZS1oZWFkZXJcIiAjdGltZWxpbmVIZWFkZXI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWVsaW5lLXNsb3RcIiAqbmdGb3I9XCJsZXQgc2xvdCBvZiBzbG90c1wiIFtzdHlsZS53aWR0aC5weF09XCJzbG90LndpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IHNsb3QubGFiZWwgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPCEtLSBIT1JJWk9OVEFMIFNDUk9MTCBPTkxZIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhvcml6b250YWwtc2Nyb2xsXCIgKHNjcm9sbCk9XCJvbkhvcml6b250YWxTY3JvbGwoJGV2ZW50KVwiICNnYW50dFNjcm9sbD5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ2FudHQtY29udGVudFwiICNnYW50dENvbnRlbnQ+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gR1JJRCAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtbGF5ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHNsb3Qgb2Ygc2xvdHM7IGxldCBpID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiIGNsYXNzPVwiZ3JpZC1saW5lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubGVmdC5weF09XCJzbG90LnggLSAxXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gZmluYWwgdmVydGljYWwgbGluZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkLWxpbmVcIiBbc3R5bGUubGVmdC5weF09XCJnYW50dFdpZHRoIC0gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGhvcml6b250YWwgbGluZXMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaG9yaXpvbnRhbC1ncmlkLWxheWVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdGFzayBvZiB0YXNrczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUluZGV4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJob3Jpem9udGFsLWxpbmVcIiBbc3R5bGUudG9wLnB4XT1cImdldEdyaWRUb3AoaSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZpbmFsIGhvcml6b250YWwgbGluZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaG9yaXpvbnRhbC1saW5lXCIgW3N0eWxlLnRvcC5weF09XCJnYW50dEhlaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8IS0tIFRBU0tTIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFza3MtbGF5ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHRhc2sgb2Ygdmlld1Rhc2tzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIiBjbGFzcz1cInRhc2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtb3VzZWVudGVyKT1cInNob3dUb29sdGlwKCRldmVudCwgdGFzaylcIiAobW91c2VsZWF2ZSk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VGFzayh0YXNrLCBmYWxzZSk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmhpZ2hsaWdodGVkLXRhc2tdPVwic2VsZWN0ZWRUYXNrSWQgPT09IHRhc2suaWRcIiBbc3R5bGUubGVmdC5weF09XCJ0YXNrLnhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwidGFzay55XCIgW3N0eWxlLndpZHRoLnB4XT1cInRhc2sud2lkdGhcIiBbc3R5bGUuaGVpZ2h0LnB4XT1cInRhc2suaGVpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhc2stbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdGFzay5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8IS0tIERFUEVOREVOQ0lFUyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImRlcGVuZGVuY2llcy1zdmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkZWZzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXJrZXIgaWQ9XCJhcnJvd1wiIHZpZXdCb3g9XCIwIDAgMTAgMTBcIiByZWZYPVwiOVwiIHJlZlk9XCI1XCIgbWFya2VyV2lkdGg9XCI2XCIgbWFya2VySGVpZ2h0PVwiNlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudD1cImF1dG9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0gMCAwIEwgMTAgNSBMIDAgMTAgelwiIGZpbGw9XCIjODY4ZDk3XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hcmtlcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGVmcz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxnIGNsYXNzPVwiZGVwZW5kZW5jaWVzLW5vcm1hbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoICpuZ0Zvcj1cImxldCBkZXAgb2YgZGVwZW5kZW5jeVBhdGhzXCIgW2F0dHIuZF09XCJkZXAucGF0aFwiIGNsYXNzPVwiZGVwZW5kZW5jeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5oaWRkZW5dPVwiaG92ZXJlZERlcGVuZGVuY3lJZHMuaGFzKGRlcC5pZClcIiBtYXJrZXItZW5kPVwidXJsKCNhcnJvdylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3BhdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZyBjbGFzcz1cImRlcGVuZGVuY2llcy1oaWdobGlnaHRlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoICpuZ0Zvcj1cImxldCBkZXAgb2YgZGVwZW5kZW5jeVBhdGhzXCIgW2F0dHIuZF09XCJkZXAucGF0aFwiIGNsYXNzPVwiaGlnaGxpZ2h0ZWQtZGVwZW5kZW5jeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5oaWRkZW5dPVwiIWhvdmVyZWREZXBlbmRlbmN5SWRzLmhhcyhkZXAuaWQpXCIgbWFya2VyLWVuZD1cInVybCgjYXJyb3cpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wYXRoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0LXBhbmVsLWRlYWRcIiAqbmdJZj1cIm1heFNsb3RzQWxlcnRcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PiJdfQ==
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export class SlotIndexToDateLabelConverter {
|
|
2
|
+
constructor(dateMode, originDate, slotSeconds, hasNegativeDependencySpace) {
|
|
3
|
+
this.dateMode = dateMode;
|
|
4
|
+
this.originDate = originDate;
|
|
5
|
+
this.slotSeconds = slotSeconds;
|
|
6
|
+
this.hasNegativeDependencySpace = hasNegativeDependencySpace;
|
|
7
|
+
this.initFormatters();
|
|
8
|
+
}
|
|
9
|
+
initFormatters() {
|
|
10
|
+
this.timeFormatter = new Intl.DateTimeFormat([], {
|
|
11
|
+
timeZone: this.dateMode === 'utc' ? 'UTC' : undefined,
|
|
12
|
+
day: '2-digit',
|
|
13
|
+
month: '2-digit',
|
|
14
|
+
year: 'numeric',
|
|
15
|
+
hour: '2-digit',
|
|
16
|
+
minute: '2-digit',
|
|
17
|
+
hour12: false
|
|
18
|
+
});
|
|
19
|
+
this.dayFormatter = new Intl.DateTimeFormat([], {
|
|
20
|
+
timeZone: this.dateMode === 'utc' ? 'UTC' : undefined,
|
|
21
|
+
day: '2-digit',
|
|
22
|
+
month: '2-digit',
|
|
23
|
+
year: 'numeric'
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
get slotMs() {
|
|
27
|
+
return this.slotSeconds * 1000;
|
|
28
|
+
}
|
|
29
|
+
indexToDate(index) {
|
|
30
|
+
const realIndex = this.hasNegativeDependencySpace && index > 0 ? index - 1 : index;
|
|
31
|
+
return new Date(this.originDate + realIndex * this.slotMs);
|
|
32
|
+
}
|
|
33
|
+
getLabelCalendar(index, scale) {
|
|
34
|
+
if (this.hasNegativeDependencySpace && index === 0) {
|
|
35
|
+
return 'N/A';
|
|
36
|
+
}
|
|
37
|
+
const date = this.indexToDate(index);
|
|
38
|
+
switch (scale) {
|
|
39
|
+
case '1m':
|
|
40
|
+
case '10m':
|
|
41
|
+
case '30m':
|
|
42
|
+
case 'hour':
|
|
43
|
+
case '6 hours':
|
|
44
|
+
case '12 hours':
|
|
45
|
+
return this.formatTime(date);
|
|
46
|
+
case 'day':
|
|
47
|
+
return this.formatDay(date);
|
|
48
|
+
case 'week':
|
|
49
|
+
return this.formatRange(date, 7);
|
|
50
|
+
case 'month':
|
|
51
|
+
return this.formatMonthRange(date);
|
|
52
|
+
case 'year':
|
|
53
|
+
return this.formatYearRange(date);
|
|
54
|
+
default:
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
getLabelDuration(index, scale) {
|
|
59
|
+
if (index === -1) {
|
|
60
|
+
return 'N/A';
|
|
61
|
+
}
|
|
62
|
+
switch (scale) {
|
|
63
|
+
case '1m':
|
|
64
|
+
return `${index * 1}m`;
|
|
65
|
+
case '10m':
|
|
66
|
+
return `${index * 10}m`;
|
|
67
|
+
case '30m':
|
|
68
|
+
return `${index * 30}m`;
|
|
69
|
+
case 'hour':
|
|
70
|
+
return `${index}h`;
|
|
71
|
+
case '6 hours':
|
|
72
|
+
return `${index * 6}h`;
|
|
73
|
+
case '12 hours':
|
|
74
|
+
return `${index * 12}h`;
|
|
75
|
+
case 'day':
|
|
76
|
+
return `${index}D`;
|
|
77
|
+
case 'week':
|
|
78
|
+
return `${index * 7}D - ${index * 7 + 7}D`;
|
|
79
|
+
case 'month':
|
|
80
|
+
return `${index * 30}D - ${index * 30 + 30}D`;
|
|
81
|
+
case 'year':
|
|
82
|
+
return `${index * 365}D - ${index * 365 + 365}D`;
|
|
83
|
+
default:
|
|
84
|
+
return '';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
formatTime(date) {
|
|
88
|
+
return this.timeFormatter.format(date);
|
|
89
|
+
}
|
|
90
|
+
formatDay(date) {
|
|
91
|
+
return this.dayFormatter.format(date);
|
|
92
|
+
}
|
|
93
|
+
formatRange(start, days) {
|
|
94
|
+
const end = new Date(start);
|
|
95
|
+
end.setDate(end.getDate() + days);
|
|
96
|
+
return `${start.toLocaleDateString()} - ${end.toLocaleDateString()}`;
|
|
97
|
+
}
|
|
98
|
+
formatMonthRange(start) {
|
|
99
|
+
const date = new Date(start);
|
|
100
|
+
date.setDate(1);
|
|
101
|
+
return date.toLocaleDateString();
|
|
102
|
+
}
|
|
103
|
+
formatYearRange(start) {
|
|
104
|
+
return `${start.toLocaleDateString()}`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQtbGl0ZS5oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nYW50dC1saXRlL3NyYy9saWIvZ2FudHQtbGl0ZS5oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFPLDZCQUE2QjtJQUd0QyxZQUNZLFFBQWtCLEVBQ2xCLFVBQWtCLEVBQ2xCLFdBQW1CLEVBQ25CLDBCQUFtQztRQUhuQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xCLGVBQVUsR0FBVixVQUFVLENBQVE7UUFDbEIsZ0JBQVcsR0FBWCxXQUFXLENBQVE7UUFDbkIsK0JBQTBCLEdBQTFCLDBCQUEwQixDQUFTO1FBRTNDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRU8sY0FBYztRQUN0QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQUU7WUFDN0MsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDckQsR0FBRyxFQUFFLFNBQVM7WUFDZCxLQUFLLEVBQUUsU0FBUztZQUNoQixJQUFJLEVBQUUsU0FBUztZQUNmLElBQUksRUFBRSxTQUFTO1lBQ2YsTUFBTSxFQUFFLFNBQVM7WUFDakIsTUFBTSxFQUFFLEtBQUs7U0FDaEIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRSxFQUFFO1lBQzVDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ3JELEdBQUcsRUFBRSxTQUFTO1lBQ2QsS0FBSyxFQUFFLFNBQVM7WUFDaEIsSUFBSSxFQUFFLFNBQVM7U0FDbEIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVHLElBQVksTUFBTTtRQUNkLE9BQU8sSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDbkMsQ0FBQztJQUVPLFdBQVcsQ0FBQyxLQUFhO1FBQzdCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQywwQkFBMEIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDbkYsT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVNLGdCQUFnQixDQUFDLEtBQWEsRUFBRSxLQUFhO1FBQ2hELElBQUksSUFBSSxDQUFDLDBCQUEwQixJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNqRCxPQUFPLEtBQUssQ0FBQztRQUNqQixDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxRQUFRLEtBQUssRUFBRSxDQUFDO1lBQ1osS0FBSyxJQUFJLENBQUM7WUFDVixLQUFLLEtBQUssQ0FBQztZQUNYLEtBQUssS0FBSyxDQUFDO1lBQ1gsS0FBSyxNQUFNLENBQUM7WUFDWixLQUFLLFNBQVMsQ0FBQztZQUNmLEtBQUssVUFBVTtnQkFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDakMsS0FBSyxLQUFLO2dCQUNOLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoQyxLQUFLLE1BQU07Z0JBQ1AsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNyQyxLQUFLLE9BQU87Z0JBQ1IsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsS0FBSyxNQUFNO2dCQUNQLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QztnQkFDSSxPQUFPLEVBQUUsQ0FBQztRQUNsQixDQUFDO0lBQ0wsQ0FBQztJQUVNLGdCQUFnQixDQUFDLEtBQWEsRUFBRSxLQUFhO1FBQ2hELElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDZixPQUFPLEtBQUssQ0FBQztRQUNqQixDQUFDO1FBRUQsUUFBUSxLQUFLLEVBQUUsQ0FBQztZQUNaLEtBQUssSUFBSTtnQkFDTCxPQUFPLEdBQUcsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDO1lBQzNCLEtBQUssS0FBSztnQkFDTixPQUFPLEdBQUcsS0FBSyxHQUFHLEVBQUUsR0FBRyxDQUFDO1lBQzVCLEtBQUssS0FBSztnQkFDTixPQUFPLEdBQUcsS0FBSyxHQUFHLEVBQUUsR0FBRyxDQUFDO1lBQzVCLEtBQUssTUFBTTtnQkFDUCxPQUFPLEdBQUcsS0FBSyxHQUFHLENBQUM7WUFDdkIsS0FBSyxTQUFTO2dCQUNWLE9BQU8sR0FBRyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUM7WUFDM0IsS0FBSyxVQUFVO2dCQUNYLE9BQU8sR0FBRyxLQUFLLEdBQUcsRUFBRSxHQUFHLENBQUM7WUFDNUIsS0FBSyxLQUFLO2dCQUNOLE9BQU8sR0FBRyxLQUFLLEdBQUcsQ0FBQztZQUN2QixLQUFLLE1BQU07Z0JBQ1AsT0FBTyxHQUFHLEtBQUssR0FBRyxDQUFDLE9BQU8sS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztZQUMvQyxLQUFLLE9BQU87Z0JBQ1IsT0FBTyxHQUFHLEtBQUssR0FBRyxFQUFFLE9BQU8sS0FBSyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQztZQUNsRCxLQUFLLE1BQU07Z0JBQ1AsT0FBTyxHQUFHLEtBQUssR0FBRyxHQUFHLE9BQU8sS0FBSyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztZQUNyRDtnQkFDSSxPQUFPLEVBQUUsQ0FBQztRQUNsQixDQUFDO0lBQ0wsQ0FBQztJQUVPLFVBQVUsQ0FBQyxJQUFVO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVPLFNBQVMsQ0FBQyxJQUFVO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVPLFdBQVcsQ0FBQyxLQUFXLEVBQUUsSUFBWTtRQUN6QyxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUNsQyxPQUFPLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixFQUFFLE1BQU0sR0FBRyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztJQUN6RSxDQUFDO0lBRUssZ0JBQWdCLENBQUMsS0FBVztRQUM5QixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDckMsQ0FBQztJQUVPLGVBQWUsQ0FBQyxLQUFXO1FBQy9CLE9BQU8sR0FBRyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO0lBQzNDLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGVNb2RlLCBHYW50dFNjYWxlLCBTY2FsZUNvbmZpZyB9IGZyb20gXCIuL2dhbnR0LWxpdGUubW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIFNsb3RJbmRleFRvRGF0ZUxhYmVsQ29udmVydGVyIHtcbiAgICBwcml2YXRlIHRpbWVGb3JtYXR0ZXIhOiBJbnRsLkRhdGVUaW1lRm9ybWF0O1xuICAgIHByaXZhdGUgZGF5Rm9ybWF0dGVyITogSW50bC5EYXRlVGltZUZvcm1hdDtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBkYXRlTW9kZTogRGF0ZU1vZGUsXG4gICAgICAgIHByaXZhdGUgb3JpZ2luRGF0ZTogbnVtYmVyLFxuICAgICAgICBwcml2YXRlIHNsb3RTZWNvbmRzOiBudW1iZXIsXG4gICAgICAgIHByaXZhdGUgaGFzTmVnYXRpdmVEZXBlbmRlbmN5U3BhY2U6IGJvb2xlYW5cbiAgICApIHtcbiAgICAgICAgdGhpcy5pbml0Rm9ybWF0dGVycygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdEZvcm1hdHRlcnMoKTogdm9pZCB7XG4gICAgdGhpcy50aW1lRm9ybWF0dGVyID0gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQoW10sIHtcbiAgICAgICAgdGltZVpvbmU6IHRoaXMuZGF0ZU1vZGUgPT09ICd1dGMnID8gJ1VUQycgOiB1bmRlZmluZWQsXG4gICAgICAgIGRheTogJzItZGlnaXQnLFxuICAgICAgICBtb250aDogJzItZGlnaXQnLFxuICAgICAgICB5ZWFyOiAnbnVtZXJpYycsXG4gICAgICAgIGhvdXI6ICcyLWRpZ2l0JyxcbiAgICAgICAgbWludXRlOiAnMi1kaWdpdCcsXG4gICAgICAgIGhvdXIxMjogZmFsc2VcbiAgICB9KTtcblxuICAgIHRoaXMuZGF5Rm9ybWF0dGVyID0gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQoW10sIHtcbiAgICAgICAgdGltZVpvbmU6IHRoaXMuZGF0ZU1vZGUgPT09ICd1dGMnID8gJ1VUQycgOiB1bmRlZmluZWQsXG4gICAgICAgIGRheTogJzItZGlnaXQnLFxuICAgICAgICBtb250aDogJzItZGlnaXQnLFxuICAgICAgICB5ZWFyOiAnbnVtZXJpYydcbiAgICB9KTtcbn1cblxuICAgIHByaXZhdGUgZ2V0IHNsb3RNcygpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5zbG90U2Vjb25kcyAqIDEwMDA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbmRleFRvRGF0ZShpbmRleDogbnVtYmVyKTogRGF0ZSB7XG4gICAgICAgIGNvbnN0IHJlYWxJbmRleCA9IHRoaXMuaGFzTmVnYXRpdmVEZXBlbmRlbmN5U3BhY2UgJiYgaW5kZXggPiAwID8gaW5kZXggLSAxIDogaW5kZXg7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZSh0aGlzLm9yaWdpbkRhdGUgKyByZWFsSW5kZXggKiB0aGlzLnNsb3RNcyk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldExhYmVsQ2FsZW5kYXIoaW5kZXg6IG51bWJlciwgc2NhbGU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0aGlzLmhhc05lZ2F0aXZlRGVwZW5kZW5jeVNwYWNlICYmIGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gJ04vQSc7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5pbmRleFRvRGF0ZShpbmRleCk7XG4gICAgICAgIHN3aXRjaCAoc2NhbGUpIHtcbiAgICAgICAgICAgIGNhc2UgJzFtJzpcbiAgICAgICAgICAgIGNhc2UgJzEwbSc6XG4gICAgICAgICAgICBjYXNlICczMG0nOlxuICAgICAgICAgICAgY2FzZSAnaG91cic6XG4gICAgICAgICAgICBjYXNlICc2IGhvdXJzJzpcbiAgICAgICAgICAgIGNhc2UgJzEyIGhvdXJzJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRUaW1lKGRhdGUpO1xuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXREYXkoZGF0ZSk7XG4gICAgICAgICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRSYW5nZShkYXRlLCA3KTtcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRNb250aFJhbmdlKGRhdGUpO1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0WWVhclJhbmdlKGRhdGUpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0TGFiZWxEdXJhdGlvbihpbmRleDogbnVtYmVyLCBzY2FsZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgcmV0dXJuICdOL0EnO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoIChzY2FsZSkge1xuICAgICAgICAgICAgY2FzZSAnMW0nOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpbmRleCAqIDF9bWA7XG4gICAgICAgICAgICBjYXNlICcxMG0nOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpbmRleCAqIDEwfW1gO1xuICAgICAgICAgICAgY2FzZSAnMzBtJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aW5kZXggKiAzMH1tYDtcbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpbmRleH1oYDtcbiAgICAgICAgICAgIGNhc2UgJzYgaG91cnMnOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpbmRleCAqIDZ9aGA7XG4gICAgICAgICAgICBjYXNlICcxMiBob3Vycyc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke2luZGV4ICogMTJ9aGA7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpbmRleH1EYDtcbiAgICAgICAgICAgIGNhc2UgJ3dlZWsnOlxuICAgICAgICAgICAgICAgIHJldHVybiBgJHtpbmRleCAqIDd9RCAtICR7aW5kZXggKiA3ICsgN31EYDtcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aW5kZXggKiAzMH1EIC0gJHtpbmRleCAqIDMwICsgMzB9RGA7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYCR7aW5kZXggKiAzNjV9RCAtICR7aW5kZXggKiAzNjUgKyAzNjV9RGA7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZm9ybWF0VGltZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGltZUZvcm1hdHRlci5mb3JtYXQoZGF0ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmb3JtYXREYXkoZGF0ZTogRGF0ZSk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmRheUZvcm1hdHRlci5mb3JtYXQoZGF0ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmb3JtYXRSYW5nZShzdGFydDogRGF0ZSwgZGF5czogbnVtYmVyKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgZW5kID0gbmV3IERhdGUoc3RhcnQpO1xuICAgICAgICBlbmQuc2V0RGF0ZShlbmQuZ2V0RGF0ZSgpICsgZGF5cyk7XG4gICAgICAgIHJldHVybiBgJHtzdGFydC50b0xvY2FsZURhdGVTdHJpbmcoKX0gLSAke2VuZC50b0xvY2FsZURhdGVTdHJpbmcoKX1gO1xuICAgIH1cblxuICBwcml2YXRlIGZvcm1hdE1vbnRoUmFuZ2Uoc3RhcnQ6IERhdGUpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoc3RhcnQpO1xuICAgICAgICBkYXRlLnNldERhdGUoMSk7XG4gICAgICAgIHJldHVybiBkYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZm9ybWF0WWVhclJhbmdlKHN0YXJ0OiBEYXRlKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGAke3N0YXJ0LnRvTG9jYWxlRGF0ZVN0cmluZygpfWA7XG4gICAgfVxufVxuIl19
|