@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,290 @@
|
|
|
1
|
+
import { Directive, Input } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export class GanttLiteBase {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.rowHeight = 40;
|
|
6
|
+
this.defaultScale = 'day';
|
|
7
|
+
this.dataType = 'duration';
|
|
8
|
+
this.dateMode = 'local';
|
|
9
|
+
this.extraColumns = [];
|
|
10
|
+
this.slots = [];
|
|
11
|
+
this.tasks = [];
|
|
12
|
+
this.dependencyPaths = [];
|
|
13
|
+
this.scaleSelected = this.getScaleConfig(this.defaultScale);
|
|
14
|
+
this.headerHeight = 32;
|
|
15
|
+
this.ganttHeight = 0;
|
|
16
|
+
this.ganttWidth = 0;
|
|
17
|
+
this.leftPanelWidth = 320;
|
|
18
|
+
this.visibleGridColumns = [];
|
|
19
|
+
this.visibleTooltipColumns = [];
|
|
20
|
+
this.layout = { rootMaxHeight: 0, bodyHeight: 0, scrollHeight: 0, resizerHeight: 0 };
|
|
21
|
+
this.scales = ['1m', '10m', '30m', 'hour', '6 hours', '12 hours', 'day', 'week', 'month', 'year'];
|
|
22
|
+
this.scalesDate = ['1m', '10m', '30m', 'hour', 'day', 'week', 'month', 'year'];
|
|
23
|
+
this.negativeSlotWidth = 50;
|
|
24
|
+
this.hasNegativeDependencySpace = false;
|
|
25
|
+
// minimum columns to show gantt
|
|
26
|
+
this.coreColumns = [
|
|
27
|
+
{
|
|
28
|
+
id: 'label',
|
|
29
|
+
title: 'Name',
|
|
30
|
+
valueGetter: t => t.label,
|
|
31
|
+
showInGrid: true,
|
|
32
|
+
showInTooltip: true
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'start',
|
|
36
|
+
title: 'Start',
|
|
37
|
+
valueGetter: t => this.getDateString(t.start),
|
|
38
|
+
showInGrid: true,
|
|
39
|
+
showInTooltip: true,
|
|
40
|
+
hidden: () => this.dataType !== 'calendar'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'end',
|
|
44
|
+
title: 'End',
|
|
45
|
+
valueGetter: t => this.getDateString(t.end),
|
|
46
|
+
showInGrid: true,
|
|
47
|
+
showInTooltip: true,
|
|
48
|
+
hidden: () => this.dataType !== 'calendar'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'duration',
|
|
52
|
+
title: 'Duration',
|
|
53
|
+
valueGetter: t => this.getDuration(t),
|
|
54
|
+
showInGrid: true,
|
|
55
|
+
showInTooltip: true,
|
|
56
|
+
hidden: () => this.dataType !== 'duration'
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
// recompute all sizes
|
|
61
|
+
recomputeLayout() {
|
|
62
|
+
this.layout.rootMaxHeight = this.ganttHeight - this.headerHeight + this.rowHeight - 3;
|
|
63
|
+
this.layout.bodyHeight = this.ganttHeight - this.rowHeight / 3;
|
|
64
|
+
this.layout.scrollHeight = this.ganttHeight - this.rowHeight;
|
|
65
|
+
this.layout.resizerHeight = this.ganttHeight + this.headerHeight - this.rowHeight;
|
|
66
|
+
}
|
|
67
|
+
get columns() {
|
|
68
|
+
return [
|
|
69
|
+
...this.coreColumns,
|
|
70
|
+
...this.extraColumns
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
ganttWidthCalcul() {
|
|
74
|
+
this.ganttWidth = this.slots.length * this.scaleSelected.px;
|
|
75
|
+
}
|
|
76
|
+
ganttHeightCalcul() {
|
|
77
|
+
const max = Math.max(...this.tasks.map((t) => t.row));
|
|
78
|
+
this.ganttHeight = (max + 2) * this.rowHeight;
|
|
79
|
+
}
|
|
80
|
+
refreshVisibleColumns() {
|
|
81
|
+
this.visibleGridColumns = this.columns.filter(c => c.showInGrid &&
|
|
82
|
+
(!c.hidden || !c.hidden()));
|
|
83
|
+
this.visibleTooltipColumns = this.columns.filter(c => c.showInTooltip &&
|
|
84
|
+
(!c.hidden || !c.hidden()));
|
|
85
|
+
}
|
|
86
|
+
getRawTaskX(task) {
|
|
87
|
+
return (task.startSlot ?? 0) * this.scaleSelected.px;
|
|
88
|
+
}
|
|
89
|
+
getDateString(date) {
|
|
90
|
+
if (!date)
|
|
91
|
+
return '';
|
|
92
|
+
if (this.dateMode === 'utc') {
|
|
93
|
+
return date
|
|
94
|
+
.toLocaleString([], {
|
|
95
|
+
timeZone: 'UTC',
|
|
96
|
+
day: '2-digit',
|
|
97
|
+
month: '2-digit',
|
|
98
|
+
year: 'numeric',
|
|
99
|
+
hour: '2-digit',
|
|
100
|
+
minute: '2-digit',
|
|
101
|
+
hour12: false,
|
|
102
|
+
})
|
|
103
|
+
.replace(',', '');
|
|
104
|
+
}
|
|
105
|
+
return date
|
|
106
|
+
.toLocaleString([], {
|
|
107
|
+
day: '2-digit',
|
|
108
|
+
month: '2-digit',
|
|
109
|
+
year: 'numeric',
|
|
110
|
+
hour: '2-digit',
|
|
111
|
+
minute: '2-digit',
|
|
112
|
+
hour12: false,
|
|
113
|
+
})
|
|
114
|
+
.replace(',', '');
|
|
115
|
+
}
|
|
116
|
+
getDuration(task) {
|
|
117
|
+
if (!task)
|
|
118
|
+
return '';
|
|
119
|
+
if (typeof task.start !== 'number' || typeof task.end !== 'number') {
|
|
120
|
+
throw new Error(`Task ${task.id} is not in duration mode`);
|
|
121
|
+
}
|
|
122
|
+
let total = task.end - task.start;
|
|
123
|
+
const days = Math.floor(total / 86400);
|
|
124
|
+
total %= 86400;
|
|
125
|
+
const hours = Math.floor(total / 3600);
|
|
126
|
+
total %= 3600;
|
|
127
|
+
const minutes = Math.floor(total / 60);
|
|
128
|
+
const seconds = total % 60;
|
|
129
|
+
let result = '';
|
|
130
|
+
if (days > 0)
|
|
131
|
+
result += `${days}d `;
|
|
132
|
+
if (hours > 0 || days > 0)
|
|
133
|
+
result += `${hours}h `;
|
|
134
|
+
if (minutes > 0 || hours > 0 || days > 0)
|
|
135
|
+
result += `${minutes}m `;
|
|
136
|
+
result += `${seconds}s`;
|
|
137
|
+
return result.trim();
|
|
138
|
+
}
|
|
139
|
+
getTaskWidth(task) {
|
|
140
|
+
return ((task.endSlot ?? 0) - (task.startSlot ?? 0)) * this.scaleSelected.px;
|
|
141
|
+
}
|
|
142
|
+
getGridTop(i) {
|
|
143
|
+
return i * this.rowHeight;
|
|
144
|
+
}
|
|
145
|
+
getTaskX(task) {
|
|
146
|
+
const base = (task.startSlot ?? 0) * this.scaleSelected.px;
|
|
147
|
+
return this.hasNegativeDependencySpace ? this.negativeSlotWidth + base : base;
|
|
148
|
+
}
|
|
149
|
+
getTaskY(task) {
|
|
150
|
+
return task.row * this.rowHeight + this.rowHeight / 10;
|
|
151
|
+
}
|
|
152
|
+
trackByIndex(index) {
|
|
153
|
+
return index;
|
|
154
|
+
}
|
|
155
|
+
// get per arrow the path
|
|
156
|
+
getDependencyPath(fromId, toId) {
|
|
157
|
+
const from = this.tasks.find((t) => t.id === fromId);
|
|
158
|
+
const to = this.tasks.find((t) => t.id === toId);
|
|
159
|
+
if (!from || !to)
|
|
160
|
+
return '';
|
|
161
|
+
const fromRight = this.getTaskX(from) + this.getTaskWidth(from);
|
|
162
|
+
const toLeft = this.getTaskX(to);
|
|
163
|
+
const fromY = this.getTaskY(from) + this.rowHeight / 2 - this.rowHeight / 12;
|
|
164
|
+
const toY = this.getTaskY(to) + this.rowHeight / 2 - this.rowHeight / 12;
|
|
165
|
+
if (from.row === to.row) {
|
|
166
|
+
return `
|
|
167
|
+
M ${fromRight} ${fromY}
|
|
168
|
+
H ${fromRight + 20}
|
|
169
|
+
V ${toY}
|
|
170
|
+
H ${toLeft}`;
|
|
171
|
+
}
|
|
172
|
+
// consistent U-turn style (even if not strictly needed)
|
|
173
|
+
const escapeY = toY - this.rowHeight * 0.54;
|
|
174
|
+
const midX1 = fromRight + 25;
|
|
175
|
+
const midX2 = toLeft - 25;
|
|
176
|
+
return `
|
|
177
|
+
M ${fromRight} ${fromY}
|
|
178
|
+
H ${midX1}
|
|
179
|
+
V ${escapeY}
|
|
180
|
+
H ${midX2}
|
|
181
|
+
V ${toY}
|
|
182
|
+
H ${toLeft}`;
|
|
183
|
+
}
|
|
184
|
+
// size of columns per minutes
|
|
185
|
+
getScaleConfig(scale) {
|
|
186
|
+
switch (scale) {
|
|
187
|
+
case '1m':
|
|
188
|
+
return { secondes: 60, px: 120 };
|
|
189
|
+
case '10m':
|
|
190
|
+
return { secondes: 600, px: 120 };
|
|
191
|
+
case '30m':
|
|
192
|
+
return { secondes: 1800, px: 120 };
|
|
193
|
+
case 'hour':
|
|
194
|
+
return { secondes: 3600, px: 120 };
|
|
195
|
+
case '6 hours':
|
|
196
|
+
return { secondes: 21600, px: 120 };
|
|
197
|
+
case '12 hours':
|
|
198
|
+
return { secondes: 43200, px: 120 };
|
|
199
|
+
case 'day':
|
|
200
|
+
return { secondes: 86400, px: 150 };
|
|
201
|
+
case 'week':
|
|
202
|
+
return { secondes: 604800, px: 200 };
|
|
203
|
+
case 'month':
|
|
204
|
+
return { secondes: 2592000, px: 350 };
|
|
205
|
+
case 'year':
|
|
206
|
+
return { secondes: 31536000, px: 500 };
|
|
207
|
+
default:
|
|
208
|
+
return { secondes: 1800, px: 120 };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
alignOriginByScale(date, defaultScale) {
|
|
212
|
+
const d = new Date(date);
|
|
213
|
+
switch (defaultScale) {
|
|
214
|
+
case 'week': {
|
|
215
|
+
// align monday
|
|
216
|
+
const d = new Date(date);
|
|
217
|
+
const day = d.getDay(); // 0 = Sunday, 1 = Monday, ...
|
|
218
|
+
const diff = day === 0 ? -6 : 1 - day; // move back to Monday
|
|
219
|
+
d.setDate(d.getDate() + diff);
|
|
220
|
+
d.setHours(0, 0, 0, 0);
|
|
221
|
+
return d;
|
|
222
|
+
}
|
|
223
|
+
case 'month': {
|
|
224
|
+
d.setDate(1);
|
|
225
|
+
d.setHours(0, 0, 0, 0);
|
|
226
|
+
return d;
|
|
227
|
+
}
|
|
228
|
+
case 'year': {
|
|
229
|
+
d.setMonth(0, 1); // Jan 1
|
|
230
|
+
d.setHours(0, 0, 0, 0);
|
|
231
|
+
return d;
|
|
232
|
+
}
|
|
233
|
+
case 'day': {
|
|
234
|
+
// shift back by 1 day (buffer slot)
|
|
235
|
+
d.setDate(d.getDate() - 1);
|
|
236
|
+
d.setHours(0, 0, 0, 0);
|
|
237
|
+
return d;
|
|
238
|
+
}
|
|
239
|
+
case 'hour': {
|
|
240
|
+
// shift back by 1 hour
|
|
241
|
+
d.setHours(d.getHours() - 1);
|
|
242
|
+
d.setMinutes(0, 0, 0);
|
|
243
|
+
return d;
|
|
244
|
+
}
|
|
245
|
+
case '6 hours': {
|
|
246
|
+
d.setHours(d.getHours() - 6);
|
|
247
|
+
d.setMinutes(0, 0, 0);
|
|
248
|
+
return d;
|
|
249
|
+
}
|
|
250
|
+
case '12 hours': {
|
|
251
|
+
d.setHours(d.getHours() - 12);
|
|
252
|
+
d.setMinutes(0, 0, 0);
|
|
253
|
+
return d;
|
|
254
|
+
}
|
|
255
|
+
case '30m': {
|
|
256
|
+
d.setMinutes(d.getMinutes() - 30);
|
|
257
|
+
d.setSeconds(0, 0);
|
|
258
|
+
return d;
|
|
259
|
+
}
|
|
260
|
+
case '10m': {
|
|
261
|
+
d.setMinutes(d.getMinutes() - 10);
|
|
262
|
+
d.setSeconds(0, 0);
|
|
263
|
+
return d;
|
|
264
|
+
}
|
|
265
|
+
case '1m': {
|
|
266
|
+
d.setMinutes(d.getMinutes() - 1);
|
|
267
|
+
d.setSeconds(0, 0);
|
|
268
|
+
return d;
|
|
269
|
+
}
|
|
270
|
+
default:
|
|
271
|
+
return d;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GanttLiteBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
275
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: GanttLiteBase, inputs: { rowHeight: "rowHeight", defaultScale: "defaultScale", dataType: "dataType", dateMode: "dateMode", extraColumns: "extraColumns" }, ngImport: i0 }); }
|
|
276
|
+
}
|
|
277
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GanttLiteBase, decorators: [{
|
|
278
|
+
type: Directive
|
|
279
|
+
}], ctorParameters: () => [], propDecorators: { rowHeight: [{
|
|
280
|
+
type: Input
|
|
281
|
+
}], defaultScale: [{
|
|
282
|
+
type: Input
|
|
283
|
+
}], dataType: [{
|
|
284
|
+
type: Input
|
|
285
|
+
}], dateMode: [{
|
|
286
|
+
type: Input
|
|
287
|
+
}], extraColumns: [{
|
|
288
|
+
type: Input
|
|
289
|
+
}] } });
|
|
290
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQtbGl0ZS1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2FudHQtbGl0ZS9zcmMvbGliL2dhbnR0LWxpdGUtYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFLakQsTUFBTSxPQUFpQixhQUFhO0lBc0JoQztRQXJCZ0IsY0FBUyxHQUFXLEVBQUUsQ0FBQztRQUN2QixpQkFBWSxHQUFlLEtBQUssQ0FBQztRQUNqQyxhQUFRLEdBQWEsVUFBVSxDQUFDO1FBQ2hDLGFBQVEsR0FBYSxPQUFPLENBQUM7UUFDN0IsaUJBQVksR0FBa0IsRUFBRSxDQUFDO1FBQ3ZDLFVBQUssR0FBbUIsRUFBRSxDQUFDO1FBQzNCLFVBQUssR0FBZ0IsRUFBRSxDQUFDO1FBQzNCLG9CQUFlLEdBQXFCLEVBQUUsQ0FBQztRQUNwQyxrQkFBYSxHQUFnQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwRSxpQkFBWSxHQUFXLEVBQUUsQ0FBQztRQUMxQixnQkFBVyxHQUFXLENBQUMsQ0FBQztRQUN4QixlQUFVLEdBQVcsQ0FBQyxDQUFDO1FBQ3ZCLG1CQUFjLEdBQUcsR0FBRyxDQUFDO1FBQ3JCLHVCQUFrQixHQUFrQixFQUFFLENBQUM7UUFDdkMsMEJBQXFCLEdBQWtCLEVBQUUsQ0FBQztRQUMxQyxXQUFNLEdBQUcsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDdkUsV0FBTSxHQUFpQixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0s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b250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRGF0YVR5cGUsIERhdGVNb2RlLCBEZXBlbmRlbmN5UGF0aCwgR2FudHRDb2x1bW4sIEdhbnR0U2NhbGUsIEdhbnR0VGFzaywgU2NhbGVDb25maWcgfSBmcm9tICcuL2dhbnR0LWxpdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBUaW1lbGluZVNsb3QgfSBmcm9tICcuL2dhbnR0LWxpdGUubW9kZWwnO1xyXG5cclxuQERpcmVjdGl2ZSgpXHJcbmV4cG9ydCBhYnN0cmFjdCAgY2xhc3MgR2FudHRMaXRlQmFzZSB7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgcm93SGVpZ2h0OiBudW1iZXIgPSA0MDtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkZWZhdWx0U2NhbGU6IEdhbnR0U2NhbGUgPSAnZGF5JztcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkYXRhVHlwZTogRGF0YVR5cGUgPSAnZHVyYXRpb24nO1xyXG4gICAgQElucHV0KCkgcHVibGljIGRhdGVNb2RlOiBEYXRlTW9kZSA9ICdsb2NhbCc7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgZXh0cmFDb2x1bW5zOiBHYW50dENvbHVtbltdID0gW107XHJcbiAgICBwcm90ZWN0ZWQgc2xvdHM6IFRpbWVsaW5lU2xvdFtdID0gW107XHJcbiAgICBwcm90ZWN0ZWQgdGFza3M6IEdhbnR0VGFza1tdID0gW107XHJcbiAgICBwdWJsaWMgZGVwZW5kZW5jeVBhdGhzOiBEZXBlbmRlbmN5UGF0aFtdID0gW107XHJcbiAgICBwcm90ZWN0ZWQgc2NhbGVTZWxlY3RlZDogU2NhbGVDb25maWcgPSB0aGlzLmdldFNjYWxlQ29uZmlnKHRoaXMuZGVmYXVsdFNjYWxlKTtcclxuICAgIHByb3RlY3RlZCBoZWFkZXJIZWlnaHQ6IG51bWJlciA9IDMyO1xyXG4gICAgcHJvdGVjdGVkIGdhbnR0SGVpZ2h0OiBudW1iZXIgPSAwO1xyXG4gICAgcHJvdGVjdGVkIGdhbnR0V2lkdGg6IG51bWJlciA9IDA7XHJcbiAgICBwcm90ZWN0ZWQgbGVmdFBhbmVsV2lkdGggPSAzMjA7XHJcbiAgICBwcm90ZWN0ZWQgdmlzaWJsZUdyaWRDb2x1bW5zOiBHYW50dENvbHVtbltdID0gW107XHJcbiAgICBwcm90ZWN0ZWQgdmlzaWJsZVRvb2x0aXBDb2x1bW5zOiBHYW50dENvbHVtbltdID0gW107XHJcbiAgICBwcm90ZWN0ZWQgbGF5b3V0ID0geyByb290TWF4SGVpZ2h0OiAwLCBib2R5SGVpZ2h0OiAwLCBzY3JvbGxIZWlnaHQ6IDAsIHJlc2l6ZXJIZWlnaHQ6IDAgfTtcclxuICAgIHByb3RlY3RlZCByZWFkb25seSBzY2FsZXM6IEdhbnR0U2NhbGVbXSA9IFsnMW0nLCAnMTBtJywgJzMwbScsICdob3VyJywgJzYgaG91cnMnLCAnMTIgaG91cnMnLCAnZGF5JywgJ3dlZWsnLCAnbW9udGgnLCAneWVhciddO1xyXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHNjYWxlc0RhdGU6IEdhbnR0U2NhbGVbXSA9IFsnMW0nLCAnMTBtJywgJzMwbScsICdob3VyJywgJ2RheScsICd3ZWVrJywgJ21vbnRoJywgJ3llYXInXTtcclxuICAgIHByb3RlY3RlZCByZWFkb25seSBuZWdhdGl2ZVNsb3RXaWR0aCA9IDUwO1xyXG4gICAgcHJvdGVjdGVkIGhhc05lZ2F0aXZlRGVwZW5kZW5jeVNwYWNlID0gZmFsc2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7IH1cclxuICAgIFxyXG4gICAgLy8gcmVjb21wdXRlIGFsbCBzaXplc1xyXG4gICAgcHJvdGVjdGVkIHJlY29tcHV0ZUxheW91dCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmxheW91dC5yb290TWF4SGVpZ2h0ID0gdGhpcy5nYW50dEhlaWdodCAtIHRoaXMuaGVhZGVySGVpZ2h0ICsgdGhpcy5yb3dIZWlnaHQgLSAzO1xyXG4gICAgICAgIHRoaXMubGF5b3V0LmJvZHlIZWlnaHQgPSB0aGlzLmdhbnR0SGVpZ2h0IC0gdGhpcy5yb3dIZWlnaHQgLyAzO1xyXG4gICAgICAgIHRoaXMubGF5b3V0LnNjcm9sbEhlaWdodCA9IHRoaXMuZ2FudHRIZWlnaHQgLSB0aGlzLnJvd0hlaWdodDtcclxuICAgICAgICB0aGlzLmxheW91dC5yZXNpemVySGVpZ2h0ID0gdGhpcy5nYW50dEhlaWdodCArIHRoaXMuaGVhZGVySGVpZ2h0IC0gdGhpcy5yb3dIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGdldCBjb2x1bW5zKCk6IEdhbnR0Q29sdW1uW10ge1xyXG4gICAgICAgIHJldHVybiBbXHJcbiAgICAgICAgICAgIC4uLnRoaXMuY29yZUNvbHVtbnMsXHJcbiAgICAgICAgICAgIC4uLnRoaXMuZXh0cmFDb2x1bW5zXHJcbiAgICAgICAgXTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBtaW5pbXVtIGNvbHVtbnMgdG8gc2hvdyBnYW50dFxyXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvcmVDb2x1bW5zOiBHYW50dENvbHVtbltdID0gW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgaWQ6ICdsYWJlbCcsXHJcbiAgICAgICAgICAgIHRpdGxlOiAnTmFtZScsXHJcbiAgICAgICAgICAgIHZhbHVlR2V0dGVyOiB0ID0+IHQubGFiZWwsXHJcbiAgICAgICAgICAgIHNob3dJbkdyaWQ6IHRydWUsXHJcbiAgICAgICAgICAgIHNob3dJblRvb2x0aXA6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgaWQ6ICdzdGFydCcsXHJcbiAgICAgICAgICAgIHRpdGxlOiAnU3RhcnQnLFxyXG4gICAgICAgICAgICB2YWx1ZUdldHRlcjogdCA9PiB0aGlzLmdldERhdGVTdHJpbmcodC5zdGFydCksXHJcbiAgICAgICAgICAgIHNob3dJbkdyaWQ6IHRydWUsXHJcbiAgICAgICAgICAgIHNob3dJblRvb2x0aXA6IHRydWUsXHJcbiAgICAgICAgICAgIGhpZGRlbjogKCkgPT4gdGhpcy5kYXRhVHlwZSAhPT0gJ2NhbGVuZGFyJ1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICBpZDogJ2VuZCcsXHJcbiAgICAgICAgICAgIHRpdGxlOiAnRW5kJyxcclxuICAgICAgICAgICAgdmFsdWVHZXR0ZXI6IHQgPT4gdGhpcy5nZXREYXRlU3RyaW5nKHQuZW5kKSxcclxuICAgICAgICAgICAgc2hvd0luR3JpZDogdHJ1ZSxcclxuICAgICAgICAgICAgc2hvd0luVG9vbHRpcDogdHJ1ZSxcclxuICAgICAgICAgICAgaGlkZGVuOiAoKSA9PiB0aGlzLmRhdGFUeXBlICE9PSAnY2FsZW5kYXInXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIGlkOiAnZHVyYXRpb24nLFxyXG4gICAgICAgICAgICB0aXRsZTogJ0R1cmF0aW9uJyxcclxuICAgICAgICAgICAgdmFsdWVHZXR0ZXI6IHQgPT4gdGhpcy5nZXREdXJhdGlvbih0KSxcclxuICAgICAgICAgICAgc2hvd0luR3JpZDogdHJ1ZSxcclxuICAgICAgICAgICAgc2hvd0luVG9vbHRpcDogdHJ1ZSxcclxuICAgICAgICAgICAgaGlkZGVuOiAoKSA9PiB0aGlzLmRhdGFUeXBlICE9PSAnZHVyYXRpb24nXHJcbiAgICAgICAgfVxyXG4gICAgXTtcclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2FudHRXaWR0aENhbGN1bCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmdhbnR0V2lkdGggPSB0aGlzLnNsb3RzLmxlbmd0aCAqIHRoaXMuc2NhbGVTZWxlY3RlZC5weDtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2FudHRIZWlnaHRDYWxjdWwoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoLi4udGhpcy50YXNrcy5tYXAoKHQpID0+IHQucm93KSk7XHJcbiAgICAgICAgdGhpcy5nYW50dEhlaWdodCA9IChtYXggKyAyKSAqIHRoaXMucm93SGVpZ2h0O1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCByZWZyZXNoVmlzaWJsZUNvbHVtbnMoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy52aXNpYmxlR3JpZENvbHVtbnMgPSB0aGlzLmNvbHVtbnMuZmlsdGVyKGMgPT5cclxuICAgICAgICAgICAgYy5zaG93SW5HcmlkICYmXHJcbiAgICAgICAgICAgICghYy5oaWRkZW4gfHwgIWMuaGlkZGVuKCkpXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgdGhpcy52aXNpYmxlVG9vbHRpcENvbHVtbnMgPSB0aGlzLmNvbHVtbnMuZmlsdGVyKGMgPT5cclxuICAgICAgICAgICAgYy5zaG93SW5Ub29sdGlwICYmXHJcbiAgICAgICAgICAgICghYy5oaWRkZW4gfHwgIWMuaGlkZGVuKCkpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0UmF3VGFza1godGFzazogR2FudHRUYXNrKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gKHRhc2suc3RhcnRTbG90ID8/IDApICogdGhpcy5zY2FsZVNlbGVjdGVkLnB4O1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBnZXREYXRlU3RyaW5nKGRhdGU6IERhdGUgfCBudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsKTogc3RyaW5nIHtcclxuICAgICAgICBpZiAoIWRhdGUpIHJldHVybiAnJztcclxuICAgICAgICBpZiAodGhpcy5kYXRlTW9kZSA9PT0gJ3V0YycpIHtcclxuICAgICAgICAgICAgcmV0dXJuIChkYXRlIGFzIERhdGUpXHJcbiAgICAgICAgICAgICAgICAudG9Mb2NhbGVTdHJpbmcoW10sIHtcclxuICAgICAgICAgICAgICAgICAgICB0aW1lWm9uZTogJ1VUQycsXHJcbiAgICAgICAgICAgICAgICAgICAgZGF5OiAnMi1kaWdpdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgbW9udGg6ICcyLWRpZ2l0JyxcclxuICAgICAgICAgICAgICAgICAgICB5ZWFyOiAnbnVtZXJpYycsXHJcbiAgICAgICAgICAgICAgICAgICAgaG91cjogJzItZGlnaXQnLFxyXG4gICAgICAgICAgICAgICAgICAgIG1pbnV0ZTogJzItZGlnaXQnLFxyXG4gICAgICAgICAgICAgICAgICAgIGhvdXIxMjogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoJywnLCAnJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gKGRhdGUgYXMgRGF0ZSlcclxuICAgICAgICAgICAgLnRvTG9jYWxlU3RyaW5nKFtdLCB7XHJcbiAgICAgICAgICAgICAgICBkYXk6ICcyLWRpZ2l0JyxcclxuICAgICAgICAgICAgICAgIG1vbnRoOiAnMi1kaWdpdCcsXHJcbiAgICAgICAgICAgICAgICB5ZWFyOiAnbnVtZXJpYycsXHJcbiAgICAgICAgICAgICAgICBob3VyOiAnMi1kaWdpdCcsXHJcbiAgICAgICAgICAgICAgICBtaW51dGU6ICcyLWRpZ2l0JyxcclxuICAgICAgICAgICAgICAgIGhvdXIxMjogZmFsc2UsXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKCcsJywgJycpO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBnZXREdXJhdGlvbih0YXNrOiBHYW50dFRhc2sgfCB1bmRlZmluZWQgfCBudWxsKTogc3RyaW5nIHtcclxuICAgICAgICBpZiAoIXRhc2spIHJldHVybiAnJztcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiB0YXNrLnN0YXJ0ICE9PSAnbnVtYmVyJyB8fCB0eXBlb2YgdGFzay5lbmQgIT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGFzayAke3Rhc2suaWR9IGlzIG5vdCBpbiBkdXJhdGlvbiBtb2RlYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgdG90YWwgPSB0YXNrLmVuZCAtIHRhc2suc3RhcnQ7XHJcbiAgICAgICAgY29uc3QgZGF5cyA9IE1hdGguZmxvb3IodG90YWwgLyA4NjQwMCk7XHJcbiAgICAgICAgdG90YWwgJT0gODY0MDA7XHJcbiAgICAgICAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKHRvdGFsIC8gMzYwMCk7XHJcbiAgICAgICAgdG90YWwgJT0gMzYwMDtcclxuICAgICAgICBjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcih0b3RhbCAvIDYwKTtcclxuICAgICAgICBjb25zdCBzZWNvbmRzID0gdG90YWwgJSA2MDtcclxuICAgICAgICBsZXQgcmVzdWx0ID0gJyc7XHJcblxyXG4gICAgICAgIGlmIChkYXlzID4gMCkgcmVzdWx0ICs9IGAke2RheXN9ZCBgO1xyXG4gICAgICAgIGlmIChob3VycyA+IDAgfHwgZGF5cyA+IDApIHJlc3VsdCArPSBgJHtob3Vyc31oIGA7XHJcbiAgICAgICAgaWYgKG1pbnV0ZXMgPiAwIHx8IGhvdXJzID4gMCB8fCBkYXlzID4gMCkgcmVzdWx0ICs9IGAke21pbnV0ZXN9bSBgO1xyXG5cclxuICAgICAgICByZXN1bHQgKz0gYCR7c2Vjb25kc31zYDtcclxuICAgICAgICByZXR1cm4gcmVzdWx0LnRyaW0oKTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0VGFza1dpZHRoKHRhc2s6IEdhbnR0VGFzayk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuICgodGFzay5lbmRTbG90ID8/IDApIC0gKHRhc2suc3RhcnRTbG90ID8/IDApKSAqIHRoaXMuc2NhbGVTZWxlY3RlZC5weDtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0R3JpZFRvcChpOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBpICogdGhpcy5yb3dIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGdldFRhc2tYKHRhc2s6IEdhbnR0VGFzayk6IG51bWJlciB7XHJcbiAgICAgICAgY29uc3QgYmFzZSA9ICh0YXNrLnN0YXJ0U2xvdCA/PyAwKSAqIHRoaXMuc2NhbGVTZWxlY3RlZC5weDtcclxuICAgICAgICByZXR1cm4gdGhpcy5oYXNOZWdhdGl2ZURlcGVuZGVuY3lTcGFjZSA/IHRoaXMubmVnYXRpdmVTbG90V2lkdGggKyBiYXNlIDogYmFzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0VGFza1kodGFzazogR2FudHRUYXNrKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGFzay5yb3cgKiB0aGlzLnJvd0hlaWdodCArIHRoaXMucm93SGVpZ2h0IC8gMTA7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHRyYWNrQnlJbmRleChpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gaW5kZXg7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZ2V0IHBlciBhcnJvdyB0aGUgcGF0aFxyXG4gICAgcHJvdGVjdGVkIGdldERlcGVuZGVuY3lQYXRoKGZyb21JZDogc3RyaW5nLCB0b0lkOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGZyb20gPSB0aGlzLnRhc2tzLmZpbmQoKHQpID0+IHQuaWQgPT09IGZyb21JZCk7XHJcbiAgICAgICAgY29uc3QgdG8gPSB0aGlzLnRhc2tzLmZpbmQoKHQpID0+IHQuaWQgPT09IHRvSWQpO1xyXG4gICAgICAgIGlmICghZnJvbSB8fCAhdG8pIHJldHVybiAnJztcclxuICAgICAgICBjb25zdCBmcm9tUmlnaHQgPSB0aGlzLmdldFRhc2tYKGZyb20pICsgdGhpcy5nZXRUYXNrV2lkdGgoZnJvbSk7XHJcbiAgICAgICAgY29uc3QgdG9MZWZ0ID0gdGhpcy5nZXRUYXNrWCh0byk7XHJcbiAgICAgICAgY29uc3QgZnJvbVkgPSB0aGlzLmdldFRhc2tZKGZyb20pICsgdGhpcy5yb3dIZWlnaHQgLyAyIC0gdGhpcy5yb3dIZWlnaHQgLyAxMjtcclxuICAgICAgICBjb25zdCB0b1kgPSB0aGlzLmdldFRhc2tZKHRvKSArIHRoaXMucm93SGVpZ2h0IC8gMiAtIHRoaXMucm93SGVpZ2h0IC8gMTI7XHJcblxyXG4gICAgICAgIGlmIChmcm9tLnJvdyA9PT0gdG8ucm93KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBgXHJcbiAgICAgICAgICAgIE0gJHtmcm9tUmlnaHR9ICR7ZnJvbVl9XHJcbiAgICAgICAgICAgIEggJHtmcm9tUmlnaHQgKyAyMH1cclxuICAgICAgICAgICAgViAke3RvWX1cclxuICAgICAgICAgICAgSCAke3RvTGVmdH1gO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gY29uc2lzdGVudCBVLXR1cm4gc3R5bGUgKGV2ZW4gaWYgbm90IHN0cmljdGx5IG5lZWRlZClcclxuICAgICAgICBjb25zdCBlc2NhcGVZID0gdG9ZIC0gdGhpcy5yb3dIZWlnaHQgKiAwLjU0O1xyXG4gICAgICAgIGNvbnN0IG1pZFgxID0gZnJvbVJpZ2h0ICsgMjU7XHJcbiAgICAgICAgY29uc3QgbWlkWDIgPSB0b0xlZnQgLSAyNTtcclxuICAgICAgICByZXR1cm4gYFxyXG4gICAgICAgICAgICBNICR7ZnJvbVJpZ2h0fSAke2Zyb21ZfVxyXG4gICAgICAgICAgICBIICR7bWlkWDF9XHJcbiAgICAgICAgICAgIFYgJHtlc2NhcGVZfVxyXG4gICAgICAgICAgICBIICR7bWlkWDJ9XHJcbiAgICAgICAgICAgIFYgJHt0b1l9XHJcbiAgICAgICAgICAgIEggJHt0b0xlZnR9YDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBzaXplIG9mIGNvbHVtbnMgcGVyIG1pbnV0ZXNcclxuICAgIHByb3RlY3RlZCBnZXRTY2FsZUNvbmZpZyhzY2FsZTogYW55KTogU2NhbGVDb25maWcge1xyXG4gICAgICAgIHN3aXRjaCAoc2NhbGUpIHtcclxuICAgICAgICAgICAgY2FzZSAnMW0nOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc2Vjb25kZXM6IDYwLCBweDogMTIwIH07XHJcbiAgICAgICAgICAgIGNhc2UgJzEwbSc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyBzZWNvbmRlczogNjAwLCBweDogMTIwIH07XHJcbiAgICAgICAgICAgIGNhc2UgJzMwbSc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyBzZWNvbmRlczogMTgwMCwgcHg6IDEyMCB9O1xyXG4gICAgICAgICAgICBjYXNlICdob3VyJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiB7IHNlY29uZGVzOiAzNjAwLCBweDogMTIwIH07XHJcbiAgICAgICAgICAgIGNhc2UgJzYgaG91cnMnOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc2Vjb25kZXM6IDIxNjAwLCBweDogMTIwIH07XHJcbiAgICAgICAgICAgIGNhc2UgJzEyIGhvdXJzJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiB7IHNlY29uZGVzOiA0MzIwMCwgcHg6IDEyMCB9O1xyXG4gICAgICAgICAgICBjYXNlICdkYXknOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc2Vjb25kZXM6IDg2NDAwLCBweDogMTUwIH07XHJcbiAgICAgICAgICAgIGNhc2UgJ3dlZWsnOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc2Vjb25kZXM6IDYwNDgwMCwgcHg6IDIwMCB9O1xyXG4gICAgICAgICAgICBjYXNlICdtb250aCc6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geyBzZWNvbmRlczogMjU5MjAwMCwgcHg6IDM1MCB9O1xyXG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcclxuICAgICAgICAgICAgICAgIHJldHVybiB7IHNlY29uZGVzOiAzMTUzNjAwMCwgcHg6IDUwMCB9O1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc2Vjb25kZXM6IDE4MDAsIHB4OiAxMjAgfTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGFsaWduT3JpZ2luQnlTY2FsZShkYXRlOiBEYXRlLCBkZWZhdWx0U2NhbGU6IEdhbnR0U2NhbGUpOiBEYXRlIHtcclxuICAgICAgICBjb25zdCBkID0gbmV3IERhdGUoZGF0ZSk7XHJcbiAgICAgICAgc3dpdGNoIChkZWZhdWx0U2NhbGUpIHtcclxuICAgICAgICAgICAgY2FzZSAnd2Vlayc6IHtcclxuICAgICAgICAgICAgICAgIC8vIGFsaWduIG1vbmRheVxyXG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IG5ldyBEYXRlKGRhdGUpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGF5ID0gZC5nZXREYXkoKTsgLy8gMCA9IFN1bmRheSwgMSA9IE1vbmRheSwgLi4uXHJcbiAgICAgICAgICAgICAgICBjb25zdCBkaWZmID0gZGF5ID09PSAwID8gLTYgOiAxIC0gZGF5OyAvLyBtb3ZlIGJhY2sgdG8gTW9uZGF5XHJcbiAgICAgICAgICAgICAgICBkLnNldERhdGUoZC5nZXREYXRlKCkgKyBkaWZmKTtcclxuICAgICAgICAgICAgICAgIGQuc2V0SG91cnMoMCwgMCwgMCwgMCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzoge1xyXG4gICAgICAgICAgICAgICAgZC5zZXREYXRlKDEpO1xyXG4gICAgICAgICAgICAgICAgZC5zZXRIb3VycygwLCAwLCAwLCAwKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgJ3llYXInOiB7XHJcbiAgICAgICAgICAgICAgICBkLnNldE1vbnRoKDAsIDEpOyAvLyBKYW4gMVxyXG4gICAgICAgICAgICAgICAgZC5zZXRIb3VycygwLCAwLCAwLCAwKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6IHtcclxuICAgICAgICAgICAgICAgIC8vIHNoaWZ0IGJhY2sgYnkgMSBkYXkgKGJ1ZmZlciBzbG90KVxyXG4gICAgICAgICAgICAgICAgZC5zZXREYXRlKGQuZ2V0RGF0ZSgpIC0gMSk7XHJcbiAgICAgICAgICAgICAgICBkLnNldEhvdXJzKDAsIDAsIDAsIDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSAnaG91cic6IHtcclxuICAgICAgICAgICAgICAgIC8vIHNoaWZ0IGJhY2sgYnkgMSBob3VyXHJcbiAgICAgICAgICAgICAgICBkLnNldEhvdXJzKGQuZ2V0SG91cnMoKSAtIDEpO1xyXG4gICAgICAgICAgICAgICAgZC5zZXRNaW51dGVzKDAsIDAsIDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSAnNiBob3Vycyc6IHtcclxuICAgICAgICAgICAgICAgIGQuc2V0SG91cnMoZC5nZXRIb3VycygpIC0gNik7XHJcbiAgICAgICAgICAgICAgICBkLnNldE1pbnV0ZXMoMCwgMCwgMCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlICcxMiBob3Vycyc6IHtcclxuICAgICAgICAgICAgICAgIGQuc2V0SG91cnMoZC5nZXRIb3VycygpIC0gMTIpO1xyXG4gICAgICAgICAgICAgICAgZC5zZXRNaW51dGVzKDAsIDAsIDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSAnMzBtJzoge1xyXG4gICAgICAgICAgICAgICAgZC5zZXRNaW51dGVzKGQuZ2V0TWludXRlcygpIC0gMzApO1xyXG4gICAgICAgICAgICAgICAgZC5zZXRTZWNvbmRzKDAsIDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSAnMTBtJzoge1xyXG4gICAgICAgICAgICAgICAgZC5zZXRNaW51dGVzKGQuZ2V0TWludXRlcygpIC0gMTApO1xyXG4gICAgICAgICAgICAgICAgZC5zZXRTZWNvbmRzKDAsIDApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSAnMW0nOiB7XHJcbiAgICAgICAgICAgICAgICBkLnNldE1pbnV0ZXMoZC5nZXRNaW51dGVzKCkgLSAxKTtcclxuICAgICAgICAgICAgICAgIGQuc2V0U2Vjb25kcygwLCAwKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIl19
|