@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.
- package/fesm2022/lumeer-pivot.mjs +58 -45
- package/fesm2022/lumeer-pivot.mjs.map +1 -1
- package/lumeer-pivot-0.1.0.tgz +0 -0
- package/package.json +4 -6
- package/esm2022/lib/directives/lmr-templates.directive.mjs +0 -27
- package/esm2022/lib/lmr-pivot-table.component.mjs +0 -147
- package/esm2022/lib/lmr-pivot-table.module.mjs +0 -63
- package/esm2022/lib/lmr-simple-pivot-table.component.mjs +0 -101
- package/esm2022/lib/pipes/cell-has-value.pipe.mjs +0 -35
- package/esm2022/lib/pipes/contrast-color.pipe.mjs +0 -41
- package/esm2022/lib/pipes/filter-visible-cells.pipe.mjs +0 -35
- package/esm2022/lib/pipes/is-cell-expandable.pipe.mjs +0 -35
- package/esm2022/lib/pipes/is-cell-expanded.pipe.mjs +0 -37
- package/esm2022/lib/pipes/is-cell-rows-expandable.pipe.mjs +0 -35
- package/esm2022/lib/pipes/pivot-data-empty.pipe.mjs +0 -38
- package/esm2022/lib/util/lmr-pivot-config.mjs +0 -17
- package/esm2022/lib/util/lmr-pivot-constants.mjs +0 -12
- package/esm2022/lib/util/lmr-pivot-data.mjs +0 -2
- package/esm2022/lib/util/lmr-pivot-state.mjs +0 -156
- package/esm2022/lib/util/lmr-pivot-table.mjs +0 -2
- package/esm2022/lib/util/lmr-simple-pivot-config.mjs +0 -2
- package/esm2022/lib/util/pivot-data-converter.mjs +0 -507
- package/esm2022/lib/util/pivot-table-converter.mjs +0 -1017
- package/esm2022/lib/util/pivot-util.mjs +0 -75
- package/esm2022/lumeer-pivot.mjs +0 -5
- package/esm2022/public-api.mjs +0 -13
- package/lumeer-pivot-0.0.12.tgz +0 -0
|
@@ -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=
|