@lumeer/pivot 0.0.12 → 0.1.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.
@@ -1,1017 +0,0 @@
1
- /*
2
- * Lumeer: Modern Data Definition and Processing Platform
3
- *
4
- * Copyright (C) since 2017 Lumeer.io, s.r.o. and/or its affiliates.
5
- *
6
- * This program is free software: you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation, either version 3 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
- */
19
- import { aggregateDataValues, DataAggregationType, isValueAggregation, NumberConstraint, PercentageConstraint, UnknownConstraint, } from '@lumeer/data-filters';
20
- import { createRange, deepObjectCopy, isArray, isNotNullOrUndefined, isNullOrUndefined, isNumeric, shadeColor, toNumber, uniqueValues, } from '@lumeer/utils';
21
- import { LmrPivotPosition, LmrPivotValueType } from './lmr-pivot-config';
22
- import { COLOR_GRAY100, COLOR_GRAY200, COLOR_GRAY300, COLOR_GRAY400, COLOR_GRAY500 } from './lmr-pivot-constants';
23
- export class PivotTableConverter {
24
- static emptyClass = 'pivot-empty-cell';
25
- static dataClass = 'pivot-data-cell';
26
- static groupDataClass = 'pivot-data-group-cell';
27
- static rowHeaderClass = 'pivot-row-header-cell';
28
- static rowGroupHeaderClass = 'pivot-row-group-header-cell';
29
- static rowAttributeHeaderClass = 'pivot-row-attribute-header-cell';
30
- static columnHeaderClass = 'pivot-column-header-cell';
31
- static columnGroupHeaderClass = 'pivot-column-group-header-cell';
32
- groupColors = [COLOR_GRAY100, COLOR_GRAY200, COLOR_GRAY300, COLOR_GRAY400, COLOR_GRAY500];
33
- percentageConstraint = new PercentageConstraint({ decimals: 2 });
34
- data;
35
- transform;
36
- values;
37
- dataResources;
38
- constraintData;
39
- rowLevels;
40
- rowsTransformationArray;
41
- columnLevels;
42
- columnsTransformationArray;
43
- valueTypeInfo;
44
- nonStickyRowIndex;
45
- nonStickyColumnIndex;
46
- createTables(pivotData, transform) {
47
- if (!pivotData) {
48
- return [{ cells: [] }];
49
- }
50
- this.transform = transform;
51
- this.constraintData = pivotData.constraintData;
52
- return (pivotData.data || []).map(d => {
53
- if (this.dataAreEmpty(d)) {
54
- return { cells: [] };
55
- }
56
- this.updateData(d);
57
- return this.transformData();
58
- });
59
- }
60
- dataAreEmpty(data) {
61
- return (data.rowHeaders || []).length === 0 && (data.columnHeaders || []).length === 0;
62
- }
63
- updateData(data) {
64
- const numberOfSums = Math.max(1, (data.valueTitles || []).length);
65
- this.valueTypeInfo = getValuesTypeInfo(data.values, data.valueTypes, numberOfSums);
66
- this.data = preparePivotData(data, this.constraintData, this.valueTypeInfo);
67
- this.values = data.values || [];
68
- this.dataResources = data.dataResources || [];
69
- this.rowLevels = (data.rowsConfig || []).length;
70
- this.columnLevels = (data.columnsConfig || []).length + (data.hasAdditionalColumnLevel ? 1 : 0);
71
- const rowAllSticky = this.data.rowsConfig?.length && this.data.rowsConfig.every(config => !!config?.sticky);
72
- this.nonStickyRowIndex = Math.max(rowAllSticky ? this.rowLevels : (this.data.rowsConfig?.findIndex(config => !config?.sticky) || 0), 0);
73
- const columnAllSticky = this.data.columnsConfig?.length && this.data.columnsConfig.every(config => !!config?.sticky);
74
- this.nonStickyColumnIndex = Math.max(columnAllSticky ? this.columnLevels : (this.data.columnsConfig?.findIndex(config => !config?.sticky) || 0), 0);
75
- const hasValue = (data.valueTitles || []).length > 0;
76
- if ((this.data.rowHeaders || []).length > 0) {
77
- this.rowsTransformationArray = createTransformationMap(this.data.rowHeaders, this.rowShowSums, this.columnLevels, 1);
78
- }
79
- else {
80
- this.rowsTransformationArray = hasValue ? [this.columnLevels] : [];
81
- }
82
- if ((this.data.columnHeaders || []).length > 0) {
83
- this.columnsTransformationArray = createTransformationMap(this.data.columnHeaders, this.columnShowSums, this.rowLevels, numberOfSums);
84
- }
85
- else {
86
- this.columnsTransformationArray = hasValue ? [this.rowLevels] : [];
87
- }
88
- }
89
- get rowShowSums() {
90
- return (this.data.rowsConfig || []).map(config => config.showSums);
91
- }
92
- get columnShowSums() {
93
- return (this.data.columnsConfig || []).map(config => config.showSums);
94
- }
95
- transformData() {
96
- const cells = this.initCells();
97
- const rowGroups = this.fillCellsByRows(cells);
98
- const columnGroups = this.fillCellsByColumns(cells);
99
- this.fillCellsByGroupIntersection(cells, rowGroups, columnGroups);
100
- return { cells };
101
- }
102
- fillCellsByRows(cells) {
103
- const rowGroups = [];
104
- this.iterateAndFillCellsByRows(cells, rowGroups, this.data.rowHeaders, this.columnLevels, this.rowShowSums, 0);
105
- return rowGroups;
106
- }
107
- iterateAndFillCellsByRows(cells, rowGroupsInfo, headers, startIndex, showSums, level, parentHeader) {
108
- let currentIndex = startIndex;
109
- for (const header of headers) {
110
- const beforeExpressions = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.BeforeHeader);
111
- this.fillCellsForExpressions(cells, rowGroupsInfo, level, currentIndex, beforeExpressions);
112
- currentIndex += beforeExpressions.length;
113
- const rowSpan = getDirectHeaderChildCount(header, level, showSums);
114
- cells[currentIndex][level] = {
115
- value: this.formatRowHeader(header.title, level),
116
- cssClass: PivotTableConverter.rowHeaderClass,
117
- isHeader: true,
118
- stickyStart: this.isRowLevelSticky(level),
119
- rowSpan,
120
- colSpan: 1,
121
- background: this.getHeaderBackground(header, level),
122
- constraint: header.constraint,
123
- label: header.attributeName,
124
- childIndexes: createRange(currentIndex, currentIndex + (header.children?.length || 1)),
125
- expandable: true,
126
- };
127
- if (header.children) {
128
- this.iterateAndFillCellsByRows(cells, rowGroupsInfo, header.children, currentIndex, showSums, level + 1, header);
129
- }
130
- else if (isNotNullOrUndefined(header.targetIndex)) {
131
- this.fillCellsForRow(cells, header.targetIndex);
132
- }
133
- const afterExpressions = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.StickToEnd);
134
- currentIndex += getHeaderChildCount(header, level, showSums) - beforeExpressions.length;
135
- this.fillCellsForExpressions(cells, rowGroupsInfo, level, currentIndex - afterExpressions.length, afterExpressions);
136
- }
137
- if (showSums[level]) {
138
- const { title, summary } = this.formatSummaryHeader(parentHeader, level);
139
- const background = this.getSummaryBackground(level);
140
- const columnIndex = Math.max(level - 1, 0);
141
- this.splitRowGroupHeader(cells, columnIndex, currentIndex, background, summary, [], false, title, parentHeader?.constraint, parentHeader?.attributeName);
142
- const rowIndexes = getTargetIndexesForHeaders(headers);
143
- const transformedRowIndexes = this.transformRowIndexes(rowIndexes);
144
- rowGroupsInfo[currentIndex] = { background, indexes: transformedRowIndexes, level };
145
- this.fillCellsForGroupedRow(cells, rowIndexes, currentIndex, background);
146
- }
147
- }
148
- fillCellsForExpressions(cells, rowGroupsInfo, level, currentIndex, expressions) {
149
- for (let i = 0; i < expressions.length; i++) {
150
- const expressionIndex = currentIndex + i;
151
- const background = this.getSummaryBackground(level);
152
- const { indexes } = this.fillCellsForExpressionRow(cells, expressions[i], expressionIndex, background);
153
- this.splitRowGroupHeader(cells, level, expressionIndex, background, expressions[i].title, indexes, expressions[i].expandable);
154
- rowGroupsInfo[expressionIndex] = { background, indexes: [], expression: expressions[i], level };
155
- }
156
- }
157
- splitRowGroupHeader(cells, columnIndex, currentIndex, background, summary, rowIndexes, expandable, title, constraint, label) {
158
- let colSpan = this.rowLevels - columnIndex;
159
- const stickyStart = this.isRowLevelSticky(columnIndex);
160
- // split row group header cell because of correct sticky scroll
161
- if (stickyStart && this.nonStickyRowIndex > 0 && this.nonStickyRowIndex < this.rowLevels && colSpan > 1) {
162
- const newColspan = this.nonStickyRowIndex - columnIndex;
163
- cells[currentIndex][this.nonStickyRowIndex] = {
164
- value: undefined,
165
- constraint: undefined,
166
- label: undefined,
167
- cssClass: PivotTableConverter.rowGroupHeaderClass,
168
- isSummary: true,
169
- rowSpan: 1,
170
- colSpan: colSpan - newColspan,
171
- background,
172
- summary: undefined,
173
- expandable,
174
- };
175
- colSpan = newColspan;
176
- }
177
- cells[currentIndex][columnIndex] = {
178
- value: title,
179
- constraint,
180
- label,
181
- cssClass: PivotTableConverter.rowGroupHeaderClass,
182
- isSummary: true,
183
- stickyStart,
184
- rowSpan: 1,
185
- colSpan,
186
- background,
187
- summary,
188
- rowIndexes,
189
- expandable,
190
- };
191
- }
192
- formatSummaryHeader(header, level) {
193
- return this.transform.formatSummaryHeader?.(header, level) || {
194
- title: header?.title,
195
- summary: '',
196
- };
197
- }
198
- formatRowHeader(title, level) {
199
- return this.transform?.formatRowHeader?.(title, level) || title;
200
- }
201
- formatColumnHeader(title, level) {
202
- return this.transform?.formatColumnHeader?.(title, level) || title;
203
- }
204
- getHeaderBackground(header, level) {
205
- if (header?.color) {
206
- return shadeColor(header.color, this.getLevelOpacity(level));
207
- }
208
- return undefined;
209
- }
210
- getLevelOpacity(level) {
211
- return Math.min(80, 50 + level * 5) / 100;
212
- }
213
- isRowLevelSticky(level) {
214
- return this.data?.rowsConfig?.[level]?.sticky;
215
- }
216
- isColumnLevelSticky(level) {
217
- const maxLevel = Math.min(level, (this.data?.columnsConfig?.length ?? Number.MAX_SAFE_INTEGER) - 1);
218
- return this.data?.columnsConfig?.[maxLevel]?.sticky;
219
- }
220
- getSummaryBackground(level) {
221
- const index = Math.min(level, this.groupColors.length - 1);
222
- return this.groupColors[index];
223
- }
224
- fillCellsForRow(cells, row) {
225
- const rowIndexInCells = this.rowsTransformationArray[row];
226
- if (isNotNullOrUndefined(rowIndexInCells)) {
227
- for (let column = 0; column < this.columnsTransformationArray.length; column++) {
228
- const columnIndexInCells = this.columnsTransformationArray[column];
229
- if (isNotNullOrUndefined(columnIndexInCells)) {
230
- const value = this.data.values[row][column];
231
- const dataResources = this.dataResources?.[row]?.[column] || [];
232
- const formattedValue = this.aggregateOrFormatSingleValue(value, column);
233
- const stringValue = isNotNullOrUndefined(formattedValue) ? String(formattedValue) : '';
234
- cells[rowIndexInCells][columnIndexInCells] = {
235
- value: stringValue,
236
- dataResources,
237
- rowSpan: 1,
238
- colSpan: 1,
239
- cssClass: PivotTableConverter.dataClass,
240
- isValue: true,
241
- };
242
- }
243
- }
244
- }
245
- }
246
- getValueIndexForColumns(columns) {
247
- return columns[0] % this.data.valueTitles.length;
248
- }
249
- formatValueByValueType(value, valueIndex) {
250
- const valueType = (this.data.valueTypes || [])[valueIndex];
251
- if (!valueType || valueType === LmrPivotValueType.Default) {
252
- return this.formatValueByConstraint(value, valueIndex);
253
- }
254
- if ([LmrPivotValueType.AllPercentage, LmrPivotValueType.ColumnPercentage, LmrPivotValueType.RowPercentage].includes(valueType)) {
255
- return this.formatValueByPercentage(value);
256
- }
257
- return this.formatValueByConstraint(value, valueIndex);
258
- }
259
- formatGroupedValueByValueType(value, rows, columns) {
260
- const valueIndex = columns[0] % this.data.valueTitles.length;
261
- const valueType = this.data.valueTypes && this.data.valueTypes[valueIndex];
262
- const valueTypeInfo = this.valueTypeInfo[valueIndex];
263
- if (!valueTypeInfo || !valueType || valueType === LmrPivotValueType.Default) {
264
- return this.formatValueByConstraint(value, valueIndex);
265
- }
266
- if (valueType === LmrPivotValueType.AllPercentage) {
267
- return this.formatValueByPercentage(divideValues(value, valueTypeInfo.sum));
268
- }
269
- else if (valueType === LmrPivotValueType.ColumnPercentage) {
270
- const columnsDividers = columns.reduce((dividers, column) => {
271
- dividers.push(valueTypeInfo.sumsColumns[column]);
272
- return dividers;
273
- }, []);
274
- const columnsDivider = aggregateDataValues(DataAggregationType.Sum, columnsDividers);
275
- return this.formatValueByPercentage(divideValues(value, columnsDivider));
276
- }
277
- else if (valueType === LmrPivotValueType.RowPercentage) {
278
- const rowsDividers = rows.reduce((dividers, row) => {
279
- dividers.push(valueTypeInfo.sumsRows[row]);
280
- return dividers;
281
- }, []);
282
- const rowsDivider = aggregateDataValues(DataAggregationType.Sum, rowsDividers);
283
- return this.formatValueByPercentage(divideValues(value, rowsDivider));
284
- }
285
- return this.formatValueByConstraint(value, valueIndex);
286
- }
287
- formatValueByPercentage(value) {
288
- return this.percentageConstraint.createDataValue(value).format();
289
- }
290
- formatValueByConstraint(value, valueIndex) {
291
- const constraint = this.data.valuesConstraints?.[valueIndex] || this.valueTypeInfo[valueIndex]?.defaultConstraint;
292
- if (constraint) {
293
- return constraint.createDataValue(value, this.constraintData).preview();
294
- }
295
- return value;
296
- }
297
- fillCellsForGroupedRow(cells, rows, rowIndexInCells, background) {
298
- for (let column = 0; column < this.columnsTransformationArray.length; column++) {
299
- const columnIndexInCells = this.columnsTransformationArray[column];
300
- if (isNotNullOrUndefined(columnIndexInCells)) {
301
- const { values, dataResources } = this.getGroupedValuesForRowsAndCols(rows, [column]);
302
- const formattedValue = this.aggregateAndFormatDataValues(values, rows, [column]);
303
- cells[rowIndexInCells][columnIndexInCells] = {
304
- value: String(formattedValue),
305
- dataResources,
306
- colSpan: 1,
307
- rowSpan: 1,
308
- cssClass: PivotTableConverter.groupDataClass,
309
- background,
310
- isValue: true,
311
- };
312
- }
313
- }
314
- }
315
- fillCellsForExpressionRow(cells, expression, rowIndexInCells, background) {
316
- let rowIndexes = [];
317
- for (let column = 0; column < this.columnsTransformationArray.length; column++) {
318
- const columnIndexInCells = this.columnsTransformationArray[column];
319
- if (isNotNullOrUndefined(columnIndexInCells)) {
320
- const { value, dataResources, indexes } = this.evaluateExpression(expression, [column]);
321
- rowIndexes = indexes;
322
- const valueIndex = column % this.data.valueTitles.length;
323
- const formattedValue = this.formatValueByConstraint(value, valueIndex);
324
- cells[rowIndexInCells][columnIndexInCells] = {
325
- value: String(formattedValue),
326
- dataResources,
327
- colSpan: 1,
328
- rowSpan: 1,
329
- cssClass: PivotTableConverter.groupDataClass,
330
- background,
331
- isValue: true,
332
- };
333
- }
334
- }
335
- return { indexes: uniqueValues([rowIndexInCells, ...rowIndexes]) };
336
- }
337
- evaluateExpression(expression, columns) {
338
- return (expression.operands || []).reduce((result, operand, index) => {
339
- const { value, dataResources, indexes } = this.evaluateOperand(operand, columns);
340
- result.dataResources.push(...dataResources);
341
- result.indexes.push(...indexes);
342
- switch (expression.operation) {
343
- case 'add':
344
- result.value += value;
345
- break;
346
- case 'subtract':
347
- result.value = (index === 0 ? value : result.value - value);
348
- break;
349
- case 'multiply':
350
- result.value = index === 0 ? value : result.value * value;
351
- break;
352
- case 'divide':
353
- result.value = index === 0 ? value : value ? result.value / value : result.value;
354
- break;
355
- }
356
- return result;
357
- }, { value: 0, dataResources: [], indexes: [] });
358
- }
359
- evaluateOperand(operand, columns) {
360
- switch (operand.type) {
361
- case 'expression': return this.evaluateExpression(operand, columns);
362
- case 'value': return { value: operand.value, dataResources: [], indexes: [] };
363
- case 'header': {
364
- const rows = getTargetIndexesForHeaders(operand.headers);
365
- const { values, dataResources } = this.getGroupedValuesForRowsAndCols(rows, columns);
366
- const { value } = this.aggregateDataValues(values, columns);
367
- return { value, dataResources, indexes: this.transformRowIndexes(rows) };
368
- }
369
- }
370
- }
371
- transformRowIndexes(rows) {
372
- return rows
373
- .map(v => this.rowsTransformationArray[v])
374
- .filter(v => isNotNullOrUndefined(v));
375
- }
376
- getGroupedValuesForRowsAndCols(rows, columns) {
377
- const values = [];
378
- const dataResources = [];
379
- for (const row of rows) {
380
- for (const column of columns) {
381
- const rowColumnValue = this.values[row][column];
382
- if (isArray(rowColumnValue)) {
383
- values.push(...rowColumnValue);
384
- }
385
- else {
386
- values.push(rowColumnValue);
387
- }
388
- dataResources.push(...(this.dataResources?.[row]?.[column] || []));
389
- }
390
- }
391
- return { values, dataResources };
392
- }
393
- fillCellsByColumns(cells) {
394
- const columnGroups = [];
395
- this.iterateAndFillCellsByColumns(cells, columnGroups, this.data.columnHeaders, this.rowLevels, this.columnShowSums, 0);
396
- return columnGroups;
397
- }
398
- iterateAndFillCellsByColumns(cells, columnGroupsInfo, headers, startIndex, showSums, level, parentHeader) {
399
- let currentIndex = startIndex;
400
- const numberOfSums = Math.max(1, this.data.valueTitles.length);
401
- for (const header of headers) {
402
- const colSpan = getDirectHeaderChildCount(header, level, showSums, numberOfSums);
403
- cells[level][currentIndex] = {
404
- value: this.formatColumnHeader(header.title, level),
405
- cssClass: PivotTableConverter.columnHeaderClass,
406
- isHeader: true,
407
- rowSpan: 1,
408
- colSpan,
409
- stickyTop: this.isColumnLevelSticky(level),
410
- background: this.getHeaderBackground(header, level),
411
- constraint: header.constraint,
412
- label: header.attributeName,
413
- };
414
- if (header.children) {
415
- this.iterateAndFillCellsByColumns(cells, columnGroupsInfo, header.children, currentIndex, showSums, level + 1, header);
416
- }
417
- else if (isNotNullOrUndefined(header.targetIndex)) {
418
- this.fillCellsForColumn(cells, header.targetIndex);
419
- }
420
- currentIndex += getHeaderChildCount(header, level, showSums, numberOfSums);
421
- }
422
- if (showSums[level]) {
423
- const background = this.getSummaryBackground(level);
424
- const { title, summary } = this.formatSummaryHeader(parentHeader, level);
425
- const numberOfValues = this.data.valueTitles.length;
426
- const rowIndex = Math.max(level - 1, 0);
427
- const shouldAddValueHeaders = numberOfValues > 1;
428
- cells[rowIndex][currentIndex] = {
429
- value: title,
430
- constraint: parentHeader?.constraint,
431
- label: parentHeader?.attributeName,
432
- cssClass: PivotTableConverter.columnGroupHeaderClass,
433
- isSummary: true,
434
- stickyTop: this.isColumnLevelSticky(level),
435
- rowSpan: this.columnLevels - rowIndex - (shouldAddValueHeaders ? 1 : 0),
436
- colSpan: numberOfSums,
437
- background,
438
- summary,
439
- };
440
- if (numberOfValues > 0) {
441
- for (let i = 0; i < numberOfValues; i++) {
442
- const columnIndexInCells = currentIndex + i;
443
- if (shouldAddValueHeaders) {
444
- const valueTitle = this.data.valueTitles[i];
445
- cells[this.columnLevels - 1][columnIndexInCells] = {
446
- value: valueTitle,
447
- cssClass: PivotTableConverter.columnGroupHeaderClass,
448
- isSummary: true,
449
- stickyTop: this.isColumnLevelSticky(level),
450
- rowSpan: 1,
451
- colSpan: 1,
452
- background,
453
- };
454
- }
455
- const columnsIndexes = getTargetIndexesForHeaders(headers);
456
- const valueColumnsIndexes = columnsIndexes.filter(index => index % numberOfValues === i);
457
- const transformedColumnIndexes = valueColumnsIndexes
458
- .map(v => this.columnsTransformationArray[v])
459
- .filter(v => isNotNullOrUndefined(v));
460
- columnGroupsInfo[columnIndexInCells] = { background, indexes: transformedColumnIndexes, level };
461
- this.fillCellsForGroupedColumn(cells, valueColumnsIndexes, columnIndexInCells, background);
462
- }
463
- }
464
- else {
465
- columnGroupsInfo[currentIndex] = { background, indexes: [], level };
466
- }
467
- }
468
- }
469
- fillCellsForGroupedColumn(cells, columns, columnIndexInCells, background) {
470
- for (let row = 0; row < this.rowsTransformationArray.length; row++) {
471
- const rowIndexInCells = this.rowsTransformationArray[row];
472
- if (isNotNullOrUndefined(rowIndexInCells)) {
473
- const { values, dataResources } = this.getGroupedValuesForRowsAndCols([row], columns);
474
- const formattedValue = this.aggregateAndFormatDataValues(values, [row], columns);
475
- cells[rowIndexInCells][columnIndexInCells] = {
476
- value: String(formattedValue),
477
- dataResources,
478
- colSpan: 1,
479
- rowSpan: 1,
480
- cssClass: PivotTableConverter.groupDataClass,
481
- background,
482
- isValue: true,
483
- };
484
- }
485
- }
486
- }
487
- aggregateAndFormatDataValues(values, rows, columns) {
488
- const { value, aggregation } = this.aggregateDataValues(values, columns);
489
- return aggregation === DataAggregationType.Join ? value : this.formatGroupedValueByValueType(value, rows, columns);
490
- }
491
- aggregateDataValues(values, columns) {
492
- const aggregation = this.aggregationByColumns(columns);
493
- if (aggregation === DataAggregationType.Join) {
494
- const valueIndex = this.getValueIndexForColumns(columns);
495
- const constraint = this.data.valuesConstraints?.[valueIndex] || this.valueTypeInfo[valueIndex]?.defaultConstraint;
496
- return { value: aggregateDataValues(aggregation, values, constraint, false, this.constraintData), aggregation };
497
- }
498
- return { value: aggregateDataValues(aggregation, values), aggregation };
499
- }
500
- aggregationByColumns(columns) {
501
- const valueIndex = columns[0] % this.data.valueTitles.length;
502
- const aggregation = this.data.valueAggregations?.[valueIndex];
503
- return isValueAggregation(aggregation) ? aggregation : DataAggregationType.Sum;
504
- }
505
- fillCellsForColumn(cells, column) {
506
- const columnIndexInCells = this.columnsTransformationArray[column];
507
- if (isNotNullOrUndefined(columnIndexInCells)) {
508
- for (let row = 0; row < this.rowsTransformationArray.length; row++) {
509
- const rowIndexInCells = this.rowsTransformationArray[row];
510
- if (isNotNullOrUndefined(rowIndexInCells)) {
511
- const value = this.data.values[row][column];
512
- const dataResources = this.dataResources?.[row]?.[column] || [];
513
- const formattedValue = this.aggregateOrFormatSingleValue(value, column);
514
- const stringValue = isNotNullOrUndefined(formattedValue) ? String(formattedValue) : '';
515
- cells[rowIndexInCells][columnIndexInCells] = {
516
- value: stringValue,
517
- dataResources,
518
- rowSpan: 1,
519
- colSpan: 1,
520
- cssClass: PivotTableConverter.dataClass,
521
- isValue: true,
522
- };
523
- }
524
- }
525
- }
526
- }
527
- aggregateOrFormatSingleValue(value, column) {
528
- const aggregation = this.aggregationByColumns([column]);
529
- const valueIndex = this.getValueIndexForColumns([column]);
530
- if (aggregation === DataAggregationType.Join) {
531
- const constraint = this.data.valuesConstraints?.[valueIndex] || this.valueTypeInfo[valueIndex]?.defaultConstraint;
532
- return aggregateDataValues(aggregation, [value], constraint, false, this.constraintData);
533
- }
534
- return this.formatValueByValueType(value, valueIndex);
535
- }
536
- fillCellsByGroupIntersection(cells, rowGroupsInfo, columnGroupsInfo) {
537
- const rowsCount = cells.length;
538
- const columnsCount = cells[0]?.length || 0;
539
- for (let i = 0; i < rowGroupsInfo.length; i++) {
540
- const rowGroupInfo = rowGroupsInfo[i];
541
- if (!rowGroupInfo) {
542
- continue;
543
- }
544
- for (let j = 0; j < columnGroupsInfo.length; j++) {
545
- if (!columnGroupsInfo[j]) {
546
- continue;
547
- }
548
- const columns = columnGroupsInfo[j].indexes;
549
- const { rowsIndexes, columnsIndexes } = this.getValuesIndexesFromCellsIndexes(rowGroupInfo.indexes, columns);
550
- let formattedValue;
551
- let dataResources;
552
- if (rowGroupInfo.expression) {
553
- const result = this.evaluateExpression(rowGroupInfo.expression, columnsIndexes);
554
- const valueIndex = columnsIndexes[0] % this.data.valueTitles.length;
555
- formattedValue = this.formatValueByConstraint(result.value, valueIndex);
556
- dataResources = result.dataResources;
557
- }
558
- else {
559
- // it's enough to fill group values only from row side
560
- const result = this.getGroupedValuesForRowsAndCols(rowsIndexes, columnsIndexes);
561
- formattedValue = this.aggregateAndFormatDataValues(result.values, rowsIndexes, columnsIndexes);
562
- dataResources = result.dataResources;
563
- }
564
- cells[i][j] = {
565
- value: String(formattedValue),
566
- dataResources,
567
- colSpan: 1,
568
- rowSpan: 1,
569
- cssClass: PivotTableConverter.groupDataClass,
570
- isValue: true,
571
- };
572
- }
573
- this.fillRowWithColor(cells, i, rowGroupInfo, columnsCount);
574
- }
575
- for (let j = 0; j < columnGroupsInfo.length; j++) {
576
- if (columnGroupsInfo[j]) {
577
- this.fillColumnWithColor(cells, j, columnGroupsInfo[j], rowGroupsInfo, rowsCount);
578
- }
579
- }
580
- }
581
- getValuesIndexesFromCellsIndexes(rows, columns) {
582
- const rowsIndexes = rows
583
- .map(row => this.rowsTransformationArray.findIndex(tRow => tRow === row))
584
- .filter(index => index >= 0);
585
- const columnsIndexes = columns
586
- .map(column => this.columnsTransformationArray.findIndex(tColumn => tColumn === column))
587
- .filter(index => index >= 0);
588
- return { rowsIndexes, columnsIndexes };
589
- }
590
- fillRowWithColor(cells, row, rowGroupInfo, columnsCount) {
591
- for (let i = this.rowLevels; i < columnsCount; i++) {
592
- cells[row][i] && (cells[row][i].background = rowGroupInfo.background);
593
- }
594
- }
595
- fillColumnWithColor(cells, column, columnGroupInfo, rowGroupsInfo, rowCount) {
596
- for (let i = this.columnLevels; i < rowCount; i++) {
597
- const rowGroupInfo = rowGroupsInfo[i];
598
- if (!rowGroupInfo || rowGroupInfo.level > columnGroupInfo.level) {
599
- cells[i][column] && (cells[i][column].background = columnGroupInfo.background);
600
- }
601
- }
602
- }
603
- initCells() {
604
- const rows = this.getRowsCount() + this.columnLevels;
605
- const columns = this.getColumnsCount() + this.rowLevels;
606
- const matrix = [];
607
- for (let i = 0; i < rows; i++) {
608
- matrix[i] = [];
609
- for (let j = 0; j < columns; j++) {
610
- if (i >= this.columnLevels && j >= this.rowLevels) {
611
- const isDataClass = this.rowsTransformationArray.includes(i) && this.columnsTransformationArray.includes(j);
612
- matrix[i][j] = {
613
- value: '',
614
- dataResources: [],
615
- cssClass: isDataClass ? PivotTableConverter.dataClass : PivotTableConverter.groupDataClass,
616
- rowSpan: 1,
617
- colSpan: 1,
618
- isValue: true,
619
- };
620
- }
621
- else {
622
- matrix[i][j] = undefined;
623
- }
624
- }
625
- }
626
- if (this.rowLevels > 0 && this.columnLevels > 0) {
627
- for (let j = 0; j < this.rowLevels; j++) {
628
- const rowHeaderAttribute = this.data.rowHeaderAttributes[j];
629
- if (rowHeaderAttribute) {
630
- const titleRowSpan = this.nonStickyColumnIndex || this.columnLevels;
631
- matrix[0][j] = {
632
- value: rowHeaderAttribute.title,
633
- cssClass: PivotTableConverter.rowAttributeHeaderClass,
634
- isAttributeHeader: true,
635
- rowSpan: titleRowSpan,
636
- colSpan: 1,
637
- stickyTop: this.isColumnLevelSticky(0),
638
- stickyStart: this.isRowLevelSticky(j),
639
- background: rowHeaderAttribute.color,
640
- };
641
- if (this.columnLevels - titleRowSpan > 0) {
642
- matrix[this.nonStickyColumnIndex][j] = {
643
- value: '',
644
- cssClass: PivotTableConverter.rowAttributeHeaderClass,
645
- isAttributeHeader: true,
646
- rowSpan: this.columnLevels - titleRowSpan,
647
- colSpan: 1,
648
- background: rowHeaderAttribute.color,
649
- stickyStart: this.isRowLevelSticky(j),
650
- };
651
- }
652
- }
653
- else {
654
- for (let i = 0; i < this.columnLevels; i++) {
655
- matrix[i][j] = {
656
- value: '',
657
- cssClass: PivotTableConverter.emptyClass,
658
- rowSpan: 1,
659
- colSpan: 1,
660
- stickyStart: this.isRowLevelSticky(j),
661
- stickyTop: this.isColumnLevelSticky(i),
662
- isHeader: false,
663
- };
664
- }
665
- }
666
- }
667
- }
668
- return matrix;
669
- }
670
- getRowsCount() {
671
- if (this.data.rowHeaders.length === 0 && (this.data.valueTitles || []).length > 0) {
672
- return 1;
673
- }
674
- return getHeadersChildCount(this.data.rowHeaders, this.rowShowSums);
675
- }
676
- getColumnsCount() {
677
- if (this.data.columnHeaders.length === 0 && (this.data.valueTitles || []).length > 0) {
678
- return 1;
679
- }
680
- const numberOfSums = Math.max(1, (this.data.valueTitles || []).length);
681
- return getHeadersChildCount(this.data.columnHeaders, this.columnShowSums, numberOfSums);
682
- }
683
- }
684
- function preparePivotData(data, constraintData, valueTypeInfo) {
685
- const numberOfSums = Math.max(1, (data.valueTitles || []).length);
686
- const values = computeValuesByValueType(data.values, data.valueTypes, numberOfSums, valueTypeInfo);
687
- const sorted = sortPivotData({ ...data, values }, constraintData);
688
- return fillExpressionsToData(sorted);
689
- }
690
- function fillExpressionsToData(data) {
691
- return {
692
- ...data,
693
- rowHeaders: fillExpressionsToHeaders(data.rowHeaders, data.rowsConfig, 0),
694
- columnHeaders: fillExpressionsToHeaders(data.columnHeaders, data.columnsConfig, 0),
695
- };
696
- }
697
- function fillExpressionsToHeaders(headers, configs, index) {
698
- const expressions = configs?.[index]?.expressions || [];
699
- const headersCopy = [...(headers || [])];
700
- for (const expression of expressions) {
701
- const dataHeaderExpression = extendPivotExpression(expression, headers);
702
- if (dataHeaderExpression.firstHeaderIndex >= 0) {
703
- const firstHeaderIndex = dataHeaderExpression.firstHeaderIndex;
704
- const newHeader = { ...headersCopy[firstHeaderIndex], expressions: [...(headersCopy[firstHeaderIndex].expressions || []), dataHeaderExpression] };
705
- headersCopy.splice(firstHeaderIndex, 1, newHeader);
706
- }
707
- }
708
- if (configs?.[index + 1]) {
709
- for (let i = 0; i < headersCopy.length; i++) {
710
- headersCopy.splice(i, 1, { ...headersCopy[i], children: fillExpressionsToHeaders(headersCopy[i].children, configs, index + 1) });
711
- }
712
- }
713
- return headersCopy;
714
- }
715
- function extendPivotExpression(expression, headers) {
716
- const dataHeaderOperands = [];
717
- let firstHeaderIndex = Number.MAX_SAFE_INTEGER;
718
- function traverse(operands) {
719
- for (const operand of operands) {
720
- if (operand.type === 'header') {
721
- const indexes = getOperandIndexesInHeaders(operand, headers);
722
- firstHeaderIndex = Math.min(firstHeaderIndex, ...indexes);
723
- const operandHeaders = indexes.map(index => headers[index]);
724
- dataHeaderOperands.push({ ...operand, headers: operandHeaders });
725
- }
726
- else if (operand.type === 'expression') {
727
- traverse(operand.operands);
728
- }
729
- else {
730
- dataHeaderOperands.push(operand);
731
- }
732
- }
733
- }
734
- traverse(expression.operands);
735
- if (expression.position === LmrPivotPosition.StickToEnd) {
736
- firstHeaderIndex = headers.length - 1;
737
- }
738
- if (firstHeaderIndex === Number.MAX_SAFE_INTEGER) {
739
- firstHeaderIndex = -1;
740
- }
741
- return { ...expression, firstHeaderIndex, operands: dataHeaderOperands };
742
- }
743
- function getOperandIndexesInHeaders(operand, headers) {
744
- return (headers || []).reduce((indexes, header, index) => {
745
- if (operandContainsHeader(operand, header)) {
746
- indexes.push(index);
747
- }
748
- return indexes;
749
- }, []);
750
- }
751
- function operandContainsHeader(operand, header) {
752
- return header.title.match(new RegExp(operand.value))?.length > 0;
753
- }
754
- function computeValuesByValueType(values, valueTypes, numValues, valueTypeInfo) {
755
- const rowsIndexes = [...Array(values.length).keys()];
756
- const modifiedValues = deepObjectCopy(values);
757
- for (let i = 0; i < numValues; i++) {
758
- const valueType = valueTypes && valueTypes[i];
759
- if (!valueType || valueType === LmrPivotValueType.Default) {
760
- continue;
761
- }
762
- const columnsCount = (values[0] && values[0].length) || 0;
763
- const columnIndexes = [...Array(columnsCount).keys()].filter(key => key % numValues === i);
764
- const info = valueTypeInfo[i];
765
- for (const row of rowsIndexes) {
766
- for (const column of columnIndexes) {
767
- if (valueType === LmrPivotValueType.AllPercentage) {
768
- modifiedValues[row][column] = divideValues(values[row][column], info.sum);
769
- }
770
- else if (valueType === LmrPivotValueType.RowPercentage) {
771
- modifiedValues[row][column] = divideValues(values[row][column], info.sumsRows[row]);
772
- }
773
- else if (valueType === LmrPivotValueType.ColumnPercentage) {
774
- modifiedValues[row][column] = divideValues(values[row][column], info.sumsColumns[column]);
775
- }
776
- }
777
- }
778
- }
779
- return modifiedValues;
780
- }
781
- function getValuesTypeInfo(values, valueTypes, numValues) {
782
- const valueTypeInfo = [];
783
- const rowsIndexes = [...Array(values.length).keys()];
784
- for (let i = 0; i < numValues; i++) {
785
- const valueType = valueTypes && valueTypes[i];
786
- const columnsCount = (values[0] && values[0].length) || 0;
787
- const columnIndexes = [...Array(columnsCount).keys()].filter(key => key % numValues === i);
788
- valueTypeInfo[i] = getValueTypeInfo(values, valueType, rowsIndexes, columnIndexes);
789
- }
790
- return valueTypeInfo;
791
- }
792
- function getValueTypeInfo(values, type, rows, columns) {
793
- const containsDecimal = containsDecimalValue(values, rows, columns);
794
- const valueTypeInfo = {
795
- defaultConstraint: containsDecimal ? new NumberConstraint({ decimals: 2 }) : null,
796
- };
797
- if (type === LmrPivotValueType.AllPercentage) {
798
- return { ...valueTypeInfo, sum: getNumericValuesSummary(values, rows, columns) };
799
- }
800
- else if (type === LmrPivotValueType.RowPercentage) {
801
- return {
802
- ...valueTypeInfo,
803
- sumsRows: rows.reduce((arr, row) => {
804
- arr[row] = getNumericValuesSummary(values, [row], columns);
805
- return arr;
806
- }, []),
807
- };
808
- }
809
- else if (type === LmrPivotValueType.ColumnPercentage) {
810
- return {
811
- ...valueTypeInfo,
812
- sumsColumns: columns.reduce((arr, column) => {
813
- arr[column] = getNumericValuesSummary(values, rows, [column]);
814
- return arr;
815
- }, []),
816
- };
817
- }
818
- return { ...valueTypeInfo };
819
- }
820
- function containsDecimalValue(values, rows, columns) {
821
- for (const row of rows) {
822
- for (const column of columns) {
823
- if (isValueDecimal(values[row][column])) {
824
- return true;
825
- }
826
- }
827
- }
828
- return false;
829
- }
830
- function isValueDecimal(value) {
831
- if (isNullOrUndefined(value)) {
832
- return false;
833
- }
834
- if (isNumeric(value)) {
835
- return toNumber(value) % 1 !== 0;
836
- }
837
- return false;
838
- }
839
- function createTransformationMap(headers, showSums, additionalNum, numberOfSums) {
840
- const array = [];
841
- iterateThroughTransformationMap(headers, additionalNum, array, 0, showSums, numberOfSums);
842
- return array;
843
- }
844
- function iterateThroughTransformationMap(headers, additionalNum, array, level, showSums, numberOfSums) {
845
- let additional = additionalNum;
846
- for (let i = 0; i < headers.length; i++) {
847
- const header = headers[i];
848
- const beforeExpressionsLength = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.BeforeHeader).length;
849
- const afterExpressionsLength = (header.expressions || []).filter(exp => exp.position === LmrPivotPosition.StickToEnd).length;
850
- if (header.children) {
851
- additional += beforeExpressionsLength;
852
- iterateThroughTransformationMap(header.children, additional, array, level + 1, showSums, numberOfSums);
853
- additional += (getHeaderChildCount(header, level, showSums, numberOfSums) - beforeExpressionsLength);
854
- }
855
- else if (isNotNullOrUndefined(header.targetIndex)) {
856
- array[header.targetIndex] = i + additional + beforeExpressionsLength;
857
- additional += beforeExpressionsLength + afterExpressionsLength;
858
- }
859
- }
860
- }
861
- function getTargetIndexesForHeaders(headers) {
862
- const allRows = (headers || []).reduce((rows, header) => {
863
- rows.push(...getTargetIndexesForHeader(header));
864
- return rows;
865
- }, []);
866
- return uniqueValues(allRows);
867
- }
868
- function getTargetIndexesForHeader(pivotDataHeader) {
869
- if (pivotDataHeader.children) {
870
- return pivotDataHeader.children.reduce((rows, header) => {
871
- rows.push(...getTargetIndexesForHeader(header));
872
- return rows;
873
- }, []);
874
- }
875
- return [pivotDataHeader.targetIndex];
876
- }
877
- function getHeadersChildCount(headers, showSums, numberOfSums = 1) {
878
- return (headers || []).reduce((sum, header) => sum + getHeaderChildCount(header, 0, showSums, numberOfSums), showSums[0] ? numberOfSums : 0);
879
- }
880
- function getHeaderChildCount(pivotDataHeader, level, showSums, numberOfSums = 1) {
881
- const numExpressions = (pivotDataHeader.expressions || []).length;
882
- if (pivotDataHeader.children) {
883
- return pivotDataHeader.children.reduce((sum, header) => sum + getHeaderChildCount(header, level + 1, showSums, numberOfSums), (showSums[level + 1] ? numberOfSums : 0) + numExpressions);
884
- }
885
- return 1 + numExpressions;
886
- }
887
- function getDirectHeaderChildCount(pivotDataHeader, level, showSums, numberOfSums = 1) {
888
- if (pivotDataHeader.children) {
889
- return pivotDataHeader.children.reduce((sum, header) => sum + getHeaderChildCount(header, level + 1, showSums, numberOfSums), 0);
890
- }
891
- return 1;
892
- }
893
- export function sortPivotData(data, constraintData) {
894
- const rowSorts = (data.rowsConfig || []).map(config => config.sort);
895
- const columnSorts = (data.columnsConfig || []).map(config => config.sort);
896
- return {
897
- ...data,
898
- rowHeaders: sortPivotRowDataHeaders(data.rowHeaders, rowSorts, data, constraintData),
899
- columnHeaders: sortPivotColumnDataHeaders(data.columnHeaders, columnSorts, data, constraintData),
900
- };
901
- }
902
- function sortPivotRowDataHeaders(rowHeaders, rowSorts, pivotData, constraintData) {
903
- return sortPivotDataHeadersRecursive(rowHeaders, 0, rowSorts, pivotData.columnHeaders, pivotData.values, pivotData.valueTitles || [], true, constraintData);
904
- }
905
- function sortPivotColumnDataHeaders(columnHeaders, columnSorts, pivotData, constraintData) {
906
- return sortPivotDataHeadersRecursive(columnHeaders, 0, columnSorts, pivotData.rowHeaders, pivotData.values, pivotData.valueTitles || [], false, constraintData);
907
- }
908
- function sortPivotDataHeadersRecursive(headers, index, sorts, otherSideHeaders, values, valueTitles, isRows, constraintData) {
909
- // we don't want to sort values headers
910
- if (!isRows && isValuesHeaders(headers, valueTitles)) {
911
- return headers;
912
- }
913
- const sort = sorts && sorts[index];
914
- const constraint = getConstraintForSort(sort, headers);
915
- const valuesMap = createHeadersValuesMap(headers, sort, otherSideHeaders, values, valueTitles, isRows);
916
- return headers
917
- .map(header => ({
918
- ...header,
919
- children: header.children &&
920
- sortPivotDataHeadersRecursive(header.children, index + 1, sorts, otherSideHeaders, values, valueTitles, isRows, constraintData),
921
- }))
922
- .sort((r1, r2) => {
923
- const r1Value = constraint.createDataValue(valuesMap[r1.title], constraintData);
924
- const r2Value = constraint.createDataValue(valuesMap[r2.title], constraintData);
925
- const multiplier = !sort || sort.asc ? 1 : -1;
926
- return r1Value.compareTo(r2Value) * multiplier;
927
- });
928
- }
929
- function getConstraintForSort(sort, headers) {
930
- if ((sort?.list?.values || []).length > 0) {
931
- // sort is done by values in columns
932
- return new NumberConstraint({});
933
- }
934
- return ((headers || [])[0] && (headers || [])[0].constraint) || new UnknownConstraint();
935
- }
936
- function isValuesHeaders(headers, valueTitles) {
937
- return (valueTitles.length > 1 &&
938
- (headers || []).every((header, index) => isNotNullOrUndefined(header.targetIndex) && header.title === valueTitles[index]));
939
- }
940
- function createHeadersValuesMap(headers, sort, otherSideHeaders, values, valueTitles, isRows) {
941
- const sortTargetIndexes = sortValueTargetIndexes(sort, otherSideHeaders, valueTitles);
942
- if (!sortTargetIndexes) {
943
- return (headers || []).reduce((valuesMap, header) => {
944
- valuesMap[header.title] = header.title;
945
- return valuesMap;
946
- }, {});
947
- }
948
- return (headers || []).reduce((valuesMap, header) => {
949
- const rows = isRows ? getTargetIndexesForHeader(header) : sortTargetIndexes;
950
- const columns = isRows ? sortTargetIndexes : getTargetIndexesForHeader(header);
951
- valuesMap[header.title] = getNumericValuesSummary(values, rows, columns);
952
- return valuesMap;
953
- }, {});
954
- }
955
- function getNumericValuesSummary(values, rows, columns) {
956
- let sum = 0;
957
- for (const row of rows) {
958
- for (const column of columns) {
959
- const value = values[row][column];
960
- if (isNotNullOrUndefined(value) && isNumeric(value)) {
961
- sum += toNumber(value);
962
- }
963
- }
964
- }
965
- return sum;
966
- }
967
- function sortValueTargetIndexes(sort, otherSideHeaders, valueTitles) {
968
- if (sort && sort.list) {
969
- let valueIndex = valueTitles.findIndex(title => title === sort.list.valueTitle);
970
- if (valueIndex === -1) {
971
- if (valueTitles.length === 1) {
972
- valueIndex = 0;
973
- }
974
- else {
975
- return null;
976
- }
977
- }
978
- let pivotHeader = null;
979
- let currentOtherSideHeaders = otherSideHeaders;
980
- for (const value of sort.list.values || []) {
981
- if (value.isSummary) {
982
- const indexes = getTargetIndexesForHeaders(currentOtherSideHeaders || []) || [];
983
- return filterIndexesByMod(indexes, valueTitles.length, valueIndex);
984
- }
985
- pivotHeader = (currentOtherSideHeaders || []).find(header => header.title === value.title);
986
- if (!pivotHeader) {
987
- break;
988
- }
989
- currentOtherSideHeaders = pivotHeader.children || [];
990
- }
991
- if (pivotHeader) {
992
- const targetIndexes = isNotNullOrUndefined(pivotHeader.targetIndex)
993
- ? [pivotHeader.targetIndex]
994
- : getTargetIndexesForHeaders(currentOtherSideHeaders);
995
- return filterIndexesByMod(targetIndexes, valueTitles.length, valueIndex);
996
- }
997
- }
998
- return null;
999
- }
1000
- function filterIndexesByMod(indexes, mod, value) {
1001
- return (indexes || []).filter(index => index % mod === value);
1002
- }
1003
- function divideValues(value, divider) {
1004
- if (isNullOrUndefined(value)) {
1005
- return null;
1006
- }
1007
- if (isNumeric(value) && isNumeric(divider)) {
1008
- if (divider !== 0) {
1009
- return value / divider;
1010
- }
1011
- else {
1012
- return 0;
1013
- }
1014
- }
1015
- return null;
1016
- }
1017
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGl2b3QtdGFibGUtY29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbG1yLXBpdm90LXRhYmxlL3NyYy9saWIvdXRpbC9waXZvdC10YWJsZS1jb252ZXJ0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsT0FBTyxFQUFDLG1CQUFtQixFQUE4QixtQkFBbUIsRUFBZ0Isa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsb0JBQW9CLEVBQUUsaUJBQWlCLEdBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4TSxPQUFPLEVBQUMsV0FBVyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsWUFBWSxHQUFFLE1BQU0sZUFBZSxDQUFDO0FBSTVKLE9BQU8sRUFBNkQsZ0JBQWdCLEVBQW1DLGlCQUFpQixFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDcEssT0FBTyxFQUFDLGFBQWEsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQWdCaEgsTUFBTSxPQUFPLG1CQUFtQjtJQUN2QixNQUFNLENBQVUsVUFBVSxHQUFHLGtCQUFrQixDQUFDO0lBQ2hELE1BQU0sQ0FBVSxTQUFTLEdBQUcsaUJBQWlCLENBQUM7SUFDOUMsTUFBTSxDQUFVLGNBQWMsR0FBRyx1QkFBdUIsQ0FBQztJQUN6RCxNQUFNLENBQVUsY0FBYyxHQUFHLHVCQUF1QixDQUFDO0lBQ3pELE1BQU0sQ0FBVSxtQkFBbUIsR0FBRyw2QkFBNkIsQ0FBQztJQUNwRSxNQUFNLENBQVUsdUJBQXVCLEdBQUcsaUNBQWlDLENBQUM7SUFDNUUsTUFBTSxDQUFVLGlCQUFpQixHQUFHLDBCQUEwQixDQUFDO0lBQy9ELE1BQU0sQ0FBVSxzQkFBc0IsR0FB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OiBNb2Rlcm4gRGF0YSBEZWZpbml0aW9uIGFuZCBQcm9jZXNzaW5nIFBsYXRmb3JtXG4gKlxuICogQ29weXJpZ2h0IChDKSBzaW5jZSAyMDE3IEx1bWVlci5pbywgcy5yLm8uIGFuZC9vciBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICovXG5pbXBvcnQge2FnZ3JlZ2F0ZURhdGFWYWx1ZXMsIENvbnN0cmFpbnQsIENvbnN0cmFpbnREYXRhLCBEYXRhQWdncmVnYXRpb25UeXBlLCBEYXRhUmVzb3VyY2UsIGlzVmFsdWVBZ2dyZWdhdGlvbiwgTnVtYmVyQ29uc3RyYWludCwgUGVyY2VudGFnZUNvbnN0cmFpbnQsIFVua25vd25Db25zdHJhaW50LH0gZnJvbSAnQGx1bWVlci9kYXRhLWZpbHRlcnMnO1xuaW1wb3J0IHtjcmVhdGVSYW5nZSwgZGVlcE9iamVjdENvcHksIGlzQXJyYXksIGlzTm90TnVsbE9yVW5kZWZpbmVkLCBpc051bGxPclVuZGVmaW5lZCwgaXNOdW1lcmljLCBzaGFkZUNvbG9yLCB0b051bWJlciwgdW5pcXVlVmFsdWVzLH0gZnJvbSAnQGx1bWVlci91dGlscyc7XG5cbmltcG9ydCB7TG1yUGl2b3REYXRhLCBMbXJQaXZvdERhdGFIZWFkZXIsIExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb24sIExtclBpdm90RGF0YUhlYWRlck9wZXJhbmQsIExtclBpdm90RGltZW5zaW9uQ29uZmlnLCBMbXJQaXZvdFN0ZW1EYXRhfSBmcm9tICcuL2xtci1waXZvdC1kYXRhJztcbmltcG9ydCB7TG1yUGl2b3RUYWJsZSwgTG1yUGl2b3RUYWJsZUNlbGx9IGZyb20gJy4vbG1yLXBpdm90LXRhYmxlJztcbmltcG9ydCB7TG1yUGl2b3RFeHByZXNzaW9uLCBMbXJQaXZvdEhlYWRlck9wZXJhbmQsIExtclBpdm90T3BlcmFuZCwgTG1yUGl2b3RQb3NpdGlvbiwgTG1yUGl2b3RTb3J0LCBMbXJQaXZvdFRyYW5zZm9ybSwgTG1yUGl2b3RWYWx1ZVR5cGV9IGZyb20gJy4vbG1yLXBpdm90LWNvbmZpZyc7XG5pbXBvcnQge0NPTE9SX0dSQVkxMDAsIENPTE9SX0dSQVkyMDAsIENPTE9SX0dSQVkzMDAsIENPTE9SX0dSQVk0MDAsIENPTE9SX0dSQVk1MDB9IGZyb20gJy4vbG1yLXBpdm90LWNvbnN0YW50cyc7XG5cbmludGVyZmFjZSBIZWFkZXJHcm91cEluZm8ge1xuICBiYWNrZ3JvdW5kOiBzdHJpbmc7XG4gIGluZGV4ZXM6IG51bWJlcltdO1xuICBleHByZXNzaW9uPzogTG1yUGl2b3REYXRhSGVhZGVyRXhwcmVzc2lvbjtcbiAgbGV2ZWw6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFZhbHVlVHlwZUluZm8ge1xuICBzdW0/OiBudW1iZXI7XG4gIHN1bXNSb3dzPzogbnVtYmVyW107XG4gIHN1bXNDb2x1bW5zPzogbnVtYmVyW107XG4gIGRlZmF1bHRDb25zdHJhaW50PzogQ29uc3RyYWludDtcbn1cblxuZXhwb3J0IGNsYXNzIFBpdm90VGFibGVDb252ZXJ0ZXIge1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGVtcHR5Q2xhc3MgPSAncGl2b3QtZW1wdHktY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgZGF0YUNsYXNzID0gJ3Bpdm90LWRhdGEtY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgZ3JvdXBEYXRhQ2xhc3MgPSAncGl2b3QtZGF0YS1ncm91cC1jZWxsJztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSByb3dIZWFkZXJDbGFzcyA9ICdwaXZvdC1yb3ctaGVhZGVyLWNlbGwnO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IHJvd0dyb3VwSGVhZGVyQ2xhc3MgPSAncGl2b3Qtcm93LWdyb3VwLWhlYWRlci1jZWxsJztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSByb3dBdHRyaWJ1dGVIZWFkZXJDbGFzcyA9ICdwaXZvdC1yb3ctYXR0cmlidXRlLWhlYWRlci1jZWxsJztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBjb2x1bW5IZWFkZXJDbGFzcyA9ICdwaXZvdC1jb2x1bW4taGVhZGVyLWNlbGwnO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGNvbHVtbkdyb3VwSGVhZGVyQ2xhc3MgPSAncGl2b3QtY29sdW1uLWdyb3VwLWhlYWRlci1jZWxsJztcblxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwQ29sb3JzID0gW0NPTE9SX0dSQVkxMDAsIENPTE9SX0dSQVkyMDAsIENPTE9SX0dSQVkzMDAsIENPTE9SX0dSQVk0MDAsIENPTE9SX0dSQVk1MDBdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcGVyY2VudGFnZUNvbnN0cmFpbnQgPSBuZXcgUGVyY2VudGFnZUNvbnN0cmFpbnQoe2RlY2ltYWxzOiAyfSk7XG5cbiAgcHJpdmF0ZSBkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhO1xuICBwcml2YXRlIHRyYW5zZm9ybTogTG1yUGl2b3RUcmFuc2Zvcm07XG4gIHByaXZhdGUgdmFsdWVzOiBhbnlbXVtdO1xuICBwcml2YXRlIGRhdGFSZXNvdXJjZXM6IERhdGFSZXNvdXJjZVtdW11bXTtcbiAgcHJpdmF0ZSBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGE7XG4gIHByaXZhdGUgcm93TGV2ZWxzOiBudW1iZXI7XG4gIHByaXZhdGUgcm93c1RyYW5zZm9ybWF0aW9uQXJyYXk6IG51bWJlcltdO1xuICBwcml2YXRlIGNvbHVtbkxldmVsczogbnVtYmVyO1xuICBwcml2YXRlIGNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5OiBudW1iZXJbXTtcbiAgcHJpdmF0ZSB2YWx1ZVR5cGVJbmZvOiBWYWx1ZVR5cGVJbmZvW107XG4gIHByaXZhdGUgbm9uU3RpY2t5Um93SW5kZXg6IG51bWJlcjtcbiAgcHJpdmF0ZSBub25TdGlja3lDb2x1bW5JbmRleDogbnVtYmVyO1xuXG4gIHB1YmxpYyBjcmVhdGVUYWJsZXMocGl2b3REYXRhOiBMbXJQaXZvdERhdGEsIHRyYW5zZm9ybTogTG1yUGl2b3RUcmFuc2Zvcm0pOiBMbXJQaXZvdFRhYmxlW10ge1xuICAgIGlmICghcGl2b3REYXRhKSB7XG4gICAgICByZXR1cm4gW3tjZWxsczogW119XTtcbiAgICB9XG5cbiAgICB0aGlzLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICB0aGlzLmNvbnN0cmFpbnREYXRhID0gcGl2b3REYXRhLmNvbnN0cmFpbnREYXRhO1xuXG4gICAgcmV0dXJuIChwaXZvdERhdGEuZGF0YSB8fCBbXSkubWFwKGQgPT4ge1xuICAgICAgaWYgKHRoaXMuZGF0YUFyZUVtcHR5KGQpKSB7XG4gICAgICAgIHJldHVybiB7Y2VsbHM6IFtdfTtcbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlRGF0YShkKTtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybURhdGEoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZGF0YUFyZUVtcHR5KGRhdGE6IExtclBpdm90U3RlbURhdGEpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKGRhdGEucm93SGVhZGVycyB8fCBbXSkubGVuZ3RoID09PSAwICYmIChkYXRhLmNvbHVtbkhlYWRlcnMgfHwgW10pLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlRGF0YShkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhKSB7XG4gICAgY29uc3QgbnVtYmVyT2ZTdW1zID0gTWF0aC5tYXgoMSwgKGRhdGEudmFsdWVUaXRsZXMgfHwgW10pLmxlbmd0aCk7XG4gICAgdGhpcy52YWx1ZVR5cGVJbmZvID0gZ2V0VmFsdWVzVHlwZUluZm8oZGF0YS52YWx1ZXMsIGRhdGEudmFsdWVUeXBlcywgbnVtYmVyT2ZTdW1zKTtcbiAgICB0aGlzLmRhdGEgPSBwcmVwYXJlUGl2b3REYXRhKGRhdGEsIHRoaXMuY29uc3RyYWludERhdGEsIHRoaXMudmFsdWVUeXBlSW5mbyk7XG4gICAgdGhpcy52YWx1ZXMgPSBkYXRhLnZhbHVlcyB8fCBbXTtcbiAgICB0aGlzLmRhdGFSZXNvdXJjZXMgPSBkYXRhLmRhdGFSZXNvdXJjZXMgfHwgW107XG4gICAgdGhpcy5yb3dMZXZlbHMgPSAoZGF0YS5yb3dzQ29uZmlnIHx8IFtdKS5sZW5ndGg7XG4gICAgdGhpcy5jb2x1bW5MZXZlbHMgPSAoZGF0YS5jb2x1bW5zQ29uZmlnIHx8IFtdKS5sZW5ndGggKyAoZGF0YS5oYXNBZGRpdGlvbmFsQ29sdW1uTGV2ZWwgPyAxIDogMCk7XG4gICAgY29uc3Qgcm93QWxsU3RpY2t5ID0gdGhpcy5kYXRhLnJvd3NDb25maWc/Lmxlbmd0aCAmJiB0aGlzLmRhdGEucm93c0NvbmZpZy5ldmVyeShjb25maWcgPT4gISFjb25maWc/LnN0aWNreSlcbiAgICB0aGlzLm5vblN0aWNreVJvd0luZGV4ID0gTWF0aC5tYXgocm93QWxsU3RpY2t5ID8gdGhpcy5yb3dMZXZlbHMgOiAodGhpcy5kYXRhLnJvd3NDb25maWc/LmZpbmRJbmRleChjb25maWcgPT4gIWNvbmZpZz8uc3RpY2t5KSB8fCAwKSwgMCk7XG4gICAgY29uc3QgY29sdW1uQWxsU3RpY2t5ID0gdGhpcy5kYXRhLmNvbHVtbnNDb25maWc/Lmxlbmd0aCAmJiB0aGlzLmRhdGEuY29sdW1uc0NvbmZpZy5ldmVyeShjb25maWcgPT4gISFjb25maWc/LnN0aWNreSlcbiAgICB0aGlzLm5vblN0aWNreUNvbHVtbkluZGV4ID0gTWF0aC5tYXgoY29sdW1uQWxsU3RpY2t5ID8gdGhpcy5jb2x1bW5MZXZlbHMgOiAodGhpcy5kYXRhLmNvbHVtbnNDb25maWc/LmZpbmRJbmRleChjb25maWcgPT4gIWNvbmZpZz8uc3RpY2t5KSB8fCAwKSwgMCk7XG4gICAgY29uc3QgaGFzVmFsdWUgPSAoZGF0YS52YWx1ZVRpdGxlcyB8fCBbXSkubGVuZ3RoID4gMDtcbiAgICBpZiAoKHRoaXMuZGF0YS5yb3dIZWFkZXJzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5ID0gY3JlYXRlVHJhbnNmb3JtYXRpb25NYXAoXG4gICAgICAgIHRoaXMuZGF0YS5yb3dIZWFkZXJzLFxuICAgICAgICB0aGlzLnJvd1Nob3dTdW1zLFxuICAgICAgICB0aGlzLmNvbHVtbkxldmVscyxcbiAgICAgICAgMVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheSA9IGhhc1ZhbHVlID8gW3RoaXMuY29sdW1uTGV2ZWxzXSA6IFtdO1xuICAgIH1cblxuICAgIGlmICgodGhpcy5kYXRhLmNvbHVtbkhlYWRlcnMgfHwgW10pLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXkgPSBjcmVhdGVUcmFuc2Zvcm1hdGlvbk1hcChcbiAgICAgICAgdGhpcy5kYXRhLmNvbHVtbkhlYWRlcnMsXG4gICAgICAgIHRoaXMuY29sdW1uU2hvd1N1bXMsXG4gICAgICAgIHRoaXMucm93TGV2ZWxzLFxuICAgICAgICBudW1iZXJPZlN1bXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXkgPSBoYXNWYWx1ZSA/IFt0aGlzLnJvd0xldmVsc10gOiBbXTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldCByb3dTaG93U3VtcygpOiBib29sZWFuW10ge1xuICAgIHJldHVybiAodGhpcy5kYXRhLnJvd3NDb25maWcgfHwgW10pLm1hcChjb25maWcgPT4gY29uZmlnLnNob3dTdW1zKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGNvbHVtblNob3dTdW1zKCk6IGJvb2xlYW5bXSB7XG4gICAgcmV0dXJuICh0aGlzLmRhdGEuY29sdW1uc0NvbmZpZyB8fCBbXSkubWFwKGNvbmZpZyA9PiBjb25maWcuc2hvd1N1bXMpO1xuICB9XG5cbiAgcHJpdmF0ZSB0cmFuc2Zvcm1EYXRhKCk6IExtclBpdm90VGFibGUge1xuICAgIGNvbnN0IGNlbGxzID0gdGhpcy5pbml0Q2VsbHMoKTtcbiAgICBjb25zdCByb3dHcm91cHMgPSB0aGlzLmZpbGxDZWxsc0J5Um93cyhjZWxscyk7XG4gICAgY29uc3QgY29sdW1uR3JvdXBzID0gdGhpcy5maWxsQ2VsbHNCeUNvbHVtbnMoY2VsbHMpO1xuICAgIHRoaXMuZmlsbENlbGxzQnlHcm91cEludGVyc2VjdGlvbihjZWxscywgcm93R3JvdXBzLCBjb2x1bW5Hcm91cHMpO1xuICAgIHJldHVybiB7Y2VsbHN9O1xuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNCeVJvd3MoY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSk6IEhlYWRlckdyb3VwSW5mb1tdIHtcbiAgICBjb25zdCByb3dHcm91cHMgPSBbXTtcbiAgICB0aGlzLml0ZXJhdGVBbmRGaWxsQ2VsbHNCeVJvd3MoY2VsbHMsIHJvd0dyb3VwcywgdGhpcy5kYXRhLnJvd0hlYWRlcnMsIHRoaXMuY29sdW1uTGV2ZWxzLCB0aGlzLnJvd1Nob3dTdW1zLCAwKTtcbiAgICByZXR1cm4gcm93R3JvdXBzO1xuICB9XG5cbiAgcHJpdmF0ZSBpdGVyYXRlQW5kRmlsbENlbGxzQnlSb3dzKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgcm93R3JvdXBzSW5mbzogSGVhZGVyR3JvdXBJbmZvW10sXG4gICAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gICAgc3RhcnRJbmRleDogbnVtYmVyLFxuICAgIHNob3dTdW1zOiBib29sZWFuW10sXG4gICAgbGV2ZWw6IG51bWJlcixcbiAgICBwYXJlbnRIZWFkZXI/OiBMbXJQaXZvdERhdGFIZWFkZXJcbiAgKSB7XG4gICAgbGV0IGN1cnJlbnRJbmRleCA9IHN0YXJ0SW5kZXg7XG4gICAgZm9yIChjb25zdCBoZWFkZXIgb2YgaGVhZGVycykge1xuXG4gICAgICBjb25zdCBiZWZvcmVFeHByZXNzaW9ucyA9IChoZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmZpbHRlcihleHAgPT4gZXhwLnBvc2l0aW9uID09PSBMbXJQaXZvdFBvc2l0aW9uLkJlZm9yZUhlYWRlcilcbiAgICAgIHRoaXMuZmlsbENlbGxzRm9yRXhwcmVzc2lvbnMoY2VsbHMsIHJvd0dyb3Vwc0luZm8sIGxldmVsLCBjdXJyZW50SW5kZXgsIGJlZm9yZUV4cHJlc3Npb25zKVxuICAgICAgY3VycmVudEluZGV4ICs9IGJlZm9yZUV4cHJlc3Npb25zLmxlbmd0aFxuXG4gICAgICBjb25zdCByb3dTcGFuID0gZ2V0RGlyZWN0SGVhZGVyQ2hpbGRDb3VudChoZWFkZXIsIGxldmVsLCBzaG93U3Vtcyk7XG4gICAgICBjZWxsc1tjdXJyZW50SW5kZXhdW2xldmVsXSA9IHtcbiAgICAgICAgdmFsdWU6IHRoaXMuZm9ybWF0Um93SGVhZGVyKGhlYWRlci50aXRsZSwgbGV2ZWwpLFxuICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5yb3dIZWFkZXJDbGFzcyxcbiAgICAgICAgaXNIZWFkZXI6IHRydWUsXG4gICAgICAgIHN0aWNreVN0YXJ0OiB0aGlzLmlzUm93TGV2ZWxTdGlja3kobGV2ZWwpLFxuICAgICAgICByb3dTcGFuLFxuICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICBiYWNrZ3JvdW5kOiB0aGlzLmdldEhlYWRlckJhY2tncm91bmQoaGVhZGVyLCBsZXZlbCksXG4gICAgICAgIGNvbnN0cmFpbnQ6IGhlYWRlci5jb25zdHJhaW50LFxuICAgICAgICBsYWJlbDogaGVhZGVyLmF0dHJpYnV0ZU5hbWUsXG4gICAgICAgIGNoaWxkSW5kZXhlczogY3JlYXRlUmFuZ2UoY3VycmVudEluZGV4LCBjdXJyZW50SW5kZXggKyAoaGVhZGVyLmNoaWxkcmVuPy5sZW5ndGggfHwgMSkpLFxuICAgICAgICBleHBhbmRhYmxlOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgaWYgKGhlYWRlci5jaGlsZHJlbikge1xuICAgICAgICB0aGlzLml0ZXJhdGVBbmRGaWxsQ2VsbHNCeVJvd3MoXG4gICAgICAgICAgY2VsbHMsXG4gICAgICAgICAgcm93R3JvdXBzSW5mbyxcbiAgICAgICAgICBoZWFkZXIuY2hpbGRyZW4sXG4gICAgICAgICAgY3VycmVudEluZGV4LFxuICAgICAgICAgIHNob3dTdW1zLFxuICAgICAgICAgIGxldmVsICsgMSxcbiAgICAgICAgICBoZWFkZXJcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQoaGVhZGVyLnRhcmdldEluZGV4KSkge1xuICAgICAgICB0aGlzLmZpbGxDZWxsc0ZvclJvdyhjZWxscywgaGVhZGVyLnRhcmdldEluZGV4KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYWZ0ZXJFeHByZXNzaW9ucyA9IChoZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmZpbHRlcihleHAgPT4gZXhwLnBvc2l0aW9uID09PSBMbXJQaXZvdFBvc2l0aW9uLlN0aWNrVG9FbmQpXG4gICAgICBjdXJyZW50SW5kZXggKz0gZ2V0SGVhZGVyQ2hpbGRDb3VudChoZWFkZXIsIGxldmVsLCBzaG93U3VtcykgLSBiZWZvcmVFeHByZXNzaW9ucy5sZW5ndGg7XG4gICAgICB0aGlzLmZpbGxDZWxsc0ZvckV4cHJlc3Npb25zKGNlbGxzLCByb3dHcm91cHNJbmZvLCBsZXZlbCwgY3VycmVudEluZGV4IC0gYWZ0ZXJFeHByZXNzaW9ucy5sZW5ndGgsIGFmdGVyRXhwcmVzc2lvbnMpXG4gICAgfVxuXG4gICAgaWYgKHNob3dTdW1zW2xldmVsXSkge1xuICAgICAgY29uc3QgeyB0aXRsZSwgc3VtbWFyeSB9ID0gdGhpcy5mb3JtYXRTdW1tYXJ5SGVhZGVyKHBhcmVudEhlYWRlciwgbGV2ZWwpXG4gICAgICBjb25zdCBiYWNrZ3JvdW5kID0gdGhpcy5nZXRTdW1tYXJ5QmFja2dyb3VuZChsZXZlbCk7XG4gICAgICBjb25zdCBjb2x1bW5JbmRleCA9IE1hdGgubWF4KGxldmVsIC0gMSwgMCk7XG4gICAgICB0aGlzLnNwbGl0Um93R3JvdXBIZWFkZXIoY2VsbHMsIGNvbHVtbkluZGV4LCBjdXJyZW50SW5kZXgsIGJhY2tncm91bmQsIHN1bW1hcnksIFtdLCBmYWxzZSwgdGl0bGUsIHBhcmVudEhlYWRlcj8uY29uc3RyYWludCwgcGFyZW50SGVhZGVyPy5hdHRyaWJ1dGVOYW1lKVxuXG4gICAgICBjb25zdCByb3dJbmRleGVzID0gZ2V0VGFyZ2V0SW5kZXhlc0ZvckhlYWRlcnMoaGVhZGVycyk7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZFJvd0luZGV4ZXMgPSB0aGlzLnRyYW5zZm9ybVJvd0luZGV4ZXMocm93SW5kZXhlcyk7XG4gICAgICByb3dHcm91cHNJbmZvW2N1cnJlbnRJbmRleF0gPSB7YmFja2dyb3VuZCwgaW5kZXhlczogdHJhbnNmb3JtZWRSb3dJbmRleGVzLCBsZXZlbH07XG5cbiAgICAgIHRoaXMuZmlsbENlbGxzRm9yR3JvdXBlZFJvdyhjZWxscywgcm93SW5kZXhlcywgY3VycmVudEluZGV4LCBiYWNrZ3JvdW5kKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0ZvckV4cHJlc3Npb25zKGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sIHJvd0dyb3Vwc0luZm86IEhlYWRlckdyb3VwSW5mb1tdLCBsZXZlbDogbnVtYmVyLCBjdXJyZW50SW5kZXg6IG51bWJlciwgZXhwcmVzc2lvbnM6IExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb25bXSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwcmVzc2lvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb25JbmRleCA9IGN1cnJlbnRJbmRleCArIGlcbiAgICAgIGNvbnN0IGJhY2tncm91bmQgPSB0aGlzLmdldFN1bW1hcnlCYWNrZ3JvdW5kKGxldmVsKTtcbiAgICAgIGNvbnN0IHtpbmRleGVzfSA9IHRoaXMuZmlsbENlbGxzRm9yRXhwcmVzc2lvblJvdyhjZWxscywgZXhwcmVzc2lvbnNbaV0sIGV4cHJlc3Npb25JbmRleCwgYmFja2dyb3VuZClcbiAgICAgIHRoaXMuc3BsaXRSb3dHcm91cEhlYWRlcihjZWxscywgbGV2ZWwsIGV4cHJlc3Npb25JbmRleCwgYmFja2dyb3VuZCwgZXhwcmVzc2lvbnNbaV0udGl0bGUsIGluZGV4ZXMsIGV4cHJlc3Npb25zW2ldLmV4cGFuZGFibGUpXG4gICAgICByb3dHcm91cHNJbmZvW2V4cHJlc3Npb25JbmRleF0gPSB7YmFja2dyb3VuZCwgaW5kZXhlczogW10sIGV4cHJlc3Npb246IGV4cHJlc3Npb25zW2ldLCBsZXZlbH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzcGxpdFJvd0dyb3VwSGVhZGVyKGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sIGNvbHVtbkluZGV4OiBudW1iZXIsIGN1cnJlbnRJbmRleDogbnVtYmVyLCBiYWNrZ3JvdW5kOiBzdHJpbmcsIHN1bW1hcnk6IHN0cmluZywgcm93SW5kZXhlczogbnVtYmVyW10sIGV4cGFuZGFibGU6IGJvb2xlYW4sIHRpdGxlPzogc3RyaW5nLCBjb25zdHJhaW50PzogQ29uc3RyYWludCwgbGFiZWw/OiBzdHJpbmcpIHtcbiAgICBsZXQgY29sU3BhbiA9IHRoaXMucm93TGV2ZWxzIC0gY29sdW1uSW5kZXg7XG4gICAgY29uc3Qgc3RpY2t5U3RhcnQgPSB0aGlzLmlzUm93TGV2ZWxTdGlja3koY29sdW1uSW5kZXgpO1xuXG4gICAgLy8gc3BsaXQgcm93IGdyb3VwIGhlYWRlciBjZWxsIGJlY2F1c2Ugb2YgY29ycmVjdCBzdGlja3kgc2Nyb2xsXG4gICAgaWYgKHN0aWNreVN0YXJ0ICYmIHRoaXMubm9uU3RpY2t5Um93SW5kZXggPiAwICYmIHRoaXMubm9uU3RpY2t5Um93SW5kZXggPCB0aGlzLnJvd0xldmVscyAmJiBjb2xTcGFuID4gMSkge1xuICAgICAgY29uc3QgbmV3Q29sc3BhbiA9IHRoaXMubm9uU3RpY2t5Um93SW5kZXggLSBjb2x1bW5JbmRleDtcblxuICAgICAgY2VsbHNbY3VycmVudEluZGV4XVt0aGlzLm5vblN0aWNreVJvd0luZGV4XSA9IHtcbiAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgY29uc3RyYWludDogdW5kZWZpbmVkLFxuICAgICAgICBsYWJlbDogdW5kZWZpbmVkLFxuICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5yb3dHcm91cEhlYWRlckNsYXNzLFxuICAgICAgICBpc1N1bW1hcnk6IHRydWUsXG4gICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgIGNvbFNwYW46IGNvbFNwYW4gLSBuZXdDb2xzcGFuLFxuICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICBzdW1tYXJ5OiB1bmRlZmluZWQsXG4gICAgICAgIGV4cGFuZGFibGUsXG4gICAgICB9O1xuXG4gICAgICBjb2xTcGFuID0gbmV3Q29sc3BhbjtcbiAgICB9XG5cbiAgICBjZWxsc1tjdXJyZW50SW5kZXhdW2NvbHVtbkluZGV4XSA9IHtcbiAgICAgIHZhbHVlOiB0aXRsZSxcbiAgICAgIGNvbnN0cmFpbnQsXG4gICAgICBsYWJlbCxcbiAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLnJvd0dyb3VwSGVhZGVyQ2xhc3MsXG4gICAgICBpc1N1bW1hcnk6IHRydWUsXG4gICAgICBzdGlja3lTdGFydCxcbiAgICAgIHJvd1NwYW46IDEsXG4gICAgICBjb2xTcGFuLFxuICAgICAgYmFja2dyb3VuZCxcbiAgICAgIHN1bW1hcnksXG4gICAgICByb3dJbmRleGVzLFxuICAgICAgZXhwYW5kYWJsZSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRTdW1tYXJ5SGVhZGVyKGhlYWRlcjogTG1yUGl2b3REYXRhSGVhZGVyLCBsZXZlbDogbnVtYmVyKToge3RpdGxlPzogc3RyaW5nOyBzdW1tYXJ5OiBzdHJpbmd9IHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0uZm9ybWF0U3VtbWFyeUhlYWRlcj8uKGhlYWRlciwgbGV2ZWwpIHx8IHtcbiAgICAgIHRpdGxlOiBoZWFkZXI/LnRpdGxlLFxuICAgICAgc3VtbWFyeTogJycsXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRSb3dIZWFkZXIodGl0bGU6IHN0cmluZywgbGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtPy5mb3JtYXRSb3dIZWFkZXI/Lih0aXRsZSwgbGV2ZWwpIHx8IHRpdGxlXG4gIH1cblxuICBwcml2YXRlIGZvcm1hdENvbHVtbkhlYWRlcih0aXRsZTogc3RyaW5nLCBsZXZlbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm0/LmZvcm1hdENvbHVtbkhlYWRlcj8uKHRpdGxlLCBsZXZlbCkgfHwgdGl0bGVcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SGVhZGVyQmFja2dyb3VuZChoZWFkZXI6IHsgY29sb3I6IHN0cmluZyB9LCBsZXZlbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoaGVhZGVyPy5jb2xvcikge1xuICAgICAgcmV0dXJuIHNoYWRlQ29sb3IoaGVhZGVyLmNvbG9yLCB0aGlzLmdldExldmVsT3BhY2l0eShsZXZlbCkpO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldExldmVsT3BhY2l0eShsZXZlbDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5taW4oODAsIDUwICsgbGV2ZWwgKiA1KSAvIDEwMDtcbiAgfVxuXG4gIHByaXZhdGUgaXNSb3dMZXZlbFN0aWNreShsZXZlbDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YT8ucm93c0NvbmZpZz8uW2xldmVsXT8uc3RpY2t5O1xuICB9XG5cbiAgcHJpdmF0ZSBpc0NvbHVtbkxldmVsU3RpY2t5KGxldmVsOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBtYXhMZXZlbCA9IE1hdGgubWluKGxldmVsLCAodGhpcy5kYXRhPy5jb2x1bW5zQ29uZmlnPy5sZW5ndGggPz8gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIC0gMSk7XG4gICAgcmV0dXJuIHRoaXMuZGF0YT8uY29sdW1uc0NvbmZpZz8uW21heExldmVsXT8uc3RpY2t5O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTdW1tYXJ5QmFja2dyb3VuZChsZXZlbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBpbmRleCA9IE1hdGgubWluKGxldmVsLCB0aGlzLmdyb3VwQ29sb3JzLmxlbmd0aCAtIDEpO1xuICAgIHJldHVybiB0aGlzLmdyb3VwQ29sb3JzW2luZGV4XTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzRm9yUm93KGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sIHJvdzogbnVtYmVyKSB7XG4gICAgY29uc3Qgcm93SW5kZXhJbkNlbGxzID0gdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheVtyb3ddO1xuICAgIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChyb3dJbmRleEluQ2VsbHMpKSB7XG4gICAgICBmb3IgKGxldCBjb2x1bW4gPSAwOyBjb2x1bW4gPCB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5Lmxlbmd0aDsgY29sdW1uKyspIHtcbiAgICAgICAgY29uc3QgY29sdW1uSW5kZXhJbkNlbGxzID0gdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheVtjb2x1bW5dO1xuICAgICAgICBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQoY29sdW1uSW5kZXhJbkNlbGxzKSkge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5kYXRhLnZhbHVlc1tyb3ddW2NvbHVtbl07XG4gICAgICAgICAgY29uc3QgZGF0YVJlc291cmNlcyA9IHRoaXMuZGF0YVJlc291cmNlcz8uW3Jvd10/Lltjb2x1bW5dIHx8IFtdO1xuICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdGhpcy5hZ2dyZWdhdGVPckZvcm1hdFNpbmdsZVZhbHVlKHZhbHVlLCBjb2x1bW4pO1xuICAgICAgICAgIGNvbnN0IHN0cmluZ1ZhbHVlID0gaXNOb3ROdWxsT3JVbmRlZmluZWQoZm9ybWF0dGVkVmFsdWUpID8gU3RyaW5nKGZvcm1hdHRlZFZhbHVlKSA6ICcnO1xuICAgICAgICAgIGNlbGxzW3Jvd0luZGV4SW5DZWxsc11bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtcbiAgICAgICAgICAgIHZhbHVlOiBzdHJpbmdWYWx1ZSxcbiAgICAgICAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmRhdGFDbGFzcyxcbiAgICAgICAgICAgIGlzVmFsdWU6IHRydWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VmFsdWVJbmRleEZvckNvbHVtbnMoY29sdW1uczogbnVtYmVyW10pOiBudW1iZXIge1xuICAgIHJldHVybiBjb2x1bW5zWzBdICUgdGhpcy5kYXRhLnZhbHVlVGl0bGVzLmxlbmd0aDtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0VmFsdWVCeVZhbHVlVHlwZSh2YWx1ZTogYW55LCB2YWx1ZUluZGV4OiBudW1iZXIpOiBhbnkge1xuICAgIGNvbnN0IHZhbHVlVHlwZSA9ICh0aGlzLmRhdGEudmFsdWVUeXBlcyB8fCBbXSlbdmFsdWVJbmRleF07XG4gICAgaWYgKCF2YWx1ZVR5cGUgfHwgdmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5EZWZhdWx0KSB7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5Q29uc3RyYWludCh2YWx1ZSwgdmFsdWVJbmRleCk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgW0xtclBpdm90VmFsdWVUeXBlLkFsbFBlcmNlbnRhZ2UsIExtclBpdm90VmFsdWVUeXBlLkNvbHVtblBlcmNlbnRhZ2UsIExtclBpdm90VmFsdWVUeXBlLlJvd1BlcmNlbnRhZ2VdLmluY2x1ZGVzKHZhbHVlVHlwZSlcbiAgICApIHtcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdFZhbHVlQnlQZXJjZW50YWdlKHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5Q29uc3RyYWludCh2YWx1ZSwgdmFsdWVJbmRleCk7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdEdyb3VwZWRWYWx1ZUJ5VmFsdWVUeXBlKHZhbHVlOiBhbnksIHJvd3M6IG51bWJlcltdLCBjb2x1bW5zOiBudW1iZXJbXSk6IGFueSB7XG4gICAgY29uc3QgdmFsdWVJbmRleCA9IGNvbHVtbnNbMF0gJSB0aGlzLmRhdGEudmFsdWVUaXRsZXMubGVuZ3RoO1xuICAgIGNvbnN0IHZhbHVlVHlwZSA9IHRoaXMuZGF0YS52YWx1ZVR5cGVzICYmIHRoaXMuZGF0YS52YWx1ZVR5cGVzW3ZhbHVlSW5kZXhdO1xuICAgIGNvbnN0IHZhbHVlVHlwZUluZm8gPSB0aGlzLnZhbHVlVHlwZUluZm9bdmFsdWVJbmRleF07XG4gICAgaWYgKCF2YWx1ZVR5cGVJbmZvIHx8ICF2YWx1ZVR5cGUgfHwgdmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5EZWZhdWx0KSB7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5Q29uc3RyYWludCh2YWx1ZSwgdmFsdWVJbmRleCk7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQWxsUGVyY2VudGFnZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeVBlcmNlbnRhZ2UoZGl2aWRlVmFsdWVzKHZhbHVlLCB2YWx1ZVR5cGVJbmZvLnN1bSkpO1xuICAgIH0gZWxzZSBpZiAodmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5Db2x1bW5QZXJjZW50YWdlKSB7XG4gICAgICBjb25zdCBjb2x1bW5zRGl2aWRlcnMgPSBjb2x1bW5zLnJlZHVjZSgoZGl2aWRlcnMsIGNvbHVtbikgPT4ge1xuICAgICAgICBkaXZpZGVycy5wdXNoKHZhbHVlVHlwZUluZm8uc3Vtc0NvbHVtbnNbY29sdW1uXSk7XG4gICAgICAgIHJldHVybiBkaXZpZGVycztcbiAgICAgIH0sIFtdKTtcbiAgICAgIGNvbnN0IGNvbHVtbnNEaXZpZGVyID0gYWdncmVnYXRlRGF0YVZhbHVlcyhEYXRhQWdncmVnYXRpb25UeXBlLlN1bSwgY29sdW1uc0RpdmlkZXJzKTtcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdFZhbHVlQnlQZXJjZW50YWdlKGRpdmlkZVZhbHVlcyh2YWx1ZSwgY29sdW1uc0RpdmlkZXIpKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuUm93UGVyY2VudGFnZSkge1xuICAgICAgY29uc3Qgcm93c0RpdmlkZXJzID0gcm93cy5yZWR1Y2UoKGRpdmlkZXJzLCByb3cpID0+IHtcbiAgICAgICAgZGl2aWRlcnMucHVzaCh2YWx1ZVR5cGVJbmZvLnN1bXNSb3dzW3Jvd10pO1xuICAgICAgICByZXR1cm4gZGl2aWRlcnM7XG4gICAgICB9LCBbXSk7XG4gICAgICBjb25zdCByb3dzRGl2aWRlciA9IGFnZ3JlZ2F0ZURhdGFWYWx1ZXMoRGF0YUFnZ3JlZ2F0aW9uVHlwZS5TdW0sIHJvd3NEaXZpZGVycyk7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5UGVyY2VudGFnZShkaXZpZGVWYWx1ZXModmFsdWUsIHJvd3NEaXZpZGVyKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWUsIHZhbHVlSW5kZXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRWYWx1ZUJ5UGVyY2VudGFnZSh2YWx1ZTogYW55KTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5wZXJjZW50YWdlQ29uc3RyYWludC5jcmVhdGVEYXRhVmFsdWUodmFsdWUpLmZvcm1hdCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRWYWx1ZUJ5Q29uc3RyYWludCh2YWx1ZTogYW55LCB2YWx1ZUluZGV4OiBudW1iZXIpOiBhbnkge1xuICAgIGNvbnN0IGNvbnN0cmFpbnQgPSB0aGlzLmRhdGEudmFsdWVzQ29uc3RyYWludHM/Llt2YWx1ZUluZGV4XSB8fCB0aGlzLnZhbHVlVHlwZUluZm9bdmFsdWVJbmRleF0/LmRlZmF1bHRDb25zdHJhaW50O1xuICAgIGlmIChjb25zdHJhaW50KSB7XG4gICAgICByZXR1cm4gY29uc3RyYWludC5jcmVhdGVEYXRhVmFsdWUodmFsdWUsIHRoaXMuY29uc3RyYWludERhdGEpLnByZXZpZXcoKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNGb3JHcm91cGVkUm93KFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgcm93czogbnVtYmVyW10sXG4gICAgcm93SW5kZXhJbkNlbGxzOiBudW1iZXIsXG4gICAgYmFja2dyb3VuZDogc3RyaW5nXG4gICkge1xuICAgIGZvciAobGV0IGNvbHVtbiA9IDA7IGNvbHVtbiA8IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXkubGVuZ3RoOyBjb2x1bW4rKykge1xuICAgICAgY29uc3QgY29sdW1uSW5kZXhJbkNlbGxzID0gdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheVtjb2x1bW5dO1xuICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGNvbHVtbkluZGV4SW5DZWxscykpIHtcbiAgICAgICAgY29uc3Qge3ZhbHVlcywgZGF0YVJlc291cmNlc30gPSB0aGlzLmdldEdyb3VwZWRWYWx1ZXNGb3JSb3dzQW5kQ29scyhyb3dzLCBbY29sdW1uXSk7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdGhpcy5hZ2dyZWdhdGVBbmRGb3JtYXREYXRhVmFsdWVzKHZhbHVlcywgcm93cywgW2NvbHVtbl0pO1xuICAgICAgICBjZWxsc1tyb3dJbmRleEluQ2VsbHNdW2NvbHVtbkluZGV4SW5DZWxsc10gPSB7XG4gICAgICAgICAgdmFsdWU6IFN0cmluZyhmb3JtYXR0ZWRWYWx1ZSksXG4gICAgICAgICAgZGF0YVJlc291cmNlcyxcbiAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuZ3JvdXBEYXRhQ2xhc3MsXG4gICAgICAgICAgYmFja2dyb3VuZCxcbiAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzRm9yRXhwcmVzc2lvblJvdyhcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIGV4cHJlc3Npb246IExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb24sXG4gICAgcm93SW5kZXhJbkNlbGxzOiBudW1iZXIsXG4gICAgYmFja2dyb3VuZDogc3RyaW5nXG4gICk6e2luZGV4ZXM6IG51bWJlcltdfSB7XG4gICAgbGV0IHJvd0luZGV4ZXM6IG51bWJlcltdID0gW107XG4gICAgZm9yIChsZXQgY29sdW1uID0gMDsgY29sdW1uIDwgdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheS5sZW5ndGg7IGNvbHVtbisrKSB7XG4gICAgICBjb25zdCBjb2x1bW5JbmRleEluQ2VsbHMgPSB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5W2NvbHVtbl07XG4gICAgICBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQoY29sdW1uSW5kZXhJbkNlbGxzKSkge1xuICAgICAgICBjb25zdCB7dmFsdWUsIGRhdGFSZXNvdXJjZXMsIGluZGV4ZXN9ID0gdGhpcy5ldmFsdWF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbiwgW2NvbHVtbl0pO1xuICAgICAgICByb3dJbmRleGVzID0gaW5kZXhlc1xuICAgICAgICBjb25zdCB2YWx1ZUluZGV4ID0gY29sdW1uICUgdGhpcy5kYXRhLnZhbHVlVGl0bGVzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmZvcm1hdFZhbHVlQnlDb25zdHJhaW50KHZhbHVlLCB2YWx1ZUluZGV4KTtcbiAgICAgICAgY2VsbHNbcm93SW5kZXhJbkNlbGxzXVtjb2x1bW5JbmRleEluQ2VsbHNdID0ge1xuICAgICAgICAgIHZhbHVlOiBTdHJpbmcoZm9ybWF0dGVkVmFsdWUpLFxuICAgICAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmdyb3VwRGF0YUNsYXNzLFxuICAgICAgICAgIGJhY2tncm91bmQsXG4gICAgICAgICAgaXNWYWx1ZTogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtpbmRleGVzOiB1bmlxdWVWYWx1ZXMoW3Jvd0luZGV4SW5DZWxscywgLi4ucm93SW5kZXhlc10pfVxuICB9XG5cbiAgcHJpdmF0ZSBldmFsdWF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbjogTG1yUGl2b3REYXRhSGVhZGVyRXhwcmVzc2lvbiwgY29sdW1uczogbnVtYmVyW10pOiB7dmFsdWU6IG51bWJlcjsgZGF0YVJlc291cmNlczogRGF0YVJlc291cmNlW107IGluZGV4ZXM6IG51bWJlcltdICB9IHtcbiAgICByZXR1cm4gKGV4cHJlc3Npb24ub3BlcmFuZHMgfHwgW10pLnJlZHVjZSgocmVzdWx0LCBvcGVyYW5kLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3Qge3ZhbHVlLCBkYXRhUmVzb3VyY2VzLCBpbmRleGVzIH0gPSB0aGlzLmV2YWx1YXRlT3BlcmFuZChvcGVyYW5kLCBjb2x1bW5zKVxuICAgICAgcmVzdWx0LmRhdGFSZXNvdXJjZXMucHVzaCguLi5kYXRhUmVzb3VyY2VzKVxuICAgICAgcmVzdWx0LmluZGV4ZXMucHVzaCguLi5pbmRleGVzKVxuICAgICAgc3dpdGNoIChleHByZXNzaW9uLm9wZXJhdGlvbikge1xuICAgICAgICBjYXNlICdhZGQnOlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSArPSB2YWx1ZVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdzdWJ0cmFjdCc6XG4gICAgICAgICAgcmVzdWx0LnZhbHVlID0gKGluZGV4ID09PSAwID8gdmFsdWUgOiByZXN1bHQudmFsdWUgLSB2YWx1ZSlcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnbXVsdGlwbHknOlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IGluZGV4ID09PSAwID8gdmFsdWUgOiByZXN1bHQudmFsdWUgKiB2YWx1ZVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdkaXZpZGUnOlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IGluZGV4ID09PSAwID8gdmFsdWUgOiB2YWx1ZSA/IHJlc3VsdC52YWx1ZSAvIHZhbHVlIDogcmVzdWx0LnZhbHVlXG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRcbiAgICB9ICwge3ZhbHVlOiAwLCBkYXRhUmVzb3VyY2VzOiBbXSwgaW5kZXhlczogW119KVxuICB9XG5cbiAgcHJpdmF0ZSBldmFsdWF0ZU9wZXJhbmQob3BlcmFuZDogTG1yUGl2b3REYXRhSGVhZGVyT3BlcmFuZCwgY29sdW1uczogbnVtYmVyW10pOiB7dmFsdWU6IG51bWJlcjsgZGF0YVJlc291cmNlczogRGF0YVJlc291cmNlW107IGluZGV4ZXM6IG51bWJlcltdIH0ge1xuICAgIHN3aXRjaCAob3BlcmFuZC50eXBlKSB7XG4gICAgICBjYXNlICdleHByZXNzaW9uJzogcmV0dXJuIHRoaXMuZXZhbHVhdGVFeHByZXNzaW9uKG9wZXJhbmQsIGNvbHVtbnMpXG4gICAgICBjYXNlICd2YWx1ZSc6IHJldHVybiB7dmFsdWU6IG9wZXJhbmQudmFsdWUsIGRhdGFSZXNvdXJjZXM6IFtdLCBpbmRleGVzOiBbXX1cbiAgICAgIGNhc2UgJ2hlYWRlcic6IHtcbiAgICAgICAgY29uc3Qgcm93cyA9IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXJzKG9wZXJhbmQuaGVhZGVycyk7XG4gICAgICAgIGNvbnN0IHt2YWx1ZXMsIGRhdGFSZXNvdXJjZXN9ID0gdGhpcy5nZXRHcm91cGVkVmFsdWVzRm9yUm93c0FuZENvbHMocm93cywgY29sdW1ucyk7XG4gICAgICAgIGNvbnN0IHt2YWx1ZX0gPSB0aGlzLmFnZ3JlZ2F0ZURhdGFWYWx1ZXModmFsdWVzLCBjb2x1bW5zKTtcbiAgICAgICAgcmV0dXJuIHt2YWx1ZSwgZGF0YVJlc291cmNlcywgaW5kZXhlczogdGhpcy50cmFuc2Zvcm1Sb3dJbmRleGVzKHJvd3MpfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNmb3JtUm93SW5kZXhlcyhyb3dzOiBudW1iZXJbXSk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gcm93c1xuICAgICAgLm1hcCh2ID0+IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXlbdl0pXG4gICAgICAuZmlsdGVyKHYgPT4gaXNOb3ROdWxsT3JVbmRlZmluZWQodikpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRHcm91cGVkVmFsdWVzRm9yUm93c0FuZENvbHMoXG4gICAgcm93czogbnVtYmVyW10sXG4gICAgY29sdW1uczogbnVtYmVyW11cbiAgKTogeyB2YWx1ZXM6IGFueVtdOyBkYXRhUmVzb3VyY2VzOiBEYXRhUmVzb3VyY2VbXSB9IHtcbiAgICBjb25zdCB2YWx1ZXMgPSBbXTtcbiAgICBjb25zdCBkYXRhUmVzb3VyY2VzID0gW107XG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuICAgICAgICBjb25zdCByb3dDb2x1bW5WYWx1ZSA9IHRoaXMudmFsdWVzW3Jvd11bY29sdW1uXTtcbiAgICAgICAgaWYgKGlzQXJyYXkocm93Q29sdW1uVmFsdWUpKSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2goLi4ucm93Q29sdW1uVmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKHJvd0NvbHVtblZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhUmVzb3VyY2VzLnB1c2goLi4uKHRoaXMuZGF0YVJlc291cmNlcz8uW3Jvd10/Lltjb2x1bW5dIHx8IFtdKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7dmFsdWVzLCBkYXRhUmVzb3VyY2VzfTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzQnlDb2x1bW5zKGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10pOiBIZWFkZXJHcm91cEluZm9bXSB7XG4gICAgY29uc3QgY29sdW1uR3JvdXBzID0gW107XG4gICAgdGhpcy5pdGVyYXRlQW5kRmlsbENlbGxzQnlDb2x1bW5zKFxuICAgICAgY2VsbHMsXG4gICAgICBjb2x1bW5Hcm91cHMsXG4gICAgICB0aGlzLmRhdGEuY29sdW1uSGVhZGVycyxcbiAgICAgIHRoaXMucm93TGV2ZWxzLFxuICAgICAgdGhpcy5jb2x1bW5TaG93U3VtcyxcbiAgICAgIDBcbiAgICApO1xuICAgIHJldHVybiBjb2x1bW5Hcm91cHM7XG4gIH1cblxuICBwcml2YXRlIGl0ZXJhdGVBbmRGaWxsQ2VsbHNCeUNvbHVtbnMoXG4gICAgY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSxcbiAgICBjb2x1bW5Hcm91cHNJbmZvOiBIZWFkZXJHcm91cEluZm9bXSxcbiAgICBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgICBzdGFydEluZGV4OiBudW1iZXIsXG4gICAgc2hvd1N1bXM6IGJvb2xlYW5bXSxcbiAgICBsZXZlbDogbnVtYmVyLFxuICAgIHBhcmVudEhlYWRlcj86IExtclBpdm90RGF0YUhlYWRlclxuICApIHtcbiAgICBsZXQgY3VycmVudEluZGV4ID0gc3RhcnRJbmRleDtcbiAgICBjb25zdCBudW1iZXJPZlN1bXMgPSBNYXRoLm1heCgxLCB0aGlzLmRhdGEudmFsdWVUaXRsZXMubGVuZ3RoKTtcbiAgICBmb3IgKGNvbnN0IGhlYWRlciBvZiBoZWFkZXJzKSB7XG4gICAgICBjb25zdCBjb2xTcGFuID0gZ2V0RGlyZWN0SGVhZGVyQ2hpbGRDb3VudChoZWFkZXIsIGxldmVsLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKTtcbiAgICAgIGNlbGxzW2xldmVsXVtjdXJyZW50SW5kZXhdID0ge1xuICAgICAgICB2YWx1ZTogdGhpcy5mb3JtYXRDb2x1bW5IZWFkZXIoaGVhZGVyLnRpdGxlLCBsZXZlbCksXG4gICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmNvbHVtbkhlYWRlckNsYXNzLFxuICAgICAgICBpc0hlYWRlcjogdHJ1ZSxcbiAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgY29sU3BhbixcbiAgICAgICAgc3RpY2t5VG9wOiB0aGlzLmlzQ29sdW1uTGV2ZWxTdGlja3kobGV2ZWwpLFxuICAgICAgICBiYWNrZ3JvdW5kOiB0aGlzLmdldEhlYWRlckJhY2tncm91bmQoaGVhZGVyLCBsZXZlbCksXG4gICAgICAgIGNvbnN0cmFpbnQ6IGhlYWRlci5jb25zdHJhaW50LFxuICAgICAgICBsYWJlbDogaGVhZGVyLmF0dHJpYnV0ZU5hbWUsXG4gICAgICB9O1xuXG4gICAgICBpZiAoaGVhZGVyLmNoaWxkcmVuKSB7XG4gICAgICAgIHRoaXMuaXRlcmF0ZUFuZEZpbGxDZWxsc0J5Q29sdW1ucyhcbiAgICAgICAgICBjZWxscyxcbiAgICAgICAgICBjb2x1bW5Hcm91cHNJbmZvLFxuICAgICAgICAgIGhlYWRlci5jaGlsZHJlbixcbiAgICAgICAgICBjdXJyZW50SW5kZXgsXG4gICAgICAgICAgc2hvd1N1bXMsXG4gICAgICAgICAgbGV2ZWwgKyAxLFxuICAgICAgICAgIGhlYWRlclxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChoZWFkZXIudGFyZ2V0SW5kZXgpKSB7XG4gICAgICAgIHRoaXMuZmlsbENlbGxzRm9yQ29sdW1uKGNlbGxzLCBoZWFkZXIudGFyZ2V0SW5kZXgpO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50SW5kZXggKz0gZ2V0SGVhZGVyQ2hpbGRDb3VudChoZWFkZXIsIGxldmVsLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKTtcbiAgICB9XG5cbiAgICBpZiAoc2hvd1N1bXNbbGV2ZWxdKSB7XG4gICAgICBjb25zdCBiYWNrZ3JvdW5kID0gdGhpcy5nZXRTdW1tYXJ5QmFja2dyb3VuZChsZXZlbCk7XG4gICAgICBjb25zdCB7IHRpdGxlLCBzdW1tYXJ5IH0gPSB0aGlzLmZvcm1hdFN1bW1hcnlIZWFkZXIocGFyZW50SGVhZGVyLCBsZXZlbClcbiAgICAgIGNvbnN0IG51bWJlck9mVmFsdWVzID0gdGhpcy5kYXRhLnZhbHVlVGl0bGVzLmxlbmd0aDtcbiAgICAgIGNvbnN0IHJvd0luZGV4ID0gTWF0aC5tYXgobGV2ZWwgLSAxLCAwKTtcbiAgICAgIGNvbnN0IHNob3VsZEFkZFZhbHVlSGVhZGVycyA9IG51bWJlck9mVmFsdWVzID4gMTtcblxuICAgICAgY2VsbHNbcm93SW5kZXhdW2N1cnJlbnRJbmRleF0gPSB7XG4gICAgICAgIHZhbHVlOiB0aXRsZSxcbiAgICAgICAgY29uc3RyYWludDogcGFyZW50SGVhZGVyPy5jb25zdHJhaW50LFxuICAgICAgICBsYWJlbDogcGFyZW50SGVhZGVyPy5hdHRyaWJ1dGVOYW1lLFxuICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5jb2x1bW5Hcm91cEhlYWRlckNsYXNzLFxuICAgICAgICBpc1N1bW1hcnk6IHRydWUsXG4gICAgICAgIHN0aWNreVRvcDogdGhpcy5pc0NvbHVtbkxldmVsU3RpY2t5KGxldmVsKSxcbiAgICAgICAgcm93U3BhbjogdGhpcy5jb2x1bW5MZXZlbHMgLSByb3dJbmRleCAtIChzaG91bGRBZGRWYWx1ZUhlYWRlcnMgPyAxIDogMCksXG4gICAgICAgIGNvbFNwYW46IG51bWJlck9mU3VtcyxcbiAgICAgICAgYmFja2dyb3VuZCxcbiAgICAgICAgc3VtbWFyeSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChudW1iZXJPZlZhbHVlcyA+IDApIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZlZhbHVlczsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgY29sdW1uSW5kZXhJbkNlbGxzID0gY3VycmVudEluZGV4ICsgaTtcbiAgICAgICAgICBpZiAoc2hvdWxkQWRkVmFsdWVIZWFkZXJzKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZVRpdGxlID0gdGhpcy5kYXRhLnZhbHVlVGl0bGVzW2ldO1xuICAgICAgICAgICAgY2VsbHNbdGhpcy5jb2x1bW5MZXZlbHMgLSAxXVtjb2x1bW5JbmRleEluQ2VsbHNdID0ge1xuICAgICAgICAgICAgICB2YWx1ZTogdmFsdWVUaXRsZSxcbiAgICAgICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuY29sdW1uR3JvdXBIZWFkZXJDbGFzcyxcbiAgICAgICAgICAgICAgaXNTdW1tYXJ5OiB0cnVlLFxuICAgICAgICAgICAgICBzdGlja3lUb3A6IHRoaXMuaXNDb2x1bW5MZXZlbFN0aWNreShsZXZlbCksXG4gICAgICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICAgIGJhY2tncm91bmQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGNvbHVtbnNJbmRleGVzID0gZ2V0VGFyZ2V0SW5kZXhlc0ZvckhlYWRlcnMoaGVhZGVycyk7XG4gICAgICAgICAgY29uc3QgdmFsdWVDb2x1bW5zSW5kZXhlcyA9IGNvbHVtbnNJbmRleGVzLmZpbHRlcihpbmRleCA9PiBpbmRleCAlIG51bWJlck9mVmFsdWVzID09PSBpKTtcbiAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZENvbHVtbkluZGV4ZXMgPSB2YWx1ZUNvbHVtbnNJbmRleGVzXG4gICAgICAgICAgICAubWFwKHYgPT4gdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheVt2XSlcbiAgICAgICAgICAgIC5maWx0ZXIodiA9PiBpc05vdE51bGxPclVuZGVmaW5lZCh2KSk7XG4gICAgICAgICAgY29sdW1uR3JvdXBzSW5mb1tjb2x1bW5JbmRleEluQ2VsbHNdID0ge2JhY2tncm91bmQsIGluZGV4ZXM6IHRyYW5zZm9ybWVkQ29sdW1uSW5kZXhlcywgbGV2ZWx9O1xuXG4gICAgICAgICAgdGhpcy5maWxsQ2VsbHNGb3JHcm91cGVkQ29sdW1uKGNlbGxzLCB2YWx1ZUNvbHVtbnNJbmRleGVzLCBjb2x1bW5JbmRleEluQ2VsbHMsIGJhY2tncm91bmQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW5Hcm91cHNJbmZvW2N1cnJlbnRJbmRleF0gPSB7YmFja2dyb3VuZCwgaW5kZXhlczogW10sIGxldmVsfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0Zvckdyb3VwZWRDb2x1bW4oXG4gICAgY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSxcbiAgICBjb2x1bW5zOiBudW1iZXJbXSxcbiAgICBjb2x1bW5JbmRleEluQ2VsbHM6IG51bWJlcixcbiAgICBiYWNrZ3JvdW5kOiBzdHJpbmdcbiAgKSB7XG4gICAgZm9yIChsZXQgcm93ID0gMDsgcm93IDwgdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheS5sZW5ndGg7IHJvdysrKSB7XG4gICAgICBjb25zdCByb3dJbmRleEluQ2VsbHMgPSB0aGlzLnJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5W3Jvd107XG4gICAgICBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQocm93SW5kZXhJbkNlbGxzKSkge1xuICAgICAgICBjb25zdCB7dmFsdWVzLCBkYXRhUmVzb3VyY2VzfSA9IHRoaXMuZ2V0R3JvdXBlZFZhbHVlc0ZvclJvd3NBbmRDb2xzKFtyb3ddLCBjb2x1bW5zKTtcbiAgICAgICAgY29uc3QgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmFnZ3JlZ2F0ZUFuZEZvcm1hdERhdGFWYWx1ZXModmFsdWVzLCBbcm93XSwgY29sdW1ucyk7XG4gICAgICAgIGNlbGxzW3Jvd0luZGV4SW5DZWxsc11bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtcbiAgICAgICAgICB2YWx1ZTogU3RyaW5nKGZvcm1hdHRlZFZhbHVlKSxcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5ncm91cERhdGFDbGFzcyxcbiAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgIGlzVmFsdWU6IHRydWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZ2dyZWdhdGVBbmRGb3JtYXREYXRhVmFsdWVzKHZhbHVlczogYW55W10sIHJvd3M6IG51bWJlcltdLCBjb2x1bW5zOiBudW1iZXJbXSk6IGFueSB7XG4gICAgY29uc3Qge3ZhbHVlLCBhZ2dyZWdhdGlvbn0gPSB0aGlzLmFnZ3JlZ2F0ZURhdGFWYWx1ZXModmFsdWVzLCBjb2x1bW5zKTtcbiAgICByZXR1cm4gYWdncmVnYXRpb24gPT09IERhdGFBZ2dyZWdhdGlvblR5cGUuSm9pbiA/IHZhbHVlIDogdGhpcy5mb3JtYXRHcm91cGVkVmFsdWVCeVZhbHVlVHlwZSh2YWx1ZSwgcm93cywgY29sdW1ucylcbiAgfVxuXG4gIHByaXZhdGUgYWdncmVnYXRlRGF0YVZhbHVlcyh2YWx1ZXM6IGFueVtdLCBjb2x1bW5zOiBudW1iZXJbXSk6IHt2YWx1ZTogYW55OyBhZ2dyZWdhdGlvbjogRGF0YUFnZ3JlZ2F0aW9uVHlwZX0ge1xuICAgIGNvbnN0IGFnZ3JlZ2F0aW9uID0gdGhpcy5hZ2dyZWdhdGlvbkJ5Q29sdW1ucyhjb2x1bW5zKTtcbiAgICBpZiAoYWdncmVnYXRpb24gPT09IERhdGFBZ2dyZWdhdGlvblR5cGUuSm9pbikge1xuICAgICAgY29uc3QgdmFsdWVJbmRleCA9IHRoaXMuZ2V0VmFsdWVJbmRleEZvckNvbHVtbnMoY29sdW1ucyk7XG4gICAgICBjb25zdCBjb25zdHJhaW50ID0gdGhpcy5kYXRhLnZhbHVlc0NvbnN0cmFpbnRzPy5bdmFsdWVJbmRleF0gfHwgdGhpcy52YWx1ZVR5cGVJbmZvW3ZhbHVlSW5kZXhdPy5kZWZhdWx0Q29uc3RyYWludDtcbiAgICAgIHJldHVybiB7dmFsdWU6IGFnZ3JlZ2F0ZURhdGFWYWx1ZXMoYWdncmVnYXRpb24sIHZhbHVlcywgY29uc3RyYWludCwgZmFsc2UsIHRoaXMuY29uc3RyYWludERhdGEpLCBhZ2dyZWdhdGlvbn07XG4gICAgfVxuICAgIHJldHVybiB7dmFsdWU6IGFnZ3JlZ2F0ZURhdGFWYWx1ZXMoYWdncmVnYXRpb24sIHZhbHVlcyksIGFnZ3JlZ2F0aW9ufTtcbiAgfVxuXG4gIHByaXZhdGUgYWdncmVnYXRpb25CeUNvbHVtbnMoY29sdW1uczogbnVtYmVyW10pOiBEYXRhQWdncmVnYXRpb25UeXBlIHtcbiAgICBjb25zdCB2YWx1ZUluZGV4ID0gY29sdW1uc1swXSAlIHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gICAgY29uc3QgYWdncmVnYXRpb24gPSB0aGlzLmRhdGEudmFsdWVBZ2dyZWdhdGlvbnM/Llt2YWx1ZUluZGV4XTtcbiAgICByZXR1cm4gaXNWYWx1ZUFnZ3JlZ2F0aW9uKGFnZ3JlZ2F0aW9uKSA/IGFnZ3JlZ2F0aW9uIDogRGF0YUFnZ3JlZ2F0aW9uVHlwZS5TdW07XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0ZvckNvbHVtbihjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLCBjb2x1bW46IG51bWJlcikge1xuICAgIGNvbnN0IGNvbHVtbkluZGV4SW5DZWxscyA9IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXlbY29sdW1uXTtcbiAgICBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQoY29sdW1uSW5kZXhJbkNlbGxzKSkge1xuICAgICAgZm9yIChsZXQgcm93ID0gMDsgcm93IDwgdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheS5sZW5ndGg7IHJvdysrKSB7XG4gICAgICAgIGNvbnN0IHJvd0luZGV4SW5DZWxscyA9IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXlbcm93XTtcbiAgICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKHJvd0luZGV4SW5DZWxscykpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZGF0YS52YWx1ZXNbcm93XVtjb2x1bW5dO1xuICAgICAgICAgIGNvbnN0IGRhdGFSZXNvdXJjZXMgPSB0aGlzLmRhdGFSZXNvdXJjZXM/Lltyb3ddPy5bY29sdW1uXSB8fCBbXTtcbiAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuYWdncmVnYXRlT3JGb3JtYXRTaW5nbGVWYWx1ZSh2YWx1ZSwgY29sdW1uKTtcbiAgICAgICAgICBjb25zdCBzdHJpbmdWYWx1ZSA9IGlzTm90TnVsbE9yVW5kZWZpbmVkKGZvcm1hdHRlZFZhbHVlKSA/IFN0cmluZyhmb3JtYXR0ZWRWYWx1ZSkgOiAnJztcbiAgICAgICAgICBjZWxsc1tyb3dJbmRleEluQ2VsbHNdW2NvbHVtbkluZGV4SW5DZWxsc10gPSB7XG4gICAgICAgICAgICB2YWx1ZTogc3RyaW5nVmFsdWUsXG4gICAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5kYXRhQ2xhc3MsXG4gICAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFnZ3JlZ2F0ZU9yRm9ybWF0U2luZ2xlVmFsdWUodmFsdWU6IGFueSwgY29sdW1uOiBudW1iZXIpOiBhbnkge1xuICAgIGNvbnN0IGFnZ3JlZ2F0aW9uID0gdGhpcy5hZ2dyZWdhdGlvbkJ5Q29sdW1ucyhbY29sdW1uXSk7XG4gICAgY29uc3QgdmFsdWVJbmRleCA9IHRoaXMuZ2V0VmFsdWVJbmRleEZvckNvbHVtbnMoW2NvbHVtbl0pO1xuICAgIGlmIChhZ2dyZWdhdGlvbiA9PT0gRGF0YUFnZ3JlZ2F0aW9uVHlwZS5Kb2luKSB7XG4gICAgICBjb25zdCBjb25zdHJhaW50ID0gdGhpcy5kYXRhLnZhbHVlc0NvbnN0cmFpbnRzPy5bdmFsdWVJbmRleF0gfHwgdGhpcy52YWx1ZVR5cGVJbmZvW3ZhbHVlSW5kZXhdPy5kZWZhdWx0Q29uc3RyYWludDtcbiAgICAgIHJldHVybiBhZ2dyZWdhdGVEYXRhVmFsdWVzKGFnZ3JlZ2F0aW9uLCBbdmFsdWVdLCBjb25zdHJhaW50LCBmYWxzZSwgdGhpcy5jb25zdHJhaW50RGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmZvcm1hdFZhbHVlQnlWYWx1ZVR5cGUodmFsdWUsIHZhbHVlSW5kZXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNCeUdyb3VwSW50ZXJzZWN0aW9uKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgcm93R3JvdXBzSW5mbzogSGVhZGVyR3JvdXBJbmZvW10sXG4gICAgY29sdW1uR3JvdXBzSW5mbzogSGVhZGVyR3JvdXBJbmZvW11cbiAgKSB7XG4gICAgY29uc3Qgcm93c0NvdW50ID0gY2VsbHMubGVuZ3RoO1xuICAgIGNvbnN0IGNvbHVtbnNDb3VudCA9IGNlbGxzWzBdPy5sZW5ndGggfHwgMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93R3JvdXBzSW5mby5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgcm93R3JvdXBJbmZvID0gcm93R3JvdXBzSW5mb1tpXTtcbiAgICAgIGlmICghcm93R3JvdXBJbmZvKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sdW1uR3JvdXBzSW5mby5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoIWNvbHVtbkdyb3Vwc0luZm9bal0pIHtcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29sdW1ucyA9IGNvbHVtbkdyb3Vwc0luZm9bal0uaW5kZXhlc1xuICAgICAgICBjb25zdCB7cm93c0luZGV4ZXMsIGNvbHVtbnNJbmRleGVzfSA9IHRoaXMuZ2V0VmFsdWVzSW5kZXhlc0Zyb21DZWxsc0luZGV4ZXMoXG4gICAgICAgICAgcm93R3JvdXBJbmZvLmluZGV4ZXMsXG4gICAgICAgICAgY29sdW1uc1xuICAgICAgICApO1xuICAgICAgICBsZXQgZm9ybWF0dGVkVmFsdWU6IHN0cmluZztcbiAgICAgICAgbGV0IGRhdGFSZXNvdXJjZXM6IERhdGFSZXNvdXJjZVtdO1xuICAgICAgICBpZiAocm93R3JvdXBJbmZvLmV4cHJlc3Npb24pIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmV2YWx1YXRlRXhwcmVzc2lvbihyb3dHcm91cEluZm8uZXhwcmVzc2lvbiwgY29sdW1uc0luZGV4ZXMpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlSW5kZXggPSBjb2x1bW5zSW5kZXhlc1swXSAlIHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gICAgICAgICAgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmZvcm1hdFZhbHVlQnlDb25zdHJhaW50KHJlc3VsdC52YWx1ZSwgdmFsdWVJbmRleCk7XG4gICAgICAgICAgZGF0YVJlc291cmNlcyA9IHJlc3VsdC5kYXRhUmVzb3VyY2VzXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaXQncyBlbm91Z2ggdG8gZmlsbCBncm91cCB2YWx1ZXMgb25seSBmcm9tIHJvdyBzaWRlXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5nZXRHcm91cGVkVmFsdWVzRm9yUm93c0FuZENvbHMocm93c0luZGV4ZXMsIGNvbHVtbnNJbmRleGVzKTtcbiAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuYWdncmVnYXRlQW5kRm9ybWF0RGF0YVZhbHVlcyhyZXN1bHQudmFsdWVzLCByb3dzSW5kZXhlcywgY29sdW1uc0luZGV4ZXMpO1xuICAgICAgICAgIGRhdGFSZXNvdXJjZXMgPSByZXN1bHQuZGF0YVJlc291cmNlc1xuICAgICAgICB9XG4gICAgICAgIGNlbGxzW2ldW2pdID0ge1xuICAgICAgICAgIHZhbHVlOiBTdHJpbmcoZm9ybWF0dGVkVmFsdWUpLFxuICAgICAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmdyb3VwRGF0YUNsYXNzLFxuICAgICAgICAgIGlzVmFsdWU6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgIH1cblxuICAgICAgdGhpcy5maWxsUm93V2l0aENvbG9yKGNlbGxzLCBpLCByb3dHcm91cEluZm8sIGNvbHVtbnNDb3VudCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBjb2x1bW5Hcm91cHNJbmZvLmxlbmd0aDsgaisrKSB7XG4gICAgICBpZiAoY29sdW1uR3JvdXBzSW5mb1tqXSkge1xuICAgICAgICB0aGlzLmZpbGxDb2x1bW5XaXRoQ29sb3IoY2VsbHMsIGosIGNvbHVtbkdyb3Vwc0luZm9bal0sIHJvd0dyb3Vwc0luZm8sIHJvd3NDb3VudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRWYWx1ZXNJbmRleGVzRnJvbUNlbGxzSW5kZXhlcyhcbiAgICByb3dzOiBudW1iZXJbXSxcbiAgICBjb2x1bW5zOiBudW1iZXJbXVxuICApOiB7IHJvd3NJbmRleGVzOiBudW1iZXJbXTsgY29sdW1uc0luZGV4ZXM6IG51bWJlcltdIH0ge1xuICAgIGNvbnN0IHJvd3NJbmRleGVzID0gcm93c1xuICAgICAgLm1hcChyb3cgPT4gdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheS5maW5kSW5kZXgodFJvdyA9PiB0Um93ID09PSByb3cpKVxuICAgICAgLmZpbHRlcihpbmRleCA9PiBpbmRleCA+PSAwKTtcbiAgICBjb25zdCBjb2x1bW5zSW5kZXhlcyA9IGNvbHVtbnNcbiAgICAgIC5tYXAoY29sdW1uID0+IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXkuZmluZEluZGV4KHRDb2x1bW4gPT4gdENvbHVtbiA9PT0gY29sdW1uKSlcbiAgICAgIC5maWx0ZXIoaW5kZXggPT4gaW5kZXggPj0gMCk7XG4gICAgcmV0dXJuIHtyb3dzSW5kZXhlcywgY29sdW1uc0luZGV4ZXN9O1xuICB9XG5cbiAgcHJpdmF0ZSBmaWxsUm93V2l0aENvbG9yKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgcm93OiBudW1iZXIsXG4gICAgcm93R3JvdXBJbmZvOiBIZWFkZXJHcm91cEluZm8sXG4gICAgY29sdW1uc0NvdW50OiBudW1iZXJcbiAgKSB7XG4gICAgZm9yIChsZXQgaSA9IHRoaXMucm93TGV2ZWxzOyBpIDwgY29sdW1uc0NvdW50OyBpKyspIHtcbiAgICAgIGNlbGxzW3Jvd11baV0gJiYgKGNlbGxzW3Jvd11baV0uYmFja2dyb3VuZCA9IHJvd0dyb3VwSW5mby5iYWNrZ3JvdW5kKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbGxDb2x1bW5XaXRoQ29sb3IoXG4gICAgY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSxcbiAgICBjb2x1bW46IG51bWJlcixcbiAgICBjb2x1bW5Hcm91cEluZm86IEhlYWRlckdyb3VwSW5mbyxcbiAgICByb3dHcm91cHNJbmZvOiBIZWFkZXJHcm91cEluZm9bXSxcbiAgICByb3dDb3VudDogbnVtYmVyXG4gICkge1xuICAgIGZvciAobGV0IGkgPSB0aGlzLmNvbHVtbkxldmVsczsgaSA8IHJvd0NvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHJvd0dyb3VwSW5mbyA9IHJvd0dyb3Vwc0luZm9baV07XG4gICAgICBpZiAoIXJvd0dyb3VwSW5mbyB8fCByb3dHcm91cEluZm8ubGV2ZWwgPiBjb2x1bW5Hcm91cEluZm8ubGV2ZWwpIHtcbiAgICAgICAgY2VsbHNbaV1bY29sdW1uXSAmJiAoY2VsbHNbaV1bY29sdW1uXS5iYWNrZ3JvdW5kID0gY29sdW1uR3JvdXBJbmZvLmJhY2tncm91bmQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdENlbGxzKCk6IExtclBpdm90VGFibGVDZWxsW11bXSB7XG4gICAgY29uc3Qgcm93cyA9IHRoaXMuZ2V0Um93c0NvdW50KCkgKyB0aGlzLmNvbHVtbkxldmVscztcbiAgICBjb25zdCBjb2x1bW5zID0gdGhpcy5nZXRDb2x1bW5zQ291bnQoKSArIHRoaXMucm93TGV2ZWxzO1xuXG4gICAgY29uc3QgbWF0cml4OiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd3M7IGkrKykge1xuICAgICAgbWF0cml4W2ldID0gW107XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHVtbnM7IGorKykge1xuICAgICAgICBpZiAoaSA+PSB0aGlzLmNvbHVtbkxldmVscyAmJiBqID49IHRoaXMucm93TGV2ZWxzKSB7XG4gICAgICAgICAgY29uc3QgaXNEYXRhQ2xhc3MgPSB0aGlzLnJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5LmluY2x1ZGVzKGkpICYmIHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXkuaW5jbHVkZXMoaik7XG4gICAgICAgICAgbWF0cml4W2ldW2pdID0ge1xuICAgICAgICAgICAgdmFsdWU6ICcnLFxuICAgICAgICAgICAgZGF0YVJlc291cmNlczogW10sXG4gICAgICAgICAgICBjc3NDbGFzczogaXNEYXRhQ2xhc3MgPyBQaXZvdFRhYmxlQ29udmVydGVyLmRhdGFDbGFzcyA6IFBpdm90VGFibGVDb252ZXJ0ZXIuZ3JvdXBEYXRhQ2xhc3MsXG4gICAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICAgIGlzVmFsdWU6IHRydWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtYXRyaXhbaV1bal0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5yb3dMZXZlbHMgPiAwICYmIHRoaXMuY29sdW1uTGV2ZWxzID4gMCkge1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLnJvd0xldmVsczsgaisrKSB7XG4gICAgICAgIGNvbnN0IHJvd0hlYWRlckF0dHJpYnV0ZSA9IHRoaXMuZGF0YS5yb3dIZWFkZXJBdHRyaWJ1dGVzW2pdO1xuICAgICAgICBpZiAocm93SGVhZGVyQXR0cmlidXRlKSB7XG4gICAgICAgICAgY29uc3QgdGl0bGVSb3dTcGFuID0gdGhpcy5ub25TdGlja3lDb2x1bW5JbmRleCB8fCB0aGlzLmNvbHVtbkxldmVsc1xuICAgICAgICAgIG1hdHJpeFswXVtqXSA9IHtcbiAgICAgICAgICAgIHZhbHVlOiByb3dIZWFkZXJBdHRyaWJ1dGUudGl0bGUsXG4gICAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5yb3dBdHRyaWJ1dGVIZWFkZXJDbGFzcyxcbiAgICAgICAgICAgIGlzQXR0cmlidXRlSGVhZGVyOiB0cnVlLFxuICAgICAgICAgICAgcm93U3BhbjogdGl0bGVSb3dTcGFuLFxuICAgICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICAgIHN0aWNreVRvcDogdGhpcy5pc0NvbHVtbkxldmVsU3RpY2t5KDApLFxuICAgICAgICAgICAgc3RpY2t5U3RhcnQ6IHRoaXMuaXNSb3dMZXZlbFN0aWNreShqKSxcbiAgICAgICAgICAgIGJhY2tncm91bmQ6IHJvd0hlYWRlckF0dHJpYnV0ZS5jb2xvcixcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgaWYgKHRoaXMuY29sdW1uTGV2ZWxzIC0gdGl0bGVSb3dTcGFuID4gMCkge1xuICAgICAgICAgICAgbWF0cml4W3RoaXMubm9uU3RpY2t5Q29sdW1uSW5kZXhdW2pdID0ge1xuICAgICAgICAgICAgICB2YWx1ZTogJycsXG4gICAgICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLnJvd0F0dHJpYnV0ZUhlYWRlckNsYXNzLFxuICAgICAgICAgICAgICBpc0F0dHJpYnV0ZUhlYWRlcjogdHJ1ZSxcbiAgICAgICAgICAgICAgcm93U3BhbjogdGhpcy5jb2x1bW5MZXZlbHMgLSB0aXRsZVJvd1NwYW4sXG4gICAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICAgIGJhY2tncm91bmQ6IHJvd0hlYWRlckF0dHJpYnV0ZS5jb2xvcixcbiAgICAgICAgICAgICAgc3RpY2t5U3RhcnQ6IHRoaXMuaXNSb3dMZXZlbFN0aWNreShqKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvbHVtbkxldmVsczsgaSsrKSB7XG4gICAgICAgICAgICBtYXRyaXhbaV1bal0gPSB7XG4gICAgICAgICAgICAgIHZhbHVlOiAnJyxcbiAgICAgICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuZW1wdHlDbGFzcyxcbiAgICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICAgICAgc3RpY2t5U3RhcnQ6IHRoaXMuaXNSb3dMZXZlbFN0aWNreShqKSxcbiAgICAgICAgICAgICAgc3RpY2t5VG9wOiB0aGlzLmlzQ29sdW1uTGV2ZWxTdGlja3koaSksXG4gICAgICAgICAgICAgIGlzSGVhZGVyOiBmYWxzZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbWF0cml4O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRSb3dzQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5kYXRhLnJvd0hlYWRlcnMubGVuZ3RoID09PSAwICYmICh0aGlzLmRhdGEudmFsdWVUaXRsZXMgfHwgW10pLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICByZXR1cm4gZ2V0SGVhZGVyc0NoaWxkQ291bnQodGhpcy5kYXRhLnJvd0hlYWRlcnMsIHRoaXMucm93U2hvd1N1bXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2x1bW5zQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5kYXRhLmNvbHVtbkhlYWRlcnMubGVuZ3RoID09PSAwICYmICh0aGlzLmRhdGEudmFsdWVUaXRsZXMgfHwgW10pLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICBjb25zdCBudW1iZXJPZlN1bXMgPSBNYXRoLm1heCgxLCAodGhpcy5kYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGgpO1xuICAgIHJldHVybiBnZXRIZWFkZXJzQ2hpbGRDb3VudCh0aGlzLmRhdGEuY29sdW1uSGVhZGVycywgdGhpcy5jb2x1bW5TaG93U3VtcywgbnVtYmVyT2ZTdW1zKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcmVwYXJlUGl2b3REYXRhKFxuICBkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhLFxuICBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGEsXG4gIHZhbHVlVHlwZUluZm86IFZhbHVlVHlwZUluZm9bXVxuKTogTG1yUGl2b3RTdGVtRGF0YSB7XG4gIGNvbnN0IG51bWJlck9mU3VtcyA9IE1hdGgubWF4KDEsIChkYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGgpO1xuICBjb25zdCB2YWx1ZXMgPSBjb21wdXRlVmFsdWVzQnlWYWx1ZVR5cGUoZGF0YS52YWx1ZXMsIGRhdGEudmFsdWVUeXBlcywgbnVtYmVyT2ZTdW1zLCB2YWx1ZVR5cGVJbmZvKTtcbiAgY29uc3Qgc29ydGVkID0gc29ydFBpdm90RGF0YSh7Li4uZGF0YSwgdmFsdWVzfSwgY29uc3RyYWludERhdGEpO1xuICByZXR1cm4gZmlsbEV4cHJlc3Npb25zVG9EYXRhKHNvcnRlZClcbn1cblxuZnVuY3Rpb24gZmlsbEV4cHJlc3Npb25zVG9EYXRhKGRhdGE6IExtclBpdm90U3RlbURhdGEpOiBMbXJQaXZvdFN0ZW1EYXRhIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5kYXRhLFxuICAgIHJvd0hlYWRlcnM6IGZpbGxFeHByZXNzaW9uc1RvSGVhZGVycyhkYXRhLnJvd0hlYWRlcnMsIGRhdGEucm93c0NvbmZpZywgMCksXG4gICAgY29sdW1uSGVhZGVyczogZmlsbEV4cHJlc3Npb25zVG9IZWFkZXJzKGRhdGEuY29sdW1uSGVhZGVycywgZGF0YS5jb2x1bW5zQ29uZmlnLCAwKSxcbiAgfVxufVxuXG5mdW5jdGlvbiBmaWxsRXhwcmVzc2lvbnNUb0hlYWRlcnMoaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sIGNvbmZpZ3M6IExtclBpdm90RGltZW5zaW9uQ29uZmlnW10sIGluZGV4OiBudW1iZXIpOiBMbXJQaXZvdERhdGFIZWFkZXJbXSB7XG4gIGNvbnN0IGV4cHJlc3Npb25zID0gY29uZmlncz8uW2luZGV4XT8uZXhwcmVzc2lvbnMgfHwgW11cbiAgY29uc3QgaGVhZGVyc0NvcHkgPSBbLi4uKGhlYWRlcnMgfHwgW10pXVxuICBmb3IgKGNvbnN0IGV4cHJlc3Npb24gb2YgZXhwcmVzc2lvbnMpIHtcbiAgICBjb25zdCBkYXRhSGVhZGVyRXhwcmVzc2lvbiA9IGV4dGVuZFBpdm90RXhwcmVzc2lvbihleHByZXNzaW9uLCBoZWFkZXJzKVxuICAgIGlmIChkYXRhSGVhZGVyRXhwcmVzc2lvbi5maXJzdEhlYWRlckluZGV4ID49IDApIHtcbiAgICAgIGNvbnN0IGZpcnN0SGVhZGVySW5kZXggPSBkYXRhSGVhZGVyRXhwcmVzc2lvbi5maXJzdEhlYWRlckluZGV4XG4gICAgICBjb25zdCBuZXdIZWFkZXI6IExtclBpdm90RGF0YUhlYWRlciA9IHsuLi5oZWFkZXJzQ29weVtmaXJzdEhlYWRlckluZGV4XSwgZXhwcmVzc2lvbnM6IFsuLi4oaGVhZGVyc0NvcHlbZmlyc3RIZWFkZXJJbmRleF0uZXhwcmVzc2lvbnMgfHwgW10pLCBkYXRhSGVhZGVyRXhwcmVzc2lvbl19XG4gICAgICBoZWFkZXJzQ29weS5zcGxpY2UoZmlyc3RIZWFkZXJJbmRleCwgMSwgbmV3SGVhZGVyKVxuICAgIH1cbiAgfVxuXG4gIGlmIChjb25maWdzPy5baW5kZXggKyAxXSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGVhZGVyc0NvcHkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGhlYWRlcnNDb3B5LnNwbGljZShpLCAxLCB7Li4uaGVhZGVyc0NvcHlbaV0sIGNoaWxkcmVuOiBmaWxsRXhwcmVzc2lvbnNUb0hlYWRlcnMoaGVhZGVyc0NvcHlbaV0uY2hpbGRyZW4sIGNvbmZpZ3MsIGluZGV4ICsgMSl9KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBoZWFkZXJzQ29weVxufVxuXG5mdW5jdGlvbiBleHRlbmRQaXZvdEV4cHJlc3Npb24oZXhwcmVzc2lvbjogTG1yUGl2b3RFeHByZXNzaW9uLCBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSk6IExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb24ge1xuICBjb25zdCBkYXRhSGVhZGVyT3BlcmFuZHM6IExtclBpdm90RGF0YUhlYWRlck9wZXJhbmRbXSA9IFtdO1xuICBsZXQgZmlyc3RIZWFkZXJJbmRleDogbnVtYmVyID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJcblxuICBmdW5jdGlvbiB0cmF2ZXJzZShvcGVyYW5kczogTG1yUGl2b3RPcGVyYW5kW10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IG9wZXJhbmQgb2Ygb3BlcmFuZHMpIHtcbiAgICAgIGlmIChvcGVyYW5kLnR5cGUgPT09ICdoZWFkZXInKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ZXMgPSBnZXRPcGVyYW5kSW5kZXhlc0luSGVhZGVycyhvcGVyYW5kLCBoZWFkZXJzKVxuICAgICAgICBmaXJzdEhlYWRlckluZGV4ID0gTWF0aC5taW4oZmlyc3RIZWFkZXJJbmRleCwgLi4uaW5kZXhlcylcbiAgICAgICAgY29uc3Qgb3BlcmFuZEhlYWRlcnMgPSBpbmRleGVzLm1hcChpbmRleCA9PiBoZWFkZXJzW2luZGV4XSlcbiAgICAgICAgZGF0YUhlYWRlck9wZXJhbmRzLnB1c2goey4uLm9wZXJhbmQsIGhlYWRlcnM6IG9wZXJhbmRIZWFkZXJzfSk7XG4gICAgICB9IGVsc2UgaWYgKG9wZXJhbmQudHlwZSA9PT0gJ2V4cHJlc3Npb24nKSB7XG4gICAgICAgIHRyYXZlcnNlKG9wZXJhbmQub3BlcmFuZHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGF0YUhlYWRlck9wZXJhbmRzLnB1c2gob3BlcmFuZClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0cmF2ZXJzZShleHByZXNzaW9uLm9wZXJhbmRzKTtcblxuICBpZiAoZXhwcmVzc2lvbi5wb3NpdGlvbiA9PT0gTG1yUGl2b3RQb3NpdGlvbi5TdGlja1RvRW5kKSB7XG4gICAgZmlyc3RIZWFkZXJJbmRleCA9IGhlYWRlcnMubGVuZ3RoIC0gMVxuICB9XG5cbiAgaWYgKGZpcnN0SGVhZGVySW5kZXggPT09IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKSB7XG4gICAgZmlyc3RIZWFkZXJJbmRleCA9IC0xXG4gIH1cblxuICByZXR1cm4gey4uLmV4cHJlc3Npb24sIGZpcnN0SGVhZGVySW5kZXgsIG9wZXJhbmRzOiBkYXRhSGVhZGVyT3BlcmFuZHN9O1xufVxuXG5mdW5jdGlvbiBnZXRPcGVyYW5kSW5kZXhlc0luSGVhZGVycyhvcGVyYW5kOiBMbXJQaXZvdEhlYWRlck9wZXJhbmQsIGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdKTogbnVtYmVyW10ge1xuICByZXR1cm4gKGhlYWRlcnMgfHwgW10pLnJlZHVjZTxudW1iZXJbXT4oKGluZGV4ZXMsIGhlYWRlciwgaW5kZXgpID0+IHtcbiAgICBpZiAob3BlcmFuZENvbnRhaW5zSGVhZGVyKG9wZXJhbmQsIGhlYWRlcikpIHtcbiAgICAgIGluZGV4ZXMucHVzaChpbmRleClcbiAgICB9XG4gICAgcmV0dXJuIGluZGV4ZXNcbiAgfSwgW10pXG59XG5cbmZ1bmN0aW9uIG9wZXJhbmRDb250YWluc0hlYWRlcihvcGVyYW5kOiBMbXJQaXZvdEhlYWRlck9wZXJhbmQsIGhlYWRlcjogTG1yUGl2b3REYXRhSGVhZGVyKTogYm9vbGVhbiB7XG4gIHJldHVybiBoZWFkZXIudGl0bGUubWF0Y2gobmV3IFJlZ0V4cChvcGVyYW5kLnZhbHVlKSk/Lmxlbmd0aCA+IDBcbn1cblxuZnVuY3Rpb24gY29tcHV0ZVZhbHVlc0J5VmFsdWVUeXBlKFxuICB2YWx1ZXM6IGFueVtdW10sXG4gIHZhbHVlVHlwZXM6IExtclBpdm90VmFsdWVUeXBlW10sXG4gIG51bVZhbHVlczogbnVtYmVyLFxuICB2YWx1ZVR5cGVJbmZvOiBWYWx1ZVR5cGVJbmZvW11cbik6IGFueVtdW10ge1xuICBjb25zdCByb3dzSW5kZXhlcyA9IFsuLi5BcnJheSh2YWx1ZXMubGVuZ3RoKS5rZXlzKCldO1xuICBjb25zdCBtb2RpZmllZFZhbHVlcyA9IGRlZXBPYmplY3RDb3B5KHZhbHVlcyk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1WYWx1ZXM7IGkrKykge1xuICAgIGNvbnN0IHZhbHVlVHlwZSA9IHZhbHVlVHlwZXMgJiYgdmFsdWVUeXBlc1tpXTtcbiAgICBpZiAoIXZhbHVlVHlwZSB8fCB2YWx1ZVR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLkRlZmF1bHQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbHVtbnNDb3VudCA9ICh2YWx1ZXNbMF0gJiYgdmFsdWVzWzBdLmxlbmd0aCkgfHwgMDtcbiAgICBjb25zdCBjb2x1bW5JbmRleGVzID0gWy4uLkFycmF5KGNvbHVtbnNDb3VudCkua2V5cygpXS5maWx0ZXIoa2V5ID0+IGtleSAlIG51bVZhbHVlcyA9PT0gaSk7XG4gICAgY29uc3QgaW5mbyA9IHZhbHVlVHlwZUluZm9baV07XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzSW5kZXhlcykge1xuICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1uSW5kZXhlcykge1xuICAgICAgICBpZiAodmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5BbGxQZXJjZW50YWdlKSB7XG4gICAgICAgICAgbW9kaWZpZWRWYWx1ZXNbcm93XVtjb2x1bW5dID0gZGl2aWRlVmFsdWVzKHZhbHVlc1tyb3ddW2NvbHVtbl0sIGluZm8uc3VtKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLlJvd1BlcmNlbnRhZ2UpIHtcbiAgICAgICAgICBtb2RpZmllZFZhbHVlc1tyb3ddW2NvbHVtbl0gPSBkaXZpZGVWYWx1ZXModmFsdWVzW3Jvd11bY29sdW1uXSwgaW5mby5zdW1zUm93c1tyb3ddKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLkNvbHVtblBlcmNlbnRhZ2UpIHtcbiAgICAgICAgICBtb2RpZmllZFZhbHVlc1tyb3ddW2NvbHVtbl0gPSBkaXZpZGVWYWx1ZXModmFsdWVzW3Jvd11bY29sdW1uXSwgaW5mby5zdW1zQ29sdW1uc1tjb2x1bW5dKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtb2RpZmllZFZhbHVlcztcbn1cblxuZnVuY3Rpb24gZ2V0VmFsdWVzVHlwZUluZm8odmFsdWVzOiBhbnlbXVtdLCB2YWx1ZVR5cGVzOiBMbXJQaXZvdFZhbHVlVHlwZVtdLCBudW1WYWx1ZXM6IG51bWJlcik6IFZhbHVlVHlwZUluZm9bXSB7XG4gIGNvbnN0IHZhbHVlVHlwZUluZm8gPSBbXTtcbiAgY29uc3Qgcm93c0luZGV4ZXMgPSBbLi4uQXJyYXkodmFsdWVzLmxlbmd0aCkua2V5cygpXTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bVZhbHVlczsgaSsrKSB7XG4gICAgY29uc3QgdmFsdWVUeXBlID0gdmFsdWVUeXBlcyAmJiB2YWx1ZVR5cGVzW2ldO1xuICAgIGNvbnN0IGNvbHVtbnNDb3VudCA9ICh2YWx1ZXNbMF0gJiYgdmFsdWVzWzBdLmxlbmd0aCkgfHwgMDtcbiAgICBjb25zdCBjb2x1bW5JbmRleGVzID0gWy4uLkFycmF5KGNvbHVtbnNDb3VudCkua2V5cygpXS5maWx0ZXIoa2V5ID0+IGtleSAlIG51bVZhbHVlcyA9PT0gaSk7XG5cbiAgICB2YWx1ZVR5cGVJbmZvW2ldID0gZ2V0VmFsdWVUeXBlSW5mbyh2YWx1ZXMsIHZhbHVlVHlwZSwgcm93c0luZGV4ZXMsIGNvbHVtbkluZGV4ZXMpO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlVHlwZUluZm87XG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlVHlwZUluZm8odmFsdWVzOiBhbnlbXVtdLCB0eXBlOiBMbXJQaXZvdFZhbHVlVHlwZSwgcm93czogbnVtYmVyW10sIGNvbHVtbnM6IG51bWJlcltdKTogVmFsdWVUeXBlSW5mbyB7XG4gIGNvbnN0IGNvbnRhaW5zRGVjaW1hbCA9IGNvbnRhaW5zRGVjaW1hbFZhbHVlKHZhbHVlcywgcm93cywgY29sdW1ucyk7XG4gIGNvbnN0IHZhbHVlVHlwZUluZm86IFZhbHVlVHlwZUluZm8gPSB7XG4gICAgZGVmYXVsdENvbnN0cmFpbnQ6IGNvbnRhaW5zRGVjaW1hbCA/IG5ldyBOdW1iZXJDb25zdHJhaW50KHtkZWNpbWFsczogMn0pIDogbnVsbCxcbiAgfTtcblxuICBpZiAodHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQWxsUGVyY2VudGFnZSkge1xuICAgIHJldHVybiB7Li4udmFsdWVUeXBlSW5mbywgc3VtOiBnZXROdW1lcmljVmFsdWVzU3VtbWFyeSh2YWx1ZXMsIHJvd3MsIGNvbHVtbnMpfTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5Sb3dQZXJjZW50YWdlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnZhbHVlVHlwZUluZm8sXG4gICAgICBzdW1zUm93czogcm93cy5yZWR1Y2UoKGFyciwgcm93KSA9PiB7XG4gICAgICAgIGFycltyb3ddID0gZ2V0TnVtZXJpY1ZhbHVlc1N1bW1hcnkodmFsdWVzLCBbcm93XSwgY29sdW1ucyk7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgICB9LCBbXSksXG4gICAgfTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5Db2x1bW5QZXJjZW50YWdlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnZhbHVlVHlwZUluZm8sXG4gICAgICBzdW1zQ29sdW1uczogY29sdW1ucy5yZWR1Y2UoKGFyciwgY29sdW1uKSA9PiB7XG4gICAgICAgIGFycltjb2x1bW5dID0gZ2V0TnVtZXJpY1ZhbHVlc1N1bW1hcnkodmFsdWVzLCByb3dzLCBbY29sdW1uXSk7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgICB9LCBbXSksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7Li4udmFsdWVUeXBlSW5mb307XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zRGVjaW1hbFZhbHVlKHZhbHVlczogYW55W11bXSwgcm93czogbnVtYmVyW10sIGNvbHVtbnM6IG51bWJlcltdKTogYm9vbGVhbiB7XG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2x1bW5zKSB7XG4gICAgICBpZiAoaXNWYWx1ZURlY2ltYWwodmFsdWVzW3Jvd11bY29sdW1uXSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNWYWx1ZURlY2ltYWwodmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAoaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGlzTnVtZXJpYyh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdG9OdW1iZXIodmFsdWUpICUgMSAhPT0gMDtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVRyYW5zZm9ybWF0aW9uTWFwKFxuICBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgc2hvd1N1bXM6IGJvb2xlYW5bXSxcbiAgYWRkaXRpb25hbE51bTogbnVtYmVyLFxuICBudW1iZXJPZlN1bXM6IG51bWJlclxuKTogbnVtYmVyW10ge1xuICBjb25zdCBhcnJheSA9IFtdO1xuICBpdGVyYXRlVGhyb3VnaFRyYW5zZm9ybWF0aW9uTWFwKGhlYWRlcnMsIGFkZGl0aW9uYWxOdW0sIGFycmF5LCAwLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKTtcbiAgcmV0dXJuIGFycmF5O1xufVxuXG5mdW5jdGlvbiBpdGVyYXRlVGhyb3VnaFRyYW5zZm9ybWF0aW9uTWFwKFxuICBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgYWRkaXRpb25hbE51bTogbnVtYmVyLFxuICBhcnJheTogbnVtYmVyW10sXG4gIGxldmVsOiBudW1iZXIsXG4gIHNob3dTdW1zOiBib29sZWFuW10sXG4gIG51bWJlck9mU3VtczogbnVtYmVyXG4pIHtcbiAgbGV0IGFkZGl0aW9uYWwgPSBhZGRpdGlvbmFsTnVtO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGhlYWRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBoZWFkZXIgPSBoZWFkZXJzW2ldO1xuICAgIGNvbnN0IGJlZm9yZUV4cHJlc3Npb25zTGVuZ3RoID0gKGhlYWRlci5leHByZXNzaW9ucyB8fCBbXSkuZmlsdGVyKGV4cCA9PiBleHAucG9zaXRpb24gPT09IExtclBpdm90UG9zaXRpb24uQmVmb3JlSGVhZGVyKS5sZW5ndGhcbiAgICBjb25zdCBhZnRlckV4cHJlc3Npb25zTGVuZ3RoID0gKGhlYWRlci5leHByZXNzaW9ucyB8fCBbXSkuZmlsdGVyKGV4cCA9PiBleHAucG9zaXRpb24gPT09IExtclBpdm90UG9zaXRpb24uU3RpY2tUb0VuZCkubGVuZ3RoXG4gICAgaWYgKGhlYWRlci5jaGlsZHJlbikge1xuICAgICAgYWRkaXRpb25hbCArPSBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aFxuICAgICAgaXRlcmF0ZVRocm91Z2hUcmFuc2Zvcm1hdGlvbk1hcChoZWFkZXIuY2hpbGRyZW4sIGFkZGl0aW9uYWwsIGFycmF5LCBsZXZlbCArIDEsIHNob3dTdW1zLCBudW1iZXJPZlN1bXMpO1xuICAgICAgYWRkaXRpb25hbCArPSAoZ2V0SGVhZGVyQ2hpbGRDb3VudChoZWFkZXIsIGxldmVsLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKSAtIGJlZm9yZUV4cHJlc3Npb25zTGVuZ3RoKTtcbiAgICB9IGVsc2UgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGhlYWRlci50YXJnZXRJbmRleCkpIHtcbiAgICAgIGFycmF5W2hlYWRlci50YXJnZXRJbmRleF0gPSBpICsgYWRkaXRpb25hbCArIGJlZm9yZUV4cHJlc3Npb25zTGVuZ3RoO1xuICAgICAgYWRkaXRpb25hbCArPSBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aCArIGFmdGVyRXhwcmVzc2lvbnNMZW5ndGg7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXJzKGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdKTogbnVtYmVyW10ge1xuICBjb25zdCBhbGxSb3dzID0gKGhlYWRlcnMgfHwgW10pLnJlZHVjZSgocm93cywgaGVhZGVyKSA9PiB7XG4gICAgcm93cy5wdXNoKC4uLmdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXIoaGVhZGVyKSk7XG4gICAgcmV0dXJuIHJvd3M7XG4gIH0sIFtdKTtcbiAgcmV0dXJuIHVuaXF1ZVZhbHVlczxudW1iZXI+KGFsbFJvd3MpO1xufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKHBpdm90RGF0YUhlYWRlcjogTG1yUGl2b3REYXRhSGVhZGVyKTogbnVtYmVyW10ge1xuICBpZiAocGl2b3REYXRhSGVhZGVyLmNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbi5yZWR1Y2UoKHJvd3MsIGhlYWRlcikgPT4ge1xuICAgICAgcm93cy5wdXNoKC4uLmdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXIoaGVhZGVyKSk7XG4gICAgICByZXR1cm4gcm93cztcbiAgICB9LCBbXSk7XG4gIH1cbiAgcmV0dXJuIFtwaXZvdERhdGFIZWFkZXIudGFyZ2V0SW5kZXhdO1xufVxuXG5mdW5jdGlvbiBnZXRIZWFkZXJzQ2hpbGRDb3VudChoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSwgc2hvd1N1bXM6IGJvb2xlYW5bXSwgbnVtYmVyT2ZTdW1zID0gMSk6IG51bWJlciB7XG4gIHJldHVybiAoaGVhZGVycyB8fCBbXSkucmVkdWNlKFxuICAgIChzdW0sIGhlYWRlcikgPT4gc3VtICsgZ2V0SGVhZGVyQ2hpbGRDb3VudChoZWFkZXIsIDAsIHNob3dTdW1zLCBudW1iZXJPZlN1bXMpLFxuICAgIHNob3dTdW1zWzBdID8gbnVtYmVyT2ZTdW1zIDogMFxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRIZWFkZXJDaGlsZENvdW50KFxuICBwaXZvdERhdGFIZWFkZXI6IExtclBpdm90RGF0YUhlYWRlcixcbiAgbGV2ZWw6IG51bWJlcixcbiAgc2hvd1N1bXM6IGJvb2xlYW5bXSxcbiAgbnVtYmVyT2ZTdW1zID0gMSxcbik6IG51bWJlciB7XG4gIGNvbnN0IG51bUV4cHJlc3Npb25zID0gKHBpdm90RGF0YUhlYWRlci5leHByZXNzaW9ucyB8fCBbXSkubGVuZ3RoXG4gIGlmIChwaXZvdERhdGFIZWFkZXIuY2hpbGRyZW4pIHtcbiAgICByZXR1cm4gcGl2b3REYXRhSGVhZGVyLmNoaWxkcmVuLnJlZHVjZShcbiAgICAgIChzdW0sIGhlYWRlcikgPT4gc3VtICsgZ2V0SGVhZGVyQ2hpbGRDb3VudChoZWFkZXIsIGxldmVsICsgMSwgc2hvd1N1bXMsIG51bWJlck9mU3VtcyksXG4gICAgICAoc2hvd1N1bXNbbGV2ZWwgKyAxXSA/IG51bWJlck9mU3VtcyA6IDApICsgbnVtRXhwcmVzc2lvbnNcbiAgICApO1xuICB9XG4gIHJldHVybiAxICsgbnVtRXhwcmVzc2lvbnM7XG59XG5cbmZ1bmN0aW9uIGdldERpcmVjdEhlYWRlckNoaWxkQ291bnQoXG4gIHBpdm90RGF0YUhlYWRlcjogTG1yUGl2b3REYXRhSGVhZGVyLFxuICBsZXZlbDogbnVtYmVyLFxuICBzaG93U3VtczogYm9vbGVhbltdLFxuICBudW1iZXJPZlN1bXMgPSAxXG4pOiBudW1iZXIge1xuICBpZiAocGl2b3REYXRhSGVhZGVyLmNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbi5yZWR1Y2UoXG4gICAgICAoc3VtLCBoZWFkZXIpID0+IHN1bSArIGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCArIDEsIHNob3dTdW1zLCBudW1iZXJPZlN1bXMpLFxuICAgICAgMFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIDE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzb3J0UGl2b3REYXRhKGRhdGE6IExtclBpdm90U3RlbURhdGEsIGNvbnN0cmFpbnREYXRhOiBDb25zdHJhaW50RGF0YSk6IExtclBpdm90U3RlbURhdGEge1xuICBjb25zdCByb3dTb3J0cyA9IChkYXRhLnJvd3NDb25maWcgfHwgW10pLm1hcChjb25maWcgPT4gY29uZmlnLnNvcnQpXG4gIGNvbnN0IGNvbHVtblNvcnRzID0gKGRhdGEuY29sdW1uc0NvbmZpZyB8fCBbXSkubWFwKGNvbmZpZyA9PiBjb25maWcuc29ydClcbiAgcmV0dXJuIHtcbiAgICAuLi5kYXRhLFxuICAgIHJvd0hlYWRlcnM6IHNvcnRQaXZvdFJvd0RhdGFIZWFkZXJzKGRhdGEucm93SGVhZGVycywgcm93U29ydHMsIGRhdGEsIGNvbnN0cmFpbnREYXRhKSxcbiAgICBjb2x1bW5IZWFkZXJzOiBzb3J0UGl2b3RDb2x1bW5EYXRhSGVhZGVycyhkYXRhLmNvbHVtbkhlYWRlcnMsIGNvbHVtblNvcnRzLCBkYXRhLCBjb25zdHJhaW50RGF0YSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHNvcnRQaXZvdFJvd0RhdGFIZWFkZXJzKFxuICByb3dIZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgcm93U29ydHM6IExtclBpdm90U29ydFtdLFxuICBwaXZvdERhdGE6IExtclBpdm90U3RlbURhdGEsXG4gIGNvbnN0cmFpbnREYXRhOiBDb25zdHJhaW50RGF0YVxuKTogTG1yUGl2b3REYXRhSGVhZGVyW10ge1xuICByZXR1cm4gc29ydFBpdm90RGF0YUhlYWRlcnNSZWN1cnNpdmUoXG4gICAgcm93SGVhZGVycyxcbiAgICAwLFxuICAgIHJvd1NvcnRzLFxuICAgIHBpdm90RGF0YS5jb2x1bW5IZWFkZXJzLFxuICAgIHBpdm90RGF0YS52YWx1ZXMsXG4gICAgcGl2b3REYXRhLnZhbHVlVGl0bGVzIHx8IFtdLFxuICAgIHRydWUsXG4gICAgY29uc3RyYWludERhdGFcbiAgKTtcbn1cblxuZnVuY3Rpb24gc29ydFBpdm90Q29sdW1uRGF0YUhlYWRlcnMoXG4gIGNvbHVtbkhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICBjb2x1bW5Tb3J0czogTG1yUGl2b3RTb3J0W10sXG4gIHBpdm90RGF0YTogTG1yUGl2b3RTdGVtRGF0YSxcbiAgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhXG4pOiBMbXJQaXZvdERhdGFIZWFkZXJbXSB7XG4gIHJldHVybiBzb3J0UGl2b3REYXRhSGVhZGVyc1JlY3Vyc2l2ZShcbiAgICBjb2x1bW5IZWFkZXJzLFxuICAgIDAsXG4gICAgY29sdW1uU29ydHMsXG4gICAgcGl2b3REYXRhLnJvd0hlYWRlcnMsXG4gICAgcGl2b3REYXRhLnZhbHVlcyxcbiAgICBwaXZvdERhdGEudmFsdWVUaXRsZXMgfHwgW10sXG4gICAgZmFsc2UsXG4gICAgY29uc3RyYWludERhdGFcbiAgKTtcbn1cblxuZnVuY3Rpb24gc29ydFBpdm90RGF0YUhlYWRlcnNSZWN1cnNpdmUoXG4gIGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICBpbmRleDogbnVtYmVyLFxuICBzb3J0czogTG1yUGl2b3RTb3J0W10sXG4gIG90aGVyU2lkZUhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICB2YWx1ZXM6IGFueVtdW10sXG4gIHZhbHVlVGl0bGVzOiBzdHJpbmdbXSxcbiAgaXNSb3dzOiBib29sZWFuLFxuICBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGFcbik6IExtclBpdm90RGF0YUhlYWRlcltdIHtcbiAgLy8gd2UgZG9uJ3Qgd2FudCB0byBzb3J0IHZhbHVlcyBoZWFkZXJzXG4gIGlmICghaXNSb3dzICYmIGlzVmFsdWVzSGVhZGVycyhoZWFkZXJzLCB2YWx1ZVRpdGxlcykpIHtcbiAgICByZXR1cm4gaGVhZGVycztcbiAgfVxuICBjb25zdCBzb3J0ID0gc29ydHMgJiYgc29ydHNbaW5kZXhdO1xuICBjb25zdCBjb25zdHJhaW50ID0gZ2V0Q29uc3RyYWludEZvclNvcnQoc29ydCwgaGVhZGVycyk7XG4gIGNvbnN0IHZhbHVlc01hcCA9IGNyZWF0ZUhlYWRlcnNWYWx1ZXNNYXAoaGVhZGVycywgc29ydCwgb3RoZXJTaWRlSGVhZGVycywgdmFsdWVzLCB2YWx1ZVRpdGxlcywgaXNSb3dzKTtcbiAgcmV0dXJuIGhlYWRlcnNcbiAgICAubWFwKGhlYWRlciA9PiAoe1xuICAgICAgLi4uaGVhZGVyLFxuICAgICAgY2hpbGRyZW46XG4gICAgICAgIGhlYWRlci5jaGlsZHJlbiAmJlxuICAgICAgICBzb3J0UGl2b3REYXRhSGVhZGVyc1JlY3Vyc2l2ZShcbiAgICAgICAgICBoZWFkZXIuY2hpbGRyZW4sXG4gICAgICAgICAgaW5kZXggKyAxLFxuICAgICAgICAgIHNvcnRzLFxuICAgICAgICAgIG90aGVyU2lkZUhlYWRlcnMsXG4gICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgIHZhbHVlVGl0bGVzLFxuICAgICAgICAgIGlzUm93cyxcbiAgICAgICAgICBjb25zdHJhaW50RGF0YVxuICAgICAgICApLFxuICAgIH0pKVxuICAgIC5zb3J0KChyMSwgcjIpID0+IHtcbiAgICAgIGNvbnN0IHIxVmFsdWUgPSBjb25zdHJhaW50LmNyZWF0ZURhdGFWYWx1ZSh2YWx1ZXNNYXBbcjEudGl0bGVdLCBjb25zdHJhaW50RGF0YSk7XG4gICAgICBjb25zdCByMlZhbHVlID0gY29uc3RyYWludC5jcmVhdGVEYXRhVmFsdWUodmFsdWVzTWFwW3IyLnRpdGxlXSwgY29uc3RyYWludERhdGEpO1xuICAgICAgY29uc3QgbXVsdGlwbGllciA9ICFzb3J0IHx8IHNvcnQuYXNjID8gMSA6IC0xO1xuICAgICAgcmV0dXJuIHIxVmFsdWUuY29tcGFyZVRvKHIyVmFsdWUpICogbXVsdGlwbGllcjtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0Q29uc3RyYWludEZvclNvcnQoc29ydDogTG1yUGl2b3RTb3J0LCBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSk6IENvbnN0cmFpbnQge1xuICBpZiAoKHNvcnQ/Lmxpc3Q/LnZhbHVlcyB8fCBbXSkubGVuZ3RoID4gMCkge1xuICAgIC8vIHNvcnQgaXMgZG9uZSBieSB2YWx1ZXMgaW4gY29sdW1uc1xuICAgIHJldHVybiBuZXcgTnVtYmVyQ29uc3RyYWludCh7fSk7XG4gIH1cbiAgcmV0dXJuICgoaGVhZGVycyB8fCBbXSlbMF0gJiYgKGhlYWRlcnMgfHwgW10pWzBdLmNvbnN0cmFpbnQpIHx8IG5ldyBVbmtub3duQ29uc3RyYWludCgpO1xufVxuXG5mdW5jdGlvbiBpc1ZhbHVlc0hlYWRlcnMoaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sIHZhbHVlVGl0bGVzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIHZhbHVlVGl0bGVzLmxlbmd0aCA+IDEgJiZcbiAgICAoaGVhZGVycyB8fCBbXSkuZXZlcnkoXG4gICAgICAoaGVhZGVyLCBpbmRleCkgPT4gaXNOb3ROdWxsT3JVbmRlZmluZWQoaGVhZGVyLnRhcmdldEluZGV4KSAmJiBoZWFkZXIudGl0bGUgPT09IHZhbHVlVGl0bGVzW2luZGV4XVxuICAgIClcbiAgKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSGVhZGVyc1ZhbHVlc01hcChcbiAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIHNvcnQ6IExtclBpdm90U29ydCxcbiAgb3RoZXJTaWRlSGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIHZhbHVlczogYW55W11bXSxcbiAgdmFsdWVUaXRsZXM6IHN0cmluZ1tdLFxuICBpc1Jvd3M6IGJvb2xlYW5cbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCBzb3J0VGFyZ2V0SW5kZXhlcyA9IHNvcnRWYWx1ZVRhcmdldEluZGV4ZXMoc29ydCwgb3RoZXJTaWRlSGVhZGVycywgdmFsdWVUaXRsZXMpO1xuICBpZiAoIXNvcnRUYXJnZXRJbmRleGVzKSB7XG4gICAgcmV0dXJuIChoZWFkZXJzIHx8IFtdKS5yZWR1Y2UoKHZhbHVlc01hcCwgaGVhZGVyKSA9PiB7XG4gICAgICB2YWx1ZXNNYXBbaGVhZGVyLnRpdGxlXSA9IGhlYWRlci50aXRsZTtcbiAgICAgIHJldHVybiB2YWx1ZXNNYXA7XG4gICAgfSwge30pO1xuICB9XG5cbiAgcmV0dXJuIChoZWFkZXJzIHx8IFtdKS5yZWR1Y2UoKHZhbHVlc01hcCwgaGVhZGVyKSA9PiB7XG4gICAgY29uc3Qgcm93cyA9IGlzUm93cyA/IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXIoaGVhZGVyKSA6IHNvcnRUYXJnZXRJbmRleGVzO1xuICAgIGNvbnN0IGNvbHVtbnMgPSBpc1Jvd3MgPyBzb3J0VGFyZ2V0SW5kZXhlcyA6IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXIoaGVhZGVyKTtcbiAgICB2YWx1ZXNNYXBbaGVhZGVyLnRpdGxlXSA9IGdldE51bWVyaWNWYWx1ZXNTdW1tYXJ5KHZhbHVlcywgcm93cywgY29sdW1ucyk7XG4gICAgcmV0dXJuIHZhbHVlc01hcDtcbiAgfSwge30pO1xufVxuXG5mdW5jdGlvbiBnZXROdW1lcmljVmFsdWVzU3VtbWFyeSh2YWx1ZXM6IGFueVtdW10sIHJvd3M6IG51bWJlcltdLCBjb2x1bW5zOiBudW1iZXJbXSk6IG51bWJlciB7XG4gIGxldCBzdW0gPSAwO1xuICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuICAgICAgY29uc3QgdmFsdWUgPSB2YWx1ZXNbcm93XVtjb2x1bW5dO1xuICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKHZhbHVlKSAmJiBpc051bWVyaWModmFsdWUpKSB7XG4gICAgICAgIHN1bSArPSB0b051bWJlcih2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBzdW07XG59XG5cbmZ1bmN0aW9uIHNvcnRWYWx1ZVRhcmdldEluZGV4ZXMoXG4gIHNvcnQ6IExtclBpdm90U29ydCxcbiAgb3RoZXJTaWRlSGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIHZhbHVlVGl0bGVzOiBzdHJpbmdbXVxuKTogbnVtYmVyW10gfCBudWxsIHtcbiAgaWYgKHNvcnQgJiYgc29ydC5saXN0KSB7XG4gICAgbGV0IHZhbHVlSW5kZXggPSB2YWx1ZVRpdGxlcy5maW5kSW5kZXgodGl0bGUgPT4gdGl0bGUgPT09IHNvcnQubGlzdC52YWx1ZVRpdGxlKTtcbiAgICBpZiAodmFsdWVJbmRleCA9PT0gLTEpIHtcbiAgICAgIGlmICh2YWx1ZVRpdGxlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgdmFsdWVJbmRleCA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgcGl2b3RIZWFkZXI6IExtclBpdm90RGF0YUhlYWRlciA9IG51bGw7XG4gICAgbGV0IGN1cnJlbnRPdGhlclNpZGVIZWFkZXJzID0gb3RoZXJTaWRlSGVhZGVycztcbiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHNvcnQubGlzdC52YWx1ZXMgfHwgW10pIHtcbiAgICAgIGlmICh2YWx1ZS5pc1N1bW1hcnkpIHtcbiAgICAgICAgY29uc3QgaW5kZXhlcyA9IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXJzKGN1cnJlbnRPdGhlclNpZGVIZWFkZXJzIHx8IFtdKSB8fCBbXTtcbiAgICAgICAgcmV0dXJuIGZpbHRlckluZGV4ZXNCeU1vZChpbmRleGVzLCB2YWx1ZVRpdGxlcy5sZW5ndGgsIHZhbHVlSW5kZXgpO1xuICAgICAgfVxuXG4gICAgICBwaXZvdEhlYWRlciA9IChjdXJyZW50T3RoZXJTaWRlSGVhZGVycyB8fCBbXSkuZmluZChoZWFkZXIgPT4gaGVhZGVyLnRpdGxlID09PSB2YWx1ZS50aXRsZSk7XG4gICAgICBpZiAoIXBpdm90SGVhZGVyKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50T3RoZXJTaWRlSGVhZGVycyA9IHBpdm90SGVhZGVyLmNoaWxkcmVuIHx8IFtdO1xuICAgIH1cblxuICAgIGlmIChwaXZvdEhlYWRlcikge1xuICAgICAgY29uc3QgdGFyZ2V0SW5kZXhlcyA9IGlzTm90TnVsbE9yVW5kZWZpbmVkKHBpdm90SGVhZGVyLnRhcmdldEluZGV4KVxuICAgICAgICA/IFtwaXZvdEhlYWRlci50YXJnZXRJbmRleF1cbiAgICAgICAgOiBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVycyhjdXJyZW50T3RoZXJTaWRlSGVhZGVycyk7XG4gICAgICByZXR1cm4gZmlsdGVySW5kZXhlc0J5TW9kKHRhcmdldEluZGV4ZXMsIHZhbHVlVGl0bGVzLmxlbmd0aCwgdmFsdWVJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZpbHRlckluZGV4ZXNCeU1vZChpbmRleGVzOiBudW1iZXJbXSwgbW9kOiBudW1iZXIsIHZhbHVlOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiAoaW5kZXhlcyB8fCBbXSkuZmlsdGVyKGluZGV4ID0+IGluZGV4ICUgbW9kID09PSB2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGRpdmlkZVZhbHVlcyh2YWx1ZTogYW55LCBkaXZpZGVyOiBhbnkpOiBudW1iZXIge1xuICBpZiAoaXNOdWxsT3JVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoaXNOdW1lcmljKHZhbHVlKSAmJiBpc051bWVyaWMoZGl2aWRlcikpIHtcbiAgICBpZiAoZGl2aWRlciAhPT0gMCkge1xuICAgICAgcmV0dXJuIHZhbHVlIC8gZGl2aWRlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4iXX0=