@datagrok-libraries/utils 4.6.3 → 4.6.5
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/css/query-builder.css +203 -0
- package/img/chevron.svg +3 -0
- package/package.json +1 -1
- package/src/query-builder/query-builder.d.ts +126 -0
- package/src/query-builder/query-builder.d.ts.map +1 -0
- package/src/query-builder/query-builder.js +695 -0
- package/src/test.js +5 -4
- package/src/viewers/forms-viewer.d.ts +2 -2
- package/src/viewers/forms-viewer.d.ts.map +1 -1
- package/src/viewers/forms-viewer.js +6 -11
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import * as ui from 'datagrok-api/ui';
|
|
11
|
+
import * as DG from 'datagrok-api/dg';
|
|
12
|
+
import { Subject } from 'rxjs';
|
|
13
|
+
import '../../css/query-builder.css';
|
|
14
|
+
import dayjs from 'dayjs';
|
|
15
|
+
export const SUGGESTIONS_FUNCTION = 'suggestionsFunction';
|
|
16
|
+
export var Operators;
|
|
17
|
+
(function (Operators) {
|
|
18
|
+
Operators.CONTAINS = 'contains';
|
|
19
|
+
Operators.IN = 'in';
|
|
20
|
+
Operators.STARTS_WITH = 'starts with';
|
|
21
|
+
Operators.ENDS_WITH = 'ends with';
|
|
22
|
+
Operators.GT = '>';
|
|
23
|
+
Operators.GTE = '>=';
|
|
24
|
+
Operators.LT = '<';
|
|
25
|
+
Operators.LTE = '<=';
|
|
26
|
+
Operators.EQ = '=';
|
|
27
|
+
Operators.NOT_EQ = '!=';
|
|
28
|
+
Operators.BEFORE = 'before';
|
|
29
|
+
Operators.AFTER = 'after';
|
|
30
|
+
Operators.ON = 'on';
|
|
31
|
+
Operators.BETWEEN = 'between';
|
|
32
|
+
Operators.IS_SIMILAR = 'is similar';
|
|
33
|
+
Operators.IS_CONTAINED = 'is contained';
|
|
34
|
+
let Logical;
|
|
35
|
+
(function (Logical) {
|
|
36
|
+
Logical["and"] = "and";
|
|
37
|
+
Logical["or"] = "or";
|
|
38
|
+
})(Logical = Operators.Logical || (Operators.Logical = {}));
|
|
39
|
+
})(Operators || (Operators = {}));
|
|
40
|
+
export var QueryBuilderLayout;
|
|
41
|
+
(function (QueryBuilderLayout) {
|
|
42
|
+
QueryBuilderLayout["Standard"] = "standard";
|
|
43
|
+
QueryBuilderLayout["Narrow"] = "narrow";
|
|
44
|
+
})(QueryBuilderLayout || (QueryBuilderLayout = {}));
|
|
45
|
+
export class BaseConditionEditor {
|
|
46
|
+
constructor(prop, operator, initialCondition) {
|
|
47
|
+
this.root = ui.div();
|
|
48
|
+
this.onChanged = new Subject();
|
|
49
|
+
this.showSuggestions = false;
|
|
50
|
+
this.suggestionsMenuClicked = false;
|
|
51
|
+
this.condition = initialCondition !== null && initialCondition !== void 0 ? initialCondition : {
|
|
52
|
+
field: prop.name,
|
|
53
|
+
operator: operator,
|
|
54
|
+
value: undefined
|
|
55
|
+
};
|
|
56
|
+
this.initializeEditor(prop);
|
|
57
|
+
}
|
|
58
|
+
initializeEditor(prop) {
|
|
59
|
+
if (Array.isArray(this.condition.value))
|
|
60
|
+
this.condition.value = undefined;
|
|
61
|
+
const initVal = prop.type === DG.TYPE.DATE_TIME && typeof this.condition.value === 'string' ?
|
|
62
|
+
dayjs(this.condition.value) : this.condition.value;
|
|
63
|
+
const input = ui.input.forProperty(prop, undefined, {
|
|
64
|
+
value: initVal,
|
|
65
|
+
nullable: false,
|
|
66
|
+
onValueChanged: () => {
|
|
67
|
+
this.condition.value = input.value;
|
|
68
|
+
this.onChanged.next(this.condition);
|
|
69
|
+
this.addSuggestions(prop, input);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
input.addCaption('');
|
|
73
|
+
this.root.append(input.root);
|
|
74
|
+
this.initializeSuggestions(prop, input);
|
|
75
|
+
}
|
|
76
|
+
initializeSuggestions(prop, input) {
|
|
77
|
+
this.showSuggestions = prop.type === DG.TYPE.STRING && prop.options[SUGGESTIONS_FUNCTION];
|
|
78
|
+
if (this.showSuggestions) {
|
|
79
|
+
suggestionMenuKeyNavigation(this.root);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
addSuggestions(prop, input) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
if (this.showSuggestions && !this.suggestionsMenuClicked) {
|
|
85
|
+
if (input.value) {
|
|
86
|
+
const suggestions = yield prop.options[SUGGESTIONS_FUNCTION](input.value);
|
|
87
|
+
if (suggestions.length === 1 && suggestions[0] === input.value)
|
|
88
|
+
return;
|
|
89
|
+
const suggestionsMenu = DG.Menu.popup();
|
|
90
|
+
suggestions.forEach((s) => {
|
|
91
|
+
suggestionsMenu.item(s, () => {
|
|
92
|
+
input.value = s;
|
|
93
|
+
this.suggestionsMenuClicked = true;
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
suggestionsMenu.show({ element: input.root, y: input.root.offsetHeight });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
this.suggestionsMenuClicked = false;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export class BetweenConditionEditor extends BaseConditionEditor {
|
|
104
|
+
initializeEditor(prop) {
|
|
105
|
+
if (!this.condition.value || !Array.isArray(this.condition.value)) {
|
|
106
|
+
this.condition.value = [this.condition.value, undefined];
|
|
107
|
+
this.onChanged.next(this.condition);
|
|
108
|
+
}
|
|
109
|
+
const input1 = ui.input.forProperty(prop, undefined, {
|
|
110
|
+
value: this.condition.value[0],
|
|
111
|
+
nullable: false,
|
|
112
|
+
onValueChanged: () => {
|
|
113
|
+
this.condition.value[0] = input1.value;
|
|
114
|
+
this.onChanged.next(this.condition);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
input1.addCaption('');
|
|
118
|
+
const input2 = ui.input.forProperty(prop, undefined, {
|
|
119
|
+
value: this.condition.value[1],
|
|
120
|
+
onValueChanged: () => {
|
|
121
|
+
this.condition.value[1] = input2.value;
|
|
122
|
+
this.onChanged.next(this.condition);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
input2.addCaption('');
|
|
126
|
+
this.root.append(ui.divH([input1.root, input2.root], { style: { gap: '10px' } }));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export class BooleanConditionEditor extends BaseConditionEditor {
|
|
130
|
+
initializeEditor(prop) {
|
|
131
|
+
if (!this.condition.value)
|
|
132
|
+
this.condition.value = true;
|
|
133
|
+
const options = ['true', 'false'];
|
|
134
|
+
const input = ui.input.choice('', {
|
|
135
|
+
items: options,
|
|
136
|
+
nullable: false,
|
|
137
|
+
value: this.condition.value ? 'true' : 'false',
|
|
138
|
+
onValueChanged: () => {
|
|
139
|
+
this.condition.value = input.value === 'true';
|
|
140
|
+
this.onChanged.next(this.condition);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
this.root.append(input.root);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export class MoleculeConditionEditor extends BaseConditionEditor {
|
|
147
|
+
initializeEditor(prop) {
|
|
148
|
+
//if we swith from similarity input to standard molecule input - need to modify value
|
|
149
|
+
if (this.condition.value && typeof this.condition.value !== 'string') {
|
|
150
|
+
if ('molecule' in this.condition.value)
|
|
151
|
+
this.condition.value = this.condition.value.molecule;
|
|
152
|
+
else
|
|
153
|
+
this.condition.value = '';
|
|
154
|
+
}
|
|
155
|
+
const input = ui.input.molecule('', {
|
|
156
|
+
value: this.condition.value,
|
|
157
|
+
onValueChanged: () => {
|
|
158
|
+
this.condition.value = input.value;
|
|
159
|
+
this.onChanged.next(this.condition);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
this.root.append(input.root);
|
|
163
|
+
//to adjust the filter width considering molecule input
|
|
164
|
+
this.root.style.paddingTop = '15px';
|
|
165
|
+
this.root.style.paddingBottom = '15px';
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export class MoleculeSimilarityConditionEditor extends BaseConditionEditor {
|
|
169
|
+
initializeEditor(prop) {
|
|
170
|
+
var _a;
|
|
171
|
+
//in case we switch from some other operator, where value is a string (contains, is contained)
|
|
172
|
+
if (!this.condition.value || typeof this.condition.value === 'string') {
|
|
173
|
+
this.condition.value = { molecule: (_a = this.condition.value) !== null && _a !== void 0 ? _a : '', threshold: 0.7 };
|
|
174
|
+
}
|
|
175
|
+
const moleculeInput = ui.input.molecule('', {
|
|
176
|
+
onValueChanged: () => {
|
|
177
|
+
this.condition.value.molecule = moleculeInput.value;
|
|
178
|
+
this.onChanged.next(this.condition);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
const tresholdInput = ui.input.float('', {
|
|
182
|
+
value: this.condition.value.threshold,
|
|
183
|
+
min: 0,
|
|
184
|
+
max: 1,
|
|
185
|
+
step: 0.01
|
|
186
|
+
});
|
|
187
|
+
DG.debounce(tresholdInput.onChanged, 300).subscribe(() => {
|
|
188
|
+
this.condition.value.threshold = tresholdInput.value;
|
|
189
|
+
this.onChanged.next(this.condition);
|
|
190
|
+
});
|
|
191
|
+
this.root.append(ui.divV([moleculeInput.root, tresholdInput.root]));
|
|
192
|
+
this.root.style.paddingTop = '15px';
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
export class MultiValueConditionEditorString extends BaseConditionEditor {
|
|
196
|
+
initializeEditor(prop) {
|
|
197
|
+
if (!Array.isArray(this.condition.value)) {
|
|
198
|
+
this.condition.value = [];
|
|
199
|
+
}
|
|
200
|
+
const input = ui.input.list('', {
|
|
201
|
+
nullable: false,
|
|
202
|
+
value: this.condition.value,
|
|
203
|
+
onValueChanged: () => {
|
|
204
|
+
this.condition.value = input.value;
|
|
205
|
+
this.onChanged.next(this.condition);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
this.root.append(input.root);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
export class MultiValueConditionEditorInt extends BaseConditionEditor {
|
|
212
|
+
initializeEditor(prop) {
|
|
213
|
+
if (!Array.isArray(this.condition.value)) {
|
|
214
|
+
this.condition.value = [];
|
|
215
|
+
}
|
|
216
|
+
const input = ui.input.list('', {
|
|
217
|
+
nullable: false,
|
|
218
|
+
value: this.condition.value,
|
|
219
|
+
onValueChanged: () => {
|
|
220
|
+
this.condition.value = input.value.map((it) => parseInt(it));
|
|
221
|
+
this.onChanged.next(this.condition);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
this.root.append(input.root);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
export class MultiValueConditionEditorFloat extends BaseConditionEditor {
|
|
228
|
+
initializeEditor(prop) {
|
|
229
|
+
if (!Array.isArray(this.condition.value)) {
|
|
230
|
+
this.condition.value = [];
|
|
231
|
+
}
|
|
232
|
+
const input = ui.input.list('', {
|
|
233
|
+
nullable: false,
|
|
234
|
+
value: this.condition.value,
|
|
235
|
+
onValueChanged: () => {
|
|
236
|
+
this.condition.value = input.value.map((it) => parseFloat(it));
|
|
237
|
+
this.onChanged.next(this.condition);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
this.root.append(input.root);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Registry for both operators and editors
|
|
244
|
+
export class ConditionRegistry {
|
|
245
|
+
constructor() {
|
|
246
|
+
this.typeOperators = new Map();
|
|
247
|
+
this.semTypeOperators = new Map();
|
|
248
|
+
this.editorRegistry = new Map();
|
|
249
|
+
this.initializeDefaultOperators();
|
|
250
|
+
this.initializeDefaultEditors();
|
|
251
|
+
}
|
|
252
|
+
static getInstance() {
|
|
253
|
+
if (!ConditionRegistry.instance) {
|
|
254
|
+
ConditionRegistry.instance = new ConditionRegistry();
|
|
255
|
+
}
|
|
256
|
+
return ConditionRegistry.instance;
|
|
257
|
+
}
|
|
258
|
+
initializeDefaultOperators() {
|
|
259
|
+
// Type operators
|
|
260
|
+
this.registerTypeOperators(DG.TYPE.BOOL, [Operators.EQ]);
|
|
261
|
+
this.registerTypeOperators(DG.TYPE.STRING, [Operators.STARTS_WITH, Operators.CONTAINS, Operators.EQ, Operators.NOT_EQ, Operators.IN]);
|
|
262
|
+
this.registerTypeOperators(DG.TYPE.INT, [Operators.GT, Operators.LT, Operators.GTE, Operators.LTE, Operators.EQ,
|
|
263
|
+
Operators.NOT_EQ, Operators.BETWEEN, Operators.IN]);
|
|
264
|
+
this.registerTypeOperators(DG.TYPE.FLOAT, [Operators.GT, Operators.LT, Operators.GTE, Operators.LTE, Operators.EQ,
|
|
265
|
+
Operators.NOT_EQ, Operators.BETWEEN, Operators.IN]);
|
|
266
|
+
this.registerTypeOperators(DG.TYPE.DATE_TIME, [Operators.BEFORE, Operators.AFTER, Operators.BETWEEN]);
|
|
267
|
+
// SemType operators (take precedence over type operators)
|
|
268
|
+
this.registerSemTypeOperators(DG.SEMTYPE.MOLECULE, [Operators.CONTAINS, Operators.IS_CONTAINED, Operators.EQ, Operators.IS_SIMILAR]);
|
|
269
|
+
}
|
|
270
|
+
initializeDefaultEditors() {
|
|
271
|
+
// Register default editors by property type (with empty semType and operator)
|
|
272
|
+
this.registerEditor(DG.TYPE.STRING, '', '', BaseConditionEditor);
|
|
273
|
+
this.registerEditor(DG.TYPE.INT, '', '', BaseConditionEditor);
|
|
274
|
+
this.registerEditor(DG.TYPE.FLOAT, '', '', BaseConditionEditor);
|
|
275
|
+
this.registerEditor(DG.TYPE.DATE_TIME, '', '', BaseConditionEditor);
|
|
276
|
+
this.registerEditor(DG.TYPE.BOOL, '', '', BaseConditionEditor);
|
|
277
|
+
// Register specialized editors for specific combinations
|
|
278
|
+
this.registerEditor(DG.TYPE.STRING, '', Operators.IN, MultiValueConditionEditorString);
|
|
279
|
+
this.registerEditor(DG.TYPE.INT, '', Operators.IN, MultiValueConditionEditorInt);
|
|
280
|
+
this.registerEditor(DG.TYPE.FLOAT, '', Operators.IN, MultiValueConditionEditorFloat);
|
|
281
|
+
this.registerEditor(DG.TYPE.DATE_TIME, '', Operators.BETWEEN, BetweenConditionEditor);
|
|
282
|
+
this.registerEditor(DG.TYPE.INT, '', Operators.BETWEEN, BetweenConditionEditor);
|
|
283
|
+
this.registerEditor(DG.TYPE.FLOAT, '', Operators.BETWEEN, BetweenConditionEditor);
|
|
284
|
+
this.registerEditor(DG.TYPE.STRING, DG.SEMTYPE.MOLECULE, Operators.CONTAINS, MoleculeConditionEditor);
|
|
285
|
+
this.registerEditor(DG.TYPE.STRING, DG.SEMTYPE.MOLECULE, Operators.IS_CONTAINED, MoleculeConditionEditor);
|
|
286
|
+
this.registerEditor(DG.TYPE.STRING, DG.SEMTYPE.MOLECULE, Operators.EQ, MoleculeConditionEditor);
|
|
287
|
+
this.registerEditor(DG.TYPE.STRING, DG.SEMTYPE.MOLECULE, Operators.IS_SIMILAR, MoleculeSimilarityConditionEditor);
|
|
288
|
+
this.registerEditor(DG.TYPE.BOOL, '', Operators.EQ, BooleanConditionEditor);
|
|
289
|
+
}
|
|
290
|
+
// Operator registration methods
|
|
291
|
+
registerTypeOperators(propertyType, operators) {
|
|
292
|
+
this.typeOperators.set(propertyType, operators);
|
|
293
|
+
}
|
|
294
|
+
registerSemTypeOperators(semType, operators) {
|
|
295
|
+
this.semTypeOperators.set(semType, operators);
|
|
296
|
+
}
|
|
297
|
+
// Get operators for a property
|
|
298
|
+
getOperatorsForProperty(property) {
|
|
299
|
+
// Check semType first, then fall back to type
|
|
300
|
+
const semTypeOps = this.semTypeOperators.get(property.semType);
|
|
301
|
+
if (semTypeOps)
|
|
302
|
+
return semTypeOps;
|
|
303
|
+
const typeOps = this.typeOperators.get(property.propertyType);
|
|
304
|
+
return typeOps || [];
|
|
305
|
+
}
|
|
306
|
+
// Check if operator is supported
|
|
307
|
+
isOperatorSupported(property, operator) {
|
|
308
|
+
const operators = this.getOperatorsForProperty(property);
|
|
309
|
+
return operators.includes(operator);
|
|
310
|
+
}
|
|
311
|
+
// Editor registration methods
|
|
312
|
+
registerEditor(propertyType, semType, operator, editorClass) {
|
|
313
|
+
const key = this.createEditorKey(propertyType, semType, operator);
|
|
314
|
+
this.editorRegistry.set(key, editorClass);
|
|
315
|
+
}
|
|
316
|
+
// Create editor for a property and operator
|
|
317
|
+
createEditor(property, operator, initialCondition) {
|
|
318
|
+
// Try to find a specialized editor first (propertyType + semType + operator)
|
|
319
|
+
const specializedKey = this.createEditorKey(property.propertyType, property.semType, operator);
|
|
320
|
+
let EditorClass = this.editorRegistry.get(specializedKey);
|
|
321
|
+
// If no specialized editor, try with empty semType (propertyType + operator)
|
|
322
|
+
if (!EditorClass) {
|
|
323
|
+
const typeOnlyKey = this.createEditorKey(property.propertyType, '', operator);
|
|
324
|
+
EditorClass = this.editorRegistry.get(typeOnlyKey);
|
|
325
|
+
}
|
|
326
|
+
// If still no specialized editor, use default editor for property type (propertyType only)
|
|
327
|
+
if (!EditorClass) {
|
|
328
|
+
const defaultKey = this.createEditorKey(property.propertyType, '', '');
|
|
329
|
+
EditorClass = this.editorRegistry.get(defaultKey);
|
|
330
|
+
}
|
|
331
|
+
// Fallback to base editor
|
|
332
|
+
if (!EditorClass) {
|
|
333
|
+
EditorClass = BaseConditionEditor;
|
|
334
|
+
}
|
|
335
|
+
return new EditorClass(property, operator, initialCondition);
|
|
336
|
+
}
|
|
337
|
+
// Get condition editor for a property and operator (with validation)
|
|
338
|
+
getConditionEditor(property, operator, condition) {
|
|
339
|
+
if (this.isOperatorSupported(property, operator)) {
|
|
340
|
+
return this.createEditor(property, operator, condition);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
throw Error(`Operator '${operator}' is not supported for property type '${property.propertyType}'`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
createEditorKey(propertyType, semType, operator) {
|
|
347
|
+
return `${propertyType}:${semType}:${operator}`;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
export function saveHistory(key, value) {
|
|
351
|
+
var _a;
|
|
352
|
+
let collection = JSON.parse((_a = localStorage.getItem(key)) !== null && _a !== void 0 ? _a : '[]');
|
|
353
|
+
const newItem = { date: new Date(), value: value };
|
|
354
|
+
if (!collection.length)
|
|
355
|
+
localStorage.setItem(key, JSON.stringify([newItem]));
|
|
356
|
+
else {
|
|
357
|
+
collection = collection.filter((it) => it.value !== value);
|
|
358
|
+
localStorage.setItem(key, JSON.stringify([newItem, ...collection.slice(0, 9)]));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
export function getHistory(key) {
|
|
362
|
+
var _a;
|
|
363
|
+
return JSON.parse((_a = localStorage.getItem(key)) !== null && _a !== void 0 ? _a : '[]');
|
|
364
|
+
}
|
|
365
|
+
export class QueryBuilder {
|
|
366
|
+
constructor(properties, initialCondition, layout = QueryBuilderLayout.Standard, _historyCacheKey = '') {
|
|
367
|
+
this.structureChanged = new Subject();
|
|
368
|
+
this.filterValueChanged = new Subject();
|
|
369
|
+
this.historyIcon = null;
|
|
370
|
+
this.properties = properties;
|
|
371
|
+
this.layout = layout;
|
|
372
|
+
this._historyCacheKey = _historyCacheKey;
|
|
373
|
+
if (initialCondition) {
|
|
374
|
+
this.condition = initialCondition;
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
const defaultCondition = this.createDefaultSimpleCondition();
|
|
378
|
+
this.condition = {
|
|
379
|
+
logicalOperator: Operators.Logical.and,
|
|
380
|
+
conditions: [defaultCondition]
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
this.root = this.buildUI(this.condition, undefined, 0);
|
|
384
|
+
this.setupHistoryIcon();
|
|
385
|
+
}
|
|
386
|
+
set historyCache(key) {
|
|
387
|
+
this._historyCacheKey = key;
|
|
388
|
+
this.setupHistoryIcon(); // This will control visibility
|
|
389
|
+
}
|
|
390
|
+
saveConditionToHistory() {
|
|
391
|
+
if (this._historyCacheKey)
|
|
392
|
+
saveHistory(this._historyCacheKey, JSON.stringify(this.condition));
|
|
393
|
+
}
|
|
394
|
+
setupHistoryIcon() {
|
|
395
|
+
if (!this.historyIcon) {
|
|
396
|
+
this.historyIcon = ui.iconFA('history', () => {
|
|
397
|
+
this.showHistoryMenu();
|
|
398
|
+
}, 'Query History');
|
|
399
|
+
this.historyIcon.classList.add('query-builder-history-icon');
|
|
400
|
+
}
|
|
401
|
+
this.root.appendChild(this.historyIcon);
|
|
402
|
+
// Set data attribute for CSS to control visibility
|
|
403
|
+
if (this.root) {
|
|
404
|
+
this.root.setAttribute('data-history', this._historyCacheKey === '' ? 'false' : 'true');
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
showHistoryMenu() {
|
|
408
|
+
const items = getHistory(this._historyCacheKey);
|
|
409
|
+
const menu = DG.Menu.popup();
|
|
410
|
+
menu.items(items.map((it) => ui.tools.click(ui.divH([
|
|
411
|
+
ui.divText(it.date.toString(), { style: { color: '#7990A5' } }),
|
|
412
|
+
ui.divText(this.conditionToString(JSON.parse(it.value))),
|
|
413
|
+
], { style: { gap: '5px' } }), () => { this.loadCondition(JSON.parse(it.value)); })), () => { });
|
|
414
|
+
menu.show();
|
|
415
|
+
}
|
|
416
|
+
loadCondition(condition) {
|
|
417
|
+
this.condition = JSON.parse(JSON.stringify(condition));
|
|
418
|
+
this.rebuildUI();
|
|
419
|
+
this.structureChanged.next(this.condition);
|
|
420
|
+
}
|
|
421
|
+
conditionToString(condition) {
|
|
422
|
+
if (!condition || !condition.conditions || condition.conditions.length === 0) {
|
|
423
|
+
return 'No conditions';
|
|
424
|
+
}
|
|
425
|
+
// If there's only one condition, don't wrap it in logical operator
|
|
426
|
+
if (condition.conditions.length === 1) {
|
|
427
|
+
return this.expressionToString(condition.conditions[0]);
|
|
428
|
+
}
|
|
429
|
+
// For multiple conditions, wrap them in logical operator
|
|
430
|
+
const logicalOp = condition.logicalOperator === Operators.Logical.and ? 'AND' : 'OR';
|
|
431
|
+
const conditionStrings = condition.conditions.map(cond => this.expressionToString(cond));
|
|
432
|
+
return `(${conditionStrings.join(` ${logicalOp} `)})`;
|
|
433
|
+
}
|
|
434
|
+
expressionToString(expression) {
|
|
435
|
+
if ('field' in expression) {
|
|
436
|
+
// This is a SimpleCondition
|
|
437
|
+
return this.simpleConditionToString(expression);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
// This is a ComplexCondition (recursive)
|
|
441
|
+
return this.conditionToString(expression);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
simpleConditionToString(condition) {
|
|
445
|
+
const field = condition.field || 'Unknown field';
|
|
446
|
+
const operator = condition.operator || 'Unknown operator';
|
|
447
|
+
const value = condition.value !== undefined && condition.value !== null ?
|
|
448
|
+
(Array.isArray(condition.value) ? `[${condition.value.join(', ')}]` : String(condition.value)) :
|
|
449
|
+
'No value';
|
|
450
|
+
return `${field} ${operator} ${value}`;
|
|
451
|
+
}
|
|
452
|
+
createDefaultSimpleCondition() {
|
|
453
|
+
const firstProperty = this.properties[0];
|
|
454
|
+
if (firstProperty) {
|
|
455
|
+
const registry = ConditionRegistry.getInstance();
|
|
456
|
+
const operators = registry.getOperatorsForProperty(firstProperty);
|
|
457
|
+
const firstOperator = operators[0];
|
|
458
|
+
return {
|
|
459
|
+
field: firstProperty.name,
|
|
460
|
+
operator: firstOperator,
|
|
461
|
+
value: undefined
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
else
|
|
465
|
+
return {
|
|
466
|
+
field: '',
|
|
467
|
+
value: undefined,
|
|
468
|
+
operator: ''
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
rebuildUI() {
|
|
472
|
+
const newRoot = this.buildUI(this.condition, undefined, 0);
|
|
473
|
+
this.root.replaceWith(newRoot);
|
|
474
|
+
this.root = newRoot;
|
|
475
|
+
// Recreate history icon after rebuilding UI
|
|
476
|
+
this.setupHistoryIcon();
|
|
477
|
+
}
|
|
478
|
+
setLayout(layout) {
|
|
479
|
+
this.layout = layout;
|
|
480
|
+
if (layout === QueryBuilderLayout.Narrow)
|
|
481
|
+
this.root.classList.add('query-builder-narrow');
|
|
482
|
+
else
|
|
483
|
+
this.root.classList.remove('query-builder-narrow');
|
|
484
|
+
// Find all filter containers and apply/remove layout classes
|
|
485
|
+
const filterContainers = this.root.querySelectorAll('.query-builder-filter-inputs, .query-builder-filter-inputs-narrow');
|
|
486
|
+
filterContainers.forEach(container => {
|
|
487
|
+
if (layout === QueryBuilderLayout.Narrow) {
|
|
488
|
+
container.classList.remove('query-builder-filter-inputs');
|
|
489
|
+
container.classList.add('query-builder-filter-inputs-narrow');
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
container.classList.remove('query-builder-filter-inputs-narrow');
|
|
493
|
+
container.classList.add('query-builder-filter-inputs');
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
getLayout() {
|
|
498
|
+
return this.layout;
|
|
499
|
+
}
|
|
500
|
+
buildUI(condition, parentCondition, nestingLevel = 0) {
|
|
501
|
+
var _a;
|
|
502
|
+
if (!condition) {
|
|
503
|
+
condition = {
|
|
504
|
+
logicalOperator: Operators.Logical.and,
|
|
505
|
+
conditions: []
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
const removeOrReplaceCondition = (condToRemove, condArray, replaceCond) => {
|
|
509
|
+
if (condArray) {
|
|
510
|
+
const condIdx = condArray.indexOf(condToRemove);
|
|
511
|
+
if (condIdx !== -1)
|
|
512
|
+
replaceCond ? condArray[condIdx] = replaceCond : condArray.splice(condIdx, 1);
|
|
513
|
+
}
|
|
514
|
+
;
|
|
515
|
+
};
|
|
516
|
+
const createPropertyFilterContainer = (cond, parentCondition) => {
|
|
517
|
+
var _a, _b;
|
|
518
|
+
const createFilter = () => {
|
|
519
|
+
ui.empty(operatorInputDiv);
|
|
520
|
+
const property = getPropByFriendlyName(fieldChoiceInput.value);
|
|
521
|
+
if (property) {
|
|
522
|
+
const registry = ConditionRegistry.getInstance();
|
|
523
|
+
const operators = registry.getOperatorsForProperty(property);
|
|
524
|
+
if (!cond.operator || cond.operator === '') {
|
|
525
|
+
cond.operator = operators[0];
|
|
526
|
+
cond.value = undefined;
|
|
527
|
+
this.filterValueChanged.next(cond);
|
|
528
|
+
}
|
|
529
|
+
const operatorsInput = ui.input.choice('', {
|
|
530
|
+
value: cond.operator,
|
|
531
|
+
items: operators,
|
|
532
|
+
onValueChanged: () => {
|
|
533
|
+
cond.operator = operatorsInput.value;
|
|
534
|
+
this.rebuildUI();
|
|
535
|
+
this.structureChanged.next(this.condition);
|
|
536
|
+
},
|
|
537
|
+
nullable: false
|
|
538
|
+
});
|
|
539
|
+
operatorInputDiv.append(operatorsInput.root);
|
|
540
|
+
createEditor(property, cond.operator, cond);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
const createEditor = (property, operator, condition) => {
|
|
544
|
+
ui.empty(criteriaDiv);
|
|
545
|
+
const registry = ConditionRegistry.getInstance();
|
|
546
|
+
const editor = registry.getConditionEditor(property, operator, condition);
|
|
547
|
+
editor.onChanged.subscribe(() => {
|
|
548
|
+
this.filterValueChanged.next(editor.condition);
|
|
549
|
+
});
|
|
550
|
+
criteriaDiv.append(editor.root);
|
|
551
|
+
};
|
|
552
|
+
const getPropByName = (name) => {
|
|
553
|
+
const property = this.properties.find((prop) => prop.name === name);
|
|
554
|
+
return property;
|
|
555
|
+
};
|
|
556
|
+
const getPropByFriendlyName = (friendlyName) => {
|
|
557
|
+
let property = this.properties.find((prop) => prop.friendlyName === friendlyName);
|
|
558
|
+
if (!property)
|
|
559
|
+
property = this.properties.find((prop) => prop.name === friendlyName);
|
|
560
|
+
return property;
|
|
561
|
+
};
|
|
562
|
+
const getFieldChoiceInputVal = (name) => {
|
|
563
|
+
var _a, _b;
|
|
564
|
+
const prop = getPropByName(name);
|
|
565
|
+
return (_b = (_a = prop === null || prop === void 0 ? void 0 : prop.friendlyName) !== null && _a !== void 0 ? _a : prop === null || prop === void 0 ? void 0 : prop.name) !== null && _b !== void 0 ? _b : '';
|
|
566
|
+
};
|
|
567
|
+
const getPropNameByChoiceInputVal = (friendlyName) => {
|
|
568
|
+
var _a;
|
|
569
|
+
const prop = getPropByFriendlyName(friendlyName);
|
|
570
|
+
return (_a = prop === null || prop === void 0 ? void 0 : prop.name) !== null && _a !== void 0 ? _a : '';
|
|
571
|
+
};
|
|
572
|
+
(_a = cond.field) !== null && _a !== void 0 ? _a : (cond.field = ((_b = this.properties[0]) === null || _b === void 0 ? void 0 : _b.name) || '');
|
|
573
|
+
const fieldChoiceInput = ui.input.choice('', {
|
|
574
|
+
items: this.properties.map((prop) => { var _a; return (_a = prop.friendlyName) !== null && _a !== void 0 ? _a : prop.name; }),
|
|
575
|
+
value: getFieldChoiceInputVal(cond.field),
|
|
576
|
+
nullable: false,
|
|
577
|
+
onValueChanged: () => {
|
|
578
|
+
cond.field = getPropNameByChoiceInputVal(fieldChoiceInput.value);
|
|
579
|
+
cond.value = undefined;
|
|
580
|
+
cond.operator = '';
|
|
581
|
+
createFilter();
|
|
582
|
+
this.filterValueChanged.next(cond);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
const deleteFieldIcon = ui.icons.delete(() => {
|
|
586
|
+
container.removeChild(filterContainer);
|
|
587
|
+
removeOrReplaceCondition(cond, parentCondition ? parentCondition.conditions : condition.conditions);
|
|
588
|
+
this.rebuildUI();
|
|
589
|
+
this.structureChanged.next(this.condition);
|
|
590
|
+
}, 'Remove current condition');
|
|
591
|
+
const addNestedConditionIcon = ui.icons.add(() => {
|
|
592
|
+
const parentCond = { logicalOperator: Operators.Logical.and, conditions: [cond] };
|
|
593
|
+
removeOrReplaceCondition(cond, parentCondition ? parentCondition.conditions : condition.conditions, parentCond);
|
|
594
|
+
this.rebuildUI();
|
|
595
|
+
this.structureChanged.next(this.condition);
|
|
596
|
+
}, 'Add nested condition');
|
|
597
|
+
const operatorInputDiv = ui.div('', 'query-builder-filter-operator');
|
|
598
|
+
const criteriaDiv = ui.div();
|
|
599
|
+
const filterContainer = ui.div([
|
|
600
|
+
ui.div([fieldChoiceInput.root], 'query-builder-filter-field'),
|
|
601
|
+
ui.div([operatorInputDiv], 'query-builder-filter-operator'),
|
|
602
|
+
ui.div([criteriaDiv], 'query-builder-filter-value'),
|
|
603
|
+
ui.div([deleteFieldIcon, addNestedConditionIcon], 'add-delete-icons')
|
|
604
|
+
], this.layout === QueryBuilderLayout.Narrow ? 'query-builder-filter-inputs-narrow' : 'query-builder-filter-inputs');
|
|
605
|
+
container.appendChild(filterContainer);
|
|
606
|
+
createFilter();
|
|
607
|
+
this.filterValueChanged.next(cond);
|
|
608
|
+
};
|
|
609
|
+
// adding filter field
|
|
610
|
+
const addFieldIcon = ui.icons.add(() => {
|
|
611
|
+
var _a;
|
|
612
|
+
const conditionForFilter = this.createDefaultSimpleCondition();
|
|
613
|
+
(_a = condition.conditions) === null || _a === void 0 ? void 0 : _a.push(conditionForFilter);
|
|
614
|
+
condition.conditions.length < 2 ? container.classList.remove('property-query-builder-multipe-filelds') :
|
|
615
|
+
container.classList.add('property-query-builder-multipe-filelds');
|
|
616
|
+
this.rebuildUI();
|
|
617
|
+
this.structureChanged.next(this.condition);
|
|
618
|
+
}, 'Add field to the condition');
|
|
619
|
+
// AND/OR operators handling
|
|
620
|
+
(_a = condition.logicalOperator) !== null && _a !== void 0 ? _a : (condition.logicalOperator = Operators.Logical.and);
|
|
621
|
+
const logicalOperatorChoice = ui.input.choice('', {
|
|
622
|
+
value: condition.logicalOperator === Operators.Logical.and ? 'all' : 'any',
|
|
623
|
+
items: ['all', 'any'],
|
|
624
|
+
nullable: false,
|
|
625
|
+
onValueChanged: () => {
|
|
626
|
+
condition.logicalOperator = logicalOperatorChoice.value === 'all' ? Operators.Logical.and : Operators.Logical.or;
|
|
627
|
+
this.rebuildUI();
|
|
628
|
+
this.structureChanged.next(this.condition);
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
const logicalOperatorDiv = ui.divH([ui.divText('Match'), logicalOperatorChoice.root], 'query-builder-match-div');
|
|
632
|
+
const addDeleteIconsDiv = ui.divH([addFieldIcon], 'nested-add-delete-icons');
|
|
633
|
+
const iconsDiv = ui.divH([logicalOperatorDiv, addDeleteIconsDiv], 'query-builder-nested-condition-operators');
|
|
634
|
+
const container = ui.divV([iconsDiv], 'query-builder-search-query-operator');
|
|
635
|
+
if (nestingLevel > 0) {
|
|
636
|
+
container.setAttribute('data-nesting-level', nestingLevel.toString());
|
|
637
|
+
const color = this.generateNestingColor(nestingLevel);
|
|
638
|
+
container.style.setProperty('--nesting-color', color);
|
|
639
|
+
}
|
|
640
|
+
//delete icon for nested conditions to remove the whole nested condition at once
|
|
641
|
+
if (parentCondition) {
|
|
642
|
+
const deleteCondition = ui.icons.delete(() => {
|
|
643
|
+
removeOrReplaceCondition(condition, parentCondition.conditions);
|
|
644
|
+
this.rebuildUI();
|
|
645
|
+
this.structureChanged.next(this.condition);
|
|
646
|
+
});
|
|
647
|
+
addDeleteIconsDiv.append(deleteCondition);
|
|
648
|
+
}
|
|
649
|
+
for (const nestedCondition of condition.conditions) {
|
|
650
|
+
if ('field' in nestedCondition)
|
|
651
|
+
createPropertyFilterContainer(nestedCondition);
|
|
652
|
+
else {
|
|
653
|
+
const nestedContainer = this.buildUI(nestedCondition, condition, nestingLevel + 1);
|
|
654
|
+
container.append(nestedContainer);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
condition.conditions.length < 2 ? container.classList.remove('property-query-builder-multipe-filelds') :
|
|
658
|
+
container.classList.add('property-query-builder-multipe-filelds');
|
|
659
|
+
return container;
|
|
660
|
+
}
|
|
661
|
+
generateNestingColor(level) {
|
|
662
|
+
const baseColor = { r: 187, g: 222, b: 251 };
|
|
663
|
+
const darkeningFactor = Math.min(0.1 + (level - 1) * 0.08, 0.9);
|
|
664
|
+
const r = Math.round(baseColor.r * (1 - darkeningFactor));
|
|
665
|
+
const g = Math.round(baseColor.g * (1 - darkeningFactor));
|
|
666
|
+
const b = Math.round(baseColor.b * (1 - darkeningFactor));
|
|
667
|
+
// Convert to hex
|
|
668
|
+
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
function suggestionMenuKeyNavigation(inputContainer) {
|
|
672
|
+
inputContainer.addEventListener('keydown', (e) => {
|
|
673
|
+
var _a;
|
|
674
|
+
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Enter')
|
|
675
|
+
return;
|
|
676
|
+
const currentlySelected = inputContainer.querySelector('.d4-menu-item-hover');
|
|
677
|
+
const allItems = Array.from((_a = inputContainer.querySelectorAll('.d4-menu-item')) !== null && _a !== void 0 ? _a : []);
|
|
678
|
+
if (!allItems || allItems.length === 0)
|
|
679
|
+
return;
|
|
680
|
+
allItems.sort((a, b) => a.offsetTop - b.offsetTop); // sort by vertical position
|
|
681
|
+
let currentIndex = currentlySelected ? allItems.indexOf(currentlySelected) : -1;
|
|
682
|
+
if (e.key === 'ArrowDown')
|
|
683
|
+
currentIndex = (currentIndex + 1) % allItems.length;
|
|
684
|
+
else if (e.key === 'ArrowUp')
|
|
685
|
+
currentIndex = (currentIndex - 1 + allItems.length) % allItems.length;
|
|
686
|
+
else if (e.key === 'Enter' && currentlySelected) {
|
|
687
|
+
currentlySelected.click();
|
|
688
|
+
e.preventDefault();
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
currentlySelected === null || currentlySelected === void 0 ? void 0 : currentlySelected.classList.remove('d4-menu-item-hover');
|
|
692
|
+
allItems[currentIndex].classList.add('d4-menu-item-hover');
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInF1ZXJ5LWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQ0EsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFFMUIsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcscUJBQXFCLENBQUM7QUFFMUQsTUFBTSxLQUFXLFNBQVMsQ0FzQnpCO0FBdEJELFdBQWlCLFNBQVM7SUFDVCxrQkFBUSxHQUFHLFVBQVUsQ0FBQztJQUN0QixZQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ1YscUJBQVcsR0FBRyxhQUFhLENBQUM7SUFDNUIsbUJBQVMsR0FBRyxXQUFXLENBQUM7SUFDeEIsWUFBRSxHQUFHLEdBQUcsQ0FBQztJQUNULGFBQUcsR0FBRyxJQUFJLENBQUM7SUFDWCxZQUFFLEdBQUcsR0FBRyxDQUFDO0lBQ1QsYUFBRyxHQUFHLElBQUksQ0FBQztJQUNYLFlBQUUsR0FBRyxHQUFHLENBQUM7SUFDVCxnQkFBTSxHQUFHLElBQUksQ0FBQztJQUNkLGdCQUFNLEdBQUcsUUFBUSxDQUFDO0lBQ2xCLGVBQUssR0FBRyxPQUFPLENBQUM7SUFDaEIsWUFBRSxHQUFHLElBQUksQ0FBQztJQUNWLGlCQUFPLEdBQUcsU0FBUyxDQUFDO0lBQ3BCLG9CQUFVLEdBQUcsWUFBWSxDQUFDO0lBQzFCLHNCQUFZLEdBQUcsY0FBYyxDQUFDO0lBRTNDLElBQVksT0FHWDtJQUhELFdBQVksT0FBTztRQUNmLHNCQUFXLENBQUE7UUFDWCxvQkFBUyxDQUFBO0lBQ2IsQ0FBQyxFQUhXLE9BQU8sR0FBUCxpQkFBTyxLQUFQLGlCQUFPLFFB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QUFLLE9BQU8sSUFBSSxpQkFBaUIsRUFBRTtZQUMvQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDbkIsT0FBTztTQUNSO1FBQ0QsaUJBQWlCLGFBQWpCLGlCQUFpQix1QkFBakIsaUJBQWlCLENBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQzFELFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDN0QsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyB1aSBmcm9tICdkYXRhZ3Jvay1hcGkvdWknO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCAnLi4vLi4vY3NzL3F1ZXJ5LWJ1aWxkZXIuY3NzJztcbmltcG9ydCBkYXlqcyBmcm9tICdkYXlqcyc7XG5cbmV4cG9ydCBjb25zdCBTVUdHRVNUSU9OU19GVU5DVElPTiA9ICdzdWdnZXN0aW9uc0Z1bmN0aW9uJztcblxuZXhwb3J0IG5hbWVzcGFjZSBPcGVyYXRvcnMge1xuICAgIGV4cG9ydCBjb25zdCBDT05UQUlOUyA9ICdjb250YWlucyc7XG4gICAgZXhwb3J0IGNvbnN0IElOID0gJ2luJztcbiAgICBleHBvcnQgY29uc3QgU1RBUlRTX1dJVEggPSAnc3RhcnRzIHdpdGgnO1xuICAgIGV4cG9ydCBjb25zdCBFTkRTX1dJVEggPSAnZW5kcyB3aXRoJztcbiAgICBleHBvcnQgY29uc3QgR1QgPSAnPic7XG4gICAgZXhwb3J0IGNvbnN0IEdURSA9ICc+PSc7XG4gICAgZXhwb3J0IGNvbnN0IExUID0gJzwnO1xuICAgIGV4cG9ydCBjb25zdCBMVEUgPSAnPD0nO1xuICAgIGV4cG9ydCBjb25zdCBFUSA9ICc9JztcbiAgICBleHBvcnQgY29uc3QgTk9UX0VRID0gJyE9JztcbiAgICBleHBvcnQgY29uc3QgQkVGT1JFID0gJ2JlZm9yZSc7XG4gICAgZXhwb3J0IGNvbnN0IEFGVEVSID0gJ2FmdGVyJztcbiAgICBleHBvcnQgY29uc3QgT04gPSAnb24nO1xuICAgIGV4cG9ydCBjb25zdCBCRVRXRUVOID0gJ2JldHdlZW4nO1xuICAgIGV4cG9ydCBjb25zdCBJU19TSU1JTEFSID0gJ2lzIHNpbWlsYXInO1xuICAgIGV4cG9ydCBjb25zdCBJU19DT05UQUlORUQgPSAnaXMgY29udGFpbmVkJztcblxuICAgIGV4cG9ydCBlbnVtIExvZ2ljYWwge1xuICAgICAgICBhbmQgPSAnYW5kJyxcbiAgICAgICAgb3IgPSAnb3InLFxuICAgIH1cbn1cblxuZXhwb3J0IGVudW0gUXVlcnlCdWlsZGVyTGF5b3V0IHtcbiAgICBTdGFuZGFyZCA9ICdzdGFuZGFyZCcsXG4gICAgTmFycm93ID0gJ25hcnJvdydcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTaW1wbGVDb25kaXRpb248VCA9IGFueT4ge1xuICAgIGZpZWxkOiBzdHJpbmc7XG4gICAgb3BlcmF0b3I6IHN0cmluZztcbiAgICB2YWx1ZTogVDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21wbGV4Q29uZGl0aW9uIHtcbiAgICBsb2dpY2FsT3BlcmF0b3I6IE9wZXJhdG9ycy5Mb2dpY2FsO1xuICAgIGNvbmRpdGlvbnM6IEV4cHJlc3Npb25bXTtcbn1cblxuZXhwb3J0IHR5cGUgRXhwcmVzc2lvbjxUID0gYW55PiA9IFNpbXBsZUNvbmRpdGlvbjxUPiB8IENvbXBsZXhDb25kaXRpb247XG5cblxuZXhwb3J0IGNsYXNzIEJhc2VDb25kaXRpb25FZGl0b3I8VCA9IGFueT4ge1xuICAgIHJvb3Q6IEhUTUxEaXZFbGVtZW50ID0gdWkuZGl2KCk7XG4gICAgY29uZGl0aW9uOiBTaW1wbGVDb25kaXRpb248VD47XG4gICAgb25DaGFuZ2VkOiBTdWJqZWN0PFNpbXBsZUNvbmRpdGlvbjxUPj4gPSBuZXcgU3ViamVjdDxTaW1wbGVDb25kaXRpb248VD4+KCk7XG4gICAgc2hvd1N1Z2dlc3Rpb25zID0gZmFsc2U7XG4gICAgc3VnZ2VzdGlvbnNNZW51Q2xpY2tlZCA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IocHJvcDogREcuUHJvcGVydHksIG9wZXJhdG9yOiBzdHJpbmcsIGluaXRpYWxDb25kaXRpb24/OiBTaW1wbGVDb25kaXRpb248VD4pIHtcbiAgICAgICAgdGhpcy5jb25kaXRpb24gPSBpbml0aWFsQ29uZGl0aW9uID8/IHtcbiAgICAgICAgICAgIGZpZWxkOiBwcm9wLm5hbWUsXG4gICAgICAgICAgICBvcGVyYXRvcjogb3BlcmF0b3IsXG4gICAgICAgICAgICB2YWx1ZTogdW5kZWZpbmVkIGFzIFRcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplRWRpdG9yKHByb3ApO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBpbml0aWFsaXplRWRpdG9yKHByb3A6IERHLlByb3BlcnR5KTogdm9pZCB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMuY29uZGl0aW9uLnZhbHVlKSlcbiAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uLnZhbHVlID0gdW5kZWZpbmVkIGFzIFQ7XG4gICAgICAgIGNvbnN0IGluaXRWYWwgPSBwcm9wLnR5cGUgPT09IERHLlRZUEUuREFURV9USU1FICYmIHR5cGVvZiB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9PT0gJ3N0cmluZycgP1xuICAgICAgICAgICAgZGF5anModGhpcy5jb25kaXRpb24udmFsdWUgYXMgc3RyaW5nKSA6IHRoaXMuY29uZGl0aW9uLnZhbHVlO1xuICAgICAgICBjb25zdCBpbnB1dCA9IHVpLmlucHV0LmZvclByb3BlcnR5KHByb3AsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgdmFsdWU6IGluaXRWYWwsXG4gICAgICAgICAgICBudWxsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBvblZhbHVlQ2hhbmdlZDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uLnZhbHVlID0gaW5wdXQudmFsdWUgYXMgVDtcbiAgICAgICAgICAgICAgICB0aGlzLm9uQ2hhbmdlZC5uZXh0KHRoaXMuY29uZGl0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZFN1Z2dlc3Rpb25zKHByb3AsIGlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlucHV0LmFkZENhcHRpb24oJycpO1xuICAgICAgICB0aGlzLnJvb3QuYXBwZW5kKGlucHV0LnJvb3QpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVTdWdnZXN0aW9ucyhwcm9wLCBpbnB1dCk7XG4gICAgfVxuXG4gICAgaW5pdGlhbGl6ZVN1Z2dlc3Rpb25zKHByb3A6IERHLlByb3BlcnR5LCBpbnB1dDogREcuSW5wdXRCYXNlKSB7XG4gICAgICAgIHRoaXMuc2hvd1N1Z2dlc3Rpb25zID0gcHJvcC50eXBlID09PSBERy5UWVBFLlNUUklORyAmJiBwcm9wLm9wdGlvbnNbU1VHR0VTVElPTlNfRlVOQ1RJT05dO1xuICAgICAgICBpZiAodGhpcy5zaG93U3VnZ2VzdGlvbnMpIHtcbiAgICAgICAgICAgc3VnZ2VzdGlvbk1lbnVLZXlOYXZpZ2F0aW9uKHRoaXMucm9vdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBhZGRTdWdnZXN0aW9ucyhwcm9wOiBERy5Qcm9wZXJ0eSwgaW5wdXQ6IERHLklucHV0QmFzZSkge1xuICAgICAgICBpZiAodGhpcy5zaG93U3VnZ2VzdGlvbnMgJiYgIXRoaXMuc3VnZ2VzdGlvbnNNZW51Q2xpY2tlZCkge1xuICAgICAgICAgICAgaWYgKGlucHV0LnZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBzdWdnZXN0aW9uczogQXJyYXk8c3RyaW5nPiA9IGF3YWl0IHByb3Aub3B0aW9uc1tTVUdHRVNUSU9OU19GVU5DVElPTl0oaW5wdXQudmFsdWUpO1xuICAgICAgICAgICAgaWYgKHN1Z2dlc3Rpb25zLmxlbmd0aCA9PT0gMSAmJiBzdWdnZXN0aW9uc1swXSA9PT0gaW5wdXQudmFsdWUpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3Qgc3VnZ2VzdGlvbnNNZW51ID0gREcuTWVudS5wb3B1cCgpO1xuICAgICAgICAgICAgc3VnZ2VzdGlvbnMuZm9yRWFjaCgocykgPT4ge1xuICAgICAgICAgICAgICAgIHN1Z2dlc3Rpb25zTWVudSEuaXRlbShzLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0LnZhbHVlID0gcztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdWdnZXN0aW9uc01lbnVDbGlja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc3VnZ2VzdGlvbnNNZW51LnNob3coeyBlbGVtZW50OiBpbnB1dC5yb290LCB5OiBpbnB1dC5yb290Lm9mZnNldEhlaWdodCB9KTtcbiAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3VnZ2VzdGlvbnNNZW51Q2xpY2tlZCA9IGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEJldHdlZW5Db25kaXRpb25FZGl0b3IgZXh0ZW5kcyBCYXNlQ29uZGl0aW9uRWRpdG9yIHtcbiAgICBvdmVycmlkZSBpbml0aWFsaXplRWRpdG9yKHByb3A6IERHLlByb3BlcnR5KTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5jb25kaXRpb24udmFsdWUgfHwgIUFycmF5LmlzQXJyYXkodGhpcy5jb25kaXRpb24udmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9IFt0aGlzLmNvbmRpdGlvbi52YWx1ZSwgdW5kZWZpbmVkXTtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2VkLm5leHQodGhpcy5jb25kaXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0MSA9IHVpLmlucHV0LmZvclByb3BlcnR5KHByb3AsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgdmFsdWU6IHRoaXMuY29uZGl0aW9uLnZhbHVlWzBdLFxuICAgICAgICAgICAgbnVsbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgb25WYWx1ZUNoYW5nZWQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZVswXSA9IGlucHV0MS52YWx1ZSE7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZWQubmV4dCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpbnB1dDEuYWRkQ2FwdGlvbignJyk7XG4gICAgICAgIGNvbnN0IGlucHV0MiA9IHVpLmlucHV0LmZvclByb3BlcnR5KHByb3AsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgdmFsdWU6IHRoaXMuY29uZGl0aW9uLnZhbHVlWzFdLFxuICAgICAgICAgICAgb25WYWx1ZUNoYW5nZWQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZVsxXSA9IGlucHV0Mi52YWx1ZSE7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZWQubmV4dCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpbnB1dDIuYWRkQ2FwdGlvbignJyk7XG4gICAgICAgIHRoaXMucm9vdC5hcHBlbmQodWkuZGl2SChbaW5wdXQxLnJvb3QsIGlucHV0Mi5yb290XSwgeyBzdHlsZTogeyBnYXA6ICcxMHB4JyB9IH0pKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCb29sZWFuQ29uZGl0aW9uRWRpdG9yIGV4dGVuZHMgQmFzZUNvbmRpdGlvbkVkaXRvciB7XG4gICAgb3ZlcnJpZGUgaW5pdGlhbGl6ZUVkaXRvcihwcm9wOiBERy5Qcm9wZXJ0eSk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuY29uZGl0aW9uLnZhbHVlKVxuICAgICAgICAgICAgdGhpcy5jb25kaXRpb24udmFsdWUgPSB0cnVlXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBbJ3RydWUnLCAnZmFsc2UnXTtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB1aS5pbnB1dC5jaG9pY2UoJycsIHtcbiAgICAgICAgICAgIGl0ZW1zOiBvcHRpb25zLFxuICAgICAgICAgICAgbnVsbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuY29uZGl0aW9uLnZhbHVlID8gJ3RydWUnIDogJ2ZhbHNlJyxcbiAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2VkOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb24udmFsdWUgPSBpbnB1dC52YWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgIHRoaXMub25DaGFuZ2VkLm5leHQodGhpcy5jb25kaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yb290LmFwcGVuZChpbnB1dC5yb290KTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNb2xlY3VsZUNvbmRpdGlvbkVkaXRvciBleHRlbmRzIEJhc2VDb25kaXRpb25FZGl0b3I8c3RyaW5nPiB7XG4gICAgb3ZlcnJpZGUgaW5pdGlhbGl6ZUVkaXRvcihwcm9wOiBERy5Qcm9wZXJ0eSk6IHZvaWQge1xuICAgICAgICAvL2lmIHdlIHN3aXRoIGZyb20gc2ltaWxhcml0eSBpbnB1dCB0byBzdGFuZGFyZCBtb2xlY3VsZSBpbnB1dCAtIG5lZWQgdG8gbW9kaWZ5IHZhbHVlXG4gICAgICAgIGlmICh0aGlzLmNvbmRpdGlvbi52YWx1ZSAmJiB0eXBlb2YgdGhpcy5jb25kaXRpb24udmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoJ21vbGVjdWxlJyBpbiB0aGlzLmNvbmRpdGlvbi52YWx1ZSlcbiAgICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb24udmFsdWUgPSAodGhpcy5jb25kaXRpb24udmFsdWUgYXMgTW9sZWN1bGVTaW1pbGFyaXR5KS5tb2xlY3VsZTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9ICcnO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0ID0gdWkuaW5wdXQubW9sZWN1bGUoJycsIHtcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNvbmRpdGlvbi52YWx1ZSxcbiAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2VkOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb24udmFsdWUgPSBpbnB1dC52YWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uQ2hhbmdlZC5uZXh0KHRoaXMuY29uZGl0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucm9vdC5hcHBlbmQoaW5wdXQucm9vdCk7XG4gICAgICAgIC8vdG8gYWRqdXN0IHRoZSBmaWx0ZXIgd2lkdGggY29uc2lkZXJpbmcgbW9sZWN1bGUgaW5wdXRcbiAgICAgICAgdGhpcy5yb290LnN0eWxlLnBhZGRpbmdUb3AgPSAnMTVweCc7XG4gICAgICAgIHRoaXMucm9vdC5zdHlsZS5wYWRkaW5nQm90dG9tID0gJzE1cHgnO1xuICAgIH1cbn1cblxuZXhwb3J0IHR5cGUgTW9sZWN1bGVTaW1pbGFyaXR5ID0ge1xuICAgIG1vbGVjdWxlOiBzdHJpbmcsXG4gICAgdGhyZXNob2xkOiBudW1iZXJcbn1cbmV4cG9ydCBjbGFzcyBNb2xlY3VsZVNpbWlsYXJpdHlDb25kaXRpb25FZGl0b3IgZXh0ZW5kcyBCYXNlQ29uZGl0aW9uRWRpdG9yPE1vbGVjdWxlU2ltaWxhcml0eT4ge1xuICAgIG92ZXJyaWRlIGluaXRpYWxpemVFZGl0b3IocHJvcDogREcuUHJvcGVydHkpOiB2b2lkIHtcbiAgICAgICAgLy9pbiBjYXNlIHdlIHN3aXRjaCBmcm9tIHNvbWUgb3RoZXIgb3BlcmF0b3IsIHdoZXJlIHZhbHVlIGlzIGEgc3RyaW5nIChjb250YWlucywgaXMgY29udGFpbmVkKVxuICAgICAgICBpZiAoIXRoaXMuY29uZGl0aW9uLnZhbHVlIHx8IHR5cGVvZiB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uLnZhbHVlID0ge21vbGVjdWxlOiB0aGlzLmNvbmRpdGlvbi52YWx1ZSA/PyAnJywgdGhyZXNob2xkOiAwLjd9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1vbGVjdWxlSW5wdXQgPSB1aS5pbnB1dC5tb2xlY3VsZSgnJywge1xuICAgICAgICAgICAgb25WYWx1ZUNoYW5nZWQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZS5tb2xlY3VsZSA9IG1vbGVjdWxlSW5wdXQudmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZWQubmV4dCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB0cmVzaG9sZElucHV0ID0gdWkuaW5wdXQuZmxvYXQoJycsIHtcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNvbmRpdGlvbi52YWx1ZS50aHJlc2hvbGQsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBzdGVwOiAwLjAxXG4gICAgICAgIH0pO1xuICAgICAgICBERy5kZWJvdW5jZSh0cmVzaG9sZElucHV0Lm9uQ2hhbmdlZCwgMzAwKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb25kaXRpb24udmFsdWUudGhyZXNob2xkID0gdHJlc2hvbGRJbnB1dC52YWx1ZSE7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlZC5uZXh0KHRoaXMuY29uZGl0aW9uKTtcbiAgICAgICAgfSlcbiAgICAgICAgdGhpcy5yb290LmFwcGVuZCh1aS5kaXZWKFttb2xlY3VsZUlucHV0LnJvb3QsIHRyZXNob2xkSW5wdXQucm9vdF0pKTtcbiAgICAgICAgdGhpcy5yb290LnN0eWxlLnBhZGRpbmdUb3AgPSAnMTVweCc7XG4gICAgfVxufVxuXG5cbmV4cG9ydCBjbGFzcyBNdWx0aVZhbHVlQ29uZGl0aW9uRWRpdG9yU3RyaW5nIGV4dGVuZHMgQmFzZUNvbmRpdGlvbkVkaXRvcjxzdHJpbmdbXT4ge1xuICAgIG92ZXJyaWRlIGluaXRpYWxpemVFZGl0b3IocHJvcDogREcuUHJvcGVydHkpOiB2b2lkIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMuY29uZGl0aW9uLnZhbHVlKSkge1xuICAgICAgICAgICAgdGhpcy5jb25kaXRpb24udmFsdWUgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnB1dCA9IHVpLmlucHV0Lmxpc3QoJycsIHtcbiAgICAgICAgICAgIG51bGxhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNvbmRpdGlvbi52YWx1ZSxcbiAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2VkOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25kaXRpb24udmFsdWUgPSBpbnB1dC52YWx1ZSE7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZWQubmV4dCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJvb3QuYXBwZW5kKGlucHV0LnJvb3QpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIE11bHRpVmFsdWVDb25kaXRpb25FZGl0b3JJbnQgZXh0ZW5kcyBCYXNlQ29uZGl0aW9uRWRpdG9yPG51bWJlcltdPiB7XG4gICAgb3ZlcnJpZGUgaW5pdGlhbGl6ZUVkaXRvcihwcm9wOiBERy5Qcm9wZXJ0eSk6IHZvaWQge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5jb25kaXRpb24udmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0ID0gdWkuaW5wdXQubGlzdCgnJywge1xuICAgICAgICAgICAgbnVsbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuY29uZGl0aW9uLnZhbHVlLFxuICAgICAgICAgICAgb25WYWx1ZUNoYW5nZWQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9IGlucHV0LnZhbHVlIS5tYXAoKGl0KSA9PiBwYXJzZUludChpdCkpO1xuICAgICAgICAgICAgICAgIHRoaXMub25DaGFuZ2VkLm5leHQodGhpcy5jb25kaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yb290LmFwcGVuZChpbnB1dC5yb290KTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNdWx0aVZhbHVlQ29uZGl0aW9uRWRpdG9yRmxvYXQgZXh0ZW5kcyBCYXNlQ29uZGl0aW9uRWRpdG9yPG51bWJlcltdPiB7XG4gICAgb3ZlcnJpZGUgaW5pdGlhbGl6ZUVkaXRvcihwcm9wOiBERy5Qcm9wZXJ0eSk6IHZvaWQge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5jb25kaXRpb24udmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0ID0gdWkuaW5wdXQubGlzdCgnJywge1xuICAgICAgICAgICAgbnVsbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuY29uZGl0aW9uLnZhbHVlLFxuICAgICAgICAgICAgb25WYWx1ZUNoYW5nZWQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmRpdGlvbi52YWx1ZSA9IGlucHV0LnZhbHVlIS5tYXAoKGl0KSA9PiBwYXJzZUZsb2F0KGl0KSk7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZWQubmV4dCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJvb3QuYXBwZW5kKGlucHV0LnJvb3QpO1xuICAgIH1cbn1cblxuLy8gUmVnaXN0cnkgZm9yIGJvdGggb3BlcmF0b3JzIGFuZCBlZGl0b3JzXG5leHBvcnQgY2xhc3MgQ29uZGl0aW9uUmVnaXN0cnkge1xuICAgIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBDb25kaXRpb25SZWdpc3RyeTtcbiAgICBwcml2YXRlIHR5cGVPcGVyYXRvcnM6IE1hcDxzdHJpbmcsIHN0cmluZ1tdPiA9IG5ldyBNYXAoKTtcbiAgICBwcml2YXRlIHNlbVR5cGVPcGVyYXRvcnM6IE1hcDxzdHJpbmcsIHN0cmluZ1tdPiA9IG5ldyBNYXAoKTtcbiAgICBwcml2YXRlIGVkaXRvclJlZ2lzdHJ5OiBNYXA8c3RyaW5nLCBuZXcgKHByb3A6IERHLlByb3BlcnR5LCBvcGVyYXRvcjogc3RyaW5nLCBpbml0aWFsQ29uZGl0aW9uPzogYW55KSA9PiBCYXNlQ29uZGl0aW9uRWRpdG9yPiA9IG5ldyBNYXAoKTtcblxuICAgIHByaXZhdGUgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZURlZmF1bHRPcGVyYXRvcnMoKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplRGVmYXVsdEVkaXRvcnMoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogQ29uZGl0aW9uUmVnaXN0cnkge1xuICAgICAgICBpZiAoIUNvbmRpdGlvblJlZ2lzdHJ5Lmluc3RhbmNlKSB7XG4gICAgICAgICAgICBDb25kaXRpb25SZWdpc3RyeS5pbnN0YW5jZSA9IG5ldyBDb25kaXRpb25SZWdpc3RyeSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDb25kaXRpb25SZWdpc3RyeS5pbnN0YW5jZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRpYWxpemVEZWZhdWx0T3BlcmF0b3JzKCk6IHZvaWQge1xuICAgICAgICAvLyBUeXBlIG9wZXJhdG9yc1xuICAgICAgICB0aGlzLnJlZ2lzdGVyVHlwZU9wZXJhdG9ycyhERy5UWVBFLkJPT0wsIFtPcGVyYXRvcnMuRVFdKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlclR5cGVPcGVyYXRvcnMoREcuVFlQRS5TVFJJTkcsIFtPcGVyYXRvcnMuU1RBUlRTX1dJVEgsIE9wZXJhdG9ycy5DT05UQUlOUywgT3BlcmF0b3JzLkVRLCBPcGVyYXRvcnMuTk9UX0VRLCBPcGVyYXRvcnMuSU5dKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlclR5cGVPcGVyYXRvcnMoREcuVFlQRS5JTlQsIFtPcGVyYXRvcnMuR1QsIE9wZXJhdG9ycy5MVCwgT3BlcmF0b3JzLkdURSwgT3BlcmF0b3JzLkxURSwgT3BlcmF0b3JzLkVRLFxuICAgICAgICAgICAgT3BlcmF0b3JzLk5PVF9FUSwgT3BlcmF0b3JzLkJFVFdFRU4sIE9wZXJhdG9ycy5JTl0pO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyVHlwZU9wZXJhdG9ycyhERy5UWVBFLkZMT0FULCBbT3BlcmF0b3JzLkdULCBPcGVyYXRvcnMuTFQsIE9wZXJhdG9ycy5HVEUsIE9wZXJhdG9ycy5MVEUsIE9wZXJhdG9ycy5FUSxcbiAgICAgICAgICAgIE9wZXJhdG9ycy5OT1RfRVEsIE9wZXJhdG9ycy5CRVRXRUVOLCBPcGVyYXRvcnMuSU5dKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlclR5cGVPcGVyYXRvcnMoREcuVFlQRS5EQVRFX1RJTUUsIFtPcGVyYXRvcnMuQkVGT1JFLCBPcGVyYXRvcnMuQUZURVIsIE9wZXJhdG9ycy5CRVRXRUVOXSk7XG5cbiAgICAgICAgLy8gU2VtVHlwZSBvcGVyYXRvcnMgKHRha2UgcHJlY2VkZW5jZSBvdmVyIHR5cGUgb3BlcmF0b3JzKVxuICAgICAgICB0aGlzLnJlZ2lzdGVyU2VtVHlwZU9wZXJhdG9ycyhERy5TRU1UWVBFLk1PTEVDVUxFLCBbT3BlcmF0b3JzLkNPTlRBSU5TLCBPcGVyYXRvcnMuSVNfQ09OVEFJTkVELCBPcGVyYXRvcnMuRVEsIE9wZXJhdG9ycy5JU19TSU1JTEFSXSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0aWFsaXplRGVmYXVsdEVkaXRvcnMoKTogdm9pZCB7XG4gICAgICAgIC8vIFJlZ2lzdGVyIGRlZmF1bHQgZWRpdG9ycyBieSBwcm9wZXJ0eSB0eXBlICh3aXRoIGVtcHR5IHNlbVR5cGUgYW5kIG9wZXJhdG9yKVxuICAgICAgICB0aGlzLnJlZ2lzdGVyRWRpdG9yKERHLlRZUEUuU1RSSU5HLCAnJywgJycsIEJhc2VDb25kaXRpb25FZGl0b3IpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyRWRpdG9yKERHLlRZUEUuSU5ULCAnJywgJycsIEJhc2VDb25kaXRpb25FZGl0b3IpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyRWRpdG9yKERHLlRZUEUuRkxPQVQsICcnLCAnJywgQmFzZUNvbmRpdGlvbkVkaXRvcik7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJFZGl0b3IoREcuVFlQRS5EQVRFX1RJTUUsICcnLCAnJywgQmFzZUNvbmRpdGlvbkVkaXRvcik7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJFZGl0b3IoREcuVFlQRS5CT09MLCAnJywgJycsIEJhc2VDb25kaXRpb25FZGl0b3IpO1xuXG4gICAgICAgIC8vIFJlZ2lzdGVyIHNwZWNpYWxpemVkIGVkaXRvcnMgZm9yIHNwZWNpZmljIGNvbWJpbmF0aW9uc1xuICAgICAgICB0aGlzLnJlZ2lzdGVyRWRpdG9yKERHLlRZUEUuU1RSSU5HLCAnJywgT3BlcmF0b3JzLklOLCBNdWx0aVZhbHVlQ29uZGl0aW9uRWRpdG9yU3RyaW5nKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlckVkaXRvcihERy5UWVBFLklOVCwgJycsIE9wZXJhdG9ycy5JTiwgTXVsdGlWYWx1ZUNvbmRpdGlvbkVkaXRvckludCk7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJFZGl0b3IoREcuVFlQRS5GTE9BVCwgJycsIE9wZXJhdG9ycy5JTiwgTXVsdGlWYWx1ZUNvbmRpdGlvbkVkaXRvckZsb2F0KTtcbiAgICAgICAgdGhpcy5yZWdpc3RlckVkaXRvcihERy5UWVBFLkRBVEVfVElNRSwgJycsIE9wZXJhdG9ycy5CRVRXRUVOLCBCZXR3ZWVuQ29uZGl0aW9uRWRpdG9yKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlckVkaXRvcihERy5UWVBFLklOVCwgJycsIE9wZXJhdG9ycy5CRVRXRUVOLCBCZXR3ZWVuQ29uZGl0aW9uRWRpdG9yKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlckVkaXRvcihERy5UWVBFLkZMT0FULCAnJywgT3BlcmF0b3JzLkJFVFdFRU4sIEJldHdlZW5Db25kaXRpb25FZGl0b3IpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyRWRpdG9yKERHLlRZUEUuU1RSSU5HLCBERy5TRU1UWVBFLk1PTEVDVUxFLCBPcGVyYXRvcnMuQ09OVEFJTlMsIE1vbGVjdWxlQ29uZGl0aW9uRWRpdG9yKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlckVkaXRvcihERy5UWVBFLlNUUklORywgREcuU0VNVFlQRS5NT0xFQ1VMRSwgT3BlcmF0b3JzLklTX0NPTlRBSU5FRCwgTW9sZWN1bGVDb25kaXRpb25FZGl0b3IpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyRWRpdG9yKERHLlRZUEUuU1RSSU5HLCBERy5TRU1UWVBFLk1PTEVDVUxFLCBPcGVyYXRvcnMuRVEsIE1vbGVjdWxlQ29uZGl0aW9uRWRpdG9yKTtcbiAgICAgICAgdGhpcy5yZWdpc3RlckVkaXRvcihERy5UWVBFLlNUUklORywgREcuU0VNVFlQRS5NT0xFQ1VMRSwgT3BlcmF0b3JzLklTX1NJTUlMQVIsIE1vbGVjdWxlU2ltaWxhcml0eUNvbmRpdGlvbkVkaXRvcik7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJFZGl0b3IoREcuVFlQRS5CT09MLCAnJywgT3BlcmF0b3JzLkVRLCBCb29sZWFuQ29uZGl0aW9uRWRpdG9yKTtcbiAgICB9XG5cbiAgICAvLyBPcGVyYXRvciByZWdpc3RyYXRpb24gbWV0aG9kc1xuICAgIHJlZ2lzdGVyVHlwZU9wZXJhdG9ycyhwcm9wZXJ0eVR5cGU6IHN0cmluZywgb3BlcmF0b3JzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLnR5cGVPcGVyYXRvcnMuc2V0KHByb3BlcnR5VHlwZSwgb3BlcmF0b3JzKTtcbiAgICB9XG5cbiAgICByZWdpc3RlclNlbVR5cGVPcGVyYXRvcnMoc2VtVHlwZTogc3RyaW5nLCBvcGVyYXRvcnM6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VtVHlwZU9wZXJhdG9ycy5zZXQoc2VtVHlwZSwgb3BlcmF0b3JzKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgb3BlcmF0b3JzIGZvciBhIHByb3BlcnR5XG4gICAgZ2V0T3BlcmF0b3JzRm9yUHJvcGVydHkocHJvcGVydHk6IERHLlByb3BlcnR5KTogc3RyaW5nW10ge1xuICAgICAgICAvLyBDaGVjayBzZW1UeXBlIGZpcnN0LCB0aGVuIGZhbGwgYmFjayB0byB0eXBlXG4gICAgICAgIGNvbnN0IHNlbVR5cGVPcHMgPSB0aGlzLnNlbVR5cGVPcGVyYXRvcnMuZ2V0KHByb3BlcnR5LnNlbVR5cGUpO1xuICAgICAgICBpZiAoc2VtVHlwZU9wcykgcmV0dXJuIHNlbVR5cGVPcHM7XG5cbiAgICAgICAgY29uc3QgdHlwZU9wcyA9IHRoaXMudHlwZU9wZXJhdG9ycy5nZXQocHJvcGVydHkucHJvcGVydHlUeXBlKTtcbiAgICAgICAgcmV0dXJuIHR5cGVPcHMgfHwgW107XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgb3BlcmF0b3IgaXMgc3VwcG9ydGVkXG4gICAgaXNPcGVyYXRvclN1cHBvcnRlZChwcm9wZXJ0eTogREcuUHJvcGVydHksIG9wZXJhdG9yOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3Qgb3BlcmF0b3JzID0gdGhpcy5nZXRPcGVyYXRvcnNGb3JQcm9wZXJ0eShwcm9wZXJ0eSk7XG4gICAgICAgIHJldHVybiBvcGVyYXRvcnMuaW5jbHVkZXMob3BlcmF0b3IpO1xuICAgIH1cblxuICAgIC8vIEVkaXRvciByZWdpc3RyYXRpb24gbWV0aG9kc1xuICAgIHJlZ2lzdGVyRWRpdG9yPFQ+KFxuICAgICAgICBwcm9wZXJ0eVR5cGU6IHN0cmluZyxcbiAgICAgICAgc2VtVHlwZTogc3RyaW5nLFxuICAgICAgICBvcGVyYXRvcjogc3RyaW5nLFxuICAgICAgICBlZGl0b3JDbGFzczogbmV3IChwcm9wOiBERy5Qcm9wZXJ0eSwgb3BlcmF0b3I6IHN0cmluZykgPT4gQmFzZUNvbmRpdGlvbkVkaXRvcjxUPlxuICAgICk6IHZvaWQge1xuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmNyZWF0ZUVkaXRvcktleShwcm9wZXJ0eVR5cGUsIHNlbVR5cGUsIG9wZXJhdG9yKTtcbiAgICAgICAgdGhpcy5lZGl0b3JSZWdpc3RyeS5zZXQoa2V5LCBlZGl0b3JDbGFzcyk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIGVkaXRvciBmb3IgYSBwcm9wZXJ0eSBhbmQgb3BlcmF0b3JcbiAgICBjcmVhdGVFZGl0b3I8VD4ocHJvcGVydHk6IERHLlByb3BlcnR5LCBvcGVyYXRvcjogc3RyaW5nLCBpbml0aWFsQ29uZGl0aW9uPzogU2ltcGxlQ29uZGl0aW9uPFQ+KTogQmFzZUNvbmRpdGlvbkVkaXRvcjxUPiB7XG4gICAgICAgIC8vIFRyeSB0byBmaW5kIGEgc3BlY2lhbGl6ZWQgZWRpdG9yIGZpcnN0IChwcm9wZXJ0eVR5cGUgKyBzZW1UeXBlICsgb3BlcmF0b3IpXG4gICAgICAgIGNvbnN0IHNwZWNpYWxpemVkS2V5ID0gdGhpcy5jcmVhdGVFZGl0b3JLZXkocHJvcGVydHkucHJvcGVydHlUeXBlLCBwcm9wZXJ0eS5zZW1UeXBlLCBvcGVyYXRvcik7XG4gICAgICAgIGxldCBFZGl0b3JDbGFzcyA9IHRoaXMuZWRpdG9yUmVnaXN0cnkuZ2V0KHNwZWNpYWxpemVkS2V5KTtcblxuICAgICAgICAvLyBJZiBubyBzcGVjaWFsaXplZCBlZGl0b3IsIHRyeSB3aXRoIGVtcHR5IHNlbVR5cGUgKHByb3BlcnR5VHlwZSArIG9wZXJhdG9yKVxuICAgICAgICBpZiAoIUVkaXRvckNsYXNzKSB7XG4gICAgICAgICAgICBjb25zdCB0eXBlT25seUtleSA9IHRoaXMuY3JlYXRlRWRpdG9yS2V5KHByb3BlcnR5LnByb3BlcnR5VHlwZSwgJycsIG9wZXJhdG9yKTtcbiAgICAgICAgICAgIEVkaXRvckNsYXNzID0gdGhpcy5lZGl0b3JSZWdpc3RyeS5nZXQodHlwZU9ubHlLZXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgc3RpbGwgbm8gc3BlY2lhbGl6ZWQgZWRpdG9yLCB1c2UgZGVmYXVsdCBlZGl0b3IgZm9yIHByb3BlcnR5IHR5cGUgKHByb3BlcnR5VHlwZSBvbmx5KVxuICAgICAgICBpZiAoIUVkaXRvckNsYXNzKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0S2V5ID0gdGhpcy5jcmVhdGVFZGl0b3JLZXkocHJvcGVydHkucHJvcGVydHlUeXBlLCAnJywgJycpO1xuICAgICAgICAgICAgRWRpdG9yQ2xhc3MgPSB0aGlzLmVkaXRvclJlZ2lzdHJ5LmdldChkZWZhdWx0S2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZhbGxiYWNrIHRvIGJhc2UgZWRpdG9yXG4gICAgICAgIGlmICghRWRpdG9yQ2xhc3MpIHtcbiAgICAgICAgICAgIEVkaXRvckNsYXNzID0gQmFzZUNvbmRpdGlvbkVkaXRvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgRWRpdG9yQ2xhc3MocHJvcGVydHksIG9wZXJhdG9yLCBpbml0aWFsQ29uZGl0aW9uKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgY29uZGl0aW9uIGVkaXRvciBmb3IgYSBwcm9wZXJ0eSBhbmQgb3BlcmF0b3IgKHdpdGggdmFsaWRhdGlvbilcbiAgICBnZXRDb25kaXRpb25FZGl0b3I8VCA9IGFueT4ocHJvcGVydHk6IERHLlByb3BlcnR5LCBvcGVyYXRvcjogc3RyaW5nLCBjb25kaXRpb24/OiBTaW1wbGVDb25kaXRpb248VD4pOiBCYXNlQ29uZGl0aW9uRWRpdG9yPFQ+IHtcbiAgICAgICAgaWYgKHRoaXMuaXNPcGVyYXRvclN1cHBvcnRlZChwcm9wZXJ0eSwgb3BlcmF0b3IpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVFZGl0b3IocHJvcGVydHksIG9wZXJhdG9yLCBjb25kaXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoYE9wZXJhdG9yICcke29wZXJhdG9yfScgaXMgbm90IHN1cHBvcnRlZCBmb3IgcHJvcGVydHkgdHlwZSAnJHtwcm9wZXJ0eS5wcm9wZXJ0eVR5cGV9J2ApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjcmVhdGVFZGl0b3JLZXkocHJvcGVydHlUeXBlOiBzdHJpbmcsIHNlbVR5cGU6IHN0cmluZywgb3BlcmF0b3I6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgJHtwcm9wZXJ0eVR5cGV9OiR7c2VtVHlwZX06JHtvcGVyYXRvcn1gO1xuICAgIH1cbn1cblxuXG5leHBvcnQgdHlwZSBIaXN0b3J5SXRlbSA9IHtcbiAgICBkYXRlOiBERy5UWVBFLkRBVEVfVElNRSxcbiAgICB2YWx1ZTogc3RyaW5nLFxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2F2ZUhpc3Rvcnkoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpIHtcbiAgICBsZXQgY29sbGVjdGlvbjogSGlzdG9yeUl0ZW1bXSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KSA/PyAnW10nKTtcbiAgICBjb25zdCBuZXdJdGVtID0geyBkYXRlOiBuZXcgRGF0ZSgpLCB2YWx1ZTogdmFsdWUgfTtcbiAgICBpZiAoIWNvbGxlY3Rpb24ubGVuZ3RoKVxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShrZXksIEpTT04uc3RyaW5naWZ5KFtuZXdJdGVtXSkpO1xuICAgIGVsc2Uge1xuICAgICAgICBjb2xsZWN0aW9uID0gY29sbGVjdGlvbi5maWx0ZXIoKGl0KSA9PiBpdC52YWx1ZSAhPT0gdmFsdWUpXG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkoW25ld0l0ZW0sIC4uLmNvbGxlY3Rpb24uc2xpY2UoMCwgOSldKSk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SGlzdG9yeShrZXk6IHN0cmluZyk6IEhpc3RvcnlJdGVtW10ge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKGtleSkgPz8gJ1tdJyk7XG59XG5cbmV4cG9ydCBjbGFzcyBRdWVyeUJ1aWxkZXIge1xuICAgIHJvb3Q6IEhUTUxFbGVtZW50O1xuICAgIGNvbmRpdGlvbjogQ29tcGxleENvbmRpdGlvbjtcbiAgICBwcm9wZXJ0aWVzOiBERy5Qcm9wZXJ0eVtdO1xuICAgIHN0cnVjdHVyZUNoYW5nZWQ6IFN1YmplY3Q8Q29tcGxleENvbmRpdGlvbj4gPSBuZXcgU3ViamVjdDxDb21wbGV4Q29uZGl0aW9uPigpO1xuICAgIGZpbHRlclZhbHVlQ2hhbmdlZDogU3ViamVjdDxTaW1wbGVDb25kaXRpb24+ID0gbmV3IFN1YmplY3Q8U2ltcGxlQ29uZGl0aW9uPigpO1xuICAgIGxheW91dDogUXVlcnlCdWlsZGVyTGF5b3V0O1xuICAgIHByaXZhdGUgX2hpc3RvcnlDYWNoZUtleTogc3RyaW5nO1xuICAgIHByaXZhdGUgaGlzdG9yeUljb246IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9wZXJ0aWVzOiBERy5Qcm9wZXJ0eVtdLCBpbml0aWFsQ29uZGl0aW9uPzogQ29tcGxleENvbmRpdGlvbiwgbGF5b3V0OiBRdWVyeUJ1aWxkZXJMYXlvdXQgPSBRdWVyeUJ1aWxkZXJMYXlvdXQuU3RhbmRhcmQsXG4gICAgICAgIF9oaXN0b3J5Q2FjaGVLZXk6IHN0cmluZyA9ICcnKSB7XG4gICAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgICAgIHRoaXMubGF5b3V0ID0gbGF5b3V0O1xuICAgICAgICB0aGlzLl9oaXN0b3J5Q2FjaGVLZXkgPSBfaGlzdG9yeUNhY2hlS2V5O1xuICAgICAgICBcbiAgICAgICAgaWYgKGluaXRpYWxDb25kaXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uID0gaW5pdGlhbENvbmRpdGlvbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRDb25kaXRpb24gPSB0aGlzLmNyZWF0ZURlZmF1bHRTaW1wbGVDb25kaXRpb24oKTtcbiAgICAgICAgICAgIHRoaXMuY29uZGl0aW9uID0ge1xuICAgICAgICAgICAgICAgICAgICBsb2dpY2FsT3BlcmF0b3I6IE9wZXJhdG9ycy5Mb2dpY2FsLmFuZCxcbiAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uczogW2RlZmF1bHRDb25kaXRpb25dXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yb290ID0gdGhpcy5idWlsZFVJKHRoaXMuY29uZGl0aW9uLCB1bmRlZmluZWQsIDApO1xuICAgICAgICB0aGlzLnNldHVwSGlzdG9yeUljb24oKTtcbiAgICB9XG5cbiAgICBzZXQgaGlzdG9yeUNhY2hlKGtleTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuX2hpc3RvcnlDYWNoZUtleSA9IGtleTtcbiAgICAgICAgdGhpcy5zZXR1cEhpc3RvcnlJY29uKCk7IC8vIFRoaXMgd2lsbCBjb250cm9sIHZpc2liaWxpdHlcbiAgICB9XG5cbiAgICBzYXZlQ29uZGl0aW9uVG9IaXN0b3J5KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5faGlzdG9yeUNhY2hlS2V5KVxuICAgICAgICAgICAgc2F2ZUhpc3RvcnkodGhpcy5faGlzdG9yeUNhY2hlS2V5LCBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmRpdGlvbikpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0dXBIaXN0b3J5SWNvbigpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmhpc3RvcnlJY29uKSB7XG4gICAgICAgICAgICB0aGlzLmhpc3RvcnlJY29uID0gdWkuaWNvbkZBKCdoaXN0b3J5JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0hpc3RvcnlNZW51KCk7XG4gICAgICAgICAgICB9LCAnUXVlcnkgSGlzdG9yeScpO1xuXG4gICAgICAgICAgICB0aGlzLmhpc3RvcnlJY29uLmNsYXNzTGlzdC5hZGQoJ3F1ZXJ5LWJ1aWxkZXItaGlzdG9yeS1pY29uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJvb3QuYXBwZW5kQ2hpbGQodGhpcy5oaXN0b3J5SWNvbik7XG4gICAgICAgIFxuICAgICAgICAvLyBTZXQgZGF0YSBhdHRyaWJ1dGUgZm9yIENTUyB0byBjb250cm9sIHZpc2liaWxpdHlcbiAgICAgICAgaWYgKHRoaXMucm9vdCkge1xuICAgICAgICAgICAgdGhpcy5yb290LnNldEF0dHJpYnV0ZSgnZGF0YS1oaXN0b3J5JywgdGhpcy5faGlzdG9yeUNhY2hlS2V5ICA9PT0gJycgPyAnZmFsc2UnIDogJ3RydWUnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2hvd0hpc3RvcnlNZW51KCk6IHZvaWQge1xuICAgICAgICBjb25zdCBpdGVtczogSGlzdG9yeUl0ZW1bXSA9IGdldEhpc3RvcnkodGhpcy5faGlzdG9yeUNhY2hlS2V5KTtcbiAgICAgICAgY29uc3QgbWVudSA9IERHLk1lbnUucG9wdXAoKTtcbiAgICAgICAgbWVudS5pdGVtcyhpdGVtcy5tYXAoKGl0KSA9PiB1aS50b29scy5jbGljayhcbiAgICAgICAgICAgIHVpLmRpdkgoW1xuICAgICAgICAgICAgICAgIHVpLmRpdlRleHQoaXQuZGF0ZS50b1N0cmluZygpLCB7c3R5bGU6IHtjb2xvcjogJyM3OTkwQTUnfX0pLFxuICAgICAgICAgICAgICAgIHVpLmRpdlRleHQodGhpcy5jb25kaXRpb25Ub1N0cmluZyhKU09OLnBhcnNlKGl0LnZhbHVlKSBhcyBDb21wbGV4Q29uZGl0aW9uKSksXG4gICAgICAgICAgICBdLCB7c3R5bGU6IHtnYXA6ICc1cHgnfX0pLFxuICAgICAgICAoKSA9PiB7dGhpcy5sb2FkQ29uZGl0aW9uKEpTT04ucGFyc2UoaXQudmFsdWUpKX0pKSwgKCkgPT4ge30pO1xuICAgICAgICBtZW51LnNob3coKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGxvYWRDb25kaXRpb24oY29uZGl0aW9uOiBDb21wbGV4Q29uZGl0aW9uKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY29uZGl0aW9uID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShjb25kaXRpb24pKTtcbiAgICAgICAgdGhpcy5yZWJ1aWxkVUkoKTtcbiAgICAgICAgdGhpcy5zdHJ1Y3R1cmVDaGFuZ2VkLm5leHQodGhpcy5jb25kaXRpb24pO1xuICAgIH1cblxuICAgIGNvbmRpdGlvblRvU3RyaW5nKGNvbmRpdGlvbjogQ29tcGxleENvbmRpdGlvbik6IHN0cmluZyB7XG4gICAgICAgIGlmICghY29uZGl0aW9uIHx8ICFjb25kaXRpb24uY29uZGl0aW9ucyB8fCBjb25kaXRpb24uY29uZGl0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiAnTm8gY29uZGl0aW9ucyc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGVyZSdzIG9ubHkgb25lIGNvbmRpdGlvbiwgZG9uJ3Qgd3JhcCBpdCBpbiBsb2dpY2FsIG9wZXJhdG9yXG4gICAgICAgIGlmIChjb25kaXRpb24uY29uZGl0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV4cHJlc3Npb25Ub1N0cmluZyhjb25kaXRpb24uY29uZGl0aW9uc1swXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb3IgbXVsdGlwbGUgY29uZGl0aW9ucywgd3JhcCB0aGVtIGluIGxvZ2ljYWwgb3BlcmF0b3JcbiAgICAgICAgY29uc3QgbG9naWNhbE9wID0gY29uZGl0aW9uLmxvZ2ljYWxPcGVyYXRvciA9PT0gT3BlcmF0b3JzLkxvZ2ljYWwuYW5kID8gJ0FORCcgOiAnT1InO1xuICAgICAgICBjb25zdCBjb25kaXRpb25TdHJpbmdzID0gY29uZGl0aW9uLmNvbmRpdGlvbnMubWFwKGNvbmQgPT4gdGhpcy5leHByZXNzaW9uVG9TdHJpbmcoY29uZCkpO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGAoJHtjb25kaXRpb25TdHJpbmdzLmpvaW4oYCAke2xvZ2ljYWxPcH0gYCl9KWA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBleHByZXNzaW9uVG9TdHJpbmcoZXhwcmVzc2lvbjogRXhwcmVzc2lvbik6IHN0cmluZyB7XG4gICAgICAgIGlmICgnZmllbGQnIGluIGV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBTaW1wbGVDb25kaXRpb25cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNpbXBsZUNvbmRpdGlvblRvU3RyaW5nKGV4cHJlc3Npb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIENvbXBsZXhDb25kaXRpb24gKHJlY3Vyc2l2ZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbmRpdGlvblRvU3RyaW5nKGV4cHJlc3Npb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzaW1wbGVDb25kaXRpb25Ub1N0cmluZyhjb25kaXRpb246IFNpbXBsZUNvbmRpdGlvbik6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gY29uZGl0aW9uLmZpZWxkIHx8ICdVbmtub3duIGZpZWxkJztcbiAgICAgICAgY29uc3Qgb3BlcmF0b3IgPSBjb25kaXRpb24ub3BlcmF0b3IgfHwgJ1Vua25vd24gb3BlcmF0b3InO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbmRpdGlvbi52YWx1ZSAhPT0gdW5kZWZpbmVkICYmIGNvbmRpdGlvbi52YWx1ZSAhPT0gbnVsbCA/IFxuICAgICAgICAgICAgKEFycmF5LmlzQXJyYXkoY29uZGl0aW9uLnZhbHVlKSA/IGBbJHtjb25kaXRpb24udmFsdWUuam9pbignLCAnKX1dYCA6IFN0cmluZyhjb25kaXRpb24udmFsdWUpKSA6IFxuICAgICAgICAgICAgJ05vIHZhbHVlJztcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBgJHtmaWVsZH0gJHtvcGVyYXRvcn0gJHt2YWx1ZX1gO1xuICAgIH1cblxuICAgIGNyZWF0ZURlZmF1bHRTaW1wbGVDb25kaXRpb24oKTogU2ltcGxlQ29uZGl0aW9uIHtcbiAgICAgICAgY29uc3QgZmlyc3RQcm9wZXJ0eSA9IHRoaXMucHJvcGVydGllc1swXTtcbiAgICAgICAgaWYgKGZpcnN0UHJvcGVydHkpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gQ29uZGl0aW9uUmVnaXN0cnkuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgICAgIGNvbnN0IG9wZXJhdG9ycyA9IHJlZ2lzdHJ5LmdldE9wZXJhdG9yc0ZvclByb3BlcnR5KGZpcnN0UHJvcGVydHkpO1xuICAgICAgICAgICAgY29uc3QgZmlyc3RPcGVyYXRvciA9IG9wZXJhdG9yc1swXTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmaWVsZDogZmlyc3RQcm9wZXJ0eS5uYW1lLFxuICAgICAgICAgICAgICAgIG9wZXJhdG9yOiBmaXJzdE9wZXJhdG9yLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnJyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIG9wZXJhdG9yOiAnJ1xuICAgICAgICAgICAgfVxuICAgIH1cblxuICAgIHJlYnVpbGRVSSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbmV3Um9vdCA9IHRoaXMuYnVpbGRVSSh0aGlzLmNvbmRpdGlvbiwgdW5kZWZpbmVkLCAwKTtcbiAgICAgICAgdGhpcy5yb290LnJlcGxhY2VXaXRoKG5ld1Jvb3QpO1xuICAgICAgICB0aGlzLnJvb3QgPSBuZXdSb290O1xuICAgICAgICBcbiAgICAgICAgLy8gUmVjcmVhdGUgaGlzdG9yeSBpY29uIGFmdGVyIHJlYnVpbGRpbmcgVUlcbiAgICAgICAgdGhpcy5zZXR1cEhpc3RvcnlJY29uKCk7XG4gICAgfVxuXG4gICAgc2V0TGF5b3V0KGxheW91dDogUXVlcnlCdWlsZGVyTGF5b3V0KTogdm9pZCB7XG4gICAgICAgIHRoaXMubGF5b3V0ID0gbGF5b3V0O1xuXG4gICAgICAgIGlmIChsYXlvdXQgPT09IFF1ZXJ5QnVpbGRlckxheW91dC5OYXJyb3cpXG4gICAgICAgICAgICB0aGlzLnJvb3QuY2xhc3NMaXN0LmFkZCgncXVlcnktYnVpbGRlci1uYXJyb3cnKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5yb290LmNsYXNzTGlzdC5yZW1vdmUoJ3F1ZXJ5LWJ1aWxkZXItbmFycm93Jyk7XG4gICAgICAgIFxuICAgICAgICAvLyBGaW5kIGFsbCBmaWx0ZXIgY29udGFpbmVycyBhbmQgYXBwbHkvcmVtb3ZlIGxheW91dCBjbGFzc2VzXG4gICAgICAgIGNvbnN0IGZpbHRlckNvbnRhaW5lcnMgPSB0aGlzLnJvb3QucXVlcnlTZWxlY3RvckFsbCgnLnF1ZXJ5LWJ1aWxkZXItZmlsdGVyLWlucHV0cywgLnF1ZXJ5LWJ1aWxkZXItZmlsdGVyLWlucHV0cy1uYXJyb3cnKTtcbiAgICAgICAgXG4gICAgICAgIGZpbHRlckNvbnRhaW5lcnMuZm9yRWFjaChjb250YWluZXIgPT4ge1xuICAgICAgICAgICAgaWYgKGxheW91dCA9PT0gUXVlcnlCdWlsZGVyTGF5b3V0Lk5hcnJvdykge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdxdWVyeS1idWlsZGVyLWZpbHRlci1pbnB1dHMnKTtcbiAgICAgICAgICAgICAgICBjb250YWluZXIuY2xhc3NMaXN0LmFkZCgncXVlcnktYnVpbGRlci1maWx0ZXItaW5wdXRzLW5hcnJvdycpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSgncXVlcnktYnVpbGRlci1maWx0ZXItaW5wdXRzLW5hcnJvdycpO1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdxdWVyeS1idWlsZGVyLWZpbHRlci1pbnB1dHMnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0TGF5b3V0KCk6IFF1ZXJ5QnVpbGRlckxheW91dCB7XG4gICAgICAgIHJldHVybiB0aGlzLmxheW91dDtcbiAgICB9XG5cbiAgICBidWlsZFVJKFxuICAgICAgICBjb25kaXRpb246IENvbXBsZXhDb25kaXRpb24sXG4gICAgICAgIHBhcmVudENvbmRpdGlvbj86IENvbXBsZXhDb25kaXRpb24sXG4gICAgICAgIG5lc3RpbmdMZXZlbDogbnVtYmVyID0gMFxuICAgICk6IEhUTUxFbGVtZW50IHtcblxuICAgICAgICBpZiAoIWNvbmRpdGlvbikge1xuICAgICAgICAgICAgY29uZGl0aW9uID0ge1xuICAgICAgICAgICAgICAgIGxvZ2ljYWxPcGVyYXRvcjogT3BlcmF0b3JzLkxvZ2ljYWwuYW5kLFxuICAgICAgICAgICAgICAgIGNvbmRpdGlvbnM6IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVtb3ZlT3JSZXBsYWNlQ29uZGl0aW9uID0gKGNvbmRUb1JlbW92ZTogRXhwcmVzc2lvbiwgY29uZEFycmF5PzogRXhwcmVzc2lvbltdLCByZXBsYWNlQ29uZD86IENvbXBsZXhDb25kaXRpb24pID0+IHtcbiAgICAgICAgICAgIGlmIChjb25kQXJyYXkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25kSWR4ID0gY29uZEFycmF5LmluZGV4T2YoY29uZFRvUmVtb3ZlKTtcbiAgICAgICAgICAgICAgICBpZiAoY29uZElkeCAhPT0gLTEpXG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VDb25kID8gY29uZEFycmF5W2NvbmRJZHhdID0gcmVwbGFjZUNvbmQgOiBjb25kQXJyYXkuc3BsaWNlKGNvbmRJZHgsIDEpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY3JlYXRlUHJvcGVydHlGaWx0ZXJDb250YWluZXIgPSAoY29uZDogU2ltcGxlQ29uZGl0aW9uLCBwYXJlbnRDb25kaXRpb24/OiBDb21wbGV4Q29uZGl0aW9uKSA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZUZpbHRlciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB1aS5lbXB0eShvcGVyYXRvcklucHV0RGl2KTtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9wZXJ0eSA9IGdldFByb3BCeUZyaWVuZGx5TmFtZShmaWVsZENob2ljZUlucHV0LnZhbHVlISk7XG4gICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlZ2lzdHJ5ID0gQ29uZGl0aW9uUmVnaXN0cnkuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3BlcmF0b3JzID0gcmVnaXN0cnkuZ2V0T3BlcmF0b3JzRm9yUHJvcGVydHkocHJvcGVydHkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbmQub3BlcmF0b3IgfHwgY29uZC5vcGVyYXRvciA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmQub3BlcmF0b3IgPSBvcGVyYXRvcnNbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25kLnZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJWYWx1ZUNoYW5nZWQubmV4dChjb25kKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcGVyYXRvcnNJbnB1dCA9IHVpLmlucHV0LmNob2ljZSgnJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGNvbmQub3BlcmF0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtczogb3BlcmF0b3JzLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25WYWx1ZUNoYW5nZWQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kLm9wZXJhdG9yID0gb3BlcmF0b3JzSW5wdXQudmFsdWUhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVidWlsZFVJKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJ1Y3R1cmVDaGFuZ2VkLm5leHQodGhpcy5jb25kaXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bGxhYmxlOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3JJbnB1dERpdi5hcHBlbmQob3BlcmF0b3JzSW5wdXQucm9vdCk7XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVkaXRvcihwcm9wZXJ0eSwgY29uZC5vcGVyYXRvciwgY29uZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjcmVhdGVFZGl0b3IgPSAocHJvcGVydHk6IERHLlByb3BlcnR5LCBvcGVyYXRvcjogc3RyaW5nLCBjb25kaXRpb246IFNpbXBsZUNvbmRpdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIHVpLmVtcHR5KGNyaXRlcmlhRGl2KTtcbiAgICAgICAgICAgICAgICBjb25zdCByZWdpc3RyeSA9IENvbmRpdGlvblJlZ2lzdHJ5LmdldEluc3RhbmNlKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgZWRpdG9yID0gcmVnaXN0cnkuZ2V0Q29uZGl0aW9uRWRpdG9yKHByb3BlcnR5LCBvcGVyYXRvciwgY29uZGl0aW9uKTtcbiAgICAgICAgICAgICAgICBlZGl0b3Iub25DaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyVmFsdWVDaGFuZ2VkLm5leHQoZWRpdG9yLmNvbmRpdGlvbik7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBjcml0ZXJpYURpdi5hcHBlbmQoZWRpdG9yLnJvb3QpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdldFByb3BCeU5hbWUgPSAobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvcGVydHkgPSB0aGlzLnByb3BlcnRpZXMuZmluZCgocHJvcDogREcuUHJvcGVydHkpID0+IHByb3AubmFtZSA9PT0gbmFtZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBnZXRQcm9wQnlGcmllbmRseU5hbWUgPSAoZnJpZW5kbHlOYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgcHJvcGVydHkgPSB0aGlzLnByb3BlcnRpZXMuZmluZCgocHJvcDogREcuUHJvcGVydHkpID0+IHByb3AuZnJpZW5kbHlOYW1lID09PSBmcmllbmRseU5hbWUpO1xuICAgICAgICAgICAgICAgIGlmICghcHJvcGVydHkpXG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnR5ID0gdGhpcy5wcm9wZXJ0aWVzLmZpbmQoKHByb3A6IERHLlByb3BlcnR5KSA9PiBwcm9wLm5hbWUgPT09IGZyaWVuZGx5TmFtZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBnZXRGaWVsZENob2ljZUlucHV0VmFsID0gKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb3AgPSBnZXRQcm9wQnlOYW1lKG5hbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9wPy5mcmllbmRseU5hbWUgPz8gcHJvcD8ubmFtZSA/PyAnJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZ2V0UHJvcE5hbWVCeUNob2ljZUlucHV0VmFsID0gKGZyaWVuZGx5TmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvcCA9IGdldFByb3BCeUZyaWVuZGx5TmFtZShmcmllbmRseU5hbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9wPy5uYW1lID8/ICcnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25kLmZpZWxkID8/PSB0aGlzLnByb3BlcnRpZXNbMF0/Lm5hbWUgfHwgJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGZpZWxkQ2hvaWNlSW5wdXQgPSB1aS5pbnB1dC5jaG9pY2UoJycsIHtcbiAgICAgICAgICAgICAgICBpdGVtczogdGhpcy5wcm9wZXJ0aWVzLm1hcCgocHJvcDogREcuUHJvcGVydHkpID0+IHByb3AuZnJpZW5kbHlOYW1lID8/IHByb3AubmFtZSksXG4gICAgICAgICAgICAgICAgdmFsdWU6IGdldEZpZWxkQ2hvaWNlSW5wdXRWYWwoY29uZC5maWVsZCksXG4gICAgICAgICAgICAgICAgbnVsbGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2VkOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmQuZmllbGQgPSBnZXRQcm9wTmFtZUJ5Q2hvaWNlSW5wdXRWYWwoZmllbGRDaG9pY2VJbnB1dC52YWx1ZSEpO1xuICAgICAgICAgICAgICAgICAgICBjb25kLnZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICBjb25kLm9wZXJhdG9yID0gJyc7XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZUZpbHRlcigpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlclZhbHVlQ2hhbmdlZC5uZXh0KGNvbmQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBkZWxldGVGaWVsZEljb24gPSB1aS5pY29ucy5kZWxldGUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChmaWx0ZXJDb250YWluZXIpO1xuICAgICAgICAgICAgICAgIHJlbW92ZU9yUmVwbGFjZUNvbmRpdGlvbihjb25kLCBwYXJlbnRDb25kaXRpb24gPyBwYXJlbnRDb25kaXRpb24uY29uZGl0aW9ucyA6IGNvbmRpdGlvbi5jb25kaXRpb25zKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlYnVpbGRVSSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RydWN0dXJlQ2hhbmdlZC5uZXh0KHRoaXMuY29uZGl0aW9uKTtcbiAgICAgICAgICAgIH0sICdSZW1vdmUgY3VycmVudCBjb25kaXRpb24nKTtcblxuICAgICAgICAgICAgY29uc3QgYWRkTmVzdGVkQ29uZGl0aW9uSWNvbiA9IHVpLmljb25zLmFkZCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50Q29uZCA9IHsgbG9naWNhbE9wZXJhdG9yOiBPcGVyYXRvcnMuTG9naWNhbC5hbmQsIGNvbmRpdGlvbnM6IFtjb25kXSB9O1xuICAgICAgICAgICAgICAgIHJlbW92ZU9yUmVwbGFjZUNvbmRpdGlvbihjb25kLCBwYXJlbnRDb25kaXRpb24gPyBwYXJlbnRDb25kaXRpb24uY29uZGl0aW9ucyA6IGNvbmRpdGlvbi5jb25kaXRpb25zLCBwYXJlbnRDb25kKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlYnVpbGRVSSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RydWN0dXJlQ2hhbmdlZC5uZXh0KHRoaXMuY29uZGl0aW9uKTtcblxuICAgICAgICAgICAgfSwgJ0FkZCBuZXN0ZWQgY29uZGl0aW9uJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IG9wZXJhdG9ySW5wdXREaXYgPSB1aS5kaXYoJycsICdxdWVyeS1idWlsZGVyLWZpbHRlci1vcGVyYXRvcicpO1xuICAgICAgICAgICAgY29uc3QgY3JpdGVyaWFEaXYgPSB1aS5kaXYoKTtcblxuICAgICAgICAgICAgY29uc3QgZmlsdGVyQ29udGFpbmVyID0gdWkuZGl2KFtcbiAgICAgICAgICAgICAgICB1aS5kaXYoW2ZpZWxkQ2hvaWNlSW5wdXQucm9vdF0sICdxdWVyeS1idWlsZGVyLWZpbHRlci1maWVsZCcpLFxuICAgICAgICAgICAgICAgIHVpLmRpdihbb3BlcmF0b3JJbnB1dERpdl0sICdxdWVyeS1idWlsZGVyLWZpbHRlci1vcGVyYXRvcicpLFxuICAgICAgICAgICAgICAgIHVpLmRpdihbY3JpdGVyaWFEaXZdLCAncXVlcnktYnVpbGRlci1maWx0ZXItdmFsdWUnKSxcbiAgICAgICAgICAgICAgICB1aS5kaXYoW2RlbGV0ZUZpZWxkSWNvbiwgYWRkTmVzdGVkQ29uZGl0aW9uSWNvbl0sICdhZGQtZGVsZXRlLWljb25zJylcbiAgICAgICAgICAgIF0sIHRoaXMubGF5b3V0ID09PSBRdWVyeUJ1aWxkZXJMYXlvdXQuTmFycm93ID8gJ3F1ZXJ5LWJ1aWxkZXItZmlsdGVyLWlucHV0cy1uYXJyb3cnIDogJ3F1ZXJ5LWJ1aWxkZXItZmlsdGVyLWlucHV0cycpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoZmlsdGVyQ29udGFpbmVyKTtcbiAgICAgICAgICAgIGNyZWF0ZUZpbHRlcigpO1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJWYWx1ZUNoYW5nZWQubmV4dChjb25kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGFkZGluZyBmaWx0ZXIgZmllbGRcbiAgICAgICAgY29uc3QgYWRkRmllbGRJY29uID0gdWkuaWNvbnMuYWRkKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbmRpdGlvbkZvckZpbHRlcjogU2ltcGxlQ29uZGl0aW9uID0gdGhpcy5jcmVhdGVEZWZhdWx0U2ltcGxlQ29uZGl0aW9uKCk7XG4gICAgICAgICAgICBjb25kaXRpb24uY29uZGl0aW9ucz8ucHVzaChjb25kaXRpb25Gb3JGaWx0ZXIpO1xuICAgICAgICAgICAgY29uZGl0aW9uLmNvbmRpdGlvbnMubGVuZ3RoIDwgMiA/IGNvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdwcm9wZXJ0eS1xdWVyeS1idWlsZGVyLW11bHRpcGUtZmlsZWxkcycpIDpcbiAgICAgICAgICAgICAgICBjb250YWluZXIuY2xhc3NMaXN0LmFkZCgncHJvcGVydHktcXVlcnktYnVpbGRlci1tdWx0aXBlLWZpbGVsZHMnKTtcbiAgICAgICAgICAgIHRoaXMucmVidWlsZFVJKCk7XG4gICAgICAgICAgICB0aGlzLnN0cnVjdHVyZUNoYW5nZWQubmV4dCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICAgIH0sICdBZGQgZmllbGQgdG8gdGhlIGNvbmRpdGlvbicpO1xuXG4gICAgICAgIC8vIEFORC9PUiBvcGVyYXRvcnMgaGFuZGxpbmdcbiAgICAgICAgY29uZGl0aW9uLmxvZ2ljYWxPcGVyYXRvciA/Pz0gT3BlcmF0b3JzLkxvZ2ljYWwuYW5kO1xuXG4gICAgICAgIGNvbnN0IGxvZ2ljYWxPcGVyYXRvckNob2ljZSA9IHVpLmlucHV0LmNob2ljZSgnJywge1xuICAgICAgICAgICAgdmFsdWU6IGNvbmRpdGlvbi5sb2dpY2FsT3BlcmF0b3IgPT09IE9wZXJhdG9ycy5Mb2dpY2FsLmFuZCA/ICdhbGwnIDogJ2FueScsXG4gICAgICAgICAgICBpdGVtczogWydhbGwnLCAnYW55J10sXG4gICAgICAgICAgICBudWxsYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBvblZhbHVlQ2hhbmdlZDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbmRpdGlvbi5sb2dpY2FsT3BlcmF0b3IgPSBsb2dpY2FsT3BlcmF0b3JDaG9pY2UudmFsdWUhID09PSAnYWxsJyA/IE9wZXJhdG9ycy5Mb2dpY2FsLmFuZCA6IE9wZXJhdG9ycy5Mb2dpY2FsLm9yO1xuICAgICAgICAgICAgICAgIHRoaXMucmVidWlsZFVJKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJ1Y3R1cmVDaGFuZ2VkLm5leHQodGhpcy5jb25kaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IGxvZ2ljYWxPcGVyYXRvckRpdiA9IHVpLmRpdkgoW3VpLmRpdlRleHQoJ01hdGNoJyksIGxvZ2ljYWxPcGVyYXRvckNob2ljZS5yb290XSwgJ3F1ZXJ5LWJ1aWxkZXItbWF0Y2gtZGl2Jyk7XG5cbiAgICAgICAgY29uc3QgYWRkRGVsZXRlSWNvbnNEaXYgPSB1aS5kaXZIKFthZGRGaWVsZEljb25dLCAnbmVzdGVkLWFkZC1kZWxldGUtaWNvbnMnKTtcbiAgICAgICAgY29uc3QgaWNvbnNEaXYgPSB1aS5kaXZIKFtsb2dpY2FsT3BlcmF0b3JEaXYsIGFkZERlbGV0ZUljb25zRGl2XSwgJ3F1ZXJ5LWJ1aWxkZXItbmVzdGVkLWNvbmRpdGlvbi1vcGVyYXRvcnMnKTtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdWkuZGl2VihbaWNvbnNEaXZdLCAncXVlcnktYnVpbGRlci1zZWFyY2gtcXVlcnktb3BlcmF0b3InKTtcblxuXG4gICAgICAgIGlmIChuZXN0aW5nTGV2ZWwgPiAwKSB7XG4gICAgICAgICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCdkYXRhLW5lc3RpbmctbGV2ZWwnLCBuZXN0aW5nTGV2ZWwudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICBjb25zdCBjb2xvciA9IHRoaXMuZ2VuZXJhdGVOZXN0aW5nQ29sb3IobmVzdGluZ0xldmVsKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1uZXN0aW5nLWNvbG9yJywgY29sb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy9kZWxldGUgaWNvbiBmb3IgbmVzdGVkIGNvbmRpdGlvbnMgdG8gcmVtb3ZlIHRoZSB3aG9sZSBuZXN0ZWQgY29uZGl0aW9uIGF0IG9uY2VcbiAgICAgICAgaWYgKHBhcmVudENvbmRpdGlvbikge1xuICAgICAgICAgICAgY29uc3QgZGVsZXRlQ29uZGl0aW9uID0gdWkuaWNvbnMuZGVsZXRlKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZW1vdmVPclJlcGxhY2VDb25kaXRpb24oY29uZGl0aW9uLCBwYXJlbnRDb25kaXRpb24uY29uZGl0aW9ucyk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWJ1aWxkVUkoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cnVjdHVyZUNoYW5nZWQubmV4dCh0aGlzLmNvbmRpdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGFkZERlbGV0ZUljb25zRGl2LmFwcGVuZChkZWxldGVDb25kaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBuZXN0ZWRDb25kaXRpb24gb2YgY29uZGl0aW9uLmNvbmRpdGlvbnMhKSB7XG4gICAgICAgICAgICBpZiAoJ2ZpZWxkJyBpbiBuZXN0ZWRDb25kaXRpb24pXG4gICAgICAgICAgICAgICAgY3JlYXRlUHJvcGVydHlGaWx0ZXJDb250YWluZXIobmVzdGVkQ29uZGl0aW9uKTtcbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5lc3RlZENvbnRhaW5lciA9IHRoaXMuYnVpbGRVSShuZXN0ZWRDb25kaXRpb24gYXMgQ29tcGxleENvbmRpdGlvbixcbiAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uLCBuZXN0aW5nTGV2ZWwgKyAxKTtcbiAgICAgICAgICAgICAgICBjb250YWluZXIuYXBwZW5kKG5lc3RlZENvbnRhaW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25kaXRpb24uY29uZGl0aW9ucy5sZW5ndGggPCAyID8gY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUoJ3Byb3BlcnR5LXF1ZXJ5LWJ1aWxkZXItbXVsdGlwZS1maWxlbGRzJykgOlxuICAgICAgICAgICAgY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ3Byb3BlcnR5LXF1ZXJ5LWJ1aWxkZXItbXVsdGlwZS1maWxlbGRzJyk7XG5cbiAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjtcbiAgICB9XG5cbiAgICBnZW5lcmF0ZU5lc3RpbmdDb2xvcihsZXZlbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgYmFzZUNvbG9yID0geyByOiAxODcsIGc6IDIyMiwgYjogMjUxIH07XG5cbiAgICAgICAgY29uc3QgZGFya2VuaW5nRmFjdG9yID0gTWF0aC5taW4oMC4xICsgKGxldmVsIC0gMSkgKiAwLjA4LCAwLjkpO1xuXG4gICAgICAgIGNvbnN0IHIgPSBNYXRoLnJvdW5kKGJhc2VDb2xvci5yICogKDEgLSBkYXJrZW5pbmdGYWN0b3IpKTtcbiAgICAgICAgY29uc3QgZyA9IE1hdGgucm91bmQoYmFzZUNvbG9yLmcgKiAoMSAtIGRhcmtlbmluZ0ZhY3RvcikpO1xuICAgICAgICBjb25zdCBiID0gTWF0aC5yb3VuZChiYXNlQ29sb3IuYiAqICgxIC0gZGFya2VuaW5nRmFjdG9yKSk7XG5cbiAgICAgICAgLy8gQ29udmVydCB0byBoZXhcbiAgICAgICAgcmV0dXJuIGAjJHtyLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCAnMCcpfSR7Zy50b1N0cmluZygxNikucGFkU3RhcnQoMiwgJzAnKX0ke2IudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJyl9YDtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gc3VnZ2VzdGlvbk1lbnVLZXlOYXZpZ2F0aW9uKGlucHV0Q29udGFpbmVyOiBIVE1MRWxlbWVudCkge1xuICBpbnB1dENvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICBpZiAoZS5rZXkgIT09ICdBcnJvd0Rvd24nICYmIGUua2V5ICE9PSAnQXJyb3dVcCcgJiYgZS5rZXkgIT09ICdFbnRlcicpXG4gICAgICByZXR1cm47XG4gICAgY29uc3QgY3VycmVudGx5U2VsZWN0ZWQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IGlucHV0Q29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5kNC1tZW51LWl0ZW0taG92ZXInKTtcbiAgICBjb25zdCBhbGxJdGVtczogSFRNTEVsZW1lbnRbXSA9IEFycmF5LmZyb20oaW5wdXRDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgnLmQ0LW1lbnUtaXRlbScpID8/IFtdKTtcbiAgICBpZiAoIWFsbEl0ZW1zIHx8IGFsbEl0ZW1zLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybjtcbiAgICBhbGxJdGVtcy5zb3J0KChhLCBiKSA9PiBhLm9mZnNldFRvcCAtIGIub2Zmc2V0VG9wKTsgLy8gc29ydCBieSB2ZXJ0aWNhbCBwb3NpdGlvblxuXG4gICAgbGV0IGN1cnJlbnRJbmRleCA9IGN1cnJlbnRseVNlbGVjdGVkID8gYWxsSXRlbXMuaW5kZXhPZihjdXJyZW50bHlTZWxlY3RlZCkgOiAtMTtcbiAgICBpZiAoZS5rZXkgPT09ICdBcnJvd0Rvd24nKVxuICAgICAgY3VycmVudEluZGV4ID0gKGN1cnJlbnRJbmRleCArIDEpICUgYWxsSXRlbXMubGVuZ3RoO1xuICAgIGVsc2UgaWYgKGUua2V5ID09PSAnQXJyb3dVcCcpXG4gICAgICBjdXJyZW50SW5kZXggPSAoY3VycmVudEluZGV4IC0gMSArIGFsbEl0ZW1zLmxlbmd0aCkgJSBhbGxJdGVtcy5sZW5ndGg7XG4gICAgZWxzZSBpZiAoZS5rZXkgPT09ICdFbnRlcicgJiYgY3VycmVudGx5U2VsZWN0ZWQpIHtcbiAgICAgIGN1cnJlbnRseVNlbGVjdGVkLmNsaWNrKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGN1cnJlbnRseVNlbGVjdGVkPy5jbGFzc0xpc3QucmVtb3ZlKCdkNC1tZW51LWl0ZW0taG92ZXInKTtcbiAgICBhbGxJdGVtc1tjdXJyZW50SW5kZXhdLmNsYXNzTGlzdC5hZGQoJ2Q0LW1lbnUtaXRlbS1ob3ZlcicpO1xuICB9KTtcbn1cblxuIl19
|